算子测试编写指南
文件结构
写一个算子的测试需要 2 个文件:
src/<op_name>/tests/
├── <op_name>_test.h # 头文件(必需)
└── <op_name>_test.cpp # 实现文件(必需)
头文件(必需)
文件:<op_name>_test.h
内容:
#pragma once
#include "test_common.h"
namespace <OpName>Test {
void run_all_tests(aclrtStream stream, OpsFftTest::TestStats& stats);
}
说明:
- 命名空间:
<OpName>Test(首字母大写,用于隔离不同算子的测试) - 函数名:
run_all_tests(固定名称,测试框架会调用此函数) - 参数说明:
aclrtStream stream- ACL 运行流,用于执行算子TestStats& stats- 测试统计对象,用于记录测试结果
实现文件(必需)
文件:<op_name>_test.cpp
必须包含的 3 个部分:
1. 测试用例函数(必需,至少1个)
函数签名:
void test_xxx(aclrtStream stream, OpsFftTest::TestStats& stats);
参数说明:
stream- 传递给算子调用,用于在 NPU 上执行stats- 传递给所有测试宏(TEST_ASSERT、TEST_CASE_PASS 等),用于自动统计
示例:
void test_xxx(aclrtStream stream, OpsFftTest::TestStats& stats) {
TEST_CASE_BEGIN("test_xxx");
// 准备数据
float input1[] = {1.0f, 2.0f};
float input2[] = {2.0f, 3.0f};
float expected[] = {3.0f, 5.0f};
float output[2];
// 调用算子
// 可以直接调用算子的接口
aclError result = acl<OpName>(input1, input2, output, 2, stream);
// 也可以通过Api来调用
// aclError result = aclfftExecR2C(plan, input1, output);
// 验证结果
TEST_ASSERT(stats, result == ACL_SUCCESS, "failed");
TEST_ASSERT_ARRAY_NEAR(stats, output, expected, 2, 1e-6f, "mismatch");
TEST_CASE_PASS(stats, "test_xxx");
}
2. run_all_tests 实现(必需)
namespace <OpName>Test {
void run_all_tests(aclrtStream stream, OpsFftTest::TestStats& stats) {
test_xxx(stream, stats);
// 可以添加更多测试函数
}
}
3. 自动注册(必需)
REGISTER_OP_TEST(<OpName>)
完整示例
my_op_test.h
#pragma once
#include "test_common.h"
namespace MyOpTest {
void run_all_tests(aclrtStream stream, OpsFftTest::TestStats& stats);
}
my_op_test.cpp
#include "cann_ops_fft.h"
#include "my_op_test.h"
void test_basic(aclrtStream stream, OpsFftTest::TestStats& stats) {
TEST_CASE_BEGIN("test_basic");
float x1[] = {1.0f, 2.0f};
float x2[] = {2.0f, 3.0f};
float expected[] = {3.0f, 5.0f};
float y[2];
aclError result = aclMyOp(x1, x2, y, 2, stream);
TEST_ASSERT(stats, result == ACL_SUCCESS, "failed");
TEST_ASSERT_ARRAY_NEAR(stats, y, expected, 2, 1e-6f, "mismatch");
TEST_CASE_PASS(stats, "test_basic");
}
namespace MyOpTest {
void run_all_tests(aclrtStream stream, OpsFftTest::TestStats& stats) {
test_basic(stream, stats);
}
}
REGISTER_OP_TEST(MyOp)
可用的宏
用例控制
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/rfft1_d/tests/rfft1_d_test.cpp