1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: TestDataArrayIterators.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 "vtkFloatArray.h"
17 #include "vtkTimerLog.h"
18 #include "vtkTypedDataArray.h"
19 #include "vtkTypedDataArrayIterator.h"
20 #include "vtkNew.h"
21
22 #include <cassert>
23 #include <iostream>
24
25 // undefine this to print benchmark results:
26 #define SILENT
27
TestDataArrayIterators(int,char * [])28 int TestDataArrayIterators(int, char *[])
29 {
30 vtkIdType numComps = 4;
31 vtkIdType numValues = 100000000; // 10 million
32 assert(numValues % numComps == 0);
33 vtkIdType numTuples = numValues / numComps;
34
35 vtkNew<vtkFloatArray> arrayContainer;
36 vtkFloatArray *array = arrayContainer.GetPointer();
37 array->SetNumberOfComponents(numComps);
38 array->SetNumberOfTuples(numTuples);
39 for (vtkIdType i = 0; i < numValues; ++i)
40 {
41 // Just fill with consistent data
42 array->SetValue(i, i % 97);
43 }
44
45 // should be vtkDataArrayTemplate<float>::Iterator (float*):
46 vtkFloatArray::Iterator datBegin = array->Begin();
47 vtkFloatArray::Iterator datIter = array->Begin();
48 if (typeid(datBegin) != typeid(float*))
49 {
50 std::cerr << "Error: vtkFloatArray::Iterator is not a float*.";
51 return EXIT_FAILURE;
52 }
53
54 // should be vtkTypedDataArrayIterator<float>:
55 vtkTypedDataArray<float>::Iterator tdaBegin =
56 vtkTypedDataArray<float>::FastDownCast(array)->Begin();
57 vtkTypedDataArray<float>::Iterator tdaIter =
58 vtkTypedDataArray<float>::FastDownCast(array)->Begin();
59 if (typeid(tdaBegin) != typeid(vtkTypedDataArrayIterator<float>))
60 {
61 std::cerr << "Error: vtkTypedDataArray<float>::Iterator is not a "
62 "vtkTypedDataArrayIterator<float>.";
63 return EXIT_FAILURE;
64 }
65
66 // Validate that the iterators return the same values from operator[] and
67 // operator* as GetValue;
68 for (vtkIdType i = 0; i < numValues; ++i)
69 {
70 float lookup = array->GetValue(i);
71 if (lookup != datBegin[i] || lookup != tdaBegin[i] ||
72 lookup != *datIter || lookup != *tdaIter)
73 {
74 std::cerr << "Mismatch at " << i << ":"
75 << " GetValue(i)=" << lookup
76 << " datBegin[i]=" << datBegin[i]
77 << " tdaBegin[i]=" << tdaBegin[i]
78 << " *datIter=" << *datIter
79 << " *tdaIter=" << *tdaIter
80 << std::endl;
81 return EXIT_FAILURE;
82 }
83 ++datIter;
84 ++tdaIter;
85 }
86
87 #ifndef SILENT
88 // Iterator timings.
89 vtkNew<vtkTimerLog> timer;
90
91 // Lookup:
92 float lookupSum = 0.f;
93 timer->StartTimer();
94 for (vtkIdType i = 0; i < numValues; ++i)
95 {
96 lookupSum += array->GetValueReference(i);
97 }
98 timer->StopTimer();
99 double lookupTime = timer->GetElapsedTime();
100
101 // Scalar iterator:
102 float datSum = 0.f;
103 timer->StartTimer();
104 vtkFloatArray::Iterator datEnd = array->End();
105 while (datBegin != datEnd)
106 {
107 datSum += *datBegin++;
108 }
109 timer->StopTimer();
110 double datTime = timer->GetElapsedTime();
111
112 // vtkTypedDataArrayIterator:
113 vtkTypedDataArray<float>::Iterator tdaEnd =
114 vtkTypedDataArray<float>::FastDownCast(array)->End();
115 float tdaSum = 0.f;
116 timer->StartTimer();
117 while (tdaBegin != tdaEnd)
118 {
119 tdaSum += *tdaBegin++;
120 }
121 timer->StopTimer();
122 double tdaTime = timer->GetElapsedTime();
123
124 std::cout << "GetValue time, sum: "
125 << lookupTime << ", " << lookupSum << std::endl;
126 std::cout << "dat time, sum: "
127 << datTime << ", " << datSum << std::endl;
128 std::cout << "tda time, sum: "
129 << tdaTime << ", " << tdaSum << std::endl;
130 #endif
131
132 return EXIT_SUCCESS;
133 }
134