code: def test_lightgbm(
      train_device, infer_device, tmp_path, num_classes, n_categorical
  ):
      import lightgbm as lgb
  
      if n_categorical > 0:
          n_features = 10
          n_rows = 1000
          n_informative = n_features
      else:
          n_features = 10 if num_classes == 2 else 50
          n_rows = 500
          n_informative = "auto"
  
      X, y = simulate_data(
          n_rows,
          n_features,
          num_classes,
          n_informative=n_informative,
          random_state=43210,
          classification=True,
      )
      if n_categorical > 0:
          X_fit, X_predict = to_categorical(
              X,
              n_categorical=n_categorical,
              invalid_frac=0.1,
              random_state=43210,
          )
      else:
          X_fit, X_predict = X, X
  
      train_data = lgb.Dataset(X_fit, label=y)
      num_round = 5
      model_path = str(os.path.join(tmp_path, "lgb.model"))
  
      if num_classes == 2:
          param = {
              "objective": "binary",
              "metric": "binary_logloss",
              "num_class": 1,
          }
          bst = lgb.train(param, train_data, num_round)
          bst.save_model(model_path)
          with using_device_type(train_device):
              fm = ForestInference.load(
                  model_path, output_class=True, model_type="lightgbm"
              )
          # binary classification
          gbm_proba = bst.predict(X_predict)
          with using_device_type(infer_device):
              fil_proba = fm.predict_proba(X_predict)[:, 0]
              gbm_preds = (gbm_proba > 0.5).astype(float)
              fil_preds = fm.predict(X_predict)[:, 0]
          assert array_equal(gbm_preds, fil_preds)
          np.testing.assert_allclose(
              gbm_proba, fil_proba, atol=proba_atol[num_classes > 2]
          )
      else:
          # multi-class classification
          lgm = lgb.LGBMClassifier(
              objective="multiclass",
              boosting_type="gbdt",
              n_estimators=num_round,
          )
          lgm.fit(X_fit, y)
          lgm.booster_.save_model(model_path)
          lgm_preds = lgm.predict(X_predict).astype(int)
          with using_device_type(train_device):
              fm = ForestInference.load(
                  model_path, output_class=True, model_type="lightgbm"
              )
          assert array_equal(
              lgm.booster_.predict(X_predict).argmax(axis=1), lgm_preds
          )
          with using_device_type(infer_device):
              assert array_equal(lgm_preds, fm.predict(X_predict))
              # lightgbm uses float64 thresholds, while FIL uses float32
              np.testing.assert_allclose(
                  lgm.predict_proba(X_predict),
                  fm.predict_proba(X_predict),
                  atol=proba_atol[num_classes > 2],
              )
  
imports: import numpy
  import pytest
  import os
  import pandas
  from math import ceil
  from cuml.experimental import ForestInference
  from cuml.testing.utils import array_equal, unit_param, quality_param, stress_param
  from cuml.internals.import_utils import has_lightgbm, has_xgboost
  from cuml.common.device_selection import using_device_type
  from sklearn.datasets import make_classification, make_regression
  from sklearn.ensemble import GradientBoostingClassifier, GradientBoostingRegressor, RandomForestClassifier, RandomForestRegressor, ExtraTreesClassifier, ExtraTreesRegressor
  from sklearn.metrics import accuracy_score, mean_squared_error
  from sklearn.model_selection import train_test_split
  import treelite
label_desc: Use image node_id 12 for calling a global function with example usage: test_lightgbm(train_device, infer_device, tmp_path, num_classes, n_categorical) without return types