code: def _extract_hist(self, histogram, pack_info=None):
      tensor_hist: dict = histogram.extract_data()
      g_all, h_all, cnt_all = None, None, None
      for k, v in tensor_hist.items():
          cnt = v["cnt"].reshape((1, -1))
  
          # if gh pack
          if "gh" in v:
              g = v["gh"][::, 0].reshape((1, -1))
              h = v["gh"][::, 1].reshape((1, -1))
              if pack_info is None:
                  raise ValueError(
                      "must provide pack info for gh packing computing"
                  )
              g = g - pack_info["g_offset"] * cnt
          else:
              g = v["g"].reshape((1, -1))
              h = v["h"].reshape((1, -1))
  
          if g_all is None:
              g_all = g
          else:
              g_all = torch.vstack([g_all, g])
          if h_all is None:
              h_all = h
          else:
              h_all = torch.vstack([h_all, h])
          if cnt_all is None:
              cnt_all = cnt
          else:
              cnt_all = torch.vstack([cnt_all, cnt])
  
      return g_all, h_all, cnt_all
  
imports: import torch
  import numpy
  import logging
  from fate.arch.dataframe import DataFrame
  from fate.arch import Context
  from fate.arch.histogram import DistributedHistogram
label_desc: Use image node_id 7 for calling the SBTSplitter obj's underlying member method code with example usage: obj._extract_hist(histogram, pack_info) and returns: g_all,  h_all,  cnt_all