Viskores  1.0
exec/cuda/internal/IteratorFromArrayPortal.h
Go to the documentation of this file.
1 //============================================================================
2 // The contents of this file are covered by the Viskores license. See
3 // LICENSE.txt for details.
4 //
5 // By contributing to this file, all contributors agree to the Developer
6 // Certificate of Origin Version 1.1 (DCO 1.1) as stated in DCO.txt.
7 //============================================================================
8 
9 //============================================================================
10 // Copyright (c) Kitware, Inc.
11 // All rights reserved.
12 // See LICENSE.txt for details.
13 //
14 // This software is distributed WITHOUT ANY WARRANTY; without even
15 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 // PURPOSE. See the above copyright notice for more information.
17 //============================================================================
18 #ifndef viskores_exec_cuda_internal_IteratorFromArrayPortal_h
19 #define viskores_exec_cuda_internal_IteratorFromArrayPortal_h
20 
21 #include <viskores/Pair.h>
22 #include <viskores/Types.h>
25 
26 // Disable warnings we check viskores for but Thrust does not.
29 #include <thrust/functional.h>
30 #include <thrust/iterator/iterator_facade.h>
31 #include <thrust/system/cuda/execution_policy.h>
33 
34 namespace viskores
35 {
36 namespace exec
37 {
38 namespace cuda
39 {
40 namespace internal
41 {
42 
43 template <class ArrayPortalType>
44 class IteratorFromArrayPortal
45  : public ::thrust::iterator_facade<IteratorFromArrayPortal<ArrayPortalType>,
46  typename ArrayPortalType::ValueType,
47  ::thrust::system::cuda::tag,
48  ::thrust::random_access_traversal_tag,
49  viskores::internal::ArrayPortalValueReference<ArrayPortalType>,
50  std::ptrdiff_t>
51 {
52 public:
54  IteratorFromArrayPortal()
55  : Portal()
56  , Index(0)
57  {
58  }
59 
61  explicit IteratorFromArrayPortal(const ArrayPortalType& portal, viskores::Id index = 0)
62  : Portal(portal)
63  , Index(index)
64  {
65  }
66 
68  viskores::internal::ArrayPortalValueReference<ArrayPortalType> operator[](
69  std::ptrdiff_t idx) const //NEEDS to be signed
70  {
71  return viskores::internal::ArrayPortalValueReference<ArrayPortalType>(
72  this->Portal, this->Index + static_cast<viskores::Id>(idx));
73  }
74 
75 private:
76  ArrayPortalType Portal;
78 
79  // Implementation for ::thrust iterator_facade
80  friend class ::thrust::iterator_core_access;
81 
83  viskores::internal::ArrayPortalValueReference<ArrayPortalType> dereference() const
84  {
85  return viskores::internal::ArrayPortalValueReference<ArrayPortalType>(this->Portal,
86  this->Index);
87  }
88 
90  bool equal(const IteratorFromArrayPortal<ArrayPortalType>& other) const
91  {
92  // Technically, we should probably check that the portals are the same,
93  // but the portal interface does not specify an equal operator. It is
94  // by its nature undefined what happens when comparing iterators from
95  // different portals anyway.
96  return (this->Index == other.Index);
97  }
98 
100  void increment() { this->Index++; }
101 
103  void decrement() { this->Index--; }
104 
106  void advance(std::ptrdiff_t delta) { this->Index += static_cast<viskores::Id>(delta); }
107 
109  std::ptrdiff_t distance_to(const IteratorFromArrayPortal<ArrayPortalType>& other) const
110  {
111  // Technically, we should probably check that the portals are the same,
112  // but the portal interface does not specify an equal operator. It is
113  // by its nature undefined what happens when comparing iterators from
114  // different portals anyway.
115  return static_cast<std::ptrdiff_t>(other.Index - this->Index);
116  }
117 };
118 }
119 }
120 }
121 } //namespace viskores::exec::cuda::internal
122 
123 //So for the unary_transform_functor and binary_transform_functor inside
124 //of thrust, they verify that the index they are storing into is a reference
125 //instead of a value, so that the contents actually are written to global memory.
126 //
127 //But for viskores we pass in facade objects, which are passed by value, but
128 //must be treated as references. So do to do that properly we need to specialize
129 //is_non_const_reference to state an ArrayPortalValueReference by value is valid
130 //for writing
131 namespace thrust
132 {
133 namespace detail
134 {
135 
136 template <typename T>
137 struct is_non_const_reference;
138 
139 template <typename T>
140 struct is_non_const_reference<viskores::internal::ArrayPortalValueReference<T>>
141  : thrust::detail::true_type
142 {
143 };
144 }
145 }
146 
147 #endif //viskores_exec_cuda_internal_IteratorFromArrayPortal_h
Types.h
Pair.h
VISKORES_THIRDPARTY_POST_INCLUDE
#define VISKORES_THIRDPARTY_POST_INCLUDE
Definition: Configure.h:200
VISKORES_EXEC_CONT
#define VISKORES_EXEC_CONT
Definition: ExportMacros.h:60
ThrustPatches.h
ExportMacros.h
viskores::Id
viskores::Int64 Id
Base type to use to index arrays.
Definition: Types.h:235
VISKORES_CONT
#define VISKORES_CONT
Definition: ExportMacros.h:65
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
ArrayPortalValueReference.h
Index
int Index
Definition: ChooseCudaDevice.h:95
VISKORES_THIRDPARTY_PRE_INCLUDE
#define VISKORES_THIRDPARTY_PRE_INCLUDE
Definition: Configure.h:199
VISKORES_EXEC
#define VISKORES_EXEC
Definition: ExportMacros.h:59