class_docstr: Net3D is a 3D graph neural network that expects a DGL graph input with 3D coordinates stored under the name 'd' and node features stored under the name 'feat'. It is based on the 3D Infomax architecture [1].
  
  Parameters
  ----------
  hidden_dim : int
      The dimension of the hidden layers.
  target_dim : int
      The dimension of the output layer.
  readout_aggregators : List[str]
      A list of aggregator functions for the readout layer. Options are 'sum', 'max', 'min', 'mean'.
  batch_norm : bool, optional (default=False)
      Whether to use batch normalization.
  node_wise_output_layers : int, optional (default=2)
      The number of output layers for each node.
  readout_batchnorm : bool, optional (default=True)
      Whether to use batch normalization in the readout layer.
  batch_norm_momentum : float, optional (default=0.1)
      The momentum for the batch normalization layers.
  reduce_func : str, optional (default='sum')
      The reduce function to use for aggregating messages.
  dropout : float, optional (default=0.0)
      The dropout rate for the layers.
  propagation_depth : int, optional (default=4)
      The number of propagation layers in the network.
  readout_layers : int, optional (default=2)
      The number of readout layers in the network.
  readout_hidden_dim : int, optional (default=None)
      The dimension of the hidden layers in the readout network.
  fourier_encodings : int, optional (default=0)
      The number of Fourier encodings to use.
  activation : str, optional (default='SiLU')
      The activation function to use in the network.
  update_net_layers : int, optional (default=2)
      The number of update network layers.
  message_net_layers : int, optional (default=2)
      The number of message network layers.
  use_node_features : bool, optional (default=False)
      Whether to use node features as input.
  
  Examples
  --------
  >>> from deepchem.feat.molecule_featurizers.conformer_featurizer import RDKitConformerFeaturizer
  >>> from deepchem.models.torch_models.gnn3d import Net3D
  >>> smiles = ["C[C@H](F)Cl", "C[C@@H](F)Cl"]
  >>> featurizer = RDKitConformerFeaturizer()
  >>> data = featurizer.featurize(smiles)
  >>> dgldata = [[graph.to_dgl_graph() for graph in conf] for conf in data]
  >>> net3d = Net3D(hidden_dim=3, target_dim=2, readout_aggregators=['sum', 'mean'])
  >>> output = [[net3d(graph) for graph in conf] for conf in dgldata]
  
  References
  ----------
  .. [1] Stärk, H. et al. 3D Infomax improves GNNs for Molecular Property Prediction. Preprint at https://doi.org/10.48550/arXiv.2110.04126 (2022).
docstr: Forward pass of the Net3D model.
  
  Parameters
  ----------
  graph : dgl.DGLGraph
      The input graph with node features stored under the key 'x' and edge distances stored under the key 'd'.
  
  Returns
  -------
  torch.Tensor
      The graph representation tensor of shape (1, target_dim).
docstr_tok: ["Forward","pass","of","the","Net3D","model",".","Parameters","--","--","--","--","--","graph",":","dgl.DGLGraph","The","input","graph","with","node","features","stored","under","the","key","'","x","'","and","edge","distances","stored","under","the","key","'d","'",".","Returns","--","--","--","-","torch.Tensor","The","graph","representation","tensor","of","shape","(","1",",","target_dim",")","."]
code: def forward(self, graph: dgl.DGLGraph):
      """
      Forward pass of the Net3D model.
  
      Parameters
      ----------
      graph : dgl.DGLGraph
          The input graph with node features stored under the key 'x' and edge distances stored under the key 'd'.
  
      Returns
      -------
      torch.Tensor
          The graph representation tensor of shape (1, target_dim).
      """
      if self.use_node_features:
          graph.ndata["feat"] = self.atom_encoder(graph.ndata["x"])
      else:
          graph.ndata["feat"] = self.node_embedding[None, :].expand(
              graph.number_of_nodes(), -1
          )
  
      if self.fourier_encodings > 0:
          graph.edata["d"] = fourier_encode_dist(
              graph.edata["d"], num_encodings=self.fourier_encodings
          )
      graph.apply_edges(self.input_edge_func)
  
      for mp_layer in self.mp_layers:
          graph = mp_layer(graph)
  
      if self.node_wise_output_layers > 0:
          graph.apply_nodes(self.output_node_func)
  
      readouts_to_cat = [
          dgl.readout_nodes(graph, "feat", op=aggr)
          for aggr in self.readout_aggregators
      ]
      readout = torch.cat(readouts_to_cat, dim=-1)
      return self.output(readout.squeeze())
  
imports: import itertools
  from typing import Callable, List, Union, Literal, Optional
  import dgl
  import dgl.function
  import torch
  from torch import nn
  from torch.nn import functional
  from deepchem.models.losses import NTXentMultiplePositives
  from deepchem.models.torch_models import ModularTorchModel
  from deepchem.models.torch_models.layers import MultilayerPerceptron
  from deepchem.models.torch_models.pna_gnn import PNA, AtomEncoder
  from deepchem.utils.graph_utils import fourier_encode_dist
label_desc: Use image node_id 2 for calling the Net3D obj's underlying member method code with example usage: obj.forward(graph) and returns: self