diff --git a/examples/a2a3/tensormap_and_ringbuffer/benchmark_bgemm/test_benchmark_bgemm.py b/examples/a2a3/tensormap_and_ringbuffer/benchmark_bgemm/test_benchmark_bgemm.py index b9bf56496d..e1eed90527 100644 --- a/examples/a2a3/tensormap_and_ringbuffer/benchmark_bgemm/test_benchmark_bgemm.py +++ b/examples/a2a3/tensormap_and_ringbuffer/benchmark_bgemm/test_benchmark_bgemm.py @@ -52,41 +52,35 @@ class TestBenchmarkBgemm(SceneTestCase): { "name": "Case0", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {"matmul_add_task_num": 500, "incore_data_size": 128, "incore_loop": 4, "grid_k": 2}, }, { "name": "Case1", "manual": True, "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {"matmul_add_task_num": 64, "incore_data_size": 128, "incore_loop": 4, "grid_k": 2}, }, { "name": "Case2", "manual": True, "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {"matmul_add_task_num": 256, "incore_data_size": 128, "incore_loop": 4, "grid_k": 2}, }, { "name": "Case3", "manual": True, "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {"matmul_add_task_num": 64, "incore_data_size": 128, "incore_loop": 16, "grid_k": 2}, }, { "name": "Case4", "manual": True, "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {"matmul_add_task_num": 64, "incore_data_size": 128, "incore_loop": 4, "grid_k": 4}, }, { "name": "Bgemm64", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {"matmul_add_task_num": 32, "incore_data_size": 64, "incore_loop": 1, "grid_k": 4}, }, ] diff --git a/examples/a2a3/tensormap_and_ringbuffer/merge_pipeline_barrier/test_merge_pipeline_barrier.py b/examples/a2a3/tensormap_and_ringbuffer/merge_pipeline_barrier/test_merge_pipeline_barrier.py index 5424cd13be..70023db1c7 100644 --- a/examples/a2a3/tensormap_and_ringbuffer/merge_pipeline_barrier/test_merge_pipeline_barrier.py +++ b/examples/a2a3/tensormap_and_ringbuffer/merge_pipeline_barrier/test_merge_pipeline_barrier.py @@ -61,7 +61,6 @@ class TestMergePipelineBarrier(SceneTestCase): # per-task via launch_spec.set_block_num in merge_orch.cpp). "name": "merge", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/examples/a2a3/tensormap_and_ringbuffer/paged_attention/test_paged_attention.py b/examples/a2a3/tensormap_and_ringbuffer/paged_attention/test_paged_attention.py index 1eb9f697e2..920d72f992 100644 --- a/examples/a2a3/tensormap_and_ringbuffer/paged_attention/test_paged_attention.py +++ b/examples/a2a3/tensormap_and_ringbuffer/paged_attention/test_paged_attention.py @@ -64,7 +64,6 @@ class TestPagedAttention(SceneTestCase): { "name": "Case1", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 256, "num_heads": 16, @@ -79,7 +78,6 @@ class TestPagedAttention(SceneTestCase): { "name": "Case2", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, @@ -95,7 +93,6 @@ class TestPagedAttention(SceneTestCase): { "name": "Case3", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, @@ -111,7 +108,6 @@ class TestPagedAttention(SceneTestCase): { "name": "CaseSmall1", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 1, "num_heads": 16, @@ -126,7 +122,6 @@ class TestPagedAttention(SceneTestCase): { "name": "CaseSmall2", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 1, @@ -142,7 +137,6 @@ class TestPagedAttention(SceneTestCase): { "name": "CaseVarSeq2", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 2, @@ -159,7 +153,6 @@ class TestPagedAttention(SceneTestCase): { "name": "CaseVarSeq4", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 4, diff --git a/examples/a2a3/tensormap_and_ringbuffer/paged_attention_manual_scope/test_paged_attention_manual_scope.py b/examples/a2a3/tensormap_and_ringbuffer/paged_attention_manual_scope/test_paged_attention_manual_scope.py index 1867de69a6..7754ecb49a 100644 --- a/examples/a2a3/tensormap_and_ringbuffer/paged_attention_manual_scope/test_paged_attention_manual_scope.py +++ b/examples/a2a3/tensormap_and_ringbuffer/paged_attention_manual_scope/test_paged_attention_manual_scope.py @@ -68,7 +68,7 @@ class TestPagedAttentionManualScope(SceneTestCase): # MANUAL scope; the default per-ring task window (16384) can fill # before the oldest task retires and wedge the orchestrator # (FLOW_CONTROL_DEADLOCK / code 3). Double the window for headroom. - "config": {"aicpu_thread_num": 4, "runtime_env": {"ring_task_window": 32768}}, + "config": {"runtime_env": {"ring_task_window": 32768}}, "params": { "batch": 256, "num_heads": 16, @@ -83,7 +83,6 @@ class TestPagedAttentionManualScope(SceneTestCase): { "name": "Case2", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, @@ -99,7 +98,6 @@ class TestPagedAttentionManualScope(SceneTestCase): { "name": "Case3", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, @@ -115,7 +113,6 @@ class TestPagedAttentionManualScope(SceneTestCase): { "name": "CaseSmall1", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 1, "num_heads": 16, @@ -130,7 +127,6 @@ class TestPagedAttentionManualScope(SceneTestCase): { "name": "CaseSmall2", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 1, @@ -146,7 +142,6 @@ class TestPagedAttentionManualScope(SceneTestCase): { "name": "CaseVarSeq2", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 2, @@ -163,7 +158,6 @@ class TestPagedAttentionManualScope(SceneTestCase): { "name": "CaseVarSeq4", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 4, diff --git a/examples/a2a3/tensormap_and_ringbuffer/paged_attention_ringbuffer/test_paged_attention_ringbuffer.py b/examples/a2a3/tensormap_and_ringbuffer/paged_attention_ringbuffer/test_paged_attention_ringbuffer.py index c332fd0a4b..cf5efd0463 100644 --- a/examples/a2a3/tensormap_and_ringbuffer/paged_attention_ringbuffer/test_paged_attention_ringbuffer.py +++ b/examples/a2a3/tensormap_and_ringbuffer/paged_attention_ringbuffer/test_paged_attention_ringbuffer.py @@ -72,7 +72,6 @@ class TestPagedAttentionRingbuffer(SceneTestCase): # ring_heap is bytes per ring. Non power-of-2 sizes are accepted, # but 4 MiB keeps the small-ring stress intent compact. "config": { - "aicpu_thread_num": 4, "runtime_env": { "ring_task_window": 64, "ring_heap": 4 * 1024 * 1024, diff --git a/examples/a2a3/tensormap_and_ringbuffer/paged_attention_unroll_manual_scope/test_paged_attention_unroll_manual_scope.py b/examples/a2a3/tensormap_and_ringbuffer/paged_attention_unroll_manual_scope/test_paged_attention_unroll_manual_scope.py index 98ab83a232..5d064bc4f8 100644 --- a/examples/a2a3/tensormap_and_ringbuffer/paged_attention_unroll_manual_scope/test_paged_attention_unroll_manual_scope.py +++ b/examples/a2a3/tensormap_and_ringbuffer/paged_attention_unroll_manual_scope/test_paged_attention_unroll_manual_scope.py @@ -64,7 +64,6 @@ class TestPagedAttentionUnrollManualScope(SceneTestCase): { "name": "Case1", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 256, "num_heads": 16, @@ -79,7 +78,6 @@ class TestPagedAttentionUnrollManualScope(SceneTestCase): { "name": "Case2", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, @@ -95,7 +93,6 @@ class TestPagedAttentionUnrollManualScope(SceneTestCase): { "name": "Case3", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, diff --git a/examples/a2a3/tensormap_and_ringbuffer/qwen3_14b_decode/test_qwen3_14b_decode.py b/examples/a2a3/tensormap_and_ringbuffer/qwen3_14b_decode/test_qwen3_14b_decode.py index a90cf9068f..a1c7e441c0 100644 --- a/examples/a2a3/tensormap_and_ringbuffer/qwen3_14b_decode/test_qwen3_14b_decode.py +++ b/examples/a2a3/tensormap_and_ringbuffer/qwen3_14b_decode/test_qwen3_14b_decode.py @@ -427,7 +427,6 @@ class TestQwen314BDecode(SceneTestCase): "name": "StressBatch16Seq3500", "platforms": ["a2a3"], # A run takes the whole device, matching the lib default. - "config": {"aicpu_thread_num": 4}, "params": {"seed": 1234, "seq_len": 3500}, }, ] diff --git a/examples/a2a3/tensormap_and_ringbuffer/scalar_data/test_scalar_data.py b/examples/a2a3/tensormap_and_ringbuffer/scalar_data/test_scalar_data.py index 617445ac76..59cf54d90b 100644 --- a/examples/a2a3/tensormap_and_ringbuffer/scalar_data/test_scalar_data.py +++ b/examples/a2a3/tensormap_and_ringbuffer/scalar_data/test_scalar_data.py @@ -49,7 +49,6 @@ class TestScalarData(SceneTestCase): { "name": "default", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/examples/a2a3/tensormap_and_ringbuffer/vector_example/test_vector_example.py b/examples/a2a3/tensormap_and_ringbuffer/vector_example/test_vector_example.py index 631b01360a..0b991eb5fa 100644 --- a/examples/a2a3/tensormap_and_ringbuffer/vector_example/test_vector_example.py +++ b/examples/a2a3/tensormap_and_ringbuffer/vector_example/test_vector_example.py @@ -51,7 +51,6 @@ class TestVectorExample(SceneTestCase): { "name": "default", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/examples/a5/tensormap_and_ringbuffer/bgemm/test_bgemm.py b/examples/a5/tensormap_and_ringbuffer/bgemm/test_bgemm.py index 897457cc77..a604b8d29e 100644 --- a/examples/a5/tensormap_and_ringbuffer/bgemm/test_bgemm.py +++ b/examples/a5/tensormap_and_ringbuffer/bgemm/test_bgemm.py @@ -64,7 +64,6 @@ class TestBgemm(SceneTestCase): { "name": "default", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/examples/a5/tensormap_and_ringbuffer/paged_attention/test_paged_attention.py b/examples/a5/tensormap_and_ringbuffer/paged_attention/test_paged_attention.py index 24ea94cc02..468a5be86e 100644 --- a/examples/a5/tensormap_and_ringbuffer/paged_attention/test_paged_attention.py +++ b/examples/a5/tensormap_and_ringbuffer/paged_attention/test_paged_attention.py @@ -70,7 +70,6 @@ class TestPagedAttention(SceneTestCase): { "name": "Case1", "platforms": ["a5"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 256, "num_heads": 16, @@ -85,7 +84,6 @@ class TestPagedAttention(SceneTestCase): { "name": "Case2", "platforms": ["a5"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, @@ -101,7 +99,6 @@ class TestPagedAttention(SceneTestCase): { "name": "Case3", "platforms": ["a5"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, @@ -117,7 +114,6 @@ class TestPagedAttention(SceneTestCase): { "name": "SmallCase1", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 1, "num_heads": 16, @@ -132,7 +128,6 @@ class TestPagedAttention(SceneTestCase): { "name": "SmallCase2", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 1, @@ -148,7 +143,6 @@ class TestPagedAttention(SceneTestCase): { "name": "SmallCaseVarSeq2", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 2, @@ -165,7 +159,6 @@ class TestPagedAttention(SceneTestCase): { "name": "SmallCaseVarSeq4", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 4, diff --git a/examples/a5/tensormap_and_ringbuffer/paged_attention_manual_scope/test_paged_attention_manual_scope.py b/examples/a5/tensormap_and_ringbuffer/paged_attention_manual_scope/test_paged_attention_manual_scope.py index 37c9b24e8a..aad02908b9 100644 --- a/examples/a5/tensormap_and_ringbuffer/paged_attention_manual_scope/test_paged_attention_manual_scope.py +++ b/examples/a5/tensormap_and_ringbuffer/paged_attention_manual_scope/test_paged_attention_manual_scope.py @@ -66,7 +66,6 @@ class TestPagedAttentionManualScope(SceneTestCase): { "name": "SmallCase1", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 1, "num_heads": 16, @@ -81,7 +80,6 @@ class TestPagedAttentionManualScope(SceneTestCase): { "name": "SmallCase2", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 1, @@ -97,7 +95,6 @@ class TestPagedAttentionManualScope(SceneTestCase): { "name": "SmallCaseVarSeq2", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 2, @@ -114,7 +111,6 @@ class TestPagedAttentionManualScope(SceneTestCase): { "name": "SmallCaseVarSeq4", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 4, diff --git a/examples/a5/tensormap_and_ringbuffer/paged_attention_unroll_manual_scope/test_paged_attention_unroll_manual_scope.py b/examples/a5/tensormap_and_ringbuffer/paged_attention_unroll_manual_scope/test_paged_attention_unroll_manual_scope.py index 0f7deed9e0..643fdc868c 100644 --- a/examples/a5/tensormap_and_ringbuffer/paged_attention_unroll_manual_scope/test_paged_attention_unroll_manual_scope.py +++ b/examples/a5/tensormap_and_ringbuffer/paged_attention_unroll_manual_scope/test_paged_attention_unroll_manual_scope.py @@ -66,7 +66,6 @@ class TestPagedAttentionUnrollManualScope(SceneTestCase): { "name": "Case1", "platforms": ["a5"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 256, "num_heads": 16, @@ -81,7 +80,6 @@ class TestPagedAttentionUnrollManualScope(SceneTestCase): { "name": "Case2", "platforms": ["a5"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, @@ -97,7 +95,6 @@ class TestPagedAttentionUnrollManualScope(SceneTestCase): { "name": "Case3", "platforms": ["a5"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, @@ -113,7 +110,6 @@ class TestPagedAttentionUnrollManualScope(SceneTestCase): { "name": "SmallCase1", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 1, "num_heads": 16, @@ -128,7 +124,6 @@ class TestPagedAttentionUnrollManualScope(SceneTestCase): { "name": "SmallCase2", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 1, diff --git a/examples/a5/tensormap_and_ringbuffer/vector_example/test_vector_example.py b/examples/a5/tensormap_and_ringbuffer/vector_example/test_vector_example.py index 791bb374d3..7c674c2097 100644 --- a/examples/a5/tensormap_and_ringbuffer/vector_example/test_vector_example.py +++ b/examples/a5/tensormap_and_ringbuffer/vector_example/test_vector_example.py @@ -51,7 +51,6 @@ class TestVectorExample(SceneTestCase): { "name": "default", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/python/simpler/task_interface.py b/python/simpler/task_interface.py index a7a3260d8e..427bb1cc7a 100644 --- a/python/simpler/task_interface.py +++ b/python/simpler/task_interface.py @@ -75,7 +75,7 @@ def _assert_bindings_match_source_tree() -> None: Nothing then rebuilds, and a changed struct layout — `CallConfig` losing a field, say — makes attributes read as 0 with no error at all. That surfaces much later as a plausible-looking runtime rejection - (``launch_aicpu_num (0) must be in range [1, 4]``) and reads as a product + (``launch_aicpu_num (1) must be 0 (auto) or in range [2, 4]``) and reads as a product bug, so it is worth one git call at import to stop. Only source-tree installs are checked: a wheel has no ``.git`` to compare @@ -1279,7 +1279,7 @@ def run( args: ChipStorageTaskArgs for this invocation. config: Optional CallConfig. If None, a default is created. **kwargs: Overrides applied to config (e.g. - ``aicpu_thread_num=4``). A run always takes the whole device; + ``aicpu_thread_num=2``). A run always takes the whole device; orchestration reads the resulting width back through ``rt_available_cluster_count()``. diff --git a/simpler_setup/scene_test.py b/simpler_setup/scene_test.py index c87df2c0af..7224c2e03f 100644 --- a/simpler_setup/scene_test.py +++ b/simpler_setup/scene_test.py @@ -1127,7 +1127,9 @@ def _build_config( from simpler.task_interface import CallConfig # noqa: PLC0415 config = CallConfig() - config.aicpu_thread_num = config_dict.get("aicpu_thread_num", 3) + # 0 = auto: DeviceRunner resolves to the arch default (1 orch + N sched) + # and clamps to the probed usable count (partial-good tolerance). + config.aicpu_thread_num = config_dict.get("aicpu_thread_num", 0) # Per-task ring sizing (tensormap_and_ringbuffer only; 0 = unset), # nested under the "runtime_env" key. Takes precedence over the # PTO2_RING_* env vars / RUNTIME_ENV. Each value is either a scalar diff --git a/src/a2a3/docs/hardware.md b/src/a2a3/docs/hardware.md index 469c537300..0bcfacfaa2 100644 --- a/src/a2a3/docs/hardware.md +++ b/src/a2a3/docs/hardware.md @@ -145,11 +145,11 @@ correctness, prefer ACL or CANN ini. | You are doing… | Use | | -------------- | --- | -| Configuring runtime `aicpu_thread_num` (per-case config) | **user-accessible** (6 — never request more) | +| Configuring runtime `aicpu_thread_num` (per-case config) | **0 = auto** → use every user CPU in the cluster with the largest usable count (higher cluster id breaks ties); explicit values must be in `[2, 4]`; auto errors when no cluster has at least 2 usable CPUs | | Setting kernel `block_dim` for AICore launch | **user-accessible** (24 — runtime rejects > 24) | | Reading the spec sheet / product datasheet | **spec / user-accessible** (24 AIC, 6 AICPU) | | Asking "what is in silicon" | **HAL physical** (25 AIC, 8 AICPU slots) — 1 PG-disabled + 1 OS-reserved on AICPU; 1 PG-disabled on AICore | -| Debugging "I set `aicpu_thread_num=8`, got error" | gap is **cpu_id 0 (AICPU OS) + cpu_id 1 (PG)** — both unreachable from runtime; cap is 6 | +| Debugging "I set `aicpu_thread_num=8`, got error" | active cap is **4** (`PLATFORM_MAX_AICPU_THREADS`); 6 is the launch pool (popcount OCCUPY). Gap to 8 AICPU slots = **cpu_id 0 (OS) + cpu_id 1 (PG)**, both unreachable from runtime | | Debugging "I set `block_dim=25`, got error" | runtime cap is **24**; the +1 slot is PG fab-disabled | | Building a chip-management dashboard | use HAL OCCUPY + OS_SCHED to expose the split; cite `tools/cann-examples/aicpu-device-query/` for the OS_SCHED query | diff --git a/src/a2a3/platform/include/common/platform_config.h b/src/a2a3/platform/include/common/platform_config.h index 6fd20ab116..ca62188c04 100644 --- a/src/a2a3/platform/include/common/platform_config.h +++ b/src/a2a3/platform/include/common/platform_config.h @@ -51,6 +51,14 @@ constexpr int PLATFORM_AIV_CORES_PER_BLOCKDIM = 2; */ constexpr int PLATFORM_MAX_AICPU_THREADS = 4; +/** + * Default active AICPU thread count when aicpu_thread_num is left at 0 (auto): + * 1 orchestrator + 3 schedulers. DeviceRunner clamps it to the probed usable + * count (PG/OS cores are absent from the AICPU OCCUPY bitmap), runs with fewer + * schedulers if usable < default, and errors if fewer than 2 AICPU are usable. + */ +constexpr int PLATFORM_DEFAULT_AICPU_THREAD_NUM = 4; // 1 orch + 3 sched + /** * Maximum AICPU launch threads (physical) * Upper bound for the number of AICPU threads that can be launched by Host. diff --git a/src/a2a3/platform/onboard/host/aicpu_topology_probe.cpp b/src/a2a3/platform/onboard/host/aicpu_topology_probe.cpp index 7a5a243b03..0f7f963259 100644 --- a/src/a2a3/platform/onboard/host/aicpu_topology_probe.cpp +++ b/src/a2a3/platform/onboard/host/aicpu_topology_probe.cpp @@ -182,4 +182,25 @@ bool compute_allowed_cpus( return true; } +bool compute_auto_allowed_cpus(const std::vector &user_cpus, std::vector &out_allowed_cpus) { + out_allowed_cpus.clear(); + int32_t chosen_cluster = -1; + int32_t chosen_count = 0; + for (const auto &candidate : user_cpus) { + int32_t count = 0; + for (const auto &cpu : user_cpus) + if (cpu.cluster_id == candidate.cluster_id) ++count; + if (count > chosen_count || (count == chosen_count && candidate.cluster_id > chosen_cluster)) { + chosen_cluster = candidate.cluster_id; + chosen_count = count; + } + } + if (chosen_count < 2) return false; + + for (const auto &cpu : user_cpus) + if (cpu.cluster_id == chosen_cluster) out_allowed_cpus.push_back(cpu.cpu_id); + std::sort(out_allowed_cpus.begin(), out_allowed_cpus.end()); + return true; +} + } // namespace pto::a2a3 diff --git a/src/a2a3/platform/onboard/host/aicpu_topology_probe.h b/src/a2a3/platform/onboard/host/aicpu_topology_probe.h index 72517fcb92..32518059f0 100644 --- a/src/a2a3/platform/onboard/host/aicpu_topology_probe.h +++ b/src/a2a3/platform/onboard/host/aicpu_topology_probe.h @@ -35,6 +35,11 @@ bool compute_allowed_cpus( const std::vector &user_cpus, int32_t active_count, std::vector &out_allowed_cpus ); +// Auto mode: use every user-schedulable CPU in the cluster with the most +// usable CPUs. Ties prefer the higher cluster id. Returns false when the best +// cluster cannot provide both an orchestrator and a scheduler. +bool compute_auto_allowed_cpus(const std::vector &user_cpus, std::vector &out_allowed_cpus); + } // namespace pto::a2a3 #endif // SRC_A2A3_PLATFORM_ONBOARD_HOST_AICPU_TOPOLOGY_PROBE_H_ diff --git a/src/a2a3/platform/onboard/host/device_runner.cpp b/src/a2a3/platform/onboard/host/device_runner.cpp index 981a213582..375aaa5436 100644 --- a/src/a2a3/platform/onboard/host/device_runner.cpp +++ b/src/a2a3/platform/onboard/host/device_runner.cpp @@ -222,7 +222,7 @@ int DeviceRunner::run(Runtime &runtime, const CallConfig &config) { // prepare_launch_shape() resolved block_dim before the graph was built, so // the geometry this run launches with is already on the runner. const int block_dim = block_dim_; - const int launch_aicpu_num = config.aicpu_thread_num; + int launch_aicpu_num = config.aicpu_thread_num; // A prior AICore launch/sync error poisoned the device context and the // in-place drain could not clear it. Refuse to run rather than cascade into // rtMalloc 507899 / halResMap rc=62 (init_aicore_register_addresses). A soft @@ -339,13 +339,29 @@ int DeviceRunner::run(Runtime &runtime, const CallConfig &config) { LOG_ERROR("A2A3 AICPU topology probe failed; cannot configure affinity gate"); return -1; } - if (!pto::a2a3::compute_allowed_cpus(user_cpus, runtime.get_aicpu_thread_num(), allowed)) { - LOG_ERROR( - "A2A3 AICPU topology has %zu user cpus, cannot fit %d active threads", user_cpus.size(), - runtime.get_aicpu_thread_num() + const bool auto_requested = runtime.get_aicpu_thread_num() == 0; + int resolved_aicpu = 0; + if (auto_requested) { + if (!pto::a2a3::compute_auto_allowed_cpus(user_cpus, allowed)) { + LOG_ERROR("A2A3 auto AICPU selection needs >=2 usable CPUs in one cluster"); + return -1; + } + resolved_aicpu = static_cast(allowed.size()); + } else { + resolved_aicpu = resolve_aicpu_thread_num( + runtime.get_aicpu_thread_num(), static_cast(user_cpus.size()), PLATFORM_DEFAULT_AICPU_THREAD_NUM ); - return -1; + if (resolved_aicpu < 0) return -1; + if (!pto::a2a3::compute_allowed_cpus(user_cpus, resolved_aicpu, allowed)) { + LOG_ERROR( + "A2A3 AICPU topology has %zu user cpus, cannot fit %d active threads", user_cpus.size(), + resolved_aicpu + ); + return -1; + } } + runtime.set_aicpu_thread_num(resolved_aicpu); + launch_aicpu_num = resolved_aicpu; const size_t cap = runtime.aicpu_allowed_cpus_capacity(); if (allowed.size() > cap) { LOG_ERROR("A2A3 compute_allowed_cpus returned %zu > cap %zu", allowed.size(), cap); diff --git a/src/a2a3/platform/sim/host/device_runner.cpp b/src/a2a3/platform/sim/host/device_runner.cpp index 912f793249..6a489e1ec0 100644 --- a/src/a2a3/platform/sim/host/device_runner.cpp +++ b/src/a2a3/platform/sim/host/device_runner.cpp @@ -235,8 +235,14 @@ int DeviceRunner::run(Runtime &runtime, const CallConfig &config) { // prepare_launch_shape() resolved block_dim before the graph was built, so // the geometry this run launches with is already on the runner. const int block_dim = block_dim_; - const int launch_aicpu_num = config.aicpu_thread_num; + int launch_aicpu_num = config.aicpu_thread_num; clear_cpu_sim_shared_storage(); + // Partial-good policy: 0=auto -> arch default (1 orch + N sched). Sim has + // no real OCCUPY/PG; onboard clamps to the probed usable count via + // DeviceRunnerBase::resolve_aicpu_thread_num. Publish the effective count + // back to Runtime so AICPU init / DFX setup match the launch gate. + if (launch_aicpu_num == 0) launch_aicpu_num = PLATFORM_DEFAULT_AICPU_THREAD_NUM; + runtime.set_aicpu_thread_num(launch_aicpu_num); if (block_dim < 1) { LOG_ERROR("run() reached with unresolved block_dim; prepare_launch_shape must run first"); return -1; diff --git a/src/a5/docs/hardware.md b/src/a5/docs/hardware.md index 84f4c2134e..0cb151f272 100644 --- a/src/a5/docs/hardware.md +++ b/src/a5/docs/hardware.md @@ -139,12 +139,12 @@ report what user code can address. | You are doing… | Use | | -------------- | --- | -| Configuring runtime `aicpu_thread_num` | **user-visible** (6) | +| Configuring runtime `aicpu_thread_num` | **0 = auto** → use every user CPU in the die with the largest usable count (higher die id breaks ties); explicit values must be in `[2, 7]`; auto errors when no die has at least 2 usable CPUs | | Setting kernel `block_dim` for AICore | **user-visible** (per CANN ini for your specific SKU) | | Counting cores in a multi-die a5 device | **per-device** HAL CORE_NUM (= 2 × per-die) | | Reasoning about hyperthreading on AICPU | **DSMI CPU_TOPO** (only it shows the hyperthread pair on cpu_id 1+2) | | Writing code expected to also work on a3 | **ACL or CANN ini only** — HAL semantics differ | -| Debugging "I requested N AICPU, only 6 ran" | gap is **1 AICPU OS scheduler (cpu_id 0) + 2 SMT-pair (cpu_id 1, 2) withheld by AICPU OS**; cap is 6 | +| Debugging "I requested N AICPU, only 6 ran" | active cap is **7** (`PLATFORM_MAX_AICPU_THREADS`); 6 are device-usable (gap = 1 OS cpu_id 0 + 2 SMT-pair withheld by AICPU OS). Host-side OCCUPY reports 8, so the default 5 stays <= 6 | For cross-generation portable code: **always go through ACL or CANN ini, never HAL**. HAL's CORE_NUM semantics shift between a3 and a5 in diff --git a/src/a5/platform/include/common/platform_config.h b/src/a5/platform/include/common/platform_config.h index e89430e93d..e68825979b 100644 --- a/src/a5/platform/include/common/platform_config.h +++ b/src/a5/platform/include/common/platform_config.h @@ -51,6 +51,14 @@ constexpr int PLATFORM_AIV_CORES_PER_BLOCKDIM = 2; */ constexpr int PLATFORM_MAX_AICPU_THREADS = 7; +/** + * Default active AICPU thread count when aicpu_thread_num is left at 0 (auto): + * 1 orchestrator + 4 schedulers. DeviceRunner clamps it to the probed usable + * count (PG/OS cores are absent from the AICPU OCCUPY bitmap), runs with fewer + * schedulers if usable < default, and errors if fewer than 2 AICPU are usable. + */ +constexpr int PLATFORM_DEFAULT_AICPU_THREAD_NUM = 5; // 1 orch + 4 sched + /** * Compile-time upper bound on the number of AICPU threads CANN may * start per launch. The actual launch count is runtime-derived: diff --git a/src/a5/platform/onboard/host/aicpu_topology_probe.cpp b/src/a5/platform/onboard/host/aicpu_topology_probe.cpp index fc4da7050e..eb3a8cfd0b 100644 --- a/src/a5/platform/onboard/host/aicpu_topology_probe.cpp +++ b/src/a5/platform/onboard/host/aicpu_topology_probe.cpp @@ -146,6 +146,10 @@ bool probe_aicpu_topology_uncached(uint32_t device_id, std::vector= 64 || ((occupy >> c.cpu_id) & 1ULL) == 0) continue; + bool has_smt_sibling = false; + for (uint32_t j = 0; j < topo.total_nums; ++j) { + if (i != j && topo.cpus[j].phy_cpu_id == c.phy_cpu_id) { + has_smt_sibling = true; + break; + } + } + if (has_smt_sibling) continue; AicpuLogicalCpu e{}; e.cpu_id = static_cast(c.cpu_id); e.phy_cpu_id = static_cast(c.phy_cpu_id); @@ -363,4 +375,25 @@ bool compute_allowed_cpus( return true; } +bool compute_auto_allowed_cpus(const std::vector &user_cpus, std::vector &out_allowed_cpus) { + out_allowed_cpus.clear(); + int32_t chosen_die = -1; + int32_t chosen_count = 0; + for (const auto &candidate : user_cpus) { + int32_t count = 0; + for (const auto &cpu : user_cpus) + if (cpu.die_id == candidate.die_id) ++count; + if (count > chosen_count || (count == chosen_count && candidate.die_id > chosen_die)) { + chosen_die = candidate.die_id; + chosen_count = count; + } + } + if (chosen_count < 2) return false; + + std::vector chosen_cpus; + for (const auto &cpu : user_cpus) + if (cpu.die_id == chosen_die) chosen_cpus.push_back(cpu); + return compute_allowed_cpus(chosen_cpus, chosen_count - 1, /*n_orch=*/1, out_allowed_cpus); +} + } // namespace pto::a5 diff --git a/src/a5/platform/onboard/host/aicpu_topology_probe.h b/src/a5/platform/onboard/host/aicpu_topology_probe.h index 99df94ebe8..63a4204916 100644 --- a/src/a5/platform/onboard/host/aicpu_topology_probe.h +++ b/src/a5/platform/onboard/host/aicpu_topology_probe.h @@ -76,6 +76,11 @@ bool compute_allowed_cpus( std::vector &out_allowed_cpus ); +// Auto mode: use every user-schedulable CPU in the die with the most usable +// CPUs. Ties prefer the higher die id. Output ordering remains +// [sched..., orch]. Returns false when the best die cannot provide both roles. +bool compute_auto_allowed_cpus(const std::vector &user_cpus, std::vector &out_allowed_cpus); + } // namespace pto::a5 #endif // SRC_A5_PLATFORM_ONBOARD_HOST_AICPU_TOPOLOGY_PROBE_H_ diff --git a/src/a5/platform/onboard/host/device_runner.cpp b/src/a5/platform/onboard/host/device_runner.cpp index aceaed3c8f..7a013af351 100644 --- a/src/a5/platform/onboard/host/device_runner.cpp +++ b/src/a5/platform/onboard/host/device_runner.cpp @@ -156,7 +156,8 @@ int DeviceRunner::run(Runtime &runtime, const CallConfig &config) { // prepare_launch_shape() resolved block_dim before the graph was built, so // the geometry this run launches with is already on the runner. const int block_dim = block_dim_; - const int launch_aicpu_num = config.aicpu_thread_num; + int launch_aicpu_num = config.aicpu_thread_num; + const bool auto_requested = launch_aicpu_num == 0; // A prior AICore launch/sync error poisoned the device context and the // in-place drain could not clear it. Refuse to run rather than cascade // into halResMap rc=62 (init_aicore_register_addresses) or rtMalloc @@ -190,6 +191,15 @@ int DeviceRunner::run(Runtime &runtime, const CallConfig &config) { } int num_aicore = block_dim * cores_per_blockdim_; + // Install the guard before allocation so topology/affinity failures below + // cannot leak the register buffer. + auto regs_cleanup = RAIIScopeGuard([this]() { + if (kernel_args_.args.regs != 0) { + mem_alloc_.free(reinterpret_cast(kernel_args_.args.regs)); + kernel_args_.args.regs = 0; + } + }); + rc = init_aicore_register_addresses(&kernel_args_.args.regs, static_cast(device_id_), mem_alloc_); if (rc != 0) { LOG_ERROR("init_aicore_register_addresses failed: %d", rc); @@ -211,65 +221,63 @@ int DeviceRunner::run(Runtime &runtime, const CallConfig &config) { // filter-style gate (see src/common/platform/onboard/aicpu/ // platform_aicpu_affinity.cpp::platform_aicpu_affinity_gate_filter). // Convention: indices 0..n_sched-1 = sched slots, last = orch slot. - // n_sched = launch_aicpu_num - 1 (one orch + the rest sched). When - // launch_aicpu_num == 1 (init-only path) we leave allowed_cpus empty — - // the gate is a no-op for a single thread. + // n_sched = active_count - 1 (one orch + the rest sched). { std::vector user_cpus; std::vector allowed; const int32_t n_orch = 1; - const int32_t n_sched = (launch_aicpu_num > 1) ? (launch_aicpu_num - n_orch) : 0; runtime.set_aicpu_allowed_cpu_count(0); - if (n_sched > 0) { - if (!pto::a5::probe_aicpu_topology(static_cast(device_id_), user_cpus)) { - LOG_ERROR("AICPU topology probe failed; affinity gate will drop all threads"); + if (!pto::a5::probe_aicpu_topology(static_cast(device_id_), user_cpus)) { + LOG_ERROR("AICPU topology probe failed; affinity gate will drop all threads"); + return -1; + } + + int resolved_aicpu = 0; + if (auto_requested) { + if (!pto::a5::compute_auto_allowed_cpus(user_cpus, allowed)) { + LOG_ERROR("A5 auto AICPU selection needs >=2 usable CPUs in one die"); return -1; } + resolved_aicpu = static_cast(allowed.size()); + } else { + resolved_aicpu = resolve_aicpu_thread_num( + launch_aicpu_num, static_cast(user_cpus.size()), PLATFORM_DEFAULT_AICPU_THREAD_NUM + ); + if (resolved_aicpu < 0) return -1; + const int32_t n_sched = resolved_aicpu - n_orch; if (!pto::a5::compute_allowed_cpus(user_cpus, n_sched, n_orch, allowed)) { LOG_ERROR( "AICPU topology has %zu user cpus, cannot fit %d sched + %d orch", user_cpus.size(), n_sched, n_orch ); return -1; } - const size_t cap = runtime.aicpu_allowed_cpus_capacity(); - if (allowed.size() > cap) { - LOG_ERROR("compute_allowed_cpus returned %zu > cap %zu", allowed.size(), cap); - return -1; - } - int32_t *allowed_cpus = runtime.get_aicpu_allowed_cpus(); - for (size_t i = 0; i < allowed.size(); ++i) - allowed_cpus[i] = allowed[i]; - runtime.set_aicpu_allowed_cpu_count(static_cast(allowed.size())); - // Launch one AICPU thread per OCCUPY-visible user cpu so CANN - // spreads exactly across the user pool — over-subscription on a - // SKU with fewer user cpus than the compile-time bound deadlocks - // the production AICPU kernel. Capped by the compile-time array - // sizing in case the SKU exceeds expectation. - int32_t launch_n = static_cast(user_cpus.size()); - if (launch_n > PLATFORM_MAX_AICPU_THREADS_JUST_FOR_LAUNCH) { - launch_n = PLATFORM_MAX_AICPU_THREADS_JUST_FOR_LAUNCH; - } - runtime.set_aicpu_launch_count(launch_n); - std::string dump; - for (size_t i = 0; i < allowed.size(); ++i) { - if (i) dump += ", "; - dump += std::to_string(allowed[i]); - if (i + 1 == allowed.size()) dump += "(orch)"; - } - LOG_INFO( - "AICPU ALLOWED_CPUS = [%s] (n_sched=%d, n_orch=%d, launch=%d, user_cpus=%zu)", dump.c_str(), n_sched, - n_orch, launch_n, user_cpus.size() - ); } - } - - // Scope guards for cleanup on all exit paths - auto regs_cleanup = RAIIScopeGuard([this]() { - if (kernel_args_.args.regs != 0) { - mem_alloc_.free(reinterpret_cast(kernel_args_.args.regs)); - kernel_args_.args.regs = 0; + launch_aicpu_num = resolved_aicpu; + runtime.set_aicpu_thread_num(resolved_aicpu); + const size_t cap = runtime.aicpu_allowed_cpus_capacity(); + if (allowed.size() > cap) { + LOG_ERROR("compute_allowed_cpus returned %zu > cap %zu", allowed.size(), cap); + return -1; } - }); + int32_t *allowed_cpus = runtime.get_aicpu_allowed_cpus(); + for (size_t i = 0; i < allowed.size(); ++i) + allowed_cpus[i] = allowed[i]; + runtime.set_aicpu_allowed_cpu_count(static_cast(allowed.size())); + int32_t launch_n = std::min( + static_cast(user_cpus.size()), static_cast(PLATFORM_MAX_AICPU_THREADS_JUST_FOR_LAUNCH) + ); + runtime.set_aicpu_launch_count(launch_n); + std::string dump; + for (size_t i = 0; i < allowed.size(); ++i) { + if (i) dump += ", "; + dump += std::to_string(allowed[i]); + if (i + 1 == allowed.size()) dump += "(orch)"; + } + LOG_INFO( + "AICPU ALLOWED_CPUS = [%s] (active=%d, launch=%d, user_cpus=%zu)", dump.c_str(), resolved_aicpu, launch_n, + user_cpus.size() + ); + } auto runtime_args_cleanup = RAIIScopeGuard([this]() { kernel_args_.finalize_device_kernel_args(); @@ -402,10 +410,8 @@ int DeviceRunner::run(Runtime &runtime, const CallConfig &config) { // launch_count = popcount(OCCUPY) from the topology probe — one thread // per user-schedulable cpu_id. The filter gate barriers exactly this // many threads (runtime.aicpu_launch_count is read on the device side - // by kernel.cpp). Fall back to the caller-requested active count when - // the probe was skipped (single-thread init / launch_aicpu_num == 1) - // — over-launching to the compile-time bound on that path would - // start 14 threads to do a 1-thread job and deadlock the device. + // by kernel.cpp). The fallback is defensive; normal runs always publish + // the topology-derived launch count above. int aicpu_launch_n = (runtime.get_aicpu_launch_count() > 0) ? runtime.get_aicpu_launch_count() : launch_aicpu_num; rc = launch_aicpu_kernel(stream_aicpu_, &kernel_args_.args, host::KernelNames::RunName, aicpu_launch_n); if (rc != 0) { diff --git a/src/a5/platform/sim/host/device_runner.cpp b/src/a5/platform/sim/host/device_runner.cpp index 2acdb05f26..853229ddfc 100644 --- a/src/a5/platform/sim/host/device_runner.cpp +++ b/src/a5/platform/sim/host/device_runner.cpp @@ -218,8 +218,14 @@ int DeviceRunner::run(Runtime &runtime, const CallConfig &config) { // prepare_launch_shape() resolved block_dim before the graph was built, so // the geometry this run launches with is already on the runner. const int block_dim = block_dim_; - const int launch_aicpu_num = config.aicpu_thread_num; + int launch_aicpu_num = config.aicpu_thread_num; clear_cpu_sim_shared_storage(); + // Partial-good policy: 0=auto -> arch default (1 orch + N sched). Sim has + // no real OCCUPY/PG; onboard clamps to the probed usable count via + // DeviceRunnerBase::resolve_aicpu_thread_num. Publish the effective count + // back to Runtime so AICPU init / DFX setup match the launch gate. + if (launch_aicpu_num == 0) launch_aicpu_num = PLATFORM_DEFAULT_AICPU_THREAD_NUM; + runtime.set_aicpu_thread_num(launch_aicpu_num); if (block_dim < 1) { LOG_ERROR("run() reached with unresolved block_dim; prepare_launch_shape must run first"); return -1; diff --git a/src/common/platform/onboard/host/device_runner_base.cpp b/src/common/platform/onboard/host/device_runner_base.cpp index 1f92a8984e..79b187a824 100644 --- a/src/common/platform/onboard/host/device_runner_base.cpp +++ b/src/common/platform/onboard/host/device_runner_base.cpp @@ -1203,13 +1203,31 @@ int DeviceRunnerBase::launch_aicore_kernel(rtStream_t stream, KernelArgs *k_args // ============================================================================= int DeviceRunnerBase::validate_launch_aicpu_num(int launch_aicpu_num) { - if (launch_aicpu_num < 1 || launch_aicpu_num > PLATFORM_MAX_AICPU_THREADS) { - LOG_ERROR("launch_aicpu_num (%d) must be in range [1, %d]", launch_aicpu_num, PLATFORM_MAX_AICPU_THREADS); + if (launch_aicpu_num == 1 || launch_aicpu_num < 0 || launch_aicpu_num > PLATFORM_MAX_AICPU_THREADS) { + LOG_ERROR( + "launch_aicpu_num (%d) must be 0 (auto) or in range [2, %d]", launch_aicpu_num, PLATFORM_MAX_AICPU_THREADS + ); return -1; } return 0; } +int DeviceRunnerBase::resolve_aicpu_thread_num(int requested, int usable, int arch_default) { + if (usable < 2) { + LOG_ERROR("AICPU usable count %d < 2 (need >=1 orchestrator + >=1 scheduler)", usable); + return -1; + } + int desired = (requested > 0) ? requested : arch_default; + int total = std::min(desired, usable); + if (total < desired) { + LOG_WARN( + "AICPU: requested %d active threads, only %d usable on this die — running 1 orch + %d sched", desired, + usable, total - 1 + ); + } + return total; +} + void DeviceRunnerBase::ensure_device_wall_buffer() { // Per-thread fixed AICPU phase records (thread-major: // AicpuPhaseRecord[NUM_AICPU_PHASES] per launched AICPU thread). Slot diff --git a/src/common/platform/onboard/host/device_runner_base.h b/src/common/platform/onboard/host/device_runner_base.h index d34b975933..6052070b49 100644 --- a/src/common/platform/onboard/host/device_runner_base.h +++ b/src/common/platform/onboard/host/device_runner_base.h @@ -678,6 +678,16 @@ class DeviceRunnerBase { */ int validate_launch_aicpu_num(int launch_aicpu_num); + /** + * Resolve the active AICPU thread count for partial-good tolerance. + * requested <= 0 means auto (use arch_default = 1 orch + N sched); the + * result is clamped to `usable` (the probed AICPU count — PG/OS cores are + * absent from OCCUPY) so a degraded die runs with fewer schedulers, and + * returns <0 if usable < 2 (need >=1 orch + >=1 sched). Returns the active + * total otherwise. + */ + int resolve_aicpu_thread_num(int requested, int usable, int arch_default); + /** * Lazy-allocate the 8-byte device-resident buffer that AICPU writes * the run wall (ns) into and that `read_device_wall_ns()` pulls diff --git a/src/common/platform/sim/host/device_runner_base.cpp b/src/common/platform/sim/host/device_runner_base.cpp index 217971929f..cbe9e72fc8 100644 --- a/src/common/platform/sim/host/device_runner_base.cpp +++ b/src/common/platform/sim/host/device_runner_base.cpp @@ -276,9 +276,11 @@ int SimDeviceRunnerBase::ensure_device_initialized() { } int SimDeviceRunnerBase::prepare_launch_shape(Runtime &runtime, const CallConfig &config) { - if (config.aicpu_thread_num < 1 || config.aicpu_thread_num > PLATFORM_MAX_AICPU_THREADS) { + if (config.aicpu_thread_num == 1 || config.aicpu_thread_num < 0 || + config.aicpu_thread_num > PLATFORM_MAX_AICPU_THREADS) { LOG_ERROR( - "launch_aicpu_num (%d) must be in range [1, %d]", config.aicpu_thread_num, PLATFORM_MAX_AICPU_THREADS + "launch_aicpu_num (%d) must be 0 (auto) or in range [2, %d]", config.aicpu_thread_num, + PLATFORM_MAX_AICPU_THREADS ); return -1; } diff --git a/src/common/task_interface/call_config.h b/src/common/task_interface/call_config.h index e61c38b3c1..27cf411c9a 100644 --- a/src/common/task_interface/call_config.h +++ b/src/common/task_interface/call_config.h @@ -109,7 +109,10 @@ struct RuntimeEnv { }; struct CallConfig { - int32_t aicpu_thread_num = 3; + // 0 = auto: onboard selects all usable CPUs in the best local topology + // unit (a2a3: cluster; a5: die); simulation uses the architecture default. + // Explicit normal-run values must be at least 2. + int32_t aicpu_thread_num = 0; int32_t enable_l2_swimlane = 0; int32_t enable_dump_args = 0; int32_t enable_pmu = 0; // 0 = disabled; >0 = enabled, value selects event type diff --git a/tests/st/a2a3/host_build_graph/available_aicore_counts/test_available_aicore_counts.py b/tests/st/a2a3/host_build_graph/available_aicore_counts/test_available_aicore_counts.py index a9aa20b525..ab9b835a78 100644 --- a/tests/st/a2a3/host_build_graph/available_aicore_counts/test_available_aicore_counts.py +++ b/tests/st/a2a3/host_build_graph/available_aicore_counts/test_available_aicore_counts.py @@ -86,7 +86,6 @@ class TestAvailableAicoreCounts(SceneTestCase): { "name": "Default", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a2a3/host_build_graph/bgemm/test_bgemm.py b/tests/st/a2a3/host_build_graph/bgemm/test_bgemm.py index 1b7fa51e16..ec283f3a82 100644 --- a/tests/st/a2a3/host_build_graph/bgemm/test_bgemm.py +++ b/tests/st/a2a3/host_build_graph/bgemm/test_bgemm.py @@ -61,7 +61,6 @@ class TestBgemmHostBuildGraph(SceneTestCase): { "name": "default", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a2a3/host_build_graph/dfx/dep_gen/test_dep_gen.py b/tests/st/a2a3/host_build_graph/dfx/dep_gen/test_dep_gen.py index 203a2461cb..930dafd37c 100644 --- a/tests/st/a2a3/host_build_graph/dfx/dep_gen/test_dep_gen.py +++ b/tests/st/a2a3/host_build_graph/dfx/dep_gen/test_dep_gen.py @@ -124,7 +124,6 @@ class TestDepGenHostBuildGraph(SceneTestCase): { "name": "default", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a2a3/host_build_graph/dump_args/test_dump_args_example.py b/tests/st/a2a3/host_build_graph/dump_args/test_dump_args_example.py index 0d926dd382..13605069b9 100644 --- a/tests/st/a2a3/host_build_graph/dump_args/test_dump_args_example.py +++ b/tests/st/a2a3/host_build_graph/dump_args/test_dump_args_example.py @@ -50,7 +50,6 @@ class TestDumpArgsExample(SceneTestCase): { "name": "default", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a2a3/host_build_graph/matmul/test_matmul.py b/tests/st/a2a3/host_build_graph/matmul/test_matmul.py index 75b7533916..8df929badf 100644 --- a/tests/st/a2a3/host_build_graph/matmul/test_matmul.py +++ b/tests/st/a2a3/host_build_graph/matmul/test_matmul.py @@ -58,7 +58,6 @@ class TestMatmulHostBuildGraph(SceneTestCase): { "name": "default", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a2a3/host_build_graph/paged_attention/test_paged_attention.py b/tests/st/a2a3/host_build_graph/paged_attention/test_paged_attention.py index 856317d7d2..87cdec9587 100644 --- a/tests/st/a2a3/host_build_graph/paged_attention/test_paged_attention.py +++ b/tests/st/a2a3/host_build_graph/paged_attention/test_paged_attention.py @@ -76,7 +76,6 @@ class TestPagedAttentionHostBuildGraph(SceneTestCase): # a large PTO2_RING_TASK_WINDOW / PTO2_RING_HEAP if needed. "name": "Case1", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 256, @@ -92,7 +91,6 @@ class TestPagedAttentionHostBuildGraph(SceneTestCase): { "name": "Case2", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, @@ -108,7 +106,6 @@ class TestPagedAttentionHostBuildGraph(SceneTestCase): { "name": "small1", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 1, "num_heads": 16, @@ -123,7 +120,6 @@ class TestPagedAttentionHostBuildGraph(SceneTestCase): { "name": "small2", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 1, diff --git a/tests/st/a2a3/host_build_graph/prepared_callable/test_prepared_callable.py b/tests/st/a2a3/host_build_graph/prepared_callable/test_prepared_callable.py index 259f96a976..c8e3369ca7 100644 --- a/tests/st/a2a3/host_build_graph/prepared_callable/test_prepared_callable.py +++ b/tests/st/a2a3/host_build_graph/prepared_callable/test_prepared_callable.py @@ -84,14 +84,12 @@ class TestPreparedCallableHbg(SceneTestCase): ], } - _COMMON_CONFIG = {"aicpu_thread_num": 4} _PLATFORMS = ["a2a3sim", "a2a3"] CASES = [ { "name": "prepare_run_twice", "platforms": _PLATFORMS, - "config": _COMMON_CONFIG, "params": {"a": 2.0, "b": 3.0}, }, ] @@ -171,7 +169,7 @@ def _run_and_validate_l2( # noqa: PLR0913 def _setup_dlopen_count_test(self, st_worker, st_platform): case = self.CASES[0] callable_obj = self.build_callable(st_platform) - config = self._build_config(case["config"]) + config = self._build_config(case.get("config", {})) return callable_obj, config, case def _run_one(self, worker, slot, config, case): diff --git a/tests/st/a2a3/host_build_graph/run_stream_reuse/test_run_stream_reuse.py b/tests/st/a2a3/host_build_graph/run_stream_reuse/test_run_stream_reuse.py index f828ebac98..07ef9875d7 100644 --- a/tests/st/a2a3/host_build_graph/run_stream_reuse/test_run_stream_reuse.py +++ b/tests/st/a2a3/host_build_graph/run_stream_reuse/test_run_stream_reuse.py @@ -106,7 +106,7 @@ class TestRunStreamReuseHbg(SceneTestCase): { "name": "repeated_runs", "platforms": ["a2a3", "a2a3sim"], - "config": {"aicpu_thread_num": 4, "block_dim": 3}, + "config": {"block_dim": 3}, "params": {}, }, ] diff --git a/tests/st/a2a3/host_build_graph/vector_example/test_vector_example.py b/tests/st/a2a3/host_build_graph/vector_example/test_vector_example.py index 8e084696f4..0a672070ce 100644 --- a/tests/st/a2a3/host_build_graph/vector_example/test_vector_example.py +++ b/tests/st/a2a3/host_build_graph/vector_example/test_vector_example.py @@ -58,7 +58,6 @@ class TestVectorExampleHostBuildGraph(SceneTestCase): { "name": "default", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/alternating_matmul_add/test_alternating_matmul_add.py b/tests/st/a2a3/tensormap_and_ringbuffer/alternating_matmul_add/test_alternating_matmul_add.py index d60a83f0d4..106363a8bb 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/alternating_matmul_add/test_alternating_matmul_add.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/alternating_matmul_add/test_alternating_matmul_add.py @@ -54,20 +54,17 @@ class TestAlternatingMatmulAdd(SceneTestCase): { "name": "default", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {"batch": 1, "M": 1, "N": 1, "matmul_batch": 1, "add_batch": 1}, }, { "name": "Case1", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {"batch": 500, "M": 4, "N": 4, "matmul_batch": 4, "add_batch": 4}, "manual": True, }, { "name": "Case2", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {"batch": 512, "M": 2, "N": 5, "matmul_batch": 4, "add_batch": 5}, "manual": True, }, diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/available_aicore_counts/test_available_aicore_counts.py b/tests/st/a2a3/tensormap_and_ringbuffer/available_aicore_counts/test_available_aicore_counts.py index 9361f2e372..fdc0785481 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/available_aicore_counts/test_available_aicore_counts.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/available_aicore_counts/test_available_aicore_counts.py @@ -79,7 +79,6 @@ class TestAvailableAicoreCounts(SceneTestCase): { "name": "Default", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/batch_paged_attention/test_batch_paged_attention.py b/tests/st/a2a3/tensormap_and_ringbuffer/batch_paged_attention/test_batch_paged_attention.py index 32a8e69e1d..b130e28db2 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/batch_paged_attention/test_batch_paged_attention.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/batch_paged_attention/test_batch_paged_attention.py @@ -64,7 +64,6 @@ class TestBatchPagedAttention(SceneTestCase): { "name": "Case1", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 256, "num_heads": 16, @@ -79,7 +78,6 @@ class TestBatchPagedAttention(SceneTestCase): { "name": "Case2", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, @@ -95,7 +93,6 @@ class TestBatchPagedAttention(SceneTestCase): { "name": "Case3", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, @@ -111,7 +108,6 @@ class TestBatchPagedAttention(SceneTestCase): { "name": "CaseSmall1", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 1, "num_heads": 16, @@ -126,7 +122,6 @@ class TestBatchPagedAttention(SceneTestCase): { "name": "CaseSmall2", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 1, @@ -142,7 +137,6 @@ class TestBatchPagedAttention(SceneTestCase): { "name": "CaseSmall3", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 1, @@ -158,7 +152,6 @@ class TestBatchPagedAttention(SceneTestCase): { "name": "CaseVarSeq2", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 2, @@ -175,7 +168,6 @@ class TestBatchPagedAttention(SceneTestCase): { "name": "CaseVarSeq4", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 4, diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/dfx/args_dump/test_args_dump.py b/tests/st/a2a3/tensormap_and_ringbuffer/dfx/args_dump/test_args_dump.py index 24c61770e2..17e0b9a617 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/dfx/args_dump/test_args_dump.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/dfx/args_dump/test_args_dump.py @@ -83,7 +83,6 @@ class TestArgsDump(SceneTestCase): { "name": "default", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/dfx/dep_gen/test_dep_gen.py b/tests/st/a2a3/tensormap_and_ringbuffer/dfx/dep_gen/test_dep_gen.py index f74bdb3f50..f5249ad905 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/dfx/dep_gen/test_dep_gen.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/dfx/dep_gen/test_dep_gen.py @@ -88,7 +88,6 @@ class TestDepGen(SceneTestCase): { "name": "default", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane.py b/tests/st/a2a3/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane.py index ae2ef89663..cdfbde35f8 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane.py @@ -76,7 +76,6 @@ class TestL2Swimlane(SceneTestCase): { "name": "default", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, { diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane_mixed.py b/tests/st/a2a3/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane_mixed.py index 6e7cef98d1..8e8c9dceda 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane_mixed.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane_mixed.py @@ -88,7 +88,6 @@ class TestL2SwimlaneMixed(SceneTestCase): { "name": "default", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/dfx/pmu/test_pmu.py b/tests/st/a2a3/tensormap_and_ringbuffer/dfx/pmu/test_pmu.py index f33674933a..864c202e26 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/dfx/pmu/test_pmu.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/dfx/pmu/test_pmu.py @@ -69,7 +69,6 @@ class TestPmu(SceneTestCase): { "name": "default", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/dfx/scope_stats/test_scope_stats.py b/tests/st/a2a3/tensormap_and_ringbuffer/dfx/scope_stats/test_scope_stats.py index 5170d378e2..9b06b73207 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/dfx/scope_stats/test_scope_stats.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/dfx/scope_stats/test_scope_stats.py @@ -88,7 +88,6 @@ class TestScopeStats(SceneTestCase): { "name": "default", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, { diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/dynamic_register/test_dynamic_register.py b/tests/st/a2a3/tensormap_and_ringbuffer/dynamic_register/test_dynamic_register.py index f97378b2ef..d83f74f549 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/dynamic_register/test_dynamic_register.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/dynamic_register/test_dynamic_register.py @@ -155,7 +155,6 @@ def test_prepare_new_identity_after_start_then_run(st_platform, st_device_ids): worker.init() try: config = CallConfig() - config.aicpu_thread_num = 4 # 1. Run pre_handle once against the snapshot-prepared chip callable. # init() already forked the chip children and prepared the startup @@ -227,7 +226,6 @@ def test_prepare_new_identity_after_start_parallel_broadcast(st_platform, st_dev worker.init() try: config = CallConfig() - config.aicpu_thread_num = 4 def orch_pre(o, _a, _c): o.submit_next_level(pre_handle, chip_args_pre, config, worker=0) @@ -283,7 +281,6 @@ def test_prepare_capacity_overflow_post_start(st_platform, st_device_ids): worker.init() try: config = CallConfig() - config.aicpu_thread_num = 4 def orch_pre(o, _a, _c): o.submit_next_level(chip_handle, chip_args_pre, config, worker=0) @@ -332,7 +329,6 @@ def test_duplicate_prepare_same_hashid_survives_one_unregister(st_platform, st_d worker.init() try: config = CallConfig() - config.aicpu_thread_num = 4 # 1. Trigger fork via pre_handle to put the chip child into the main loop. def orch_one(o, _args, _cfg): @@ -402,7 +398,6 @@ def test_unregister_last_handle_allows_reprepare_same_hashid(st_platform, st_dev worker.init() try: config = CallConfig() - config.aicpu_thread_num = 4 def orch_one(o, _args, _cfg): o.submit_next_level(pre_handle, chip_args_one, config, worker=0) diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/fanin_lookup_perf/test_fanin_lookup_perf.py b/tests/st/a2a3/tensormap_and_ringbuffer/fanin_lookup_perf/test_fanin_lookup_perf.py index b0c133abcb..3d3dce4130 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/fanin_lookup_perf/test_fanin_lookup_perf.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/fanin_lookup_perf/test_fanin_lookup_perf.py @@ -49,13 +49,11 @@ class TestFaninLookupPerf(SceneTestCase): { "name": "LookupOnlyProducers64Consumers64", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {"producer_count": 64, "consumer_count": 64, "use_real_kernels": 0}, }, { "name": "SwimlaneProducers64Consumers64", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {"producer_count": 64, "consumer_count": 64, "use_real_kernels": 1}, }, ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/mixed_example/test_mixed_example.py b/tests/st/a2a3/tensormap_and_ringbuffer/mixed_example/test_mixed_example.py index d745b363a9..427073ea58 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/mixed_example/test_mixed_example.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/mixed_example/test_mixed_example.py @@ -98,14 +98,12 @@ class TestMixedExample(SceneTestCase): { "name": "case1", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {"num_iters": 4}, }, { "name": "case2", "manual": True, "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {"num_iters": 1}, }, ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/multi_round_paged_attention/test_multi_round_paged_attention.py b/tests/st/a2a3/tensormap_and_ringbuffer/multi_round_paged_attention/test_multi_round_paged_attention.py index a11f79f39d..97909684d8 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/multi_round_paged_attention/test_multi_round_paged_attention.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/multi_round_paged_attention/test_multi_round_paged_attention.py @@ -69,7 +69,6 @@ class TestMultiRoundPagedAttention(SceneTestCase): { "name": "Case1", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 1, "num_heads": 16, @@ -85,7 +84,6 @@ class TestMultiRoundPagedAttention(SceneTestCase): "name": "Case2", "platforms": ["a2a3sim", "a2a3"], "manual": True, - "config": {"aicpu_thread_num": 4}, "params": { "batch": 1, "num_heads": 16, @@ -101,7 +99,6 @@ class TestMultiRoundPagedAttention(SceneTestCase): "name": "CaseVarSeq2", "platforms": ["a2a3sim", "a2a3"], "manual": True, - "config": {"aicpu_thread_num": 4}, "params": { "batch": 2, "num_heads": 16, @@ -118,7 +115,6 @@ class TestMultiRoundPagedAttention(SceneTestCase): "name": "CaseVarSeq4", "platforms": ["a2a3sim", "a2a3"], "manual": True, - "config": {"aicpu_thread_num": 4}, "params": { "batch": 4, "num_heads": 16, diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/orch_so_cache/test_orch_so_cache.py b/tests/st/a2a3/tensormap_and_ringbuffer/orch_so_cache/test_orch_so_cache.py index 61e7b3e359..b707d63c5a 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/orch_so_cache/test_orch_so_cache.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/orch_so_cache/test_orch_so_cache.py @@ -72,7 +72,6 @@ class TestOrchSoCache(SceneTestCase): # Three cases sharing one callable. The framework iterates them on a # single Worker; cases after the first land on cache-hit. Sizes vary so # a stale handle would manifest as wrong output, not "happens to pass". - _COMMON_CONFIG = {"aicpu_thread_num": 4} _PLATFORMS = ["a2a3sim", "a2a3"] # All cases use the same size (128*128) because the AIV kernels have @@ -84,19 +83,16 @@ class TestOrchSoCache(SceneTestCase): { "name": "first_miss", "platforms": _PLATFORMS, - "config": _COMMON_CONFIG, "params": {"size": 128 * 128, "a": 2.0, "b": 3.0}, }, { "name": "second_hit", "platforms": _PLATFORMS, - "config": _COMMON_CONFIG, "params": {"size": 128 * 128, "a": 1.0, "b": 4.0}, }, { "name": "third_hit", "platforms": _PLATFORMS, - "config": _COMMON_CONFIG, "params": {"size": 128 * 128, "a": 0.5, "b": 0.5}, }, ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/paged_attention_unroll/test_paged_attention_unroll.py b/tests/st/a2a3/tensormap_and_ringbuffer/paged_attention_unroll/test_paged_attention_unroll.py index cbaff55a5d..40c31af915 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/paged_attention_unroll/test_paged_attention_unroll.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/paged_attention_unroll/test_paged_attention_unroll.py @@ -64,7 +64,6 @@ class TestPagedAttentionUnroll(SceneTestCase): { "name": "Case1", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 256, "num_heads": 16, @@ -79,7 +78,6 @@ class TestPagedAttentionUnroll(SceneTestCase): { "name": "Case2", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, @@ -95,7 +93,6 @@ class TestPagedAttentionUnroll(SceneTestCase): { "name": "Case3", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/paged_attention_unroll_4dims/test_paged_attention_unroll_4dims.py b/tests/st/a2a3/tensormap_and_ringbuffer/paged_attention_unroll_4dims/test_paged_attention_unroll_4dims.py index 388a10d185..87aa6c8a23 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/paged_attention_unroll_4dims/test_paged_attention_unroll_4dims.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/paged_attention_unroll_4dims/test_paged_attention_unroll_4dims.py @@ -67,7 +67,6 @@ class TestPagedAttentionUnroll4dims(SceneTestCase): { "name": "Case1", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 256, "num_heads": 16, @@ -82,7 +81,6 @@ class TestPagedAttentionUnroll4dims(SceneTestCase): { "name": "Case2", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 64, "num_heads": 64, @@ -98,7 +96,6 @@ class TestPagedAttentionUnroll4dims(SceneTestCase): { "name": "Case3", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 64, "num_heads": 64, diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/prepared_callable/test_prepared_callable.py b/tests/st/a2a3/tensormap_and_ringbuffer/prepared_callable/test_prepared_callable.py index 319426ffc6..cd64818302 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/prepared_callable/test_prepared_callable.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/prepared_callable/test_prepared_callable.py @@ -71,14 +71,12 @@ class TestPreparedCallable(SceneTestCase): ], } - _COMMON_CONFIG = {"aicpu_thread_num": 4} _PLATFORMS = ["a2a3sim", "a2a3"] CASES = [ { "name": "prepare_run_twice", "platforms": _PLATFORMS, - "config": _COMMON_CONFIG, "params": {"a": 2.0, "b": 3.0}, }, ] @@ -163,7 +161,7 @@ def _setup_dlopen_count_test(self, st_worker, st_platform): """Common fixture: build callable + config, return (callable, config, case).""" case = self.CASES[0] callable_obj = self.build_callable(st_platform) - config = self._build_config(case["config"]) + config = self._build_config(case.get("config", {})) return callable_obj, config, case def _run_one(self, worker, slot, config, case): @@ -279,7 +277,7 @@ class MissingEntryCallable(type(self)): MissingEntryCallable.CALLABLE["orchestration"]["function_name"] = "missing_aicpu_orchestration_entry" bad_callable = MissingEntryCallable().build_callable(st_platform) - config = self._build_config(self.CASES[0]["config"]) + config = self._build_config(self.CASES[0].get("config", {})) case = self.CASES[0] baseline = st_worker.aicpu_dlopen_count chip_worker = self._chip_worker(st_worker) diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_basic/test_spmd_basic.py b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_basic/test_spmd_basic.py index 70a3c0018b..5254d5ba7c 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_basic/test_spmd_basic.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_basic/test_spmd_basic.py @@ -68,7 +68,6 @@ class TestSpmdBasic(SceneTestCase): { "name": "Case1", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_batch_dispatch_oob/test_spmd_batch_dispatch_oob.py b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_batch_dispatch_oob/test_spmd_batch_dispatch_oob.py index 7dcb76996b..e62b61799b 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_batch_dispatch_oob/test_spmd_batch_dispatch_oob.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_batch_dispatch_oob/test_spmd_batch_dispatch_oob.py @@ -67,7 +67,6 @@ class TestSpmdBatchDispatchOob(SceneTestCase): { "name": "Case1", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_multiblock_aiv/test_spmd_multiblock_aiv.py b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_multiblock_aiv/test_spmd_multiblock_aiv.py index 593034a1ca..a01863a7f8 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_multiblock_aiv/test_spmd_multiblock_aiv.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_multiblock_aiv/test_spmd_multiblock_aiv.py @@ -50,7 +50,6 @@ class TestSpmdMultiblockAiv(SceneTestCase): { "name": "Case1", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_multiblock_mix/test_spmd_multiblock_mix.py b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_multiblock_mix/test_spmd_multiblock_mix.py index d0552eac69..491645ce6b 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_multiblock_mix/test_spmd_multiblock_mix.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_multiblock_mix/test_spmd_multiblock_mix.py @@ -68,7 +68,6 @@ class TestSpmdMultiblockMix(SceneTestCase): { "name": "Case1", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_paged_attention/test_spmd_paged_attention.py b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_paged_attention/test_spmd_paged_attention.py index 993cd92efd..c174545fe6 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_paged_attention/test_spmd_paged_attention.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_paged_attention/test_spmd_paged_attention.py @@ -57,7 +57,6 @@ class TestPagedAttentionUnrollTpushPop(SceneTestCase): { "name": "Case1", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 256, "num_heads": 16, @@ -72,7 +71,6 @@ class TestPagedAttentionUnrollTpushPop(SceneTestCase): { "name": "Case2", "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, @@ -94,7 +92,6 @@ class TestPagedAttentionUnrollTpushPop(SceneTestCase): "name": "SmallCase1", "platforms": ["a2a3"], "manual": True, - "config": {"aicpu_thread_num": 4}, "params": { "batch": 24, "num_heads": 16, diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_paged_attention_highperf/test_spmd_paged_attention_highperf.py b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_paged_attention_highperf/test_spmd_paged_attention_highperf.py index 292e667a17..cd730d786a 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_paged_attention_highperf/test_spmd_paged_attention_highperf.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_paged_attention_highperf/test_spmd_paged_attention_highperf.py @@ -174,7 +174,6 @@ class TestSpmdPagedAttentionHighPerf(SceneTestCase): # producer-side DdrBarrierBeforeFfts cross-core DDR fence, validated # over 19 st-onboard-a2a3 rounds. "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 1, "num_heads": 32, @@ -190,7 +189,6 @@ class TestSpmdPagedAttentionHighPerf(SceneTestCase): "name": "b4_h32_kv8_s512_bs128_fp16", "manual": True, "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 4, "num_heads": 32, @@ -206,7 +204,6 @@ class TestSpmdPagedAttentionHighPerf(SceneTestCase): "name": "b1_h32_kv8_s16384_bs128_fp16", "manual": True, "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 1, "num_heads": 32, @@ -222,7 +219,6 @@ class TestSpmdPagedAttentionHighPerf(SceneTestCase): "name": "b1_h32_kv8_s4096_bs128_fp16", "manual": True, "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 1, "num_heads": 32, @@ -238,7 +234,6 @@ class TestSpmdPagedAttentionHighPerf(SceneTestCase): "name": "b1_h32_kv8_s6144_bs128_fp16", "manual": True, "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 1, "num_heads": 32, @@ -254,7 +249,6 @@ class TestSpmdPagedAttentionHighPerf(SceneTestCase): "name": "b1_h32_kv8_s8192_bs128_fp16", # enabled in CI to guard the long-sequence fix onboard. "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 1, "num_heads": 32, @@ -270,7 +264,6 @@ class TestSpmdPagedAttentionHighPerf(SceneTestCase): "name": "b2_h32_kv8_s4096_bs128_fp16", "manual": True, "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 2, "num_heads": 32, @@ -286,7 +279,6 @@ class TestSpmdPagedAttentionHighPerf(SceneTestCase): "name": "b2_h32_kv8_s8192_bs128_fp16", "manual": True, "platforms": ["a2a3"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 2, "num_heads": 32, diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_starvation/test_spmd_starvation.py b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_starvation/test_spmd_starvation.py index 1606504954..4200621dd5 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_starvation/test_spmd_starvation.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_starvation/test_spmd_starvation.py @@ -85,7 +85,6 @@ class TestSpmdStarvation(SceneTestCase): { "name": "Case1", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start/test_spmd_sync_start.py b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start/test_spmd_sync_start.py index c392a42a3c..f5094f84b8 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start/test_spmd_sync_start.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start/test_spmd_sync_start.py @@ -70,7 +70,6 @@ class TestSpmdSyncStart(SceneTestCase): { "name": "Case1", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_aiv/test_spmd_sync_start_aiv.py b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_aiv/test_spmd_sync_start_aiv.py index f4f75afc29..6c21eb4bc7 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_aiv/test_spmd_sync_start_aiv.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_aiv/test_spmd_sync_start_aiv.py @@ -54,7 +54,6 @@ class TestSpmdSyncStartAiv(SceneTestCase): { "name": "Case1", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_early_dispatch/test_spmd_sync_start_early_dispatch.py b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_early_dispatch/test_spmd_sync_start_early_dispatch.py index d87eeea09a..1fc1f61e0e 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_early_dispatch/test_spmd_sync_start_early_dispatch.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_early_dispatch/test_spmd_sync_start_early_dispatch.py @@ -78,7 +78,6 @@ class TestSpmdSyncStartEarlyDispatch(SceneTestCase): { "name": "Case1", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_edge/test_spmd_sync_start_edge.py b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_edge/test_spmd_sync_start_edge.py index e5003ddb5f..3c788efad0 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_edge/test_spmd_sync_start_edge.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_edge/test_spmd_sync_start_edge.py @@ -68,7 +68,6 @@ class TestSpmdSyncStartEdge(SceneTestCase): { "name": "Case1", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_stress/test_spmd_sync_start_stress.py b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_stress/test_spmd_sync_start_stress.py index 1b859b2138..d90b86ada9 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_stress/test_spmd_sync_start_stress.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/spmd_sync_start_stress/test_spmd_sync_start_stress.py @@ -100,7 +100,6 @@ class TestSpmdSyncStartStress(SceneTestCase): { "name": "Case1", "platforms": ["a2a3sim", "a2a3"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/test_l3_dependency.py b/tests/st/a2a3/tensormap_and_ringbuffer/test_l3_dependency.py index f5e8046b00..85fd0a394e 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/test_l3_dependency.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/test_l3_dependency.py @@ -85,7 +85,7 @@ class TestL3Dependency(SceneTestCase): { "name": "default", "platforms": ["a2a3sim", "a2a3"], - "config": {"device_count": 1, "num_sub_workers": 1, "aicpu_thread_num": 4}, + "config": {"device_count": 1, "num_sub_workers": 1}, "params": {}, }, ] diff --git a/tests/st/a2a3/tensormap_and_ringbuffer/test_l3_group.py b/tests/st/a2a3/tensormap_and_ringbuffer/test_l3_group.py index 686fc5d56c..767e15af81 100644 --- a/tests/st/a2a3/tensormap_and_ringbuffer/test_l3_group.py +++ b/tests/st/a2a3/tensormap_and_ringbuffer/test_l3_group.py @@ -95,7 +95,7 @@ class TestL3Group(SceneTestCase): { "name": "default", "platforms": ["a2a3sim", "a2a3"], - "config": {"device_count": 2, "num_sub_workers": 1, "aicpu_thread_num": 4}, + "config": {"device_count": 2, "num_sub_workers": 1}, "params": {}, }, ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/available_aicore_counts/test_available_aicore_counts.py b/tests/st/a5/tensormap_and_ringbuffer/available_aicore_counts/test_available_aicore_counts.py index 157b60f895..1860799c30 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/available_aicore_counts/test_available_aicore_counts.py +++ b/tests/st/a5/tensormap_and_ringbuffer/available_aicore_counts/test_available_aicore_counts.py @@ -79,7 +79,6 @@ class TestAvailableAicoreCounts(SceneTestCase): { "name": "Default", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/dfx/args_dump/test_args_dump.py b/tests/st/a5/tensormap_and_ringbuffer/dfx/args_dump/test_args_dump.py index 3eada64391..37d09d0d1a 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/dfx/args_dump/test_args_dump.py +++ b/tests/st/a5/tensormap_and_ringbuffer/dfx/args_dump/test_args_dump.py @@ -83,7 +83,6 @@ class TestArgsDump(SceneTestCase): { "name": "default", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/dfx/dep_gen/test_dep_gen.py b/tests/st/a5/tensormap_and_ringbuffer/dfx/dep_gen/test_dep_gen.py index 2c29030b58..2d10b818ff 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/dfx/dep_gen/test_dep_gen.py +++ b/tests/st/a5/tensormap_and_ringbuffer/dfx/dep_gen/test_dep_gen.py @@ -88,7 +88,6 @@ class TestDepGen(SceneTestCase): { "name": "default", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane.py b/tests/st/a5/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane.py index 859bfb00bc..f582d85cbe 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane.py +++ b/tests/st/a5/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane.py @@ -76,7 +76,6 @@ class TestL2Swimlane(SceneTestCase): { "name": "default", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, { diff --git a/tests/st/a5/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane_mixed.py b/tests/st/a5/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane_mixed.py index a2af269a42..d679ac2ad9 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane_mixed.py +++ b/tests/st/a5/tensormap_and_ringbuffer/dfx/l2_swimlane/test_l2_swimlane_mixed.py @@ -88,7 +88,6 @@ class TestL2SwimlaneMixed(SceneTestCase): { "name": "default", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/dfx/pmu/test_pmu.py b/tests/st/a5/tensormap_and_ringbuffer/dfx/pmu/test_pmu.py index 2f48028f1e..bca24cf47c 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/dfx/pmu/test_pmu.py +++ b/tests/st/a5/tensormap_and_ringbuffer/dfx/pmu/test_pmu.py @@ -69,7 +69,6 @@ class TestPmu(SceneTestCase): { "name": "default", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/dfx/scope_stats/test_scope_stats.py b/tests/st/a5/tensormap_and_ringbuffer/dfx/scope_stats/test_scope_stats.py index f42c700059..7c60e0a171 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/dfx/scope_stats/test_scope_stats.py +++ b/tests/st/a5/tensormap_and_ringbuffer/dfx/scope_stats/test_scope_stats.py @@ -88,7 +88,6 @@ class TestScopeStats(SceneTestCase): { "name": "default", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, { diff --git a/tests/st/a5/tensormap_and_ringbuffer/mixed_example/test_mixed_example.py b/tests/st/a5/tensormap_and_ringbuffer/mixed_example/test_mixed_example.py index dbd52bb444..1cd287323d 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/mixed_example/test_mixed_example.py +++ b/tests/st/a5/tensormap_and_ringbuffer/mixed_example/test_mixed_example.py @@ -95,14 +95,12 @@ class TestMixedExample(SceneTestCase): { "name": "case1", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {"num_iters": 4}, }, { "name": "case2", "manual": True, "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {"num_iters": 1}, }, ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/orch_so_cache/test_orch_so_cache.py b/tests/st/a5/tensormap_and_ringbuffer/orch_so_cache/test_orch_so_cache.py index a8109fca0f..87078faeb1 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/orch_so_cache/test_orch_so_cache.py +++ b/tests/st/a5/tensormap_and_ringbuffer/orch_so_cache/test_orch_so_cache.py @@ -72,7 +72,6 @@ class TestOrchSoCache(SceneTestCase): # Three cases sharing one callable. The framework iterates them on a # single Worker; cases after the first land on cache-hit. Sizes vary so # a stale handle would manifest as wrong output, not "happens to pass". - _COMMON_CONFIG = {"aicpu_thread_num": 4} _PLATFORMS = ["a5sim", "a5"] # All cases use the same size (128*128) because the AIV kernels have @@ -84,19 +83,16 @@ class TestOrchSoCache(SceneTestCase): { "name": "first_miss", "platforms": _PLATFORMS, - "config": _COMMON_CONFIG, "params": {"size": 128 * 128, "a": 2.0, "b": 3.0}, }, { "name": "second_hit", "platforms": _PLATFORMS, - "config": _COMMON_CONFIG, "params": {"size": 128 * 128, "a": 1.0, "b": 4.0}, }, { "name": "third_hit", "platforms": _PLATFORMS, - "config": _COMMON_CONFIG, "params": {"size": 128 * 128, "a": 0.5, "b": 0.5}, }, ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/paged_attention_unroll/test_paged_attention_unroll.py b/tests/st/a5/tensormap_and_ringbuffer/paged_attention_unroll/test_paged_attention_unroll.py index 92165381f2..3070d355b8 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/paged_attention_unroll/test_paged_attention_unroll.py +++ b/tests/st/a5/tensormap_and_ringbuffer/paged_attention_unroll/test_paged_attention_unroll.py @@ -64,7 +64,6 @@ class TestPagedAttentionUnroll(SceneTestCase): { "name": "Case1", "platforms": ["a5"], - "config": {"aicpu_thread_num": 4}, "params": { "batch": 256, "num_heads": 16, @@ -79,7 +78,6 @@ class TestPagedAttentionUnroll(SceneTestCase): { "name": "Case2", "platforms": ["a5"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, @@ -95,7 +93,6 @@ class TestPagedAttentionUnroll(SceneTestCase): { "name": "Case3", "platforms": ["a5"], - "config": {"aicpu_thread_num": 4}, "manual": True, "params": { "batch": 64, diff --git a/tests/st/a5/tensormap_and_ringbuffer/prepared_callable/test_prepared_callable.py b/tests/st/a5/tensormap_and_ringbuffer/prepared_callable/test_prepared_callable.py index d1ba9053de..8465e76a57 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/prepared_callable/test_prepared_callable.py +++ b/tests/st/a5/tensormap_and_ringbuffer/prepared_callable/test_prepared_callable.py @@ -72,14 +72,12 @@ class TestPreparedCallable(SceneTestCase): ], } - _COMMON_CONFIG = {"aicpu_thread_num": 4} _PLATFORMS = ["a5sim", "a5"] CASES = [ { "name": "prepare_run_twice", "platforms": _PLATFORMS, - "config": _COMMON_CONFIG, "params": {"a": 2.0, "b": 3.0}, }, ] @@ -164,7 +162,7 @@ def _setup_dlopen_count_test(self, st_worker, st_platform): """Common fixture: build callable + config, return (callable, config, case).""" case = self.CASES[0] callable_obj = self.build_callable(st_platform) - config = self._build_config(case["config"]) + config = self._build_config(case.get("config", {})) return callable_obj, config, case def _run_one(self, worker, slot, config, case): @@ -248,7 +246,7 @@ class MissingEntryCallable(type(self)): MissingEntryCallable.CALLABLE["orchestration"]["function_name"] = "missing_aicpu_orchestration_entry" bad_callable = MissingEntryCallable().build_callable(st_platform) - config = self._build_config(self.CASES[0]["config"]) + config = self._build_config(self.CASES[0].get("config", {})) case = self.CASES[0] baseline = st_worker.aicpu_dlopen_count chip_worker = self._chip_worker(st_worker) diff --git a/tests/st/a5/tensormap_and_ringbuffer/simt_basic/test_simt_basic.py b/tests/st/a5/tensormap_and_ringbuffer/simt_basic/test_simt_basic.py index b2d8fff4e0..0168fb3113 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/simt_basic/test_simt_basic.py +++ b/tests/st/a5/tensormap_and_ringbuffer/simt_basic/test_simt_basic.py @@ -9,7 +9,7 @@ # ----------------------------------------------------------------------------------------------------------- """SIMT basic element-scatter: minimal AIV scatter kernel that exercises the SIMT launch path. -Config: aicpu_thread_num=4, sequential identity indices. +Config: default aicpu_thread_num (auto), sequential identity indices. Identity indices keep the golden trivially src-equals-out so a failure here points at the SIMT launch path itself (TLV injection, localMemorySize budget, sync) rather than at the scatter index semantics. @@ -52,7 +52,6 @@ class TestSimtBasic(SceneTestCase): { "name": "Case1", "platforms": ["a5", "a5sim"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/spmd_basic/test_spmd_basic.py b/tests/st/a5/tensormap_and_ringbuffer/spmd_basic/test_spmd_basic.py index a7394ad88a..f6ca4c8978 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/spmd_basic/test_spmd_basic.py +++ b/tests/st/a5/tensormap_and_ringbuffer/spmd_basic/test_spmd_basic.py @@ -68,7 +68,6 @@ class TestSpmdBasic(SceneTestCase): { "name": "Case1", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, }, ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/spmd_multiblock_aiv/test_spmd_multiblock_aiv.py b/tests/st/a5/tensormap_and_ringbuffer/spmd_multiblock_aiv/test_spmd_multiblock_aiv.py index f9d6f07500..c0b9f3bc77 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/spmd_multiblock_aiv/test_spmd_multiblock_aiv.py +++ b/tests/st/a5/tensormap_and_ringbuffer/spmd_multiblock_aiv/test_spmd_multiblock_aiv.py @@ -43,7 +43,6 @@ class TestSpmdMultiblockAiv(SceneTestCase): { "name": "Case1", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/spmd_multiblock_mix/test_spmd_multiblock_mix.py b/tests/st/a5/tensormap_and_ringbuffer/spmd_multiblock_mix/test_spmd_multiblock_mix.py index e6b7b734c5..fd7bb57a62 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/spmd_multiblock_mix/test_spmd_multiblock_mix.py +++ b/tests/st/a5/tensormap_and_ringbuffer/spmd_multiblock_mix/test_spmd_multiblock_mix.py @@ -64,7 +64,6 @@ class TestSpmdMultiblockMix(SceneTestCase): { "name": "Case1", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/spmd_starvation/test_spmd_starvation.py b/tests/st/a5/tensormap_and_ringbuffer/spmd_starvation/test_spmd_starvation.py index 45c20237ed..05190dbb1c 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/spmd_starvation/test_spmd_starvation.py +++ b/tests/st/a5/tensormap_and_ringbuffer/spmd_starvation/test_spmd_starvation.py @@ -85,7 +85,6 @@ class TestSpmdStarvation(SceneTestCase): { "name": "Case1", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start/test_spmd_sync_start.py b/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start/test_spmd_sync_start.py index 7d5585e504..58c0130e66 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start/test_spmd_sync_start.py +++ b/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start/test_spmd_sync_start.py @@ -70,7 +70,6 @@ class TestSpmdSyncStart(SceneTestCase): { "name": "Case1", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_aiv/test_spmd_sync_start_aiv.py b/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_aiv/test_spmd_sync_start_aiv.py index d66af12cb2..8757f95dc8 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_aiv/test_spmd_sync_start_aiv.py +++ b/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_aiv/test_spmd_sync_start_aiv.py @@ -52,7 +52,6 @@ class TestSpmdSyncStartAiv(SceneTestCase): { "name": "Case1", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_early_dispatch/test_spmd_sync_start_early_dispatch.py b/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_early_dispatch/test_spmd_sync_start_early_dispatch.py index f468afde84..fcb51da594 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_early_dispatch/test_spmd_sync_start_early_dispatch.py +++ b/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_early_dispatch/test_spmd_sync_start_early_dispatch.py @@ -78,13 +78,11 @@ class TestSpmdSyncStartEarlyDispatch(SceneTestCase): { "name": "EarlyOn", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {"early_on": 1}, }, { "name": "EarlyOff", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {"early_on": 0}, }, ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_edge/test_spmd_sync_start_edge.py b/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_edge/test_spmd_sync_start_edge.py index 9794331214..986c4b1bab 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_edge/test_spmd_sync_start_edge.py +++ b/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_edge/test_spmd_sync_start_edge.py @@ -68,7 +68,6 @@ class TestSpmdSyncStartEdge(SceneTestCase): { "name": "Case1", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_mix_spill/test_spmd_sync_start_mix_spill.py b/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_mix_spill/test_spmd_sync_start_mix_spill.py index 175b552dc5..91a4e0e3d4 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_mix_spill/test_spmd_sync_start_mix_spill.py +++ b/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_mix_spill/test_spmd_sync_start_mix_spill.py @@ -81,13 +81,11 @@ class TestSpmdSyncStartMixSpill(SceneTestCase): { "name": "EarlyOn", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {"early_on": 1}, }, { "name": "EarlyOff", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {"early_on": 0}, }, ] diff --git a/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_stress/test_spmd_sync_start_stress.py b/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_stress/test_spmd_sync_start_stress.py index 4f5f1c1d0f..3965ba51ee 100644 --- a/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_stress/test_spmd_sync_start_stress.py +++ b/tests/st/a5/tensormap_and_ringbuffer/spmd_sync_start_stress/test_spmd_sync_start_stress.py @@ -100,7 +100,6 @@ class TestSpmdSyncStartStress(SceneTestCase): { "name": "Case1", "platforms": ["a5sim", "a5"], - "config": {"aicpu_thread_num": 4}, "params": {}, } ] diff --git a/tests/st/task_timing/task_timing_slots/test_task_timing_e2e.py b/tests/st/task_timing/task_timing_slots/test_task_timing_e2e.py index fa0f3de089..feebc21fd7 100644 --- a/tests/st/task_timing/task_timing_slots/test_task_timing_e2e.py +++ b/tests/st/task_timing/task_timing_slots/test_task_timing_e2e.py @@ -314,7 +314,6 @@ def test_mix_task_aggregates_across_subtasks(st_platform, st_device_ids, capfd): platform=st_platform, runtime="tensormap_and_ringbuffer", device_id=int(st_device_ids[0]), - aicpu_thread_num=4, ) chip_handle = worker.register(_build_mix_chip_callable(st_platform)) worker.init() diff --git a/tests/ut/cpp/CMakeLists.txt b/tests/ut/cpp/CMakeLists.txt index cc75282a04..3e14663567 100644 --- a/tests/ut/cpp/CMakeLists.txt +++ b/tests/ut/cpp/CMakeLists.txt @@ -760,6 +760,27 @@ target_link_libraries(test_a2a3_aicpu_affinity_select PRIVATE add_test(NAME test_a2a3_aicpu_affinity_select COMMAND test_a2a3_aicpu_affinity_select) set_tests_properties(test_a2a3_aicpu_affinity_select PROPERTIES LABELS "no_hardware") +# a5 host-side AICPU affinity selection. Like the a2a3 test above, this +# exercises only pure placement logic and needs no device. +set(A5_ONBOARD_HOST_DIR ${CMAKE_SOURCE_DIR}/../../../src/a5/platform/onboard/host) +add_executable(test_a5_aicpu_affinity_select + a5/test_aicpu_affinity_select.cpp + ${A5_ONBOARD_HOST_DIR}/aicpu_topology_probe.cpp +) +target_include_directories(test_a5_aicpu_affinity_select PRIVATE + ${GTEST_INCLUDE_DIRS} + ${A5_ONBOARD_HOST_DIR} + ${SIMPLER_LOG_DIR}/include +) +target_link_libraries(test_a5_aicpu_affinity_select PRIVATE + ${GTEST_MAIN_LIB} + ${GTEST_LIB} + ${CMAKE_DL_LIBS} + pthread +) +add_test(NAME test_a5_aicpu_affinity_select COMMAND test_a5_aicpu_affinity_select) +set_tests_properties(test_a5_aicpu_affinity_select PROPERTIES LABELS "no_hardware") + # Hardware-gated tests. Block is only entered when the project is configured # with -DSIMPLER_ENABLE_HARDWARE_TESTS=ON. CI's no-hw `ut` job does not pass # this flag, so nothing here is compiled there — this is the structural diff --git a/tests/ut/cpp/a2a3/test_aicpu_affinity_select.cpp b/tests/ut/cpp/a2a3/test_aicpu_affinity_select.cpp index 97c2793393..7946698f3c 100644 --- a/tests/ut/cpp/a2a3/test_aicpu_affinity_select.cpp +++ b/tests/ut/cpp/a2a3/test_aicpu_affinity_select.cpp @@ -45,6 +45,7 @@ void unified_log_debug(const char *, const char *, ...) {} using pto::a2a3::AicpuLogicalCpu; using pto::a2a3::compute_allowed_cpus; +using pto::a2a3::compute_auto_allowed_cpus; namespace { @@ -122,3 +123,23 @@ TEST(A2a3AffinitySelect, RejectsNonPositiveCount) { EXPECT_FALSE(compute_allowed_cpus(standard_pool(), 0, allowed)); EXPECT_FALSE(compute_allowed_cpus(standard_pool(), -1, allowed)); } + +TEST(A2a3AffinitySelect, AutoUsesEveryCpuInLargestCluster) { + std::vector allowed; + ASSERT_TRUE(compute_auto_allowed_cpus(standard_pool(), allowed)); + EXPECT_EQ(allowed, (std::vector{4, 5, 6, 7})); +} + +TEST(A2a3AffinitySelect, AutoBreaksEqualSizeTieByHigherCluster) { + std::vector pool = {cpu(2), cpu(3), cpu(4), cpu(5)}; + std::vector allowed; + ASSERT_TRUE(compute_auto_allowed_cpus(pool, allowed)); + EXPECT_EQ(allowed, (std::vector{4, 5})); +} + +TEST(A2a3AffinitySelect, AutoRejectsClustersWithOnlyOneCpu) { + std::vector pool = {cpu(3), cpu(7)}; + std::vector allowed; + EXPECT_FALSE(compute_auto_allowed_cpus(pool, allowed)); + EXPECT_TRUE(allowed.empty()); +} diff --git a/tests/ut/cpp/a5/test_aicpu_affinity_select.cpp b/tests/ut/cpp/a5/test_aicpu_affinity_select.cpp new file mode 100644 index 0000000000..0d7127739a --- /dev/null +++ b/tests/ut/cpp/a5/test_aicpu_affinity_select.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) PyPTO Contributors. + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of + * CANN Open Software License Agreement Version 2.0 (the "License"). + * Please refer to the License for details. You may not use this file except in compliance with the License. + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. + * See LICENSE in the root of the software repository for the full text of the License. + * ----------------------------------------------------------------------------------------------------------- + */ + +#include + +#include + +#include "aicpu_topology_probe.h" + +extern "C" { +void unified_log_error(const char *, const char *, ...) {} +void unified_log_warn(const char *, const char *, ...) {} +void unified_log_timing(const char *, const char *, ...) {} +void unified_log_info(const char *, const char *, ...) {} +void unified_log_debug(const char *, const char *, ...) {} +} + +using pto::a5::AicpuLogicalCpu; +using pto::a5::compute_auto_allowed_cpus; + +namespace { + +AicpuLogicalCpu cpu(int32_t cpu_id, int32_t phy_cpu_id) { + return AicpuLogicalCpu{ + cpu_id, phy_cpu_id, /*hyperthread_id=*/0, /*cluster_id=*/phy_cpu_id / 2, /*die_id=*/phy_cpu_id / 4 + }; +} + +} // namespace + +TEST(A5AffinitySelect, AutoUsesEveryCpuInLargestDie) { + std::vector pool = { + cpu(3, 2), cpu(4, 3), cpu(5, 4), cpu(6, 5), cpu(7, 6), cpu(8, 7), + }; + std::vector allowed; + ASSERT_TRUE(compute_auto_allowed_cpus(pool, allowed)); + ASSERT_EQ(allowed.size(), 4u); + EXPECT_EQ(allowed.back(), 8); + for (int32_t id : allowed) + EXPECT_GE(id, 5); +} + +TEST(A5AffinitySelect, AutoBreaksEqualSizeTieByHigherDie) { + std::vector pool = { + cpu(3, 2), + cpu(4, 3), + cpu(5, 4), + cpu(6, 5), + }; + std::vector allowed; + ASSERT_TRUE(compute_auto_allowed_cpus(pool, allowed)); + EXPECT_EQ(allowed, (std::vector{5, 6})); +} + +TEST(A5AffinitySelect, AutoRejectsDiesWithOnlyOneCpu) { + std::vector pool = {cpu(4, 3), cpu(5, 4)}; + std::vector allowed; + EXPECT_FALSE(compute_auto_allowed_cpus(pool, allowed)); + EXPECT_TRUE(allowed.empty()); +} diff --git a/tests/ut/py/test_chip_worker.py b/tests/ut/py/test_chip_worker.py index c27df08930..e8ae210d9c 100644 --- a/tests/ut/py/test_chip_worker.py +++ b/tests/ut/py/test_chip_worker.py @@ -20,8 +20,8 @@ class TestCallConfig: def test_defaults(self): config = CallConfig() # 0 is the "auto" sentinel — DeviceRunner resolves it at run() time - # to the max the AICore stream allows. - assert config.aicpu_thread_num == 3 + # to PLATFORM_DEFAULT_AICPU_THREAD_NUM, clamped to the probed usable pool. + assert config.aicpu_thread_num == 0 assert config.enable_l2_swimlane == 0 assert config.enable_dump_args == 0 assert config.enable_pmu == 0 @@ -296,7 +296,7 @@ def test_public_wrapper_rejects_raw_slot_run(self): worker = ChipWorker() with pytest.raises(TypeError, match="CallableHandle returned by ChipWorker.register_callable"): - worker.run(0, ChipStorageTaskArgs(), CallConfig()) + worker.run(0, ChipStorageTaskArgs(), CallConfig()) # pyright: ignore[reportArgumentType] # ============================================================================