Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/a2a3/runtime/tensormap_and_ringbuffer/aicpu/aicpu_executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -695,9 +695,20 @@ int32_t AicpuExecutor::run(Runtime *runtime) {

#if SIMPLER_DFX
// dep_gen plugs into the orchestrator thread (single-instance subsystem):
// record the per-thread ready_queue index before any submit_task fires
// inside orch_func_.
// resolve its buffer state and record the per-thread ready_queue index
// before any submit_task fires inside orch_func_. The init belongs to
// this thread, not to the scheduler cold path: dep_gen needs nothing
// from the AICore handshake, while the orchestrator skips that
// handshake entirely on the decoupled path and starts submitting
// immediately. Initialising it behind the handshake makes the first
// submits race a barrier they never joined — and the wider the device,
// the longer that handshake, so the orchestrator wins more of the race
// the more clusters there are.
//
// The free_queue is SPSC: this must remain the only site that pops
// from it on the device side.
if (is_dep_gen_enabled()) {
dep_gen_aicpu_init();
dep_gen_aicpu_set_orch_thread_idx(thread_idx);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -981,9 +981,7 @@ void SchedulerContext::post_handshake_profiling_init() {
pmu_aicpu_init(physical_core_ids_, cores_total_num_);
LOG_INFO_V0("PMU profiling started on %d cores", cores_total_num_);
}
if (is_dep_gen_enabled()) {
dep_gen_aicpu_init();
}
if (is_dep_gen_enabled()) {}
#endif
}

Expand Down Expand Up @@ -1224,9 +1222,7 @@ int32_t SchedulerContext::post_handshake_init(Runtime *runtime) {
// init() only pops the initial buffer from instance 0's free_queue; the
// orchestrator thread still records its idx via
// dep_gen_aicpu_set_orch_thread_idx() before the first record_submit.
if (is_dep_gen_enabled()) {
dep_gen_aicpu_init();
}
if (is_dep_gen_enabled()) {}
#endif

// total_tasks_ is read in pre_handshake_init (before the orchestrator's early
Expand Down
15 changes: 13 additions & 2 deletions src/a5/runtime/tensormap_and_ringbuffer/aicpu/aicpu_executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,9 +696,20 @@ int32_t AicpuExecutor::run(Runtime *runtime) {
scope_stats_aicpu_set_orch_thread_idx(thread_idx);

// dep_gen plugs into the orchestrator thread (single-instance subsystem):
// record the per-thread ready_queue index before any submit_task fires
// inside orch_func_.
// resolve its buffer state and record the per-thread ready_queue index
// before any submit_task fires inside orch_func_. The init belongs to
// this thread, not to the scheduler cold path: dep_gen needs nothing
// from the AICore handshake, while the orchestrator skips that
// handshake entirely on the decoupled path and starts submitting
// immediately. Initialising it behind the handshake makes the first
// submits race a barrier they never joined — and the wider the device,
// the longer that handshake, so the orchestrator wins more of the race
// the more clusters there are.
//
// The free_queue is SPSC: this must remain the only site that pops
// from it on the device side.
if (is_dep_gen_enabled()) {
dep_gen_aicpu_init();
dep_gen_aicpu_set_orch_thread_idx(thread_idx);
}
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -973,9 +973,7 @@ void SchedulerContext::post_handshake_profiling_init() {
pmu_aicpu_init(physical_core_ids_, cores_total_num_);
LOG_INFO_V0("PMU profiling started on %d cores", cores_total_num_);
}
if (is_dep_gen_enabled()) {
dep_gen_aicpu_init();
}
if (is_dep_gen_enabled()) {}
#endif
}

Expand Down Expand Up @@ -1220,9 +1218,7 @@ int32_t SchedulerContext::post_handshake_init(Runtime *runtime) {
// init() only pops the initial buffer from instance 0's free_queue; the
// orchestrator thread still records its idx via
// dep_gen_aicpu_set_orch_thread_idx() before the first record_submit.
if (is_dep_gen_enabled()) {
dep_gen_aicpu_init();
}
if (is_dep_gen_enabled()) {}
#endif

// total_tasks_ is read in pre_handshake_init (before the orchestrator's early
Expand Down
19 changes: 18 additions & 1 deletion src/common/platform/shared/aicpu/dep_gen_collector_aicpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ static bool g_enable_dep_gen = false;
static DepGenDataHeader *s_dep_gen_header = nullptr;
static DepGenBufferState *s_dep_gen_state = nullptr;
static int s_orch_thread_idx = -1; // set via dep_gen_aicpu_set_orch_thread_idx
// A record arriving before dep_gen_aicpu_init() cannot be accounted: the
// counter reconcile_counters() reads lives in the very BufferState that is
// still null, so the host would see total == collected == dropped == 0 and
// call an empty deps.json clean. One-shot so a per-task path never floods the
// AICPU log (see .claude/rules/codestyle.md).
static bool s_pre_init_drop_reported = false;

static constexpr uint64_t kDepGenQueueBackpressureWaitCycles = PLATFORM_DFX_BACKPRESSURE_TIMEOUT_CYCLES;

Expand Down Expand Up @@ -133,6 +139,7 @@ void dep_gen_aicpu_init() {
LOG_ERROR("dep_gen_aicpu_init: dep_gen_data_base is NULL");
return;
}
s_pre_init_drop_reported = false;
s_dep_gen_header = get_dep_gen_header(base);
s_dep_gen_state = get_dep_gen_buffer_state(base, /*instance_index=*/0);

Expand All @@ -156,7 +163,17 @@ void dep_gen_aicpu_record_submit(
const uint8_t *arg_types, int explicit_dep_count, const uint64_t *explicit_deps_raw, int block_num,
const int32_t kernel_ids[3]
) {
if (!g_enable_dep_gen || s_dep_gen_state == nullptr) {
if (!g_enable_dep_gen) {
return;
}
if (s_dep_gen_state == nullptr) {
if (!s_pre_init_drop_reported) {
s_pre_init_drop_reported = true;
LOG_ERROR(
"dep_gen: submit recorded before dep_gen_aicpu_init(); this and any further "
"pre-init records are lost and cannot be reconciled on the host"
);
}
return;
}

Expand Down
Loading