docstr: Conduct layer-wise inference to get all the node embeddings.
docstr_tok: ["Conduct","layer-wise","inference","to","get","all","the","node","embeddings","."]
code: def inference(self, graph, features, dataloader, device):
      """Conduct layer-wise inference to get all the node embeddings."""
      feature = features.read("node", None, "feat")
  
      buffer_device = torch.device("cpu")
      # Enable pin_memory for faster CPU to GPU data transfer if the
      # model is running on a GPU.
      pin_memory = buffer_device != device
  
      for layer_idx, layer in enumerate(self.layers):
          is_last_layer = layer_idx == len(self.layers) - 1
  
          y = torch.empty(
              graph.total_num_nodes,
              self.out_size if is_last_layer else self.hidden_size,
              dtype=torch.float32,
              device=buffer_device,
              pin_memory=pin_memory,
          )
          feature = feature.to(device)
  
          for step, data in tqdm(enumerate(dataloader)):
              x = feature[data.input_nodes]
              hidden_x = layer(data.blocks[0], x)  # len(blocks) = 1
              if not is_last_layer:
                  hidden_x = F.relu(hidden_x)
                  hidden_x = self.dropout(hidden_x)
              # By design, our output nodes are contiguous.
              y[
                  data.seed_nodes[0] : data.seed_nodes[-1] + 1
              ] = hidden_x.to(buffer_device)
          feature = y
  
      return y
  
imports: import argparse
  import time
  import dgl.graphbolt
  import dgl.nn
  import torch
  import torch.nn
  import torch.nn.functional
  import torchmetrics.functional
  from tqdm import tqdm
label_desc: Use image node_id 4 for calling the SAGE obj's underlying member method code with example usage: obj.inference(graph, features, dataloader, device) and returns: y