code: def test_early_stopping(early_stop, tmp_path):
      (
          input_features,
          output_features,
      ) = synthetic_test_data.get_feature_configs()
  
      config = {
          "input_features": input_features,
          "output_features": output_features,
          "combiner": {"type": "concat"},
          TRAINER: {
              "epochs": 75,
              "early_stop": early_stop,
              "batch_size": 16,
          },
      }
  
      # create sub-directory to store results
      results_dir = tmp_path / "results"
      results_dir.mkdir()
  
      # run experiment
      generated_data = synthetic_test_data.get_generated_data()
      _, _, _, _, output_dir = experiment_cli(
          training_set=generated_data.train_df,
          validation_set=generated_data.validation_df,
          test_set=generated_data.test_df,
          output_directory=str(results_dir),
          config=config,
          skip_save_processed_input=True,
          skip_save_progress=True,
          skip_save_unprocessed_output=True,
          skip_save_model=True,
          skip_save_log=True,
      )
  
      # test existence of required files
      train_stats_fp = os.path.join(
          output_dir, "training_statistics.json"
      )
      metadata_fp = os.path.join(output_dir, DESCRIPTION_FILE_NAME)
      assert os.path.isfile(train_stats_fp)
      assert os.path.isfile(metadata_fp)
  
      # retrieve results so we can validate early stopping
      with open(train_stats_fp) as f:
          train_stats = json.load(f)
      with open(metadata_fp) as f:
          metadata = json.load(f)
  
      # get early stopping value
      early_stop_value = metadata["config"][TRAINER]["early_stop"]
  
      # retrieve validation losses
      vald_losses_data = train_stats["validation"]["combined"]["loss"]
  
      last_evaluation = len(vald_losses_data) - 1
      best_evaluation = np.argmin(vald_losses_data)
  
      assert last_evaluation - best_evaluation == early_stop_value
  
imports: import json
  import logging
  import os.path
  import re
  import numpy
  import pandas
  import pytest
  import torch
  from ludwig import globals
  from ludwig.api import LudwigModel
  from ludwig.backend import LOCAL_BACKEND
  from ludwig.constants import BATCH_SIZE, CATEGORY, DEFAULTS, EPOCHS, INPUT_FEATURES, OUTPUT_FEATURES, PREPROCESSING, TRAINER, TRAINING
  from ludwig.contribs.mlflow import MlflowCallback
  from ludwig.experiment import experiment_cli
  from ludwig.features.number_feature import numeric_transformation_registry
  from ludwig.globals import DESCRIPTION_FILE_NAME, TRAINING_PREPROC_FILE_NAME
  from ludwig.schema.optimizers import optimizer_registry
  from ludwig.utils.data_utils import load_json, replace_file_extension
  from ludwig.utils.misc_utils import get_from_registry
  from ludwig.utils.package_utils import LazyLoader
  from tests.integration_tests import synthetic_test_data
  from tests.integration_tests.utils import category_feature, generate_data, LocalTestBackend
label_desc: Use image node_id 1 for calling a global function with example usage: test_early_stopping(early_stop, tmp_path) without return types