Cyclops Tensor Framework
parallel arithmetic on multidimensional arrays
dft.cxx
Go to the documentation of this file.
1 /*Copyright (c) 2011, Edgar Solomonik, all rights reserved.*/
2 
10 #include <ctf.hpp>
11 using namespace CTF;
12 
13 int test_dft(int64_t n,
14  World &wrld){
15  int numPes, myRank;
16  int64_t np, i;
17  int64_t * idx;
18  std::complex<double> * data;
19  std::complex<double> imag(0,1);
20  MPI_Comm_size(MPI_COMM_WORLD, &numPes);
21  MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
22  Matrix < std::complex<double> >DFT(n, n, SY, wrld, "DFT", 1);
23  Matrix < std::complex<double> >IDFT(n, n, SY, wrld, "IDFT", 0);
24 
25  DFT.get_local_data(&np, &idx, &data);
26 
27  for (i=0; i<np; i++){
28  data[i] = exp(-2.*(idx[i]/n)*(idx[i]%n)*(M_PI/n)*imag);
29  // printf("[%lld][%lld] (%20.14E,%20.14E)\n",i%n,i/n,data[i].real(),data[i].imag());
30  }
31  DFT.write(np, idx, data);
32  //DFT.print(stdout);
33  free(idx);
34  delete [] data;
35 
36  IDFT.get_local_data(&np, &idx, &data);
37 
38  for (i=0; i<np; i++){
39  data[i] = (1./n)*exp(2.*(idx[i]/n)*(idx[i]%n)*(M_PI/n)*imag);
40  }
41  IDFT.write(np, idx, data);
42  //IDFT.print(stdout);
43  free(idx);
44  delete [] data;
45 
46  /*DFT.contract(std::complex<double> (1.0, 0.0), DFT, "ij", IDFT, "jk",
47  std::complex<double> (0.0, 0.0), "ik");*/
48  DFT["ik"] = .5*DFT["ij"]*IDFT["jk"];
49 
51  ss[""] = Function< std::complex<double>, std::complex<double>, std::complex<double> >([](std::complex<double> a, std::complex<double> b){ return a+b; })(DFT["ij"],DFT["ij"]);
52 
53  DFT.get_local_data(&np, &idx, &data);
54  int pass = 1;
55  //DFT.print(stdout);
56  for (i=0; i<np; i++){
57  //printf("data[%lld] = %lf\n",idx[i],data[i].real());
58  if (idx[i]/n == idx[i]%n){
59  if (fabs(data[i].real() - 1.)>=1.E-9)
60  pass = 0;
61  } else {
62  if (fabs(data[i].real())>=1.E-9)
63  pass = 0;
64  }
65  }
66  MPI_Allreduce(MPI_IN_PLACE, &pass, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
67 
68  if (myRank == 0) {
69  MPI_Reduce(MPI_IN_PLACE, &pass, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD);
70  if (pass)
71  printf("{ DFT[\"ik\"] = DFT[\"ij\"]*IDFT[\"jk\"] } passed\n");
72  else
73  printf("{ DFT[\"ik\"] = DFT[\"ij\"]*IDFT[\"jk\"] } failed\n");
74  } else
75  MPI_Reduce(&pass, MPI_IN_PLACE, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD);
76 
77  MPI_Barrier(MPI_COMM_WORLD);
78 
79  free(idx);
80  delete [] data;
81  return pass;
82 }
83 
84 #ifndef TEST_SUITE
85 
88 int main(int argc, char ** argv){
89  int logn;
90  int64_t n;
91 
92  MPI_Init(&argc, &argv);
93 
94  if (argc > 1){
95  logn = atoi(argv[1]);
96  if (logn<0) logn = 5;
97  } else {
98  logn = 5;
99  }
100  n = 1<<logn;
101 
102 
103  {
104  World dw(argc, argv);
105  int pass = test_dft(n, dw);
106  assert(pass);
107  }
108 
109  MPI_Finalize();
110 
111 }
118 #endif
Matrix class which encapsulates a 2D tensor.
Definition: matrix.h:18
def real(tensor, A)
Definition: core.pyx:2997
int main(int argc, char **argv)
Forms N-by-N DFT matrix A and inverse-dft iA and checks A*iA=I.
Definition: dft.cxx:88
an instance of the CTF library (world) on a MPI communicator
Definition: world.h:19
def imag(tensor, A)
Definition: core.pyx:3038
Scalar class which encapsulates a 0D tensor.
Definition: scalar.h:13
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
int test_dft(int64_t n, World &wrld)
Definition: dft.cxx:13
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