StorageImplicit.h 5.23 KB
Newer Older
1 2 3 4 5 6 7 8
//============================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt for details.
//  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.
//
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 15 16 17 18 19
//  the U.S. Government retains certain rights in this software.
//
//  Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
//  Laboratory (LANL), the U.S. Government retains certain rights in
//  this software.
//============================================================================
20 21
#ifndef vtk_m_cont_StorageImplicit
#define vtk_m_cont_StorageImplicit
22 23 24

#include <vtkm/Types.h>

25
#include <vtkm/cont/ArrayPortalToIterators.h>
26
#include <vtkm/cont/ErrorBadValue.h>
27 28
#include <vtkm/cont/Storage.h>

29 30
#include <vtkm/cont/internal/ArrayTransfer.h>

31 32 33 34
namespace vtkm
{
namespace cont
{
35 36 37

/// \brief An implementation for read-only implicit arrays.
///
38
/// It is sometimes the case that you want VTK-m to operate on an array of
39
/// implicit values. That is, rather than store the data in an actual array, it
40 41 42 43 44
/// 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.
45
///
46
template <class ArrayPortalType>
47
struct VTKM_ALWAYS_EXPORT StorageTagImplicit
48
{
49
  using PortalType = ArrayPortalType;
50 51
};

52 53
namespace internal
{
54

55
template <class ArrayPortalType>
56 57
class VTKM_ALWAYS_EXPORT
  Storage<typename ArrayPortalType::ValueType, StorageTagImplicit<ArrayPortalType>>
58
{
59 60 61
  using ClassType =
    Storage<typename ArrayPortalType::ValueType, StorageTagImplicit<ArrayPortalType>>;

62
public:
63 64
  using ValueType = typename ArrayPortalType::ValueType;
  using PortalConstType = ArrayPortalType;
65 66 67

  // This is meant to be invalid. Because implicit arrays are read only, you
  // should only be able to use the const version.
68 69
  struct PortalType
  {
70 71
    using ValueType = void*;
    using IteratorType = void*;
72 73
  };

74
  VTKM_CONT
75 76
  Storage(const PortalConstType& portal = PortalConstType())
    : Portal(portal)
77
    , NumberOfValues(portal.GetNumberOfValues())
78 79
  {
  }
80

81 82 83 84 85
  VTKM_CONT Storage(const ClassType& src) = default;
  VTKM_CONT Storage(ClassType&& src) = default;
  VTKM_CONT ClassType& operator=(const ClassType& src) = default;
  VTKM_CONT ClassType& operator=(ClassType&& src) = default;

86
  // All these methods do nothing but raise errors.
87
  VTKM_CONT
88
  PortalType GetPortal() { throw vtkm::cont::ErrorBadValue("Implicit arrays are read-only."); }
89
  VTKM_CONT
90
  PortalConstType GetPortalConst() const { return this->Portal; }
91
  VTKM_CONT
92
  vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; }
93
  VTKM_CONT
94
  void Allocate(vtkm::Id numberOfValues)
95
  {
96 97
    VTKM_ASSERT(numberOfValues <= this->Portal.GetNumberOfValues());
    this->NumberOfValues = numberOfValues;
98
  }
99
  VTKM_CONT
100
  void Shrink(vtkm::Id numberOfValues)
101
  {
102 103
    VTKM_ASSERT(numberOfValues <= this->Portal.GetNumberOfValues());
    this->NumberOfValues = numberOfValues;
104
  }
105
  VTKM_CONT
106
  void ReleaseResources() {}
107 108 109

private:
  PortalConstType Portal;
110
  vtkm::Id NumberOfValues;
111 112
};

113
template <typename T, class ArrayPortalType, class DeviceAdapterTag>
114
class ArrayTransfer<T, StorageTagImplicit<ArrayPortalType>, DeviceAdapterTag>
115
{
116
public:
117
  using StorageTag = StorageTagImplicit<ArrayPortalType>;
118
  using StorageType = vtkm::cont::internal::Storage<T, StorageTag>;
119

120
  using ValueType = T;
121

122 123 124 125
  using PortalControl = typename StorageType::PortalType;
  using PortalConstControl = typename StorageType::PortalConstType;
  using PortalExecution = PortalControl;
  using PortalConstExecution = PortalConstControl;
126

127
  VTKM_CONT
128 129
  ArrayTransfer(StorageType* storage)
    : Storage(storage)
130
  {
131 132
  }

133 134 135
  VTKM_CONT
  vtkm::Id GetNumberOfValues() const { return this->Storage->GetNumberOfValues(); }

136
  VTKM_CONT
137
  PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
138
  {
139
    return this->Storage->GetPortalConst();
140 141
  }

142
  VTKM_CONT
143
  PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
144
  {
145
    throw vtkm::cont::ErrorBadValue("Implicit arrays cannot be used for output or in place.");
146 147
  }

148
  VTKM_CONT
149
  PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues))
150
  {
151
    throw vtkm::cont::ErrorBadValue("Implicit arrays cannot be used for output.");
152
  }
153
  VTKM_CONT
154
  void RetrieveOutputData(StorageType* vtkmNotUsed(controlArray)) const
155
  {
156
    throw vtkm::cont::ErrorBadValue("Implicit arrays cannot be used for output.");
157 158
  }

159
  VTKM_CONT
160
  void Shrink(vtkm::Id vtkmNotUsed(numberOfValues))
161
  {
162
    throw vtkm::cont::ErrorBadValue("Implicit arrays cannot be resized.");
163 164
  }

165
  VTKM_CONT
166
  void ReleaseResources() {}
167 168

private:
169
  StorageType* Storage;
170 171 172 173 174 175
};

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

176
#endif //vtk_m_cont_StorageImplicit