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