Cyclops Tensor Framework
parallel arithmetic on multidimensional arrays
endomorphism_cust.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 struct cust_type {
14  char name[256];
15  int len_name;
16 };
17 
19  if (strlen(a.name) >= strlen(b.name)) return a;
20  else return b;
21 }
22 
23 void mpi_cadd(void * a, void * b, int * len, MPI_Datatype * d){
24  for (int i=0; i<*len; i++){
25  ((cust_type*)b)[i] = cadd(((cust_type*)a)[i], ((cust_type*)b)[i]);
26 
27  }
28 }
29 
31  World & dw){
32 
33  int shapeN4[] = {NS,NS,NS,NS};
34  int sizeN4[] = {n+1,n,n+2,n+3};
35 
36  cust_type addid;
37  addid.name[0] = '\0';
38  addid.len_name = 0;
39 
40  MPI_Op mop;
41  MPI_Op_create(&mpi_cadd, 1, &mop);
42 
44 
45  Tensor<cust_type> A(4, sizeN4, shapeN4, dw, m);
46 
47  int64_t * inds;
48  cust_type * vals;
49  int64_t nvals;
50 
51  A.get_local_data(&nvals, &inds, &vals);
52 
53  srand48(dw.rank);
54  for (int64_t i=0; i<nvals; i++){
55  int str_len = drand48()*250;
56  std::fill(vals[i].name, vals[i].name+str_len, 'a');
57  vals[i].name[str_len]='\0';
58  }
59 
60  A.write(nvals, inds, vals);
61 
63  [](cust_type & a){
64  a.len_name = strlen(a.name);
65  });
66  // below is equivalent to A.scale(NULL, "ijkl", endo);
67  endo(A["ijkl"]);
68 
69 
70  int64_t * indices;
71  cust_type * loc_data;
72  int64_t nloc;
73  A.get_local_data(&nloc, &indices, &loc_data);
74 
75  int pass = 1;
76  if (pass){
77  for (int64_t i=0; i<nloc; i++){
78  if ((int)strlen(loc_data[i].name) != loc_data[i].len_name) pass = 0;
79  }
80  }
81  MPI_Allreduce(MPI_IN_PLACE, &pass, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
82 
83  if (dw.rank == 0){
84  if (pass){
85  printf("{ A[\"ijkl\"] = comp_len(A[\"ijkl\"]) } passed\n");
86  } else {
87  printf("{ A[\"ijkl\"] = comp_len(A[\"ijkl\"]) } failed\n");
88  }
89  }
90 
91  free(indices);
92  delete [] loc_data;
93  delete [] vals;
94  free(inds);
95 
96  return pass;
97 }
98 
99 
100 #ifndef TEST_SUITE
101 
102 char* getCmdOption(char ** begin,
103  char ** end,
104  const std::string & option){
105  char ** itr = std::find(begin, end, option);
106  if (itr != end && ++itr != end){
107  return *itr;
108  }
109  return 0;
110 }
111 
112 
113 int main(int argc, char ** argv){
114  int rank, np, n;
115  int const in_num = argc;
116  char ** input_str = argv;
117 
118  MPI_Init(&argc, &argv);
119  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
120  MPI_Comm_size(MPI_COMM_WORLD, &np);
121 
122  if (getCmdOption(input_str, input_str+in_num, "-n")){
123  n = atoi(getCmdOption(input_str, input_str+in_num, "-n"));
124  if (n < 0) n = 5;
125  } else n = 5;
126 
127 
128  {
129  World dw(MPI_COMM_WORLD, argc, argv);
130 
131  if (rank == 0){
132  printf("Computing user-defined endomorphism on a tensor over a monoid, A_ijkl = f(A_ijkl)\n");
133  }
134  endomorphism_cust(n, dw);
135  }
136 
137 
138  MPI_Finalize();
139  return 0;
140 }
141 
147 #endif
char * getCmdOption(char **begin, char **end, const std::string &option)
def rank(self)
Definition: core.pyx:312
int main(int argc, char **argv)
Definition: common.h:37
char name[256]
int endomorphism_cust(int n, World &dw)
an instance of the CTF library (world) on a MPI communicator
Definition: world.h:19
string
Definition: core.pyx:456
int rank
rank of local processor
Definition: world.h:24
cust_type cadd(cust_type a, cust_type b)
void mpi_cadd(void *a, void *b, int *len, MPI_Datatype *d)
Definition: apsp.cxx:17
A Monoid is a Set equipped with a binary addition operator &#39;+&#39; or a custom function addition must hav...
Definition: monoid.h:69
an instance of a tensor within a CTF world
Definition: tensor.h:74
def np(self)
Definition: core.pyx:315