From 8dc8ca46df2e3c694e1c84944c01f2bb7c492887 Mon Sep 17 00:00:00 2001 From: Vincent Gong Date: Tue, 14 Jul 2026 17:04:34 +0200 Subject: [PATCH] Support explicit_chunk for mode-choice components Location, destination, and scheduling components already honor the `explicit_chunk` setting (a fixed chunk size, used when chunk_training_mode: explicit), but mode-choice components did not: the setting was never plumbed from the component settings into simple_simulate's chunk loop. This wires it through: add `explicit_chunk` to TemplatedLogitComponentSettings (the base for mode-choice settings), and pass it via mode_choice_simulate -> simple_simulate -> adaptive_chunked_choosers. Defaults to 0 (unchanged behavior). This lets tour_mode_choice and trip_mode_choice run with a fixed, bounded per-chunk memory footprint, which is what makes large samples fit on memory-constrained machines under chunk_training_mode: explicit. --- activitysim/abm/models/trip_mode_choice.py | 1 + activitysim/abm/models/util/mode.py | 3 +++ activitysim/core/configuration/logit.py | 8 ++++++++ activitysim/core/simulate.py | 5 ++++- 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/activitysim/abm/models/trip_mode_choice.py b/activitysim/abm/models/trip_mode_choice.py index f7c20800f7..4aad9dda62 100644 --- a/activitysim/abm/models/trip_mode_choice.py +++ b/activitysim/abm/models/trip_mode_choice.py @@ -228,6 +228,7 @@ def trip_mode_choice( trace_choice_name="trip_mode_choice", estimator=estimator, compute_settings=model_settings.compute_settings, + explicit_chunk_size=model_settings.explicit_chunk, ) if state.settings.trace_hh_id: diff --git a/activitysim/abm/models/util/mode.py b/activitysim/abm/models/util/mode.py index d82dd09ea8..22b32dccbe 100644 --- a/activitysim/abm/models/util/mode.py +++ b/activitysim/abm/models/util/mode.py @@ -36,6 +36,7 @@ def mode_choice_simulate( trace_column_names=None, estimator: Optional[Estimator] = None, compute_settings: ComputeSettings | None = None, + explicit_chunk_size: float = 0, ): """ common method for both tour_mode_choice and trip_mode_choice @@ -74,6 +75,7 @@ def mode_choice_simulate( estimator=estimator, trace_column_names=trace_column_names, compute_settings=compute_settings, + explicit_chunk_size=explicit_chunk_size, ) # for consistency, always return dataframe, whether or not logsums were requested @@ -176,6 +178,7 @@ def run_tour_mode_choice_simulate( trace_column_names=trace_column_names, estimator=estimator, compute_settings=model_settings.compute_settings, + explicit_chunk_size=model_settings.explicit_chunk, ) return choices diff --git a/activitysim/core/configuration/logit.py b/activitysim/core/configuration/logit.py index a1c305e532..0561c4b0d7 100644 --- a/activitysim/core/configuration/logit.py +++ b/activitysim/core/configuration/logit.py @@ -200,6 +200,14 @@ class TemplatedLogitComponentSettings(LogitComponentSettings, extra="forbid"): segment-specific names. """ + explicit_chunk: float = 0 + """ + If > 0, use this fixed chunk size (number of chooser rows) instead of adaptive + chunking. If less than 1, use this fraction of the total number of rows. Plumbed + through mode_choice_simulate -> simple_simulate so mode-choice models can be chunked + (default 0 = unchanged chunkless/adaptive behavior). + """ + class LocationComponentSettings(BaseLogitComponentSettings): """ diff --git a/activitysim/core/simulate.py b/activitysim/core/simulate.py index 3f4ff0d309..7293d180e4 100644 --- a/activitysim/core/simulate.py +++ b/activitysim/core/simulate.py @@ -1719,6 +1719,7 @@ def simple_simulate( trace_choice_name=None, trace_column_names=None, compute_settings: ComputeSettings | None = None, + explicit_chunk_size: float = 0, ): """ Run an MNL or NL simulation for when the model spec does not involve alternative @@ -1737,7 +1738,9 @@ def simple_simulate( chooser_chunk, chunk_trace_label, chunk_sizer, - ) in chunk.adaptive_chunked_choosers(state, choosers, trace_label): + ) in chunk.adaptive_chunked_choosers( + state, choosers, trace_label, explicit_chunk_size=explicit_chunk_size + ): choices = _simple_simulate( state, chooser_chunk,