Cyclops Tensor Framework
parallel arithmetic on multidimensional arrays
bivar_function.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 double f2(double a, double b){
14  return a*b+b*a;
15 }
16 
17 int bivar_function(int n,
18  World & dw){
19 
20  int shapeN4[] = {NS,NS,NS,NS};
21  int sizeN4[] = {n+1,n,n+2,n+3};
22 
23  Tensor<> A(4, sizeN4, shapeN4, dw);
24  Tensor<> B(4, sizeN4, shapeN4, dw);
25 
26  srand48(dw.rank);
27  A.fill_random(-.5, .5);
28  B.fill_random(-.5, .5);
29 
30 
31  double * all_start_data_A;
32  int64_t nall_A;
33  A.read_all(&nall_A, &all_start_data_A);
34  double * all_start_data_B;
35  int64_t nall_B;
36  B.read_all(&nall_B, &all_start_data_B);
37 
38  CTF::Function<> bfun([](double a, double b){ return a*b + b*a; });
39  .5*A["ijkl"]+=bfun(A["ijkl"],B["ijkl"]);
40 
41  double * all_end_data_A;
42  int64_t nall2_A;
43  A.read_all(&nall2_A, &all_end_data_A);
44 
45  int pass = (nall_A == nall2_A);
46  if (pass){
47  for (int64_t i=0; i<nall_A; i++){
48  if (fabs(.5*all_start_data_A[i]+f2(all_start_data_A[i],all_start_data_B[i])-all_end_data_A[i])>=1.E-6) pass =0;
49  }
50  }
51  MPI_Allreduce(MPI_IN_PLACE, &pass, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
52 
53  if (dw.rank == 0){
54  if (pass){
55  printf("{ A[\"ijkl\"] = f2(A[\"ijkl\"], B[\"ijkl\"]) } passed\n");
56  } else {
57  printf("{ A[\"ijkl\"] = f2(A[\"ijkl\"], B[\"ijkl\"]) } failed\n");
58  }
59  }
60 
61  delete [] all_start_data_A;
62  delete [] all_end_data_A;
63  delete [] all_start_data_B;
64 
65  return pass;
66 }
67 
68 
69 #ifndef TEST_SUITE
70 
71 char* getCmdOption(char ** begin,
72  char ** end,
73  const std::string & option){
74  char ** itr = std::find(begin, end, option);
75  if (itr != end && ++itr != end){
76  return *itr;
77  }
78  return 0;
79 }
80 
81 
82 int main(int argc, char ** argv){
83  int rank, np, n;
84  int const in_num = argc;
85  char ** input_str = argv;
86 
87  MPI_Init(&argc, &argv);
88  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
89  MPI_Comm_size(MPI_COMM_WORLD, &np);
90 
91  if (getCmdOption(input_str, input_str+in_num, "-n")){
92  n = atoi(getCmdOption(input_str, input_str+in_num, "-n"));
93  if (n < 0) n = 5;
94  } else n = 5;
95 
96 
97  {
98  World dw(MPI_COMM_WORLD, argc, argv);
99 
100  if (rank == 0){
101  printf("Computing bivar_function A_ijkl = f(B_ijkl, A_ijkl)\n");
102  }
103  bivar_function(n, dw);
104  }
105 
106 
107  MPI_Finalize();
108  return 0;
109 }
110 
116 #endif
int main(int argc, char **argv)
def rank(self)
Definition: core.pyx:312
int bivar_function(int n, World &dw)
void read_all(int64_t *npair, dtype **data, bool unpack=false)
collects the entire tensor data on each process (not memory scalable)
Definition: tensor.cxx:377
Definition: common.h:37
an instance of the CTF library (world) on a MPI communicator
Definition: world.h:19
double f2(double a, double b)
string
Definition: core.pyx:456
char * getCmdOption(char **begin, char **end, const std::string &option)
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
Definition: apsp.cxx:17
an instance of a tensor within a CTF world
Definition: tensor.h:74
def np(self)
Definition: core.pyx:315