It is necessary to sum two vectors on separate processes in parts. I find a portion of vectors that needs to be sent out and send it using MPI_Send. Next, I summarize the parts of the vectors on the processes, I succeeded.
It is not possible to collect the resulting array again on the zero process. As far as I understand, you need to use MPI_Isend.
#include <iostream>
#include <stdio.h>
#include <mpi.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
void Print(int *vector, int n, int start) {
for (int i = start; i < n; i++)
printf("%4d", vector[i]);
}
void RandomFill(int *vector, int n) {
for (int i = 0; i < n; i++)
vector[i] = rand() % 100;
}
//C = A + B
int main(int argc, char* argv[])
{
int ProcNum, ProcRank;
MPI_Status status;
MPI_Request request;
int *A, *B, *C, *buf;
int nResult = 0;
int n = 5 + rand() % (25 - 5 + 1);
bool yes = true;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &ProcNum);
MPI_Comm_rank(MPI_COMM_WORLD, &ProcRank);
if (ProcRank == 0) {
int part_send = 0;
A = new int[n];
B = new int[n];
C = new int[n];
RandomFill(A, n);
RandomFill(B, n);
printf("\nProcess number: %d\t n = %d", ProcRank, n);
printf("\nVector A:\n");
Print(A, n, 0);
printf("\nVector B:\n");
Print(B, n, 0);
int rest = n % (ProcNum - 1);
int *rest_array = new int[rest];
printf("\n\nRest = %d", rest);
if (rest != 0)
{
part_send = (n - rest) / (ProcNum - 1);
nResult = ProcNum;
int j = 0;
for (int i = n - rest; i < n; i++) {
rest_array[j] = A[i] + B[i];
j++;
}
}
else
{
nResult = ProcNum - 1;
part_send = n / (ProcNum - 1);
}
for (int i = 1; i < ProcNum; i++)
{
int index = (i - 1) * part_send;
MPI_Send(&A[index], part_send, MPI_INT, i, 1, MPI_COMM_WORLD);
MPI_Send(&B[index], part_send, MPI_INT, i, 1, MPI_COMM_WORLD);
}
printf("\n\n");
buf = new int[part_send];
for (int i = 1; i < ProcNum; i++) {
MPI_Irecv(&buf, part_send, MPI_INT, MPI_ANY_SOURCE, 3, MPI_COMM_WORLD, &request);
if (MPI_Wait(&request, &status) == MPI_SUCCESS) {
for (int j = 0; j < part_send; j++)
C[(part_send * i) + j] = buf[j];
printf("Result:");
Print(C, n, 0);
}
}
}
else
{
printf("\n Process number: %d\n", ProcRank);
int nRecv = 0;
MPI_Probe(0, 1, MPI_COMM_WORLD, &status);
MPI_Get_count(&status, MPI_INT, &nRecv);
int *recvArr1 = new int[nRecv];
int *recvArr2 = new int[nRecv];
int *recvArrSum = new int[nRecv];
MPI_Recv(recvArr1, nRecv, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
MPI_Recv(recvArr2, nRecv, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
for (int i = 0; i < nRecv; i++) {
recvArrSum[i] = recvArr1[i] + recvArr2[i];
}
printf("recvArrSum:\n");
Print(recvArrSum, nRecv, 0);
MPI_Isend(&recvArrSum, nRecv, MPI_INT, 0, 3, MPI_COMM_WORLD, &request);
}
MPI_Finalize();
return 0;
}
Related
I want to convert backwards substitution sequential C code to parallel and I have an error while rank 1-size receiving data MPI_Recv(prev_x, displacements[rank], MPI_FLOAT, rank-1, tag, MPI_COMM_WORLD, &status);. The logic is a pipeline between processes.
MY code:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <time.h>
#include <math.h>
int main(int argc, char* argv[]){
int i,j,N;
float **a, *b;
float *local_x, *prev_x, *total_proc_x;
int tag = 100;
//MPI variables
int rank, size;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if(argc != 2){
if(rank == 0) printf("Using : %s <matrix_size>\n", argv[0]);
return 0;
}
N = strtol(argv[1], NULL, 10);
/* Allocate space for matrices */
a = (float **) malloc ( N * sizeof ( float *) );
for ( i = 0; i < N; i++)
a[i] = ( float * ) malloc ( (i+1) * sizeof ( float ) );
b = ( float * ) malloc ( N * sizeof ( float ) );
if(rank == 0){
srand ( time ( NULL));
for (i = 0; i < N; i++) {
b[i] = (float)rand()/(RAND_MAX*2.0-1.0);
a[i][i] = 2.0+(float)rand()/(RAND_MAX*2.0-1.0);
for (j = 0; j < i; j++)
a[i][j] = (float)rand()/(RAND_MAX*2.0-1.0);
for (j=i; j<N; j++)
a[i][j] = 0.0;
}
}
//broadcast data (a,b)
MPI_Bcast(a, N*N, MPI_FLOAT, 0, MPI_COMM_WORLD);
MPI_Bcast(b, N, MPI_FLOAT, 0, MPI_COMM_WORLD);
int block_size = N/size;
int *counts = (int *) malloc(size*sizeof(int));
int *displacements = (int *) malloc(size*sizeof(int));
int start, end;
for(i=0; i<size; i++){
start = 0;
for(j=0; j<i; j++){
start += block_size;
if(size-(j+1) < N%size) start++;
}
end = start + block_size;
if(size-(i+1) < N%size) end++;
counts[i] = end - start;
displacements[i] = start;
}
local_x = (float *) malloc(counts[rank]*sizeof(float));
for(i=0; i<counts[rank]; i++){
local_x[i] = 0.0;
}
prev_x = (float *) malloc(displacements[rank]*sizeof(float));
if(rank == 0) printf("Size: %d\n", size);
printf("Rank %d, Displacement: %d, Count: %d\n", rank, displacements[rank], counts[rank]);
//calculation
float sum;
if(rank == 0){
printf("Rank %d, OK\n", rank);
for(i=0; i<counts[0]; i++){
sum = 0.0;
for(j=0; j<i; j++){
sum = sum + (local_x[j] * a[i][j]);
}
local_x[i] = (b[i] - sum) / a[i][i];
}
MPI_Send(local_x, displacements[rank+1], MPI_FLOAT, rank+1, tag, MPI_COMM_WORLD);
printf("Process %d sent data to process %d\n", rank, rank+1);
}
if(rank != 0 && rank != (size-1)){
printf("Rank %d, OK\n", rank);
MPI_Recv(prev_x, displacements[rank], MPI_FLOAT, rank-1, tag, MPI_COMM_WORLD, &status);
printf("Process %d received data from process %d", rank, rank-1);
for(i=displacements[rank]; i<(displacements[rank] + counts[rank]); i++){
sum = 0.0;
//unowned rows
for(j=0; j<displacements[rank]; j++){
sum = sum + (prev_x[j] * a[i][j]);
}
//owned rows
for(j=displacements[rank]; j<i; j++){
sum = sum + (local_x[j-displacements[rank]] * a[i][j]);
}
local_x[i] = (b[i] - sum) / a[i][i];
}
//concatenate prev and local x
total_proc_x = (float *) malloc((displacements[rank] + counts[rank])*sizeof(float));
for(i=0; i<displacements[rank]; i++){
total_proc_x[i] = prev_x[i];
}
for(i=0; i<counts[rank]; i++){
total_proc_x[i+displacements[rank]] = local_x[i];
}
//send to next process
MPI_Send(total_proc_x, displacements[rank+1], MPI_FLOAT, rank+1, tag, MPI_COMM_WORLD);
}
if(rank == (size-1)){
printf("Rank %d, OK\n", rank);
MPI_Recv(prev_x, displacements[rank], MPI_FLOAT, rank-1, tag, MPI_COMM_WORLD, &status);
printf("Process %d received data from process %d", rank, rank-1);
for(i=displacements[rank]; i<(displacements[rank] + counts[rank]); i++){
sum = 0.0;
//unowned rows
for(j=0; j<displacements[rank]; j++){
sum = sum + (prev_x[j] * a[i][j]);
}
//owned rows
for(j=displacements[rank]; j<i; j++){
sum = sum + (local_x[j-displacements[rank]] * a[i][j]);
}
local_x[i] = (b[i] - sum) / a[i][i];
}
//concatenate prev and local x
float *total_proc_x = (float *) malloc((displacements[rank] + counts[rank])*sizeof(float));
for(i=0; i<displacements[rank]; i++){
total_proc_x[i] = prev_x[i];
}
for(i=0; i<counts[rank]; i++){
total_proc_x[i+displacements[rank]] = local_x[i];
}
/* Print result */
for (i = 0; i < N; i++) {
for (j = 0; j <= i; j++)
printf ("%f \t", a[i][j]);
printf ("%f \t%f\n", total_proc_x[i], b[i]);
}
/* Check result */
for (i = 0; i < N; i++) {
sum = 0.0;
for (j = 0; j <= i; j++)
sum = sum + (total_proc_x[j]*a[i][j]);
if (fabsf(sum - b[i]) > 0.00001) {
printf("%f != %f\n", sum, b[i]);
printf("Validation Failed...\n");
}
}
}
MPI_Finalize();
return 0;
}
Output:
$ mpicc -o backsub_mpi backsub_mpi.c
$ mpiexec -n 4 ./backsub_mpi 20
Rank 1, Displacement: 5, Count: 5
Rank 1, OK
Rank 3, Displacement: 15, Count: 5
Rank 3, OK
Size: 4
Rank 0, Displacement: 0, Count: 5
Rank 0, OK
Process 0 sent data to process 1
Rank 2, Displacement: 10, Count: 5
Rank 2, OK
-----------------------------------------------------------------------------
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 4105 failed on node n0 (127.0.0.1) due to signal 11.
-----------------------------------------------------------------------------
mpirun failed with exit status 11
Your problem is in how you allocate the matrix
a = (float **) malloc ( N * sizeof ( float *) );
for ( i = 0; i < N; i++)
a[i] = ( float * ) malloc ( (i+1) * sizeof ( float ) );
You're trying to allocate a triangular array, but you send it
MPI_Bcast(a, N*N, MPI_FLOAT, 0, MPI_COMM_WORLD);
as a square array.
Since a is an array or pointers, the actual matrix elements are probably not in contiguous memory.
You need to allocate double *a as a long enough single array, and then do some index translation to figure out where element i,j goes into this array. Something like i*(i+1)/2+j.
I am trying to calculate the sum of an array A using the reduce command; note here that A is only visible to the master node/root (0).
I am getting the following error and I can't seem to figure out why. Also, broadcasting the part (N) still produces the same error.
Error:
[kali:74924:0:74924] Caught signal 11 (Segmentation fault: address not mapped to object at address (nil))
==== backtrace (tid: 74924) ====
0 /lib/x86_64-linux-gnu/libucs.so.0(ucs_handle_error+0x2dc) [0x7f14b5486a9c]
1 /lib/x86_64-linux-gnu/libucs.so.0(+0x28c8f) [0x7f14b5486c8f]
2 /lib/x86_64-linux-gnu/libucs.so.0(+0x28e4a) [0x7f14b5486e4a]
3 /lib/x86_64-linux-gnu/libc.so.6(+0x3c910) [0x7f14b564e910]
4 ./parts(+0x14f1) [0x557de43984f1]
5 /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xcd) [0x7f14b56397ed]
6 ./parts(+0x113a) [0x557de439813a]
=================================
[kali:74925:0:74925] Caught signal 11 (Segmentation fault: address not mapped to object at address (nil))
==== backtrace (tid: 74925) ====
0 /lib/x86_64-linux-gnu/libucs.so.0(ucs_handle_error+0x2dc) [0x7fb3324b0a9c]
1 /lib/x86_64-linux-gnu/libucs.so.0(+0x28c8f) [0x7fb3324b0c8f]
2 /lib/x86_64-linux-gnu/libucs.so.0(+0x28e4a) [0x7fb3324b0e4a]
3 /lib/x86_64-linux-gnu/libc.so.6(+0x3c910) [0x7fb332678910]
4 ./parts(+0x14f1) [0x5581e42d44f1]
5 /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xcd) [0x7fb3326637ed]
6 ./parts(+0x113a) [0x5581e42d413a]
=================================
[kali:74926:0:74926] Caught signal 11 (Segmentation fault: address not mapped to object at address (nil))
==== backtrace (tid: 74926) ====
0 /lib/x86_64-linux-gnu/libucs.so.0(ucs_handle_error+0x2dc) [0x7f7e8e8f9a9c]
1 /lib/x86_64-linux-gnu/libucs.so.0(+0x28c8f) [0x7f7e8e8f9c8f]
2 /lib/x86_64-linux-gnu/libucs.so.0(+0x28e4a) [0x7f7e8e8f9e4a]
3 /lib/x86_64-linux-gnu/libc.so.6(+0x3c910) [0x7f7e8eac1910]
4 ./parts(+0x14f1) [0x558b09e094f1]
5 /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xcd) [0x7f7e8eaac7ed]
6 ./parts(+0x113a) [0x558b09e0913a]
=================================
===================================================================================
= BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
= PID 74924 RUNNING AT kali
= EXIT CODE: 11
= 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
Codes:
w/out broadcast
#include <stdio.h>
#include <mpi.h>
#include <stdlib.h>
#include <time.h>
int main (int argc, char** argv) {
int rank;
int size;
int sum = 0;
int grand_sum = 0;
int i;
int *A;
int N;
int part;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (rank == 0) {
do {
printf("Enter the array size: ");
scanf("%d", &N);
} while (N <= 0);
A = malloc(N * sizeof(int));
if (!A) {
printf("Array too big!\nExiting the program...\n");
return -1;
}
part = N / size;
srand(10);
for (i = 0; i < N; i++) {
A[i] = rand() % 10 + 1;
grand_sum += A[i];
printf("A[%d] = %d\n", i, A[i]);
}
for (i = 1; i < size; i++) {
MPI_Send(&part, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
MPI_Send(&A[i * part], part, MPI_INT, i, 0, MPI_COMM_WORLD);
}
} else {
int part;
MPI_Recv(&part, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
int Aw[part];
MPI_Recv(&Aw, part, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
for (i = 0; i < part; i++) {
sum += A[i];
}
}
MPI_Reduce(&sum, &grand_sum, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
if (rank == 0) {
for (i = size * part; i < N; i++) {
grand_sum += A[i];
}
printf("\nThe grand sum is: %d", grand_sum);
}
MPI_Finalize();
}
w/broadcast
#include <stdio.h>
#include <mpi.h>
#include <stdlib.h>
#include <time.h>
int main (int argc, char** argv) {
int rank;
int size;
int sum = 0;
int grand_sum = 0;
int i;
int *A;
int N;
int part;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (rank == 0) {
do {
printf("Enter the array size: ");
scanf("%d", &N);
} while (N <= 0);
A = malloc(N * sizeof(int));
if (!A) {
printf("Array too big!\nExiting the program...\n");
return -1;
}
part = N / size;
srand(10);
for (i = 0; i < N; i++) {
A[i] = rand() % 10 + 1;
printf("A[%d] = %d\n", i, A[i]);
}
for (i = 1; i < size; i++) {
//MPI_Send(&part, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
MPI_Send(&A[i * part], part, MPI_INT, i, 0, MPI_COMM_WORLD);
}
}
MPI_Bcast(&part, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (rank != 0) {
//MPI_Recv(&part, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
int Aw[part];
MPI_Recv(&Aw, part, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
for (i = 0; i < part; i++) {
sum += A[i];
}
}
MPI_Reduce(&sum, &grand_sum, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
if (rank == 0) {
for (i = size * part; i < N; i++) {
grand_sum += A[i];
}
printf("\nThe grand sum is: %d", grand_sum);
}
MPI_Finalize();
}
After rereading my code, I've spotted a mistake at the for loop, of the else statement:
for (i = 0; i < part; i++) {
sum += A[i];
}
A is not visible here; thus the error. Aw should have been used here instead.
Correct code:
for (i = 0; i < part; i++) {
sum += Aw[i];
}
The task is a 2D matrix multiplication. N is the data size and P is number of processors. dn029 is my remote host.
I tested this code for multiple number of Ps and I either got a code 139 or 11 error.
The error message I get :
BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
= PID 147347 RUNNING AT dn029
= EXIT CODE: 139
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<mpi.h>
int P;
int N = 1024;
/*Single Row, Single Column Matrix Multiplication Function*/
float row_col_multi(float* row, float* col){
int i0;
float c0;
for(i0 = 0; i0 < N ; i0++)
c0 += row[i0]*col[i0];
return c0;
}
int main(int argc, char *argv[]){
MPI_Init(&argc, &argv);
int i, j, k, rank, size;
double start, end, total;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Request request[2];
P = size;
float A_row [N];
float B_col [N];
float matrix_C[N][N];
float matrix_A[N][N];
float matrix_BT[N][N];
if(rank == 0){
double wall_time;
for(i = 0; i < N; i++)
for (j = 0; j < N; j++)
matrix_A[i][j] = -1+2*((float)rand())/RAND_MAX;
for(i = 0; i < N; i++)
for (j = 0; j < N; j++)
matrix_BT[i][j] = -1+2*((float)rand())/RAND_MAX;
}
start = MPI_Wtime();
if(rank == 0)
printf("Root processor %d: Scatterring is started for diagonal elements...\n", rank);
for(i = 0; i < N/P ; i++){
MPI_Iscatter(matrix_A[rank + P*i], N, MPI_FLOAT, A_row, N, MPI_FLOAT, 0, MPI_COMM_WORLD, &request[0]);
MPI_Iscatter(matrix_BT[rank + P*i], N, MPI_FLOAT, B_col, N, MPI_FLOAT, 0, MPI_COMM_WORLD, &request[1]);
MPI_Waitall(2,request, MPI_STATUSES_IGNORE);
matrix_C[rank + P*i][rank + P*i] = row_col_multi(A_row, B_col);
}
for(i = 1 ; i < N ; i++){
if(rank < i){
for(k = 0; k < N/P ; k++){
MPI_Iscatter(matrix_A[rank+i + P*k], N, MPI_FLOAT, A_row, N, MPI_FLOAT, 0, MPI_COMM_WORLD, &request[0]);
MPI_Iscatter(matrix_BT[rank + P*k], N, MPI_FLOAT, B_col, N, MPI_FLOAT, 0, MPI_COMM_WORLD, &request[1]);
MPI_Waitall(2,request, MPI_STATUSES_IGNORE);
matrix_C[rank+i + P*k][rank + P*k] = row_col_multi(A_row, B_col);
}
}
}
end = MPI_Wtime();
printf("Total Time: %f\n", end - start);
MPI_Finalize();
}
I'm trying to understand http://wyattgorman.com/?p=25. So far I have made not much more than clang-format:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 20
int m_row = SIZE, m_column = SIZE, zed = 30, matrix[SIZE][SIZE], visited[SIZE], best_path[SIZE];
int best_cost = 9999999, size = SIZE;
void dfs(int city, int visited_in[], int path_in[], int path_i_in, int cost_in) {
if (cost_in < best_cost) {
int* visited = calloc(sizeof(int), size + 1);
int* path = calloc(sizeof(int), size + 1);
int path_i = path_i_in, cost = cost_in, i;
for (i = 0; i < size; i++) {
visited[i] = visited_in[i];
path[i] = path_in[i];
}
visited[city] = 1;
path[path_i] = city;
path_i++;
int leaf = 0;
for (i = 0; i < size; i++) {
if (visited[i] == 0) {
leaf++;
dfs(i, visited.get(), path.get(), path_i, cost + matrix[city][i]);
}
}
if (leaf == 0) {
cost += matrix[city][0];
path[path_i] = 0;
path_i++;
if (cost < best_cost) {
// printf("Found new best cost: %i\n", cost);
best_cost = cost;
for (i = 0; i < size; i++)
best_path[i] = path[i];
}
}
free(visited);
free(path);
}
}
int main(int argc, char *argv[]) {
int rank, p;
// , source, dest;
// int tag = 0;
MPI_Status status;
MPI_Init(0, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
srand(time(NULL));
if (rank == 0) {
int i, j;
for (i = 0; i < m_row; i++)
for (j = 0; j < m_column; j++)
matrix[i][j] = 0;
for (i = 0; i < m_row; i++) {
for (j = 0; j < i; j++) {
if (i != j) {
int temp = (rand() % zed) + 1;
matrix[i][j] = temp;
matrix[j][i] = temp;
}
}
}
for (i = 1; i < p; i++)
MPI_Send(&matrix[0][0], size * size, MPI_LONG, i, 0, MPI_COMM_WORLD);
printf("Matrix, %ix %i, Max Int : %i\n", m_row, m_column, zed);
for (i = 0; i < m_row; i++) {
for (j = 0; j < m_column; j++)
printf("%i\t", matrix[i][j]);
printf("\n");
fflush(NULL);
}
printf("\n");
int winner;
int node_array[p - 1];
int node_array_i = 0;
for (i = 0; i < p - 1; i++)
node_array[i] = i + 1;
for (i = 1; i < size; i++) {
int temp_best_cost, node;
node = node_array[node_array_i];
if (node_array_i < p - 2)
node_array_i++;
else
node_array_i = 0;
int* temp_best_path = calloc(sizeof(int), size + 1);
MPI_Recv(&temp_best_cost, 1, MPI_INT, node, 0, MPI_COMM_WORLD,&status);
MPI_Recv(&temp_best_path[0], size + 1, MPI_INT, node, 0, MPI_COMM_WORLD, &status);
if (temp_best_cost < best_cost) {
winner = node;
best_cost = temp_best_cost;
for (j = 0; j < size + 1; j++)
best_path[j] = temp_best_path[j];
}
MPI_Send(&best_cost, 1, MPI_INT, node, 0, MPI_COMM_WORLD);
}
printf("Best Path Found by node % i :\n", winner);
printf("% i", best_path[0]);
for (i = 1; i < size + 1; i++)
printf(" –> % i", best_path[i]);
printf("\nBest Cost Found : % i\n", best_cost);
} else {
MPI_Recv(&(matrix[0][0]), m_row * m_column, MPI_LONG, 0, 0, MPI_COMM_WORLD, &status);
int i;
for (i = rank; i < size; i += (p - 1)) {
int* visited = calloc(sizeof(int), size + 1);
int* path = calloc(sizeof(int), size + 1);
int cost = matrix[0][i], path_i = 1;
path[0] = 0;
visited[0] = 1;
dfs(i, visited.get(), path.get(), path_i, cost);
MPI_Send(&best_cost, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
MPI_Send(&best_path[0], size + 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
MPI_Recv(&best_cost, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
free(visited);
free(path);
}
}
MPI_Finalize();
return 0;
}
To my eyes it looks like visited[] from
int m_row = SIZE, m_column = SIZE, zed = 30, matrix[SIZE][SIZE], visited[SIZE], best_path[SIZE];
gets overwritten by
int* visited = calloc(sizeof(int), size + 1);
So, is that ok?
Also, in rank, at
MPI_Recv(&(matrix[0][0]), m_row * m_column, MPI_LONG, 0, 0, MPI_COMM_WORLD, &status);
destination matrix looks like the same as origin matrix (does that make sense?), in rank 0, at:
MPI_Send(&matrix[0][0], size * size, MPI_LONG, i, 0, MPI_COMM_WORLD);
Since matrix is shared by all ranks, right?
int m_row = SIZE, m_column = SIZE, zed = 30, matrix[SIZE][SIZE], visited[SIZE], best_path[SIZE];
Also, I'll guess best_path[] (there on the begining) should be best_path[SIZE+1] instead of best_path[SIZE]. Because loop goes to size+1, right?
for (j = 0; j < size + 1; j++)
best_path[j] = temp_best_path[j];
The first (global) visited variable is "shadowed" by the local one used with calloc(). This isn't necessarily wrong, but it is poor coding style.
Yes, matrix is shared by all ranks (for some definition of shared).
As for the writing past the end of best_path, you're correct, that code is broken (it has undefined behavior).
I'm making an MPI program with Visual studio and a problem occurred.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <mpi.h>
int main(void) {
int a[1000], b[1000];
int my_rank, p;
int source = 0, tag = 5;
int count[100], result = 0;
MPI_Status status;
MPI_Init(NULL, NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &p);
srand(time(NULL));
if (my_rank == 0) {
for (int j = 0; j < p; j++) {
for (int i = j / p; i < 1000 * ((j+1) / p); i++) {
a[i] = rand() % 100;
MPI_Send(a[i], 1, MPI_INT, j, tag, MPI_COMM_WORLD);
}
}
printf("&d", a[30]);
for (int i = 0; i < 1000 / p; i++) {
MPI_Recv(&b[i], 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status);
if (b[i] % 2 != 0) {
count[my_rank] += b[i];
}
}
}
else if (my_rank != 0) {
count[my_rank] = 0;
for (int j = 0; j < 1000 / p; j++) {
MPI_Recv(&b[j], 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status);
if (b[j] % 2 != 0) {
count[my_rank] += b[j];
}
}
}
for (int i = 0; i < p; i++) {
result += count[i];
}
printf("The sum of the odd numbers is %d.", result);
MPI_Finalize();
return 0;
}
If I run the code above (I inserted mpiexec -n 4 HW1.exe at the command prompt), I get an error message like this :
0: samsungpc: 0xc0000005: process excited without calling finalize
1: samsungpc: terminated
2: samsungpc: terminated
3: samsungpc: terminated
---error analysis---
0: HW1.exe ended prematurely and may have crashed on samsungpc
---error analysis---