File: acou3d.cpp

package info (click to toggle)
blitz%2B%2B 1%3A0.10-3.2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 13,276 kB
  • ctags: 12,037
  • sloc: cpp: 70,465; sh: 11,116; fortran: 1,510; python: 1,246; f90: 852; makefile: 701
file content (211 lines) | stat: -rw-r--r-- 5,988 bytes parent folder | download | duplicates (2)
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#define BZ_DISABLE_RESTRICT

#include <blitz/array.h>
#include <blitz/traversal.h>
#include <blitz/timer.h>

#ifdef BZ_HAVE_STD
  #include <fstream>
#else
  #include <fstream.h>
#endif

BZ_USING_NAMESPACE(blitz)

#if defined(BZ_FORTRAN_SYMBOLS_WITH_TRAILING_UNDERSCORES)
 #define acoustic3d_f90 acoustic3d_f90_
 #define acoustic3d_f77 acoustic3d_f77_
 #define acoustic3d_f90tuned acoustic3d_f90tuned_
 #define acoustic3d_f77tuned acoustic3d_f77tuned_
#elif defined(BZ_FORTRAN_SYMBOLS_WITH_DOUBLE_TRAILING_UNDERSCORES)
 #define acoustic3d_f90 acoustic3d_f90__
 #define acoustic3d_f77 acoustic3d_f77__
 #define acoustic3d_f90tuned acoustic3d_f90tuned__
 #define acoustic3d_f77tuned acoustic3d_f77tuned__
#elif defined(BZ_FORTRAN_SYMBOLS_CAPS)
 #define acoustic3d_f90       ACOUSTIC3D_F90
 #define acoustic3d_f77       ACOUSTIC3D_F77
 #define acoustic3d_f90tuned  ACOUSTIC3D_F90TUNED
 #define acoustic3d_f77tuned  ACOUSTIC3D_F77TUNED
#endif

extern "C" {
void acoustic3d_f90(int& N, int& niters, float& check);
void acoustic3d_f77(int& N, int& niters, float& check);
void acoustic3d_f90tuned(int& N, int& niters, float& check);
void acoustic3d_f77tuned(int& N, int& niters, float& check);
}

float acoustic3D_BlitzRaw(int N, int niters);
float acoustic3D_BlitzInterlacedCycled(int N, int niters);
float acoustic3D_BlitzCycled(int N, int niters);
float acoustic3D_BlitzStencil(int N, int niters);


void output_data(const char* type, const Timer& t, float check, double Gflops)
{
  cout << type << ": " << t.elapsed() 
	 << t.indep_var() << "  check = " 
         << check << " Gflop/" << t.indep_var() << " = " 
	 << (Gflops/t.elapsed())
         << endl << endl;
}

int main()
{
    Timer timer;
    int N = 112;
    int niters = 210;    // Must be divisible by 3 for tuned Fortran versions
    float check;

		cout << "Acoustic 3D Benchmark" << endl << endl;

		double Gflops = (N-2)*(N-2)*(N-2) * 11.0 * niters / 1.0e+9;

    generateFastTraversalOrder(TinyVector<int,2>(N-2,N-2));

    timer.start();
    check = acoustic3D_BlitzRaw(N, niters);
    timer.stop();
    output_data("Blitz++ (raw)", timer, check, Gflops);

    timer.start();
    check = acoustic3D_BlitzStencil(N, niters);
    timer.stop();
    output_data("Blitz++ (stencil)", timer, check, Gflops);

#if 0
    timer.start();
    check = acoustic3D_BlitzInterlaced(N, niters, c);
    timer.stop();
    output_data("Blitz++ (interlaced)", timer, check, Gflops);
#endif

    timer.start();
    check = acoustic3D_BlitzCycled(N, niters);
    timer.stop();
    output_data("Blitz++ (cycled)", timer, check, Gflops);
 
    timer.start();
    check = acoustic3D_BlitzInterlacedCycled(N, niters);
    timer.stop();
    output_data("Blitz++ (interlaced & cycled)", timer, check, Gflops);

#ifdef FORTRAN_90
    timer.start();
    acoustic3d_f90(N, niters, check);
    timer.stop();
    output_data("Fortran 90", timer, check, Gflops);

    timer.start();
    acoustic3d_f90tuned(N, niters, check);
    timer.stop();
    output_data("Fortran 90 (tuned)", timer, check, Gflops);
#endif

    timer.start(); 
    acoustic3d_f77(N, niters, check);
    timer.stop(); 
    output_data("Fortran 77", timer, check, Gflops);

    timer.start();
    acoustic3d_f77tuned(N, niters, check);
    timer.stop();
    output_data("Fortran 77 (tuned)", timer, check, Gflops);

    return 0;
}

