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
9 changes: 6 additions & 3 deletions .github/workflows/sanitizers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,13 @@ jobs:
KFILTER="not dlopen_count"
export TSAN_OPTIONS=halt_on_error=0:exitcode=0
else
# ASAN (~1.7x) takes the broader set; dynamic_register is a2a3-only.
# ASAN (~1.7x) + UBSan. Like TSAN, the chip-fork L3 cases
# (dynamic_register is all level=3) livelock on the 4-vCPU runner
# once a sanitizer's slowdown is in play (#884 oversubscription
# family — AICPU + AICore + host threads oversubscribe), so scope to
# the light prepared_callable L2 set. UBSan halt_on_error=1 keeps it
# a real gate: any undefined behaviour fails the cell.
TARGETS="$PC"
[ -d "tests/st/$ARCH/tensormap_and_ringbuffer/dynamic_register" ] && \
TARGETS="$TARGETS tests/st/$ARCH/tensormap_and_ringbuffer/dynamic_register"
MAXPAR=2
KFILTER="not parallel_broadcast and not dlopen_count"
export ASAN_OPTIONS=detect_leaks=0:abort_on_error=1:halt_on_error=1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -882,11 +882,19 @@ int32_t SchedulerContext::init(
// Initialize task counters. Task count comes from PTO2 shared memory.
if (runtime->get_gm_sm_ptr()) {
auto *header = static_cast<PTO2SharedMemoryHeader *>(runtime->get_gm_sm_ptr());
int32_t pto2_count = 0;
// Read at one-time boot init, before the SM is reset for the run, so a
// ring not yet written holds uninitialized memory (0xbe... under ASAN's
// malloc-fill). Sum in int64 and only count rings whose value is a
// plausible task count — (0, PTO2_SCOPE_TASKS_CAP]; a ring cannot hold
// more than the scope cap. This rejects any garbage pattern (negative
// or positive), so uninitialized rings contribute 0 (the correct boot
// count) while valid counts still add up, with no signed overflow.
int64_t pto2_count = 0;
for (int r = 0; r < PTO2_MAX_RING_DEPTH; r++) {
pto2_count += header->rings[r].fc.current_task_index.load(std::memory_order_acquire);
int32_t ring_tasks = header->rings[r].fc.current_task_index.load(std::memory_order_acquire);
if (ring_tasks > 0 && ring_tasks <= PTO2_SCOPE_TASKS_CAP) pto2_count += ring_tasks;
}
total_tasks_ = pto2_count > 0 ? pto2_count : 0;
total_tasks_ = static_cast<int32_t>(pto2_count);
Comment thread
ChaoWao marked this conversation as resolved.
} else {
total_tasks_ = 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -895,11 +895,19 @@ int32_t SchedulerContext::init(
// Initialize task counters. Task count comes from PTO2 shared memory.
if (runtime->get_gm_sm_ptr()) {
auto *header = static_cast<PTO2SharedMemoryHeader *>(runtime->get_gm_sm_ptr());
int32_t task_count = 0;
// Read at one-time boot init, before the SM is reset for the run, so a
// ring not yet written holds uninitialized memory (0xbe... under ASAN's
// malloc-fill). Sum in int64 and only count rings whose value is a
// plausible task count — (0, PTO2_SCOPE_TASKS_CAP]; a ring cannot hold
// more than the scope cap. This rejects any garbage pattern (negative
// or positive), so uninitialized rings contribute 0 (the correct boot
// count) while valid counts still add up, with no signed overflow.
int64_t task_count = 0;
for (int r = 0; r < PTO2_MAX_RING_DEPTH; r++) {
task_count += header->rings[r].fc.current_task_index.load(std::memory_order_acquire);
int32_t ring_tasks = header->rings[r].fc.current_task_index.load(std::memory_order_acquire);
if (ring_tasks > 0 && ring_tasks <= PTO2_SCOPE_TASKS_CAP) task_count += ring_tasks;
}
total_tasks_ = task_count > 0 ? task_count : 0;
total_tasks_ = static_cast<int32_t>(task_count);
Comment thread
ChaoWao marked this conversation as resolved.
} else {
total_tasks_ = 0;
}
Expand Down