Cyclops Tensor Framework
parallel arithmetic on multidimensional arrays
spectral_element.cxx
Go to the documentation of this file.
1 
7 #include <ctf.hpp>
8 using namespace CTF;
9 
18 int spectral(int n,
19  World & dw){
20  int lens_u[] = {n, n, n};
21 
22  Tensor<> u(3, lens_u);
23  Matrix<> D(n, n);
24  u.fill_random(0.0,1.0);
25  D.fill_random(0.0,1.0);
26 
27  Tensor<> ** G;
28  G = (Tensor<>**)malloc(sizeof(Tensor<>*)*3);
29  for (int a=0; a<3; a++){
30  G[a] = new Tensor<>[3];
31  for (int b=0; b<3; b++){
32  G[a][b] = Tensor<>(3, lens_u);
33  G[a][b].fill_random(0.0,1.0);
34  }
35  }
36 
37  Tensor<> * w = new Tensor<>[3];
38  Tensor<> * z = new Tensor<>[3];
39  for (int a=0; a<3; a++){
40  w[a] = Tensor<>(3, lens_u);
41  z[a] = Tensor<>(3, lens_u);
42  }
43 
44  double st_time = MPI_Wtime();
45 
46  w[0]["ijk"] = D["kl"]*u["ijl"];
47  w[1]["ijk"] = D["jl"]*u["ilk"];
48  w[2]["ijk"] = D["il"]*u["ljk"];
49 
50  for (int a=0; a<3; a++){
51  for (int b=0; b<3; b++){
52  z[a]["ijk"] += G[a][b]["ijk"]*w[b]["ijk"];
53  }
54  }
55 
56  u["ijk"] = D["lk"]*z[0]["ijl"];
57  u["ijk"] += D["lj"]*z[1]["ilk"];
58  u["ijk"] += D["li"]*z[2]["ljk"];
59 
60  double exe_time = MPI_Wtime() - st_time;
61 
62  bool pass = u.norm2() >= 1.E-6;
63 
64  for (int a=0; a<3; a++){
65  delete [] G[a];
66  }
67  free(G);
68  delete [] w;
69  delete [] z;
70 
71  if (dw.rank == 0){
72  if (pass)
73  printf("{ Spectral element method } passed \n");
74  else
75  printf("{ spectral element method } failed \n");
76  #ifndef TEST_SUITE
77  printf("Spectral element method on %d*%d*%d grid with %d processors took %lf seconds\n", n,n,n,dw.np,exe_time);
78  #endif
79  }
80  return pass;
81 }
82 
83 
84 #ifndef TEST_SUITE
85 char* getCmdOption(char ** begin,
86  char ** end,
87  const std::string & option){
88  char ** itr = std::find(begin, end, option);
89  if (itr != end && ++itr != end){
90  return *itr;
91  }
92  return 0;
93 }
94 
95 
96 int main(int argc, char ** argv){
97  int rank, np, n, pass;
98  int const in_num = argc;
99  char ** input_str = argv;
100 
101  MPI_Init(&argc, &argv);
102  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
103  MPI_Comm_size(MPI_COMM_WORLD, &np);
104 
105  if (getCmdOption(input_str, input_str+in_num, "-n")){
106  n = atoi(getCmdOption(input_str, input_str+in_num, "-n"));
107  if (n < 0) n = 16;
108  } else n = 16;
109 
110  {
111  World dw(argc, argv);
112 
113  if (rank == 0){
114  printf("Running 3D spectral element method with %d*%d*%d grid\n",n,n,n);
115  }
116  pass = spectral(n, dw);
117  assert(pass);
118  }
119 
120  MPI_Finalize();
121  return 0;
122 }
128 #endif
Matrix class which encapsulates a 2D tensor.
Definition: matrix.h:18
def rank(self)
Definition: core.pyx:312
an instance of the CTF library (world) on a MPI communicator
Definition: world.h:19
string
Definition: core.pyx:456
dtype norm2()
computes the frobenius norm of the tensor (needs sqrt()!)
Definition: tensor.h:811
void fill_random(dtype rmin, dtype rmax)
fills local unique tensor elements to random values in the range [min,max] works only for dtype in {f...
Definition: tensor.cxx:928
int rank
rank of local processor
Definition: world.h:24
char * getCmdOption(char **begin, char **end, const std::string &option)
Definition: apsp.cxx:17
an instance of a tensor within a CTF world
Definition: tensor.h:74
int main(int argc, char **argv)
int np
number of processors
Definition: world.h:26
def np(self)
Definition: core.pyx:315
int spectral(int n, World &dw)
computes the following kernel of the spectral element method Given u, D, and diagonal matrices G_{xy}...