增加稳定性

This commit is contained in:
sladro 2026-01-29 20:44:16 +08:00
parent 4399ecd601
commit 4940926866
3 changed files with 58 additions and 128 deletions

View File

@ -1,123 +0,0 @@
name: CI
on:
push:
branches: [ master, main ]
pull_request:
branches: [ master, main ]
workflow_dispatch:
inputs:
enable_cross_build:
description: "Enable RK3588 cross build job"
required: false
default: "false"
jobs:
host-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y ninja-build clang-format cppcheck
- name: Quality gates (clang-format + cppcheck on changed files)
shell: bash
run: |
set -euo pipefail
python3 - <<'PY'
import json, os, subprocess, sys
def sh(*args):
return subprocess.check_output(list(args), text=True).strip()
event = os.environ.get('GITHUB_EVENT_NAME','')
event_path = os.environ.get('GITHUB_EVENT_PATH','')
payload = {}
if event_path:
with open(event_path, 'r', encoding='utf-8') as f:
payload = json.load(f)
base = None
head = os.environ.get('GITHUB_SHA','HEAD')
if event == 'pull_request':
base = (((payload.get('pull_request') or {}).get('base') or {}).get('sha'))
else:
base = payload.get('before')
if base and set(base) == {'0'}:
base = None
if not base:
# Fallback to previous commit if possible.
try:
base = sh('git','rev-parse','HEAD~1')
except Exception:
base = None
if base:
diff = subprocess.check_output(['git','diff','--name-only',f'{base}...{head}'], text=True)
paths = [p.strip() for p in diff.splitlines() if p.strip()]
else:
paths = [p.strip() for p in sh('git','ls-files').splitlines() if p.strip()]
exts = ('.c','.cc','.cpp','.cxx','.h','.hh','.hpp','.hxx')
files = []
for p in paths:
if not p.endswith(exts):
continue
if p.startswith(('third_party/','build/','.git/')):
continue
files.append(p)
if not files:
print('No C/C++ files changed; skipping format/cppcheck.')
sys.exit(0)
# clang-format
subprocess.check_call(['clang-format','--version'])
subprocess.check_call(['clang-format','--dry-run','--Werror',*files])
# cppcheck
subprocess.check_call(['cppcheck','--version'])
subprocess.check_call([
'cppcheck',
'--error-exitcode=1',
'--enable=warning,style,performance,portability',
'--inline-suppr',
'--suppress=missingIncludeSystem',
'--std=c++17',
'-I','include',
'-I','third_party',
*files,
])
PY
- name: Configure & build (host)
env:
CMAKE_ARGS: -DBUILD_TESTS=ON
run: |
./scripts/build_host.sh
- name: Run unit tests
run: |
ctest --test-dir build/host --output-on-failure
rk3588-cross-build:
if: github.event_name == 'workflow_dispatch' && github.event.inputs.enable_cross_build == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install toolchain
run: |
sudo apt-get update
sudo apt-get install -y ninja-build gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
- name: Build (cross)
env:
RK3588_SYSROOT: /opt/rk3588-sysroot
run: |
mkdir -p "$RK3588_SYSROOT"
./scripts/build_board.sh

View File

