Segmentation fault by using MPI_Scatter and MPI_Gather - c++

I was trying to calculate elementwise multiplication of matrix elements.
But I've got this error and don't know what to do.
===================================================================================
= BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
= PID 16855 RUNNING AT kevlinsky-PC
= EXIT CODE: 139
= CLEANING UP REMAINING PROCESSES
= YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
YOUR APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault (signal 11)
This typically refers to a problem with your application.
Please see the FAQ page for debugging suggestions
The task was to split it between processes, calculate the result and return it to the zero process.
Code example:
#include <iostream>
#include <math.h>
#include "mpi.h"
int main(int argc, char *argv[]){
MPI_Init(&argc, &argv);
int rank, size;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
const int n = 4;
int arrayA[n][n];
int arrayB[n][n];
for (int i = 0; i < n; i++){
for (int j = 0; j < n; i++) {
arrayA[i][j] = (rand() % 1000) - 500;
}
for (int j = 0; j < n; i++) {
arrayB[i][j] = (rand() % 1000) - 500;
}
}
int getbufA[n];
int getbufB[n];
int arrayC[n][n];
int bufC[n];
MPI_Scatter(&arrayA, n, MPI_INT, &getbufA, n, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Scatter(&arrayB, n, MPI_INT, &getbufB, n, MPI_INT, 0, MPI_COMM_WORLD);
for (int i = 0; i < n; i++) {
bufC[i] = getbufA[i] * getbufB[i];
}
MPI_Gather(&bufC, n, MPI_INT, &arrayC, n, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0) {
printf("MATRIX C \n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("%d ", arrayC[i][j]);
}
printf("\n");
}
}
MPI_Finalize();
}
Can someone help with this?

I think this is your error:
for (int j = 0; j < n; i++) {
arrayA[i][j] = (rand() % 1000) - 500;
}
You need j++ in this loop. And you have this error in two places. j is never incremented and stays 0, and i is incremented indefinitely (because the condition for the loop is based on j), so very soon you go out of bounds for the array, hence the segmentation fault.

Related

How to fix issue while doing parallel programming with MPI for Matrix-Multiplication with dynamic 2D array?

I am trying to create three matrices a,b,c where c = a*b with using MPI. Also, I am taking the length of these matrices as N (common for all) as it I have to create a square matrix. However, whenever I enter the value of N in runtime, I am getting a segmentation fault error and if I put I gave the value of N in the program, then it works fine.
I have tried this with scatter and gather as given it in here: matrix multiplication using Mpi_Scatter and Mpi_Gather
. Now I have to di dynamically, so that can check the time consumption done by the program to execute it. Just want to inform that I have done this OpenMP, and which was great, but want to compare which one is really good i.e. OpenMP or MPI.
#include <iostream>
#include <math.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stddef.h>
#include "mpi.h"
int main(int argc, char *argv[])
{
int i, j, k, rank, size, tag = 99, blksz, sum = 0,N=0;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int aa[N],cc[N];
if(rank ==0)
{
std::cout << "input value of N" << '\n';
std::cin >> N;
}
MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
int **a = new int*[N];
for (int i = 0; i < N; i++)
a[i] = new int[N];
int **b = new int*[N];
for (int i = 0; i < N; i++)
b[i] = new int[N];
int **c = new int*[N];
for (int i = 0; i < N; i++)
c[i] = new int[N];
if (rank == 0)
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
a[i][j] =rand() % 10;
std::cout << a[i][j];
}
std::cout << '\n';
}
std::cout << '\n';
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
b[i][j] =rand() % 10;
std::cout << b[i][j];
}
std::cout << '\n';
}
}
MPI_Scatter(a, N*N/size, MPI_INT, aa, N*N/size, MPI_INT,0,MPI_COMM_WORLD);
//broadcast second matrix to all processes
MPI_Bcast(b, N*N, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
//perform vector multiplication by all processes
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
sum = sum + aa[j] * b[j][i]; //MISTAKE_WAS_HERE
}
cc[i] = sum;
sum = 0;
}
MPI_Gather(cc, N*N/size, MPI_INT, c, N*N/size, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
if (rank == 0) //I_ADDED_THIS
{
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++)
{
std::cout << a[i][j]<< '\n';
}
std::cout << '\n';
}
std::cout << '\n' << '\n';
}
delete *a;
delete *b;
delete *c;
}
The error which I am getting is:
mpirun noticed that process rank 3 with PID 3580 on node localhost exited on signal 11 (Segmentation fault).
I just wanted here that matrix multiplication to be done.
Declaring array like this
int **a = new int*[N];
for (int i = 0; i < N; i++)
a[i] = new int[N];
will not allocate it in contiguous memory location. Replacing above declaration with one of the following will make the application work.
int a[N][N]; // or
int **a=malloc(N*N*sizeof(int));
MPI_Scatter, Gather etc works on arrays with contiguous memory location.
#include <iostream>
#include <math.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stddef.h>
#include "mpi.h"
int main(int argc, char *argv[])
{
int i, j, k, rank, size, tag = 99, blksz, sum = 0,N=0;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if(rank ==0)
{
std::cout << "input value of N" << '\n';
std::cin >> N;
}
MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
int size_array=(N*N)/size;
int aa[size_array],cc[size_array]; // Declare arrays here since value of N is 0 otherwise
int a[N][N];
int b[N][N];
int c[N][N];
for (int i = 0; i < N; i++)
c[i] = new int[N];
if (rank == 0)
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
a[i][j] =rand() % 10;
std::cout << a[i][j];
}
std::cout << '\n';
}
std::cout << '\n';
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
b[i][j] =rand() % 10;
std::cout << b[i][j];
}
std::cout << '\n';
}
}
MPI_Scatter(a, N*N/size, MPI_INT, aa, N*N/size, MPI_INT,0,MPI_COMM_WORLD);
//broadcast second matrix to all processes
MPI_Bcast(b, N*N, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
//perform vector multiplication by all processes
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
sum = sum + aa[j] * b[j][i]; //MISTAKE_WAS_HERE
}
cc[i] = sum;
sum = 0;
}
MPI_Gather(cc, N*N/size, MPI_INT, c, N*N/size, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
if (rank == 0) //I_ADDED_THIS
{
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++)
{
std::cout << a[i][j]<< '\n';
}
std::cout << '\n';
}
std::cout << '\n' << '\n';
}
}
Also declare the array int aa[N],cc[N]; after the scanf.

