StorageImplicit.h 4.77 KB
Newer Older
1 2 3 4
//============================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt for details.
5
//
6 7 8 9
//  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.
//============================================================================
10 11
#ifndef vtk_m_cont_StorageImplicit
#define vtk_m_cont_StorageImplicit
12 13 14

#include <vtkm/Types.h>

15
#include <vtkm/cont/ArrayPortalToIterators.h>
16
#include <vtkm/cont/ErrorBadValue.h>
17 18
#include <vtkm/cont/Storage.h>

19 20
#include <vtkm/cont/internal/ArrayTransfer.h>

21 22 23 24
namespace vtkm
{
namespace cont
{
25 26 27

/// \brief An implementation for read-only implicit arrays.
///
28
/// It is sometimes the case that you want VTK-m to operate on an array of
29
/// implicit values. That is, rather than store the data in an actual array, it
30 31 32 33 34
/// is gerenated on the fly by a function. This is handled in VTK-m by creating
/// an ArrayHandle in VTK-m with a StorageTagImplicit type of \c Storage. This
/// tag itself is templated to specify an ArrayPortal that generates the
/// desired values. An ArrayHandle created with this tag will raise an error on
/// any operation that tries to modify it.
35
///
36
template <class ArrayPortalType>
37
struct VTKM_ALWAYS_EXPORT StorageTagImplicit
38
{
39
  using PortalType = ArrayPortalType;
40 41
};

42 43
namespace internal
{
44

45
template <class ArrayPortalType>
46 47
class VTKM_ALWAYS_EXPORT
  Storage<typename ArrayPortalType::ValueType, StorageTagImplicit<ArrayPortalType>>
48
{
49 50 51
  using ClassType =
    Storage<typename ArrayPortalType::ValueType, StorageTagImplicit<ArrayPortalType>>;

52
public:
53 54
  using ValueType = typename ArrayPortalType::ValueType;
  using PortalConstType = ArrayPortalType;
55 56 57

  // This is meant to be invalid. Because implicit arrays are read only, you
  // should only be able to use the const version.
58 59
  struct PortalType
  {
60 61
    using ValueType = void*;
    using IteratorType = void*;
62 63
  };

64
  VTKM_CONT
65 66
  Storage(const PortalConstType& portal = PortalConstType())
    : Portal(portal)
67
    , NumberOfValues(portal.GetNumberOfValues())
68 69
  {
  }
70

71 72 73 74
  VTKM_CONT Storage(const ClassType&) = default;
  VTKM_CONT Storage(ClassType&&) = default;
  VTKM_CONT ClassType& operator=(const ClassType&) = default;
  VTKM_CONT ClassType& operator=(ClassType&&) = default;
75

76
  // All these methods do nothing but raise errors.
77
  VTKM_CONT
78
  PortalType GetPortal() { throw vtkm::cont::ErrorBadValue("Implicit arrays are read-only."); }
79
  VTKM_CONT
80
  PortalConstType GetPortalConst() const { return this->Portal; }
81
  VTKM_CONT
82
  vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; }
83
  VTKM_CONT
84
  void Allocate(vtkm::Id numberOfValues)
85
  {
86 87
    VTKM_ASSERT(numberOfValues <= this->Portal.GetNumberOfValues());
    this->NumberOfValues = numberOfValues;
88
  }
89
  VTKM_CONT
90
  void Shrink(vtkm::Id numberOfValues)
91
  {
92 93
    VTKM_ASSERT(numberOfValues <= this->Portal.GetNumberOfValues());
    this->NumberOfValues = numberOfValues;
94
  }
95
  VTKM_CONT
96
  void ReleaseResources() {}
97 98 99

private:
  PortalConstType Portal;
100
  vtkm::Id NumberOfValues;
101 102
};

103
template <typename T, class ArrayPortalType, class DeviceAdapterTag>
104
class ArrayTransfer<T, StorageTagImplicit<ArrayPortalType>, DeviceAdapterTag>
105
{
106
public:
107
  using StorageTag = StorageTagImplicit<ArrayPortalType>;
108
  using StorageType = vtkm::cont::internal::Storage<T, StorageTag>;
109

110
  using ValueType = T;
111

112 113 114 115
  using PortalControl = typename StorageType::PortalType;
  using PortalConstControl = typename StorageType::PortalConstType;
  using PortalExecution = PortalControl;
  using PortalConstExecution = PortalConstControl;
116

117
  VTKM_CONT
118 119
  ArrayTransfer(StorageType* storage)
    : Storage(storage)
120
  {
121 122
  }

123 124 125
  VTKM_CONT
  vtkm::Id GetNumberOfValues() const { return this->Storage->GetNumberOfValues(); }

126
  VTKM_CONT
127
  PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
128
  {
129
    return this->Storage->GetPortalConst();
130 131
  }

132
  VTKM_CONT
133
  PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
134
  {
135
    throw vtkm::cont::ErrorBadValue("Implicit arrays cannot be used for output or in place.");
136 137
  }

138
  VTKM_CONT
139
  PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues))
140
  {
141
    throw vtkm::cont::ErrorBadValue("Implicit arrays cannot be used for output.");
142
  }
143
  VTKM_CONT
144
  void RetrieveOutputData(StorageType* vtkmNotUsed(controlArray)) const
145
  {
146
    throw vtkm::cont::ErrorBadValue("Implicit arrays cannot be used for output.");
147 148
  }

149
  VTKM_CONT
150
  void Shrink(vtkm::Id vtkmNotUsed(numberOfValues))
151
  {
152
    throw vtkm::cont::ErrorBadValue("Implicit arrays cannot be resized.");
153 154
  }

155
  VTKM_CONT
156
  void ReleaseResources() {}
157 158

private:
159
  StorageType* Storage;
160 161 162 163 164 165
};

} // namespace internal
}
} // namespace vtkm::cont

166
#endif //vtk_m_cont_StorageImplicit