UnitTestStorageBasic.cxx 5.44 KB
Newer Older
1 2 3 4
//============================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt for details.
5
//
6 7 8 9 10
//  This software is distributed WITHOUT ANY WARRANTY; without even
//  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//  PURPOSE.  See the above copyright notice for more information.
//============================================================================

11
#include <vtkm/cont/ArrayHandle.h>
12
#include <vtkm/cont/StorageBasic.h>
13

14
#include <vtkm/VecTraits.h>
15
#include <vtkm/cont/testing/Testing.h>
16

17 18 19 20 21 22
#if defined(VTKM_STORAGE)
#undef VTKM_STORAGE
#endif

#define VTKM_STORAGE VTKM_STORAGE_ERROR

23 24
namespace
{
25 26 27 28 29 30

const vtkm::Id ARRAY_SIZE = 10;

template <typename T>
struct TemplatedTests
{
31 32 33
  using StorageType = vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagBasic>;
  using ValueType = typename StorageType::ValueType;
  using PortalType = typename StorageType::PortalType;
34

35
  void SetStorage(StorageType& array, const ValueType& value)
36
  {
37 38
    PortalType portal = array.GetPortal();
    for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
39
    {
40
      portal.Set(index, value);
41
    }
42 43
  }

44
  bool CheckStorage(StorageType& array, const ValueType& value)
45
  {
46 47
    PortalType portal = array.GetPortal();
    for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
48
    {
49 50 51 52
      if (!test_equal(portal.Get(index), value))
      {
        return false;
      }
53
    }
54 55 56
    return true;
  }

57
  typename vtkm::VecTraits<ValueType>::ComponentType STOLEN_ARRAY_VALUE() { return 29; }
58 59 60 61

  /// Returned value should later be passed to StealArray2.  It is best to
  /// put as much between the two test parts to maximize the chance of a
  /// deallocated array being overridden (and thus detected).
62
  ValueType* StealArray1()
63
  {
64
    ValueType* stolenArray;
65 66 67

    ValueType stolenArrayValue = ValueType(STOLEN_ARRAY_VALUE());

68
    StorageType stealMyArray;
69
    stealMyArray.Allocate(ARRAY_SIZE);
70
    this->SetStorage(stealMyArray, stolenArrayValue);
71 72

    VTKM_TEST_ASSERT(stealMyArray.GetNumberOfValues() == ARRAY_SIZE,
73
                     "Array not properly allocated.");
74
    // This call steals the array and prevents deallocation.
75 76
    VTKM_TEST_ASSERT(stealMyArray.WillDeallocate() == true,
                     "Array to be stolen needs to be owned by VTK-m");
77 78
    auto stolen = stealMyArray.StealArray();
    stolenArray = stolen.first;
79 80
    VTKM_TEST_ASSERT(stealMyArray.WillDeallocate() == false,
                     "Stolen array should not be owned by VTK-m");
81 82 83

    return stolenArray;
  }
84
  void StealArray2(ValueType* stolenArray)
85 86 87 88
  {
    ValueType stolenArrayValue = ValueType(STOLEN_ARRAY_VALUE());

    for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
89
    {
90
      VTKM_TEST_ASSERT(test_equal(stolenArray[index], stolenArrayValue),
91 92
                       "Stolen array did not retain values.");
    }
93
    typename StorageType::AllocatorType allocator;
94
    allocator.deallocate(stolenArray);
95 96 97 98
  }

  void BasicAllocation()
  {
99
    StorageType arrayStorage;
100
    VTKM_TEST_ASSERT(arrayStorage.GetNumberOfValues() == 0, "New array storage not zero sized.");
101

102 103
    arrayStorage.Allocate(ARRAY_SIZE);
    VTKM_TEST_ASSERT(arrayStorage.GetNumberOfValues() == ARRAY_SIZE,
104
                     "Array not properly allocated.");
105

106
    const ValueType BASIC_ALLOC_VALUE = ValueType(48);
107 108
    this->SetStorage(arrayStorage, BASIC_ALLOC_VALUE);
    VTKM_TEST_ASSERT(this->CheckStorage(arrayStorage, BASIC_ALLOC_VALUE),
109
                     "Array not holding value.");
110

111 112
    arrayStorage.Allocate(ARRAY_SIZE * 2);
    VTKM_TEST_ASSERT(arrayStorage.GetNumberOfValues() == ARRAY_SIZE * 2,
113
                     "Array not reallocated correctly.");
114

115 116
    arrayStorage.Shrink(ARRAY_SIZE);
    VTKM_TEST_ASSERT(arrayStorage.GetNumberOfValues() == ARRAY_SIZE,
117
                     "Array Shrnk failed to resize.");
118

119
    arrayStorage.ReleaseResources();
120
    VTKM_TEST_ASSERT(arrayStorage.GetNumberOfValues() == 0, "Array not released correctly.");
121 122

    try
123
    {
124
      arrayStorage.Shrink(ARRAY_SIZE);
125
      VTKM_TEST_ASSERT(true == false,
126 127
                       "Array shrink do a larger size was possible. This can't be allowed.");
    }
128 129 130
    catch (vtkm::cont::ErrorBadValue&)
    {
    }
131 132
  }

133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
  void UserFreeFunction()
  {
    ValueType* temp = new ValueType[ARRAY_SIZE];
    StorageType arrayStorage(
      temp, ARRAY_SIZE, [](void* ptr) { delete[] static_cast<ValueType*>(ptr); });
    VTKM_TEST_ASSERT(temp == arrayStorage.GetArray(),
                     "improper pointer after telling storage to own user allocated memory");

    const ValueType BASIC_ALLOC_VALUE = ValueType(48);
    this->SetStorage(arrayStorage, BASIC_ALLOC_VALUE);
    VTKM_TEST_ASSERT(this->CheckStorage(arrayStorage, BASIC_ALLOC_VALUE),
                     "Array not holding value.");

    arrayStorage.Allocate(ARRAY_SIZE * 2);
    VTKM_TEST_ASSERT(arrayStorage.GetNumberOfValues() == ARRAY_SIZE * 2,
                     "Array not reallocated correctly.");
  }

151 152
  void operator()()
  {
153
    ValueType* stolenArray = StealArray1();
154 155

    BasicAllocation();
156
    UserFreeFunction();
157 158 159 160 161 162 163 164

    StealArray2(stolenArray);
  }
};

struct TestFunctor
{
  template <typename T>
165
  void operator()(T) const
166 167 168 169 170 171
  {
    TemplatedTests<T> tests;
    tests();
  }
};

172
void TestStorageBasic()
173
{
174
  vtkm::testing::Testing::TryTypes(TestFunctor());
175 176 177 178
}

} // Anonymous namespace

179
int UnitTestStorageBasic(int argc, char* argv[])
180
{
181
  return vtkm::cont::testing::Testing::Run(TestStorageBasic, argc, argv);
182
}