Reputation: 9
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <omp.h>
#include <algorithm>
/**
* Pipeline-parallel implementation of Gauss-Seidel method
* Maintains original function signature while implementing wavefront parallelism
*/
void my_seidel(int n, int T, double *A)
{
// Determine number of threads available
int num_threads = omp_get_max_threads();
omp_set_num_threads(num_threads);
for (int t = 0; t < T; t++) {
// Number of diagonals in an (n-2)x(n-2) interior grid is 2*(n-2)-1
const int num_diagonals = 2 * (n - 2) - 1;
// Process diagonals in sequence
for (int d = 0; d < num_diagonals; d++) {
// Determine start and end points for this diagonal
int start_i = std::max(1, d - (n - 3));
int end_i = std::min(n - 2, d + 1);
// Process cells along this diagonal in parallel
#pragma omp parallel for schedule(dynamic)
for (int i = start_i; i <= end_i; i++) {
int j = d - (i - 1) + 1;
if (j >= 1 && j < n - 1) {
// Use the most up-to-date values (already computed in this iteration)
A[i * n + j] = (A[(i - 1) * n + j - 1] + A[(i - 1) * n + j] + A[(i - 1) * n + j + 1]
+ A[i * n + j - 1] + A[i * n + j] + A[i * n + j + 1]
+ A[(i + 1) * n + j - 1] + A[(i + 1) * n + j] + A[(i + 1) * n + j + 1])
/ 9.0;
}
}
// Implicit barrier at the end of parallel region ensures all
// updates in this diagonal are complete before proceeding
}
}
}
I found that once I used OMP to parallelize the process, the calculation went wrong. I have tried a lot of things to avoid the error but they didn't work. Could anyone give some suggestions to optimize the code without losing accuracy?
Upvotes: 0
Views: 82