MPI program segmentation error

I am writing a program with C ++ that uses MPI. A simplified version of my code

#include <iostream> #include <fstream> #include <cstdlib> #include <mpi.h> #define RNumber 3000000 //Number of loops to go using namespace std; class LObject { /*Something here*/ public: void FillArray(long * RawT){ /*Does something*/ for (int i = 0; i < RNumber; i++){ RawT[i] = i; } } }; int main() { int my_rank; int comm_sz; MPI_Init(NULL, NULL); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); MPI_Comm_size(MPI_COMM_WORLD, &comm_sz); LObject System; long rawT[RNumber]; long * Times = NULL; if (my_rank == 0) Times = (long*) malloc(comm_sz*RNumber*sizeof(long)); System.FillArray(rawT); if (my_rank == 0) { MPI_Gather(rawT, RNumber, MPI_LONG, Times, RNumber, MPI_LONG, 0, MPI_COMM_WORLD); } else { MPI_Gather(rawT, RNumber, MPI_LONG, Times, RNumber, MPI_LONG, 0, MPI_COMM_WORLD); } MPI_Finalize(); return 0; }; 

The program compiles fine, but when the error occurs, segmentation errors. Message

 ================================================================================= = BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES = EXIT CODE: 11 = CLEANING UP REMAINING PROCESSES = YOU CAN IGNORE THE BELOW CLEANUP MESSAGES ================================================================================= APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault (signal 11) 

When I decrease RNumber , the program works fine. Maybe someone can explain what exactly is going wrong? Am I trying to allocate too much space for an array? If this happens, will this problem be solved by storing the results in a file instead of an array?

If possible, could you give broad comments on what I am doing wrong.

Thank you for your time and effort!

+4
source share
3 answers

Some possible problems:

 long rawT[RNumber]; 

It is rather a large array to put on the stack. Usually there is a limit on the size of the stack (especially in a multi-threaded program), and the typical size is one or two megabytes. You will be better off with std::vector<long> here.

 Times = (long*) malloc(comm_sz*RNumber*sizeof(long)); 

You must ensure that the memory allocation is successful. Or even better, use std::vector<long> (which will also eliminate memory leak).

 if (my_rank == 0) { // do stuff } else { // do exactly the same stuff } 

I assume the else block should do something else; in particular, something that is not related to Times , since this value is null if my_rank == 0 .

UPDATE: use a vector instead of a raw array, just initialize it with the desired size, and then use a pointer to the first element in which you would use a (pointer to) array:

 std::vector<long> rawT(RNumber); System.FillArray(&rawT[0]); std::vector<long> Times(comm_sz*RNumber); MPI_Gather(&rawT[0], RNumber, MPI_LONG, &Times[0], RNumber, MPI_LONG, 0, MPI_COMM_WORLD); 

Remember that the pointer will be invalid if you resize the vector (although you do not need to do this if you just use it as a replacement for the array).

+2
source

You can check what returns with

 MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); MPI_Comm_size(MPI_COMM_WORLD, &comm_sz); 

eg. comm_sz==0 may cause this problem.

+1
source

You do not check the return value from malloc . Given that you are trying to allocate more than three million lengths, it is likely that malloc will fail.

Perhaps this is not what causes your problem.

0
source

Source: https://habr.com/ru/post/1380130/


All Articles