Cyclops Tensor Framework
parallel arithmetic on multidimensional arrays
dft_3D.cxx
Go to the documentation of this file.
1 /*Copyright (c) 2011, Edgar Solomonik, all rights reserved.*/
2 
11 #include <ctf.hpp>
12 using namespace CTF;
13 
14 
15 int test_dft_3D(int n,
16  World & wrld){
17  int myRank, numPes;
18  int i, j;
19  int64_t np;
20  int64_t * idx;
21  std::complex<long double> * data;
22  std::complex<long double> imag(0,1);
23 
24  int len[] = {n,n,n};
25  int sym[] = {NS,NS,NS};
26 
27  MPI_Comm_size(MPI_COMM_WORLD, &numPes);
28  MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
29 
31 
32  Matrix < std::complex<long double> >DFT(n, n, SY, wrld, ldr);
33  Matrix < std::complex<long double> >IDFT(n, n, SY, wrld, ldr);
34  Tensor < std::complex<long double> >MESH(3, len, sym, wrld, ldr);
35 
36  DFT.get_local_data(&np, &idx, &data);
37 
38  for (i=0; i<np; i++){
39  data[i] = ((long double)1./n)*exp(-2.*(idx[i]/n)*(idx[i]%n)*((long double)M_PI/n)*imag);
40  }
41  DFT.write(np, idx, data);
42  //DFT.print(stdout);
43  free(idx);
44  delete [] data;
45 
46  IDFT.get_local_data(&np, &idx, &data);
47 
48  for (i=0; i<np; i++){
49  data[i] = ((long double)1./n)*exp(2.*(idx[i]/n)*(idx[i]%n)*((long double)M_PI/n)*imag);
50  }
51  IDFT.write(np, idx, data);
52  //IDFT.print(stdout);
53  free(idx);
54  delete [] data;
55 
56  MESH.get_local_data(&np, &idx, &data);
57  for (i=0; i<np; i++){
58  for (j=0; j<n; j++){
59  data[i] += exp(imag*(long double)((-2.*M_PI*(j/(double)(n)))
60  *((idx[i]%n) + ((idx[i]/n)%n) +(idx[i]/(n*n)))));
61  }
62  }
63  MESH.write(np, idx, data);
64  //MESH.print(stdout);
65  free(idx);
66  delete [] data;
67 
68  MESH["ijk"] = 1.0*MESH["pqr"]*DFT["ip"]*DFT["jq"]*DFT["kr"];
69 
70  MESH.get_local_data(&np, &idx, &data);
71  //MESH.print(stdout);
72  int pass = 1;
73  for (i=0; i<np; i++){
74  if (idx[i]%n == (idx[i]/n)%n && idx[i]%n == idx[i]/(n*n)){
75  if (fabs((double)data[i].real() - 1.)>=1.E-9) pass = 0;
76  } else {
77  if (fabs((double)data[i].real())>=1.E-9) pass = 0;
78  }
79  }
80  MPI_Allreduce(MPI_IN_PLACE, &pass, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
81 
82  if (myRank == 0){
83  MPI_Reduce(MPI_IN_PLACE, &pass, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD);
84  if (pass)
85  printf("{ MESH[\"ijk\"] = MESH[\"pqr\"]*DFT[\"ip\"]*DFT[\"jq\"]*DFT[\"kr\"] } passed\n");
86  else
87  printf("{ MESH[\"ijk\"] = MESH[\"pqr\"]*DFT[\"ip\"]*DFT[\"jq\"]*DFT[\"kr\"] } failed\n");
88  } else
89  MPI_Reduce(&pass, MPI_IN_PLACE, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD);
90 
91  MPI_Barrier(MPI_COMM_WORLD);
92 
93 
94  free(idx);
95  delete [] data;
96  return pass;
97 }
98 
99 #ifndef TEST_SUITE
100 
103 int main(int argc, char ** argv){
104  int logn;
105  int64_t n;
106  MPI_Init(&argc, &argv);
107 
108  if (argc > 1){
109  logn = atoi(argv[1]);
110  if (logn<0) logn = 3;
111  } else {
112  logn = 3;
113  }
114  n = 1<<logn;
115 
116  {
117  World dw(argc, argv);
118  int pass = test_dft_3D(n, dw);
119  assert(pass);
120  }
121 
122  MPI_Finalize();
123 
124 }
130 #endif
int test_dft_3D(int n, World &wrld)
Definition: dft_3D.cxx:15
int main(int argc, char **argv)
Forms N-by-N DFT matrix A and inverse-dft iA and checks A*iA=I.
Definition: dft_3D.cxx:103
Ring class defined by a datatype and addition and multiplicaton functions addition must have an ident...
Definition: ring.h:18
Matrix class which encapsulates a 2D tensor.
Definition: matrix.h:18
def real(tensor, A)
Definition: core.pyx:2997
Definition: common.h:37
an instance of the CTF library (world) on a MPI communicator
Definition: world.h:19
def imag(tensor, A)
Definition: core.pyx:3038
def exp(init_x, out=None, where=True, casting='same_kind', order='F', dtype=None, subok=True)
Definition: core.pyx:3954
void get_local_data(int64_t *npair, int64_t **global_idx, dtype **data, bool nonzeros_only=false, bool unpack_sym=false) const
Gives the global indices and values associated with the local data.
Definition: tensor.cxx:159
Definition: apsp.cxx:17
an instance of a tensor within a CTF world
Definition: tensor.h:74
Definition: common.h:37
void write(int64_t npair, int64_t const *global_idx, dtype const *data)
writes in values associated with any set of indices The sparse data is defined in coordinate format...
Definition: tensor.cxx:264
def np(self)
Definition: core.pyx:315