@ -249,7 +249,9 @@ private:
const intptr_t dif = static_cast<intptr_t>(seq) - static_cast<intptr_t>(pos + 1);
if (dif == 0) {
if (dequeue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed)) {
// Drop without moving data out.
// Drop the item and release its resources eagerly.
T dropped_item = std::move(cell.data);
(void)dropped_item;
cell.seq.store(pos + capacity_, std::memory_order_release);
size_.fetch_sub(1, std::memory_order_acq_rel);
dropped_.fetch_add(1, std::memory_order_relaxed);

View File

@ -1,8 +1,10 @@
#include "ai_scheduler.h"
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <limits>
#include "utils/logger.h"
@ -22,6 +24,26 @@ int GetEnvInt(const char* name, int default_value) {
}
}
uint64_t GetEnvU64(const char* name, uint64_t default_value) {
if (!name) return default_value;
const char* v = std::getenv(name);
if (!v || !*v) return default_value;
try {
return static_cast<uint64_t>(std::stoull(v));
} catch (...) {
return default_value;
}
}
uint64_t DefaultMaxModelBytes() {
// Guardrail against tellg() failures or accidentally huge model files.
// Override with env: RK3588_MODEL_MAX_BYTES.
const uint64_t def = 512ull * 1024ull * 1024ull;
const uint64_t v = GetEnvU64("RK3588_MODEL_MAX_BYTES", def);
// Clamp to a sane range.
return std::min<uint64_t>(std::max<uint64_t>(v, 4ull * 1024ull * 1024ull), 4ull * 1024ull * 1024ull * 1024ull);
}
int ClampInt(int v, int lo, int hi) {
if (v < lo) return lo;
if (v > hi) return hi;
@ -105,12 +127,29 @@ ModelHandle AiScheduler::LoadModel(const std::string& model_path, std::string& e
return kInvalidModelHandle;
}
size_t model_size = file.tellg();
const std::streampos end_pos = file.tellg();
if (end_pos <= 0) {
err = "Failed to read model size: " + model_path;
return kInvalidModelHandle;
}
const uint64_t model_size_u64 = static_cast<uint64_t>(end_pos);
const uint64_t max_bytes = DefaultMaxModelBytes();
if (model_size_u64 > max_bytes) {
err = "Model file too large (" + std::to_string(model_size_u64) + " bytes, max=" +
std::to_string(max_bytes) + "): " + model_path;
return kInvalidModelHandle;
}
if (model_size_u64 > static_cast<uint64_t>(std::numeric_limits<std::streamsize>::max())) {
err = "Model file too large for this build: " + model_path;
return kInvalidModelHandle;
}
const size_t model_size = static_cast<size_t>(model_size_u64);
file.seekg(0, std::ios::beg);
auto model_data = std::make_shared<std::vector<uint8_t>>();
model_data->resize(model_size);
if (!file.read(reinterpret_cast<char*>(model_data->data()), model_size)) {
if (!file.read(reinterpret_cast<char*>(model_data->data()), static_cast<std::streamsize>(model_size))) {
err = "Failed to read model file: " + model_path;
return kInvalidModelHandle;
}
@ -306,6 +345,12 @@ InferResult AiScheduler::Infer(ModelHandle handle, const InferInput& input) {
return result;
}
if (ctx->n_input != 1) {
result.error = "Model expects " + std::to_string(ctx->n_input) + " inputs; current pipeline provides 1";
total_errors_.fetch_add(1);
return result;
}
// Lock this specific model for inference.
std::lock_guard<std::mutex> infer_lock(ctx->infer_mutex);
@ -381,7 +426,7 @@ InferResult AiScheduler::Infer(ModelHandle handle, const InferInput& input) {
inputs[0].buf = const_cast<void*>(input.data);
inputs[0].pass_through = 0;
int ret = rknn_inputs_set(ctx->ctx, ctx->n_input, inputs);
int ret = rknn_inputs_set(ctx->ctx, 1, inputs);
if (ret < 0) {
result.error = "rknn_inputs_set failed: " + std::to_string(ret);
total_errors_.fetch_add(1);
@ -475,6 +520,12 @@ AiScheduler::BorrowedInferResult AiScheduler::InferBorrowed(ModelHandle handle,
return result;
}
if (ctx->n_input != 1) {
result.error = "Model expects " + std::to_string(ctx->n_input) + " inputs; current pipeline provides 1";
total_errors_.fetch_add(1);
return result;
}
if (!input.data || input.size == 0) {
result.error = "Invalid input data";
total_errors_.fetch_add(1);
@ -548,7 +599,7 @@ AiScheduler::BorrowedInferResult AiScheduler::InferBorrowed(ModelHandle handle,
inputs[0].buf = const_cast<void*>(input.data);
inputs[0].pass_through = 0;
int ret = rknn_inputs_set(ctx->ctx, ctx->n_input, inputs);
int ret = rknn_inputs_set(ctx->ctx, 1, inputs);
if (ret < 0) {
result.error = "rknn_inputs_set failed: " + std::to_string(ret);
total_errors_.fetch_add(1);