solving 2d heat equation using mpi - c++

Basically, I am trying to solve the 2d heat equation using OpenMPI.
We start off with a matrix(which represents the heat distribution of a 2-dimensional object) with the heat at the bottom(i.e, all the bottom values are 100), time passes and all the heat flows from the hotter surface to the colder surface and we are simulating this through each iteration.
We start off
int max_iterations = 15000;
double epsilon = 1.0e-3;
int N = 20;
int M = 20;
// Initialize MPI
MPI_Init(&argc, &argv);
int pid, np;
MPI_Comm_rank(MPI_COMM_WORLD, &pid);
MPI_Comm_size(MPI_COMM_WORLD, &np);
// Calculate the number of rows per process
int rows_per_process = M / np;
rows_per_process += 2; // boundary rows
then we declare and initialize the local matrix by dividing the main matrix horizontally in to np parts where np is number of processes
Matrix U(rows_per_process, N);
Matrix W(rows_per_process, N);
// Init & Boundary
for (i = 0; i < rows_per_process; ++i) {
for (j = 0; j < N; ++j) {
U(i, j) = 0.0;
}
}
for (j = 0; j < N; ++j) {
U(rows_per_process - 1, j) = 100.0;
}
after that, we distribute the boundaries of local matrices to the other processes (this is the part, I think doesn't work as expected)
// Check if this is not process 0
if (pid != 0) {
MPI_Send(&U(1, 0), N, MPI_DOUBLE, pid - 1, 0, MPI_COMM_WORLD);
MPI_Recv(&U(0, 0), N, MPI_DOUBLE, pid - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
// Check if this is not the last process
if (pid != np - 1) {
MPI_Send(&U(rows_per_process-2, 0), N, MPI_DOUBLE, pid + 1, 0, MPI_COMM_WORLD);
MPI_Recv(&U(rows_per_process-1, 0), N, MPI_DOUBLE, pid + 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
after this main loop begins
iteration_count = 0;
do
{
iteration_count++;
diffnorm = 0.0;
for (i = 1; i < rows_per_process - 1; ++i)
{
for (j = 1; j < N - 1; ++j)
{
W(i, j) = (U(i, j + 1) + U(i, j - 1) + U(i + 1, j) + U(i - 1, j)) * 0.25;
diffnorm += (W(i, j) - U(i, j)) * (W(i, j) - U(i, j));
}
}
for (i = 1; i < rows_per_process - 1; ++i)
for (j = 1; j < N - 1; ++j)
U(i, j) = W(i, j);
// Check if this is not process 0
if (pid != 0) {
MPI_Send(&U(1, 0), N, MPI_DOUBLE, pid - 1, 0, MPI_COMM_WORLD);
MPI_Recv(&U(0, 0), N, MPI_DOUBLE, pid - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
// Check if this is not the last process
if (pid != np - 1) {
MPI_Send(&U(rows_per_process-2, 0), N, MPI_DOUBLE, pid + 1, 0, MPI_COMM_WORLD);
MPI_Recv(&U(rows_per_process-1, 0), N, MPI_DOUBLE, pid + 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
diffnorm = sqrt(diffnorm);
MPI_Allreduce(&diffnorm, &diffnorm, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
} while (epsilon <= diffnorm && iteration_count < max_iterations);
after this we gather the processed data from the children (this part is also in doubt)
Matrix U_MPI(M, N);
int nElm = N*(rows_per_process -2), nth = (pid*(rows_per_process - 2));
MPI_Gather(&U(1, 0), nElm, MPI_DOUBLE,
&U_MPI(nth, 0), nElm, MPI_DOUBLE, 0, MPI_COMM_WORLD);
OUTPUT
0 0.93421 1.67984 2.09131 2.09131 1.67984 0.93421 0
0 2.05719 3.69419 4.59451 4.59451 3.69419 2.05719 0
0 3.60071 6.44586 7.99882 7.99882 6.44586 3.60071 0
0 5.90026 10.4906 12.9572 12.9572 10.4906 5.90026 0
0 9.51028 16.6601 20.3833 20.3833 16.6601 9.51028 0
0 15.4813 26.2571 31.5339 31.5339 26.2571 15.4813 0
0 26.1585 41.3538 47.9623 47.9623 41.3538 26.1585 0
Expected output
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 2.285033 4.078976 5.051108 5.051108 4.078976 2.285033 0.000000
0.000000 5.061334 8.980086 11.074751 11.074751 8.980086 5.061334 0.000000
0.000000 8.980539 15.705866 19.193785 19.193785 15.705866 8.980539 0.000000
0.000000 15.155358 25.669779 30.801644 30.801644 25.669779 15.155358 0.000000
0.000000 25.971518 41.016975 47.542273 47.542273 41.016975 25.971518 0.000000
0.000000 47.714062 64.884910 70.808927 70.808927 64.884910 47.714062 0.000000
100.000000 100.000000 100.000000 100.000000 100.000000 100.000000 100.000000 100.000000
Matrix
struct Mat {
int height;
int width;
std::vector<double> data;
Mat();
Mat(int height, int width)
: height(height), width(width), data(height*width)
{ }
double& operator()(int h, int w) {
int id = h*width + w;
if(id >= (height * width)) {
throw std::runtime_error("Invalid acess");
}
return data[h*width + w];
}
};

This code:
for (j = 0; j < N; ++j) {
U(rows_per_process - 1, j) = 100.0;
}
Appears to be initializing the boundary condition into the lowest ghost-zone row on each process, not the lowest row of the domain. Is that what you intended?
Also here:
int nElm = N*(rows_per_process -2), nth = (pid*(rows_per_process - 2));
MPI_Gather(&U(1, 0), nElm, MPI_DOUBLE,
&U_MPI(nth, 0), nElm, MPI_DOUBLE, 0, MPI_COMM_WORLD);
The &U_MPI(nth, 0) expression looks like an out-of-bounds access.
There may be other problems...

Related

How to generate an array in each process and in these processes find the minimum value of its generated part

I need generate an array in each process and in these processes find the minimum value of its generated part.I do not understand how to divide the generation into parts and find the minimum value in these parts.
int rank, num_procs;
double result;
int length = 10e6;
double *arr = new double[length];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int load = length / num_procs;
auto min = DBL_MAX, max = DBL_MIN;
for (int i = rank * load; i < (rank + 1) * load; ++i) {
arr[i] = (pow(2 * i, 1 / 3) + 6) / abs(i * cos(i));
if (arr[i] > max) {
max = arr[i];
}
if (arr[i] < min) {
min = arr[i];
}
}
result = min * max;
cout << result << endl;
MPI_Send(&result, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
if (rank == 0) {
MPI_Recv(&result, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
result *= result;
cout << result << endl;
}
One naive way to do is divide your load (perform the number generation) equally. Say (load=length/num_procs). So each process will generate load numbers. Basically rank 0 will generates values from i=0 to i=load, while rank 1 will generate values from i=load to i=2*load and so on. Basically, each rank will loop from i=rank*load to i=(rank+1)*load. Assumption: length/num_procs is divisible. Otherwise you have to distribute the remaining load.
load=length / num_procs;
for (int i = rank*load; i < (rank+1)*load; ++i) {
arr[i] = (pow(2 * i, 1/3) + 6) / abs(i * cos(i));
}

Problem with MPI_Gather Couldnt gather 8 arrays of 32 element into a big array of 256 elements

i am new to MPI , i have an array of 256 integer , i want to divide each number by 16 , I suggested to Scatter 32 element on each Processor but i couldn't gather them as each Return value contains array of 32
int globalhistogram[256];
float globalProb[256];
float* localprob = new float[32];
int localpixel[32];
MPI_Scatter(&globalhistogram, 32, MPI_INT, localpixel, 32, MPI_INT, 0, MPI_COMM_WORLD);
for (int i = 0; i < 32; i++)
{
localprob[i] = (float)localpixel[i] / 16;
}
MPI_Gather(localprob, 32, MPI_FLOAT, &globalprob, 32, MPI_FLOAT, 0, MPI_COMM_WORLD);
I don't understand the issue - the code appears to run correctly after I correct what I assume is a typo float globalProb[256] -> float globalprob[256].
I agree with #victor-eijkhout about the &globalprob issue but it doesn't appear to make a difference.
If I compile and run the appended code I get the expected answer:
dsh#laptop$ mpicxx -o play play.cpp
dsh#laptop$ mpirun -n 8 ./play
rank 0: globalprob[0] = 0.000000
...
rank 0: globalprob[31] = 31.000000
rank 0: globalprob[32] = 64.000000
...
rank 0: globalprob[255] = 2040.000000
Here's the full code:
#include <stdio.h>
#include <mpi.h>
int main(void)
{
int rank, size, i;
MPI_Init(NULL, NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int globalhistogram[256];
float globalprob[256];
float* localprob = new float[32];
int localpixel[32];
for (i=0; i < 256; i++)
{
globalhistogram[i] = i;
}
MPI_Scatter(&globalhistogram, 32, MPI_INT, localpixel, 32, MPI_INT, 0, MPI_COMM_WORLD);
for (int i = 0; i < 32; i++)
{
localprob[i] = (float)localpixel[i] *(rank+1);
}
MPI_Gather(localprob, 32, MPI_FLOAT, &globalprob, 32, MPI_FLOAT, 0, MPI_COMM_WORLD);
if (rank == 0)
{
for (i=0; i < 256; i++)
{
printf("rank %d: globalprob[%d] = %f\n", rank, i, globalprob[i]);
}
}
MPI_Finalize();
}

MPI convert matrix to upper triangular form in C++ doesn't work

I'm new to MPI; so forgive me if my code is clumsy. I want to convert a n*n matrix to upper triangular form and then calculate its determinant. My code works with one processor, but with more than one processor, it doesn't work. I am hoping someone can give me some advice about it.
My code:
#include <stdio.h>
#include <string.h> /* For strlen */
#include <mpi.h> /* For MPI functions, etc */
#include<stdlib.h> /* for rand */
#include<math.h>
#define n 10
#define N 100
int main(void)
{
srand(0);
double A[N];
double temp[N];
int i;
int j;
int k;
int m=100;
int s=1;
int y;
double z;
double det=1;
int pid;
int np;
int share=0;
for (i = 0; i < N; i++)
{
A[i] = rand();
}
MPI_Init(NULL, NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &pid);
MPI_Comm_size(MPI_COMM_WORLD, &np);
if (np == 1)
{
for (i = 0; i < n; i++)
{
if (A[i * n + i] == 0)
{
s = 0;
for (j = i + 1; j < n; j++)
{
if (A[j * n + i] != 0)
{
for (k = i; k < n; k++)
{
A[i * n + k] = A[i * n + k] + A[j * n + k];
}
s = 1;
}
if (s == 1)
break;
}
}
if (s != 1)
{
det = 0;
break;
}
z = A[i * n + i];
det = det * z;
for (k = i; k < n; k++)
{
A[i * n + k] = A[i * n + k] / z;
}
for (j = i + 1; j < n; j++)
{
z = A[j * n + i];
for (k = i; k < n; k++)
{
A[j * n + k] = A[j * n + k] - z * A[i * n + k];
}
}
}
for (i = 0; i < N; i++)
{
printf("element %d of matrix is %G \n", i, A[i]);
}
printf("det is %G", det);
}
else
{
for (i = 0; i < n ; i++)
{
if (A[i * n + i] == 0)
{
s = 0;
for (j = i + 1; j < n; j++)
{
if (A[j * n + i] != 0)
{
for (k = i; k < n; k++)
{
A[i * n + k] = A[i * n + k] + A[j * n + k];
}
s = 1;
}
if (s == 1)
break;
}
}
if (s != 1)
{
det = 0;
break;
}
z = A[i * n + i];
det = det * z;
for (k = i; k < n; k++)
{
A[i * n + k] = A[i * n + k] / z;
}
m = n - i;
if (m > 1)
{
if (np >= m)
{
if (pid == 0)
{
for (k = 1; k < m; k++)
{
MPI_Send(&m, 1, MPI_INT, k, 0, MPI_COMM_WORLD);
MPI_Send(&A[(k + i) * n + i], m, MPI_DOUBLE, k, 0, MPI_COMM_WORLD);
}
for (k = 1; k < m; k++)
{
MPI_Recv(&temp[0], m + 1, MPI_DOUBLE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
for (j = 0; j < m; j++)
{
A[(int(temp[m]) + i) * n + i + j] = temp[j];
}
}
printf("det is %G", det);
}
else
{
double local_A[N];
double local_z;
int local_m;
MPI_Recv(&local_m, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
MPI_Recv(&local_A[0], local_m, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
local_z = local_A[0];
for (k = 0; k < m; k++)
{
local_A[k] = local_A[k] - (local_z * A[(i * n) + i + k]);
}
local_A[k + 1] = pid;
MPI_Send(&local_A[0], local_m + 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
}
}
if (np < m)
{
if (m % np == 0)
{
if (pid == 0)
{
share = m / np;
for (k = 1; k < np; k++)
{
MPI_Send(&m, 1, MPI_INT, k, 0, MPI_COMM_WORLD);
MPI_Send(&share, 1, MPI_INT, k, 0, MPI_COMM_WORLD);
MPI_Send(&A[share * k * n], share * n, MPI_DOUBLE, k, 0, MPI_COMM_WORLD);
}
for (k = 1; k < share; k++)
{
z = A[(k + i) * n + i];
for (j = 0; j < m; j++)
{
A[(k + i) * n + i + j] = A[(k + i) * n + i + j] - z;
}
}
for (k = 1; k < np; k++)
{
MPI_Recv(&temp[0], share * m + 1, MPI_DOUBLE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
for (j = 0; j < share * m; j++)
{
A[(int(temp[share * m]) + i) * n * share + i + j] = temp[j];
}
}
printf("det is %G", det);
}
else
{
double local_A[N];
double local_z;
int local_share;
int local_m;
MPI_Recv(&local_m, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
MPI_Recv(&local_share, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
MPI_Recv(&local_A[0], local_share * n, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
for (k = 0; k < local_share; k++)
{
local_z = local_A[(k + i) * n + i];
for (j = 0; j < n; j++)
{
local_A[k * n + j] = local_A[(k + i) * n + i + j] - local_z;
}
}
local_A[local_share * local_m] = pid;
MPI_Send(&local_A[0], share * local_m + 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
}
}
if (m % np != 0)
{
if (pid == 0)
{
share = m / np;
for (k = 1; k < np; k++)
{
MPI_Send(&m, 1, MPI_INT, k, 0, MPI_COMM_WORLD);
MPI_Send(&share, 1, MPI_INT, k, 0, MPI_COMM_WORLD);
MPI_Send(&A[share * k * n], share * n, MPI_DOUBLE, k, 0, MPI_COMM_WORLD);
}
for (k = 1; k < share; k++)
{
z = A[(k + i) * n + i];
for (j = 0; j < m; j++)
{
A[(k + i) * n + i + j] = A[(k + i) * n + i + j] - z;
}
}
for (k = 1; k < np; k++)
{
MPI_Recv(&temp[0], share * m + 1, MPI_DOUBLE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
for (j = 0; j < share * m; j++)
{
A[(int(temp[share * m]) + i) * n * share + i + j] = temp[j];
}
}
for (k = 1; k < (m % np) + 1; k++)
{
y = (share * np) + k;
MPI_Send(&y, 1, MPI_INT, k, 0, MPI_COMM_WORLD);
MPI_Send(&A[(share * np + i + k) * n + i], m, MPI_DOUBLE, k, 0, MPI_COMM_WORLD);
}
for (k = 1; k < m; k++)
{
MPI_Recv(&temp[0], m + 1, MPI_DOUBLE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
for (j = 0; j < n; j++)
{
A[int(temp[n]) * n + i + j] = temp[j];
}
}
printf("det is %G", det);
}
else
{
double local_A[N];
double local_z;
double local_y;
int local_share;
int local_m;
MPI_Recv(&local_m, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
MPI_Recv(&local_share, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
MPI_Recv(&local_A[0], local_share * n, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
for (k = 0; k < local_share; k++)
{
local_z = local_A[(k + i) * n + i];
for (j = 0; j < n; j++)
{
local_A[k * n + j] = local_A[(k + i) * n + i + j] - local_z;
}
}
local_A[local_share * local_m] = pid;
MPI_Send(&local_A[0], local_share * local_m + 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
MPI_Recv(&local_y, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
MPI_Recv(&local_A[0], m, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
local_z = local_A[0];
for (j = 0; j < local_m; j++)
{
local_A[j] = local_A[j] - local_z;
}
local_A[j + 1] = local_y;
MPI_Send(&local_A[0], m + 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
}
}
}
}
}
}
MPI_Finalize();
}
Even with two or treee processor my code doesn't work, and I don't know why it doesn't work.

Matrix-Vector Multiplication on MPI - ERROR Compiled code

I need assistance to resolve an error in the following code:
#include <iostream>
#include <mpi.h>
using namespace std;
//matrix in two dimension in memory!!
int main(int argc, char** argv)
{
const int WIDTH = 100;
const int HEIGHT = 100;
int id, P;
double tempValue = 0;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &P);
MPI_Comm_rank(MPI_COMM_WORLD, &id);
double A[WIDTH][HEIGHT];
double x[HEIGHT], b[WIDTH];
int upperBound, lowerBound = 0;
// Master controls worksharing..
if (id == 0)
{
// Init A & x
for (int i = 0; i < WIDTH; i++)
for (int j = 0; j < HEIGHT; j++)
A[i][j] = 1;
for (int j = 0; j < HEIGHT; j++)
x[j] = 2;
// Send to each node its portion of A to be processed
int portionSize = WIDTH / P;
for (int i = 0; i < P; i++)
{
lowerBound = i * portionSize;
upperBound = (i + 1) * portionSize;
// let the last node process the remainder
if (i == (P - 1))
upperBound += (HEIGHT - portionSize * P);
if (i > 0)// Do not send to master node!!
{
// Send to node i the lower & upper bounds the A portion
//and complete vector x
MPI_Send(&lowerBound, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
MPI_Send(&upperBound, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
MPI_Send(&A[lowerBound][0], (upperBound - lowerBound) * HEIGHT,
MPI_DOUBLE, i, 0, MPI_COMM_WORLD);
MPI_Send(&x[0], HEIGHT, MPI_DOUBLE, i, 0, MPI_COMM_WORLD);
}
}
// master perform part of the job...
for (int i = 0; i < portionSize; i++)
{
tempValue = 0;
for (int j = 0; j < HEIGHT; j++)
tempValue += A[i][j] * x[j];
b[i] = tempValue;
}
//Get the results in order, each node would send their boundaries and data part
for (int i = 1; i < P; i++)
{
MPI_Recv(&lowerBound, 1, MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
MPI_Recv(&upperBound, 1, MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
MPI_Recv(&P[lowerBound], (upperBound - lowerBound), MPI_DOUBLE, i, 0,
MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
}
// Print the first 2 values to check..
cout << "b[0]=" << b[0] << " b[Width-1]=" << b[WIDTH - 1] << endl;
}
else // the rest of the workers do their parts
{
//Receive the inputs
MPI_Recv(&lowerBound, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
MPI_Recv(&upperBound, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
MPI_Recv(&A[lowerBound][0], (upperBound - lowerBound) * WIDTH, MPI_DOUBLE, 0, 0,
MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
MPI_Recv(&x, HEIGHT, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
cout << "Node:" << id << " Received from:" << lowerBound << " to " << upperBound - 1
<< endl;
double* result = new double[upperBound - lowerBound];
//Do the job
for (int i = lowerBound, resultCounter = 0; i < upperBound; i++, resultCounter++)
{
tempValue = 0;
for (int j = 0; j < HEIGHT; j++)
tempValue += A[i][j] * x[j];
result[resultCounter] = tempValue;
}
//send the results
MPI_Send(&lowerBound, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
MPI_Send(&upperBound, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
MPI_Send(&result[0], upperBound - lowerBound, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
delete[] result;
}
MPI_Finalize();
return 0;
}
When I compile the code in Microsoft Visual Studio 2019, I get this error message:
Error (active) E0142 expression must have pointer-to-object type ConsoleApplication9 C:\Users\m_swe\Desktop\Assignments\Assignments\PrjP2P\MatMPI\MatMPI\Source.cpp 59
Error C2109 subscript requires array or pointer type ConsoleApplication9 C:\Users\m_swe\Desktop\Assignments\Assignments\PrjP2P\MatMPI\MatMPI\Source.cpp 59
I think the problem is on line: 59
MPI_Recv(&P[lowerBound], (upperBound - lowerBound), MPI_DOUBLE, i, 0,
MPI_Recv takes in a pointer to a buffer (the first argument) where you are going to receive and store the incoming data. In this case it could be in some variable which you can define inside the for loop, as:
int receivedValues[ WIDTH * HEIGHT ];
for (int i = 1; i < P; i++)
{
MPI_Recv(&lowerBound, 1, MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
MPI_Recv(&upperBound, 1, MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
MPI_Recv(&receivedValues[0], (upperBound - lowerBound), MPI_DOUBLE, i, 0,
MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
// do your computation here with receivedValues
}
}

MPI Send and Receive Multiple Times

I am trying to do some MPI parallel work. I am able to run this on any number of processors. The issue is that each processor will take one job, execute it and send it back then the program is done. I want to be able to send a processor another job when it has finished. Im not sure how to implement this. Basically I am trying to send each core 10 jobs.
if (myRank == 0) {
int numCores = MPI::COMM_WORLD.Get_size();
for (int rank = 1; rank < numCores; rank++) {
MPI::COMM_WORLD.Send(&yarray[0], imax, MPI::DOUBLE, rank, 0);
MPI::COMM_WORLD.Send(&tarray[0], imax, MPI::DOUBLE, rank, 0);
MPI::COMM_WORLD.Recv(&ans, imax, MPI::DOUBLE, MPI::ANY_SOURCE, MPI_ANY_TAG, mystatus);
answers[counter] = ans;
counter++;
}
}
else
{
MPI::COMM_WORLD.Recv(&yarray1, imax, MPI::DOUBLE, MPI::ANY_SOURCE, MPI_ANY_TAG, mystatus);
MPI::COMM_WORLD.Recv(&tarray1, imax, MPI::DOUBLE, MPI::ANY_SOURCE, MPI_ANY_TAG, mystatus);
double floor = 0.5, ceiling = 3.5, range = (ceiling - floor);
double rnd = floor + double((range * rand()) / (RAND_MAX + 1.0));
yarray [0] = rnd;
yarray1 [0] = rnd;
double temp = 0;
for (int k = 0; k < imax; k++) {
tarray1[k+1] = tarray1[k] + h;
yarray1[k+1] = yarray1[k] + h * (2 * yarray1[k] - 2 * tarray1[k] * tarray1[k] - 3);
}
temp = yarray1[int(imax)];
//cout << "Rank = " << myRank << " Solution = " << temp << endl;
MPI::COMM_WORLD.Send(&temp, 1, MPI::DOUBLE, 0, 0);
}
Update: within in myrank == 0
while(counter != jobs){
MPI::COMM_WORLD.Recv(&ans, imax, MPI::DOUBLE, MPI::ANY_SOURCE, MPI_ANY_TAG, mystatus);
answers[counter] = ans;
counter++;
}
You need to have some sort of feedback from rank 0 to the other ranks. After the other ranks return their work to rank 0, they should receive a new message back that tells them either their next job or that there is no more work to be completed. The ranks should continue looping until there is no more work to be done.