Skip to content
This repository was archived by the owner on Mar 28, 2023. It is now read-only.

Commit 60cfbf7

Browse files
committed
Add matrix types extension tests.
This adds a set of initial tests that check that some of the matrix types extension matches the spec. Reviewers: anemet, paquette, rjmccall, LuoYuanke Reviewed By: anemet Differential Revision: https://reviews.llvm.org/D72770
1 parent a70e8c8 commit 60cfbf7

File tree

3 files changed

+188
-0
lines changed

3 files changed

+188
-0
lines changed

SingleSource/UnitTests/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
include(CheckCCompilerFlag)
2+
13
add_subdirectory(C++11)
24
add_subdirectory(SignlessTypes)
35
add_subdirectory(Threads)
@@ -45,4 +47,13 @@ if(NOT ARCH STREQUAL "x86")
4547
ms_struct_pack_layout-1.c
4648
)
4749
endif()
50+
51+
# Enable matrix types extension tests for compilers supporting -fenable-matrix.
52+
check_c_compiler_flag(-fenable-matrix COMPILER_HAS_MATRIX_FLAG)
53+
if (COMPILER_HAS_MATRIX_FLAG)
54+
set_property(SOURCE matrix-types-spec.cpp PROPERTY COMPILE_FLAGS -fenable-matrix)
55+
else()
56+
list(REMOVE_ITEM Source matrix-types-spec.cpp)
57+
endif()
58+
4859
llvm_singlesource()
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
// Runtime tests to ensure the Matrix Type extension implementation matches the
2+
// specification.
3+
4+
// Only build the tests if the proper extensions is available.
5+
#if __has_extension(matrix_types)
6+
7+
#include <iostream>
8+
#include <random>
9+
#include <stdlib.h>
10+
11+
#define EXPECT_MATRIX_EQ(A, B, R, C) \
12+
do { \
13+
for (unsigned r = 0; r < R; r++) \
14+
for (unsigned c = 0; c < C; c++) \
15+
if (A[r + c * R] != B[r + c * R]) { \
16+
std::cerr << "mismatch at " << r << ":" << c << "\n"; \
17+
exit(1); \
18+
} \
19+
} while (false)
20+
21+
template <typename EltTy>
22+
void zeroMatrix(EltTy *M, unsigned Rows, unsigned Cols) {
23+
for (unsigned r = 0; r < Rows; r++)
24+
for (unsigned c = 0; c < Cols; c++)
25+
M[r + c * Rows] = 0;
26+
}
27+
28+
template <typename EltTy> void print(EltTy *X, unsigned Rows, unsigned Cols) {
29+
for (int r = 0; r < Rows; r++) {
30+
for (int c = 0; c < Cols; c++)
31+
std::cout << X[r + c * Rows] << ", ";
32+
std::cout << "\n";
33+
}
34+
}
35+
36+
template <typename Ty> void initRandom(Ty *A, unsigned Rows, unsigned Cols) {
37+
std::default_random_engine generator;
38+
std::uniform_int_distribution<double> distribution(-10.0, 10.0);
39+
auto random_double = std::bind(distribution, generator);
40+
41+
for (unsigned i = 0; i < Rows * Cols; i++)
42+
A[i] = random_double();
43+
}
44+
45+
template <typename EltTy, unsigned R, unsigned C>
46+
void transposeBuiltin(EltTy *ResPtr, EltTy *SrcPtr) {
47+
auto M = __builtin_matrix_column_major_load(SrcPtr, R, C, R);
48+
__builtin_matrix_column_major_store(__builtin_matrix_transpose(M), ResPtr, C);
49+
}
50+
51+
template <typename EltTy, unsigned R, unsigned C>
52+
void transposeSpec(EltTy *ResPtr, EltTy *SrcPtr) {
53+
using matrix_trans_t = EltTy __attribute__((matrix_type(C, R)));
54+
auto M = __builtin_matrix_column_major_load(SrcPtr, R, C, R);
55+
matrix_trans_t Res;
56+
for (int c = 0; c < C; ++c)
57+
for (int r = 0; r < R; ++r)
58+
Res[c][r] = M[r][c];
59+
__builtin_matrix_column_major_store(Res, ResPtr, C);
60+
}
61+
62+
template <typename Ty>
63+
static void transposeBase(Ty *Res, Ty *Src, unsigned R0, unsigned C0) {
64+
for (unsigned r = 0; r < R0; r++) {
65+
for (unsigned c = 0; c < C0; c++)
66+
Res[c + r * C0] = Src[r + c * R0];
67+
}
68+
}
69+
70+
template <typename EltTy, unsigned R0, unsigned C0> void testTranspose() {
71+
EltTy X[R0 * C0];
72+
EltTy ResBase[R0 * C0];
73+
EltTy ResSpec[R0 * C0];
74+
EltTy ResBuiltin[R0 * C0];
75+
76+
initRandom(X, R0, C0);
77+
zeroMatrix(ResBase, C0, R0);
78+
zeroMatrix(ResSpec, C0, R0);
79+
zeroMatrix(ResBuiltin, C0, R0);
80+
81+
transposeBase(ResBase, X, R0, C0);
82+
transposeSpec<EltTy, R0, C0>(ResSpec, X);
83+
transposeBuiltin<EltTy, R0, C0>(ResBuiltin, X);
84+
85+
EXPECT_MATRIX_EQ(ResBase, ResBuiltin, R0, C0);
86+
EXPECT_MATRIX_EQ(ResBase, ResSpec, C0, R0);
87+
}
88+
89+
template <typename EltTy, unsigned R0, unsigned C0, unsigned C1>
90+
void multiplyBuiltin(EltTy *Res, EltTy *Matrix1, EltTy *Matrix2) {
91+
using res_t = EltTy __attribute__((matrix_type(R0, C1)));
92+
93+
auto A = __builtin_matrix_column_major_load(Matrix1, R0, C0, R0);
94+
auto B = __builtin_matrix_column_major_load(Matrix2, C0, C1, C0);
95+
res_t C = A * B;
96+
__builtin_matrix_column_major_store(C, Res, R0);
97+
}
98+
99+
template <typename EltTy, unsigned R0, unsigned C0, unsigned C1>
100+
void multiplySpec(EltTy *Res, EltTy *Matrix1, EltTy *Matrix2) {
101+
using res_t = EltTy __attribute__((matrix_type(R0, C1)));
102+
103+
auto A = __builtin_matrix_column_major_load(Matrix1, R0, C0, R0);
104+
auto B = __builtin_matrix_column_major_load(Matrix2, C0, C1, C0);
105+
res_t ResM;
106+
for (int C = 0; C < C1; ++C) {
107+
for (int R = 0; R < R0; ++R) {
108+
EltTy Elt = 0;
109+
for (int K = 0; K < C0; K++)
110+
Elt += A[R][K] * B[K][C];
111+
ResM[R][C] = Elt;
112+
}
113+
}
114+
__builtin_matrix_column_major_store(ResM, Res, R0);
115+
}
116+
117+
template <typename Ty>
118+
static void BaseMatrixMult(Ty *A, Ty *B, Ty *C, unsigned R0, unsigned C0,
119+
unsigned R1, unsigned C1) {
120+
for (unsigned i = 0; i < R0; i++)
121+
for (unsigned j = 0; j < C1; j++)
122+
for (unsigned c = 0; c < C0; c++)
123+
C[i + j * R0] += A[i + c * R0] * B[c + j * R1];
124+
}
125+
126+
template <typename EltTy, unsigned R0, unsigned C0, unsigned C1>
127+
static void multiplyBase(EltTy *C, EltTy *A, EltTy *B) {
128+
for (unsigned i = 0; i < R0; i++)
129+
for (unsigned j = 0; j < C1; j++)
130+
for (unsigned c = 0; c < C0; c++) {
131+
C[i + j * R0] += A[i + c * R0] * B[c + j * C0];
132+
}
133+
}
134+
135+
template <typename EltTy, unsigned R0, unsigned C0, unsigned C1>
136+
void testMultiply() {
137+
EltTy X[R0 * C0];
138+
EltTy Y[C0 * C1];
139+
EltTy ResBase[R0 * C1];
140+
EltTy ResSpec[R0 * C1];
141+
EltTy ResBuiltin[R0 * C1];
142+
143+
initRandom(X, R0, C0);
144+
initRandom(Y, C0, C1);
145+
zeroMatrix(ResBase, R0, C1);
146+
zeroMatrix(ResSpec, R0, C1);
147+
zeroMatrix(ResBuiltin, R0, C1);
148+
149+
multiplyBase<EltTy, R0, C0, C1>(ResBase, X, Y);
150+
multiplySpec<EltTy, R0, C0, C1>(ResSpec, X, Y);
151+
multiplyBuiltin<EltTy, R0, C0, C1>(ResBuiltin, X, Y);
152+
153+
EXPECT_MATRIX_EQ(ResSpec, ResBuiltin, R0, C1);
154+
EXPECT_MATRIX_EQ(ResBase, ResBuiltin, R0, C1);
155+
EXPECT_MATRIX_EQ(ResBase, ResSpec, R0, C1);
156+
}
157+
158+
int main(void) {
159+
testTranspose<double, 3, 3>();
160+
testTranspose<double, 3, 10>();
161+
testTranspose<double, 4, 3>();
162+
testTranspose<float, 31, 17>();
163+
testTranspose<unsigned, 8, 7>();
164+
165+
testMultiply<double, 3, 3, 3>();
166+
testMultiply<double, 10, 21, 23>();
167+
testMultiply<double, 25, 19, 11>();
168+
169+
return 0;
170+
}
171+
172+
#else
173+
int main(void) {
174+
return 0;
175+
}
176+
#endif
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exit 0

0 commit comments

Comments
 (0)