Implement multiprocessing for the CVM model - #443
Conversation
|
@yueshuaing Just saw this PR and assigned myself as reviewer. |
Hi Susan, thanks for taking care of the reviewer assignment. I changed the PR ready for review. Please test run it and let me know if you run into any issues. |
|
@i-am-sijia , the PR is ready for your review. |
|
I implemented the multi‑process configuration in the SANDAG CVM model and verified that the runtime dropped from 3 hours to 35 minutes—an enormous improvement. I also compared the model output (final_trips.csv) from the single‑process and multi‑process versions of CVM. Files Compared:
I understood that the differences are expected and intentional. The multi-process CVM doesn't replicate the old single-process results because the old version had non-reproducible random number generation. Below is the detailed statistical analysis: 1. Trip Volume Differences
2. Vehicle Type Distribution
Key Insight: DRIVEALONE and HHDT vehicles increased while LHDT decreased slightly. The distribution percentages remained remarkably stable. 3. Time of Day (TOD) Distribution
Key Insight: Most additional trips occurred during Midday (MD) and Evening (EV) periods. 4. Trip Purpose DistributionOrigin Purpose
Key Insight: Significant increase in goods_delivery trips (+1,677), partially offset by reduction in maintenance trips (-493). Destination Type
5. Performance Metrics Summary - System-Wide Totals
Critical Finding: Despite slightly less total travel time, File 2 costs $1.18 million more due to additional trips and different route patterns. |
|
Thank you @JiaXu1024 for the comprehensive comparisons! Quick questions: Do we have a new single process run to compare with the multi process run to confirm they have the same results? I think they should. Are we using the same inputs including skims as the old single process run? Can some of the difference be because of the differences in inputs? |
| random_order = state.get_rn_generator().random_for_df(df) | ||
|
|
||
| random_dwell_times = scipy.stats.beta.ppf( | ||
| random_order[:,0], |
There was a problem hiding this comment.
@yueshuaing @i-am-sijia Just wanna confirm if this section of code change fixes the issue of non-reproducible random number generation?
There was a problem hiding this comment.
Hi Susan, yes, we removed the previous global random draw np.random.seed(seed=42), as in multiprocessing this code runs in each of the process, seed to the same draw. And the previous scipy.stats.beta.rvs() function draws a batch of len(df) random numbers, assigns them to the row based on its position, so reproducibility now depends on df's row order being identical every time which is not guaranteed in multiprocessing. So we switched to the ActivitySim's reproducible method state.get_rn_generator().random_for_df(df) from SimpleChannel
There was a problem hiding this comment.
Hi @yueshuaing , thanks for the clarification. So the previous global random‑draw settings in the single‑process setup didn’t have any issues, right?
There was a problem hiding this comment.
Yes, the code wasn't broken in the single-process cause the single-process processes the same data in the same order every time. The issue only appears when introducing multiprocessing, which became not reproducible between single vs multi process.
Proposed changes
This PR adds multiprocessing to the existing commercial vehicle model (CVM). The main changes include: adding a multiprocessing configuration to the settings, registering CVM tables with the RNG channel, table checkpointing, and using reproducible random draws so that multiprocess output is correct and consistent.
Impact
All output tables now match exactly between the old single-process and the new multiprocess runs, except
cv_trips. This is because the old single-process implementation used global random draws inroute_stopsthat weren't fully reproducible. The difference versus the old baseline is small, about 0.14% of total trips, with differences in OD pairs with 0-10 trips. With this PR, single-process and multiprocess results are consistent with each other.Multiple runs were tested on a 512 GB memory, 64 process machine. Performance is as follows:
Types of changes
What types of changes does your code introduce to ABM?
Put an
xin the boxes that applyHow has this been tested?
Please describe the tests that you ran to verify your changes.
Checklist:
Further comments
If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did and what alternatives you considered, etc...