C++ mpi module for stochmagnet_main Package
OMP_PtrField.h
1 #ifndef OMP_PtrField_H
2 #define OMP_PtrField_H
3 
4 #include "CORE_Field.h"
5 
6 //corresponding array header
7 #include "OMP_PtrArray.h"
8 
15 template <typename T,typename K,K D>
16 class OMP_PtrField : public CORE_Field<T,K,D,OMP_PtrArray<T>,OMP_PtrField<T,K,D>> {
17 
18 private:
19 
20  //This class type
21  typedef OMP_PtrField<T,K,D> Self;
22 
23 
24 
25  // CONSTRUCTORS
26 public:
30  }
31 
32 
33 
34  // DESTRUCTORS
37  virtual ~OMP_PtrField() {
38  }
39 
40 
41 private:
42 
43 
44 
45 
46  //MEMORY
47  //=====
48 public:
56  virtual tMemSize getMemorySize() const override {
57  return sizeof(*this)+this->getContentsMemorySize();
58  }
59 
60  //allocation methods
61  //===================
62 
63 public:
67  static inline CORE_UniquePointer<Self> New() {
68  return CORE_UniquePointer<Self>(new Self(),CORE_Object::Delete());
69  }
70 
71 
72 
73 
74  //accessor operators
75  //====================
76 
77 
78  //accessor iterator
79  //=================
80 
81 
82  //accessor methods
83  //=================
84 
85 
86  //assignment operators
87  //====================
91  inline Self& operator=(const T& v) {
92  initialize(v);
93  return *this;
94  }
98  inline Self& operator=(const std::initializer_list<T>& values) {
99  if (values.size()==D) {
100  initialize(values);
101  } else {
102  copy(values);
103  }
104  return *this;
105  }
109  inline Self& operator=(std::initializer_list<T>&& values) {
110  if (values.size()==D) {
111  initialize(values);
112  } else {
113  copy(values);
114  }
115  return *this;
116  }
117 
118 
124  template<size_t N,typename Q>
125  inline Self& operator=(const std::array<Q,N>& values) {
126  initialize(values);
127  return *this;
128 
129  }
130 
135  template<typename Q>
136  inline Self& operator=(const std::valarray<Q>& values) {
137  copy(values);
138  return *this;
139  }
140 
145  template<typename Q>
146  inline Self& operator=(const std::vector<Q>& values) {
147  copy(values);
148  return *this;
149  }
150 
154  inline Self& operator=(const Self& values) {
155  copy(values);
156  return *this;
157  }
161  inline Self& operator=(Self&& values) {
162  copy(values);
163  return *this;
164  }
165 
172  template<typename Q,class S1,class I1>
173  inline Self& operator=(const CORE_Field<Q,K,D,S1,I1>& values) {
174  copy(values);
175  return *this;
176  }
183  template<typename Q,class S1,class I1>
185  copy(values);
186  return *this;
187  }
188 
189 
190  //initializers methods
191  //====================
195  inline void initialize(const T& a) {
196  this->getStorage().initialize(a);
197  }
202  template<typename Q>
203  inline void initialize(const std::initializer_list<Q>&& a) {
204  //values of A
205  auto vA =std::ranges::cbegin(a);
206 
207  //end iterator of A
208  const auto iAe=std::ranges::cend(a);
209 
210  //begin iterator on this values
211  auto values=this->getValues();
212 
213  //number of elements
214  tInteger n=this->getElementsNumber();
215 
216  OMP_PARALLEL_SHARED((n,vA,iAe,values)) {
217 
218  // thread id
219  tInteger threadId=OMP_GET_THREAD_ID();
220 
221  //threads number
222  tInteger nThreads=OMP_GET_THREADS_NUMBER();
223 
224  //start index of element
225  tInteger start=threadId*n/nThreads;
226 
227  //end index of element
228  tInteger end=(threadId+1)*n/nThreads;
229 
230  //start iterator on values
231  T* iV=values+D*start;
232 
233  //end iterator on values
234  const T* iVe=values+D*end;
235 
236  //iterator on A
237  auto iA=vA;
238 
239  while (iV!=iVe) {//loop on i
240 
241  iA=vA;
242  while (iA!=iAe) {//loop on d
243 
244  //Vi[d]=A[d];
245  (*iV)=(*iA);
246 
247  iA++;
248  iV++;
249  }
250 
251 
252  }
253 
254 
255  }
256 
257  }
262  template<typename Q>
263  inline void initialize(const std::initializer_list<Q>& a) {
264  //values of a
265  auto vA =std::ranges::cbegin(a);
266 
267  //end iterator of A
268  const auto iAe=std::ranges::cend(a);
269 
270  //begin iterator on this values
271  auto values=this->getValues();
272 
273  //number of elements
274  tInteger n=this->getElementsNumber();
275 
276  OMP_PARALLEL_SHARED((n,vA,iAe,values)) {
277 
278  // thread id
279  tInteger threadId=OMP_GET_THREAD_ID();
280 
281  //threads number
282  tInteger nThreads=OMP_GET_THREADS_NUMBER();
283 
284  //start index of element
285  tInteger start=threadId*n/nThreads;
286 
287  //end index of element
288  tInteger end=(threadId+1)*n/nThreads;
289 
290  //start iterator on values
291  T* iV=values+D*start;
292 
293  //end iterator on values
294  const T* iVe=values+D*end;
295 
296  //iterator on A
297  auto iA=vA;
298 
299  while (iV!=iVe) {//loop on i
300 
301  iA=vA;
302  while (iA!=iAe) {//loop on d
303 
304  //Vi[d]=A[d];
305  (*iV)=(*iA);
306 
307  iA++;
308  iV++;
309  }
310 
311 
312  }
313 
314 
315  }
316 
317  }
322  template<typename Q>
323  inline void initialize(const std::array<Q,D>& a) {
324 
325  //values of A
326  const Q* vA =a.data();
327 
328  //end iterator of A
329  const Q* iAe=vA+D;
330 
331  //begin iterator on this values
332  auto values=this->getValues();
333 
334  //number of elements
335  tInteger n=this->getElementsNumber();
336 
337  OMP_PARALLEL_SHARED((n,vA,iAe,values)) {
338 
339  // thread id
340  tInteger threadId=OMP_GET_THREAD_ID();
341 
342  //threads number
343  tInteger nThreads=OMP_GET_THREADS_NUMBER();
344 
345  //start index of element
346  tInteger start=threadId*n/nThreads;
347 
348  //end index of element
349  tInteger end=(threadId+1)*n/nThreads;
350 
351  //start iterator on values
352  T* iV=values+D*start;
353 
354  //end iterator on values
355  const T* iVe=values+D*end;
356 
357  //iterator on A
358  const Q* iA=null;
359 
360  while (iV!=iVe) {//loop on i
361 
362  iA=vA;
363  while (iA!=iAe) {//loop on d
364 
365  //Vi[d]=A[d];
366  (*iV)=(*iA);
367 
368  iA++;
369  iV++;
370  }
371  }
372 
373 
374  }
375  }
376 
377 
378 
379 
380 
381 
382  //compound assignement operators (+=,-=,*=,/=,^=...)
383  //===================================================
384  //arithmetic type compound operators
385  //====================================
389  inline Self& operator+=(const T& v) {
390  this->getStorage()+=v;
391  return (*this);
392  }
396  inline Self& operator-=(const T& v) {
397  this->getStorage()-=v;
398  return (*this);
399 
400  }
401 
405  inline Self& operator*=(const T& v) {
406  this->getStorage()*=v;
407  return (*this);
408 
409  }
413  inline Self& operator/=(const T& v) {
414  this->getStorage()/=v;
415  return (*this);
416  }
417 
418  //integer type compond operators
419  //===============================
423  inline Self& operator%=(const T& v) requires functions_type::isIntegerType<T>{
424  this->getStorage()%=v;
425  return (*this);
426  }
427 
431  inline Self& operator&=(const T& v) requires functions_type::isIntegerType<T>{
432  this->getStorage()&=v;
433  return (*this);
434  }
435 
439  inline Self& operator|=(const T& v) requires functions_type::isIntegerType<T>{
440  this->getStorage()|=v;
441  return (*this);
442  }
443 
447  inline Self& operator^=(const T& v) requires functions_type::isIntegerType<T> {
448  this->getStorage()^=v;
449  return (*this);
450  }
454  inline Self& operator<<=(const T& v) requires functions_type::isIntegerType<T> {
455  this->getStorage()<<=v;
456  return (*this);
457  }
458 
462  inline Self& operator>>=(const T& v) requires functions_type::isIntegerType<T> {
463  this->getStorage()>>=v;
464  return (*this);
465  }
466 
467  //class type compound operatos
468  //=============================
469 
476  template<class Q,class S,class I>
477  inline Self& operator+=(const CORE_Field<Q,K,D,S,I>& X) {
478  this->getStorage()+=X.getStorage();
479  return (*this);
480  }
487  template<class Q,class S,class I>
489  this->getStorage()-=X.getStorage();
490  return (*this);
491  }
498  template<class Q,class S,class I>
500  //T=F(T,V)
501  this->getStorage()*=X.getStorage();
502  return (*this);
503  }
510  template<class Q,class S,class I>
512  this->getStorage()/=X.getStorage();
513  return (*this);
514  }
515 
516 
517  //transform methods
518  //=================
519 
520 
521 
527  template<typename LambdaFct>
528  static inline void ElementsTransform(LambdaFct&& F,
529  Self& X) {
530 
531  //number of elements
532  tIndex n=X.getElementsNumber();
533 
534 
535  //get the const begin stride iterator of X
536  auto iX=X.sbegin();
537 
538 
539  //init the random data
540  OMP_PARALLEL_SHARED((n,iX,F)) {//begin parallel section
541 
542  // thread id
543  tInteger threadId=OMP_GET_THREAD_ID();
544  //threads number
545  tInteger nThreads=OMP_GET_THREADS_NUMBER();
546 
547  //start index of element
548  tInteger start=threadId*n/nThreads;
549 
550  //end index of element
551  tInteger end=(threadId+1)*n/nThreads;
552 
553 
554  std::transform(iX+start,iX+end,
555  iX+start,F);
556 
557 
558  }//end parallel section
559 
560 
561  }
562 
563 
568  template<typename LambdaFct>
569  inline void elementsTransform(LambdaFct&& F) {
570  this->ElementsTransform(F,(*this));
571  }
572 
573 
574 
579  inline void normalize() {
580 
581  //error to detect null
582  T eps=std::numeric_limits<T>::epsilon();
583 
584 
585  //number of elements
586  tIndex n=this->getElementsNumber();
587 
588 
589  //get values of this
590  T* values=this->getValues();
591 
592 
593  //init the random data
594  OMP_PARALLEL_SHARED((n,values,eps)) {//begin parallel section
595 
596  // thread id
597  tInteger threadId=OMP_GET_THREAD_ID();
598  //threads number
599  tInteger nThreads=OMP_GET_THREADS_NUMBER();
600  //start index of element
601  tInteger start=threadId*n/nThreads;
602  //end index of element
603  tInteger end=(threadId+1)*n/nThreads;
604 
605  //iterator of index of the values of the start element
606  T* iV=values+D*start;
607 
608  //iterator of index of the values of the end element
609  const T* iVe=values+D*end;
610 
611  //begin iterator on dimension ie iVd=iV
612  const T* iVd=null;
613 
614  //end iterator on dimension
615  const T* iVde=null;
616 
617  //norm2
618  T norm2=0;
619  while (iV!=iVe) {//loop on element i
620 
621 
622  //iterator on end of element i
623  iVde=iV+D;
624 
625  //compute the norm at element iV
626  iVd=iV;
627  norm2=0;
628  while (iVd!=iVde) {
629  norm2+=(*iVd)*(*iVd);
630  iVd++;
631  }
632  //normlize
633  if (norm2>eps) {
634  norm2=1./sqrt(norm2);
635  while (iV!=iVde) {
636  (*iV)*=norm2;
637  iV++;
638  }
639  } else {
640  //go to next element
641  iV+=D;
642  }
643  }
644 
645  }//end parallel section
646 
647  }
648 
649 
650  //Data consistency
651  //=================
652 
653 
654  //transform methods
655  //==================
656 
657 
658  //algebric methods
659  //================
660 
661 
662 
667  template<class I>
668  inline void mod2(CORE_Array<T,I>& X) const {
669 
670 
671  //number of elements
672  tIndex n=this->getElementsNumber();
673 
674  //resize x to the number of elements
675  X.setSize(n);
676 
677  //get values of this
678  const T* values=this->getValues();
679 
680  //get the values of X
681  T* vX=X.getValues();
682 
683 
684  //init the random data
685  OMP_PARALLEL_SHARED((n,vX,values)) {//begin parallel section
686 
687 
688  // thread id
689  tInteger threadId=OMP_GET_THREAD_ID();
690  //threads number
691  tInteger nThreads=OMP_GET_THREADS_NUMBER();
692  //start element index
693  tInteger start=threadId*n/nThreads;
694  //end element index
695  tInteger end=(threadId+1)*n/nThreads;
696 
697  // iterator on values of element start
698  const T* iV=values+start*D;
699 
700  //iterator on values of element send
701  const T* iVe=values+end*D;
702 
703  //end iterator on element i
704  const T* iVde=null;
705 
706  //start iterator on X
707  T* iX=vX+start;
708 
709  while (iV!=iVe) {//loop on element
710 
711  (*iX)=0;
712  iVde=iV+D;//end iterator on dimension
713  while (iV!=iVde) {//loopon dimension
714  (*iX)+=(*iV)*(*iV);
715  iV++;
716  }
717 
718  iX++;
719 
720  }//end loop on element
721 
722  }//end parallel section
723 
724 
725 
726  }//end norm2(X) method
727 
736  template<class Q,class S1,class I1>
737  inline T& scalarProduct(const CORE_Field<Q,K,D,S1,I1>& X,T& s) const {
738  return this->getStorage().scalarProduct(X.getStorage(),s);
739  }
749  template<class Q,class S1,class I1>
750  inline T& scalarProduct(const std::valarray<Q>& weights,const CORE_Field<Q,K,D,S1,I1>& X,T& s) const {
751 
752  //number of elements
753  tIndex n=this->getElementsNumber();
754 
755  //increment on X
756  tBoolean incXs=(X.getElementsNumber()!=1);
757 
758 
759  //s=sum_i Xi Yi
760  s=0;
761 
762  if (weights.size()==0) {
764  }
765  if ((weights.size()==1)&& (incXs)) {
767  s*=weights[0];
768  return s;
769  }
770 
771 
772  //values of W
773  const tReal *Ws=&weights[0];
774  tBoolean incW=(weights.size()!=1);
775 
776  //values of this
777  const T* Ys=this->getValues();
778 
779  //values of X
780  const Q* Xs=X.getValues();
781 
782 
783 
784  OMP_PARALLEL_SHARED_REDUCTION((n,incW,Ws,Ys,Xs,incXs),
785  (+:s)) {//begin parallel section
786 
787 
788  // thread id
789  tInteger threadId=OMP_GET_THREAD_ID();
790  // threads number
791  tInteger nThreads=OMP_GET_THREADS_NUMBER();
792 
793  //start idnex of the loop
794  tIndex start=threadId*n/nThreads;
795 
796 
797  //begin weight iterator
798  const Q* iW=Ws;
799  iW+=incW*start;
800 
801 
802 
803  start*=D;
804 
805  //start iterator on X
806  const Q* iX=Xs;
807  iX+=incXs*start;
808  const Q* iXd=null;//iterator on d-coordinate
809 
810 
811  //start iterator on Y
812  const T* iY=Ys;
813  iY+=start;
814 
815  //end index oft the loop
816  tIndex end=(threadId+1)*n/nThreads;;
817  end*=D;
818 
819 
820  //end iterator on Y
821  const T* iYe=Ys;
822  iYe+=end;
823 
824  //end iterator on Y for element
825  const T* iYd=null;
826 
827 
828  //s=wi <X^i.Y^i>_d
829  s=0;
830  while (iY!=iYe) {//loop on elements
831 
832  iYd=iY+D;
833  iXd=iX;
834  while(iY!=iYd) {//loop on <X^i,Y^i>
835  s+=(*iW)*(*iXd)*(*iY);
836  iY++;
837  iXd++;
838  }//end loop on <X^i,Y^i>
839 
840  //weight of next elemnt
841  iW+=incW;
842  iX+=incXs*D;
843  }//end loop on element
844 
845  }//end parallel loop
846 
847  return s;
848  }
849 
850 
851 
852 
853 
854 };
855 
856 
857 
858 
859 //defualt dimension
860 #ifndef DIMENSION_TYPE
861 #define DIMENSION_TYPE
862 typedef tUCInt tDimension;//d in [0,256[
863 #endif
864 
866 
867 
868 
869 //default field
870 #ifndef DEFAULT_OMP_FIELD
871 #define DEFAULT_OMP_FIELD
873 #endif
874 
875 #endif
this class describes an array of values T of dynamical size with algebrical operators and I is an imp...
Definition: CORE_Array.h:91
const T * getValues() const
get the values of the array for reading
Definition: CORE_Array.h:206
void setSize(const tIndex &n)
set the size of the container
Definition: CORE_Collection.h:104
this class describes an field. A field is composed by
Definition: CORE_Field.h:49
virtual tMemSize getContentsMemorySize() const override
return the memory size of the included associations
Definition: CORE_Field.h:102
void copy(const tIndex &n, const Q *vs)
initialize the field to the values of pointer of size n
Definition: CORE_Field.h:447
const T * getValues() const
get the values of the array for reading
Definition: CORE_Field.h:323
auto sbegin()
return begin stride iterator for writing
Definition: CORE_Field.h:276
tIndex getElementsNumber() const
return the number values of the container
Definition: CORE_Field.h:135
auto end()
return end iterator for writing
Definition: CORE_Field.h:242
const OMP_PtrArray< T > & getStorage() const
get the storage
Definition: CORE_Field.h:336
class Free introduced for deleting a smart pointer
Definition: CORE_Object.h:113
this class define a PTR array with OpenMP vectorization
Definition: OMP_PtrArray.h:22
this class describes a standart arithmetic array type implemented with a std::valarray object
Definition: OMP_PtrField.h:16
Self & operator%=(const T &v) requires functions_type
modulo operator
Definition: OMP_PtrField.h:423
Self & operator*=(const T &v)
multiplicator operator
Definition: OMP_PtrField.h:405
void elementsTransform(LambdaFct &&F)
apply the transform element with the lambda function Xid = F(Xid)
Definition: OMP_PtrField.h:569
Self & operator/=(const T &v)
divisor operator
Definition: OMP_PtrField.h:413
Self & operator=(Self &&values)
build an array by a copy of values
Definition: OMP_PtrField.h:161
Self & operator=(const std::initializer_list< T > &values)
build an array by a copy of values
Definition: OMP_PtrField.h:98
void normalize()
normalize all the elements of the field return false if the method is not compatible with the floatin...
Definition: OMP_PtrField.h:579
Self & operator=(CORE_Field< Q, K, D, S1, I1 > &&values)
build an array by a copy of c
Definition: OMP_PtrField.h:184
void initialize(const std::initializer_list< Q > &&a)
copy at element elemnt the array of size D
Definition: OMP_PtrField.h:203
static CORE_UniquePointer< Self > New()
return a new unique pointer of this
Definition: OMP_PtrField.h:67
Self & operator=(const std::valarray< Q > &values)
build an array by a copy of values
Definition: OMP_PtrField.h:136
T & scalarProduct(const CORE_Field< Q, K, D, S1, I1 > &X, T &s) const
return the weight scalar product
Definition: OMP_PtrField.h:737
void initialize(const std::array< Q, D > &a)
copy at element elemnt the array of size D
Definition: OMP_PtrField.h:323
OMP_PtrField()
build an array of T*
Definition: OMP_PtrField.h:29
Self & operator=(const Self &values)
build an array by a copy of values
Definition: OMP_PtrField.h:154
Self & operator=(std::initializer_list< T > &&values)
build an array by a copy of values
Definition: OMP_PtrField.h:109
void mod2(CORE_Array< T, I > &X) const
return the norm2 array per each element
Definition: OMP_PtrField.h:668
virtual ~OMP_PtrField()
destroy an array of T*
Definition: OMP_PtrField.h:37
Self & operator=(const T &v)
fill the values of the array with v
Definition: OMP_PtrField.h:91
void initialize(const T &a)
copy at element elemnt the array of size D
Definition: OMP_PtrField.h:195
Self & operator=(const std::array< Q, N > &values)
build an array by a copy of values
Definition: OMP_PtrField.h:125
Self & operator-=(const T &v)
sub operator
Definition: OMP_PtrField.h:396
void initialize(const std::initializer_list< Q > &a)
copy at element elemnt the array of size D
Definition: OMP_PtrField.h:263
Self & operator-=(const CORE_Field< Q, K, D, S, I > &X)
array sub operator
Definition: OMP_PtrField.h:488
Self & operator*=(const CORE_Field< Q, K, D, S, I > &X)
array multiply operator
Definition: OMP_PtrField.h:499
T & scalarProduct(const std::valarray< Q > &weights, const CORE_Field< Q, K, D, S1, I1 > &X, T &s) const
return the weight scalar product
Definition: OMP_PtrField.h:750
Self & operator+=(const T &v)
add operator
Definition: OMP_PtrField.h:389
Self & operator=(const std::vector< Q > &values)
build an array by a copy of values
Definition: OMP_PtrField.h:146
virtual tMemSize getMemorySize() const override
return the memory size of the class
Definition: OMP_PtrField.h:56
static void ElementsTransform(LambdaFct &&F, Self &X)
apply the transform element with the lambda function Ri = F(Xi)
Definition: OMP_PtrField.h:528
Self & operator=(const CORE_Field< Q, K, D, S1, I1 > &values)
build an array by a copy of values
Definition: OMP_PtrField.h:173
Self & operator/=(const CORE_Field< Q, K, D, S, I > &X)
array divisor operator
Definition: OMP_PtrField.h:511