35#define MPICH_IGNORE_CXX_SEEK
42#include "MultiPoolSample.h"
44#ifdef HAVE_MPI_THREADS
48void mpi_send_paket_signal(
Signal* pSig,
int CoilID);
49void mpi_recv_paket_signal(
Signal* pSig,
int SlaveID,
int CoilID);
52inline MPI_Datatype MPIspindata () {
56 MPI_Datatype MPI_SPINDATA ;
57 MPI_Datatype type = MPI_DOUBLE;
60 MPI_Type_struct( 1, &NUM_DATA, &disp, &type, &MPI_SPINDATA);
62 MPI_Type_create_struct( 1, &NUM_DATA, &disp, &type, &MPI_SPINDATA);
64 MPI_Type_commit( &MPI_SPINDATA);
72#ifdef HAVE_MPI_THREADS
75void* CountProgress(
void * arg) {
77 int TotalNoSpins = *((
int *) arg);
78 int SpinsDone = TotalNoSpins - *(((
int *) arg )+1);
80 int progress_percent = -1;
81 static string bars =
"***************************************************";
82 static string blancs =
" ";
86 while (SpinsDone != TotalNoSpins) {
87 MPI_Recv(&NowDone,1,MPI_INT,MPI_ANY_SOURCE,SPINS_PROGRESS,MPI_COMM_WORLD,&status);
91 int progr = (100*(SpinsDone+1)/TotalNoSpins);
92 if ( progr != progress_percent) {
93 progress_percent = progr;
94 ofstream fout(
".jemris_progress.out" , ios::out);
98 cout <<
"\rSimulating | ";
99 cout << bars.substr(0, progr/2) <<
" " << blancs.substr(0, 50-progr/2) <<
"| " <<setw(3) << setfill(
' ') << progr <<
"% done";
114#ifdef HAVE_MPI_THREADS
116 pthread_t counter_thread;
123 errcode=pthread_create(&counter_thread,
129 cout <<
"thread creation failed !! exit."<< endl;
136 std::string hm (MPI_MAX_PROCESSOR_NAME,
' ');
138 MPI_Comm_size(MPI_COMM_WORLD, &size);
139 MPI_Get_processor_name(&hm[0], &ilen);
141 cout << endl << hm.c_str() <<
" -> Master Process: send MR sample (" << pSam->
GetSize()
142 <<
" spins) to " << size-1 <<
" slave(s)"<< endl << endl << flush;
144 std::vector<int> sendcount (size);
145 std::vector<int> displs (size);
147 double* recvdummy = 0;
156 MPI_Scatter (sendcount.data(), 1, MPI_INT, &recvbuf, 1, MPI_INT, 0, MPI_COMM_WORLD);
167 long TotalSpinNumber=pSam->
GetSize(),nextSpinMem=-1;
168 for(ii=0;ii<size;ii++)
172 MPI_Send(&TotalSpinNumber,1,MPI_LONG,ii,SEND_TOTAL_NO_SPINS,MPI_COMM_WORLD);
173 MPI_Send(&displs[ii],1,MPI_LONG,ii,SEND_BEGIN_SPIN,MPI_COMM_WORLD);
182 MPI_Bcast (&NProps, 1, MPI_LONG, 0, MPI_COMM_WORLD);
184 long hsize = pSam->GetHelperSize();
185 MPI_Bcast (&hsize, 1, MPI_LONG, 0, MPI_COMM_WORLD);
186 MPI_Bcast (pSam->GetHelper(), hsize, MPI_DOUBLE, 0, MPI_COMM_WORLD);
189 MPI_Bcast (&dsize, 1, MPI_LONG, 0, MPI_COMM_WORLD);
190 MPI_Bcast (&(pSam->
GetSampleDims()[0]), dsize, MPI_INT, 0, MPI_COMM_WORLD);
192 int csize = pSam->GetNoSpinCompartments();
193 MPI_Bcast (&csize , 1, MPI_INT, 0, MPI_COMM_WORLD);
195 MPI_Datatype MPI_SPINDATA = MPIspindata();
198 MPI_Scatterv (pSam->
GetSpinsData(), sendcount.data(), displs.data(),
199 MPI_SPINDATA, &recvdummy, 0, MPI_SPINDATA, 0, MPI_COMM_WORLD);
201 MPI_Bcast (pSam->
GetResolution(),3,MPI_DOUBLE,0, MPI_COMM_WORLD);
205 while (SlavesDone < size - 1) {
211 MPI_Recv(&SlaveID, 1, MPI_INT, MPI_ANY_SOURCE,
212 REQUEST_SPINS, MPI_COMM_WORLD, &status);
219 for(ii=0;ii<size;ii++)
222 if(ii>0 && NextSpinToSend!=nextSpinMem) {
223 MPI_Send(&NextSpinToSend,1,MPI_LONG,SlaveID,SEND_BEGIN_SPIN,MPI_COMM_WORLD);
225 nextSpinMem=NextSpinToSend;
226 if(nextSpinMem<0) nextSpinMem-=1;
237 for (
unsigned int i=0; i < RxCA->
GetSize(); i++)
244 MPI_Send(&NoSpins,1,MPI_INT,SlaveID,SEND_NO_SPINS, MPI_COMM_WORLD);
247 NoSpins, MPI_SPINDATA,SlaveID,SEND_SAMPLE, MPI_COMM_WORLD);
249#ifndef HAVE_MPI_THREADS
252 static int progress_percent = -1;
253 static int spinsdone = 0;
254 spinsdone += sendcount[SlaveID];
255 sendcount[SlaveID] = NoSpins;
261 if (SlavesDone==(size-1)) progr=100;
263 if (progr != progress_percent) {
264 progress_percent = progr;
265 ofstream fout(
".jemris_progress.out" , ios::out);
275#ifdef HAVE_MPI_THREADS
278 errcode = pthread_join(counter_thread,(
void **) &status);
280 cout <<
"Joining of threads failed! (so what... ;) )"<<endl;
295Sample* mpi_receive_sample(
int sender,
int tag){
302 MPI_Scatter(NULL,1,MPI_INT,&nospins,1,MPI_INT,0, MPI_COMM_WORLD);
305 long TotalSpinNumber=0,beginTraj=0;
308 MPI_Recv(&TotalSpinNumber,1,MPI_LONG,0,SEND_TOTAL_NO_SPINS,MPI_COMM_WORLD,&status);
309 MPI_Recv(&beginTraj,1,MPI_LONG,0,SEND_BEGIN_SPIN,MPI_COMM_WORLD,&status);
311 int num_traj=beginTraj;
315 NPoints= (long) nospins;
318 MPI_Bcast (&NProps,1,MPI_LONG,0, MPI_COMM_WORLD);
326 MPI_Bcast (&hsize, 1, MPI_LONG,0, MPI_COMM_WORLD);
327 pSam->CreateHelper(hsize);
329 MPI_Bcast (pSam->GetHelper(),(
int)hsize,MPI_DOUBLE,0, MPI_COMM_WORLD);
331 pSam->GetHelper( pW->
Helper() );
334 MPI_Bcast (&dsize, 1, MPI_LONG,0, MPI_COMM_WORLD);
335 pSam->CreateDims(dsize);
337 MPI_Bcast (&(pSam->
GetSampleDims()[0]),(
int)dsize,MPI_INT,0, MPI_COMM_WORLD);
339 MPI_Bcast (&csize, 1, MPI_INT,0, MPI_COMM_WORLD);
340 pSam->SetNoSpinCompartments(csize);
344 MPI_Datatype MPI_SPINDATA = MPIspindata();
346 MPI_Scatterv (NULL,NULL,NULL,MPI_SPINDATA,pSam->
GetSpinsData(),nospins,MPI_SPINDATA,0, MPI_COMM_WORLD);
348 MPI_Bcast (pSam->
GetResolution(),3,MPI_DOUBLE,0, MPI_COMM_WORLD);
350 int ilen; std::string hm (MPI_MAX_PROCESSOR_NAME,
' ');
351 MPI_Get_processor_name(&hm[0],&ilen);
376 MPI_Send(&myRank,1,MPI_INT,0,REQUEST_SPINS,MPI_COMM_WORLD);
379 for (
unsigned int i=0; i < RxCA->
GetSize(); i++)
384 MPI_Recv(&NoSpins,1,MPI_INT,0,SEND_NO_SPINS,MPI_COMM_WORLD,&status);
390 MPI_Recv(&beginTraj,1,MPI_LONG,0,SEND_BEGIN_SPIN,MPI_COMM_WORLD,&status);
396 if (NoSpins == 0)
return false;
406 MPI_Datatype MPI_SPINDATA = MPIspindata();
407 MPI_Recv(samp->
GetSpinsData(),NoSpins,MPI_SPINDATA,0,SEND_SAMPLE,MPI_COMM_WORLD,&status);
408 int ilen; std::string hm (MPI_MAX_PROCESSOR_NAME,
' ');
409 MPI_Get_processor_name(&hm[0],&ilen);
424void mpi_send_paket_signal (
Signal* pSig,
const int CoilID) {
426 int tsize = (int) pSig->
Repo()->
Size();
429 MPI_Send(pSig->
Repo()->
Times(), (int) pSig->
Repo()->
Samples(), MPI_DOUBLE, 0, SIG_TP + (CoilID)*4,MPI_COMM_WORLD);
431 MPI_Send(pSig->
Repo()->
Data(), tsize, MPI_DOUBLE, 0, SIG_MX + (CoilID)*4,MPI_COMM_WORLD);
437void mpi_recv_paket_signal(
Signal *pSig,
const int SlaveId,
const int CoilID) {
439 int tsize = (int) pSig->
Repo()->
Size();
440 double* data = pSig->
Repo()->
Data();
441 std::vector<double> tmp (tsize);
445 MPI_Recv(pSig->
Repo()->
Times(), (
int) pSig->
Repo()->
Samples(), MPI_DOUBLE, SlaveId, SIG_TP + (CoilID)*4,MPI_COMM_WORLD,&status);
447 MPI_Recv(&tmp[0], tsize, MPI_DOUBLE, SlaveId, SIG_MX + (CoilID)*4,MPI_COMM_WORLD,&status);
449 for (
int i = 0; i < tsize; i++)
Implementation of JEMRIS Declarations.
Implementation of JEMRIS Sample.
Implementation of JEMRIS Signal.
Coil configuration and sensitivities.
Definition CoilArray.h:40
unsigned int GetSize()
Get the number of channels.
Definition CoilArray.h:93
Coil * GetCoil(unsigned channel)
Get a particular coil.
Definition CoilArray.cpp:390
Signal * GetSignal()
Get the received signal of this coil.
Definition Coil.h:116
The Sample is the object to simulate. It contains the spins.
Definition Sample.h:301
double * GetResolution()
Get grid resolution.
Definition Sample.h:417
void CreateSpins(const size_t size)
create the spin structure
Definition Sample.cpp:88
vector< size_t > GetSampleDims() const
Definition Sample.h:378
void ClearSpins()
delete the spin structure
Definition Sample.cpp:80
void SetSampleDims(vector< size_t > d)
Definition Sample.h:385
int SpinsLeft()
Returns No spins which still needs to be calculated.
Definition Sample.cpp:582
const int GetSampleDimsSize() const
Dimensions.
Definition Sample.h:392
double * GetSpinsData()
Definition Sample.h:462
void DumpRestartInfo(CoilArray *RxCA)
Utility function for restart: dump information to restart jemris after crash.
Definition Sample.cpp:522
size_t GetSize() const
Definition Sample.cpp:320
void GetScatterVectors(int *sendcount, int *displ, int size)
utility function to send sample in parallel mode: initial samples are send via mpi_scatterv; get need...
Definition Sample.cpp:366
void GetNextPacket(int &noSpins, int &NextSpinToSend, int SlaveId)
utility function to send sample in parallel mode: get next spin packet to be sent....
Definition Sample.cpp:458
size_t GetNProps() const
Definition Sample.h:371
The signal store and IO.
Definition Signal.h:249
Repository * Repo()
Definition Signal.h:306
Singleton with information about the simulation of the current spin.
Definition World.h:51
void InitHelper(long size)
Initilize helper array.
Definition World.cpp:127
long TotalSpinNumber
Total number of spins.
Definition World.h:163
void setTrajLoading(int firstSpin, int paketSize)
Set trajectory parameters for MPI current sample paket.
Definition World.h:71
int GetNoOfSpinProps()
Get number of spin properties.
Definition World.h:113
double * Helper()
Reference to helper array.
Definition World.h:119
int m_myRank
MPI rank of this process. if m_myRank<0 process is serial jemris.
Definition World.h:188
static World * instance()
Get sole instance of the sequence tree.
Definition World.cpp:34
void SetNoOfSpinProps(int n)
Set number of spinproperties.
Definition World.cpp:109
bool mpi_recieve_sample_paket(Sample *samp, CoilArray *RxCA)
Definition mpi_Model.h:366
long Size()
Size of bulk data (i.e. number of elemments of m_data)
Definition Signal.h:71
double * Data()
Reference to data repository.
Definition Signal.h:83
const long Samples() const
Number of samples.
Definition Signal.h:107
double * Times()
Reference to time point repository.
Definition Signal.h:95