I’ve defined my own structure withing my custom fix_my.h
…
protected:
struct teststruct{
…
double** testarr;
…
}testvar;
…
in fix_my.cpp Proc 0 then reads a file and fills the 2d-array testarr which was created malloc or memory->create(…). Doesn’t matter.
Now something very strange happens.
After I’ve read the file and filled the array I’m using
MPI_Bcast(&(testvar->testarr[0][0]),rows*cols,MPI_DOUBLE,0,world);
to send the data to all the procs.
Then if I try to modify the array e.g.
testvar->testarr[0][0]=0.0;
I get a Segmentation error. If I comment the MPI_Bcast, manipulation of the array works perfectly fine.
Even more strange: If I create a completely unrelated array “double random[10][10]” and Bcast this one, the same segmentation-error occurs if I try to manipulate testarr.
It seems like MPI_Bcast somehow deletes the memory allocated for all my data which is allocated for my struct.
Any idea why this happens?
Issue resolved.
Seems like lammps doesn’t like structure definitions within the class definition. I just placed the structure outside. Don’t know why, but it works.
Frank,
It can only work by accident. Your MPI call is wrong. You seem to misunderstand how data structures in C/C++ work. There should be no difference where the struct is defined.
If you want to broadcast the content of of the 2d array in one go, you must use memory->create(), because that guarantees that all content is stored consecutively in address space.
Axel
While I don’t see your whole code so I can’t know for sure; I’m confused at your use of testvar-> to dereference a structure pointer when your example shows testvar is the structure itself. Hence id expect to see MPI_Bcast(&(testvar.testarr[0][0]),rows*cols,MPI_DOUBLE,0,world); with the member access operator “.”
Well, Im using “->” because the function which does the Bcast looks something like this:
int MyFix::myfun(struct Mystruct *tmp, …)
{
…
}
so it requires a pointer.
Maybe that’s causing the problem.
However, is it really that much of a deal if I allocate the memory “manually” with malloc instead of using memory->create(…).
This seems not to be a problem in my stand-alone code which I’ve tested thoroughly before implementing into lammps.
If I was a betting man I’d say something in your code is causing undefined behavior. You should compile with warnings and try it on another system with mpi to see if the behavior is exactly the same or weirder.
You should also make sure that every task reaches your Bcast call; also I’m not sure if Bcast returns the same address to the input pointer as the one you put in, this might effect your code since you passed the pointer by value and it can obtain a different address than the pointer that was passed if thats the case. Someone more experienced might be able to comment with certainty on that since I can’t find an answer online.
I agreed to allocate the memory using “memory->create(…)” and now everything works fine. I still don’t understand why it makes such a difference but for now I’m happy it works at all.
Thanks for your suggestions, I really appreciate.
ah, I was under the impression your program failed even when using memory->create; the reason is memory->create establishes a 1D version of your 2D array that is aligned. If you malloc your 2D array in the conventional way, allocating array of pointers then allocating each pointer in the array, there is no guarantee of alignment. Since you only passed the first pointer type location &(array[0][0]) to MPI_Bcast and the size of the array is column*row, MPI Bcast just treats it as a 1D array; which is consistent with memory->create but not the malloc scheme.
oooh jeez… I’m doing this same mistake over and over again…Thx for pointing this out.