MOAB: Mesh Oriented datABase  (version 5.5.0)
adj_mem_time_test.cpp
Go to the documentation of this file.
1 /*This function profiles the performance of the AHF datastructure */
2 #include <iostream>
3 #include <cassert>
4 #include <ctime>
5 #include <vector>
6 #include "moab/Core.hpp"
7 #include "moab/Range.hpp"
8 #include "moab/MeshTopoUtil.hpp"
9 #include "moab/HalfFacetRep.hpp"
10 #include "../TestUtil.hpp"
11 #include "moab/CpuTimer.hpp"
12 
13 #ifdef MOAB_HAVE_MPI
14 #include "moab/ParallelComm.hpp"
15 #include "MBParallelConventions.h"
16 #include "moab/FileOptions.hpp"
17 #include "MBTagConventions.hpp"
18 #include "moab_mpi.h"
19 #endif
20 
21 using namespace moab;
22 
23 #ifdef MOAB_HAVE_MPI
24 std::string read_options;
25 #endif
26 
29 
30 struct query_time
31 {
57 };
58 
59 struct mesh_mem
60 {
61  unsigned long long total_storage[2];
62  unsigned long long amortized_total_storage[2];
63  unsigned long long entity_storage[2];
64  unsigned long long amortized_entity_storage[2];
65  unsigned long long adjacency_storage[2];
66  unsigned long long amortized_adjacency_storage[2];
67  unsigned long long tag_storage[2];
68  unsigned long long amortized_tag_storage[2];
69 };
70 
71 void handle_error_code( ErrorCode rv, int& number_failed, int& number_successful )
72 {
73  if( rv == MB_SUCCESS )
74  {
75 #ifdef MOAB_HAVE_MPI
76  int rank = 0;
77  MPI_Comm_rank( MPI_COMM_WORLD, &rank );
78  if( rank == 0 ) std::cout << "Success";
79 #else
80  std::cout << "Success";
81 #endif
82  number_successful++;
83  }
84  else
85  {
86  std::cout << "Failure";
87  number_failed++;
88  }
89 }
90 
91 ErrorCode adj_perf( const char* filename )
92 {
94  Core moab;
95  Interface* mbImpl = &moab;
96  MeshTopoUtil mtu( mbImpl );
97 
98  struct query_time qtime;
99  struct mesh_mem qmem;
100 
101 #ifdef MOAB_HAVE_MPI
102  int procs = 1;
103  MPI_Comm_size( MPI_COMM_WORLD, &procs );
104 
105  if( procs > 1 )
106  {
107  read_options = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARALLEL_RESOLVE_SHARED_ENTS";
108 
109  error = mbImpl->load_file( filename, 0, read_options.c_str() );CHECK_ERR( error );
110  }
111  else if( procs == 1 )
112  {
113 #endif
114  error = mbImpl->load_file( filename );CHECK_ERR( error );
115 #ifdef MOAB_HAVE_MPI
116  }
117 #endif
118 
119  // Storage Costs before any call to adjacencies
120  unsigned long long sTotS, sTAS, sES, sAES, sAS, sAAS, sTS, sATS;
121  sTotS = sTAS = sES = sAES = sAS = sAAS = sTS = sATS = 0;
122  mbImpl->estimated_memory_use( NULL, 0, &sTotS, &sTAS, &sES, &sAES, &sAS, &sAAS, NULL, 0, &sTS, &sATS );
123 
124  qmem.total_storage[0] = sTotS;
125  qmem.amortized_total_storage[0] = sTAS;
126  qmem.entity_storage[0] = sES;
127  qmem.amortized_entity_storage[0] = sAES;
128  qmem.adjacency_storage[0] = sAS;
129  qmem.amortized_adjacency_storage[0] = sAAS;
130  qmem.tag_storage[0] = sTS;
131  qmem.amortized_tag_storage[0] = sATS;
132 
133  // Create ranges for handles of explicit elements of the mixed mesh
134  Range verts, edges, faces, cells;
135  error = mbImpl->get_entities_by_dimension( 0, 0, verts );
136  error = mbImpl->get_entities_by_dimension( 0, 1, edges );
137  error = mbImpl->get_entities_by_dimension( 0, 2, faces );
138  error = mbImpl->get_entities_by_dimension( 0, 3, cells );
139 
140  int nverts = verts.size();
141  int nedges = edges.size();
142  int nfaces = faces.size();
143  int ncells = cells.size();
144 
145  std::cout << "MESH SIZE :: "
146  << "NV = " << nverts << ", NE = " << nedges << ", NF = " << nfaces << ", NC = " << ncells << std::endl;
147 
148  CpuTimer* mt = new CpuTimer;
149  double time_start, time_avg, time_total;
150 
151  // Perform queries
152  std::vector< EntityHandle > adjents;
153  Range ngbents;
154 
155  // This call should create all the necessary ahf maps or adjacency lists
156  time_start = mt->time_elapsed();
157  error = mbImpl->get_adjacencies( &*verts.begin(), 1, 1, false, adjents );
158  time_total = mt->time_elapsed() - time_start;
159  qtime.ds_construction = time_total;
160 
161  // 1D Queries
162 
163  std::cout << "1D QUERIES Start" << std::endl;
164 
165  // IQ1: For every vertex, obtain incident edges
166  time_start = mt->time_elapsed();
167  for( Range::iterator i = verts.begin(); i != verts.end(); ++i )
168  {
169  adjents.clear();
170  error = mbImpl->get_adjacencies( &*i, 1, 1, false, adjents );
171  }
172  time_total = mt->time_elapsed() - time_start;
173  time_avg = time_total / (double)verts.size();
174 
175  qtime.vertex_to_edges_total = time_total;
176  qtime.vertex_to_edges_avg = time_avg;
177 
178  // NQ1: For every edge, obtain neighbor edges
179 #ifdef MOAB_HAVE_AHF
180  time_start = mt->time_elapsed();
181  for( Range::iterator i = edges.begin(); i != edges.end(); ++i )
182  {
183  adjents.clear();
184  error = mbImpl->get_adjacencies( &*i, 1, 1, false, adjents );
185  }
186  time_total = mt->time_elapsed() - time_start;
187  time_avg = time_total / (double)edges.size();
188 #else
189  error = mtu.get_bridge_adjacencies( *edges.begin(), 0, 1, ngbents );
190  time_start = mt->time_elapsed();
191  for( Range::iterator i = edges.begin(); i != edges.end(); ++i )
192  {
193  ngbents.clear();
194  error = mtu.get_bridge_adjacencies( *i, 0, 1, ngbents );
195  }
196  time_total = mt->time_elapsed() - time_start;
197  time_avg = time_total / (double)edges.size();
198 #endif
199 
200  qtime.edge_to_edges_total = time_total;
201  qtime.edge_to_edges_avg = time_avg;
202 
203  std::cout << "1D QUERIES End" << std::endl;
204 
205  // 2D Queries
206 
207  std::cout << "2D QUERIES Start" << std::endl;
208 
209  // IQ21: For every vertex, obtain incident faces
210  time_start = mt->time_elapsed();
211  for( Range::iterator i = verts.begin(); i != verts.end(); ++i )
212  {
213  adjents.clear();
214  error = mbImpl->get_adjacencies( &*i, 1, 2, false, adjents );
215  }
216  time_total = mt->time_elapsed() - time_start;
217  time_avg = time_total / (double)verts.size();
218 
219  qtime.vertex_to_faces_total = time_total;
220  qtime.vertex_to_faces_avg = time_avg;
221 
222  // IQ22: For every edge, obtain incident faces
223  time_start = mt->time_elapsed();
224  for( Range::iterator i = edges.begin(); i != edges.end(); ++i )
225  {
226  adjents.clear();
227  error = mbImpl->get_adjacencies( &*i, 1, 2, false, adjents );
228  }
229  time_total = mt->time_elapsed() - time_start;
230  time_avg = time_total / (double)edges.size();
231 
232  qtime.edge_to_faces_total = time_total;
233  qtime.edge_to_faces_avg = time_avg;
234 
235  // NQ2: For every face, obtain neighbor faces
236 #ifdef MOAB_HAVE_AHF
237  time_start = mt->time_elapsed();
238  for( Range::iterator i = faces.begin(); i != faces.end(); ++i )
239  {
240  adjents.clear();
241  error = mbImpl->get_adjacencies( &*i, 1, 2, false, adjents );
242  }
243  time_total = mt->time_elapsed() - time_start;
244  time_avg = time_total / (double)faces.size();
245 #else
246  error = mtu.get_bridge_adjacencies( *faces.begin(), 1, 2, ngbents );
247  time_start = mt->time_elapsed();
248  for( Range::iterator i = faces.begin(); i != faces.end(); ++i )
249  {
250  ngbents.clear();
251  error = mtu.get_bridge_adjacencies( *i, 1, 2, ngbents );
252  }
253  time_total = mt->time_elapsed() - time_start;
254  time_avg = time_total / (double)faces.size();
255 #endif
256 
257  qtime.face_to_faces_total = time_total;
258  qtime.face_to_faces_avg = time_avg;
259 
260  // DQ2: For every face, obtain its edges
261  time_start = mt->time_elapsed();
262  for( Range::iterator i = faces.begin(); i != faces.end(); ++i )
263  {
264  adjents.clear();
265  error = mbImpl->get_adjacencies( &*i, 1, 1, false, adjents );
266  }
267  time_total = mt->time_elapsed() - time_start;
268  time_avg = time_total / (double)faces.size();
269 
270  qtime.face_to_edges_total = time_total;
271  qtime.face_to_edges_avg = time_avg;
272 
273  std::cout << "2D QUERIES End" << std::endl;
274 
275  // 3D Queries
276 
277  std::cout << "3D QUERIES Start " << std::endl;
278 
279  // IQ31: For every vertex, obtain incident cells
280  time_start = mt->time_elapsed();
281  for( Range::iterator i = verts.begin(); i != verts.end(); ++i )
282  {
283  adjents.clear();
284  error = mbImpl->get_adjacencies( &*i, 1, 3, false, adjents );
285  }
286  time_total = mt->time_elapsed() - time_start;
287  time_avg = time_total / (double)verts.size();
288 
289  qtime.vertex_to_cells_total = time_total;
290  qtime.vertex_to_cells_avg = time_avg;
291 
292  // IQ 32: For every edge, obtain incident cells
293  time_start = mt->time_elapsed();
294  for( Range::iterator i = edges.begin(); i != edges.end(); ++i )
295  {
296  adjents.clear();
297  error = mbImpl->get_adjacencies( &*i, 1, 3, false, adjents );
298  }
299  time_total = mt->time_elapsed() - time_start;
300  time_avg = time_total / (double)edges.size();
301 
302  qtime.edge_to_cells_total = time_total;
303  qtime.edge_to_cells_avg = time_avg;
304 
305  // IQ32: For every face, obtain incident cells
306  time_start = mt->time_elapsed();
307  for( Range::iterator i = faces.begin(); i != faces.end(); ++i )
308  {
309  adjents.clear();
310  error = mbImpl->get_adjacencies( &*i, 1, 3, false, adjents );
311  }
312  time_total = mt->time_elapsed() - time_start;
313  time_avg = time_total / (double)faces.size();
314 
315  qtime.face_to_cells_total = time_total;
316  qtime.face_to_cells_avg = time_avg;
317 
318  // NQ3: For every cell, obtain neighbor cells
319 #ifdef MOAB_HAVE_AHF
320  time_start = mt->time_elapsed();
321  for( Range::iterator i = cells.begin(); i != cells.end(); ++i )
322  {
323  adjents.clear();
324  error = mbImpl->get_adjacencies( &*i, 1, 3, false, adjents );
325  }
326  time_total = mt->time_elapsed() - time_start;
327  time_avg = time_total / (double)cells.size();
328 #else
329  error = mtu.get_bridge_adjacencies( *cells.begin(), 2, 3, ngbents );
330  time_start = mt->time_elapsed();
331  for( Range::iterator i = cells.begin(); i != cells.end(); ++i )
332  {
333  ngbents.clear();
334  error = mtu.get_bridge_adjacencies( *i, 2, 3, ngbents );
335  }
336  time_total = mt->time_elapsed() - time_start;
337  time_avg = time_total / (double)cells.size();
338 #endif
339 
340  qtime.cell_to_cells_total = time_total;
341  qtime.cell_to_cells_avg = time_avg;
342 
343  // DQ31: For every cell, obtain its edges
344  time_start = mt->time_elapsed();
345  for( Range::iterator i = cells.begin(); i != cells.end(); ++i )
346  {
347  adjents.clear();
348  error = mbImpl->get_adjacencies( &*i, 1, 1, false, adjents );
349  }
350  time_total = mt->time_elapsed() - time_start;
351  time_avg = time_total / (double)cells.size();
352 
353  qtime.cell_to_edges_total = time_total;
354  qtime.cell_to_edges_avg = time_avg;
355 
356  // DQ32: For every cell, obtain its faces
357  time_start = mt->time_elapsed();
358  for( Range::iterator i = cells.begin(); i != cells.end(); ++i )
359  {
360  adjents.clear();
361  error = mbImpl->get_adjacencies( &*i, 1, 2, false, adjents );
362  }
363  time_total = mt->time_elapsed() - time_start;
364  time_avg = time_total / (double)cells.size();
365 
366  qtime.cell_to_faces_total = time_total;
367  qtime.cell_to_faces_avg = time_avg;
368 
369  std::cout << "3D QUERIES End" << std::endl;
370 
371  // Storage Costs after calling ahf deinitialize
372  unsigned long long eTotS, eTAS, eES, eAES, eAS, eAAS, eTS, eATS;
373  eTotS = eTAS = eES = eAES = eAS = eAAS = eTS = eATS = 0;
374  mbImpl->estimated_memory_use( NULL, 0, &eTotS, &eTAS, &eES, &eAES, &eAS, &eAAS, NULL, 0, &eTS, &eATS );
375 
376  qmem.total_storage[1] = eTotS;
377  qmem.amortized_total_storage[1] = eTAS;
378  qmem.entity_storage[1] = eES;
379  qmem.amortized_entity_storage[1] = eAES;
380  qmem.adjacency_storage[1] = eAS;
381  qmem.amortized_adjacency_storage[1] = eAAS;
382  qmem.tag_storage[1] = eTS;
383  qmem.amortized_tag_storage[1] = eATS;
384 
385  // Print times
386  std::cout << std::endl;
387  std::cout << " Data Structure Construction Time = " << qtime.ds_construction << " Secs" << std::endl;
388  std::cout << std::endl;
389  std::cout << "Query times in Seconds" << std::endl;
390 #ifdef MOAB_HAVE_AHF
391  std::cout << "QUERY: Vertex -> Edges :: MOAB_AHF: Average time = " << qtime.vertex_to_edges_avg;
392  std::cout << ", Total time = " << qtime.vertex_to_edges_total << std::endl;
393  std::cout << std::endl;
394 #else
395  std::cout << "QUERY: Vertex -> Edges :: MOAB: Average time = " << qtime.vertex_to_edges_avg;
396  std::cout << ", Total time = " << qtime.vertex_to_edges_total << std::endl;
397  std::cout << std::endl;
398 #endif
399 
400 #ifdef MOAB_HAVE_AHF
401  std::cout << "QUERY: Edge -> Edges :: MOAB_AHF: Average time = " << qtime.edge_to_edges_avg;
402  std::cout << ", Total time = " << qtime.edge_to_edges_total << std::endl;
403  std::cout << std::endl;
404 #else
405  std::cout << "QUERY: Edge -> Edges :: MOAB: Average time = " << qtime.edge_to_edges_avg;
406  std::cout << ", Total time = " << qtime.edge_to_edges_total << std::endl;
407  std::cout << std::endl;
408 #endif
409 
410 #ifdef MOAB_HAVE_AHF
411  std::cout << "QUERY: Vertex -> Faces :: MOAB_AHF: Average time = " << qtime.vertex_to_faces_avg;
412  std::cout << ", Total time = " << qtime.vertex_to_faces_total << std::endl;
413  std::cout << std::endl;
414 #else
415  std::cout << "QUERY: Vertex -> Faces :: MOAB: Average time = " << qtime.vertex_to_faces_avg;
416  std::cout << ", Total time = " << qtime.vertex_to_faces_total << std::endl;
417  std::cout << std::endl;
418 #endif
419 
420 #ifdef MOAB_HAVE_AHF
421  std::cout << "QUERY: Edge -> Faces :: MOAB_AHF: Average time = " << qtime.edge_to_faces_avg;
422  std::cout << ", Total time = " << qtime.edge_to_faces_total << std::endl;
423  std::cout << std::endl;
424 #else
425  std::cout << "QUERY: Edge -> Faces :: MOAB: Average time = " << qtime.edge_to_faces_avg;
426  std::cout << ", Total time = " << qtime.edge_to_faces_total << std::endl;
427  std::cout << std::endl;
428 #endif
429 
430 #ifdef MOAB_HAVE_AHF
431  std::cout << "QUERY: Face -> Faces :: MOAB_AHF: Average time = " << qtime.face_to_faces_avg;
432  std::cout << ", Total time = " << qtime.face_to_faces_total << std::endl;
433  std::cout << std::endl;
434 #else
435  std::cout << "QUERY: Face -> Faces :: MOAB: Average time = " << qtime.face_to_faces_avg;
436  std::cout << ", Total time = " << qtime.face_to_faces_total << std::endl;
437  std::cout << std::endl;
438 #endif
439 
440 #ifdef MOAB_HAVE_AHF
441  std::cout << "QUERY: Face -> Edges :: MOAB_AHF: Average time = " << qtime.face_to_edges_avg;
442  std::cout << ", Total time = " << qtime.face_to_edges_total << std::endl;
443  std::cout << std::endl;
444 #else
445  std::cout << "QUERY: Face -> Edges :: MOAB: Average time = " << qtime.face_to_edges_avg;
446  std::cout << ", Total time = " << qtime.face_to_edges_total << std::endl;
447  std::cout << std::endl;
448 #endif
449 
450 #ifdef MOAB_HAVE_AHF
451  std::cout << "QUERY: Vertex -> Cells :: MOAB_AHF: Average time = " << qtime.vertex_to_cells_avg;
452  std::cout << ", Total time = " << qtime.vertex_to_cells_total << std::endl;
453  std::cout << std::endl;
454 #else
455  std::cout << "QUERY: Vertex -> Cells :: MOAB: Average time = " << qtime.vertex_to_cells_avg;
456  std::cout << ", Total time = " << qtime.vertex_to_cells_total << std::endl;
457  std::cout << std::endl;
458 #endif
459 
460 #ifdef MOAB_HAVE_AHF
461  std::cout << "QUERY: Edge -> Cells :: MOAB_AHF: Average time = " << qtime.edge_to_cells_avg;
462  std::cout << ", Total time = " << qtime.edge_to_cells_total << std::endl;
463  std::cout << std::endl;
464 #else
465  std::cout << "QUERY: Edge -> Cells :: MOAB: Average time = " << qtime.edge_to_cells_avg;
466  std::cout << ", Total time = " << qtime.edge_to_cells_total << std::endl;
467  std::cout << std::endl;
468 #endif
469 
470 #ifdef MOAB_HAVE_AHF
471  std::cout << "QUERY: Face -> Cells :: MOAB_AHF: Average time = " << qtime.face_to_cells_avg;
472  std::cout << ", Total time = " << qtime.face_to_cells_total << std::endl;
473  std::cout << std::endl;
474 #else
475  std::cout << "QUERY: Face -> Cells :: MOAB: Average time = " << qtime.face_to_cells_avg;
476  std::cout << ", Total time = " << qtime.face_to_cells_total << std::endl;
477  std::cout << std::endl;
478 #endif
479 
480 #ifdef MOAB_HAVE_AHF
481  std::cout << "QUERY: Cell -> Cells :: MOAB_AHF: Average time = " << qtime.cell_to_cells_avg;
482  std::cout << ", Total time = " << qtime.cell_to_cells_total << std::endl;
483  std::cout << std::endl;
484 #else
485  std::cout << "QUERY: Cell -> Cells :: MOAB: Average time = " << qtime.cell_to_cells_avg;
486  std::cout << ", Total time = " << qtime.cell_to_cells_total << std::endl;
487  std::cout << std::endl;
488 #endif
489 
490 #ifdef MOAB_HAVE_AHF
491  std::cout << "QUERY: Cell -> Edges :: MOAB_AHF: Average time = " << qtime.cell_to_edges_avg;
492  std::cout << ", Total time = " << qtime.cell_to_edges_total << std::endl;
493  std::cout << std::endl;
494 #else
495  std::cout << "QUERY: Cell -> Edges :: MOAB: Average time = " << qtime.cell_to_edges_avg;
496  std::cout << ", Total time = " << qtime.cell_to_edges_total << std::endl;
497  std::cout << std::endl;
498 #endif
499 
500 #ifdef MOAB_HAVE_AHF
501  std::cout << "QUERY: Cell -> Faces :: MOAB_AHF: Average time = " << qtime.cell_to_faces_avg;
502  std::cout << ", Total time = " << qtime.cell_to_faces_total << std::endl;
503  std::cout << std::endl;
504 #else
505  std::cout << "QUERY: Cell -> Faces :: MOAB: Average time = " << qtime.cell_to_faces_avg;
506  std::cout << ", Total time = " << qtime.cell_to_faces_total << std::endl;
507  std::cout << std::endl;
508 #endif
509 
510  // Print Storage
511  std::cout << std::endl;
512  for( int i = 0; i < 2; i++ )
513  {
514  if( i == 0 )
515  std::cout << "STORAGE BEFORE CALLING ADJACENCIES" << std::endl;
516  else
517  std::cout << "STORAGE AFTER CALLING ADJACENCIES" << std::endl;
518 
519  std::cout << "Total storage = " << qmem.total_storage[i] << std::endl;
520  std::cout << "Total amortized storage = " << qmem.amortized_total_storage[i] << std::endl;
521  std::cout << std::endl;
522 
523  std::cout << "Entity storage = " << qmem.entity_storage[i] << std::endl;
524  std::cout << "Amortized entity storage = " << qmem.amortized_entity_storage[i] << std::endl;
525  std::cout << std::endl;
526 
527  std::cout << "Adjacency storage = " << qmem.adjacency_storage[i] << std::endl;
528  std::cout << "Amortized adjacency storage = " << qmem.amortized_adjacency_storage[i] << std::endl;
529  std::cout << std::endl;
530 
531  std::cout << "Tag storage = " << qmem.tag_storage[i] << std::endl;
532  std::cout << "Amortized tag storage = " << qmem.amortized_tag_storage[i] << std::endl;
533  std::cout << std::endl;
534  }
535 
536  double total_time = qtime.vertex_to_edges_total + qtime.edge_to_edges_total + qtime.vertex_to_faces_total +
540 
541  // Print values in a line to aid data copying later
542  std::cout << qtime.ds_construction << " " << total_time << " " << qmem.entity_storage[1] << " "
543  << qmem.adjacency_storage[1] << " " << qtime.vertex_to_edges_avg << " " << qtime.edge_to_edges_avg
544  << " " << qtime.vertex_to_faces_avg << " " << qtime.edge_to_faces_avg << " " << qtime.face_to_faces_avg
545  << " " << qtime.face_to_edges_avg << " " << qtime.vertex_to_cells_avg << " " << qtime.edge_to_cells_avg
546  << " " << qtime.face_to_cells_avg << " " << qtime.cell_to_cells_avg << " " << qtime.cell_to_edges_avg
547  << " " << qtime.cell_to_faces_avg << std::endl;
548 
549  delete mt;
550  return MB_SUCCESS;
551 }
552 
553 int main( int argc, char* argv[] )
554 {
555 
556 #ifdef MOAB_HAVE_MPI
557  MPI_Init( &argc, &argv );
558 
559  int nprocs, rank;
560  MPI_Comm_size( MPI_COMM_WORLD, &nprocs );
561  MPI_Comm_rank( MPI_COMM_WORLD, &rank );
562 #endif
563 
564  std::string filename;
565 #ifdef MOAB_HAVE_HDF5
566  filename = TestDir + "unittest/32hex_ef.h5m";
567 #else
568  filename = TestDir + "unittest/hexes_mixed.vtk";
569 #endif
570 
571  if( argc == 1 )
572  {
573 #ifdef MOAB_HAVE_MPI
574  if( rank == 0 ) std::cout << "Using default input file:" << filename << std::endl;
575 #else
576  std::cout << "Using default input file:" << filename << std::endl;
577 #endif
578  }
579 
580  else if( argc == 2 )
581  filename = argv[1];
582  else
583  {
584  std::cerr << "Usage: " << argv[0] << " [filename]" << std::endl;
585  return 1;
586  }
587 
588  ErrorCode result;
589 
590 #ifdef MOAB_HAVE_MPI
591  if( rank == 0 ) std::cout << " para_adj_perf: ";
592 #else
593  std::cout << "adj_perf:";
594 #endif
595 
596  result = adj_perf( filename.c_str() );
598  std::cout << "\n";
599 
600 #ifdef MOAB_HAVE_MPI
601  MPI_Finalize();
602 #endif
603 
604  return number_tests_failed;
605 }