void setupInitialConditions(Array<float,3>& P1, Array<float,3>& P2,
    Array<float,3>& P3, Array<float,3>& c, int N);

void snapshot(const Array<float,3>& P, const Array<float,3>& c);

void checkArray(const Array<float,3>& A, int N);

void setupInitialConditions(Array<float,3>& P1, Array<float,3>& P2,
    Array<float,3>& P3, Array<float,3>& c, int N)
{
    // Set the velocity field
    c(Range(0,N/2-1), Range::all(), Range::all()) = 0.05;
    c(Range(N/2,N-1), Range::all(), Range::all()) = 0.3;

    double Nfp = static_cast<double>(N);
    int cavityLeft = static_cast<int>(3*Nfp/7-1);
    int cavityRight = static_cast<int>(4*Nfp/7-1);
    int cavityFront = static_cast<int>(3*Nfp/7-1);
    int cavityBack = static_cast<int>(4*Nfp/7-1);
    int cavityTop = static_cast<int>(5*Nfp/7-1);
    int cavityBottom = static_cast<int>(6*Nfp/7-1);

    c(Range(cavityTop,cavityBottom),Range(cavityLeft,cavityRight), 
        Range(cavityFront,cavityBack)) = 0.02;

    int cavityTop2 = static_cast<int>(1*Nfp/7-1);
    int cavityBottom2 = static_cast<int>(2*Nfp/7-1);
    c(Range(cavityTop2,cavityBottom2),Range(cavityLeft,cavityRight),
        Range(cavityFront,cavityBack)) = 0.001;

    // Initial pressure distribution
    BZ_USING_NAMESPACE(blitz::tensor);
      
    float NN = N;
    float ci = N/2-1;
    float cj = N/2-1;
    float ck = N/2-1;
    // pow2 is an ET-only function, it's not defined for POD types
    float s2 = 64.0 * 9.0 / pow(NN/2.0, 2);
    P1 = 0.0;
    P2 = exp(-(pow2(i-ci)+pow2(j-cj)+pow2(k-ck)) * s2);
    P3 = 0.0;

    checkArray(P2, N);
    checkArray(c, N);
}

void checkArray(const Array<float,3>& A, int N)
{
    double check = 0.0;

    for (int i=0; i < N; ++i)
      for (int j=0; j < N; ++j)
        for (int k=0; k < N; ++k)
          check += A(i,j,k) * ((i+1)+N*(j+1)+N*N*(k+1));

    cout << "Array check: " << check << endl;
}

void snapshot(const Array<float,3>& P, const Array<float,3>& c)
{
    static int count = 0, snapshotNum = 0;
    if (++count < 5)
        return;

    count = 0;
    ++snapshotNum;
    char filename[128];
    sprintf(filename, "snapshot%03d.m", snapshotNum);

    ofstream ofs(filename);
    int N = P.length(firstDim);

    int k = N/2;
    float Pmin = -0.2;
    float PScale = 1.0/0.4;
    float VScale = 0.5;

    ofs << "P" << snapshotNum << " = [ ";
    for (int i=0; i < N; ++i)
    {
        for (int j=0; j < N; ++j)
        {
            float value = (P(i,j,k)-Pmin)*PScale + c(i,j,k)*VScale;
            int r = static_cast<int>(value * 4096);
            ofs << r << " ";
        }
        if (i < N-1)
            ofs << ";" << endl;
    }
    ofs << "];" << endl;
}