算子测试编写指南
文件结构
写一个算子的测试需要 2 个文件:
src/<op_name>/tests/
├── <op_name>_test.h # 头文件(必需)
└── <op_name>_test.cpp # 实现文件(必需)
说明:测试框架提供了 ElementwiseBinaryTestConfig 辅助类和 ExecuteElementwiseBinaryTest 通用函数,简化测试编写。
头文件(必需)
文件:<op_name>_test.h
内容:
#pragma once
#include "test_common.h"
namespace <OpName>Test {
void run_all_tests(aclrtStream stream, OpsTensorTest::TestStats& stats);
}
说明:
- 命名空间:
<OpName>Test(首字母大写,用于隔离不同算子的测试) - 函数名:
run_all_tests(固定名称,测试框架会调用此函数) - 参数说明:
aclrtStream stream- ACL 运行流,用于执行算子TestStats& stats- 测试统计对象,用于记录测试结果
实现文件(必需)
文件:<op_name>_test.cpp
必须包含的 3 个部分:
1. 测试用例函数(必需,至少1个)
函数签名:
void test_xxx(aclrtStream stream, OpsTensorTest::TestStats& stats);
参数说明:
stream- 传递给算子调用,用于在 NPU 上执行stats- 传递给所有测试宏(TEST_ASSERT、TEST_CASE_PASS 等),用于自动统计
示例:
void test_<test_case_name>(aclrtStream stream, OpsTensorTest::TestStats& stats) {
TEST_CASE_BEGIN("test_<test_case_name>");
// 准备数据
std::vector<float> A{1.0f, 2.0f};
std::vector<float> C{2.0f, 3.0f};
std::vector<float> expected{3.0f, 5.0f};
std::vector<float> D(2);
// 使用测试框架提供的配置类
ElementwiseBinaryTestConfig config(2); // 一维,大小为2
// 调用通用测试函数(自动处理内存管理、数据拷贝等)
acltensorStatus_t result = ExecuteElementwiseBinaryTest(
A.data(), C.data(), D.data(), config, ACLTENSOR_OP_<OP_NAME>, stream);
// 验证结果
TEST_ASSERT(stats, result == ACLTENSOR_STATUS_SUCCESS, "failed");
TEST_ASSERT_ARRAY_NEAR(stats, D, expected, 2, 1e-6f, "mismatch");
TEST_CASE_PASS(stats, "test_<test_case_name>");
}
2. run_all_tests 实现(必需)
namespace <OpName>Test {
void run_all_tests(aclrtStream stream, OpsTensorTest::TestStats& stats) {
test_xxx(stream, stats);
// 可以添加更多测试函数
}
}
3. 自动注册(必需)
REGISTER_OP_TEST(<OpName>)
完整示例
<op_name>_test.h
#pragma once
#include "test_common.h"
namespace <OpName>Test {
void run_all_tests(aclrtStream stream, OpsTensorTest::TestStats& stats);
}
<op_name>_test.cpp
#include "cann_ops_tensor.h"
#include "<op_name>_test.h"
#include <vector>
void test_<case_name>(aclrtStream stream, OpsTensorTest::TestStats& stats) {
TEST_CASE_BEGIN("test_<case_name>");
std::vector<float> A{1.0f, 2.0f};
std::vector<float> C{2.0f, 3.0f};
std::vector<float> expected{3.0f, 5.0f};
std::vector<float> D(2);
ElementwiseBinaryTestConfig config(2);
acltensorStatus_t result = ExecuteElementwiseBinaryTest(
A.data(), C.data(), D.data(), config, ACLTENSOR_OP_<OP_NAME>, stream);
TEST_ASSERT(stats, result == ACLTENSOR_STATUS_SUCCESS, "failed");
TEST_ASSERT_ARRAY_NEAR(stats, D, expected, 2, 1e-6f, "mismatch");
TEST_CASE_PASS(stats, "test_<case_name>");
}
namespace <OpName>Test {
void run_all_tests(aclrtStream stream, OpsTensorTest::TestStats& stats) {
test_<case_name>(stream, stats);
}
}
REGISTER_OP_TEST(<op_name>)
可用的宏
用例控制
TEST_CASE_BEGIN("test_name") // 标记开始
TEST_CASE_PASS(stats, "test_name") // 标记通过
断言
TEST_ASSERT(stats, condition, "error") // 条件断言
TEST_ASSERT_ARRAY_EQ(stats, actual, expected, size, "error") // 精确比较
TEST_ASSERT_ARRAY_NEAR(stats, actual, expected, size, tol, "error") // 容差比较
编译运行
./build.sh --ops=<op_name> --run
参考示例
完整示例:src/add/tests/add_test.cpp