Repository navigation
summarize step: high peak memory from merging full tables #1124
Description
Summary
The summarize step can use a lot of memory on large models. Three things contribute:
- Wide merge. It merges
tripswithtours_mergedusing every column of both tables, although thesummarizespecs usually reference only a few of them. - Merged inputs. It takes
persons,persons_merged,households,households_mergedandtours_mergedas step inputs. The framework therefore builds the full merged tables before the step body runs, andpersonsis held twice (once on its own and once insidepersons_merged). - Temporaries. Every
summarize.csvrow whose Output starts with_stays inlocals_duntil the step ends. Many large temporaries therefore all stay in memory at the same time.
Observed
- For the Temporaries, a user reordering
summarize.csvso each temporary is deleted right after its last use did not change the peak—deleting temporaries cannot lower a peak that is set earlier in the Wide Merge. RSS sampling can also miss a short peak.
Run 1: Memory usage during summarize step, original version without any memory reduction helpers.
Run 2: Delete each Temporary right after its last use.
We can see a small reduction near the end of Run 2, which reflects the impact of deleting Temporaries. However, the peak memory did not reduce. The previous spikes happen during the Wide Merge.
Proposed Changes
_deldirective. An Output of_delin summarize.csv removes the named temporaries (comma-separated) from the expression namespace. The code change for this has been implemented in Implement deletion of temporary variables in summarize.py #1062. A unit test to confirm the deletion has been added in Implement deletion of temporary variables in summarize.py (reviewed) #1116.- Trim before merging. Drop columns from
tripsandtours_mergedthat no spec references, usingutil.drop_unused_columns. Column references come fromsummarize.csv, the preprocessor spec and theBIN/AGGREGATEsettings. Unsuffixed names are kept for any_trip/_tourreference so the merged column names don't change. Controlled by a newDROP_UNUSED_COLUMNSsetting (defaultTrue) and skipped whenEXPORT_PIPELINE_TABLESisTrue. A test checks that the output CSVs are identical with and without trimming.
Drafted code changes in #1125. Tested the memory reduction for Boston, see Run 3 below.
Run 3: Drop unused variables before wide merge of trips and tours
-
Possible follow-up (not implemented). Take the base tables as step inputs, select only the needed columns, and join them inside the step. This would avoid building the full
persons_merged,households_mergedandtours_mergedtables at all. It needs a way to know which source table each referenced column comes from, and the other users ofpersons_merged(for exampleshadow_pricing) must keep working. -
Chunking? Chunking with some additional engineering for
summarizemay help memory, but sometimes summaries do need to be calculated on the full dataset, otherwise the denominators would be incorrect.
Limitations
- Columns referenced through names built at runtime cannot be detected.
- The input tables are already loaded when the step starts, so trimming reduces the merge and later steps' memory, not the inputs themselves.
- Memory benefit depends on the data and the contents in the summarize.csv (how many summaries are being created).
Activity