POOMA: A C++ Toolkit for High-Performance Parallel Scientific Computing | ||
---|---|---|
Prev | Chapter 3. A Tutorial Introduction | Next |
Before implementing Doof2d using the POOMA Toolkit, we present a hand-coded implementation of Doof2d. See Example 3-1. After querying the user for the number of averagings, the arrays' memory is allocated. Since the arrays' size is not known at compile time, the arrays are accessed via pointers to allocated dynamic memory. This memory is deallocated at the program's end to avoid memory leaks. The arrays are initialized with initial conditions. For the b array, all values except the central ones have nonzero values. Only the outermost values of the a array need be initialized to zero, but we instead initialize them all using the same loop initializing b.
The simulation's kernel consists of triply nested loops. The outermost loop controls the number of iterations. The two inner nested loops iterate through the arrays' elements, excepting the outermost elements; note the loop indices range from 1 to n-2 while the array indices range from 0 to n-1. Each a value is assigned the average of its corresponding value in b and the latter's neighbors. Values in the two-dimensional grids are accessed using two sets of brackets, e.g., a[i][j]. After assigning values to a, a second averaging reads values in a, writing values in b.
After the kernel finishes, the final central value is printed. If the desired number of averagings is even, the value in b is printed; otherwise, the value in a is used. Finally, the dynamically-allocated memory must be freed to avoid memory leaks.
Example 3-1. Hand-Coded Implementation of Doof2d
#include <iostream> // has std::cout, ... #include <stdlib.h> // has EXIT_SUCCESS // Doof2d: C-like, element-wise implementation int main() { // Ask the user for the number of averagings.long nuAveragings, nuIterations; std::cout < < "Please enter the number of averagings: "; std::cin > > nuAveragings; nuIterations = (nuAveragings+1)/2; // Each iteration performs two averagings. // Use two-dimensional grids of values.
double **a; double **b; // Ask the user for the number n of values along one // dimension of the grid.
long n; std::cout < < "Please enter the array size: "; std::cin > > n; // Allocate the arrays.
typedef double* doublePtr; a = new doublePtr[n]; b = new doublePtr[n]; for (int i = 0; i < n; i++) { a[i] = new double[n]; b[i] = new double[n]; } // Set up the initial conditions. // All grid values should be zero except for the // central value.
for (int j = 0; j < n; j++) for (int i = 0; i < n; i++) a[i][j] = b[i][j] = 0.0; b[n/2][n/2] = 1000.0; // Average using this weight.
const double weight = 1.0/9.0; // Perform the simulation. for (int k = 0; k < nuIterations; ++k) { // Read from b. Write to a.
for (int j = 1; j < n-1; j++) for (int i = 1; i < n-1; i++) a[i][j] = weight * (b[i+1][j+1] + b[i+1][j ] + b[i+1][j-1] + b[i ][j+1] + b[i ][j ] + b[i ][j-1] + b[i-1][j+1] + b[i-1][j ] + b[i-1][j-1]); // Read from a. Write to b.
for (int j = 1; j < n-1; j++) for (int i = 1; i < n-1; i++) b[i][j] = weight * (a[i+1][j+1] + a[i+1][j ] + a[i+1][j-1] + a[i ][j+1] + a[i ][j ] + a[i ][j-1] + a[i-1][j+1] + a[i-1][j ] + a[i-1][j-1]); } // Print out the final central value.
std::cout < < (nuAveragings % 2 ? a[n/2][n/2] : b[n/2][n/2]) < < std::endl; // Deallocate the arrays.
for (int i = 0; i < n; i++) { delete [] a[i]; delete [] b[i]; } delete [] a; delete [] b; return EXIT_SUCCESS; }
To compile the executable, change directories to the POOMA examples/Manual/Doof2d directory. Ensure the POOMASUITE environment variable specifies the desired suite name suiteName, as we did when compiling POOMA in Section 3.1. Issuing the make Doof2d-C-element command creates the executable suiteName/Doof2d-C-element.
When running the executable, specify the desired nonnegative number of averagings and the nonnegative number of grid cells along any dimension. The resulting grid has the same number of cells along each dimension. After the executable finishes, the resulting value of the central element is printed.