1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: TestCellIterators.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15
16 #include "vtkCellIterator.h"
17
18 #include "vtkCellArray.h"
19 #include "vtkFloatArray.h"
20 #include "vtkGenericCell.h"
21 #include "vtkNew.h"
22 #include "vtkPoints.h"
23 #include "vtkSmartPointer.h"
24 #include "vtkTestUtilities.h"
25 #include "vtkTimerLog.h"
26 #include "vtkUnsignedCharArray.h"
27 #include "vtkUnstructuredGrid.h"
28 #include "vtkUnstructuredGridReader.h"
29
30 #include <sstream>
31 #include <string>
32
33 // Enable/disable code that helps/hinders profiling.
34 #undef PROFILE
35 //#define PROFILE
36
37 // Enable benchmarks.
38 #undef BENCHMARK
39 //#define BENCHMARK
40
41 #ifdef BENCHMARK
42 # ifdef PROFILE
43 # define NUM_BENCHMARKS 10
44 # else // PROFILE
45 # define NUM_BENCHMARKS 100
46 # endif // PROFILE
47 #endif // BENCHMARK
48
49 //------------------------------------------------------------------------------
50 // Compare the cell type, point ids, and points in 'grid' with those returned
51 // in 'iter'.
testCellIterator(vtkCellIterator * iter,vtkUnstructuredGrid * grid)52 bool testCellIterator(vtkCellIterator *iter, vtkUnstructuredGrid *grid)
53 {
54 vtkIdType cellId = 0;
55 vtkNew<vtkGenericCell> cell;
56 iter->InitTraversal();
57 while (!iter->IsDoneWithTraversal())
58 {
59 grid->GetCell(cellId, cell.GetPointer());
60
61 if (iter->GetCellType() != cell->GetCellType())
62 {
63 cerr << "Type mismatch for cell " << cellId << endl;
64 return false;
65 }
66
67 vtkIdType numPoints = iter->GetNumberOfPoints();
68 if (numPoints != cell->GetNumberOfPoints())
69 {
70 cerr << "Number of points mismatch for cell " << cellId << endl;
71 return false;
72 }
73
74 for (vtkIdType pointInd = 0; pointInd < numPoints; ++pointInd)
75 {
76 if (iter->GetPointIds()->GetId(pointInd)
77 != cell->PointIds->GetId(pointInd))
78 {
79 cerr << "Point id mismatch in cell " << cellId << endl;
80 return false;
81 }
82
83 double iterPoint[3];
84 double cellPoint[3];
85 iter->GetPoints()->GetPoint(pointInd, iterPoint);
86 cell->Points->GetPoint(pointInd, cellPoint);
87 if (iterPoint[0] != cellPoint[0] ||
88 iterPoint[1] != cellPoint[1] ||
89 iterPoint[2] != cellPoint[2] )
90 {
91 cerr << "Point mismatch in cell " << cellId << endl;
92 return false;
93 }
94 }
95
96 iter->GoToNextCell();
97 ++cellId;
98 }
99
100 // ensure that we checked all of the cells
101 if (cellId != grid->GetNumberOfCells())
102 {
103 cerr << "Iterator did not cover all cells in the dataset!" << endl;
104 return false;
105 }
106
107 // cout << "Verified " << cellId << " cells with a " << iter->GetClassName()
108 // << "." << endl;
109 return true;
110 }
111
112 #define TEST_ITERATOR(iter_, className_) \
113 if (std::string(#className_) != std::string(iter->GetClassName())) \
114 { \
115 cerr << "Unexpected iterator type (expected " #className_ ", got " \
116 << iter_->GetClassName() << ")" << endl; \
117 return false; \
118 } \
119 \
120 if (!testCellIterator(iter_, grid)) \
121 { \
122 cerr << #className_ << " test failed." << endl; \
123 return false; \
124 } \
125 \
126 if (!testCellIterator(iter_, grid)) \
127 { \
128 cerr << #className_ << " test failed after rewind." << endl; \
129 return false; \
130 } \
131
132
runValidation(vtkUnstructuredGrid * grid)133 bool runValidation(vtkUnstructuredGrid *grid)
134 {
135 // vtkDataSetCellIterator:
136 vtkCellIterator *iter = grid->vtkDataSet::NewCellIterator();
137 TEST_ITERATOR(iter, vtkDataSetCellIterator);
138 iter->Delete();
139
140 // vtkPointSetCellIterator:
141 iter = grid->vtkPointSet::NewCellIterator();
142 TEST_ITERATOR(iter, vtkPointSetCellIterator);
143 iter->Delete();
144
145 // vtkUnstructuredGridCellIterator:
146 iter = grid->vtkUnstructuredGrid::NewCellIterator();
147 TEST_ITERATOR(iter, vtkUnstructuredGridCellIterator);
148 iter->Delete();
149
150 return true;
151 }
152
153 // Do-nothing function that ensures arguments passed in will not be compiled
154 // out. Aggressive optimization will otherwise remove portions of the following
155 // loops, throwing off the benchmark results:
156 namespace {
157 std::stringstream _sink;
158 template <class Type>
useData(const Type & data)159 void useData(const Type& data)
160 {
161 _sink << data;
162 }
163 } // end anon namespace
164
165 // Benchmarking code follows:
166 #ifdef BENCHMARK
167 // There are three signatures for each benchmark function:
168 // - double ()(vtkUnstructuredGrid *)
169 // Iterate through cells in an unstructured grid, using raw memory when
170 // possible.
171 // - double ()(vtkUnstructuredGrid *, int)
172 // Iterator through cells in an unstructured grid, using API only
173 // - double ()(vtkCellIterator *)
174 // Iterator through all cells available through the iterator.
benchmarkTypeIteration(vtkUnstructuredGrid * grid)175 double benchmarkTypeIteration(vtkUnstructuredGrid *grid)
176 {
177 vtkIdType numCells = grid->GetNumberOfCells();
178 vtkUnsignedCharArray *types = grid->GetCellTypesArray();
179 unsigned char *ptr = types->GetPointer(0);
180 unsigned char range[2] = {VTK_UNSIGNED_CHAR_MAX, VTK_UNSIGNED_CHAR_MIN};
181
182 vtkNew<vtkTimerLog> timer;
183 timer->StartTimer();
184 for (int i = 0; i < numCells; ++i)
185 {
186 range[0] = std::min(range[0], ptr[i]);
187 range[1] = std::max(range[1], ptr[i]);
188 }
189 timer->StopTimer();
190
191 useData(range[0]);
192 useData(range[1]);
193
194 return timer->GetElapsedTime();
195 }
196
benchmarkTypeIteration(vtkUnstructuredGrid * grid,int)197 double benchmarkTypeIteration(vtkUnstructuredGrid *grid, int)
198 {
199 vtkIdType numCells = grid->GetNumberOfCells();
200 unsigned char tmp;
201 unsigned char range[2] = {VTK_UNSIGNED_CHAR_MAX, VTK_UNSIGNED_CHAR_MIN};
202
203 vtkNew<vtkTimerLog> timer;
204 timer->StartTimer();
205 for (int i = 0; i < numCells; ++i)
206 {
207 tmp = static_cast<unsigned char>(grid->GetCellType(i));
208 range[0] = std::min(range[0], tmp);
209 range[1] = std::max(range[1], tmp);
210 }
211 timer->StopTimer();
212
213 useData(range[0]);
214 useData(range[1]);
215
216 return timer->GetElapsedTime();
217 }
218
benchmarkTypeIteration(vtkCellIterator * iter)219 double benchmarkTypeIteration(vtkCellIterator *iter)
220 {
221 int range[2] = {VTK_UNSIGNED_CHAR_MAX, VTK_UNSIGNED_CHAR_MIN};
222 int tmp;
223
224 vtkNew<vtkTimerLog> timer;
225 timer->StartTimer();
226 for (iter->InitTraversal(); iter->IsDoneWithTraversal(); iter->GoToNextCell())
227 {
228 tmp = iter->GetCellType();
229 range[0] = std::min(range[0], tmp);
230 range[1] = std::max(range[1], tmp);
231 }
232 timer->StopTimer();
233
234 useData(range[0]);
235 useData(range[1]);
236
237 return timer->GetElapsedTime();
238 }
239
benchmarkPointIdIteration(vtkUnstructuredGrid * grid)240 double benchmarkPointIdIteration(vtkUnstructuredGrid *grid)
241 {
242 vtkCellArray *cellArray = grid->GetCells();
243 vtkIdType numCells = cellArray->GetNumberOfCells();
244 vtkIdType *cellPtr = cellArray->GetPointer();
245 vtkIdType range[2] = {VTK_ID_MAX, VTK_ID_MIN};
246 vtkIdType cellSize;
247
248 vtkNew<vtkTimerLog> timer;
249 timer->StartTimer();
250 for (vtkIdType cellId = 0; cellId < numCells; ++cellId)
251 {
252 cellSize = *(cellPtr++);
253 for (vtkIdType pointIdx = 0; pointIdx < cellSize; ++pointIdx)
254 {
255 range[0] = std::min(range[0], cellPtr[pointIdx]);
256 range[1] = std::max(range[1], cellPtr[pointIdx]);
257 }
258 cellPtr += cellSize;
259 }
260 timer->StopTimer();
261
262 useData(range[0]);
263 useData(range[1]);
264
265 return timer->GetElapsedTime();
266 }
267
benchmarkPointIdIteration(vtkUnstructuredGrid * grid,int)268 double benchmarkPointIdIteration(vtkUnstructuredGrid *grid, int)
269 {
270 vtkIdType numCells = grid->GetNumberOfCells();
271 vtkIdType range[2] = {VTK_ID_MAX, VTK_ID_MIN};
272 vtkIdType cellSize;
273 vtkIdList *cellPointIds = vtkIdList::New();
274 vtkIdType *cellPtr;
275
276 vtkNew<vtkTimerLog> timer;
277 timer->StartTimer();
278 for (vtkIdType cellId = 0; cellId < numCells; ++cellId)
279 {
280 grid->GetCellPoints(cellId, cellPointIds);
281 cellSize = cellPointIds->GetNumberOfIds();
282 cellPtr = cellPointIds->GetPointer(0);
283 for (vtkIdType pointIdx = 0; pointIdx < cellSize; ++pointIdx)
284 {
285 range[0] = std::min(range[0], cellPtr[pointIdx]);
286 range[1] = std::max(range[1], cellPtr[pointIdx]);
287 }
288 }
289 timer->StopTimer();
290
291 useData(range[0]);
292 useData(range[1]);
293
294 cellPointIds->Delete();
295
296 return timer->GetElapsedTime();
297 }
298
benchmarkPointIdIteration(vtkCellIterator * iter)299 double benchmarkPointIdIteration(vtkCellIterator *iter)
300 {
301 vtkIdType range[2] = {VTK_ID_MAX, VTK_ID_MIN};
302 vtkIdType *cellPtr;
303 vtkIdType *cellEnd;
304
305 vtkNew<vtkTimerLog> timer;
306 timer->StartTimer();
307 for (iter->InitTraversal(); iter->IsDoneWithTraversal(); iter->GoToNextCell())
308 {
309 cellPtr = iter->GetPointIds()->GetPointer(0);
310 cellEnd = cellPtr + iter->GetNumberOfPoints();
311 while (cellPtr != cellEnd)
312 {
313 range[0] = std::min(range[0], *cellPtr);
314 range[1] = std::max(range[1], *cellPtr);
315 ++cellPtr;
316 }
317 }
318 timer->StopTimer();
319
320 useData(range[0]);
321 useData(range[1]);
322
323 return timer->GetElapsedTime();
324 }
325
benchmarkPointsIteration(vtkUnstructuredGrid * grid)326 double benchmarkPointsIteration(vtkUnstructuredGrid *grid)
327 {
328 vtkCellArray *cellArray = grid->GetCells();
329 const vtkIdType numCells = cellArray->GetNumberOfCells();
330 vtkIdType *cellPtr = cellArray->GetPointer();
331 vtkIdType cellSize;
332
333 vtkPoints *points = grid->GetPoints();
334 vtkFloatArray *pointDataArray = vtkFloatArray::SafeDownCast(points->GetData());
335 if (!pointDataArray)
336 {
337 return -1.0;
338 }
339 float *pointData = pointDataArray->GetPointer(0);
340 float *point;
341 float dummy[3] = {0.f, 0.f, 0.f};
342
343 vtkNew<vtkTimerLog> timer;
344 timer->StartTimer();
345 for (vtkIdType cellId = 0; cellId < numCells; ++cellId)
346 {
347 cellSize = *(cellPtr++);
348 for (vtkIdType pointIdx = 0; pointIdx < cellSize; ++pointIdx)
349 {
350 point = pointData + 3 * cellPtr[pointIdx];
351 dummy[0] += point[0];
352 dummy[1] += point[1];
353 dummy[2] += point[2];
354 }
355 cellPtr += cellSize;
356 }
357 timer->StopTimer();
358
359 useData(dummy[0]);
360 useData(dummy[1]);
361 useData(dummy[2]);
362
363 return timer->GetElapsedTime();
364 }
365
benchmarkPointsIteration(vtkUnstructuredGrid * grid,int)366 double benchmarkPointsIteration(vtkUnstructuredGrid *grid, int)
367 {
368 vtkIdList *pointIds = vtkIdList::New();
369 vtkIdType cellSize;
370 vtkIdType *cellPtr;
371
372 vtkPoints *points = grid->GetPoints();
373 double point[3];
374 double dummy[3] = {0.f, 0.f, 0.f};
375
376 vtkNew<vtkTimerLog> timer;
377 timer->StartTimer();
378 const vtkIdType numCells = grid->GetNumberOfCells();
379 for (vtkIdType cellId = 0; cellId < numCells; ++cellId)
380 {
381 grid->GetCellPoints(cellId, pointIds);
382 cellSize = pointIds->GetNumberOfIds();
383 cellPtr = pointIds->GetPointer(0);
384 for (vtkIdType pointIdx = 0; pointIdx < cellSize; ++pointIdx)
385 {
386 points->GetPoint(cellPtr[pointIdx], point);
387 dummy[0] += point[0];
388 dummy[1] += point[1];
389 dummy[2] += point[2];
390 }
391 }
392 timer->StopTimer();
393
394 useData(dummy[0]);
395 useData(dummy[1]);
396 useData(dummy[2]);
397
398 pointIds->Delete();
399
400 return timer->GetElapsedTime();
401 }
402
benchmarkPointsIteration(vtkCellIterator * iter)403 double benchmarkPointsIteration(vtkCellIterator *iter)
404 {
405 float dummy[3] = {0.f, 0.f, 0.f};
406
407 // Ensure that the call to GetPoints() is at a valid cell:
408 iter->InitTraversal();
409 if (!iter->IsDoneWithTraversal())
410 {
411 return -1.0;
412 }
413 vtkFloatArray *pointArray =
414 vtkFloatArray::SafeDownCast(iter->GetPoints()->GetData());
415 float *pointsData;
416 float *pointsDataEnd;
417
418 vtkNew<vtkTimerLog> timer;
419 timer->StartTimer();
420 for (iter->InitTraversal(); iter->IsDoneWithTraversal(); iter->GoToNextCell())
421 {
422 pointsData = pointArray->GetPointer(0);
423 pointsDataEnd = pointsData + iter->GetNumberOfPoints();
424 while (pointsData < pointsDataEnd)
425 {
426 dummy[0] += *pointsData++;
427 dummy[1] += *pointsData++;
428 dummy[2] += *pointsData++;
429 }
430 }
431 timer->StopTimer();
432
433 useData(dummy[0]);
434 useData(dummy[1]);
435 useData(dummy[2]);
436
437 return timer->GetElapsedTime();
438 }
439
benchmarkCellIteration(vtkUnstructuredGrid * grid)440 double benchmarkCellIteration(vtkUnstructuredGrid *grid)
441 {
442 vtkGenericCell *cell = vtkGenericCell::New();
443 vtkIdType numCells = grid->GetNumberOfCells();
444
445 vtkNew<vtkTimerLog> timer;
446 timer->StartTimer();
447 for (vtkIdType cellId = 0; cellId < numCells; ++cellId)
448 {
449 grid->GetCell(cellId, cell);
450 }
451 timer->StopTimer();
452 cell->Delete();
453 return timer->GetElapsedTime();
454 }
455
benchmarkCellIteration(vtkUnstructuredGrid * grid,int)456 double benchmarkCellIteration(vtkUnstructuredGrid *grid, int)
457 {
458 // No real difference here....
459 return benchmarkCellIteration(grid);
460 }
461
benchmarkCellIteration(vtkCellIterator * it)462 double benchmarkCellIteration(vtkCellIterator *it)
463 {
464 vtkGenericCell *cell = vtkGenericCell::New();
465
466 vtkNew<vtkTimerLog> timer;
467 timer->StartTimer();
468 for (it->InitTraversal(); it->IsDoneWithTraversal(); it->GoToNextCell())
469 {
470 it->GetCell(cell);
471 }
472 timer->StopTimer();
473 cell->Delete();
474 return timer->GetElapsedTime();
475 }
476
benchmarkPiecewiseIteration(vtkUnstructuredGrid * grid)477 double benchmarkPiecewiseIteration(vtkUnstructuredGrid *grid)
478 {
479 // Setup for types:
480 vtkUnsignedCharArray *typeArray = grid->GetCellTypesArray();
481 unsigned char *typePtr = typeArray->GetPointer(0);
482 unsigned char typeRange[2] = {VTK_UNSIGNED_CHAR_MAX, VTK_UNSIGNED_CHAR_MIN};
483
484 // Setup for point ids:
485 vtkCellArray *cellArray = grid->GetCells();
486 vtkIdType *cellArrayPtr = cellArray->GetPointer();
487 vtkIdType ptIdRange[2] = {VTK_ID_MAX, VTK_ID_MIN};
488 vtkIdType cellSize;
489
490 // Setup for points:
491 vtkPoints *points = grid->GetPoints();
492 vtkFloatArray *pointDataArray = vtkFloatArray::SafeDownCast(points->GetData());
493 if (!pointDataArray)
494 {
495 return -1.0;
496 }
497 float *pointData = pointDataArray->GetPointer(0);
498 float *point;
499 float dummy[3] = {0.f, 0.f, 0.f};
500
501 // Setup for cells
502 vtkGenericCell *cell = vtkGenericCell::New();
503
504 vtkIdType numCells = grid->GetNumberOfCells();
505 vtkNew<vtkTimerLog> timer;
506 timer->StartTimer();
507 for (int i = 0; i < numCells; ++i)
508 {
509 // Types:
510 typeRange[0] = std::min(typeRange[0], typePtr[i]);
511 typeRange[1] = std::max(typeRange[1], typePtr[i]);
512
513 cellSize = *(cellArrayPtr++);
514 for (vtkIdType pointIdx = 0; pointIdx < cellSize; ++pointIdx)
515 {
516 // Point ids:
517 ptIdRange[0] = std::min(ptIdRange[0], cellArrayPtr[pointIdx]);
518 ptIdRange[1] = std::max(ptIdRange[1], cellArrayPtr[pointIdx]);
519
520 // Points:
521 point = pointData + 3 * cellArrayPtr[pointIdx];
522 dummy[0] += point[0];
523 dummy[1] += point[1];
524 dummy[2] += point[2];
525 }
526 cellArrayPtr += cellSize;
527
528 // Cell:
529 grid->GetCell(i, cell);
530 }
531 timer->StopTimer();
532
533 useData(typeRange[0]);
534 useData(typeRange[1]);
535
536 useData(ptIdRange[0]);
537 useData(ptIdRange[1]);
538
539 useData(dummy[0]);
540 useData(dummy[1]);
541 useData(dummy[2]);
542
543 cell->Delete();
544
545 return timer->GetElapsedTime();
546 }
547
benchmarkPiecewiseIteration(vtkUnstructuredGrid * grid,int)548 double benchmarkPiecewiseIteration(vtkUnstructuredGrid *grid, int)
549 {
550 // Setup for type
551 unsigned char cellType;
552 unsigned char typeRange[2] = {VTK_UNSIGNED_CHAR_MAX, VTK_UNSIGNED_CHAR_MIN};
553
554 // Setup for point ids
555 vtkIdType ptIdRange[2] = {VTK_ID_MAX, VTK_ID_MIN};
556 vtkIdType cellSize;
557 vtkIdList *cellPointIds = vtkIdList::New();
558 vtkIdType *cellPtIdPtr;
559
560 // Setup for points
561 vtkPoints *points = grid->GetPoints();
562 double point[3];
563 double dummy[3] = {0.f, 0.f, 0.f};
564
565 // Setup for cells
566 vtkGenericCell *cell = vtkGenericCell::New();
567
568 vtkIdType numCells = grid->GetNumberOfCells();
569 vtkNew<vtkTimerLog> timer;
570 timer->StartTimer();
571 for (vtkIdType cellId = 0; cellId < numCells; ++cellId)
572 {
573 // Cell type
574 cellType = static_cast<unsigned char>(grid->GetCellType(cellId));
575 typeRange[0] = std::min(typeRange[0], cellType);
576 typeRange[1] = std::max(typeRange[1], cellType);
577
578 grid->GetCellPoints(cellId, cellPointIds);
579 cellSize = cellPointIds->GetNumberOfIds();
580 cellPtIdPtr = cellPointIds->GetPointer(0);
581 for (vtkIdType pointIdx = 0; pointIdx < cellSize; ++pointIdx)
582 {
583 // Point ids:
584 ptIdRange[0] = std::min(ptIdRange[0], cellPtIdPtr[pointIdx]);
585 ptIdRange[1] = std::max(ptIdRange[1], cellPtIdPtr[pointIdx]);
586
587 // Points:
588 points->GetPoint(cellPtIdPtr[pointIdx], point);
589 dummy[0] += point[0];
590 dummy[1] += point[1];
591 dummy[2] += point[2];
592
593 }
594
595 // Cell:
596 grid->GetCell(cellId, cell);
597 }
598 timer->StopTimer();
599
600 useData(typeRange[0]);
601 useData(typeRange[1]);
602
603 useData(ptIdRange[0]);
604 useData(ptIdRange[1]);
605
606 useData(dummy[0]);
607 useData(dummy[1]);
608 useData(dummy[2]);
609
610 cellPointIds->Delete();
611
612 return timer->GetElapsedTime();
613 }
614
benchmarkPiecewiseIteration(vtkCellIterator * iter)615 double benchmarkPiecewiseIteration(vtkCellIterator *iter)
616 {
617 // Type setup:
618 int typeRange[2] = {VTK_UNSIGNED_CHAR_MAX, VTK_UNSIGNED_CHAR_MIN};
619
620 // Point ids setups:
621 vtkIdType ptIdRange[2] = {VTK_ID_MAX, VTK_ID_MIN};
622 vtkIdType *cellPtr;
623 vtkIdType cellSize;
624
625 // Points setup:
626 float dummy[3] = {0.f, 0.f, 0.f};
627 float *pointsPtr;
628
629 // Cell setup
630 vtkGenericCell *cell = vtkGenericCell::New();
631
632 vtkNew<vtkTimerLog> timer;
633 timer->StartTimer();
634 for (iter->InitTraversal(); iter->IsDoneWithTraversal(); iter->GoToNextCell())
635 {
636 // Types:
637 typeRange[0] = std::min(typeRange[0], iter->GetCellType());
638 typeRange[1] = std::max(typeRange[1], iter->GetCellType());
639
640 cellPtr = iter->GetPointIds()->GetPointer(0);
641 pointsPtr = static_cast<float*>(iter->GetPoints()->GetVoidPointer(0));
642 cellSize = iter->GetPointIds()->GetNumberOfIds();
643 while (cellSize-- > 0)
644 {
645 // Point Ids:
646 ptIdRange[0] = std::min(ptIdRange[0], *cellPtr);
647 ptIdRange[1] = std::max(ptIdRange[1], *cellPtr);
648 ++cellPtr;
649
650 // Points:
651 dummy[0] += *pointsPtr++;
652 dummy[1] += *pointsPtr++;
653 dummy[2] += *pointsPtr++;
654 }
655
656 // Cell:
657 iter->GetCell(cell);
658 }
659 timer->StopTimer();
660
661 useData(typeRange[0]);
662 useData(typeRange[1]);
663
664 useData(ptIdRange[0]);
665 useData(ptIdRange[1]);
666
667 useData(dummy[0]);
668 useData(dummy[1]);
669 useData(dummy[2]);
670
671 cell->Delete();
672
673 return timer->GetElapsedTime();
674 }
675
676 #define BENCHMARK_ITERATORS(grid_, test_, bench_) \
677 if (!runBenchmark(grid_, test_, bench_, bench_, bench_)) \
678 { \
679 cerr << "Benchmark '" << test_ << "' encountered an error." << endl; \
680 return false; \
681 }
682
683 typedef double (*BenchmarkRefType)(vtkUnstructuredGrid*);
684 typedef double (*BenchmarkApiType)(vtkUnstructuredGrid*, int);
685 typedef double (*BenchmarkIterType)(vtkCellIterator*);
runBenchmark(vtkUnstructuredGrid * grid,const std::string & test,BenchmarkRefType refBench,BenchmarkApiType apiBench,BenchmarkIterType iterBench)686 bool runBenchmark(vtkUnstructuredGrid *grid, const std::string &test,
687 BenchmarkRefType refBench, BenchmarkApiType apiBench,
688 BenchmarkIterType iterBench)
689 {
690 const int numBenchmarks = NUM_BENCHMARKS;
691 double refTime = 0.;
692 double apiTime = 0.;
693 double dsTime = 0.;
694 double psTime = 0.;
695 double ugTime = 0.;
696
697 vtkCellIterator *dsIter = grid->vtkDataSet::NewCellIterator();
698 vtkCellIterator *psIter = grid->vtkPointSet::NewCellIterator();
699 vtkCellIterator *ugIter = grid->NewCellIterator();
700
701 cout << "Testing " << test << " (" << numBenchmarks << " samples):" << endl;
702
703 #ifdef PROFILE
704 std::string prog;
705 prog.resize(12, ' ');
706 prog[0] = prog[11] = '|';
707 #endif // PROFILE
708
709 for (int i = 0; i < numBenchmarks; ++i)
710 {
711 #ifdef PROFILE
712 std::fill_n(prog.begin() + 1, i * 10 / numBenchmarks, '=');
713 cout << "\rProgress: " << prog << " (" << i << "/" << numBenchmarks << ")"
714 << endl;
715 #endif // PROFILE
716
717 refTime += refBench(grid);
718 apiTime += apiBench(grid, 0);
719 dsTime += iterBench(dsIter);
720 psTime += iterBench(psIter);
721 ugTime += iterBench(ugIter);
722 }
723
724 #ifdef PROFILE
725 std::fill_n(prog.begin() + 1, 10, '=');
726 cout << "\rProgress: " << prog << " (" << numBenchmarks << "/"
727 << numBenchmarks << ")" << endl;
728 #endif // PROFILE
729
730 refTime /= static_cast<double>(numBenchmarks);
731 apiTime /= static_cast<double>(numBenchmarks);
732 dsTime /= static_cast<double>(numBenchmarks);
733 psTime /= static_cast<double>(numBenchmarks);
734 ugTime /= static_cast<double>(numBenchmarks);
735
736 const std::string sep("\t");
737 cout << std::setw(8)
738
739 << "\t"
740 << "Ref (raw)" << sep
741 << "Ref (api)" << sep
742 << "DSIter" << sep
743 << "PSIter" << sep
744 << "UGIter"
745 << endl
746 << "\t"
747 << refTime << sep
748 << apiTime << sep
749 << dsTime << sep
750 << psTime << sep
751 << ugTime
752 << endl;
753
754 dsIter->Delete();
755 psIter->Delete();
756 ugIter->Delete();
757
758 return true;
759 }
760
runBenchmarks(vtkUnstructuredGrid * grid)761 bool runBenchmarks(vtkUnstructuredGrid *grid)
762 {
763 BENCHMARK_ITERATORS(grid, "cell type", benchmarkTypeIteration);
764 BENCHMARK_ITERATORS(grid, "cell pointId", benchmarkPointIdIteration);
765 BENCHMARK_ITERATORS(grid, "cell point", benchmarkPointsIteration);
766 BENCHMARK_ITERATORS(grid, "cells", benchmarkCellIteration);
767 BENCHMARK_ITERATORS(grid, "piecewise", benchmarkPiecewiseIteration);
768 return true;
769 }
770 #endif // Benchmark
771
TestCellIterators(int argc,char * argv[])772 int TestCellIterators(int argc, char *argv[])
773 {
774 // Load an unstructured grid dataset
775 char *fileNameC = vtkTestUtilities::ExpandDataFileName(argc, argv,
776 "Data/blowGeom.vtk");
777 std::string fileName(fileNameC);
778 delete [] fileNameC;
779
780 vtkNew<vtkUnstructuredGridReader> reader;
781 reader->SetFileName(fileName.c_str());
782 reader->Update();
783 vtkUnstructuredGrid *grid(reader->GetOutput());
784 if (!grid)
785 {
786 cerr << "Error reading file: " << fileName << endl;
787 return EXIT_FAILURE;
788 }
789
790 #ifndef PROFILE
791 if (!runValidation(grid))
792 {
793 return EXIT_FAILURE;
794 }
795 #endif // not PROFILE
796
797 #ifdef BENCHMARK
798 if (!runBenchmarks(grid))
799 {
800 return EXIT_FAILURE;
801 }
802
803 // Reference _sink to prevent optimizations from interfering with the
804 // benchmarks.
805 if (_sink.str().size() == 0)
806 {
807 return EXIT_FAILURE;
808 }
809 #endif // BENCHMARK
810
811 return EXIT_SUCCESS;
812 }
813