-1

I have seen many similar threads here, but the problem with me, is, that my program actually runs for different settings.

For example: when my matrix is 1024x1024

For 2 cores : Error 11

For 4, 8, 16 etc works fine.

Matrix 2048x2048:

For any core setting : Error 11.

I don't understand why this happens, each process is taking a 2048/(total processes) X 2028 matrix to calculate. And it should be working correctly.

This is how i declare my matrix:

int temp[wp][hp];

For receive:

rc = MPI_Recv(&temp[0][0], wp*hp, MPI_INT, i, tag, MPI_COMM_WORLD, &status);

And for send:

 rc = MPI_Send(&temp[0][0], wp*hp, MPI_INT, 0, tag, MPI_COMM_WORLD);

I don't get it, it should be working. Do you think it is perhaps a memory issue and not pointer related?

Mpk Roes
  • 3
  • 3
  • 1
    C and C++ are two different languages. If `wp` and / or `hp` are variables, this: `int temp[wp][hp];` is not legal C++. – PaulMcKenzie Feb 07 '17 at 22:16
  • 3
    Also, `2048 * 2048 * sizeof(int)` -- Consider what that equates to, and whether your array is declared locally or globally. If it's local. you may be blowing out the stack. – PaulMcKenzie Feb 07 '17 at 22:24
  • 1
    @PaulMcKenzie It is C, you are correct. I am not quite sure what you mean by globally or locally. ``temp``It is declared inside main() and it accessible to every process; this matrix should be 256x2048 if we had 8 processes. The final matrix called ``im`` and it is 2048x2048, also accessible to every process but in fact only the master process will use it in the end. – Mpk Roes Feb 07 '17 at 22:30
  • *tempIt is declared inside main()* -- Well, that is probably the issue. You're declaring the array locally, thus uses stack space. I doubt you have 16 megabytes of stack space. Instead use dynamic allocation (such as `malloc`). – PaulMcKenzie Feb 07 '17 at 22:32
  • @PaulMcKenzie Okay, I am new to C (I even thought it was the same with C++) I am more into java,python & matlab so I am having a bit hard time to grasp this. Should i allocate some space outside main() or something (how)? – Mpk Roes Feb 07 '17 at 22:36
  • The C program uses the stack to store local variables, and the stack is limited in size (1 megabytes to 8 megabytes, usually). If the number of bytes that your local variables takes up exceeds the stack space, you will get either a runtime error, or if the compiler is smart, the compiler may give an error. The answer given is the way you dynamically allocate memory using `malloc`, thus the memory comes from the heap, not the stack. [Possible duplicate](http://stackoverflow.com/questions/12762944/segmentation-fault-11) – PaulMcKenzie Feb 07 '17 at 22:40

3 Answers3

3

I would create the array with malloc

int *temp =(int*)malloc(wp * hp * sizeof(int));

then I would change the other lines to

rc = MPI_Recv(temp, wp*hp, MPI_INT, i, tag, MPI_COMM_WORLD, &status);

and

rc = MPI_Send(temp, wp*hp, MPI_INT, 0, tag, MPI_COMM_WORLD);

and when I'm done with the array, I free it.

free(temp)

Like one of the commenters already stated, allocating the array your way is not legal c++.

Edit:

if you want to access to array twodimensional, here is the pattern for that:

temp[rowToAccess * numberOfColumns + columnToAcess]
Alex
  • 779
  • 7
  • 15
  • Thanks for the input! I am getting this now: ``error: subscripted value is not an array, pointer, or vector`` ``im[k][l]=temp[cnt][l];`` – Mpk Roes Feb 07 '17 at 22:51
  • 1
    @MpkRoes The problem is that you're using 2 dimensional array syntax to access basically a 1 dimensional "array" (it's not actually an array, but let's call it that for arguments sake). So you have to create the 2D array dynamically if you want to keep the `[ ][ ]` syntax, and that is where a good `C` book is better than a quick answer on a programming board. – PaulMcKenzie Feb 07 '17 at 23:01
  • 1
    @MpkRoes - The answer given is basically right. The only issue is that you need to use `malloc` in a way to create a 2D array so that you use the 2D array syntax `[][]`. I posted an answer if you're interested. – PaulMcKenzie Feb 07 '17 at 23:12
0

The answer given is basically a rundown of the issue -- you are more than likely using up the stack space to store the array, and thus exhausting the memory reserved for the stack.

Thus the solution is to create the array dynamically.

Here is an example of creating a 2D array dynamically:

#include <stdlib.h>
//...
int** create2DArray(unsigned nrows, unsigned ncols)
{
   unsigned i;
   int** ptr = malloc(nrows * sizeof(int*));  // allocate pointers to rows
   if ( ptr != NULL )
   { 
       int* pool = malloc(nrows * ncols * sizeof(int)); // allocate pool of memory
       if ( pool != NULL )
       {
           for (i = 0; i < nrows; ++i, pool += ncols )
               ptr[i] = pool;  // point the row pointers into the pool
       }
       else
       { 
          free(ptr);  
          ptr = NULL;
       }
   }
   return ptr;
}

void delete2DArray(int** arr)
{
   free(arr[0]);  // remove the pool
   free(arr);     // remove the pointers
}

int main()
{ 
   int **temp = create2DArray(2048, 2048); 
   if ( temp != NULL )
   {
       temp[0][0] = 10;  // for example you can use it like a 2D array
       delete2DArray(temp);  // free the memory
   }
}

This will create in essence, a contiguous 2D array, similar to the one you attempted to create using int temp[2048][2048], but this time, the memory is obtained from the heap, not the stack.

Note you can use the [][] syntax, just like a 2 dimensional array.

I won't go into detail to how it works, however it is simple enough to follow the logic.

PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45
  • Hmmm, would it be nice C tactic to allocate all my arrays like this? – Mpk Roes Feb 07 '17 at 23:14
  • If your arrays are not large and the dimensions are known at compile-time, then I wouldn't recommend doing this, as you have the issue of making sure you `free()` the memory, else you get a memory leak. Only when you need to create an array dynamically should you do so. The reasons being -- 1) The size of the array is unknown until runtime or 2) the array is too large for the stack. – PaulMcKenzie Feb 07 '17 at 23:17
  • I did all my matrixes like this. It compiles. I use ``send`` and ``recv`` as in my original post, otherwise I am getting every kind of error. The computations are not correct though. No idea what is going on. – Mpk Roes Feb 07 '17 at 23:27
0

So these were the problems:

1) As indicated by @PaulMcKenzie and @Alex, I had to dynamically allocate memory. Now the problem was that If i used

rc = MPI_Send(temp, wp*hp, MPI_INT, 0, tag, MPI_COMM_WORLD);

or

rc = MPI_Recv(temp, wp*hp, MPI_INT, i, tag, MPI_COMM_WORLD, &status);

as @Alex suggested, then, my program would crash for some reason. So my initial &temp[0][0] was correct.

2) The second problem, was, that I was saving this array using fwrite but when u have dynamical arrays you need to do it like this:

for (int i = 0; i < w; i++){
for (int j = 0; j < h; j++){
    fwrite(&im[i][j], sizeof(int), 1, yourfilename);
}
} 

Cheers everyone

Mpk Roes
  • 3
  • 3