code: def get_parameters_for_gemm_common(
      lefts,
      rights,
      features,
      thresholds,
      values,
      n_features,
      extra_config={},
  ):
      """
      Common functions used by all tree algorithms to generate the parameters according to the GEMM strategy.
  
      Args:
          left: The left nodes
          right: The right nodes
          features: The features used in the decision nodes
          thresholds: The thresholds used in the decision nodes
          values: The values stored in the leaf nodes
          n_features: The number of expected input features
  
      Returns:
          The weights and bias for the GEMM implementation
      """
      values = np.array(values)
      weights = []
      biases = []
  
      if len(lefts) == 1:
          # Model creating trees with just a single leaf node. We transform it
          # to a model with one internal node.
          lefts = [1, -1, -1]
          rights = [2, -1, -1]
          features = [0, 0, 0]
          thresholds = [0, 0, 0]
          n_classes = values.shape[1]
          values = np.array(
              [
                  np.zeros(n_classes),
                  values.reshape(1),
                  values.reshape(1),
              ]
          )
          values.reshape(3, n_classes)
  
      # First hidden layer has all inequalities.
      hidden_weights = []
      hidden_biases = []
      for left, feature, thresh in zip(lefts, features, thresholds):
          if left != -1:
              hidden_weights.append(
                  [1 if i == feature else 0 for i in range(n_features)]
              )
              hidden_biases.append(thresh)
      weights.append(np.array(hidden_weights).astype("float32"))
      biases.append(np.array(hidden_biases, dtype=np.float64))
  
      n_splits = len(hidden_weights)
  
      # Second hidden layer has ANDs for each leaf of the decision tree.
      # Depth first enumeration of the tree in order to determine the AND by the path.
      hidden_weights = []
      hidden_biases = []
  
      path = [0]
      n_nodes = len(lefts)
      visited = [False for _ in range(n_nodes)]
  
      class_proba = []
      nodes = list(zip(lefts, rights, features, thresholds, values))
  
      while True and len(path) > 0:
          i = path[-1]
          visited[i] = True
          left, right, feature, threshold, value = nodes[i]
          if left == -1 and right == -1:
              vec = [0 for _ in range(n_splits)]
              # Keep track of positive weights for calculating bias.
              num_positive = 0
              for j, p in enumerate(path[:-1]):
                  num_leaves_before_p = list(lefts[:p]).count(-1)
                  if path[j + 1] in lefts:
                      vec[p - num_leaves_before_p] = 1
                      num_positive += 1
                  elif path[j + 1] in rights:
                      vec[p - num_leaves_before_p] = -1
                  else:
                      raise RuntimeError(
                          "Inconsistent state encountered while tree translation."
                      )
  
              if values.shape[-1] > 1:
                  proba = (values[i] / np.sum(values[i])).flatten()
              else:
                  # We have only a single value. e.g., GBDT
                  proba = values[i].flatten()
              # Some Sklearn tree implementations require normalization.
              if constants.NUM_TREES in extra_config:
                  proba /= extra_config[constants.NUM_TREES]
              class_proba.append(proba)
  
              hidden_weights.append(vec)
              hidden_biases.append(num_positive)
              path.pop()
          elif not visited[left]:
              path.append(left)
          elif not visited[right]:
              path.append(right)
          else:
              path.pop()
  
      weights.append(np.array(hidden_weights).astype("float32"))
      biases.append(np.array(hidden_biases).astype("float32"))
  
      # OR neurons from the preceding layer in order to get final classes.
      weights.append(
          np.transpose(np.array(class_proba).astype("float64"))
      )
      biases.append(None)
  
      return weights, biases
  
imports: import copy
  import numpy
  import torch
  from ._tree_implementations import TreeImpl
  from ._tree_implementations import GEMMDecisionTreeImpl, TreeTraversalDecisionTreeImpl, PerfectTreeTraversalDecisionTreeImpl
  from .None import constants
  from hummingbird.ml.exceptions import MissingConverter
label_desc: Use image node_id 8 for calling a global function with example usage: get_parameters_for_gemm_common(lefts, rights, features, thresholds, values, n_features, extra_config) and returns: weights,  biases