program ended prematurely and may have crashed. exit code 0xc0000005

Here is my code I want to multiply a 2D array with a vector array:
#include<iostream>
#include<mpi.h>
using namespace std;
int v_array[10] ;
int ch_size, start, close;
int res ;
int rows, cols;
int main(int argc, char *argv[])
{
int pro_id, tot_pros;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &pro_id);
MPI_Comm_size(MPI_COMM_WORLD, &tot_pros);
if (pro_id == 0) {
cout << "Enter rows and columns: ";
cin >> rows >> cols;
int **array = new int*[rows];
int size1 = rows * cols;
array[0] = new int[size1];
for (int j = 1; j < rows; j++) {
array[j] = &array[0][j*cols];
}
for (int i = 0; i < rows; i++) {
v_array[i] = 1;
for (int j = 0; j < cols; j++) {
array[i][j] = 1;
}
}
for (int i = 1; i < tot_pros; i++) {
ch_size = (rows / (tot_pros - 1));
start = (i - 1) * ch_size;
if (((i + 1) == tot_pros) && ((rows % (tot_pros - 1)) != 0)) {
close = rows;
}
else {
close = start + ch_size;
}
MPI_Send(&start, 1, MPI_INT, i, 1, MPI_COMM_WORLD);
MPI_Send(&close, 1, MPI_INT, i, 2, MPI_COMM_WORLD);
MPI_Send(&cols, 1, MPI_INT, i, 4, MPI_COMM_WORLD);
MPI_Send(&array[start][0], ch_size *cols, MPI_INT, i, 3, MPI_COMM_WORLD);
}
}
else
{
int cols;
MPI_Recv(&start, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
MPI_Recv(&close, 1, MPI_INT, 0, 2, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
MPI_Recv(&cols, 1, MPI_INT, 0, 4, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
int **array = new int*[(close - start)*cols];
MPI_Recv(array, (close - start) *cols , MPI_INT, 0, 3, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
for (int i = start; i < close; i++) {
for (int j = 0; j < cols; j++) {
cout << array[i]<<array[j];
res += array[i][j] * v_array[i];
cout << res;
}
}
}
MPI_Finalize();
return 0;
}
This same program is working fine when I have static array, But with dynamic I got this error.
E:\MS(CS)\2nd Semester\Parallel
Programing\programs\arr_multi\Debug>mpiexec -n 4 arr_multi.exe Enter
rows and columns: 3 2
job aborted: [ranks] message
[0-1] terminated
[2] process exited without calling finalize
[3] terminated
---- error analysis -----
[2] on RAMISHA-PC arr_multi.exe ended prematurely and may have
crashed. exit code 0xc0000005
---- error analysis -----
I declared an array with contiguous location and my rows are divided correctly among processes. I think I have problem with my data structure and tried many solutions but in vain.
First and foremost, there are ways to debug an MPI application, which should really be your top priority. A general approach for multi-process applications is to pause at the beginning of your application e.g. with a getchar() then attach to each process with a debugger as described here:
compile, link and start running your MPI program (you may wish to put a read statement early on to hold the program while you do the next steps)
attach to one of the currently running MPI processes: Debug - Attach to Process brings up a dialogue box which lists Available Processes. You should see NUM instances (where N is from mpiexec -n NUM) of your executable. Select all of these and click on Attach. You can now debug by adding breakpoints etc. To move between MPI processes use the Process drop-down menu just above the code listing.
Having said that, at least one of the problems is with this part: int **array = new int*[(close - start)*cols]; (in the receive part of the application). You allocate the first dimension but not the second, so all pointers in the first dimension are uninitialized.
Change it to something like:
int *array = new int[(close - start) * cols];
MPI_Recv(array, (close - start) *cols, MPI_INT, 0, 3, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
for (int i = start; i < close; i++) {
for (int j = 0; j < cols; j++) {
cout << array[(i - start) * cols];
res += array[(i - start) * cols] * v_array[i];
cout << res;
}
}
delete[] array;
Or if you really want to use a 2D array, copy the initialization code from the sending part:
int rows = close - start;
int **array = new int*[rows];
int size1 = rows * cols;
array[0] = new int[size1];
for (int j = 1; j < rows; j++) {
array[j] = &array[0][j*cols];
}
The second problem is that v_array, being a global is not initialized in your receiver processes. Remember that in MPI each process is an independent program. So you should initialize v_array always, i.e. regardless of pro_id.
for (int i = 0; i < rows; i++) {
v_array[i] = 1;
}

MPI_Scatter a 2D array in other 2D arrays

I want to scatter a 2D array in other 2D arrays (one for each process) using this specific way of allocating memory.
int (*matrix)[cols] = malloc(sizeof *matrix* rows);
I keep getting this error:
One of the processes started by mpirun has exited with a nonzero exit
code. This typically indicates that the process finished in error.
If your process did not finish in error, be sure to include a "return
0" or "exit(0)" in your C code before exiting the application.
PID 7035 failed on node n0 (127.0.0.1) due to signal 11.
I think the problem is on scatter but I am new to parallel programming so if anyone knows what the issue is please help me.
Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "mpi.h"
int main(int argc, char** argv) {
int my_rank;
int p;
int root;
int rows = 0;
int cols = 0;
int **matrix;
int i, j;
int local_rows;
int answer = 0;
int broke = 0;
MPI_Init(& argc, & argv);
MPI_Comm_rank(MPI_COMM_WORLD, & my_rank);
MPI_Comm_size(MPI_COMM_WORLD, & p);
if (my_rank == 0) {
do {
printf("Enter Dimensions NxN\n");
scanf("%d", & rows);
scanf("%d", & cols);
if (cols != rows) {
printf("Columns must be the same as rows,enter dimensions again.\n");
}
} while (rows != cols);
int (*matrix)[cols] = malloc(sizeof *matrix* rows);
printf("Fill array %dx%d\n", rows, cols);
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
scanf("%d",&matrix[i][j]);
}
}
printf("\n");
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
printf("%d ",matrix[i][j]);
}
printf("\n");
}
}
root = 0;
MPI_Bcast(&rows, 1, MPI_INT, root, MPI_COMM_WORLD);
MPI_Bcast(&cols, 1, MPI_INT, root, MPI_COMM_WORLD);
local_rows = rows / p;
int (*local_matrix)[rows] = malloc(sizeof *local_matrix* local_rows);
MPI_Scatter(matrix, local_rows*rows, MPI_INT,local_matrix, local_rows*rows, MPI_INT, 0, MPI_COMM_WORLD);
printf("\nLocal matrix fo the process %d is :\n", my_rank);
for (i = 0; i < local_rows; i++) {
for (j = 0; j < cols; j++) {
printf("%d ", local_matrix[i][j]);
}
printf("\n");
}
if (my_rank==0){
free(matrix);
free(local_matrix);
}
MPI_Finalize();
}
The problem with your code is that you declared two variables with the name matrix:
int **matrix;
and
int (*matrix)[cols] = malloc(sizeof *matrix* rows);
and since the latter was declared inside the if (my_rank == 0) {..} the variable begin used in the scatter MPI_Scatter(matrix, local_rows*rows, MPI_INT,local_matrix, local_rows*rows, MPI_INT, 0, MPI_COMM_WORLD);
is the first one, the not allocated one, and not the one you allocated space for. That is why you are getting the error.
Try this:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "mpi.h"
int main(int argc, char** argv) {
int my_rank;
int p;
int root;
int rows = 0;
int cols = 0;
int i, j;
int local_rows;
int answer = 0;
int broke = 0;
MPI_Init(& argc, & argv);
MPI_Comm_rank(MPI_COMM_WORLD, & my_rank);
MPI_Comm_size(MPI_COMM_WORLD, & p);
int (*matrix)[cols];
if (my_rank == 0) {
do {
printf("Enter Dimensions NxN\n");
scanf("%d", & rows);
scanf("%d", & cols);
if (cols != rows) {
printf("Columns must be the same as rows,enter dimensions again.\n");
}
} while (rows != cols);
matrix = malloc(sizeof *matrix * rows);
printf("Fill array %dx%d\n", rows, cols);
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
scanf("%d",&matrix[i][j]);
}
}
printf("\n");
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
printf("%d ",matrix[i][j]);
}
printf("\n");
}
}
root = 0;
MPI_Bcast(&rows, 1, MPI_INT, root, MPI_COMM_WORLD);
MPI_Bcast(&cols, 1, MPI_INT, root, MPI_COMM_WORLD);
local_rows = rows / p;
// Changed from the original
int (*local_matrix)[cols] = malloc(sizeof *local_matrix* local_rows);
printf("R = (%d, %d, %d) \n",my_rank, local_rows, cols);
if(my_rank == 0)
{
printf("\n");
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
printf("%d ",matrix[i][j]);
}
printf("\n");
}
}
MPI_Scatter(matrix, local_rows*cols, MPI_INT,local_matrix,
local_rows*cols, MPI_INT, 0, MPI_COMM_WORLD);
...
Btw I think you meant:
int (*local_matrix)[cols] = malloc(sizeof *local_matrix* local_rows);
and not
int (*local_matrix)[rows] = malloc(sizeof *local_matrix* local_rows);
Also do not forget to free the "local_matrix" for the slaves also.

