code: def predict(
      ctx: Context,
      role: Role,
      test_data: cpn.dataframe_input(roles=[GUEST, HOST]),
      input_model: cpn.json_model_input(roles=[GUEST, HOST]),
      test_output_data: cpn.dataframe_output(roles=[GUEST, HOST]),
  ):
      from fate.ml.feature_selection import (
          HeteroSelectionModuleGuest,
          HeteroSelectionModuleHost,
      )
  
      logger.info(f"start selection predict")
      sub_ctx = ctx.sub_ctx("predict")
      model = input_model.read()
      if role.is_guest:
          selection = HeteroSelectionModuleGuest.from_model(model)
      elif role.is_host:
          selection = HeteroSelectionModuleHost.from_model(model)
      else:
          raise ValueError(f"role: {role} is not valid")
  
      test_data = test_data.read()
  
      output_data = test_data
      if selection.method is not None:
          output_data = selection.transform(sub_ctx, test_data)
      test_output_data.write(output_data)
  
imports: import logging
  from typing import List
  from fate.arch import Context
  from fate.components.core import GUEST, HOST, Role, cpn, params
label_desc: Use image node_id 3 for calling a global function with example usage: predict(ctx, role, test_data, input_model, test_output_data) without return types