-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.h
More file actions
118 lines (104 loc) · 3.96 KB
/
utils.h
File metadata and controls
118 lines (104 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// ============================================================================
// 矩阵生成函数
// ============================================================================
// 生成行主序布局的随机矩阵(float32)
// 行主序:matrix[r][c] 存储在 matrix[r * cols + c]
// 参数:
// - a: 输出矩阵数组
// - rows: 行数
// - cols: 列数
// - seed: 随机数种子
static inline void generate_random_matrix_row_major(float* a, int rows, int cols, unsigned int seed) {
srand(seed);
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < cols; ++c) {
a[r * cols + c] = (float)rand() / (float)RAND_MAX * 2.0f - 1.0f;
}
}
}
// 生成列主序布局的随机矩阵(float32)
// 列主序:matrix[r][c] 存储在 matrix[c * rows + r]
// 参数:
// - a: 输出矩阵数组
// - rows: 行数
// - cols: 列数
// - seed: 随机数种子
static inline void generate_random_matrix_column_major(float* a, int rows, int cols, unsigned int seed) {
srand(seed);
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < cols; ++c) {
a[c * rows + r] = (float)rand() / (float)RAND_MAX * 2.0f - 1.0f;
}
}
}
// 生成行主序布局的随机矩阵(int16_t)
// 参数:
// - a: 输出矩阵数组
// - rows: 行数
// - cols: 列数
// - seed: 随机数种子
static inline void generate_random_matrix_row_major_int16(int16_t* a, int rows, int cols, unsigned int seed) {
srand(seed);
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < cols; ++c) {
a[r * cols + c] = (int16_t)(((float)rand() / (float)RAND_MAX * 0.1f + 1.0f) * 256);
}
}
}
// 生成列主序布局的随机矩阵(int16_t)
// 参数:
// - a: 输出矩阵数组
// - rows: 行数
// - cols: 列数
// - seed: 随机数种子
static inline void generate_random_matrix_column_major_int16(int16_t* a, int rows, int cols, unsigned int seed) {
srand(seed);
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < cols; ++c) {
a[c * rows + r] = (int16_t)(((float)rand() / (float)RAND_MAX * 0.1f + 1.0f) * 256);
}
}
}
// ============================================================================
// 结果验证函数
// ============================================================================
// 验证两个 float 数组是否匹配(统一验证函数)
// 使用 "绝对值转正数" 方法避免除零问题
// 参数:
// - got: 实际计算结果数组
// - ref: 期望结果数组(CPU 参考结果)
// - total_elements: 数组元素总数
// - name: 验证名称(用于输出)
// - atol: 绝对误差容忍阈值
// - rtol: 相对误差容忍阈值
// 返回值:1 表示通过,0 表示失败
//
// 验证逻辑:
// - 计算绝对误差:|got[i] - ref[i]|
// - 计算相对误差:|got[i] - ref[i]| / |ref[i]|(处理 ref[i] == 0 的情况)
// - 只要 max_abs_err <= atol 或 max_rel_err <= rtol,就认为通过
static inline int verify_rm_rm(const float* got, const float* ref, int total_elements, const char* name,
float atol, float rtol) {
float max_abs_err = 0.0f, max_rel_err = 0.0f;
for (int i = 0; i < total_elements; ++i) {
// 计算绝对误差
float abs_err = got[i] - ref[i];
if (abs_err < 0) abs_err = -abs_err;
// 计算相对误差(使用绝对值转正数方法避免除零)
float abs_ref = ref[i];
if (abs_ref < 0) abs_ref = -abs_ref;
float rel_err = (abs_ref == 0.0f) ? abs_err : (abs_err / abs_ref);
// 更新最大误差
if (abs_err > max_abs_err) max_abs_err = abs_err;
if (rel_err > max_rel_err) max_rel_err = rel_err;
}
// 判断是否通过(绝对误差或相对误差任一满足即可)
int pass = (max_abs_err <= atol) || (max_rel_err <= rtol);
printf("%s Check: %s (abs=%.6f, rel=%.6f, atol=%.6f, rtol=%.6f)\n",
name, pass ? "PASS" : "FAIL", max_abs_err, max_rel_err, atol, rtol);
return pass;
}