Line data Source code
1 : /*************************************************************************
2 : * Testing Mtx class operations
3 : ************************************************************************/
4 : #include "t_matrix.hpp"
5 : #include <chrono>
6 : #include <cmath>
7 : #include <cstdint>
8 : #include <gtest/gtest.h>
9 : #include <iostream>
10 : #include <limits.h>
11 : #include <openGPMP/linalg/mtx.hpp>
12 : #include <openGPMP/linalg/mtx_tmpl.hpp>
13 : #include <string>
14 : #include <vector>
15 :
16 : const double TOLERANCE = 1e-3;
17 :
18 : using namespace gpmp;
19 : #define TEST_COUT std::cerr << "\033[32m[ ] [ INFO ] \033[0m"
20 : #define INFO_COUT \
21 : std::cerr << "\033[32m[ ] [ INFO ] \033[0m\033[1;34m\033[1m"
22 :
23 : namespace {
24 :
25 4 : TEST(MatrixArrayTestF64, AdditionComparisonSmall) {
26 :
27 1 : INFO_COUT << "MATRIX (as Arrays) FLOAT64" << std::endl;
28 :
29 1 : int mtx_size = 64;
30 : // define input matrices A and B
31 1 : double *A = new double[mtx_size * mtx_size];
32 1 : double *B = new double[mtx_size * mtx_size];
33 1 : double *expected = new double[mtx_size * mtx_size];
34 1 : double *result = new double[mtx_size * mtx_size];
35 :
36 : // initialize random number generator
37 1 : std::random_device rd;
38 1 : std::mt19937 gen(rd());
39 1 : std::uniform_real_distribution<double> distribution(1.0, 100.0);
40 :
41 : // populate matrices A and B with random values
42 65 : for (int i = 0; i < mtx_size; ++i) {
43 4160 : for (int j = 0; j < mtx_size; ++j) {
44 4096 : A[i * mtx_size + j] = distribution(gen);
45 4096 : B[i * mtx_size + j] = distribution(gen);
46 : }
47 : }
48 :
49 : gpmp::linalg::Mtx mtx;
50 : // expected result using the naive implementation
51 1 : mtx.std_mtx_add(A, B, expected, mtx_size, mtx_size);
52 :
53 : // result using the intrinsics implementation
54 1 : mtx.mtx_add(A, B, result, mtx_size, mtx_size);
55 :
56 : /*
57 : std::cout << "Matrix EXPECTED after addition:" << std::endl;
58 : for (int i = 0; i < mtx_size; ++i) {
59 : for (int j = 0; j < mtx_size; ++j) {
60 : std::cout << expected[i][j] << " ";
61 : }
62 : std::cout << std::endl;
63 : }
64 :
65 : std::cout << "Matrix RESULT after addition:" << std::endl;
66 : for (int i = 0; i < mtx_size; ++i) {
67 : for (int j = 0; j < mtx_size; ++j) {
68 : std::cout << result[i][j] << " ";
69 : }
70 : std::cout << std::endl;
71 : }
72 : */
73 :
74 : // compare the results
75 1 : ASSERT_TRUE(mtx_verif(expected, result, mtx_size, mtx_size));
76 1 : delete[] A;
77 1 : delete[] B;
78 1 : delete[] expected;
79 1 : delete[] result;
80 1 : }
81 :
82 4 : TEST(MatrixArrayTestF64, AdditionComparisonLarge) {
83 1 : int mtx_size = 1024;
84 : // define input matrices A and B
85 1 : double *A = new double[mtx_size * mtx_size];
86 1 : double *B = new double[mtx_size * mtx_size];
87 1 : double *expected = new double[mtx_size * mtx_size];
88 1 : double *result = new double[mtx_size * mtx_size];
89 :
90 : // initialize random number generator
91 1 : std::random_device rd;
92 1 : std::mt19937 gen(rd());
93 1 : std::uniform_real_distribution<double> distribution(1.0, 100.0);
94 :
95 : // populate matrices A and B with random values
96 1025 : for (int i = 0; i < mtx_size; ++i) {
97 1049600 : for (int j = 0; j < mtx_size; ++j) {
98 1048576 : A[i * mtx_size + j] = distribution(gen);
99 1048576 : B[i * mtx_size + j] = distribution(gen);
100 : }
101 : }
102 :
103 : gpmp::linalg::Mtx mtx;
104 : // expected result using the naive implementation
105 1 : mtx.std_mtx_add(A, B, expected, mtx_size, mtx_size);
106 :
107 : // result using the intrinsics implementation
108 1 : mtx.mtx_add(A, B, result, mtx_size, mtx_size);
109 : // compare the results
110 1 : ASSERT_TRUE(mtx_verif(expected, result, mtx_size, mtx_size));
111 1 : delete[] A;
112 1 : delete[] B;
113 1 : delete[] expected;
114 1 : delete[] result;
115 1 : }
116 :
117 4 : TEST(MatrixArrayTestF64, AdditionPerformanceComparison) {
118 1 : int mtx_size = 1024;
119 1 : TEST_COUT << "Matrix size : " << mtx_size << std::endl;
120 : // define input matrices A and B
121 1 : double *A = new double[mtx_size * mtx_size];
122 1 : double *B = new double[mtx_size * mtx_size];
123 1 : double *expected = new double[mtx_size * mtx_size];
124 1 : double *result = new double[mtx_size * mtx_size];
125 :
126 : // initialize random number generator
127 1 : std::random_device rd;
128 1 : std::mt19937 gen(rd());
129 1 : std::uniform_real_distribution<double> distribution(1.0, 100.0);
130 :
131 : // populate matrices A and B with random values
132 1025 : for (int i = 0; i < mtx_size; ++i) {
133 1049600 : for (int j = 0; j < mtx_size; ++j) {
134 1048576 : A[i * mtx_size + j] = distribution(gen);
135 1048576 : B[i * mtx_size + j] = distribution(gen);
136 : }
137 : }
138 :
139 : gpmp::linalg::Mtx mtx;
140 1 : auto start_std = std::chrono::high_resolution_clock::now();
141 :
142 : // expected result using the naive implementation
143 1 : mtx.std_mtx_add(A, B, expected, mtx_size, mtx_size);
144 :
145 1 : auto end_std = std::chrono::high_resolution_clock::now();
146 1 : std::chrono::duration<double> elapsed_seconds_std = end_std - start_std;
147 :
148 1 : auto start_intrin = std::chrono::high_resolution_clock::now();
149 :
150 : // result using the intrinsics implementation
151 1 : mtx.mtx_add(A, B, result, mtx_size, mtx_size);
152 1 : auto end_intrin = std::chrono::high_resolution_clock::now();
153 : std::chrono::duration<double> elapsed_seconds_intrin =
154 1 : end_intrin - start_intrin;
155 :
156 1 : TEST_COUT << "INTRINSIC Matrix Addition Time : "
157 1 : << elapsed_seconds_intrin.count() << " seconds" << std::endl;
158 1 : TEST_COUT << "STANDARD Matrix Addition Time : "
159 1 : << elapsed_seconds_std.count() << " seconds" << std::endl;
160 :
161 : // compare the results
162 1 : ASSERT_TRUE(mtx_verif(expected, result, mtx_size, mtx_size));
163 1 : delete[] A;
164 1 : delete[] B;
165 1 : delete[] expected;
166 1 : delete[] result;
167 1 : }
168 :
169 4 : TEST(MatrixArrayTestF64, MultiplicationPerformanceComparison) {
170 1 : int mtx_size = 1024;
171 1 : TEST_COUT << "Matrix size : " << mtx_size << std::endl;
172 : // define input matrices A and B
173 1 : double *A = new double[mtx_size * mtx_size];
174 1 : double *B = new double[mtx_size * mtx_size];
175 1 : double *expected = new double[mtx_size * mtx_size];
176 1 : double *result = new double[mtx_size * mtx_size];
177 :
178 : // initialize random number generator
179 1 : std::random_device rd;
180 1 : std::mt19937 gen(rd());
181 1 : std::uniform_real_distribution<double> distribution(1.0, 100.0);
182 :
183 : // populate matrices A and B with random values
184 1025 : for (int i = 0; i < mtx_size; ++i) {
185 1049600 : for (int j = 0; j < mtx_size; ++j) {
186 1048576 : A[i * mtx_size + j] = distribution(gen);
187 1048576 : B[i * mtx_size + j] = distribution(gen);
188 : }
189 : }
190 :
191 : gpmp::linalg::Mtx mtx;
192 1 : auto start_std = std::chrono::high_resolution_clock::now();
193 :
194 : // expected result using the naive implementation
195 1 : mtx.std_mtx_mult(A, B, expected, mtx_size, mtx_size, mtx_size);
196 :
197 1 : auto end_std = std::chrono::high_resolution_clock::now();
198 1 : std::chrono::duration<double> elapsed_seconds_std = end_std - start_std;
199 :
200 1 : auto start_intrin = std::chrono::high_resolution_clock::now();
201 :
202 : // result using the intrinsics implementation
203 1 : mtx.mtx_mult(A, B, result, mtx_size, mtx_size, mtx_size);
204 1 : auto end_intrin = std::chrono::high_resolution_clock::now();
205 : std::chrono::duration<double> elapsed_seconds_intrin =
206 1 : end_intrin - start_intrin;
207 :
208 1 : TEST_COUT << "INTRINSIC Matrix Multiplication Time : "
209 1 : << elapsed_seconds_intrin.count() << " seconds" << std::endl;
210 1 : TEST_COUT << "STANDARD Matrix Multiplication Time : "
211 1 : << elapsed_seconds_std.count() << " seconds" << std::endl;
212 :
213 : // compare the results
214 1025 : for (int i = 0; i < mtx_size; i++) {
215 1049600 : for (int j = 0; j < mtx_size; j++) {
216 1048576 : EXPECT_NEAR(expected[i * mtx_size + j],
217 : result[i * mtx_size + j],
218 1048576 : TOLERANCE);
219 : }
220 : }
221 : // ASSERT_TRUE(mtx_verif(expected, result, mtx_size, mtx_size));
222 :
223 1 : delete[] A;
224 1 : delete[] B;
225 1 : delete[] expected;
226 1 : delete[] result;
227 1 : }
228 :
229 : } // namespace
|