1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 // This software is distributed WITHOUT ANY WARRANTY; without even
6 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
7 // PURPOSE. See the above copyright notice for more information.
8 //
9 // Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
10 // Copyright 2014 UT-Battelle, LLC.
11 // Copyright 2014 Los Alamos National Security.
12 //
13 // Under the terms of Contract DE-NA0003525 with NTESS,
14 // the U.S. Government retains certain rights in this software.
15 //
16 // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
17 // Laboratory (LANL), the U.S. Government retains certain rights in
18 // this software.
19 //============================================================================
20
21 #include <vtkm/cont/ArrayHandle.h>
22 #include <vtkm/cont/StorageBasic.h>
23
24 #include <vtkm/VecTraits.h>
25 #include <vtkm/cont/testing/Testing.h>
26
27 #if defined(VTKM_STORAGE)
28 #undef VTKM_STORAGE
29 #endif
30
31 #define VTKM_STORAGE VTKM_STORAGE_ERROR
32
33 namespace
34 {
35
36 const vtkm::Id ARRAY_SIZE = 10;
37
38 template <typename T>
39 struct TemplatedTests
40 {
41 using StorageType = vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagBasic>;
42 using ValueType = typename StorageType::ValueType;
43 using PortalType = typename StorageType::PortalType;
44
SetStorage__anon9c0f15680111::TemplatedTests45 void SetStorage(StorageType& array, const ValueType& value)
46 {
47 PortalType portal = array.GetPortal();
48 for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
49 {
50 portal.Set(index, value);
51 }
52 }
53
CheckStorage__anon9c0f15680111::TemplatedTests54 bool CheckStorage(StorageType& array, const ValueType& value)
55 {
56 PortalType portal = array.GetPortal();
57 for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
58 {
59 if (!test_equal(portal.Get(index), value))
60 {
61 return false;
62 }
63 }
64 return true;
65 }
66
STOLEN_ARRAY_VALUE__anon9c0f15680111::TemplatedTests67 typename vtkm::VecTraits<ValueType>::ComponentType STOLEN_ARRAY_VALUE() { return 29; }
68
69 /// Returned value should later be passed to StealArray2. It is best to
70 /// put as much between the two test parts to maximize the chance of a
71 /// deallocated array being overridden (and thus detected).
StealArray1__anon9c0f15680111::TemplatedTests72 ValueType* StealArray1()
73 {
74 ValueType* stolenArray;
75
76 ValueType stolenArrayValue = ValueType(STOLEN_ARRAY_VALUE());
77
78 StorageType stealMyArray;
79 stealMyArray.Allocate(ARRAY_SIZE);
80 this->SetStorage(stealMyArray, stolenArrayValue);
81
82 VTKM_TEST_ASSERT(stealMyArray.GetNumberOfValues() == ARRAY_SIZE,
83 "Array not properly allocated.");
84 // This call steals the array and prevents deallocation.
85 VTKM_TEST_ASSERT(stealMyArray.WillDeallocate() == true,
86 "Array to be stolen needs to be owned by VTK-m");
87 stolenArray = stealMyArray.StealArray();
88 VTKM_TEST_ASSERT(stealMyArray.WillDeallocate() == false,
89 "Stolen array should not be owned by VTK-m");
90
91 return stolenArray;
92 }
StealArray2__anon9c0f15680111::TemplatedTests93 void StealArray2(ValueType* stolenArray)
94 {
95 ValueType stolenArrayValue = ValueType(STOLEN_ARRAY_VALUE());
96
97 for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
98 {
99 VTKM_TEST_ASSERT(test_equal(stolenArray[index], stolenArrayValue),
100 "Stolen array did not retain values.");
101 }
102 typename StorageType::AllocatorType allocator;
103 allocator.deallocate(stolenArray);
104 }
105
BasicAllocation__anon9c0f15680111::TemplatedTests106 void BasicAllocation()
107 {
108 StorageType arrayStorage;
109 VTKM_TEST_ASSERT(arrayStorage.GetNumberOfValues() == 0, "New array storage not zero sized.");
110
111 arrayStorage.Allocate(ARRAY_SIZE);
112 VTKM_TEST_ASSERT(arrayStorage.GetNumberOfValues() == ARRAY_SIZE,
113 "Array not properly allocated.");
114
115 const ValueType BASIC_ALLOC_VALUE = ValueType(48);
116 this->SetStorage(arrayStorage, BASIC_ALLOC_VALUE);
117 VTKM_TEST_ASSERT(this->CheckStorage(arrayStorage, BASIC_ALLOC_VALUE),
118 "Array not holding value.");
119
120 arrayStorage.Allocate(ARRAY_SIZE * 2);
121 VTKM_TEST_ASSERT(arrayStorage.GetNumberOfValues() == ARRAY_SIZE * 2,
122 "Array not reallocated correctly.");
123
124 arrayStorage.Shrink(ARRAY_SIZE);
125 VTKM_TEST_ASSERT(arrayStorage.GetNumberOfValues() == ARRAY_SIZE,
126 "Array Shrnk failed to resize.");
127
128 arrayStorage.ReleaseResources();
129 VTKM_TEST_ASSERT(arrayStorage.GetNumberOfValues() == 0, "Array not released correctly.");
130
131 try
132 {
133 arrayStorage.Shrink(ARRAY_SIZE);
134 VTKM_TEST_ASSERT(true == false,
135 "Array shrink do a larger size was possible. This can't be allowed.");
136 }
137 catch (vtkm::cont::ErrorBadValue&)
138 {
139 }
140 }
141
UserFreeFunction__anon9c0f15680111::TemplatedTests142 void UserFreeFunction()
143 {
144 ValueType* temp = new ValueType[ARRAY_SIZE];
145 StorageType arrayStorage(
146 temp, ARRAY_SIZE, [](void* ptr) { delete[] static_cast<ValueType*>(ptr); });
147 VTKM_TEST_ASSERT(temp == arrayStorage.GetArray(),
148 "improper pointer after telling storage to own user allocated memory");
149
150 const ValueType BASIC_ALLOC_VALUE = ValueType(48);
151 this->SetStorage(arrayStorage, BASIC_ALLOC_VALUE);
152 VTKM_TEST_ASSERT(this->CheckStorage(arrayStorage, BASIC_ALLOC_VALUE),
153 "Array not holding value.");
154
155 arrayStorage.Allocate(ARRAY_SIZE * 2);
156 VTKM_TEST_ASSERT(arrayStorage.GetNumberOfValues() == ARRAY_SIZE * 2,
157 "Array not reallocated correctly.");
158 }
159
operator ()__anon9c0f15680111::TemplatedTests160 void operator()()
161 {
162 ValueType* stolenArray = StealArray1();
163
164 BasicAllocation();
165 UserFreeFunction();
166
167 StealArray2(stolenArray);
168 }
169 };
170
171 struct TestFunctor
172 {
173 template <typename T>
operator ()__anon9c0f15680111::TestFunctor174 void operator()(T) const
175 {
176 TemplatedTests<T> tests;
177 tests();
178 }
179 };
180
TestStorageBasic()181 void TestStorageBasic()
182 {
183 vtkm::testing::Testing::TryTypes(TestFunctor());
184 }
185
186 } // Anonymous namespace
187
UnitTestStorageBasic(int,char * [])188 int UnitTestStorageBasic(int, char* [])
189 {
190 return vtkm::cont::testing::Testing::Run(TestStorageBasic);
191 }
192