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---
Related
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;
}
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];
}
A program was written to find the minimum value in the matrix. At small values of the matrix dimension, it works correctly, however, if the dimension exceeds 350x350, then when calculating on a different number of nodes, a similar error occurs.
mpirun noticed that process rank 4 with PID 15014 on node cluster exited on signal 11 (Segmentation fault).
Everything works on two cores, but not always on others.
I use the following commands:
mpicc Lab777.c -o 1 -lm -std=c99
mpirun -np 16 ./1
The code:
#include "mpi.h"
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define ROWS 350
#define COLS 350
#define max 999999999
void rand_matrix(int array[ROWS][COLS])
{
srand((unsigned int)time(NULL));
for (int i = 0; i < ROWS; i++)
for (int j = 0; j < COLS; j++)
array[i][j] = rand();
}
void show(int array[ROWS][COLS])
{
for (int i = 0; i < ROWS; i++)
{
printf("\n");
for (int j = 0; j < COLS; j++)
{
printf("\t|%d|", array[i][j]);
}
printf("\n");
}
}
void convert(int array[ROWS][COLS], int *conv_arr)
{
int k = 0;
for (int i = 0; i < ROWS; i++)
for (int j = 0; j < COLS; j++)
{
conv_arr[k] = array[i][j];
k++;
}
}
int find_min(int *array, int piece, int num_of_pieces)
{
int result = max;
for (int i = 0; i < (ROWS * COLS / (num_of_pieces)); i++)
if (array[i] < result)
result = array[i];
return result;
}
int main(int argc, char *argv[])
{
int matrix[ROWS][COLS], lin_arr[ROWS * COLS], min;
double startwtime, endwtime;
int ProcNum;
int ProcRank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &ProcNum);
MPI_Comm_rank(MPI_COMM_WORLD, &ProcRank);
int recv_matrix[ProcNum][ROWS * COLS], func[ProcNum];
if (ProcRank == 0)
{
printf("Matrix is filling\n");
rand_matrix(matrix);
convert(matrix, lin_arr);
printf("Matrix:\n");
//show(matrix);
}
startwtime = MPI_Wtime();
MPI_Scatter(&lin_arr[(ProcRank) * (ROWS * COLS / (ProcNum))], (ROWS * COLS / (ProcNum)), MPI_INT, &recv_matrix[ProcRank],(ROWS * COLS / (ProcNum)), MPI_INT, 0, MPI_COMM_WORLD);
func[ProcRank] = find_min(recv_matrix[ProcRank], ProcRank, ProcNum);
MPI_Reduce(&func[ProcRank], &min, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD);
endwtime = MPI_Wtime();
if (ProcRank == 0)
{
printf("Min value: %d\n", min);
printf("Time: %.4f\n", endwtime-startwtime);
}
MPI_Finalize();
return 0;
}
UPD:
Trying to reduce memory for recv_matrix and func.
I added the following line :
#define MAXPROC 20
And changed the following:
int recv_matrix[MAXPROC][ROWS * COLS], func[MAXPROC];
But now it works with a smaller matrix size
Trying to pass an array pointer between MPI Processes and receiving it to dynamically allocated memory. it keeps giving a segmentation fault, which we believe is due to the way we are sending it between processes. Our code is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "mpi.h"
#include <math.h>
int main(int argc, char* argv[])
{
int my_rank, i, j, p;
MPI_Request request, request2;
MPI_Status mpi_status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Barrier(MPI_COMM_WORLD);
if (my_rank == 0)
{
int size = 5;
int **slice;
slice = (int **)malloc(sizeof(int*)* size);
slice[0] = (int *)malloc(sizeof(int)* size*size);
for(i = 0; i< size;i++)
{
slice[i] = (*slice + size*i);
}
for (i = 0; i < size; i++)
{
for (j = 0; j < size; j++)
{
slice[i][j] = i*j;
}
}
for (i = 0; i < size; i++)
{
for (j = 0; j < size; j++)
{
printf("slice[%d][%d]: %d\n", i, j, slice[i][j]);
}
}
MPI_Send(&slice, size * size, MPI_INT, 1, 1, MPI_COMM_WORLD);
} else {
int local_size=5;
int **local_slice;
local_slice = (int **)malloc(sizeof(int*)* local_size);
local_slice[0] = (int *)malloc(sizeof(int)* local_size*local_size);
for(i = 0; i< local_size;i++)
{
local_slice[i] = (*local_slice + local_size*i);
}
MPI_Recv(&local_slice, local_size * local_size, MPI_INT, 0, 1, MPI_COMM_WORLD, &mpi_status);
for (i = 0; i < local_size; i++)
{
for (j = 0; j < local_size; j++)
{
printf("local_slice[%d][%d]: %d\n", i, j, local_slice[i][j]);
}
}
}
MPI_Finalize();
return 0;
}
Can someone explain how to properly pass this type of array between MPI Processes please?
It looks like you need to change the first argument to MPI_Send from &slice to slice[0] and do the same for MPI_Recv.
I'm doing some matrix multiplication in C with MPI.
It works fine until I try to go above 15x15 and I cant figure out why...
From what I've noticed the error seems to mostly happen after I see a "Process # sending..." print, which happens when the slave processes are sending their data back to the master process.
Error message:
[LEC-B125N4J:12183] *** Process received signal ***
[LEC-B125N4J:12183] Signal: Segmentation fault (11)
[LEC-B125N4J:12183] Signal code: Address not mapped (1)
Code:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <mpi.h>
//#define DIM 1000
#define DIM 15
/*
* Statically allocate the matrices to make the rows
* sequentially placed in memory. (This eases the task
* of distributing the problem among the slaves.)
* Make the matrices global to allow for larger
* dimensions.
*/
int A[DIM][DIM];
int B[DIM][DIM];
int C[DIM][DIM];
int D[DIM][DIM];
int correct_result(int A[DIM][DIM], int B[DIM][DIM])
{
int i,j;
for (i=0; i<DIM; ++i)
for (j=0; j<DIM; ++j)
if (A[i][j] != B[i][j])
return 0;
return 1;
}
int main (argc, argv)
int argc;
char *argv[];
{
int rank=0, size;
int i, j, k;
int time1;
volatile int tmp;
int iOffset = 0;
int iProblemSize = 0;
MPI_Init(&argc, &argv); /* starts MPI */
MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* get current process id */
MPI_Comm_size(MPI_COMM_WORLD, &size); /* get number of processes */
iProblemSize = (DIM / (size - 1));
if(rank == 0) { //Master
printf("Number of processes: %d (1 Master and %d slaves) - DIM: %d\n", size, (size - 1), DIM);
//Fill matrices A and B with random numbers
srand(timer(NULL));
for(i=0; i<DIM; ++i)
{
for (j=0; j<DIM; ++j)
{
A[i][j] = random() % 100 - 50;
B[i][j] = random() % 100 - 50;
C[i][j] = 0;
}
}
}
MPI_Bcast(B, (DIM * DIM), MPI_INT, 0, MPI_COMM_WORLD);
if(rank == 0) { //Master
/* Calculate the true answer */
for (i=0; i<DIM; ++i)
for (k=0; k<DIM; ++k)
for (j=0; j<DIM; ++j)
D[i][j] += A[i][k] * B[k][j];
time1 = timer();
//Send pieces of A to the slaves
iOffset = 0;
for(i = 1; i < size; i++) {
MPI_Send(A[iOffset], (iProblemSize * DIM), MPI_INT, i, 0, MPI_COMM_WORLD);
iOffset += iProblemSize;
/*for(j = 0; j < iProblemSize; j++) {
MPI_Send(A[iOffset + j], DIM, MPI_INT, i, 0, MPI_COMM_WORLD);
}
iOffset += iProblemSize;*/
}
//Take care of leftovers if needed (if uneven number of slaves)
if((size - 1) % DIM != 0) {
for(i = iOffset; i < DIM; i++) {
for(k = 0; k < DIM; k++) {
for(j = 0; j < DIM; j++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
}
//Gather the results from the slaves
iOffset = 0;
for(i = 1; i < size; i++) {
MPI_Recv(C[iOffset], (iProblemSize * DIM), MPI_INT, i, 0, MPI_COMM_WORLD, NULL);
iOffset += iProblemSize;
printf("Received from %d!\n", i);
}
printf("All received!\n");
/* Error checking */
time1 = timer() - time1;
printf ("Your calculation is %scorrect.\n", correct_result(C,D) ? "" : "not ");
printf ("Total runtime: %f seconds\n", time1/1000000.0);
}
else { //Slaves
MPI_Recv(A, (iProblemSize * DIM), MPI_INT, 0, 0, MPI_COMM_WORLD, NULL);
/*for(j = 0; j < iProblemSize; j++) {
MPI_Recv(A[j], DIM, MPI_INT, 0, 0, MPI_COMM_WORLD, NULL);
}*/
//Do the calculations for C
//printf("Process %d doing calculations...\n", rank);
for (i = 0; i < (iProblemSize * DIM); ++i) {
for (k = 0; k < DIM; ++k) {
for (j = 0; j < DIM; ++j) {
C[i][j] += A[i][k] * B[k][j];
}
//printf("\n");
}
}
//printf("Process %d finished doing the calculations!\n", rank);
//Send the result to the master
printf("Process %d sending...\n", rank);
MPI_Send(C, (iProblemSize * DIM), MPI_INT, 0, 0, MPI_COMM_WORLD);
printf("Process %d finished sending!\n", rank);
}
MPI_Finalize();
return 0;
}
OK I finally fixed the error.
The problem was in the loop when the slaves are doing the calculations...
for (i = 0; i < (iProblemSize * DIM); ++i) {
should be
for (i = 0; i < iProblemSize; ++i) {
:)