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
2 changes: 1 addition & 1 deletion .claude/rules/codestyle.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@

| Tier | What | Policy |
| ---- | ---- | ------ |
| **A1 — brand prose** | The brand itself in docs, headings, skill descriptions, issue templates, and code comments (`# PTO Runtime2 Profiling Levels`, "the PTO Runtime consists of…") | **Fix on sight, unconditionally**, and the hook will make you. No compile risk, no contract, and no Tier-C name can hide in a file banner. Say `simpler`, or name the actual component ("the AICPU orchestrator", "the `tensormap_and_ringbuffer` runtime"). Follow the banner style already in the tree: `host_build_graph/shared/orchestrator.cpp` opens `* host_build_graph orchestrator implementation`. |
| **A1 — brand prose** | The brand itself in docs, headings, skill descriptions, issue templates, and code comments (`# PTO Runtime2 Profiling Levels`, "the PTO Runtime consists of…") | **Fix on sight, unconditionally**, and the hook will make you. No compile risk, no contract, and no Tier-C name can hide in a file banner. Say `simpler`, or name the actual component ("the AICPU orchestrator", "the `tensormap_and_ringbuffer` runtime"). Follow the banner style already in the tree: `host_build_graph/host/orchestrator.cpp` opens `* host_build_graph orchestrator implementation`. |
| **A2 — comments naming a `pto_*` that does not exist** | e.g. `pto_submit_task` (the entry is `rt_submit_task`), `pto_runtime2_init` (the work is `SchedulerState::init_data_from_layout`) | **Fix on sight**, but this is a [`doc-consistency.md`](doc-consistency.md) §3 defect, not a naming preference: a reader who greps the name finds nothing. Confirm the symbol is absent before renaming it — `git grep -w <name>` returning only comments is the test. |
| **B — internal identifiers** | `PTO2Foo` types, `pto2_*` functions, internal `PTO2_*` macros and enumerators, `pto_*.h` / `pto_runtime2*.cpp` file names | Rename **only when you are already modifying that code**, per rule 9, and finish the identifier you started (below). |
| **C — external contracts** | `runtime_env` knobs, `extern "C"` symbols in `runtime_c_api.h`, on-wire / serialized names, and **every live `pto_cpu_sim_*` / `pto_sim_*` hook** | **Exempt until a migration ships.** Renaming these breaks callers in other repos. The sim hooks are the worst case and the reason A2 above demands a grep first: `cpu_sim_context.cpp` exports them for "pto-isa via `dlsym(RTLD_DEFAULT)`" and `device_runner_base.cpp` fetches `pto_sim_register_hooks` by `dlsym`, so a rename produces **no compile error** — just a hook that is never found at run time. Ask the user before touching one; land it only with a compatibility alias or a coordinated cross-repo change. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
reading 1 below: the wait is gone and scalar access rejects a tensor with a
producer outright.

Paths below name the tree as it stood then. `shared/runtime_core.cpp` and
`shared/orchestrator.cpp` now sit under `host/`, and neither still holds the wait
or the `last_consumer_local_id` seeding described here.

## The defect

`wait_for_tensor_ready()` in `src/common/host_build_graph/shared/runtime_core.cpp`
Expand Down
2 changes: 0 additions & 2 deletions src/a2a3/runtime/host_build_graph/aicpu/aicpu_executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,6 @@ int32_t AicpuExecutor::run(Runtime *runtime) {
}

