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
10 changes: 8 additions & 2 deletions tools/cann-examples/aicpu-kernel-launch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ zero changes as long as you preserve the two-export contract.
+---------------------+
| libhello_aicpu.so | inside AICPU OS process:
| (inner SO) | DlogRecord("hello kernel running")
+---------------------+ halGetDeviceInfo(AICPU, CORE_NUM) -> 6
+---------------------+ halGetDeviceInfo(AICPU, OS_SCHED) -> 0x1
| write HelloResult { magic, echoed_token, hal_rc, hal_value }
| D2H aclrtMemcpy
v
Expand Down Expand Up @@ -170,9 +170,15 @@ Successful output:
=== device=<N> hello_aicpu HelloResult ===
magic = 0xdeadbeefc0ffee01 OK
echoed_token = 0x???????????????? OK (expected 0x????????????????)
hal AICPU+CORE_NUM rc=0 val=6 (host-side rtGetAiCpuCount reports 6 on a3/a5)
hal AICPU+OS_SCHED rc=0 val=0x1 OK
```

The HAL `AICPU + OS_SCHED` result is `0x1` on both a3 and a5: the AICPU
OS scheduler owns cpu_id 0 in the per-die AICPU layout (see
[`src/a2a3/docs/hardware.md`](../../../src/a2a3/docs/hardware.md#device-side-probe-resolves-the-aicpu-question)
and `src/a5/docs/hardware.md` for the device-side probe writeup that
established this).

Exit code: 0 on full success, 1 on bootstrap / load / launch failure, 2 on
mismatched magic or token (kernel ran but the I/O contract is broken).

Expand Down
21 changes: 13 additions & 8 deletions tools/cann-examples/aicpu-kernel-launch/device/hello_aicpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
// as fatal. Returning 0 is enough.
// simpler_aicpu_run — reads DeviceArgs.input_token (so the host can
// prove the kernel saw its input), calls one
// halGetDeviceInfo to show device-side CANN works,
// halGetDeviceInfo(AICPU, OS_SCHED) to show
// device-side CANN works (returns 0x1 on a3/a5),
// and writes a HelloResult to GM at
// DeviceArgs.result_addr.
//
Expand Down Expand Up @@ -120,16 +121,20 @@ __attribute__((visibility("default"))) int simpler_aicpu_run(void *args) {
out->echoed_token = d->input_token;
out->_pad = 0;

// Single device-side HAL call: ask "how many AICPU cores does this die
// expose?" — the answer (6 on a3, 6 on a5) is independently verifiable
// from the host-side `tools/cann-examples/query` tool. Local device id
// 0 means "myself" device-side; using the host's logical did returns
// rc=1 (see aicpu-device-query's writeup for why).
// Single device-side HAL call: AICPU + OS_SCHED returns a bitmask of
// which AICPU cpu_ids the AICPU OS scheduler owns. Per the
// aicpu-device-query findings (src/{a2a3,a5}/docs/hardware.md), this
// is 0x1 on both a3 and a5 — bit 0 set = cpu_id 0 owned by the AICPU
// OS. We pick this query rather than AICPU + CORE_NUM because the
// latter is "used in device" / restricted and returns rc=3 from
// inside an AICPU OS process. Local device id 0 means "myself"
// device-side; using the host's logical did returns rc=1 (see
// aicpu-device-query's writeup for why).
constexpr uint32_t self_did = 0;
constexpr int kModuleAicpu = 1;
constexpr int kInfoCoreNum = 1;
constexpr int kInfoOsSched = 5;
int64_t hal_value = 0;
drvError_t hal_rc = halGetDeviceInfo(self_did, kModuleAicpu, kInfoCoreNum, &hal_value);
drvError_t hal_rc = halGetDeviceInfo(self_did, kModuleAicpu, kInfoOsSched, &hal_value);
out->hal_rc = static_cast<int32_t>(hal_rc);
out->hal_value = (hal_rc == kHalSuccess) ? hal_value : 0;

Expand Down
17 changes: 12 additions & 5 deletions tools/cann-examples/aicpu-kernel-launch/host/launch_hello.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,10 +447,14 @@ int main(int argc, char **argv) {
}
} json_tmp;
{
char tmpl[] = "/tmp/simpler_inner_XXXXXX";
int fd = mkstemp(tmpl);
// CANN's rtsBinaryLoadFromFile expects a .json filename — confirmed
// by hardware test: with a plain mkstemp temp file (no suffix) the
// call returns rc=107000 even though the JSON body is well-formed.
// mkstemps keeps the trailing suffix when randomizing XXXXXX.
char tmpl[] = "/tmp/simpler_inner_XXXXXX.json";
int fd = mkstemps(tmpl, 5); // 5 = strlen(".json")
if (fd < 0) {
std::fprintf(stderr, "mkstemp failed: %s\n", std::strerror(errno));
std::fprintf(stderr, "mkstemps failed: %s\n", std::strerror(errno));
return 1;
}
json_tmp.path = tmpl;
Expand Down Expand Up @@ -527,9 +531,12 @@ int main(int argc, char **argv) {
got.echoed_token == input_token ? "OK" : "BAD", input_token
);
if (got.echoed_token != input_token) ok = false;
// OS_SCHED bit 0 = AICPU OS owns cpu_id 0; matches
// src/{a2a3,a5}/docs/hardware.md and the aicpu-device-query
// results. rc=0 val=0x1 is the expected outcome on a3 and a5.
std::printf(
" hal AICPU+CORE_NUM rc=%d val=%ld (host-side rtGetAiCpuCount reports 6 on a3/a5)\n", got.hal_rc,
(long)got.hal_value
" hal AICPU+OS_SCHED rc=%d val=0x%lx %s\n", got.hal_rc, (unsigned long)got.hal_value,
(got.hal_rc == 0 && got.hal_value == 0x1) ? "OK" : "(unexpected)"
);
Comment thread
hw-native-sys-bot marked this conversation as resolved.

// Stream destroy + device reset + aclFinalize are handled by
Expand Down