code: def random_sample_no_replacement(
      pool: Mapping[int, Collection[int]],
      num_tokens: int,
      num_entities: Optional[int] = None,
  ) -> torch.LongTensor:
      """Sample randomly without replacement num_tokens relations for each entity.
  
      If a graph has disconnected nodes, then num_entities > number of rows in the pool.
  
      :param pool:
          a dictionary of entity: [relations]
      :param num_tokens:
          the number of tokens to sample for each entity
      :param num_entities:
          the total number of nodes in the graph, might be bigger than the pool size for graphs with disconnected nodes.
          If not given, is calculated based the length of ``pool``.
  
      :return: shape: (num_entities, num_tokens), -1 <= res < vocabulary_size
          the selected relation IDs for each entity. -1 is used as a padding token.
      """
      if num_entities is None:
          num_entities = len(pool)
      assignment = torch.full(
          size=(num_entities, num_tokens),
          dtype=torch.long,
          fill_value=-1,
      )
      # TODO: vectorization?
      for idx, this_pool in tqdm(
          pool.items(), desc="sampling", leave=False, unit_scale=True
      ):
          this_pool_t = torch.as_tensor(
              data=list(this_pool), dtype=torch.long
          )
          this_pool = this_pool_t[
              torch.randperm(this_pool_t.shape[0])[:num_tokens]
          ]
          assignment[idx, : len(this_pool_t)] = this_pool
      return assignment
  
file_path: pykeen/src/pykeen/nn/node_piece/utils.py
imports: import logging
  from typing import Collection, Mapping, Optional
  import numpy
  import torch
  from tqdm.auto import tqdm
label_desc: Use image node_id 1 for calling a global function with example usage: random_sample_no_replacement(pool, num_tokens, num_entities) and returns: assignment