C++ mpi module for stochmagnet_main Package
SMOMPI_PackedBlockSymmetricMatrix.hpp
1 #ifndef SMOMPI_PackedBlockSymmetricMatrix_HPP
2 #define SMOMPI_PackedBlockSymmetricMatrix_HPP
3 
4 #include "MPI_Run.h"
5 #include "MPI_WorldToWorldMessage.h"
6 
7 template<typename T,tUCInt P>
9 
10  const tIndex &N=this->getRowBlocksNumber();
11 
12  //vY=0
13  memset(vY,0,sizeof(T)*P*N);
14 
15  //MPI environment
17 
18  //current id of the MPI core
19  const tMPICoreId& coreId=mpiEnv.getCoreId();
20 
21  //number of MPI cores
22  const tMPICoreId& coresNumber=mpiEnv.getCoresNumber();
23 
24  std::valarray<int> valuesLengthPerCore;
25  valuesLengthPerCore.resize(coresNumber);
26 
27  std::valarray<int> valuesOffset;
28  valuesOffset.resize(coresNumber);
29 
30  //start index for diagonal values
31  tIndex start=coreId*N/coresNumber;
32 
33  //end index for diagonal values
34  tIndex end=(coreId+1)*N/coresNumber;
35 
36  //diagonla values
37  const T* vD=&this->getDiagonalValues()[0];
38 
39  //iterator on block
40  const T* vB=&this->getSupBlocksValues()[0];
41 
42 
43 
44 
45  //work indices of element in block of size PxP
46  //tUCInt i=0,j=0;
47  //tUCInt incB=0;//increment on block
48  //const T* iXj=null;//iterator of Xj inside block
49 
50  //iterator on X
51  const T* Xj=0;
52 
53 
54  //indices of block
55  tIndex ib=0,jb=0;
56 
57  //iterator on diagonal values
58  const T* Di=&vD[start];
59 
60  //iterator on block
61  const T* Bij=&vB[(start==0)?0:SM_PackedBlockSymmetricMatrix<T,P>::GetBlockIndex(0,start)];
62 
63  //block at row 0 and column ib
64  const T* B0i=Bij;
65 
66  //increment of block for next column
67  tIndex incBij=0;
68 
69 
70  //Y values at block start
71  T* Yi_d,*Yi=&vY[start*P];
72  T* eYi=Yi;eYi+=P;
73 
74  //work pointers
75  T* w1,*w2,*w3,*w4;
76 
77  for (ib=start;ib<end;ib++) {//row index of the block in [start,end[
78 
79 
80  //Yi+=Bij.Xj
81  Xj=vX;
82 
83  //Yi_x=&Yi[0];
84  //Yi_y=&Yi[1];
85  //Yi_z=&Yi[2];
86 
87  Bij=B0i;
88  for (jb=0;jb<ib;jb++) {//column index of the block
89 
90  //Block product Yi + =B_ij . X_j
91  //BlockVectorProduct(Bij,Xj,Yi,
92  // i,j,incB,iXj);
93  //Xj_x=Xj[0];
94  //Xj_y=Xj[1];
95  //Xj_z=Xj[2];
96  //BlockVectorProduct(Bij,Xj_x,Xj_y,Xj_z,*Yi_x,*Yi_y,*Yi_z);
97 
99 
100  //iterators at block at next row
102 
103  Xj+=P;
104 
105  }//end loop on column index < i index
106 
107 
108  //diagonal term
109  //jb=ib Yi+=Di.Xi
110  Yi_d=Yi;
111  while (Yi_d!=eYi) {
112  (*Yi_d)+=(*Di)*(*Xj);
113  Yi_d++;
114  Xj++;
115  }
116  Di++;
117 
118  //jb>ib : jb=ib+1;
119  jb=ib;jb++;
120  //block for next column
121  B0i=Bij;
122  //jb-th block of next colum
123  incBij=ib;
125  Bij+=incBij;
126  while (jb<N) {//column index of the block
127 
128  //Block product
129 
131 
132 
133  //next block for X
134  Xj+=P;
135 
136  //iterators to block at next column +=jb*BLOCK_SIZE
138  Bij+=incBij;
139 
140  //next column
141  jb++;
142  }//end loop on column index >= i index
143 
144  //Yi at next row block
145  Yi=eYi;
146  eYi+=P;
147 
148  }//end loop on row index
149 
150  //dispatch all values
151  MPI_WorldToWorldMessage::AllGather(mpiEnv,(int)(end-start)*P,valuesLengthPerCore);
152  MPI_WorldToWorldMessage::BuildOffset(valuesLengthPerCore,valuesOffset);
153 
154  MPI_WorldToWorldMessage::AllGather(mpiEnv,&vY[start*P],valuesLengthPerCore[coreId],
155  &vY[0],valuesLengthPerCore,valuesOffset);
156 
157 }
158 
159 
160 
161 template<typename T,tUCInt P>
162 void SMOMPI_PackedBlockSymmetricMatrix<T,P>::vectorProduct3D(const T* vX,T* vY ) const {
163 
164  const tIndex &N=this->getRowBlocksNumber();
165 
166  //vY=0
167  memset(vY,0,sizeof(T)*P*N);
168 
169 
170  //MPI environment
172 
173  //current id of the MPI core
174  const tMPICoreId& coreId=mpiEnv.getCoreId();
175 
176  //number of MPI cores
177  const tMPICoreId& coresNumber=mpiEnv.getCoresNumber();
178 
179  std::valarray<int> valuesLengthPerCore;
180  valuesLengthPerCore.resize(coresNumber);
181  std::valarray<int> valuesOffset;
182  valuesOffset.resize(coresNumber);
183 
184  //start index for diagonal values
185  tIndex start=coreId*N/coresNumber;
186 
187  //end index for diagonal values
188  tIndex end=(coreId+1)*N/coresNumber;
189 
190  //diagonal values
191  const T* vD=&this->getDiagonalValues()[0];
192 
193  //iterator on block
194  const T* vB=&this->getSupBlocksValues()[0];
195 
196 
197 
198 
199 
200  //work indices of element in block of size PxP
201  //tUCInt i=0,j=0;
202  //tUCInt incB=0;//increment on block
203  //const T* iXj=null;//iterator of Xj inside block
204 
205  //iterator on X
206  const T* Xj=0;
207 
208 
209  //indices of block
210  tIndex ib=0,jb=0;
211 
212  //iterator on diagonal values
213  const T* Di=&vD[start];
214 
215  //iterator on block
216  const T* Bij=&vB[(start==0)?0:SM_PackedBlockSymmetricMatrix<T,P>::GetBlockIndex(0,start)];
217 
218  //block at row 0 and column ib
219  const T* B0i=Bij;
220 
221  //increment of block for next column
222  tIndex incBij=0;
223 
224  //iterator on Yi at coordinate d
225  //T* Yi_d=null;
226 
227  //Y values at block start
228  T* Yi=&vY[start*P];
229 
230  tReal Xj_x,Xj_y,Xj_z;
231  tReal *Yi_x,*Yi_y,*Yi_z;
232  for (ib=start;ib<end;ib++) {//row index of the block in [start,end[
233 
234 
235  //Yi+=Bij.Xj
236  Xj=vX;
237 
238  Yi_x=&Yi[0];
239  Yi_y=&Yi[1];
240  Yi_z=&Yi[2];
241 
242  Bij=B0i;
243  for (jb=0;jb<ib;jb++) {//column index of the block
244 
245  //Block product Yi + =B_ij . X_j
246  //BlockVectorProduct(Bij,Xj,Yi,
247  // i,j,incB,iXj);
248  Xj_x=Xj[0];
249  Xj_y=Xj[1];
250  Xj_z=Xj[2];
251 
252  //Bij[0]
253  (*Yi_x)+=(*Bij)*Xj_x;
254  Bij++;
255 
256  //Bij[1]
257  (*Yi_x)+=(*Bij)*Xj_y;
258  (*Yi_y)+=(*Bij)*Xj_x;
259  Bij++;
260 
261  //Bij[2]
262  (*Yi_y)+=(*Bij)*Xj_y;
263  Bij++;
264 
265  //Bij[3]
266  (*Yi_x)+=(*Bij)*Xj_z;
267  (*Yi_z)+=(*Bij)*Xj_x;
268  Bij++;
269 
270  //Bij[4]
271  (*Yi_y)+=(*Bij)*Xj_z;
272  (*Yi_z)+=(*Bij)*Xj_y;
273  Bij++;
274 
275  //Bij[5]
276  (*Yi_z)+=(*Bij)*Xj_z;
277  Bij++;
278 
279  //iterators at block at next row
280  //Bij+=BLOCK_SIZE;
281 
282  Xj+=P;
283 
284  }//end loop on column index < i index
285 
286  //jb=ib Yi+=Di.Xi
287  // Yi_d=Yi;
288  // for(jb=0;jb<P;jb++) {
289  // (*Yi_d)+=(*Di)*(*Xj);
290  // Xj++;
291  // Yi_d++;
292  // }
293  Xj_x=Xj[0];
294  Xj_y=Xj[1];
295  Xj_z=Xj[2];
296  (*Yi_x)+=(*Di)*Xj_x;
297  (*Yi_y)+=(*Di)*Xj_y;
298  (*Yi_z)+=(*Di)*Xj_z;
299  Xj+=P;
300  // if (ib==2) {
301  // std::cout<<"<"<<ib<<","<<jb<<">["<<(*Di)<<"]";
302  // std::cout<<"["<<Xj[-3]<<",";
303  // std::cout<<Xj[-2]<<",";
304  // std::cout<<Xj[-1]<<"]";
305  // std::cout<<"=["<<Yi[0]<<","<<Yi[1]<<","<<Yi[2]<<"]\n";
306 
307  // }
308  Di++;
309 
310  //jb>ib : jb=ib+1;
311  jb=ib;jb++;
312  //block for next column
313  B0i=Bij;
314  //jb-th block of next colum
315  incBij=ib;
317  Bij+=incBij;
318  while (jb<N) {//column index of the block
319 
320  //Block product
321  //BlockVectorProduct(Bij,Xj,Yi,
322  // i,j,incB,iXj);
323  Xj_x=Xj[0];
324  Xj_y=Xj[1];
325  Xj_z=Xj[2];
326 
327  //Bij[0]
328  (*Yi_x)+=(*Bij)*Xj_x;
329  Bij++;
330 
331  //Bij[1]
332  (*Yi_x)+=(*Bij)*Xj_y;
333  (*Yi_y)+=(*Bij)*Xj_x;
334  Bij++;
335 
336  //Bij[2]
337  (*Yi_y)+=(*Bij)*Xj_y;
338  Bij++;
339 
340  //Bij[3]
341  (*Yi_x)+=(*Bij)*Xj_z;
342  (*Yi_z)+=(*Bij)*Xj_x;
343  Bij++;
344 
345  //Bij[4]
346  (*Yi_y)+=(*Bij)*Xj_z;
347  (*Yi_z)+=(*Bij)*Xj_y;
348  Bij++;
349 
350  //Bij[5]
351  (*Yi_z)+=(*Bij)*Xj_z;
352  Bij++;
353 
354 
355  // if (ib==2) {
356  // std::cout<<"<"<<ib<<","<<jb<<">["<<Bij[0]<<",";
357  // std::cout<<Bij[1]<<",";
358  // std::cout<<Bij[2]<<",";
359  // std::cout<<Bij[3]<<",";
360  // std::cout<<Bij[4]<<",";
361  // std::cout<<Bij[5]<<"].";
362  // std::cout<<"["<<Xj[0]<<",";
363  // std::cout<<Xj[1]<<",";
364  // std::cout<<Xj[2]<<"]";
365  // std::cout<<"=["<<Yi[0]<<","<<Yi[1]<<","<<Yi[2]<<"]\n";
366 
367  // }
368  //next block for X
369  Xj+=P;
370  //iterators to block at next column +=jb*BLOCK_SIZE
371  Bij+=incBij;
373  //next column
374  jb++;
375  }//end loop on column index >= i index
376 
377  //Yi at next row block
378  Yi+=P;
379 
380  }//end loop on row index
381 
382  //dispatch all values
383  MPI_WorldToWorldMessage::AllGather(mpiEnv,(int) (end-start)*P,valuesLengthPerCore);
384  MPI_WorldToWorldMessage::BuildOffset(valuesLengthPerCore,valuesOffset);
385 
386  MPI_WorldToWorldMessage::AllGather(mpiEnv,&vY[start*P],valuesLengthPerCore[coreId],
387  &vY[0],valuesLengthPerCore,valuesOffset);
388 }
389 
390 
391 
392 
393 #endif
This class is a Environment class to define MPI world.
Definition: MPI_Environment.h:36
const tMPICoreId & getCoreId() const
get the id of the current process of this environment
Definition: MPI_Environment.h:200
const tMPICoreId & getCoresNumber() const
get the number of cores of this environment of common environment
Definition: MPI_Environment.h:180
static MPI_Environment & GetEnvironment()
get the environment
Definition: MPI_Run.h:114
static tBoolean AllGather(const MPI_Environment &env, const T &srcData, std::valarray< T > &dstData)
blocking gathering a data from all cores of enviroments to all cores
Definition: MPI_WorldToWorldMessage.h:414
static int BuildOffset(const std::valarray< tMPIIndex > &dataLength, std::valarray< tMPIIndex > &dataOffset)
compute the displacement from the data length per core
Definition: MPI_WorldToWorldMessage.h:467
This class describes an OpenMP/MPI implemntation of symmetric matrix by block of size in a packed st...
Definition: SMOMPI_PackedBlockSymmetricMatrix.h:19
static void BlockVectorProduct(const T *B, const T *X, T *Y, const T *eY, const T *Xi, const T *Xj, T *Yi, T *Yj)
compute sthe vector product of the packed symmetric block B of dimension P by X to obtain Y=B....
Definition: SM_PackedBlockMatrix.h:188
This class described a symmetric matrix by block of size PxP in a packed storage.
Definition: SM_PackedBlockSymmetricMatrix.h:18