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
996 changes: 744 additions & 252 deletions src/a5/runtime/host_build_graph/aicore/aicore_executor.cpp

Large diffs are not rendered by default.

303 changes: 303 additions & 0 deletions src/a5/runtime/host_build_graph/aicore/aicore_legacy_executor.cpp

Large diffs are not rendered by default.

442 changes: 442 additions & 0 deletions src/a5/runtime/host_build_graph/aicpu/aicore_lifecycle.cpp

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions src/a5/runtime/host_build_graph/aicpu/aicore_lifecycle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* 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.
* -----------------------------------------------------------------------------------------------------------
*/

#pragma once

#include <atomic>
#include <cstdint>

#include "common/core_type.h"

class Runtime;
struct AicpuCoreLifecycleTrace;

class AicoreLifecycle {
public:
int32_t pre_handshake_init(Runtime *runtime, int32_t aicpu_thread_num, uint64_t regs_base);
void handshake_partition(Runtime *runtime, int32_t tidx, int32_t nthreads);
int32_t post_handshake_init(Runtime *runtime);
void publish_context_partition(Runtime *runtime, int32_t thread_idx);
int32_t wait_bootstrap_complete(Runtime *runtime);
int32_t release_partition(int32_t thread_idx, bool start_execution);
void signal_shutdown_partition(int32_t thread_idx);
int32_t finish_shutdown_partition(int32_t thread_idx, Runtime *runtime);
void deinit();

private:
static constexpr int32_t kMaxWorkers = 108;

struct CoreState {
uint64_t reg_addr;
uint32_t physical_core_id;
CoreType core_type;
AicpuCoreLifecycleTrace *trace;
uint64_t handshake_observed_cycles;
uint64_t handshake_partition_complete_cycles;
};

CoreState cores_[kMaxWorkers]{};
uint32_t physical_core_ids_[kMaxWorkers]{};
std::atomic<bool> handshake_failed_{false};
int32_t core_count_{0};
int32_t aicpu_thread_num_{0};
uint64_t regs_base_{0};
};
54 changes: 54 additions & 0 deletions src/a5/runtime/host_build_graph/aicpu/aicore_scheduler_error.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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.
* -----------------------------------------------------------------------------------------------------------
*/

#pragma once

#include <atomic>
#include <cstdint>

#include "host_build_graph/runtime_status.h"
#include "scheduler/scheduler_graph.h"
#include "scheduler/scheduler_types.h"

// This bridge is intentionally AICPU/host-only. AICore code publishes its
// detailed first error through SchedulerRunControl; AICPU maps that internal
// diagnostic to the existing host runtime status ABI without making this
// std::atomic helper visible to either AICore compiler.
inline int32_t aicore_scheduler_runtime_error_code(uint64_t scheduler_error) {
if (scheduler_error == 0) return SIMPLER_ERROR_NONE;
if (scheduler_error == static_cast<uint64_t>(SchedulerGraphResult::TIMEOUT)) {
return SIMPLER_ERROR_SCHEDULER_TIMEOUT;
}
return SIMPLER_ERROR_INVALID_ARGS;
}

inline bool latch_aicore_scheduler_runtime_error(std::atomic<int32_t> *sched_error_code, uint64_t scheduler_error) {
if (sched_error_code == nullptr || scheduler_error == 0) return false;
int32_t expected = SIMPLER_ERROR_NONE;
return sched_error_code->compare_exchange_strong(
expected, aicore_scheduler_runtime_error_code(scheduler_error), std::memory_order_acq_rel,
std::memory_order_acquire
);
}

inline bool record_aicore_scheduler_runtime_error(
SchedulerRunControl *run_control, SchedulerGraphResult scheduler_error, SchedulerErrorSite error_site
) {
if (run_control == nullptr || scheduler_error == SchedulerGraphResult::OK) return false;
uint64_t expected = 0;
if (!__atomic_compare_exchange_n(
&run_control->error_claimed, &expected, UINT64_C(1), false, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE
))
return false;
__atomic_store_n(&run_control->error_site, static_cast<uint64_t>(error_site), __ATOMIC_RELAXED);
__atomic_store_n(&run_control->scheduler_error, static_cast<uint64_t>(scheduler_error), __ATOMIC_RELEASE);
return true;
}
48 changes: 48 additions & 0 deletions src/a5/runtime/host_build_graph/aicpu/aicore_scheduler_state.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* 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.
* -----------------------------------------------------------------------------------------------------------
*/

#pragma once

#include "runtime.h"
#include "scheduler/scheduler_types.h"

inline bool aicore_scheduler_runtime_mode_is_resident(uint32_t mode) {
return mode == SCHEDULER_RUNTIME_MODE_RESIDENT_PENDING || mode == SCHEDULER_RUNTIME_MODE_RESIDENT_READY;
}

inline bool aicore_scheduler_runtime_mode_is_explicit_legacy(uint32_t mode) {
return mode == SCHEDULER_RUNTIME_MODE_LEGACY_GRAPH || mode == SCHEDULER_RUNTIME_MODE_LEGACY_UNSUPPORTED_SHAPE;
}

inline bool aicore_scheduler_runtime_enabled(const Runtime *runtime) {
return runtime != nullptr && runtime->get_worker_count() > 0 &&
aicore_scheduler_runtime_mode_is_resident(runtime->workers[0].aicpu_ready);
}

inline bool aicore_scheduler_explicit_legacy_enabled(const Runtime *runtime) {
return runtime != nullptr && runtime->get_worker_count() > 0 &&
aicore_scheduler_runtime_mode_is_explicit_legacy(runtime->workers[0].aicpu_ready);
}

inline SchedulerWorkerContext *aicore_scheduler_bootstrap_context(Runtime *runtime) {
if (!aicore_scheduler_runtime_enabled(runtime) || runtime->workers[0].task == 0) return nullptr;
return reinterpret_cast<SchedulerWorkerContext *>(runtime->workers[0].task);
}

inline void *aicore_scheduler_state_base(SchedulerWorkerContext *context) {
return context == nullptr ? nullptr : reinterpret_cast<void *>(context->scheduler_state_base_address);
}

inline SchedulerRunControl *aicore_scheduler_run_control(SchedulerWorkerContext *context) {
void *state_base = aicore_scheduler_state_base(context);
return state_base == nullptr ? nullptr :
scheduler_state_at<SchedulerRunControl>(state_base, context->run_control_offset);
}
Loading
Loading