s100 cpp sdk更新
This commit is contained in:
@@ -130,6 +130,38 @@ Output: actions (1, 12)
|
|||||||
repeat=1000 avg_ms=0.733020
|
repeat=1000 avg_ms=0.733020
|
||||||
```
|
```
|
||||||
|
|
||||||
|
纯 C++ BPU wrapper/bench,不经过 Python 推理路径:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /root/go1_pro_deploy/deploy_45dim_rl_gym/bpu_deploy_s100/cpp
|
||||||
|
bash build_board.sh
|
||||||
|
|
||||||
|
./s100_bpu_bench \
|
||||||
|
/root/go1_pro_deploy/deploy_45dim_rl_gym/bpu_quantization/mapper_output_26000_s100_gemm/policy_robotlab_26000_s100_int16_gemm.hbm \
|
||||||
|
/root/go1_pro_deploy/deploy_45dim_rl_gym/bpu_quantization/calibration_data_26000_robotlab_fast64/00000.bin \
|
||||||
|
1000 \
|
||||||
|
-1
|
||||||
|
```
|
||||||
|
|
||||||
|
参数含义:
|
||||||
|
|
||||||
|
- 第 1 个参数:S100 `.hbm` 模型。
|
||||||
|
- 第 2 个参数:float32 输入样本,当前 RobotLab 10 帧模型应为 450 个 float。
|
||||||
|
- 第 3 个参数:重复推理次数。
|
||||||
|
- 第 4 个参数:BPU core,`-1` 表示自动选择,`0..3` 表示固定单核。
|
||||||
|
|
||||||
|
这个 C++ wrapper 只做离线推理:模型加载和 tensor 内存分配只初始化一次,循环里只做输入拷贝、cache flush、`hbDNNInferV2`、`hbUCPSubmitTask`、等待和输出拷贝。它不会连接机器人,也不会发送电机指令。
|
||||||
|
|
||||||
|
当前板端纯 C++ 结果:
|
||||||
|
|
||||||
|
```text
|
||||||
|
backend=cpp_dnn_api_s100
|
||||||
|
input_floats=450 output_floats=12 bpu_core=0
|
||||||
|
action [0.544585 -1.108296 0.916061 -0.837005 0.074006 -0.434765 -0.858212 -2.766010 1.127831 0.422954 1.424179 -0.016353]
|
||||||
|
action_max_abs 2.766010
|
||||||
|
repeat=5000 cpp_avg_ms=0.426015
|
||||||
|
```
|
||||||
|
|
||||||
## 离线推理检查
|
## 离线推理检查
|
||||||
|
|
||||||
这一步会连接 MCU 读取状态,但不会发送电机指令:
|
这一步会连接 MCU 读取状态,但不会发送电机指令:
|
||||||
|
|||||||
33
deploy_45dim_rl_gym/bpu_deploy_s100/cpp/build_board.sh
Executable file
33
deploy_45dim_rl_gym/bpu_deploy_s100/cpp/build_board.sh
Executable file
@@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
CXX="${CXX:-g++}"
|
||||||
|
CXXFLAGS=(
|
||||||
|
-O3
|
||||||
|
-DNDEBUG
|
||||||
|
-std=c++17
|
||||||
|
-Wall
|
||||||
|
-Wextra
|
||||||
|
-fPIC
|
||||||
|
-I/usr/include
|
||||||
|
)
|
||||||
|
LDFLAGS=(
|
||||||
|
-L/usr/hobot/lib
|
||||||
|
-ldnn
|
||||||
|
-lhbucp
|
||||||
|
-Wl,-rpath,/usr/hobot/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
"${CXX}" "${CXXFLAGS[@]}" -shared s100_bpu_policy.cpp \
|
||||||
|
"${LDFLAGS[@]}" \
|
||||||
|
-o libs100_bpu_policy.so
|
||||||
|
|
||||||
|
"${CXX}" "${CXXFLAGS[@]}" s100_bpu_bench.cpp \
|
||||||
|
-L. -ls100_bpu_policy -Wl,-rpath,'$ORIGIN' \
|
||||||
|
"${LDFLAGS[@]}" \
|
||||||
|
-o s100_bpu_bench
|
||||||
|
|
||||||
|
echo "[OK] built $(pwd)/libs100_bpu_policy.so"
|
||||||
|
echo "[OK] built $(pwd)/s100_bpu_bench"
|
||||||
129
deploy_45dim_rl_gym/bpu_deploy_s100/cpp/s100_bpu_bench.cpp
Normal file
129
deploy_45dim_rl_gym/bpu_deploy_s100/cpp/s100_bpu_bench.cpp
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
#include <algorithm>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void *rlgym_s100_bpu_create(const char *model_path, int bpu_core, int priority,
|
||||||
|
char *err, int err_len);
|
||||||
|
int rlgym_s100_bpu_infer(void *handle, const float *input, float *output, char *err,
|
||||||
|
int err_len);
|
||||||
|
int rlgym_s100_bpu_input_floats(void *handle);
|
||||||
|
int rlgym_s100_bpu_output_floats(void *handle);
|
||||||
|
void rlgym_s100_bpu_destroy(void *handle);
|
||||||
|
const char *rlgym_s100_bpu_version();
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool read_f32_file(const std::string &path, std::vector<float> *data) {
|
||||||
|
std::ifstream ifs(path, std::ios::binary);
|
||||||
|
if (!ifs) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ifs.seekg(0, std::ios::end);
|
||||||
|
const auto size = ifs.tellg();
|
||||||
|
ifs.seekg(0, std::ios::beg);
|
||||||
|
if (size <= 0 || size % static_cast<std::streamoff>(sizeof(float)) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
data->resize(static_cast<size_t>(size) / sizeof(float));
|
||||||
|
ifs.read(reinterpret_cast<char *>(data->data()), size);
|
||||||
|
return ifs.good();
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_usage(const char *argv0) {
|
||||||
|
std::cerr << "Usage: " << argv0 << " [model.hbm] [input.bin] [repeat] [bpu_core]\n"
|
||||||
|
<< " bpu_core: -1 means any core; 0..3 pins one BPU core\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
const char *model =
|
||||||
|
"/root/go1_pro_deploy/deploy_45dim_rl_gym/bpu_quantization/"
|
||||||
|
"mapper_output_26000_s100_gemm/policy_robotlab_26000_s100_int16_gemm.hbm";
|
||||||
|
const char *input =
|
||||||
|
"/root/go1_pro_deploy/deploy_45dim_rl_gym/bpu_quantization/"
|
||||||
|
"calibration_data_26000_robotlab_fast64/00000.bin";
|
||||||
|
int repeat = 1000;
|
||||||
|
int bpu_core = -1;
|
||||||
|
if (argc > 1) model = argv[1];
|
||||||
|
if (argc > 2) input = argv[2];
|
||||||
|
if (argc > 3) repeat = std::atoi(argv[3]);
|
||||||
|
if (argc > 4) bpu_core = std::atoi(argv[4]);
|
||||||
|
if (argc > 5 || repeat <= 0) {
|
||||||
|
print_usage(argv[0]);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
char err[2048] = {};
|
||||||
|
void *handle = rlgym_s100_bpu_create(model, bpu_core, 0, err, sizeof(err));
|
||||||
|
if (handle == nullptr) {
|
||||||
|
std::cerr << err << "\n";
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int input_floats = rlgym_s100_bpu_input_floats(handle);
|
||||||
|
const int output_floats = rlgym_s100_bpu_output_floats(handle);
|
||||||
|
if (input_floats <= 0 || output_floats <= 0) {
|
||||||
|
std::cerr << "invalid tensor sizes from S100 BPU runtime\n";
|
||||||
|
rlgym_s100_bpu_destroy(handle);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> obs;
|
||||||
|
if (!read_f32_file(input, &obs) || static_cast<int>(obs.size()) != input_floats) {
|
||||||
|
std::cerr << "failed to read " << input_floats << " float32 input: " << input
|
||||||
|
<< "\n";
|
||||||
|
rlgym_s100_bpu_destroy(handle);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> out(static_cast<size_t>(output_floats), 0.0f);
|
||||||
|
if (rlgym_s100_bpu_infer(handle, obs.data(), out.data(), err, sizeof(err)) != 0) {
|
||||||
|
std::cerr << err << "\n";
|
||||||
|
rlgym_s100_bpu_destroy(handle);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto t0 = std::chrono::steady_clock::now();
|
||||||
|
for (int i = 0; i < repeat; ++i) {
|
||||||
|
if (rlgym_s100_bpu_infer(handle, obs.data(), out.data(), err, sizeof(err)) != 0) {
|
||||||
|
std::cerr << err << "\n";
|
||||||
|
rlgym_s100_bpu_destroy(handle);
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const auto t1 = std::chrono::steady_clock::now();
|
||||||
|
const double elapsed_ms =
|
||||||
|
std::chrono::duration<double, std::milli>(t1 - t0).count();
|
||||||
|
|
||||||
|
const auto max_it = std::max_element(out.begin(), out.end(), [](float a, float b) {
|
||||||
|
return std::fabs(a) < std::fabs(b);
|
||||||
|
});
|
||||||
|
|
||||||
|
std::cout << "backend=" << rlgym_s100_bpu_version() << "\n";
|
||||||
|
std::cout << "input_floats=" << input_floats << " output_floats=" << output_floats
|
||||||
|
<< " bpu_core=" << bpu_core << "\n";
|
||||||
|
std::cout << std::fixed << std::setprecision(6);
|
||||||
|
std::cout << "action [";
|
||||||
|
for (int i = 0; i < output_floats; ++i) {
|
||||||
|
if (i != 0) {
|
||||||
|
std::cout << ' ';
|
||||||
|
}
|
||||||
|
std::cout << out[static_cast<size_t>(i)];
|
||||||
|
}
|
||||||
|
std::cout << "]\n";
|
||||||
|
std::cout << "action_max_abs " << (max_it == out.end() ? 0.0f : std::fabs(*max_it))
|
||||||
|
<< "\n";
|
||||||
|
std::cout << "repeat=" << repeat << " cpp_avg_ms=" << (elapsed_ms / repeat) << "\n";
|
||||||
|
|
||||||
|
rlgym_s100_bpu_destroy(handle);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
349
deploy_45dim_rl_gym/bpu_deploy_s100/cpp/s100_bpu_policy.cpp
Normal file
349
deploy_45dim_rl_gym/bpu_deploy_s100/cpp/s100_bpu_policy.cpp
Normal file
@@ -0,0 +1,349 @@
|
|||||||
|
#include <algorithm>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <exception>
|
||||||
|
#include <limits>
|
||||||
|
#include <memory>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <hobot/dnn/hb_dnn.h>
|
||||||
|
#include <hobot/dnn/hb_dnn_status.h>
|
||||||
|
#include <hobot/hb_ucp.h>
|
||||||
|
#include <hobot/hb_ucp_status.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void set_error(char *err, int err_len, const std::string &msg) {
|
||||||
|
if (err == nullptr || err_len <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::snprintf(err, static_cast<size_t>(err_len), "%s", msg.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string api_error(const std::string &where, int32_t code) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << where << " failed: " << code;
|
||||||
|
const char *desc = hbDNNGetErrorDesc(code);
|
||||||
|
if (desc == nullptr) {
|
||||||
|
desc = hbUCPGetErrorDesc(code);
|
||||||
|
}
|
||||||
|
if (desc != nullptr) {
|
||||||
|
oss << " (" << desc << ")";
|
||||||
|
}
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_api(int32_t code, const std::string &where) {
|
||||||
|
if (code != 0) {
|
||||||
|
throw std::runtime_error(api_error(where, code));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t element_count(const hbDNNTensorShape &shape) {
|
||||||
|
int64_t count = 1;
|
||||||
|
for (int i = 0; i < shape.numDimensions; ++i) {
|
||||||
|
if (shape.dimensionSize[i] <= 0) {
|
||||||
|
throw std::runtime_error("dynamic or invalid tensor shape is not supported");
|
||||||
|
}
|
||||||
|
count *= shape.dimensionSize[i];
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int element_size(int tensor_type) {
|
||||||
|
switch (tensor_type) {
|
||||||
|
case HB_DNN_TENSOR_TYPE_BOOL8:
|
||||||
|
case HB_DNN_TENSOR_TYPE_S8:
|
||||||
|
case HB_DNN_TENSOR_TYPE_U8:
|
||||||
|
return 1;
|
||||||
|
case HB_DNN_TENSOR_TYPE_F16:
|
||||||
|
case HB_DNN_TENSOR_TYPE_S16:
|
||||||
|
case HB_DNN_TENSOR_TYPE_U16:
|
||||||
|
return 2;
|
||||||
|
case HB_DNN_TENSOR_TYPE_F32:
|
||||||
|
case HB_DNN_TENSOR_TYPE_S32:
|
||||||
|
case HB_DNN_TENSOR_TYPE_U32:
|
||||||
|
return 4;
|
||||||
|
case HB_DNN_TENSOR_TYPE_F64:
|
||||||
|
case HB_DNN_TENSOR_TYPE_S64:
|
||||||
|
case HB_DNN_TENSOR_TYPE_U64:
|
||||||
|
return 8;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("unsupported tensor type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t compact_tail_bytes(const int32_t *dims, int dim_count, int elem_bytes) {
|
||||||
|
int64_t bytes = elem_bytes;
|
||||||
|
for (int i = 0; i < dim_count; ++i) {
|
||||||
|
bytes *= dims[i];
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_compact_to_strided(char *dst, const char *src, const hbDNNTensorProperties &props,
|
||||||
|
int dim, int elem_bytes) {
|
||||||
|
const auto &shape = props.validShape;
|
||||||
|
if (dim + 1 == shape.numDimensions) {
|
||||||
|
std::memcpy(dst, src, static_cast<size_t>(shape.dimensionSize[dim] * elem_bytes));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int64_t src_step =
|
||||||
|
compact_tail_bytes(shape.dimensionSize + dim + 1, shape.numDimensions - dim - 1,
|
||||||
|
elem_bytes);
|
||||||
|
const int64_t dst_step = props.stride[dim];
|
||||||
|
for (int i = 0; i < shape.dimensionSize[dim]; ++i) {
|
||||||
|
copy_compact_to_strided(dst + dst_step * i, src + src_step * i, props, dim + 1,
|
||||||
|
elem_bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_strided_to_compact(char *dst, const char *src, const hbDNNTensorProperties &props,
|
||||||
|
int dim, int elem_bytes) {
|
||||||
|
const auto &shape = props.validShape;
|
||||||
|
if (dim + 1 == shape.numDimensions) {
|
||||||
|
std::memcpy(dst, src, static_cast<size_t>(shape.dimensionSize[dim] * elem_bytes));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int64_t dst_step =
|
||||||
|
compact_tail_bytes(shape.dimensionSize + dim + 1, shape.numDimensions - dim - 1,
|
||||||
|
elem_bytes);
|
||||||
|
const int64_t src_step = props.stride[dim];
|
||||||
|
for (int i = 0; i < shape.dimensionSize[dim]; ++i) {
|
||||||
|
copy_strided_to_compact(dst + dst_step * i, src + src_step * i, props, dim + 1,
|
||||||
|
elem_bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t core_mask_from_arg(int bpu_core) {
|
||||||
|
if (bpu_core < 0) {
|
||||||
|
return HB_UCP_BPU_CORE_ANY;
|
||||||
|
}
|
||||||
|
if (bpu_core > 3) {
|
||||||
|
throw std::runtime_error("bpu_core must be -1 or 0..3");
|
||||||
|
}
|
||||||
|
return 1ULL << static_cast<uint64_t>(bpu_core);
|
||||||
|
}
|
||||||
|
|
||||||
|
class S100BpuPolicy {
|
||||||
|
public:
|
||||||
|
S100BpuPolicy(const char *model_path, int bpu_core, int priority)
|
||||||
|
: bpu_core_mask_(core_mask_from_arg(bpu_core)), priority_(priority) {
|
||||||
|
if (model_path == nullptr || model_path[0] == '\0') {
|
||||||
|
throw std::runtime_error("empty model path");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *model_files[] = {model_path};
|
||||||
|
check_api(hbDNNInitializeFromFiles(&packed_handle_, model_files, 1),
|
||||||
|
"hbDNNInitializeFromFiles");
|
||||||
|
|
||||||
|
const char **model_names = nullptr;
|
||||||
|
int32_t model_count = 0;
|
||||||
|
check_api(hbDNNGetModelNameList(&model_names, &model_count, packed_handle_),
|
||||||
|
"hbDNNGetModelNameList");
|
||||||
|
if (model_count <= 0 || model_names == nullptr || model_names[0] == nullptr) {
|
||||||
|
throw std::runtime_error("model has no names");
|
||||||
|
}
|
||||||
|
model_name_ = model_names[0];
|
||||||
|
check_api(hbDNNGetModelHandle(&dnn_handle_, packed_handle_, model_names[0]),
|
||||||
|
"hbDNNGetModelHandle");
|
||||||
|
|
||||||
|
int32_t input_count = 0;
|
||||||
|
int32_t output_count = 0;
|
||||||
|
check_api(hbDNNGetInputCount(&input_count, dnn_handle_), "hbDNNGetInputCount");
|
||||||
|
check_api(hbDNNGetOutputCount(&output_count, dnn_handle_), "hbDNNGetOutputCount");
|
||||||
|
if (input_count != 1 || output_count != 1) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "expected 1 input and 1 output, got " << input_count << " inputs and "
|
||||||
|
<< output_count << " outputs";
|
||||||
|
throw std::runtime_error(oss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
input_tensors_.resize(1);
|
||||||
|
output_tensors_.resize(1);
|
||||||
|
check_api(hbDNNGetInputTensorProperties(&input_tensors_[0].properties, dnn_handle_, 0),
|
||||||
|
"hbDNNGetInputTensorProperties");
|
||||||
|
check_api(hbDNNGetOutputTensorProperties(&output_tensors_[0].properties, dnn_handle_, 0),
|
||||||
|
"hbDNNGetOutputTensorProperties");
|
||||||
|
|
||||||
|
validate_float_tensor(input_tensors_[0].properties, "input");
|
||||||
|
validate_float_tensor(output_tensors_[0].properties, "output");
|
||||||
|
input_floats_ = checked_float_count(input_tensors_[0].properties, "input");
|
||||||
|
output_floats_ = checked_float_count(output_tensors_[0].properties, "output");
|
||||||
|
|
||||||
|
alloc_tensor_mem(input_tensors_[0]);
|
||||||
|
alloc_tensor_mem(output_tensors_[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
~S100BpuPolicy() {
|
||||||
|
release_tensor_mem(input_tensors_);
|
||||||
|
release_tensor_mem(output_tensors_);
|
||||||
|
if (packed_handle_ != nullptr) {
|
||||||
|
hbDNNRelease(packed_handle_);
|
||||||
|
packed_handle_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void infer(const float *input, float *output) {
|
||||||
|
if (input == nullptr || output == nullptr) {
|
||||||
|
throw std::runtime_error("null input/output pointer");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &input_tensor = input_tensors_[0];
|
||||||
|
const auto &input_props = input_tensor.properties;
|
||||||
|
std::memset(input_tensor.sysMem.virAddr, 0,
|
||||||
|
static_cast<size_t>(input_props.alignedByteSize));
|
||||||
|
copy_compact_to_strided(reinterpret_cast<char *>(input_tensor.sysMem.virAddr),
|
||||||
|
reinterpret_cast<const char *>(input), input_props, 0,
|
||||||
|
sizeof(float));
|
||||||
|
check_api(hbUCPMemFlush(&input_tensor.sysMem, HB_SYS_MEM_CACHE_CLEAN),
|
||||||
|
"hbUCPMemFlush(input)");
|
||||||
|
|
||||||
|
hbUCPTaskHandle_t task_handle = nullptr;
|
||||||
|
check_api(hbDNNInferV2(&task_handle, output_tensors_.data(), input_tensors_.data(),
|
||||||
|
dnn_handle_),
|
||||||
|
"hbDNNInferV2");
|
||||||
|
|
||||||
|
hbUCPSchedParam sched_param{};
|
||||||
|
HB_UCP_INITIALIZE_SCHED_PARAM(&sched_param);
|
||||||
|
sched_param.priority = priority_;
|
||||||
|
sched_param.backend = bpu_core_mask_;
|
||||||
|
try {
|
||||||
|
check_api(hbUCPSubmitTask(task_handle, &sched_param), "hbUCPSubmitTask");
|
||||||
|
check_api(hbUCPWaitTaskDone(task_handle, 0), "hbUCPWaitTaskDone");
|
||||||
|
|
||||||
|
auto &output_tensor = output_tensors_[0];
|
||||||
|
check_api(hbUCPMemFlush(&output_tensor.sysMem, HB_SYS_MEM_CACHE_INVALIDATE),
|
||||||
|
"hbUCPMemFlush(output)");
|
||||||
|
copy_strided_to_compact(reinterpret_cast<char *>(output),
|
||||||
|
reinterpret_cast<const char *>(output_tensor.sysMem.virAddr),
|
||||||
|
output_tensor.properties, 0, sizeof(float));
|
||||||
|
} catch (...) {
|
||||||
|
hbUCPReleaseTask(task_handle);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
check_api(hbUCPReleaseTask(task_handle), "hbUCPReleaseTask");
|
||||||
|
}
|
||||||
|
|
||||||
|
int input_floats() const { return input_floats_; }
|
||||||
|
int output_floats() const { return output_floats_; }
|
||||||
|
const std::string &model_name() const { return model_name_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void validate_float_tensor(const hbDNNTensorProperties &props, const char *name) {
|
||||||
|
if (props.tensorType != HB_DNN_TENSOR_TYPE_F32) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << name << " tensor type " << props.tensorType << " != "
|
||||||
|
<< HB_DNN_TENSOR_TYPE_F32;
|
||||||
|
throw std::runtime_error(oss.str());
|
||||||
|
}
|
||||||
|
if (props.alignedByteSize <= 0) {
|
||||||
|
throw std::runtime_error(std::string(name) + " alignedByteSize <= 0");
|
||||||
|
}
|
||||||
|
if (props.validShape.numDimensions <= 0) {
|
||||||
|
throw std::runtime_error(std::string(name) + " has invalid dimensions");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int checked_float_count(const hbDNNTensorProperties &props, const char *name) {
|
||||||
|
const int64_t floats = element_count(props.validShape);
|
||||||
|
const int64_t bytes = floats * element_size(props.tensorType);
|
||||||
|
if (bytes > props.alignedByteSize) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << name << " compact bytes " << bytes << " > alignedByteSize "
|
||||||
|
<< props.alignedByteSize;
|
||||||
|
throw std::runtime_error(oss.str());
|
||||||
|
}
|
||||||
|
if (floats > static_cast<int64_t>(std::numeric_limits<int>::max())) {
|
||||||
|
throw std::runtime_error(std::string(name) + " tensor is too large");
|
||||||
|
}
|
||||||
|
return static_cast<int>(floats);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void alloc_tensor_mem(hbDNNTensor &tensor) {
|
||||||
|
std::memset(&tensor.sysMem, 0, sizeof(tensor.sysMem));
|
||||||
|
check_api(hbUCPMallocCached(&tensor.sysMem,
|
||||||
|
static_cast<uint64_t>(tensor.properties.alignedByteSize), 0),
|
||||||
|
"hbUCPMallocCached");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void release_tensor_mem(std::vector<hbDNNTensor> &tensors) {
|
||||||
|
for (auto &tensor : tensors) {
|
||||||
|
if (tensor.sysMem.virAddr != nullptr) {
|
||||||
|
hbUCPFree(&tensor.sysMem);
|
||||||
|
std::memset(&tensor.sysMem, 0, sizeof(tensor.sysMem));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hbDNNPackedHandle_t packed_handle_{nullptr};
|
||||||
|
hbDNNHandle_t dnn_handle_{nullptr};
|
||||||
|
std::string model_name_;
|
||||||
|
std::vector<hbDNNTensor> input_tensors_;
|
||||||
|
std::vector<hbDNNTensor> output_tensors_;
|
||||||
|
int input_floats_{0};
|
||||||
|
int output_floats_{0};
|
||||||
|
uint64_t bpu_core_mask_{HB_UCP_BPU_CORE_ANY};
|
||||||
|
int priority_{HB_UCP_PRIORITY_LOWEST};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
void *rlgym_s100_bpu_create(const char *model_path, int bpu_core, int priority,
|
||||||
|
char *err, int err_len) {
|
||||||
|
try {
|
||||||
|
set_error(err, err_len, "");
|
||||||
|
return new S100BpuPolicy(model_path, bpu_core, priority);
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
set_error(err, err_len, e.what());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int rlgym_s100_bpu_infer(void *handle, const float *input, float *output, char *err,
|
||||||
|
int err_len) {
|
||||||
|
try {
|
||||||
|
set_error(err, err_len, "");
|
||||||
|
if (handle == nullptr) {
|
||||||
|
throw std::runtime_error("null policy handle");
|
||||||
|
}
|
||||||
|
static_cast<S100BpuPolicy *>(handle)->infer(input, output);
|
||||||
|
return 0;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
set_error(err, err_len, e.what());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int rlgym_s100_bpu_input_floats(void *handle) {
|
||||||
|
if (handle == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return static_cast<S100BpuPolicy *>(handle)->input_floats();
|
||||||
|
}
|
||||||
|
|
||||||
|
int rlgym_s100_bpu_output_floats(void *handle) {
|
||||||
|
if (handle == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return static_cast<S100BpuPolicy *>(handle)->output_floats();
|
||||||
|
}
|
||||||
|
|
||||||
|
void rlgym_s100_bpu_destroy(void *handle) {
|
||||||
|
delete static_cast<S100BpuPolicy *>(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *rlgym_s100_bpu_version() {
|
||||||
|
return "cpp_dnn_api_s100";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -92,7 +92,7 @@ BPU_MODEL_REGISTRY = {
|
|||||||
}
|
}
|
||||||
DEFAULT_BPU_ROUND = "26000"
|
DEFAULT_BPU_ROUND = "26000"
|
||||||
DEFAULT_BPU_MODEL = BPU_MODEL_REGISTRY[DEFAULT_BPU_ROUND]
|
DEFAULT_BPU_MODEL = BPU_MODEL_REGISTRY[DEFAULT_BPU_ROUND]
|
||||||
LOWCMD_BACKEND = "cpp_lowcmd_cpp_lowstate_s100"
|
LOWCMD_BACKEND = "cpp_lowcmd_cpp_lowstate_cpp_udp_s100"
|
||||||
SPORT_KILL_CMD = (
|
SPORT_KILL_CMD = (
|
||||||
'ssh pi@192.168.123.161 "sudo pkill -9 -f keep_sport_alive; '
|
'ssh pi@192.168.123.161 "sudo pkill -9 -f keep_sport_alive; '
|
||||||
'sudo pkill -9 -f Legged_sport; sudo pkill -9 -f appTransit"'
|
'sudo pkill -9 -f Legged_sport; sudo pkill -9 -f appTransit"'
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ BPU_MODEL_REGISTRY = {
|
|||||||
}
|
}
|
||||||
DEFAULT_BPU_ROUND = "26000"
|
DEFAULT_BPU_ROUND = "26000"
|
||||||
DEFAULT_BPU_MODEL = BPU_MODEL_REGISTRY[DEFAULT_BPU_ROUND]
|
DEFAULT_BPU_MODEL = BPU_MODEL_REGISTRY[DEFAULT_BPU_ROUND]
|
||||||
LOWCMD_BACKEND = "cpp_lowcmd_cpp_lowstate"
|
LOWCMD_BACKEND = "cpp_lowcmd_cpp_lowstate_cpp_udp"
|
||||||
SPORT_KILL_CMD = (
|
SPORT_KILL_CMD = (
|
||||||
'ssh pi@192.168.123.161 "sudo pkill -9 -f keep_sport_alive; '
|
'ssh pi@192.168.123.161 "sudo pkill -9 -f keep_sport_alive; '
|
||||||
'sudo pkill -9 -f Legged_sport; sudo pkill -9 -f appTransit"'
|
'sudo pkill -9 -f Legged_sport; sudo pkill -9 -f appTransit"'
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ BPU_MODEL_REGISTRY = {
|
|||||||
}
|
}
|
||||||
DEFAULT_BPU_ROUND = "35k"
|
DEFAULT_BPU_ROUND = "35k"
|
||||||
DEFAULT_BPU_MODEL = BPU_MODEL_REGISTRY[DEFAULT_BPU_ROUND]
|
DEFAULT_BPU_MODEL = BPU_MODEL_REGISTRY[DEFAULT_BPU_ROUND]
|
||||||
LOWCMD_BACKEND = "cpp_lowcmd_cpp_lowstate"
|
LOWCMD_BACKEND = "cpp_lowcmd_cpp_lowstate_cpp_udp"
|
||||||
SPORT_KILL_CMD = (
|
SPORT_KILL_CMD = (
|
||||||
'ssh pi@192.168.123.161 "sudo pkill -9 -f keep_sport_alive; '
|
'ssh pi@192.168.123.161 "sudo pkill -9 -f keep_sport_alive; '
|
||||||
'sudo pkill -9 -f Legged_sport; sudo pkill -9 -f appTransit"'
|
'sudo pkill -9 -f Legged_sport; sudo pkill -9 -f appTransit"'
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ except ImportError as exc:
|
|||||||
) from exc
|
) from exc
|
||||||
|
|
||||||
DEFAULT_ONNX = HERE / "policy_robotlab_6500.onnx"
|
DEFAULT_ONNX = HERE / "policy_robotlab_6500.onnx"
|
||||||
LOWCMD_BACKEND = "cpp_lowcmd_cpp_lowstate"
|
LOWCMD_BACKEND = "cpp_lowcmd_cpp_lowstate_cpp_udp"
|
||||||
SPORT_KILL_CMD = (
|
SPORT_KILL_CMD = (
|
||||||
'ssh pi@192.168.123.161 "sudo pkill -9 -f keep_sport_alive; '
|
'ssh pi@192.168.123.161 "sudo pkill -9 -f keep_sport_alive; '
|
||||||
'sudo pkill -9 -f Legged_sport; sudo pkill -9 -f appTransit"'
|
'sudo pkill -9 -f Legged_sport; sudo pkill -9 -f appTransit"'
|
||||||
|
|||||||
Reference in New Issue
Block a user