code: def create_dataloader(args, graph, features, itemset, is_train=True):
      """Get a GraphBolt version of a dataloader for link prediction tasks. This
      function demonstrates how to utilize functional forms of datapipes in
      GraphBolt. Alternatively, you can create a datapipe using its class
      constructor. For a more detailed tutorial, please read the examples in
      `dgl/notebooks/graphbolt/walkthrough.ipynb`.
      """
  
      ############################################################################
      # [Input]:
      # 'itemset': The current dataset.
      # 'args.batch_size': Specify the number of samples to be processed together,
      # referred to as a 'mini-batch'. (The term 'mini-batch' is used here to
      # indicate a subset of the entire dataset that is processed together. This
      # is in contrast to processing the entire dataset, known as a 'full batch'.)
      # 'is_train': Determining if data should be shuffled. (Shuffling is
      # generally used only in training to improve model generalization. It's
      # not used in validation and testing as the focus there is to evaluate
      # performance rather than to learn from the data.)
      # [Output]:
      # An ItemSampler object for handling mini-batch sampling.
      # [Role]:
      # Initialize the ItemSampler to sample mini-batche from the dataset.
      ############################################################################
      datapipe = gb.ItemSampler(
          itemset,
          batch_size=args.train_batch_size
          if is_train
          else args.eval_batch_size,
          shuffle=is_train,
      )
  
      ############################################################################
      # [Input]:
      # 'device': The device to copy the data to.
      # [Output]:
      # A CopyTo object to copy the data to the specified device. Copying here
      # ensures that the rest of the operations run on the GPU.
      ############################################################################
      if args.storage_device != "cpu":
          datapipe = datapipe.copy_to(device=args.device)
  
      ############################################################################
      # [Input]:
      # 'args.neg_ratio': Specify the ratio of negative to positive samples.
      # (E.g., if neg_ratio is 1, for each positive sample there will be 1
      # negative sample.)
      # 'graph': The overall network topology for negative sampling.
      # [Output]:
      # A UniformNegativeSampler object that will handle the generation of
      # negative samples for link prediction tasks.
      # [Role]:
      # Initialize the UniformNegativeSampler for negative sampling in link
      # prediction.
      # [Note]:
      # If 'is_train' is False, the UniformNegativeSampler will not be used.
      # Since, in validation and testing, the itemset already contains the
      # negative edges information.
      ############################################################################
      if is_train:
          datapipe = datapipe.sample_uniform_negative(
              graph, args.neg_ratio
          )
  
      ############################################################################
      # [Input]:
      # 'datapipe' is either 'ItemSampler' or 'UniformNegativeSampler' depending
      # on whether training is needed ('is_train'),
      # 'graph': The network topology for sampling.
      # 'args.fanout': Number of neighbors to sample per node.
      # [Output]:
      # A NeighborSampler object to sample neighbors.
      # [Role]:
      # Initialize a neighbor sampler for sampling the neighborhoods of nodes.
      ############################################################################
      datapipe = datapipe.sample_neighbor(graph, args.fanout)
  
      ############################################################################
      # [Input]:
      # 'gb.exclude_seed_edges': Function to exclude seed edges, optionally
      # including their reverse edges, from the sampled subgraphs in the
      # minibatch.
      # [Output]:
      # A MiniBatchTransformer object with excluded seed edges.
      # [Role]:
      # During the training phase of link prediction, negative edges are
      # sampled. It's essential to exclude the seed edges from the process
      # to ensure that positive samples are not inadvertently included within
      # the negative samples.
      ############################################################################
      if is_train and args.exclude_edges:
          datapipe = datapipe.transform(
              partial(gb.exclude_seed_edges, include_reverse_edges=True)
          )
  
      ############################################################################
      # [Input]:
      # 'features': The node features.
      # 'node_feature_keys': The node feature keys (list) to be fetched.
      # [Output]:
      # A FeatureFetcher object to fetch node features.
      # [Role]:
      # Initialize a feature fetcher for fetching features of the sampled
      # subgraphs. This step is skipped in evaluation/inference because features
      # are updated as a whole during it, thus storing features in minibatch is
      # unnecessary.
      ############################################################################
      if is_train:
          datapipe = datapipe.fetch_feature(
              features, node_feature_keys=["feat"]
          )
  
      ############################################################################
      # [Input]:
      # 'device': The device to copy the data to.
      # [Output]:
      # A CopyTo object to copy the data to the specified device.
      ############################################################################
      if args.storage_device == "cpu":
          datapipe = datapipe.copy_to(device=args.device)
  
      ############################################################################
      # [Input]:
      # 'datapipe': The datapipe object to be used for data loading.
      # 'args.num_workers': The number of processes to be used for data loading.
      # [Output]:
      # A DataLoader object to handle data loading.
      # [Role]:
      # Initialize a multi-process dataloader to load the data in parallel.
      ############################################################################
      dataloader = gb.DataLoader(
          datapipe,
          num_workers=args.num_workers,
      )
  
      # Return the fully-initialized DataLoader object.
      return dataloader
  
imports: import argparse
  import time
  from functools import partial
  import dgl.graphbolt
  import dgl.nn
  import torch
  import torch.nn
  import torch.nn.functional
  import tqdm
  from ogb.linkproppred import Evaluator
label_desc: Use image node_id 1 for calling a global function with example usage: create_dataloader(args, graph, features, itemset, is_train) and returns: dataloader