MPI_Scatter and MPI_Allgather

Okay, so here is another question related to my previous post MPI_Broadcast using vectors
I want to scatter a matrix (4x4) in such a way that each process receives one row (total of 4 processes). I am using vectors which need to be resized and a bit of playing around. It worked well when using arrays but with vectors I can't get the desired output.
updated code (Minimal)
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cmath>
#include <chrono>
#include <cmath>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include"mpi.h"
using namespace std;
const int num_rows1 = 4, num_rows2 = 4, num_cols1 = 4, num_cols2 = 4;
const int root = 0;
int i, j, k;
vector<vector<int> > matrix1(num_rows1, vector <int>(num_cols1));
vector<vector<int> > matrix2(num_rows2, vector <int>(num_cols2));
vector<vector<int> > result(num_rows1, vector <int>(num_cols1));
int finale[num_rows1][num_cols2];
vector<vector<int> > transpose_mat(num_cols2, vector <int>(num_rows2));
vector<int> column1(num_rows1);
vector<int> column2(num_cols2);
double start_time, end_time;
int * column3 = new int[];
//Function working with the multiplication
vector<int> mult(vector<vector<int> > A, vector<int> B)
{
//Multiplication
for (int i = 0; i < num_rows1; ++i)
{
int sum = 0;
for (int j = 0; j < num_cols1; ++j)
{
sum += A[i][j] * B[j];
}
column1.push_back(sum);
}
return column1;
}
//Function generating random matrices
vector<vector<int>> generate_matrix(int nrow, int ncol)
{
vector<vector<int>> matrix(nrow, vector <int>(ncol));
for (int i = 0; i < nrow; ++i)
{
for (int j = 0; j < ncol; ++j)
{
matrix[i][j] = (15 *rand() / RAND_MAX - 3);
}
}
return matrix;
}
//function taking the transpose
vector<vector<int>>transpose(vector<vector<int> > matrix , int nrow, int ncol)
{
//Transpose of matrix 2
for (i = 0; i < nrow; ++i)
for (j = 0; j < ncol; ++j)
{
transpose_mat[j][i] = matrix2[i][j];
}
cout << "Transpose " << endl;
for (int i = 0; i < num_rows2; ++i)
{
for (int j = 0; j < num_cols2; ++j)
{
cout << transpose_mat[i][j] << " ";
}
cout << endl;
}
return transpose_mat;
}
//main function
int main(int argc, char *argv[])
{
MPI_Status status;
MPI_Request request;
int tag = 1;
int rank;
int world_size; //Number of processes
// Initialize the MPI environment
MPI_Init(NULL, NULL);
// Get the rank of the process
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
// Get the name of the processor
char processor_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
MPI_Get_processor_name(processor_name, &name_len);
// Get the number of processes
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
if (rank == root)
{
//Filling
matrix1 = generate_matrix(num_rows1, num_cols1);
for (int i = 0; i < num_rows1; ++i)
{
MPI_Bcast(&matrix1[i][0], num_rows1, MPI_INT, root, MPI_COMM_WORLD);
}
}
else if (rank == 1)
{
srand(time(NULL));
//Filling
matrix2 = generate_matrix(num_rows2, num_cols2);
transpose_mat = transpose(matrix2, num_rows2, num_cols2);
}
if (rank > root)
{
int size = matrix1.size();
result.resize(size);
for (int i = 0; i < size; i++){
result[i].resize(size);
}
for (int i = 0; i < size; ++i)
{
MPI_Bcast(&result[i][0], size, MPI_INT, root, MPI_COMM_WORLD);
}
}
int size1 = transpose_mat.size();
column2.resize(size1);
//Scattering the transposed matrix
for (j = 0; j < num_rows2; ++j)
{
MPI_Scatter(&transpose_mat[0][j], size1*size1 / world_size, MPI_INT, &column2[j], size1*size1 / world_size, MPI_INT, 1, MPI_COMM_WORLD);
}
cout << "The scattered data at process " << rank << " is: " << endl;
for (int j = 0; j < num_cols2; ++j)
{
cout << column2[j] << endl;
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
return 0;
}
In the updated PNG one can see that the first two rows of the matrix are scattered. The first one being received by Process 0 and the second row by Process 2. Why do Process 1 and Process 3 don't give the desired reault.
Updated PNG

Parallel processing - does the slaves generate the data set?

In my parallel programming book, I came across this code that says the slaves generate the data set, however, I think the master acutally generates the data set.
This line in particular is why I believe that master generates the data set.
for (i=0; i < ARRAY_SIZE; i++)
numbers[i] = i;
Can someone confirm if master or slaves generate the data set?
#include "mpi.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define TRIALS 20
#define ARRAY_SIZE 1000000
int main(int argc, char *argv[])
{
int myid, numprocs;
double startwtime, endwtime;
int namelen;
int* numbers = new int[ARRAY_SIZE];
int i, j, sum, part_sum;
int s, s0, startIndex, endIndex;
double totalTime;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
MPI_Get_processor_name(processor_name,&namelen);
fprintf(stderr,"Process %d on %s\n", myid, processor_name);
fflush(stderr);
for (i=0; i < ARRAY_SIZE; i++)
numbers[i] = i;
if (myid == 0)
{
s = (int) floor(ARRAY_SIZE/numprocs);
s0 = s + ARRAY_SIZE%numprocs;
//printf("s=%d , s0= %d\n", s, s0);
}
MPI_Bcast(&s, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&s0, 1, MPI_INT, 0, MPI_COMM_WORLD);
startIndex = s0 + (myid - 1)*s;
endIndex = startIndex + s;
totalTime = 0;
for (j = 1; j <= TRIALS; j++)
{
if (myid == 0)
{
startwtime = MPI_Wtime();
}
sum = 0;
part_sum = 0;
if (myid == 0) // master
{
// compute sum of master's numbers
for (i = 0; i < s0; i++)
{
part_sum += numbers[i];
}
}
else
{
for (i = startIndex; i < endIndex; i++)
{
part_sum += numbers[i];
}
}
MPI_Reduce(&part_sum, &sum, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
if (myid == 0)
{
double runTime;
endwtime = MPI_Wtime();
runTime = endwtime - startwtime;
printf("Trial %d : Execution time (sec) = %f\n", j, runTime);
printf("Sum = %d \n", sum);
totalTime += runTime;
}
} // end for
if (myid == 0)
printf("Average time for %d trials = %f", TRIALS, totalTime/TRIALS);
MPI_Finalize();
}
Both the master and the slaves generate the entire array. You have to remember that your program runs on all nodes and the part of the code in question doesn't distinguish between master/slave. So the wording of your book isn't wrong, but it could be clarified. :)