SUNphi  1.0
checks.cpp
1 #include <SUNphi.hpp>
2 
3 #include <array>
4 #include <iostream>
5 #include <sstream>
6 
7 using namespace std;
8 using namespace SUNphi;
9 
10 /// Report that a test is passed
11 #define TEST_PASSED
12  runLog()<<__PRETTY_FUNCTION__<<" passed!"
13 
14 /// Prints an IntSeq
15 template <int...Ints>
16 std::string printIntSeq(IntSeq<Ints...>)
17 {
18  std::ostringstream os;
19  for(int a : {Ints...})
20  os<<a<<" ";
21 
22  return os.str();
23 }
24 
25 // void test_first_vectorizer()
26 // {
27 // int a=MyTk::firstVectorizingComp<double>;
28 // runLog<<a;
29 // }
30 
31 /// Check that \c conj is ignored when Compl is not a component
32 ///
33 /// Check that \c conj of a non-complex type object is the same of
34 /// original type
35 void checkNonComplConjCancelation()
36 {
37  /// Tensor Kind to be used
38  using MyTk=
39  TensKind<RwCol,
40  Spin,
41  CnCol>;
42 
43  /// Tensor class to be used
44  using MyTens=
45  Tens<MyTk,
46  double>;
47 
48  /// Tensor instance
49  const MyTens c;
50 
51  /// Result of conj
52  using Res=
53  decltype(conj(c));
54 
55  // Check that the original type is the same of the result
56  STATIC_ASSERT_IS_BASE_OF(MyTens,Res);
57 
59 }
60 
61 /// Check nested \c conj cancelation
62 ///
63 /// Check that \c conj of a complex type object is the same of original
64 /// type, by issuing twice \c conj on a Tensor
65 void checkNestedConjCancelation()
66 {
67  /// Tensor Kind to be used
68  using MyTk=
69  TensKind<RwCol,
70  Compl,
71  CnCol>;
72 
73  /// Tensor class to be used
74  using MyTens=
75  Tens<MyTk,
76  double>;
77 
78  /// Tensor instance
79  const MyTens c;
80 
81  /// Result of double conj
82  using Res=
83  decltype(conj(conj(c)));
84 
85  // Check that the original type is the same of the result
86  STATIC_ASSERT_IS_BASE_OF(MyTens,Res);
87 
89 }
90 
91 /// Check duplicated "-" cancellation
92 ///
93 /// Check that repeated minus is canceled, by issuing twice it ovr a tensor
94 void checkDuplicatedUMinusCancellation()
95 {
96  /// Tensor Kind to be used
97  using MyTk=
98  TensKind<RwCol,
99  Spin,
100  CnCol>;
101 
102  /// Tensor class to be used
103  using MyTens=
104  Tens<MyTk,
105  double>;
106 
107  /// Tensor instance
108  const MyTens c;
109 
110  /// Result of double -
111  using Res=
112  decltype(-(-c));
113 
114  // Check that the original type is the same of the result
115  STATIC_ASSERT_IS_BASE_OF(MyTens,Res);
116 
117  TEST_PASSED;
118 }
119 
120 /// Check ability to filter the position of the variadic class
121 ///
122 /// First a variadic class, specifiied by integer of various
123 /// value. Then, a filter through "IsNotNull" is issued. Lastly the
124 /// type resulting is checked
125 void checkFilterVariadicClassPos()
126 {
127  /// Variadic class to be filtered
128  using VClass=
129  IntSeq<0,1,0,10>;
130 
131  /// Result of the filtering
132  using Res=
133  FilterVariadicClassPos<IsNotNull,
134  VClass>;
135 
136  /// Comparison of the fileer
137  using Ref=IntSeq<1,3>;
138 
139  // Check
140  STATIC_ASSERT_IS_BASE_OF(Res,Ref);
141 
142  TEST_PASSED;
143 }
144 
145 /// Check that a simple type can be wrapped into a ScalarWrapper
146 void checkScalarWrap()
147 {
148  /// Simple type
149  int a=
150  10;
151 
152  /// Wrap into a SmeT
153  auto b=
154  scalarWrap(a);
155 
156  /// Rewrap into a SmeT
157  auto c=
158  scalarWrap(b);
159 
160  if(c.eval()!=10)
161  CRASH<<"Wrapping 10 from rvalue failed";
162 
163  // Check that b and c are of the same type
164  STATIC_ASSERT_IS_BASE_OF(decltype(c),decltype(b));
165 
166  /// Rewrap into a SmeT an rvalue
167  auto d=
168  scalarWrap(10);
169 
170  if(d.eval()!=10)
171  CRASH<<"Wrapping 10 from rvalue failed";
172 
173  TEST_PASSED;
174 }
175 
176 /// Checks that a TensKind is contained into another one
177 void checkTensKindIscontained()
178 {
179  /// Fist Tensor Kind to be used
180  using MyTk1=
181  TensKind<RwCol,
182  Spin,
183  CnCol>;
184 
185  /// Second Tensor Kind to be used
186  using MyTk2=
187  TensKind<RwCol,
188  CnCol>;
189 
190  static_assert(MyTk1::contains<MyTk2>,"First TensKind not contained");
191  static_assert(not MyTk2::contains<MyTk1>,"Second TensKind contained");
192 
193  TEST_PASSED;
194 }
195 
196 /// Check the implementation of the call operator
197 void checkCallOperator()
198 {
199  /// Tensor Kind to be used
200  using MyTk=
201  TensKind<RwCol,
202  Spin,
203  CnCol>;
204 
205  /// Tensor class to be used
206  using MyTens=
207  Tens<MyTk,
208  double>;
209 
210  /// Tensor to be used
211  MyTens tens;
212 
213  /// Value to be assigned
214  const double val=
215  10.0;
216 
217  // Try to assign and check it
218  tens=val;
219 
220  /// Result of the check
221  auto& res=
222  tens(0,0,0);
223 
224  if(val!=res)
225  CRASH<<"Tens is "<<res<<" expected "<<val;
226 
227  /// Type of the result, to be checked
228  using D=
229  decltype(res);
230 
231  static_assert(std::is_lvalue_reference_v<D>,"Expected lvalue");
232 
233  TEST_PASSED;
234 }
235 
236 /// Performs simple checks on the Grid class
237 void checkGrid()
238 {
239  /// Flags of the grid
240  static constexpr int flags=
241  combineFlags<GridFlag::HASHED,
242  GridFlag::SHIFTED_BC>;
243 
244  /// Check that volume is as expected
245  auto checkVolume=
246  [](const auto grid,
247  const int64_t expVolume)
248  {
249  /// Voluem of the grid
250  const int64_t volume=
251  grid.volume();
252 
253  if(expVolume!=volume)
254  CRASH<<"Expected volume"<<expVolume<<"obtained"<<volume;
255  };
256 
257  /// Grid
258  auto grid=
259  Grid<2,int32_t,int64_t,flags>({1,2});
260 
261  /// Type of grid
262  using Grid=
263  decltype(grid);
264 
265  checkVolume(grid,2);
266 
267  grid.setSides({3,3});
268 
269  checkVolume(grid,9);
270 
271  /// Type of the list of neighbors
272  using GridNeighs=
273  std::vector<typename Grid::Neigh>;
274 
275  /// Cehck neighbors
276  auto checkNeigh=[](const auto& grid, ///< Grid to check
277  const GridNeighs& expNeighs) ///< Expected neighbors
278  {
279  grid.forAllPoints([&](const int64_t i)
280  {
281  Grid::forAllOriDirs([&](const int oriDir)
282  {
283  /// Neighbor
284  auto neigh=
285  grid.neighOfPoint(i,oriDir);
286 
287  /// Expected neighbor
288  auto expNeigh=
289  expNeighs[i][oriDir];
290 
291  if(neigh!=expNeigh)
292  CRASH<<"Point"<<i<<"direction"<<oriDir<<"expected neighbor"<<expNeigh<<"obtained"<<neigh;
293  });
294  });
295  };
296 
297  /// List of expected neighbors when not shifting BC
298  const GridNeighs expUnshiftedNeigh=
299  {{6,3,2,1},
300  {7,4,0,2},
301  {8,5,1,0},
302  {0,6,5,4},
303  {1,7,3,5},
304  {2,8,4,3},
305  {3,0,8,7},
306  {4,1,6,8},
307  {5,2,7,6}};
308 
309  checkNeigh(grid,expUnshiftedNeigh);
310 
311  grid.setShiftBC(1,{1,0});
312 
313  /// List of expected neighbors when shifting BC
314  const GridNeighs expShiftedNeigh=
315  {{6,3,8,1},
316  {7,4,0,2},
317  {8,5,1,3},
318  {0,6,2,4},
319  {1,7,3,5},
320  {2,8,4,6},
321  {3,0,5,7},
322  {4,1,6,8},
323  {5,2,7,0}};
324 
325  /// Shift read from grid
326  const int shiftOfBC0=
327  grid.shiftOfBC(0);
328 
329  if(shiftOfBC0!=1)
330  CRASH<<"Expected shift of"<<1<<"obtained"<<shiftOfBC0;
331 
332  checkNeigh(grid,expShiftedNeigh);
333 
334  TEST_PASSED;
335 }
336 
337 /// Ceck combining three flags
338 void checkFlagMasks()
339 {
340  /// Three flags
341  enum r_t{A,B,C};
342 
343  /// Combine A and C
344  constexpr int maskAC=
345  combineFlags<A,C>;
346  static_assert(maskAC==5,"Expecting 5");
347 
348  /// Add B
349  constexpr int maskABC=
350  addFlags<maskAC,B>;
351  static_assert(maskABC==7,"Expecting 7");
352 
353  /// Remove A and C
354  constexpr int maskB=
355  remFlags<maskABC,A,C>;
356  static_assert(maskB==2,"Expecting 2");
357 
358  TEST_PASSED;
359 }
360 
361 /// Check that modulo operation is performed as expected
362 void checkSafeModulo()
363 {
364  /// Function to test the result of modulo
365  auto check=
366  [](const int val,const int mod,const int expRes)
367  {
368  /// Result
369  int res=
370  safeModulo(val,mod);
371 
372  if(expRes!=res)
373  CRASH<<val<<" MOD "<<res<<" expected "<<expRes<<", is "<<res;
374  };
375 
376  check(5,3,2);
377  check(-2,3,1);
378  check(-3,3,0);
379 
380  TEST_PASSED;
381 }
382 
383 /// Check that a number factorizes as expected
384 void checkFactorize()
385 {
386  /// Function checking the number factorization
387  auto check=
388  [](const int n, ///< Number to factorize
389  const std::vector<int> expFacts) ///< Expected factors
390  {
391  /// Factors to be checked
392  const std::vector<int> facts=
393  factorize(n);
394 
395  if(facts.size()!=expFacts.size())
396  CRASH<<"Factorizing "<<n<<" facts size "<<(int)facts.size()<<" different from size expected, "<<(int)expFacts.size();
397 
398  for(int iFact=0;iFact<(int)facts.size();iFact++)
399  {
400  /// Factor obtained
401  const int f=
402  facts[iFact];
403 
404  /// Factor expected
405  const int eF=
406  expFacts[iFact];
407 
408  if(f!=eF)
409  CRASH<<"Factorizing "<<n<<" Factor "<<iFact<<" is expected to be "<<eF<<" is"<<f;
410  }
411  };
412 
413  check(1,{1});
414  check(2,{2});
415  check(3,{3});
416  check(4,{2,2});
417  check(5,{5});
418  check(6,{2,3});
419  check(101,{101});
420 
421  TEST_PASSED;
422 }
423 
424 /// Check the lhs assignement to transposed
425 void checkLhsTranspose()
426 {
427  /// A real 3 X 3 matrix
428  using Su3Tens=
429  Tens<TensKind<RwCol,CnCol>,double>;
430 
431  /// Matrix used in the test
432  Su3Tens t;
433 
434  /// Write in the matrix as transposed
435  for(int rw_c=0;rw_c<NCOL;rw_c++)
436  for(int cn_c=0;cn_c<NCOL;cn_c++)
437  rwCol(cnCol(transpose(t),cn_c),rw_c)=cn_c;
438 
439  /// Read the matrix as non-transposed
440  for(int rw_c=0;rw_c<NCOL;rw_c++)
441  for(int cn_c=0;cn_c<NCOL;cn_c++)
442  if(rwCol(cnCol(t,cn_c),rw_c)!=rw_c)
443  CRASH<<"Matrix entry ("<<rw_c<<","<<cn_c<<" expected "<<rw_c<<" obtained "<<rwCol(cnCol(t,cn_c),rw_c);
444 
445  TEST_PASSED;
446 }
447 
448 /// Assert if a duplicated call is not removed
449 #define STATIC_ASSERT_DUPLICATED_CALL_REMOVER(FUN,...)
450  static_assert(isSame<
451  __VA_ARGS__,
452  RemRef<decltype(FUN(FUN(__VA_ARGS__{})))>
453  >,"Not same")
454 
455 /// Assert if a duplicated call is not absorbed
456 #define STATIC_ASSERT_DUPLICATED_CALL_ABSORBER(FUN,...)
457  static_assert(isSame<
458  RemRef<decltype(FUN(__VA_ARGS__{}))>,
459  RemRef<decltype(FUN(FUN(__VA_ARGS__{})))>
460  >,"Not same")
461 
462 /// Verify that calling duplicated-removed or absorbed functions are treated as expected
463 void checkDuplicatedCallRemoverOrAbsorber()
464 {
465  STATIC_ASSERT_DUPLICATED_CALL_REMOVER(conj,Tens<TensKind<Compl>,double>);
466  STATIC_ASSERT_DUPLICATED_CALL_REMOVER(transpose,Tens<TensKind<RwCol,CnCol>,double>);
467  STATIC_ASSERT_DUPLICATED_CALL_REMOVER(adj,Tens<TensKind<Compl>,double>);
468  STATIC_ASSERT_DUPLICATED_CALL_ABSORBER(wrap,Tens<TensKind<Compl>,double>);
469 
470  TEST_PASSED;
471 }
472 
473 /// Test the nested binding of a tens
474 void checkBinding()
475 {
476  ///Tensor to be used
477  Tens<TensKind<RwSpin,Compl>,double> cicc;
478 
479  /// Value to be assigned
480  const double value=
481  1.9234424;
482 
483  /// Bind \c spin
484  auto d=
485  spin(cicc,0);
486 
487  /// Bind real part
488  auto &e=
489  reIm(d,0);
490 
491  // Assign
492  e=value;
493 
494  /// Result
495  double res=
496  real(spin(cicc,0));
497 
498  if(res!=value)
499  CRASH<<"Expected "<<value<<" obtained "<<res;
500 
501  const Tens<TensKind<RwSpin,Compl>,double> co;
502 
503  /// Type of the binding
504  using T=
505  decltype(rwSpin(imag(co),0));
506 
507  static_assert(isConst<T>,"Expected const");
508  static_assert(isLvalue<T>,"Expected const");
509 
510  TEST_PASSED;
511 }
512 
513 /// Test the conjugation
514 void checkConj()
515 {
516  /// Tensor type
517  using ComplTens=
518  Tens<TensKind<Compl>,double>;
519 
520  /// Tensor
521  ComplTens t;
522 
523  /// Expecte real value
524  const double re=
525  1.0;
526  const double im=
527  -3.14598712480;
528 
529  // Assign real and imag
530  real(t)=re;
531  imag(t)=im;
532 
533  /// Conjugated value
534  auto c=
535  conj(t);
536 
537  // Check real value
538  if(real(c)!=re)
539  CRASH<<"Real part: "<<real(c)<<" expected: "<<re;
540 
541  // Check imag value
542  if(imag(c)!=-im)
543  CRASH<<"Imag part: "<<imag(c)<<" expected: "<<-im;
544 
545  TEST_PASSED;
546 }
547 
548 /// Test class
549 template <typename T>
550 class fuffa
551  : public SingleInstance<fuffa<T>>
552 {
553 public:
554  /// Dummy initializer
555  fuffa<T>()
556  {
557  }
558 };
559 
560 /// Check single instances classes
561 void checkSingleInstances()
562 {
563  /// Single instance of \c fuffa<void>
564  fuffa<void> test1;
565 
566  /// Single instance of \c fuffa<<int>
567  fuffa<int> test2;
568 
569  TEST_PASSED;
570 }
571 
572 /// Check that MPI is initialized
573 void checkMPIisInitalized()
574 {
575  /// Initialization flag
576  const int isInitialized=
578 
579  if(not isInitialized)
580  CRASH<<"MPI not initialized!";
581 
582  TEST_PASSED;
583 }
584 
585 /// Check MPI all reduce
586 void checkMPIallReduce()
587 {
588  /// Value to sum
589  const int val=
590  2;
591 
592  /// Sum 2
593  const int sum=
594  mpi.allReduce(val);
595 
596  /// Expected value of the sum
597  const int expSum=
598  2*mpi.nRanks();
599 
600  if(sum!=expSum)
601  CRASH<<"Summing "<<val<<" on all "<<mpi.nRanks()<<" nodes produced "<<sum<<" instead of expected "<<expSum;
602 
603  TEST_PASSED;
604 }
605 
606 /// Test adding and removing of signness
607 void checkSignUnsign()
608 {
609  /// Check the unsigning of A into B
610 #define CHECK_UNSIGN(A,B)
611  static_assert(isSame<UnsignedOf<A>,B>,"Unsigned version of " #A " is not the same of " #B)
612 
613  /// Check the signing of A into B
614 #define CHECK_SIGN(A,B)
615  static_assert(isSame<SignedOf<A>,B>,"Signed version of " #A " is not the same of " #B)
616 
617  CHECK_UNSIGN(int64_t,uint64_t);
618  CHECK_UNSIGN(const int64_t,const uint64_t);
619  CHECK_UNSIGN(int64_t&,uint64_t&);
620  CHECK_UNSIGN(const int64_t&,const uint64_t&);
621 
622  CHECK_SIGN(uint64_t,int64_t);
623  CHECK_SIGN(const uint64_t,const int64_t);
624  CHECK_SIGN(uint64_t&,int64_t&);
625  CHECK_SIGN(const uint64_t&,const int64_t&);
626 
627  TEST_PASSED;
628 
629 #undef CHECK_UNSIGN
630 #undef CHECK_SIGN
631 }
632 
633 /// Test vector class
634 void checkVectorClass()
635 {
636  /// Vector to allocate
637  Vector<int> a{1,2,3,6,1};
638 
639  /// Expected size
640  const long int expSize=
641  5;
642 
643  // Check size
644  if(a.size()!=expSize)
645  CRASH<<"Expected size: "<<expSize<<", obtained: "<<a.size();
646 
647  /////////////////////////////////////////////////////////////////
648 
649  /// Check first or last occurrency
650  auto check=[&a](const int& searching,
651  const int& expectedPos,
652  const bool& firstLast)
653  {
654  /// Finds
655  const int pos=
656  (firstLast==false)?
657  a.findFirst(searching):
658  a.findLast(searching);
659 
660  // Check position
661  if(pos!=expectedPos)
662  CRASH<<"First "<<searching<<" expected at position "<<expectedPos<<"found at "<<pos;
663  };
664 
665  check(6,3,false);
666  check(4,expSize,false);
667  check(3,2,true);
668  check(8,-1,true);
669 
670  /////////////////////////////////////////////////////////////////
671 
672  /// Sum of all elements of \c a
673  const int sum=
674  a.summatorial(1);
675 
676  /// Expected result of the sum
677  const int expSum=
678  12;
679 
680  // Check sum
681  if(sum!=expSum)
682  CRASH<<"Expected sum: "<<expSum<<", obtained: "<<sum;
683 
684  /////////////////////////////////////////////////////////////////
685 
686  /// Take the product of all elements of \c a
687  const int prod=
688  a.productorial(1);
689 
690  /// Expected result of the product
691  const int expProd=
692  36;
693 
694  // Check product
695  if(prod!=expProd)
696  CRASH<<"Expected prod: "<<expProd<<",obtained: "<<prod;
697 
698  /////////////////////////////////////////////////////////////////
699 
700  TEST_PASSED;
701 }
702 
703 /// Test combinatorial
704 void checkCombinatorial()
705 {
706  /// Maximal number of object for each slot
707  const Vector<int64_t> nMaxPerSlot=
708  {1,2,3,2};
709 
710  /// Number of objects
711  const int nObj=
712  3;
713 
714  /// Set the combinatorial
715  Combinatorial c(nMaxPerSlot,nObj);
716 
717  /// First combinatorial
718  const auto l=
719  c.getFirst();
720 
721  /// Expected
722  const Vector<int64_t> expFirst=
723  {1,2,0,0};
724 
725  if(expFirst!=c())
726  CRASH<<"First combinatorial not working";
727 
728  c.advance();
729  c.rewind();
730 
731  if(expFirst!=c())
732  CRASH<<"Advancing and rewinding not coming back to first combinatorial";
733 
734  TEST_PASSED;
735 }
736 
737 /// Test the sitmo random generator
738 void checkSitmo()
739 {
740  // /// Create a random number generator
741  // Sitmo rng;
742 
743  // // seed
744  // rng.seed(100);
745 
746  // // Skip 8
747  // for(int i=0;i<8;i++)
748  // runLog()<<rng();
749 
750  // /// Test the rng
751  // const uint32_t r=
752  // rng();
753 
754  // /// Expected result
755  // constexpr uint32_t expR=
756  // 2770169712;
757 
758  // if(r!=expR)
759  // CRASH<<"Expected "<<expR<<" obtained "<<r;
760 
761  // /////////////////////////////////////////////////////////////////
762 
763  // // Seed again
764  // rng.seed(100);
765 
766  // // Skip 8
767  // rng.discard(8);
768 
769  // /// Test the rng again
770  // const uint32_t r2=
771  // rng();
772 
773  // if(r2!=expR)
774  // CRASH<<"Expected "<<expR<<" obtained "<<r2;
775 
776  WARNING<<"NO SITMO CHECKED!!!!!";
777 
778  TEST_PASSED;
779 }
780 
781 /// Check the serialization features
782 void checkSerializer()
783 {
784  /// SubTestClass to be incapsulated inside the main TestClass
785  DEFINE_SERIALIZABLE_CLASS(SubTestClass)
786  {
787  public:
788 
789  /// Pair to be used
790  using P=
791  std::pair<std::string,std::string>;
792 
793  SERIALIZABLE_SCALAR(P,p,"fi","se");
794 
795  SERIALIZABLE_SCALAR(std::vector<double>,v,3);
796  SERIALIZABLE_SCALAR(double,b,1.0);
797 
799  };
800 
801  /// TestClass to be serialized
802  DEFINE_SERIALIZABLE_CLASS(TestClass)
803  {
804  public:
805 
806  SERIALIZABLE_CLASS(SubTestClass,subTestClass);
807  SERIALIZABLE_SCALAR(std::string,ciccio,"pasticcio");
808 
809  LIST_SERIALIZABLE_MEMBERS(subTestClass,ciccio);
810  };
811 
812  SERIALIZABLE_SCALAR_WITH_TAG(TestClass,test1,"testClass");
813  SERIALIZABLE_SCALAR_WITH_TAG(TestClass,test2,"testClass");
814  SERIALIZABLE_SCALAR_WITH_TAG(TestClass,test3,"testClass");
815 
816  test1().subTestClass().b=
817  345235.1413;
818 
819  test1().subTestClass().v()[2]=
820  4;
821 
822  test1().subTestClass().p().first=
823  "primo";
824 
825  test1().ciccio=
826  "pasticcissimo";
827 
828  test2.deSerialize(test1.serialize(ONLY_NON_DEFAULT));
829 
830  test3.deBinarize(test1.binarize());
831 
832 #define CHECK(A)
833  if(test1().A!=test2().A)
834  CRASH<<"Expected "<<test1().A<<" for " #A ", obtained in serialized: "<<test2().A<<"\n"<<test1.serialize(ONLY_NON_DEFAULT)<<"\n\n"<<test2;
835 
836  if(test1().A!=test3().A)
837  CRASH<<"Expected "<<test1().A<<" for " #A ", obtained in binarized: "<<test3().A<<"\n"<<test1<<"\n\n"<<test3;
838 
839  CHECK(subTestClass().b);
840  CHECK(subTestClass().v()[2]);
841  CHECK(subTestClass().p().first);
842  CHECK(ciccio());
843 
844 #undef CHECK
845 
846  TEST_PASSED;
847 }
848 
849 /// Check storing of max
850 void checkValWithMax()
851 {
852  /// First addend
853  const int64_t first=
854  12;
855 
856  /// Second addend
857  const int64_t second=
858  13;
859 
860  /// Third addend (to subtract)
861  const int64_t third=
862  23;
863 
864  /// Val to check max
865  ValWithMax<int64_t> a=
866  first;
867 
868  a+=
869  second;
870 
871  a-=
872  third;
873 
874  /// Expected maximum
875  const int64_t expExtr=
876  first+second;
877 
878  /// Expected final
879  const int64_t expFin=
880  first+second-third;
881 
882  if(a.extreme()!=expExtr)
883  CRASH<<"Extreme expected: "<<expExtr<<", obtained: "<<a.extreme();
884 
885  if(a!=expFin)
886  CRASH<<"Final expected: "<<expFin<<", obtained: "<<a;
887 
888  TEST_PASSED;
889 }
890 
891 //////////////////////////////// TESTS TO BE FINISHED /////////////////////////////////
892 
893 void checkIsAliasing()
894 {
895  using ComplTens=Tens<TensKind<Compl>,double>;
896 
897  ComplTens t,u;
898 
899  //transpose_bis(t);
900 
901  auto a=wrap(Tens<TensKind<Compl>,double>{});
902  auto b=wrap(wrap(Tens<TensKind<Compl>,double>{}));
903 
904  runLog()<< isSame<RemRef<decltype(a)>,RemRef<decltype(b)>> ;
905  runLog()<<isSame<decltype(a),decltype(b)>;
906  runLog()<<"t.isAliasing(t): "<<t.isAliasing(t.getStor());
907  runLog()<<"t.isAliasing(u): "<<t.isAliasing(u.getStor());
908  runLog()<<"conj(t).isAliasing(t): "<<conj(t).isAliasing(t.getStor());
909 }
910 
911 void checkBindComplicatedExpression()
912 {
913  TEST_PASSED;
914 
915  Tens<TensKind<Compl>,double> t;
916  auto tr=transpose(wrap(wrap(t)));
917  reIm(transpose(tr),0)=1.0;
918  //reim(transpose(transpose(Tens<TensKind<Compl>,double>{})),0)=1.0;
919  //const double &e=reim(conj()),0);
920  using MyTk=TensKind<Spacetime,Col,Spin,Compl>;
921  //using MyTk=TensKind<Col,Spin,Compl>;
922  using MyTens=Tens<MyTk,double>;
923 
924  //int a=MyTk::firstVectorizingComp<double>;
925  //runLog()<<a;
926 
927  int vol=10;
928  MyTens cicc(vol);
929 
930  // auto &v=cicc.getStor();
931 
932  // index<MyTk>(v.dynSizes,0,0,0,0);
933 
934  //eval(cicc.getStor(),0,0,0,0);
935 
936  for(int ic=0;ic<NCOL;ic++)
937  for(int id=0;id<NSPIN;id++)
938  for(int ri=0;ri<NCOMPL;ri++)
939  {
940  //double &ref=eval(color(spin(cicc,id),ic));
941  double &ref=site(reIm(spin(col(transpose(transpose(cicc)),ic),id),ri),0);
942  //printf("%lld %lld\n",(long long int)cicc.get_v()._v,(long long int)&ref);
943  ref=3.141592352352;
944  }
945 
946  auto binder1=site(reIm(spin(col(cicc,2),3),1),0);
947  // //auto binder2=color(spin(cicc,2),1);
948 
949  // // eval(binder1)=8.0;
950  // printf("%d\n",cicc.getStor().nel);
951  printf("ANNA %lg\n",binder1);
952  // runLog()<<Spacetime::name();
953  // runLog()<<Col::name();
954  }
955 
956 // void test_assigner()
957 // {
958 // TEST_PASSED;
959 
960 // using MyTk1=TensKind<Col,Spin,Compl>;
961 // using MyTens1=Tens<MyTk1,double>;
962 
963 // using MyTk2=TensKind<Spin,Col,Compl>;
964 // using MyTens2=Tens<MyTk2,double>;
965 
966 // MyTens1 cicc1;
967 // MyTens2 cicc2;
968 
969 // runLog()<<"cicc1 storage: "<<getStor(cicc1)._v;
970 
971 // for(int icol=0;icol<NCOL;icol++)
972 // for(int ispin=0;ispin<NSPIN;ispin++)
973 // for(int icompl=0;icompl<NCOMPL;icompl++)
974 // col(spin(reim(cicc1,icompl),ispin),icol) EVAL=
975 // icompl+NCOMPL*(ispin+NSPIN*icol);
976 
977 // MyTens2 cicc3;
978 
979 // auto co=conj(cicc1);
980 // transpose(cicc3)=cicc2=transpose(co);
981 // transpose(cicc3)=cicc2=transpose(conj(cicc1));
982 
983 // //cicc2=cicc1;
984 
985 // //int a=ass.ref2;
986 
987 // // double a=0.0;
988 // // for(int icol=0;icol<NCOL;icol++)
989 // // for(int ispin=0;ispin<NSPIN;ispin++)
990 // // for(int icompl=0;icompl<NCOMPL;icompl++)
991 // // {
992 // // double b=col(spin(reim(cicc2,icompl),ispin),icol);
993 // // a+=b;
994 // // runLog()<<b;
995 // // }
996 // // runLog()<<a;
997 
998 // // using MyTk1=TensKind<Col,Compl>;
999 // // using MyTens1=Tens<MyTk1,double>;
1000 
1001 // // using MyTk2=TensKind<Col,Compl>;
1002 // // using MyTens2=Tens<MyTk2,double>;
1003 
1004 // // MyTens1 cicc1;
1005 // // MyTens2 cicc2;
1006 
1007 // // for(int icol=0;icol<NCOL;icol++)
1008 // // for(int icompl=0;icompl<NCOMPL;icompl++)
1009 // // col(reim(cicc1,icompl),icol).eval()=
1010 // // icompl;
1011 
1012 // // runLog()<<"/////////////////////////////////////////////////////////////////";
1013 // // // for(int icol=0;icol<NCOL;icol++)
1014 // // // for(int icompl=0;icompl<NCOMPL;icompl++)
1015 // // // {
1016 // // // col(reim(cicc2,icompl),icol).eval()=
1017 // // // col(reim(conj(cicc1),icompl),icol).eval();
1018 // // // runLog()<<col(reim(cicc2,icompl),icol).eval()<<
1019 // // // " "<<col(reim(cicc1,icompl),icol).eval();
1020 // // // }
1021 // // // runLog()<<"/////////////////////////////////////////////////////////////////";
1022 
1023 // // auto c1=conj(cicc1);
1024 // // auto ass=assign(cicc2,c1);
1025 // // ass.close();
1026 
1027 // // for(int icol=0;icol<NCOL;icol++)
1028 // // for(int icompl=0;icompl<NCOMPL;icompl++)
1029 // // runLog()<<col(reim(cicc2,icompl),icol).eval()<<" "<<col(reim(cicc1,icompl),icol).eval();
1030 
1031 // }
1032 
1033 void checkNnaryBuilder()
1034 {
1035  /// Fist Tensor Kind to be used
1036  using MyTk1=
1037  TensKind<RwCol,
1038  Spin,
1039  CnCol>;
1040 
1041  /// Second Tensor Kind to be used
1042  using MyTk2=
1043  TensKind<RwCol,
1044  CnCol>;
1045 
1046  /// Third Tensor Kind to be used
1047  using MyTk3=
1048  TensKind<Spin,
1049  CnCol>;
1050 
1051  /// First Tensor class to be used
1052  using MyTens1=
1053  Tens<MyTk1,
1054  double>;
1055 
1056  /// Second Tensor class to be used
1057  using MyTens2=
1058  Tens<MyTk2,
1059  float>;
1060 
1061  /// Second Tensor class to be used
1062  using MyTens3=
1063  Tens<MyTk3,
1064  float>;
1065 
1066  /// First Tensor to be used
1067  MyTens1 tens1;
1068 
1069  /// Second Tensor to be used
1070  MyTens2 tens2;
1071 
1072  /// Third Tensor to be used
1073  MyTens3 tens3;
1074 
1075  [[ maybe_unused ]]
1076  auto mulAdder=
1077  mulAdd(tens3,tens2,tens1);
1078 
1079  // using Mu=
1080  // decltype(mulAdder);
1081 
1082  mulAdder.eval(0,0,0);
1083 
1084  // using Md=
1085  // Mu::MergingDelimsOfRefs<IntSeq<0,3>>;
1086 
1087  // using Pos=
1088  // Mu::PosOfResTcsInRefsTk;
1089 
1090  //int y=Mu::MergeableComps{};
1091 
1092  //mulAdder.getMergedCompsView<IntSeq<0,1,2,3>>();
1093 }
1094 
1095  // // Check on Diag
1096  // {
1097  // using MyTk=TensKind<RwCol,Spin,CnCol>;
1098  // using A=IntSeq<1,0,1>;
1099  // using B=MyTk::IsMatrixComp;
1100  // STATIC_ASSERT_IS_BASE_OF(A,B);
1101 
1102  // using F=MyTk::Diag;
1103 
1104 
1105 
1106  // using G=TensKind<RwCol,Spin>;
1107  // STATIC_ASSERT_IS_BASE_OF(G,F);
1108 
1109  // }
1110 
1111  // // Check relBind
1112  // {
1113  // using MyTk=TensKind<RwCol,Spin,Spacetime,CnCol>;
1114 
1115  // using MyTens=Tens<MyTk,double>;
1116  // MyTens c(10);
1117 
1118  // c.eval(1,2,0,1)=1.0594;
1119 
1120  // auto b1=relBind<RwCol,CnCol>(c,[](int id){return id;});
1121  // auto b2=relBind<CnCol,RwCol>(c,[](int id){return id;});
1122  // // runLog()<<decltype(c)::Tk::name();
1123  // // runLog()<<decltype(b1)::Tk::name();
1124  // // runLog()<<decltype(b2)::Tk::name();
1125  // runLog()<<c.eval(1,2,0,1)<< " "<<b1.eval(2,0,1)<<" "<<b2.eval(1,2,0);
1126 
1127  // auto bb1=relBind<Spin,Col>(b1,[](int id){return id+1;});
1128  // auto bb2=relBind<Spin,Col>(b2,[](int id){return id+1;});
1129 
1130  // runLog()<<c.eval(1,2,0,1)<< " "<<bb1.eval(0,1)<<" "<<bb2.eval(1,0);
1131 
1132  // runLog()<<decltype(c.getMaximallyMergedCompsView())::Tk::name();
1133  // runLog()<<" c: "<<decltype(c)::Tk::name();
1134  // runLog()<<" bb2: "<<decltype(bb2)::Tk::name();
1135  // // int o=decltype(b1)::ExtraDelims{};
1136  // // int oo=decltype(b1)::PosOfResTcsInRefsTk{};
1137  // // int p=decltype(b1)::MergeableComps{};
1138  // runLog()<<decltype(b1.getMaximallyMergedCompsView())::Tk::name();
1139  // }
1140 
1141  // //come trovare le componenti non twinnate? crea un IntSeq che dica
1142  // //se le componenti devono essere prese o no, prendi di questo le
1143  // //posizioni non nulle, e chiama getIndexed
1144  // {
1145  // using MyTk=TensKind<RwCol,Spin,CnCol>;
1146  // using MyTens=Tens<MyTk,double>;
1147 
1148  // MyTens c;
1149 
1150  // runLog()<<" "<<posOfType<RwCol,MyTk::Twinned::types>;
1151 
1152  // STATIC_ASSERT_IS_BASE_OF(MyTens,decltype(+c));
1153  // }
1154 
1155  // //check the blending of two TensKind
1156  // {
1157  // using MyTk1=TensKind<RwCol,Spin>;
1158  // using MyTk2=TensKind<RwCol,CnCol>;
1159  // using MyTkBCompa=TensKind<RwCol,Spin,CnCol>;
1160 
1161  // using MyTkBRes1=typename MyTk1::BlendWithTensKind<MyTk2>;
1162  // STATIC_ASSERT_IS_BASE_OF(MyTkBRes1,MyTkBCompa);
1163 
1164  // using MyTkBRes2=BlendTensKinds<MyTk1,MyTk2>;
1165  // STATIC_ASSERT_IS_BASE_OF(MyTkBRes2,MyTkBCompa);
1166 
1167  // using MyTkBRes3=BlendTensKinds<MyTk1,MyTk2,MyTk2>;
1168  // STATIC_ASSERT_IS_BASE_OF(MyTkBRes3,MyTkBCompa);
1169  // }
1170 
1171 
1172  // using MyTk=TensKind<RwCol,Spin,Compl,CnCol>;
1173  // using MyTens=Tens<MyTk,double>;
1174 
1175  // MyTens cicc;
1176  // for(int irw_col=0;irw_col<NCOL;irw_col++)
1177  // for(int ispin=0;ispin<NSPIN;ispin++)
1178  // for(int icn_col=0;icn_col<NCOL;icn_col++)
1179  // for(int ri=0;ri<NCOMPL;ri++)
1180  // rwCol(reIm(cnCol(spin(cicc,
1181  // ispin),
1182  // icn_col),
1183  // ri),
1184  // irw_col)=
1185  // icn_col+NCOL*(0+NCOMPL*(ispin+NSPIN*irw_col));
1186 
1187  // cicc.getMaximallyMergedCompsView()=1.0;
1188 
1189  // auto i=imag(conj(cnCol(spin(rwCol(-cicc,0),0),0)));
1190  // runLog()<<i;
1191 
1192  // runLog()<<"/////////////////////////////////////////////////////////////////";
1193 
1194  // for(int irw_col=0;irw_col<NCOL;irw_col++)
1195  // for(int ispin=0;ispin<NSPIN;ispin++)
1196  // for(int icn_col=0;icn_col<NCOL;icn_col++)
1197  // for(int ri=0;ri<NCOMPL;ri++)
1198  // {
1199  // runLog()<<"------";
1200  // runLog()<<&rwCol(reIm(cnCol(spin(cicc,
1201  // ispin),
1202  // icn_col),
1203  // ri),
1204  // irw_col);
1205  // }
1206 
1207  // runLog()<<"/////////////////////////////////////////////////////////////////";
1208 
1209  // double a=0.0;
1210  // for(int irw_col=0;irw_col<NCOL;irw_col++)
1211  // for(int ispin=0;ispin<NSPIN;ispin++)
1212  // for(int icn_col=0;icn_col<NCOL;icn_col++)
1213  // a+=imag(conj(rwCol(cnCol(spin(cicc,
1214  // ispin),
1215  // icn_col),
1216  // irw_col)));
1217  // // a+=real(conj(rwCol(cnCol(spin(cicc,
1218  // // ispin),
1219  // // icn_col),
1220  // // irw_col)));
1221 
1222  // runLog()<<a;
1223 
1224 
1225 /// Check the sum of two \c SmET
1226 ///
1227 /// Two tensors are tried to be summed
1228 void checkSumOfTwoSmETs()
1229 {
1230  /// Tensor kind to be used for first SmET
1231  using MyTk1=
1232  TensKind<CnCol,
1233  RwCol,
1234  CnSpin>;
1235 
1236  /// Tensor class to be used for first tensor
1237  using MyTens1=
1238  Tens<MyTk1,
1239  double>;
1240 
1241  /// Tensor kind to be used for second SmET
1242  using MyTk2=
1243  TensKind<RwCol,
1244  // RwSpin,
1245  CnSpin,
1246  Compl>;
1247 
1248  /// Tensor class to be used for second tensor
1249  using MyTens2=
1250  Tens<MyTk2,
1251  double>;
1252 
1253  /// Tensors used to test the sum
1254  MyTens1 a;
1255  for(int iCnCol=0;iCnCol<NCOL;iCnCol++)
1256  for(int iRwCol=0;iRwCol<NCOL;iRwCol++)
1257  for(int iCnSpin=0;iCnSpin<NSPIN;iCnSpin++)
1258  cnCol(rwCol(cnSpin(a,iCnSpin),iRwCol),iCnCol)=3.0;
1259 
1260  MyTens2 b;
1261  for(int iRwCol=0;iRwCol<NCOL;iRwCol++)
1262  for(int iCnSpin=0;iCnSpin<NSPIN;iCnSpin++)
1263  for(int iReIm=0;iReIm<NCOMPL;iReIm++)
1264  rwCol(cnSpin(reIm(b,iReIm),iCnSpin),iRwCol)=5.0;
1265 
1266  Tens<decltype((a+b).getMaximallyMergedCompsView())::Tk,double> d;
1267 
1268  d=(a+b).getMaximallyMergedCompsView();
1269 
1270  runLog()<<"d: "<<d.eval(1,1,1);
1271 
1272  //auto sum=a+b;
1273  // this was added here to show the maximally mergeable delims
1274  //int e=decltype(sum)::MergeableComps{};
1275  //int e=decltype(sum)::PosOfRef1TcsInResTk{};
1276  //int e=decltype(sum)::MergedDelims1<IntSeq<0,1,3,4>>{};
1277 
1278 
1279  //runLog()<<"Col: "<<c.compSize<RwCol>();
1280  //runLog()<<"Spin: "<<c.compSize<CnSpin>();
1281  runLog()<<"Tensor Kind of addendum 1: "<<decltype(a)::Tk::name();
1282  using M1=
1283  typename decltype(a)::MergeableComps;
1284  runLog()<<"Mergeability of addendum 1: "<<printIntSeq(M1{});
1285  runLog()<<"Tensor Kind of addendum 2: "<<decltype(b)::Tk::name();
1286  using M2=
1287  typename decltype(b)::MergeableComps;
1288  runLog()<<"Mergeability of addendum 2: "<<printIntSeq(M2{});
1289  runLog()<<"Tensor Kind: "<<decltype(a+b)::Tk::name();
1290 
1291  runLog()<<"PosOf types 1 present: "<<printIntSeq(TupleElementType<0,decltype(a+b)::PosOfResTcsPresInRefsTk>{});
1292  runLog()<<"PosOf types 2 present: "<<printIntSeq(TupleElementType<1,decltype(a+b)::PosOfResTcsPresInRefsTk>{});
1293 
1294  // using P1=
1295  // decltype(c)::posOfAddend1TcInResTk;
1296  // runLog()<<"PosOf types 1: "<<printIntSeq(P1{});
1297  // using P2=
1298  // decltype(c)::posOfAddend2TcInResTk;
1299  // runLog()<<"PosOf types 2: "<<printIntSeq(P2{});
1300 
1301  // using P3=
1302  // PairOfTensKindMergeability::template CompsMergeability<M1,M2,P1,P2>;
1303 
1304  // runLog()<<"Mergeability: "<<printIntSeq(P3{});
1305 
1306  // using MDel=
1307  // IntSeq<0,1,3,4>;
1308 
1309  // runLog()<<"Trying to merge with: "<<printIntSeq(MDel{});
1310 
1311  // using P4=
1312  // decltype(c)::template MergedDelims1<MDel>;
1313 
1314  // runLog()<<"The first needs to be merged like this: "<<printIntSeq(P4{});
1315 
1316  TEST_PASSED;
1317 }
1318 
1319 int main()
1320 {
1321  runLog()<<"Timings: "<<timings.isStarted()<<" "<<timings.currentMeasure().count();
1322  runLog()<<"Timings: "<<timings["ciao"].isStarted()<<" "<<timings["ciao"].currentMeasure().count();
1323 
1324  runLog()<<"Anna\n";
1325  {
1327  SCOPE_REAL_PRECISION(runLog,3);
1328  {
1330  SCOPE_ALWAYS_PUT_SIGN(runLog);
1331  SCOPE_REAL_PRECISION(runLog,10);
1332  runLog()<<1.23523524<<"\n";
1333  }
1334  runLog()<<1.23523524<<"\n";
1335 
1336  runLog()<<"Elena\n";
1337  }
1338 
1339  runLog()<<"Caterina\n";
1340 
1341  checkSignUnsign();
1342 
1343  checkVectorClass();
1344 
1345  checkCombinatorial();
1346 
1347  checkNonComplConjCancelation();
1348 
1349  checkNestedConjCancelation();
1350 
1351  checkDuplicatedUMinusCancellation();
1352 
1353  checkFilterVariadicClassPos();
1354 
1355  checkScalarWrap();
1356 
1357  checkTensKindIscontained();
1358 
1359  // this is not passing...
1360  //checkCallOperator();
1361 
1362  checkGrid();
1363 
1364  checkFlagMasks();
1365 
1366  checkSafeModulo();
1367 
1368  checkFactorize();
1369 
1370  checkLhsTranspose();
1371 
1372  checkDuplicatedCallRemoverOrAbsorber();
1373 
1374  checkBinding();
1375 
1376  checkConj();
1377 
1378  checkSingleInstances();
1379 
1380  checkMPIisInitalized();
1381 
1382  checkMPIallReduce();
1383 
1384  checkSitmo();
1385 
1386  checkSerializer();
1387 
1388  checkValWithMax();
1389 
1390  return 0;
1391 }
Mpi mpi
Gloabl MPI.
Definition: SUNphi.cpp:212
#define STATIC_ASSERT_IS_BASE_OF(BASE, DERIVED)
Static assert if DERIVED does not derive from BASE.
Definition: TypeTraits.hpp:388
#define DEFINE_SERIALIZABLE_CLASS(T)
Shortcut to define a serializable class.
Definition: Map.hpp:194
#define LIST_SERIALIZABLE_MEMBERS(...)
Defines a list of serializable members.
Definition: Map.hpp:203
#define CRASH
Initialize the crasher.
Definition: Crash.hpp:13
bool isInitialized() const
Check initialization flag.
Definition: Mpi.hpp:122
#define CHECK(A)
#define SCOPE_ALWAYS_PUT_SIGN(STREAM)
Set printing always sign at the beginning of a number for current scope.
Definition: File.hpp:45
static constexpr const char * name()
Name of the Tk provided with "name()" suffix.
Definition: TensKind.hpp:117
#define SERIALIZABLE_SCALAR_WITH_TAG(TYPE, NAME, TAG,...)
Defines a serializable scalar with an explicit tag.
Definition: Scalar.hpp:15
ScopeIndenter(Logger &logger)
Create and increase indent level.
Definition: Logger.hpp:415
#define STATIC_ASSERT_DUPLICATED_CALL_ABSORBER(FUN,...)
Assert if a duplicated call is not absorbed.
Definition: checks.cpp:456
void divWithMod(Vector< TOut > &quotient, Vector< TOut > &remainder, const Vector &divisor) const
Returns the result and remainder of the division.
Definition: Vector.hpp:310
#define SERIALIZABLE_SCALAR(TYPE, NAME,...)
Defines a serializable scalar with the same tag of the variable name.
Definition: Scalar.hpp:19
Logger runLog("/dev/stdout")
Global logger.
~Tens()
Move constructor.
Definition: TensClass.hpp:120
int nRanks() const
Cached value of total number of ranks.
Definition: Mpi.hpp:224
static constexpr int element()
Get the I element of the sequence.
Definition: IntSeq.hpp:95
#define SCOPE_REAL_PRECISION(STREAM, VAL)
Set the precision for current scope.
Definition: File.hpp:25
decltype(auto) operator+(T1 &&smet1, T2 &&smet2)
Implement smet1+smet2.
Definition: Add.hpp:87
#define CHECK_SIGN(A, B)
#define SCOPE_INDENT(VAR)
Mark the stream to be more indented.
Definition: File.hpp:16
#define TEST_PASSED
Report that a test is passed.
Definition: checks.cpp:11
#define WARNING
Starts a new line in bold brown.
Definition: Warning.hpp:9
#define CHECK_UNSIGN(A, B)
Test class.
Definition: checks.cpp:550
#define SERIALIZABLE_CLASS(TYPE, NAME)
Defines a serializable class.
Definition: Map.hpp:199
#define STATIC_ASSERT_DUPLICATED_CALL_REMOVER(FUN,...)
Assert if a duplicated call is not removed.
Definition: checks.cpp:449