code: def train(
      ctx: Context,
      role: Role,
      train_data: cpn.dataframe_input(roles=[GUEST, HOST]),
      validate_data: cpn.dataframe_input(
          roles=[GUEST, HOST], optional=True
      ),
      num_trees: cpn.parameter(
          type=params.conint(gt=0), default=3, desc="max tree num"
      ),
      learning_rate: cpn.parameter(
          type=params.confloat(gt=0),
          default=0.3,
          desc="decay factor of each tree",
      ),
      max_depth: cpn.parameter(
          type=params.conint(gt=0),
          default=3,
          desc="max depth of a tree",
      ),
      complete_secure: cpn.parameter(
          type=params.conint(ge=0),
          default=0,
          desc="number of trees to use guest features only in the complete secure mode, "
          "0 means no complete secure",
      ),
      max_bin: cpn.parameter(
          type=params.conint(gt=0),
          default=32,
          desc="max bin number of feature binning",
      ),
      objective: cpn.parameter(
          type=params.string_choice(
              choice=[BINARY_BCE, MULTI_CE, REGRESSION_L2]
          ),
          default=BINARY_BCE,
          desc="objective function, available: {}".format(
              [BINARY_BCE, MULTI_CE, REGRESSION_L2]
          ),
      ),
      num_class: cpn.parameter(
          type=params.conint(gt=0),
          default=2,
          desc="class number of multi classification, active when objective is {}".format(
              MULTI_CE
          ),
      ),
      goss: cpn.parameter(
          type=bool, default=False, desc="whether to use goss subsample"
      ),
      goss_start_iter: cpn.parameter(
          type=params.conint(ge=0),
          default=5,
          desc="start iteration of goss subsample",
      ),
      top_rate: cpn.parameter(
          type=params.confloat(gt=0, lt=1),
          default=0.2,
          desc="top rate of goss subsample",
      ),
      other_rate: cpn.parameter(
          type=params.confloat(gt=0, lt=1),
          default=0.1,
          desc="other rate of goss subsample",
      ),
      l1: cpn.parameter(
          type=params.confloat(ge=0),
          default=0,
          desc="L1 regularization",
      ),
      l2: cpn.parameter(
          type=params.confloat(ge=0),
          default=0.1,
          desc="L2 regularization",
      ),
      min_impurity_split: cpn.parameter(
          type=params.confloat(gt=0),
          default=1e-2,
          desc="min impurity when splitting a tree node",
      ),
      min_sample_split: cpn.parameter(
          type=params.conint(gt=0),
          default=2,
          desc="min sample to split a tree node",
      ),
      min_leaf_node: cpn.parameter(
          type=params.conint(gt=0),
          default=1,
          desc="mininum sample contained in a leaf node",
      ),
      min_child_weight: cpn.parameter(
          type=params.confloat(gt=0),
          default=1,
          desc="minumum hessian contained in a leaf node",
      ),
      gh_pack: cpn.parameter(
          type=bool,
          default=True,
          desc="whether to pack gradient and hessian together",
      ),
      split_info_pack: cpn.parameter(
          type=bool,
          default=True,
          desc="for host side, whether to pack split info together",
      ),
      hist_sub: cpn.parameter(
          type=bool,
          default=True,
          desc="whether to use histogram subtraction",
      ),
      he_param: cpn.parameter(
          type=params.he_param(),
          default=params.HEParam(kind="paillier", key_length=1024),
          desc="homomorphic encryption param, support paillier, ou and mock in current version",
      ),
      train_data_output: cpn.dataframe_output(
          roles=[GUEST, HOST], optional=True
      ),
      train_model_output: cpn.json_model_output(
          roles=[GUEST, HOST], optional=True
      ),
      train_model_input: cpn.json_model_input(
          roles=[GUEST, HOST], optional=True
      ),
  ):
      train_data = train_data.read()
      if validate_data is not None:
          validate_data = validate_data.read()
  
      if train_model_input is not None:
          train_model_input = train_model_input.read()
  
      if role.is_guest:
          # initialize encrypt kit
          ctx.cipher.set_phe(ctx.device, he_param.dict())
  
          booster = HeteroSecureBoostGuest(
              num_trees=num_trees,
              max_depth=max_depth,
              complete_secure=complete_secure,
              learning_rate=learning_rate,
              max_bin=max_bin,
              l1=l1,
              l2=l2,
              min_impurity_split=min_impurity_split,
              min_sample_split=min_sample_split,
              min_leaf_node=min_leaf_node,
              min_child_weight=min_child_weight,
              objective=objective,
              num_class=num_class,
              gh_pack=gh_pack,
              split_info_pack=split_info_pack,
              hist_sub=hist_sub,
              top_rate=top_rate,
              other_rate=other_rate,
              goss_start_iter=goss_start_iter,
              goss=goss,
          )
          if train_model_input:
              booster.from_model(train_model_input)
              logger.info(
                  "sbt input model loaded, will start warmstarting"
              )
          booster.fit(ctx, train_data, validate_data)
          # get cached train data score
          train_scores = booster.get_train_predict()
          train_scores = add_dataset_type(
              train_scores, consts.TRAIN_SET
          )
          train_data_output.write(train_scores)
          # get tree param
          tree_dict = booster.get_model()
          train_model_output.write(tree_dict, metadata={})
  
      elif role.is_host:
          booster = HeteroSecureBoostHost(
              num_trees=num_trees,
              max_depth=max_depth,
              complete_secure=complete_secure,
              max_bin=max_bin,
              hist_sub=hist_sub,
          )
          if train_model_input is not None:
              booster.from_model(train_model_input)
              logger.info(
                  "sbt input model loaded, will start warmstarting"
              )
          booster.fit(ctx, train_data, validate_data)
          tree_dict = booster.get_model()
          train_model_output.write(tree_dict, metadata={})
  
      else:
          raise RuntimeError(f"Unknown role: {role}")
  
file_path: FATE/python/fate/components/components/hetero_secureboost.py
imports: import logging
  from fate.arch.dataframe import DataFrame
  from fate.arch import Context
  from fate.components.core import GUEST, HOST, Role, cpn, params
  from fate.ml.ensemble import HeteroSecureBoostGuest, HeteroSecureBoostHost, BINARY_BCE, MULTI_CE, REGRESSION_L2
  from fate.components.components.utils.tools import add_dataset_type
  from fate.components.components.utils import consts
label_desc: Use image node_id 2 for calling a global function with example usage: train(ctx, role, train_data, validate_data, num_trees, learning_rate, max_depth, complete_secure, max_bin, objective, num_class, goss, goss_start_iter, top_rate, other_rate, l1, l2, min_impurity_split, min_sample_split, min_leaf_node, min_child_weight, gh_pack, split_info_pack, hist_sub, he_param, train_data_output, train_model_output, train_model_input) without return types