-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.cpp
151 lines (140 loc) · 4.32 KB
/
main.cpp
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <ctime>
#include <iostream>
#include <cstdlib>
extern "C"
{
#include <cblas.h> // OpenBlas
}
#define re (0)
#define im (1)
#define rounds (5000000)
#define A_R (3) // The number of rows and columns in each matrix.
#define A_C (3) // This makes the arguments in OpenBLAS easier to understand.
#define B_R (3)
#define B_C (3)
/*
* multiply complex 3x3 matrix
* C = A X B
*/
void multiply_complex_matrix(double A[3][3][2],double B[3][3][2],double C[3][3][2])
{
int i,j,k;
for (i=0; i<3; i++) {
for (j=0; j<3; j++) {
for (k=0; k<3; k++) {
C[i][j][re] += A[i][k][re]*B[k][j][re]-A[i][k][im]*B[k][j][im];
C[i][j][im] += A[i][k][im]*B[k][j][re]+A[i][k][re]*B[k][j][im];
}
}
}
}
/*
* multiply complex 3x3 matrix and 3 vector
* W = A X V
*/
void multiply_complex_matvec(double A[3][3][2],double V[3][2],double W[3][2])
{
int i;
for(i=0;i<3;i++) {
W[i][re] = A[i][0][re]*V[0][re]-A[i][0][im]*V[0][im]+
A[i][1][re]*V[1][re]-A[i][1][im]*V[1][im]+
A[i][2][re]*V[2][re]-A[i][2][im]*V[2][im] ;
W[i][im] = A[i][0][re]*V[0][im]+A[i][0][im]*V[0][re]+
A[i][1][re]*V[1][im]+A[i][1][im]*V[1][re]+
A[i][2][re]*V[2][im]+A[i][2][im]*V[2][re] ;
}
}
double fRand(double fMin, double fMax)
{
double f = (double)std::rand() / RAND_MAX;
return fMin + f * (fMax - fMin);
}
int main()
{
std::srand(std::time(0));
double A[3][3][2];
double B[3][3][2];
double C[3][3][2];
double V[3][2];
double W[3][2];
// Generate some random numbers
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
for(int k=0; k<2; k++)
{
A[i][j][k] = fRand(0,1000);
B[i][j][k] = fRand(0,1000);
C[i][j][k] = 0.0;
}
}
}
for(int i=0; i<3; i++)
{
for(int j=0; j<2; j++)
{
V[i][j] = fRand(0,1000);
}
}
////////////// Calculate with mosc3
clock_t begin = clock();
// MxM
for(int i=0; i<rounds; i++)
{
multiply_complex_matrix(A,B,C);
}
clock_t end = clock();
double elapsed_mosc3_mm = double(end-begin)/CLOCKS_PER_SEC;
begin = clock();
// MxV
for(int i=0; i<rounds; i++)
{
multiply_complex_matvec(A, V, W);
}
end = clock();
double elapsed_mosc3_mv = double(end-begin)/CLOCKS_PER_SEC;
////////////// Calculate with OpenBlas
double alpha[2];
alpha[0] = 1.0;
alpha[1] = 0.0;
double beta[2];
beta[0] = 0.0;
beta[1] = 0.0;
begin = clock();
// MxM
for(int i=0; i<rounds; i++)
{
// Reference: http://www.netlib.org/lapack/explore-html/dc/d17/group__complex16__blas__level3.html#ga4ef748ade85e685b8b2241a7c56dd21c
// ZGEMM performs
// C := alpha*op(A)*op(B)+beta*C
// where op(X) is either X or transpose of X etc.
// alpha and beta are scalars.
// The first three '3' in the argument are the number of:
// rows of A2 and C2,
// columns of B2 and columns of C2,
// columns of A2 and rows of B2
// The '1' declare the first dimension of each matrix as declared in the calling program.
cblas_zgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, A_R, B_C, B_R, alpha, **A, A_C, **B, B_C, beta, **C, B_C);
}
end = clock();
double elapsed_openBlas_mm = double(end-begin)/CLOCKS_PER_SEC;
begin = clock();
// MxV
int stepSize = 1;
for(int i=0; i<rounds; i++)
{
// Reference: http://www.netlib.org/lapack/explore-html/dc/dc1/group__complex16__blas__level2.html#gafaeb2abd9fffa7442b938dc384aeaf47
cblas_zgemv(CblasRowMajor, CblasNoTrans, A_R, A_C, alpha, **A, A_C, *V, stepSize, beta, *W, stepSize);
}
end = clock();
double elapsed_openBlas_mv = double(end-begin)/CLOCKS_PER_SEC;
std::cout << "Evaluated CPU time with Mosc3 (MxM): " << elapsed_mosc3_mm << std::endl;
std::cout << "Evaluated CPU time with OpenBLAS (MxM): " << elapsed_openBlas_mm << std::endl;
std::cout << "Evaluated CPU time with Mosc3 (MxV): " << elapsed_mosc3_mv << std::endl;
std::cout << "Evaluated CPU time with OpenBLAS (MxV): " << elapsed_openBlas_mv << std::endl;
}