diff --git a/.github/workflows/core_tests.yml b/.github/workflows/core_tests.yml index 8e659b25c..3e4fd52f9 100644 --- a/.github/workflows/core_tests.yml +++ b/.github/workflows/core_tests.yml @@ -130,6 +130,7 @@ jobs: - run: uv run pytest test/test_skim_name_conflicts.py - run: uv run pytest test/random_seed/test_random_seed.py + - run: uv run pytest test/trace_id/test_trace_id.py builtin_regional_models: needs: foundation diff --git a/activitysim/cli/run.py b/activitysim/cli/run.py index af9a76daa..a1b23048c 100644 --- a/activitysim/cli/run.py +++ b/activitysim/cli/run.py @@ -9,11 +9,14 @@ import sys import warnings from datetime import datetime +import struct +import time import numpy as np from activitysim.core import chunk, config, mem, timing, tracing, workflow from activitysim.core.configuration import FileSystem, Settings +from activitysim.core.run_id import RunId from activitysim.abm.models.settings_checker import check_model_settings @@ -29,6 +32,7 @@ "settings_file_name", "imported_extensions", "run_timestamp", + "run_id", ] @@ -161,6 +165,8 @@ def inject_arg(name, value): # 'configs', 'data', and 'output' folders by default os.chdir(args.working_dir) + inject_arg("run_id", state.tracing.run_id) + if args.ext: for e in args.ext: basepath, extpath = os.path.split(e) @@ -268,6 +274,7 @@ def run(args): """ state = workflow.State() + _init_run_id = state.tracing.run_id # register abm steps and other abm-specific injectables # by default, assume we are running activitysim.abm diff --git a/activitysim/core/configuration/top.py b/activitysim/core/configuration/top.py index 405560810..a6c29269a 100644 --- a/activitysim/core/configuration/top.py +++ b/activitysim/core/configuration/top.py @@ -2,6 +2,8 @@ from pathlib import Path from typing import Any, Literal +import struct +import time from pydantic import model_validator, validator diff --git a/activitysim/core/mp_tasks.py b/activitysim/core/mp_tasks.py index 42b1ab444..f54e2f8d2 100644 --- a/activitysim/core/mp_tasks.py +++ b/activitysim/core/mp_tasks.py @@ -19,6 +19,7 @@ from activitysim.core import config, mem, tracing, util, workflow from activitysim.core.configuration import FileSystem, Settings +from activitysim.core.run_id import RunId from activitysim.core.workflow.checkpoint import ( CHECKPOINT_NAME, CHECKPOINT_TABLE_NAME, @@ -890,6 +891,10 @@ def setup_injectables_and_logging(injectables, locutor: bool = True) -> workflow injects injectables """ state = workflow.State() + _run_id = injectables.get("run_id", None) + if _run_id: + state.tracing.run_id = RunId(_run_id) + state = state.initialize_filesystem(**injectables) state.settings = injectables.get("settings", Settings()) state.filesystem.parse_settings(state.settings) diff --git a/activitysim/core/run_id.py b/activitysim/core/run_id.py new file mode 100644 index 000000000..a5d4ea1c8 --- /dev/null +++ b/activitysim/core/run_id.py @@ -0,0 +1,11 @@ +import struct +import time + + +class RunId(str): + def __new__(cls, x=None): + if x is None: + return cls( + hex(struct.unpack("