docstr: Inference with the GraphSAGE model on full neighbors (i.e. without
  neighbor sampling).
  
  g : the entire graph.
  x : the input of entire node set.
  
  The inference code is written in a fashion that it could handle any
  number of nodes and layers.
docstr_tok: ["Inference","with","the","GraphSAGE","model","on","full","neighbors","(","i.e",".","without","neighbor","sampling",")",".","g",":","the","entire","graph",".","x",":","the","input","of","entire","node","set",".","The","inference","code","is","written","in","a","fashion","that","it","could","handle","any","number","of","nodes","and","layers","."]
code: def inference(self, g, x, batch_size, device):
      """
      Inference with the GraphSAGE model on full neighbors (i.e. without
      neighbor sampling).
  
      g : the entire graph.
      x : the input of entire node set.
  
      The inference code is written in a fashion that it could handle any
      number of nodes and layers.
      """
      # During inference with sampling, multi-layer blocks are very
      # inefficient because lots of computations in the first few layers are
      # repeated. Therefore, we compute the representation of all nodes layer
      # by layer.  The nodes on each layer are of course splitted in batches.
      # TODO: can we standardize this?
      nodes = dgl.distributed.node_split(
          np.arange(g.num_nodes()),
          g.get_partition_book(),
          force_even=True,
      )
      y = dgl.distributed.DistTensor(
          (g.num_nodes(), self.n_hidden),
          th.float32,
          "h",
          persistent=True,
      )
      for i, layer in enumerate(self.layers):
          if i == len(self.layers) - 1:
              y = dgl.distributed.DistTensor(
                  (g.num_nodes(), self.n_classes),
                  th.float32,
                  "h_last",
                  persistent=True,
              )
          # Create sampler
          sampler = dgl.dataloading.NeighborSampler([-1])
          # Create dataloader
          dataloader = dgl.dataloading.DistNodeDataLoader(
              g,
              nodes,
              sampler,
              batch_size=batch_size,
              shuffle=False,
              drop_last=False,
          )
  
          for input_nodes, output_nodes, blocks in tqdm.tqdm(
              dataloader
          ):
              block = blocks[0].to(device)
              h = x[input_nodes].to(device)
              h_dst = h[: block.number_of_dst_nodes()]
              h = layer(block, (h, h_dst))
              if i != len(self.layers) - 1:
                  h = self.activation(h)
                  h = self.dropout(h)
  
              y[output_nodes] = h.cpu()
  
          x = y
          g.barrier()
      return y
  
imports: import argparse
  import time
  from contextlib import contextmanager
  import numpy
  import sklearn.linear_model
  import sklearn.metrics
  import torch
  import torch.nn
  import torch.nn.functional
  import torch.optim
  import tqdm
  import dgl
  import dgl.function
  import dgl.nn.pytorch
label_desc: Use image node_id 3 for calling the DistSAGE obj's underlying member method code with example usage: obj.inference(g, x, batch_size, device) and returns: y