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 2016 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
10 //  Copyright 2016 UT-Battelle, LLC.
11 //  Copyright 2016 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 #ifndef vtk_m_cont_ArrayRangeCompute_h
21 #define vtk_m_cont_ArrayRangeCompute_h
22 
23 #include <vtkm/Range.h>
24 
25 #include <vtkm/cont/ArrayHandle.h>
26 #include <vtkm/cont/ArrayHandleCartesianProduct.h>
27 #include <vtkm/cont/ArrayHandleCompositeVector.h>
28 #include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
29 #include <vtkm/cont/ArrayHandleVirtualCoordinates.h>
30 #include <vtkm/cont/RuntimeDeviceTracker.h>
31 
32 namespace vtkm
33 {
34 namespace cont
35 {
36 
37 /// \brief Compute the range of the data in an array handle.
38 ///
39 /// Given an \c ArrayHandle, this function computes the range (min and max) of
40 /// the values in the array. For arrays containing Vec values, the range is
41 /// computed for each component.
42 ///
43 /// This method optionally takes a \c RuntimeDeviceTracker to control which
44 /// devices to try.
45 ///
46 /// The result is returned in an \c ArrayHandle of \c Range objects. There is
47 /// one value in the returned array for every component of the input's value
48 /// type.
49 ///
50 template <typename ArrayHandleType>
51 VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
52   const ArrayHandleType& input,
53   vtkm::cont::RuntimeDeviceTracker tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker());
54 
55 // Precompiled versions of ArrayRangeCompute
56 #define VTKM_ARRAY_RANGE_COMPUTE_EXPORT_T(T, Storage)                                              \
57   VTKM_CONT_EXPORT                                                                                 \
58   VTKM_CONT                                                                                        \
59   vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(                                          \
60     const vtkm::cont::ArrayHandle<T, Storage>& input,                                              \
61     vtkm::cont::RuntimeDeviceTracker tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker())
62 #define VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(T, N, Storage)                                         \
63   VTKM_CONT_EXPORT                                                                                 \
64   VTKM_CONT                                                                                        \
65   vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(                                          \
66     const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, Storage>& input,                                \
67     vtkm::cont::RuntimeDeviceTracker tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker())
68 
69 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_T(char, vtkm::cont::StorageTagBasic);
70 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::Int8, vtkm::cont::StorageTagBasic);
71 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::UInt8, vtkm::cont::StorageTagBasic);
72 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::Int16, vtkm::cont::StorageTagBasic);
73 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::UInt16, vtkm::cont::StorageTagBasic);
74 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::Int32, vtkm::cont::StorageTagBasic);
75 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::UInt32, vtkm::cont::StorageTagBasic);
76 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::Int64, vtkm::cont::StorageTagBasic);
77 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::UInt64, vtkm::cont::StorageTagBasic);
78 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::Float32, vtkm::cont::StorageTagBasic);
79 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::Float64, vtkm::cont::StorageTagBasic);
80 
81 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Int32, 2, vtkm::cont::StorageTagBasic);
82 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Int64, 2, vtkm::cont::StorageTagBasic);
83 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Float32, 2, vtkm::cont::StorageTagBasic);
84 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Float64, 2, vtkm::cont::StorageTagBasic);
85 
86 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Int32, 3, vtkm::cont::StorageTagBasic);
87 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Int64, 3, vtkm::cont::StorageTagBasic);
88 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Float32, 3, vtkm::cont::StorageTagBasic);
89 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Float64, 3, vtkm::cont::StorageTagBasic);
90 
91 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(char, 4, vtkm::cont::StorageTagBasic);
92 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Int8, 4, vtkm::cont::StorageTagBasic);
93 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::UInt8, 4, vtkm::cont::StorageTagBasic);
94 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Float32, 4, vtkm::cont::StorageTagBasic);
95 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Float64, 4, vtkm::cont::StorageTagBasic);
96 
97 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::FloatDefault,
98                                     3,
99                                     vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag);
100 
101 VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::FloatDefault,
102                                     3,
103                                     vtkm::cont::ArrayHandleVirtualCoordinates::StorageTag);
104 
105 #undef VTKM_ARRAY_RANGE_COMPUTE_EXPORT_T
106 #undef VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC
107 
108 // Implementation of composite vectors
109 VTKM_CONT_EXPORT
110 VTKM_CONT
111 vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
112   const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>,
113                                 typename vtkm::cont::ArrayHandleCompositeVector<
114                                   vtkm::cont::ArrayHandle<vtkm::Float32>,
115                                   vtkm::cont::ArrayHandle<vtkm::Float32>,
116                                   vtkm::cont::ArrayHandle<vtkm::Float32>>::StorageTag>& input,
117   vtkm::cont::RuntimeDeviceTracker tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker());
118 
119 VTKM_CONT_EXPORT
120 VTKM_CONT
121 vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
122   const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>,
123                                 typename vtkm::cont::ArrayHandleCompositeVector<
124                                   vtkm::cont::ArrayHandle<vtkm::Float64>,
125                                   vtkm::cont::ArrayHandle<vtkm::Float64>,
126                                   vtkm::cont::ArrayHandle<vtkm::Float64>>::StorageTag>& input,
127   vtkm::cont::RuntimeDeviceTracker tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker());
128 
129 // Implementation of cartesian products
130 template <typename T, typename ArrayType1, typename ArrayType2, typename ArrayType3>
131 VTKM_CONT inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
132   const vtkm::cont::ArrayHandle<
133     T,
134     vtkm::cont::internal::StorageTagCartesianProduct<ArrayType1, ArrayType2, ArrayType3>>& input,
135   vtkm::cont::RuntimeDeviceTracker tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker())
136 {
137   vtkm::cont::ArrayHandle<vtkm::Range> result;
138   result.Allocate(3);
139 
140   vtkm::cont::ArrayHandle<vtkm::Range> componentRangeArray;
141   vtkm::Range componentRange;
142 
143   ArrayType1 firstArray = input.GetStorage().GetFirstArray();
144   componentRangeArray = vtkm::cont::ArrayRangeCompute(firstArray, tracker);
145   componentRange = componentRangeArray.GetPortalConstControl().Get(0);
146   result.GetPortalControl().Set(0, componentRange);
147 
148   ArrayType2 secondArray = input.GetStorage().GetSecondArray();
149   componentRangeArray = vtkm::cont::ArrayRangeCompute(secondArray, tracker);
150   componentRange = componentRangeArray.GetPortalConstControl().Get(0);
151   result.GetPortalControl().Set(1, componentRange);
152 
153   ArrayType3 thirdArray = input.GetStorage().GetThirdArray();
154   componentRangeArray = vtkm::cont::ArrayRangeCompute(thirdArray, tracker);
155   componentRange = componentRangeArray.GetPortalConstControl().Get(0);
156   result.GetPortalControl().Set(2, componentRange);
157 
158   return result;
159 }
160 
161 VTKM_CONT_EXPORT void ThrowArrayRangeComputeFailed();
162 }
163 } // namespace vtkm::cont
164 
165 #endif //vtk_m_cont_ArrayRangeCompute_h
166