class_docstr: HistogramIndexer is used to index the `VectorizedHistogram` data.
  
  The data is stored in a flatten array with the shape is (num_node * sum(feature_bin_sizes)) and the
  data is indexed by (node_id, feature_id, bin_id) in the flatten array.
  At logical level, the data is indexed by (node_id, feature_id, bin_id) likes:
  
  node_id_0:
      feature_id_0:
          bin_id_0: data
          bin_id_1: data
          ...
      feature_id_1:
          bin_id_0: data
          bin_id_1: data
          ...
      ...
  node_id_1:
      feature_id_0:
          bin_id_0: data
          bin_id_1: data
          ...
      feature_id_1:
          bin_id_0: data
          bin_id_1: data
          ...
      ...
  ...
  notice that the data is stored in the flatten array, so the index is calculated by:
      position = node_id * sum(feature_bin_sizes) + feature_bin_sizes[feature_id] + bin_id
  
  which means the bin_size of each feature is not necessary to be the same but the sum of all feature_bin_sizes
  should be the same.
  
  Notes: This class will be rewritten in rust in the future.
docstr: get data positions by node_ids and bin_ids
  Args:
      nids: node ids
      bids: bin ids
  
  Returns: data positions
docstr_tok: ["get","data","positions","by","node_ids","and","bin_ids","Args",":","nids",":","node","ids","bids",":","bin","ids","Returns",":","data","positions"]
code: def get_positions(self, nids: List[int], bids: List[List[int]]):
      """
      get data positions by node_ids and bin_ids
      Args:
          nids: node ids
          bids: bin ids
  
      Returns: data positions
      """
      positions = []
      assert len(nids) == len(
          bids
      ), f"nids length {len(nids)} is not equal to bids length {len(bids)}"
      for nid, bids in zip(nids, bids):
          positions.append(
              [
                  self.get_position(nid, fid, bid)
                  for fid, bid in enumerate(bids)
              ]
          )
      return positions
  
imports: from typing import List, Tuple, Dict
  import numpy
  import torch
label_desc: Use image node_id 6 for calling the HistogramIndexer obj's underlying member method code with example usage: obj.get_positions(nids, bids) and returns: positions