class_docstr: The implementation of super-net cell follows `DARTS <https://github.com/quark0/darts>`__.
  
  When ``factory_used`` is true, it reconstructs the cell for every possible combination of operation and input index,
  because for different input index, the cell factory could instantiate different operations (e.g., with different stride).
  On export, we first have best (operation, input) pairs, the select the best ``num_ops_per_node``.
  
  ``loose_end`` is not supported yet, because it will cause more problems (e.g., shape mismatch).
  We assumes ``loose_end`` to be ``all`` regardless of its configuration.
  
  A supernet cell can't slim its own weight to fit into a sub network, which is also a known issue.
class_docstr_tok: ["The","implementation","of","super-net","cell","follows","`","DARTS","<","https",":","\/\/github.com\/quark0\/darts",">","`","__",".","When","``","factory_used","``","is","true",",","it","reconstructs","the","cell","for","every","possible","combination","of","operation","and","input","index",",","because","for","different","input","index",",","the","cell","factory","could","instantiate","different","operations","(","e.g.",",","with","different","stride",")",".","On","export",",","we","first","have","best","(","operation",",","input",")","pairs",",","the","select","the","best","``","num_ops_per_node","``",".","``","loose_end","``","is","not","supported","yet",",","because","it","will","cause","more","problems","(","e.g.",",","shape","mismatch",")",".","We","assumes","``","loose_end","``","to","be","``","all","``","regardless","of","its","configuration",".","A","supernet","cell","ca","n't","slim","its","own","weight","to","fit","into","a","sub","network",",","which","is","also","a","known","issue","."]
code: def __init__(
      self,
      op_factory: list[CellOpFactory] | dict[str, CellOpFactory],
      num_nodes: int,
      num_ops_per_node: int,
      num_predecessors: int,
      preprocessor: Any,
      postprocessor: Any,
      concat_dim: int,
      memo: dict,  # although not used here, useful in subclass
      mutate_kwargs: dict,  # same as memo
      label: str,
  ):
      super().__init__()
      self.num_nodes = num_nodes
      self.num_ops_per_node = num_ops_per_node
      self.num_predecessors = num_predecessors
      self.preprocessor = preprocessor
      self.ops = nn.ModuleList()
      self.postprocessor = postprocessor
      self.concat_dim = concat_dim
      self.op_names: list[str] = cast(List[str], None)
      self.output_node_indices = list(
          range(
              self.num_predecessors,
              self.num_nodes + self.num_predecessors,
          )
      )
  
      # Create a fully-connected graph.
      # Each edge is a ModuleDict with op candidates.
      # Can not reuse LayerChoice here, because the spec, resample, export all need to be customized.
      # InputChoice is implicit in this graph.
      for i in self.output_node_indices:
          self.ops.append(nn.ModuleList())
          for k in range(i):
              # Second argument in (i, **0**, k) is always 0.
              # One-shot strategy can't handle the cases where op spec is dependent on `op_index`.
              ops, _ = create_cell_op_candidates(op_factory, i, 0, k)
              self.op_names = list(ops.keys())
              cast(nn.ModuleList, self.ops[-1]).append(
                  nn.ModuleDict(ops)
              )
  
      with label_scope(label) as self.label_scope:
          for i in range(
              self.num_predecessors,
              self.num_nodes + self.num_predecessors,
          ):
              for k in range(self.num_ops_per_node):
                  op_label = f"op_{i}_{k}"
                  input_label = f"input_{i}_{k}"
                  self.add_mutable(
                      Categorical(self.op_names, label=op_label)
                  )
                  # Need multiple here to align with the original cell.
                  self.add_mutable(
                      CategoricalMultiple(
                          range(i), n_chosen=1, label=input_label
                      )
                  )
  
      self._sampled: dict[str, str | int] = {}
  
imports: from __future__ import annotations
  import copy
  import functools
  import random
  from typing import Any, List, Dict, Sequence, cast
  import torch
  import torch.nn
  from nni.mutable import MutableExpression, label_scope, Mutable, Categorical, CategoricalMultiple
  from nni.nas.nn.pytorch import LayerChoice, InputChoice, Repeat, Cell
  from nni.nas.nn.pytorch.cell import CellOpFactory, create_cell_op_candidates, preprocess_cell_inputs
  from .base import BaseSuperNetModule
  from ._expression_utils import weighted_sum
  from .operation import MixedOperationSamplingPolicy, MixedOperation
label_desc: Use image node_id 1 to create a new PathSamplingCell object from inherited base classes: BaseSuperNetModule with example: obj = PathSamplingCell(op_factory, num_nodes, num_ops_per_node, num_predecessors, preprocessor, postprocessor, concat_dim, memo, mutate_kwargs, label)