MOAB: Mesh Oriented datABase  (version 5.5.0)
tree_searching_perf.cpp
Go to the documentation of this file.
1 #include "moab/Core.hpp"
3 #include "moab/Tree.hpp"
4 #include "moab/HomXform.hpp"
5 #include "moab/ScdInterface.hpp"
6 #include "moab/CartVect.hpp"
8 #include "moab/BVHTree.hpp"
9 #include "moab/ProgOptions.hpp"
10 #include "moab/CpuTimer.hpp"
11 
12 #ifdef MOAB_HAVE_MPI
13 #include "moab_mpi.h"
14 #endif
15 
16 #include <cstdlib>
17 #include <sstream>
18 
19 using namespace moab;
20 
21 ErrorCode test_locator( SpatialLocator& sl, int npoints, double& cpu_time, double& percent_outside );
22 ErrorCode create_hex_mesh( Interface& mb, Range& elems, int n, int dim );
23 
24 int main( int argc, char** argv )
25 {
26 #ifdef MOAB_HAVE_MPI
27  int fail = MPI_Init( &argc, &argv );
28  if( fail ) return fail;
29 #else
30  // silence the warning of parameters not used, in serial; there should be a smarter way :(
31  argv[0] = argv[argc - argc];
32 #endif
33 
34  int npoints = 100, dim = 3;
35  int dints = 1, dleafs = 1, ddeps = 1, csints = 0;
36 
37  ProgOptions po;
38  po.addOpt< int >( "candidateplaneset,c",
39  "Candidate plane set (0=SUBDIVISION,1=SUBDIV_SNAP,2=VERTEX_MEDIAN,3=VERTEX_SAMPLE", &csints );
40  po.addOpt< int >( "ints,i", "Number of doublings of intervals on each side of scd mesh", &dints );
41  po.addOpt< int >( "leaf,l", "Number of doublings of maximum number of elements per leaf", &dleafs );
42  po.addOpt< int >( "max_depth,m", "Number of 5-intervals on maximum depth of tree", &ddeps );
43  po.addOpt< int >( "npoints,n", "Number of query points", &npoints );
44  po.addOpt< int >( "dim,d", "Dimension of the mesh", &dim );
45  // po.addOpt<void>( "print,p", "Print tree details", &print_tree);
46  po.parseCommandLine( argc, argv );
47 
48  std::vector< int > ints, deps, leafs;
49  ints.push_back( 10 );
50  for( int i = 1; i < dints; i++ )
51  ints.push_back( 2 * ints[i - 1] );
52  deps.push_back( 30 );
53  for( int i = 1; i < ddeps; i++ )
54  deps.push_back( deps[i - 1] - 5 );
55  leafs.push_back( 6 );
56  for( int i = 1; i < dleafs; i++ )
57  leafs.push_back( 2 * leafs[i - 1] );
58 
59  ErrorCode rval = MB_SUCCESS;
60  std::cout << "Tree_type"
61  << " "
62  << "Elems_per_leaf"
63  << " "
64  << "Tree_depth"
65  << " "
66  << "Ints_per_side"
67  << " "
68  << "N_elements"
69  << " "
70  << "search_time"
71  << " "
72  << "perc_outside"
73  << " "
74  << "initTime"
75  << " "
76  << "nodesVisited"
77  << " "
78  << "leavesVisited"
79  << " "
80  << "numTraversals"
81  << " "
82  << "leafObjectTests" << std::endl;
83 
84  // outermost iteration: # elements
85  for( std::vector< int >::iterator int_it = ints.begin(); int_it != ints.end(); ++int_it )
86  {
87  Core mb;
88  Range elems;
89  rval = create_hex_mesh( mb, elems, *int_it, dim );
90  if( MB_SUCCESS != rval ) return rval;
91 
92  // iteration: tree depth
93  for( std::vector< int >::iterator dep_it = deps.begin(); dep_it != deps.end(); ++dep_it )
94  {
95 
96  // iteration: tree max elems/leaf
97  for( std::vector< int >::iterator leafs_it = leafs.begin(); leafs_it != leafs.end(); ++leafs_it )
98  {
99 
100  // iteration: tree type
101  for( int tree_tp = 0; tree_tp < 2; tree_tp++ )
102  {
103  // create tree
104  Tree* tree;
105  if( 0 == tree_tp )
106  tree = new BVHTree( &mb );
107  else
108  tree = new AdaptiveKDTree( &mb );
109 
110  std::ostringstream opts;
111  opts << "MAX_DEPTH=" << *dep_it << ";MAX_PER_LEAF=" << *leafs_it;
112  if( csints )
113  {
114  if( opts.str().length() > 0 ) opts << ";";
115  opts << "PLANE_SET=" << csints;
116  }
117  FileOptions fo( opts.str().c_str() );
118  rval = tree->parse_options( fo );
119  if( MB_SUCCESS != rval ) return rval;
120  SpatialLocator sl( &mb, elems, tree );
121 
122  // call evaluation
123  double cpu_time, perc_outside;
124  rval = test_locator( sl, npoints, cpu_time, perc_outside );
125  if( MB_SUCCESS != rval ) return rval;
126 
127  std::cout << ( tree_tp == 0 ? "BVH" : "KD" ) << " " << *leafs_it << " " << *dep_it << " " << *int_it
128  << " " << ( *int_it ) * ( *int_it ) * ( *int_it ) << " " << cpu_time << " "
129  << perc_outside << " ";
130 
131  tree->tree_stats().output_all_stats();
132 
133  } // tree_tp
134 
135  } // max elems/leaf
136 
137  } // max depth
138 
139  } // # elements
140 
141 #ifdef MOAB_HAVE_MPI
142  fail = MPI_Finalize();
143  if( fail ) return fail;
144 #endif
145 
146  return 0;
147 }
148 
149 ErrorCode test_locator( SpatialLocator& sl, int npoints, double& cpu_time, double& percent_outside )
150 {
151  BoundBox box = sl.local_box();
152  CartVect box_del = box.bMax - box.bMin;
153 
154  std::vector< CartVect > test_pts( npoints ), test_res( npoints );
155  std::vector< EntityHandle > ents( npoints );
156  int* is_in = new int[npoints];
157 
158  double denom = 1.0 / (double)RAND_MAX;
159  for( int i = 0; i < npoints; i++ )
160  {
161  // generate a small number of random point to test
162  double rx = (double)rand() * denom, ry = (double)rand() * denom, rz = (double)rand() * denom;
163  test_pts[i] = box.bMin + CartVect( rx * box_del[0], ry * box_del[1], rz * box_del[2] );
164  }
165 
166  CpuTimer ct;
167 
168  // call spatial locator to locate points
169  ErrorCode rval = sl.locate_points( test_pts[0].array(), npoints, &ents[0], test_res[0].array(), &is_in[0] );
170  if( MB_SUCCESS != rval )
171  {
172  delete[] is_in;
173  return rval;
174  }
175 
176  cpu_time = ct.time_elapsed();
177 
178  int num_out = std::count( is_in, is_in + npoints, false );
179  percent_outside = ( (double)num_out ) / npoints;
180  delete[] is_in;
181 
182  return rval;
183 }
184 
186 {
187  ScdInterface* scdi;
188  ErrorCode rval = mb.query_interface( scdi );
189  if( MB_SUCCESS != rval ) return rval;
190 
191  HomCoord high( n - 1, -1, -1 );
192  if( dim > 1 ) high[1] = n - 1;
193  if( dim > 2 ) high[2] = n - 1;
194  ScdBox* new_box;
195  rval = scdi->construct_box( HomCoord( 0, 0, 0 ), high, NULL, 0, new_box );
196  if( MB_SUCCESS != rval ) return rval;
197  rval = mb.release_interface( scdi );
198  if( MB_SUCCESS != rval ) return rval;
199 
200  rval = mb.get_entities_by_dimension( 0, dim, elems );
201  if( MB_SUCCESS != rval ) return rval;
202 
203  return rval;
204 }