if (boot_ok) {
runtime_bind_ops(rt);

sched_ctx_.bind_runtime(rt);

// Latch the host-built task count (on_graph_attached sets total_tasks_)
Expand Down
8 changes: 5 additions & 3 deletions src/a2a3/runtime/host_build_graph/host/runtime_maker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -935,10 +935,12 @@ int32_t run_host_orchestration(
~static_cast<uintptr_t>(CHIP_ALIGN_SIZE - 1)
);

// The copied zone carries no host address: the orchestrator is host-only and
// no device code may reach host memory through the image. Its work is done, so
// the pointer goes early rather than at the guard's scope exit.
// The copied zone carries no host address: the orchestrator and the ops table are
// both host-only, and no device code may reach host memory through the image.
// Their work is done, so the pointers go early rather than at the guard's scope
// exit.
rt->orchestrator = nullptr;
rt->ops = nullptr;
std::memcpy(upload_base, static_cast<const char *>(host_arena.base()) + layout.off_copied_begin, copied_bytes);
const uint64_t compacted = sm_layout::compact_live_image(
static_cast<const char *>(host_sm), task_capacity, bind_usage, heap_rebase, upload_base + copied_bytes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "common/host_phase_kind.h" // HostPhaseKind, for the phase records below
#include "host_build_graph/graph_cache.h" // Graph Execution key and result helpers
#include "host_build_graph/graph_host_state.h" // GRAPH_MAX_DEFINITIONS
#include "host_build_graph/runtime_ops.h" // RuntimeOps, RuntimeContext forward declaration
#include "host_build_graph/runtime_types.h" // SIMPLER_ERROR_*
#include "host_build_graph/submit_types.h" // MixedKernels, INVALID_KERNEL_ID, subtask slots
#include "types.h" // Arg, TaskOutputTensors, TensorArgType
Expand All @@ -63,77 +64,9 @@
// build ChipTensors through the same controlled path.

// =============================================================================
// Ops Table and Opaque Runtime
// Opaque Runtime
// =============================================================================

/**
* Forward declaration — the orchestration sees RuntimeContext as a partial
* struct whose first field is the ops pointer. The full definition
* lives in runtime_core.h (used only by runtime .cpp files).
*/
typedef struct RuntimeContext RuntimeContext;

/**
* Function-pointer table for runtime operations.
* Populated by the runtime; called by orchestration through inline wrappers.
*/
typedef struct RuntimeOps {
TaskOutputTensors (*submit_task)(RuntimeContext *rt, const MixedKernels &mixed_kernels, const CoreTaskArgs &args);
void (*scope_begin)(RuntimeContext *rt);
void (*scope_end)(RuntimeContext *rt);
void (*orchestration_done)(RuntimeContext *rt);
bool (*is_fatal)(RuntimeContext *rt);
void (*report_fatal)(RuntimeContext *rt, int32_t error_code, const char *func, const char *fmt, ...);

// Logging (populated by runtime, called by orchestration)
void (*log_error)(const char *func, const char *fmt, ...);
void (*log_warn)(const char *func, const char *fmt, ...);
void (*log_timing)(const char *func, const char *fmt, ...);
void (*log_info)(const char *func, const char *fmt, ...);
void (*log_debug)(const char *func, const char *fmt, ...);

// Cross-layer data access (orchestration reads/writes tensor values via runtime)
// Placed after logging to avoid shifting hot-path field offsets.
uint64_t (*get_tensor_data)(
RuntimeContext *rt, const simpler::hbg::Tensor &tensor, uint32_t ndims, const uint32_t indices[]
);
void (*set_tensor_data)(
RuntimeContext *rt, const simpler::hbg::Tensor &tensor, uint32_t ndims, const uint32_t indices[], uint64_t value
);
TaskOutputTensors (*alloc_tensors)(RuntimeContext *rt, const CoreTaskArgs &args);
TaskOutputTensors (*submit_dummy_task)(RuntimeContext *rt, const CoreTaskArgs &args);

// This-run core geometry latched by the host bind: MIX clusters
// (one AIC each) and standalone AIV cores.
int32_t (*available_cluster_count)(RuntimeContext *rt);
int32_t (*available_aiv_count)(RuntimeContext *rt);
GraphScopeResult (*graph_begin)(RuntimeContext *rt, uint64_t graph_key, const GraphTaskArgs &args);
bool (*graph_prepare)(RuntimeContext *rt, void *recording_handle, const GraphTaskArgs &args);
void (*graph_abort)(RuntimeContext *rt, void *recording_handle);
bool (*graph_end)(RuntimeContext *rt);
void (*graph_commit)(RuntimeContext *rt);

// Record one orchestration-side phase. The submission segments this carries are
// measured here and invisible to the runtime, which sees only what it is called
// for. Always present to keep ops-table layout stable across SIMPLER_DFX
// settings; nullptr when DFX is off.
//
// This struct is declared twice — here and in the runtime's runtime_core.h — and
// the two must stay in lockstep field for field, since the runtime fills the table
// and this .so calls through it.
void (*record_orch_phase)(uint32_t kind, uint64_t start_ns, uint64_t end_ns, uint64_t detail);
// Queue one Graph body for asynchronous recording, and drain every queued one.
// `job` is a `std::function<void(GraphTaskArgs &)> *` the pool moves out of --
// whether or not it queues it, since start() takes the callable before it checks
// capacity -- so the caller must not invoke it afterwards. Nothing is owned across
// the boundary either way: the caller's std::function destructs normally, empty or
// not, and rt_graph_submit's fallback re-runs its own copy of the body. The pool is
// runtime-owned (host/graph_recorder_pool.h) and the AICPU build links a refusing
// fallback, which is what makes the device path record synchronously.
bool (*graph_record_start)(RuntimeContext *rt, const GraphTaskArgs &args, void *job);
void (*graph_record_wait)(RuntimeContext *rt);
} RuntimeOps;

/**
* Partial RuntimeContext definition for orchestration.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
#include "host_build_graph/runtime_types.h"
#include "host_build_graph/shared_memory.h"

#include "aicpu/device_time.h" // get_sys_cnt_aicpu (weak; used by early-dispatch doorbell timing too)
#include "aicpu/device_time.h" // get_sys_cnt_aicpu (used by early-dispatch doorbell timing too)
#if SIMPLER_SCHED_PROFILING
#define SCHED_CYCLE_START() uint64_t _st0 = get_sys_cnt_aicpu(), _st1
#define SCHED_CYCLE_LAP(acc) \
Expand Down
2 changes: 0 additions & 2 deletions src/a5/runtime/host_build_graph/aicpu/aicpu_executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,6 @@ int32_t AicpuExecutor::run(Runtime *runtime) {
}

if (boot_ok) {
runtime_bind_ops(rt);

sched_ctx_.bind_runtime(rt);

// Latch the host-built task count (on_graph_attached sets total_tasks_)
Expand Down
8 changes: 5 additions & 3 deletions src/a5/runtime/host_build_graph/host/runtime_maker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -935,10 +935,12 @@ int32_t run_host_orchestration(
~static_cast<uintptr_t>(CHIP_ALIGN_SIZE - 1)
);

// The copied zone carries no host address: the orchestrator is host-only and
// no device code may reach host memory through the image. Its work is done, so
// the pointer goes early rather than at the guard's scope exit.
// The copied zone carries no host address: the orchestrator and the ops table are
// both host-only, and no device code may reach host memory through the image.
// Their work is done, so the pointers go early rather than at the guard's scope
// exit.
rt->orchestrator = nullptr;
rt->ops = nullptr;
std::memcpy(upload_base, static_cast<const char *>(host_arena.base()) + layout.off_copied_begin, copied_bytes);
const uint64_t compacted = sm_layout::compact_live_image(
static_cast<const char *>(host_sm), task_capacity, bind_usage, heap_rebase, upload_base + copied_bytes
Expand Down
71 changes: 2 additions & 69 deletions src/a5/runtime/host_build_graph/orchestration/orchestration_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "common/host_phase_kind.h" // HostPhaseKind, for the phase records below
#include "host_build_graph/graph_cache.h" // Graph Execution key and result helpers
#include "host_build_graph/graph_host_state.h" // GRAPH_MAX_DEFINITIONS
#include "host_build_graph/runtime_ops.h" // RuntimeOps, RuntimeContext forward declaration
#include "host_build_graph/runtime_types.h" // SIMPLER_ERROR_*
#include "host_build_graph/submit_types.h" // MixedKernels, INVALID_KERNEL_ID, subtask slots
#include "types.h" // Arg, TaskOutputTensors, TensorArgType
Expand All @@ -63,77 +64,9 @@
// build ChipTensors through the same controlled path.

// =============================================================================
// Ops Table and Opaque Runtime
// Opaque Runtime
// =============================================================================

/**
* Forward declaration — the orchestration sees RuntimeContext as a partial
* struct whose first field is the ops pointer. The full definition
* lives in runtime_core.h (used only by runtime .cpp files).
*/
typedef struct RuntimeContext RuntimeContext;

/**
* Function-pointer table for runtime operations.
* Populated by the runtime; called by orchestration through inline wrappers.
*/
typedef struct RuntimeOps {
TaskOutputTensors (*submit_task)(RuntimeContext *rt, const MixedKernels &mixed_kernels, const CoreTaskArgs &args);
void (*scope_begin)(RuntimeContext *rt);
void (*scope_end)(RuntimeContext *rt);
void (*orchestration_done)(RuntimeContext *rt);
bool (*is_fatal)(RuntimeContext *rt);
void (*report_fatal)(RuntimeContext *rt, int32_t error_code, const char *func, const char *fmt, ...);

// Logging (populated by runtime, called by orchestration)
void (*log_error)(const char *func, const char *fmt, ...);
void (*log_warn)(const char *func, const char *fmt, ...);
void (*log_timing)(const char *func, const char *fmt, ...);
void (*log_info)(const char *func, const char *fmt, ...);
void (*log_debug)(const char *func, const char *fmt, ...);

// Cross-layer data access (orchestration reads/writes tensor values via runtime)
// Placed after logging to avoid shifting hot-path field offsets.
uint64_t (*get_tensor_data)(
RuntimeContext *rt, const simpler::hbg::Tensor &tensor, uint32_t ndims, const uint32_t indices[]
);
void (*set_tensor_data)(
RuntimeContext *rt, const simpler::hbg::Tensor &tensor, uint32_t ndims, const uint32_t indices[], uint64_t value
);
TaskOutputTensors (*alloc_tensors)(RuntimeContext *rt, const CoreTaskArgs &args);
TaskOutputTensors (*submit_dummy_task)(RuntimeContext *rt, const CoreTaskArgs &args);

// This-run core geometry latched by the host bind: MIX clusters
// (one AIC each) and standalone AIV cores.
int32_t (*available_cluster_count)(RuntimeContext *rt);
int32_t (*available_aiv_count)(RuntimeContext *rt);
GraphScopeResult (*graph_begin)(RuntimeContext *rt, uint64_t graph_key, const GraphTaskArgs &args);
bool (*graph_prepare)(RuntimeContext *rt, void *recording_handle, const GraphTaskArgs &args);
void (*graph_abort)(RuntimeContext *rt, void *recording_handle);
bool (*graph_end)(RuntimeContext *rt);
void (*graph_commit)(RuntimeContext *rt);

// Record one orchestration-side phase. The submission segments this carries are
// measured here and invisible to the runtime, which sees only what it is called
// for. Always present to keep ops-table layout stable across SIMPLER_DFX
// settings; nullptr when DFX is off.
//
// This struct is declared twice — here and in the runtime's runtime_core.h — and
// the two must stay in lockstep field for field, since the runtime fills the table
// and this .so calls through it.
void (*record_orch_phase)(uint32_t kind, uint64_t start_ns, uint64_t end_ns, uint64_t detail);
// Queue one Graph body for asynchronous recording, and drain every queued one.
// `job` is a `std::function<void(GraphTaskArgs &)> *` the pool moves out of --
// whether or not it queues it, since start() takes the callable before it checks
// capacity -- so the caller must not invoke it afterwards. Nothing is owned across
// the boundary either way: the caller's std::function destructs normally, empty or
// not, and rt_graph_submit's fallback re-runs its own copy of the body. The pool is
// runtime-owned (host/graph_recorder_pool.h) and the AICPU build links a refusing
// fallback, which is what makes the device path record synchronously.
bool (*graph_record_start)(RuntimeContext *rt, const GraphTaskArgs &args, void *job);
void (*graph_record_wait)(RuntimeContext *rt);
} RuntimeOps;

/**
* Partial RuntimeContext definition for orchestration.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
#include "host_build_graph/shared_memory.h"
#include "scheduler_graph.h"

#include "aicpu/device_time.h" // get_sys_cnt_aicpu (weak; used by early-dispatch doorbell timing too)
#include "aicpu/device_time.h" // get_sys_cnt_aicpu (used by early-dispatch doorbell timing too)

// scheduler_graph.h states the storage layout as literals, because the AICore .o
// that reads it cannot include runtime_types.h. This translation unit sees both,
Expand Down
4 changes: 2 additions & 2 deletions src/common/host_build_graph/dep_gen_host_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
* Control surface, called from the device runner (same host_runtime.so):
* set_enabled() / active() / emit()
*
* The runtime translation unit links weak no-op fallbacks (orchestrator.cpp)
* so the AICPU build, which has no host graph, resolves without this .cpp.
* Every runtime build links this .cpp. A unit test that takes the orchestrator
* without it resolves to the no-ops in tests/ut/cpp/stubs/hbg_orch_stubs.cpp.
*
* The graph lives in thread-local state, so capture is lock-free and two
* prepared contexts on different threads cannot overwrite one another. Emit
Expand Down
4 changes: 2 additions & 2 deletions src/common/host_build_graph/graph_recorder_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
#include <utility>
#include <vector>

// Deliberately no runtime_core.h: it declares the real RuntimeOps while
// orchestration_api.h declares a partial one, so a translation unit that sees both fails
// Deliberately no runtime_core.h: it defines the full RuntimeContext while
// orchestration_api.h defines a partial one, so a translation unit that sees both fails
// to compile. Only the ops implementations in graph_recorder_pool.cpp need it.
#include "graph_host_state.h" // GRAPH_MAX_DEFINITIONS
#include "host_build_graph/types.h" // GraphTaskArgs, GRAPH_MAX_{TENSOR,SCALAR}_ARGS
Expand Down
Loading
Loading