Cyclops Tensor Framework
parallel arithmetic on multidimensional arrays
force_integration_sparse.cxx
Go to the documentation of this file.
1 /*Copyright (c) 2011, Edgar Solomonik, all rights reserved.*/
2 
10 #include <ctf.hpp>
11 #include "moldynamics.h"
12 using namespace CTF;
13 
15  World & dw){
16  assert(n>1);
17 
20 
21  Vector<particle> P(n, dw, sP);
22  Matrix<force> F (n, n, AS | SP, dw, gF);
23  Matrix<force> F2(n, n, AS | SP, dw, gF);
24 
25  particle * loc_parts;
26  int64_t nloc;
27  int64_t * inds;
28  P.get_local_data(&nloc, &inds, &loc_parts);
29 
30  srand48(dw.rank);
31 
32  for (int64_t i=0; i<nloc; i++){
33  //put first particle in middle, so its always within cutoff of all other particles
34  if (inds[i] == 0){
35  loc_parts[i].dx = .5;
36  loc_parts[i].dy = .5;
37  } else {
38  loc_parts[i].dx = drand48();
39  loc_parts[i].dy = drand48();
40  }
41  loc_parts[i].coeff = .001*drand48();
42  loc_parts[i].id = 777;
43  }
44  P.write(nloc, inds, loc_parts);
45 
46  particle * all_parts;
47  int64_t nall;
48  std::vector< Pair<force> > my_forces;
49  P.read_all(&nall, &all_parts);
50  for (int i=0; i<nloc; i++){
51  for (int j=0; j<nall; j++){
52  if (j != inds[i]){
53  //add force if distance within 1/sqrt(2)
54  if (get_distance(loc_parts[i], all_parts[j])<.708){
55  my_forces.push_back( Pair<force>(inds[i]*n+j, get_force(loc_parts[i], all_parts[j])));
56  }
57  }
58  }
59  }
60  delete [] all_parts;
61 
62  F.write(my_forces.size(), &my_forces[0]);
63 
65 
66  F2["ij"] += F["ij"];
67  F2["ij"] += F["ij"];
68 
69 
70  uacc(F2["ij"],P["i"]);
71 
72  particle * loc_parts_new = new particle[nloc];
73  P.read(nloc, inds, loc_parts_new);
74 
75 
76  //check that something changed
77  int pass = 0;
78  for (int64_t i=0; i<nloc; i++){
79  if (fabs(loc_parts[i].dx - loc_parts_new[i].dx)>1.E-6 ||
80  fabs(loc_parts[i].dy - loc_parts_new[i].dy)>1.E-6) pass = 1;
81  }
82  MPI_Allreduce(MPI_IN_PLACE, &pass, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
83  if (!pass && dw.rank == 0){
84  printf("Test incorrect: application of uacc did not modify some value.\n");
85  }
86 
87  //FIXME = must invert tensors over groups via addinv() rather than - or -=, since these use the inverse of the multiplicative id
88  F.addinv();
89  uacc(F["ij"],P["i"]);
90  uacc(F["ij"],P["i"]);
91 
92  P.read(nloc, inds, loc_parts_new);
93  free(inds);
94 
95  if (pass){
96  for (int64_t i=0; i<nloc; i++){
97  if (fabs(loc_parts[i].dx - loc_parts_new[i].dx)>1.E-6 ||
98  fabs(loc_parts[i].dy - loc_parts_new[i].dy)>1.E-6) pass = 0;
99  }
100  }
101  delete [] loc_parts;
102  delete [] loc_parts_new;
103  MPI_Allreduce(MPI_IN_PLACE, &pass, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
104 
105  if (dw.rank == 0){
106  if (pass){
107  printf("{ P[\"i\"] = uacc(F[\"ij\"]) } passed\n");
108  } else {
109  printf("{ P[\"i\"] = uacc(F[\"ij\"]) } failed\n");
110  }
111  }
112 
113 
114  return pass;
115 }
116 
117 
118 #ifndef TEST_SUITE
119 
120 char* getCmdOption(char ** begin,
121  char ** end,
122  const std::string & option){
123  char ** itr = std::find(begin, end, option);
124  if (itr != end && ++itr != end){
125  return *itr;
126  }
127  return 0;
128 }
129 
130 
131 int main(int argc, char ** argv){
132  int rank, np, n;
133  int const in_num = argc;
134  char ** input_str = argv;
135 
136  MPI_Init(&argc, &argv);
137  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
138  MPI_Comm_size(MPI_COMM_WORLD, &np);
139 
140  if (getCmdOption(input_str, input_str+in_num, "-n")){
141  n = atoi(getCmdOption(input_str, input_str+in_num, "-n"));
142  if (n < 0) n = 5;
143  } else n = 5;
144 
145 
146  {
147  World dw(MPI_COMM_WORLD, argc, argv);
148 
149  if (rank == 0){
150  printf("Computing force_integration_sparse P_i = f(F_ij)\n");
151  }
153  }
154 
155 
156  MPI_Finalize();
157  return 0;
158 }
159 
165 #endif
Set class defined by a datatype and a min/max function (if it is partially ordered i...
Definition: set.h:280
Matrix class which encapsulates a 2D tensor.
Definition: matrix.h:18
def rank(self)
Definition: core.pyx:312
double dy
Definition: moldynamics.h:38
Definition: common.h:37
Vector class which encapsulates a 1D tensor.
Definition: vector.h:14
int force_integration_sparse(int n, World &dw)
an instance of the CTF library (world) on a MPI communicator
Definition: world.h:19
string
Definition: core.pyx:456
char * getCmdOption(char **begin, char **end, const std::string &option)
index-value pair used for tensor data input
Definition: tensor.h:28
void acc_force(force f, particle &p)
Definition: moldynamics.h:50
int rank
rank of local processor
Definition: world.h:24
double get_distance(particle const &p, particle const &q)
Definition: moldynamics.h:58
double coeff
Definition: moldynamics.h:39
Group is a Monoid with operator &#39;-&#39; defined special case (parent) of a ring.
Definition: group.h:16
force get_force(particle const p, particle const q)
Definition: moldynamics.h:65
Definition: apsp.cxx:17
double dx
Definition: moldynamics.h:37
int main(int argc, char **argv)
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