TECA
The Toolkit for Extreme Climate Analysis
teca_variant_array_util.h
Go to the documentation of this file.
1 #ifndef teca_variant_array_util_h
2 #define teca_variant_array_util_h
3 
4 /// @file
5 
6 #include <tuple>
7 
8 #if defined(TECA_HAS_CUDA)
9 #include "teca_cuda_util.h"
10 #endif
11 
12 /// some functions helping us manipulate teca_variant_array
14 {
15 /// synchronize the default stream.
16 inline
18 {
19 #if defined(TECA_HAS_CUDA)
21 #endif
22 }
23 
24 /** synchronize the default stream once if any of the passed arrays are not
25  * accessible on the host. this should be done after all get_host_accessible
26  * are issued and before the data is accessed.
27  */
28 template <typename... array_t>
29 void sync_host_access_any(const array_t &... arrays)
30 {
31  if ((!arrays->host_accessible() || ...))
32  {
33 #if defined(TECA_HAS_CUDA)
35 #endif
36  }
37 }
38 
39 /** static_cast a number of p_teca_variant_array into their derived type
40  * teca_variant_array_impl<NT>*. Can be used with p_const_teca_variant_array as
41  * well.
42  *
43  * @tparam TT teca_variant_array_impl<NT>
44  * @tparam PP a parameter pack
45  * @param args some number of p_teca_variant_array instances.
46  * @returns a std::tuple of teca_variant_array_impl<NT>* one for each of args
47  * in the same order.
48  */
49 template <typename TT, typename... PP>
50 auto va_static_cast(PP &&... args)
51 {
52  return std::make_tuple(static_cast<TT*>(args.get())...);
53 }
54 
55 /** dynamic_cast a number of p_teca_variant_array into their derived type
56  * teca_variant_array_impl<NT>*. Can be used with p_const_teca_variant_array as
57  * well.
58  *
59  * @tparam TT teca_variant_array_impl<NT>
60  * @tparam PP a parameter pack
61  * @param args some number of p_teca_variant_array instances.
62  * @returns a std::tuple of teca_variant_array_impl<NT>* one for each of args
63  * in the same order.
64  */
65 template <typename TT, typename... PP>
66 auto va_dynamic_cast(PP &&... args)
67 {
68  return std::make_tuple(dynamic_cast<TT*>(args.get())...);
69 }
70 
71 /// terminates recursion
72 template <typename TT>
73 void assert_type() {}
74 
75 /** Check that a number of p_teca_variant_array are teca_variant_array_impl<NT>
76  * instances. This will terminate execution if the check fails. Unlike asssert
77  * this check is always applied.
78  *
79  * @tparam TT teca_variant_array_impl<NT>
80  * @tparam PP a parameter pack
81  * @param va a p_teca_variant_array instance
82  * @param args some number of p_teca_variant_array instances.
83  */
84 template <typename TT, typename... PP>
85 void assert_type(const const_p_teca_variant_array &va, PP &&... args)
86 {
87  if (!dynamic_cast<const TT*>(va.get()))
88  {
89  TECA_FATAL_ERROR("teca_variant_array instance is not a"
90  " teca_variant_array_impl<" << typeid(typename TT::element_type).name()
91  << sizeof(typename TT::element_type) << ">")
92  }
93 
94  (assert_type<TT>(args), ...);
95 }
96 
97 /// terminates recursion
98 template <typename TT>
100 {
101  return std::make_tuple();
102 }
103 
104 /** Calls teca_varaint_array_impl<NT>::get_host_accessible on a number of
105  * p_teca_variant_array instances. The instances are first static_cast to
106  * teca_variant_array_impl<NT>*. One should only use this method when one is
107  * certain that this static_cast is appropriate. See va_assert_type for one
108  * way to validate that the types are as expected.
109  *
110  * @tparam TT teca_variant_array_impl<NT>
111  * @tparam PP a paramater pack
112  * @param va a p_teca_variant_array instance
113  * @param args any number of p_teca_variant_array instances
114  * @returns a tuple of std::shared_ptr<NT> and NT* one for each
115  * p_teca_variant_array passed in.
116  */
117 template <typename TT, typename... PP>
118 auto get_host_accessible(const std::shared_ptr<const TT> &va, PP &&... args)
119 {
120  auto tva = static_cast<const TT*>(va.get());
121  auto spva = tva->get_host_accessible();
122  return std::tuple_cat(std::make_tuple
123  (spva, spva.get()), get_host_accessible<TT>(args...));
124 }
125 
126 /** Calls teca_varaint_array_impl<NT>::get_host_accessible on a number of
127  * p_teca_variant_array instances. The instances are first static_cast to
128  * teca_variant_array_impl<NT>*. One should only use this method when one is
129  * certain that this static_cast is appropriate. See va_assert_type for one
130  * way to validate that the types are as expected.
131  *
132  * @tparam TT teca_variant_array_impl<NT>
133  * @tparam PP a paramater pack
134  * @param va a const_p_teca_variant_array instance
135  * @param args any number of p_teca_variant_array instances
136  * @returns a tuple of std::shared_ptr<const NT> and const NT* one for each
137  * p_teca_variant_array passed in.
138  */
139 template <typename TT, typename... V>
140 auto get_host_accessible(const std::shared_ptr<TT> &va, V &&... args)
141 {
142  auto tva = static_cast<TT*>(va.get());
143  auto spva = tva->get_host_accessible();
144  return std::tuple_cat(std::make_tuple
145  (spva, spva.get()), get_host_accessible<TT>(args...));
146 }
147 
148 /** Calls teca_varaint_array_impl<NT>::get_host_accessible on a number of
149  * p_teca_variant_array instances. The instances are first static_cast to
150  * teca_variant_array_impl<NT>*. One should only use this method when one is
151  * certain that this static_cast is appropriate. See va_assert_type for one
152  * way to validate that the types are as expected.
153  *
154  * @tparam TT teca_variant_array_impl<NT>
155  * @tparam PP a paramater pack
156  * @param va a p_teca_variant_array instance
157  * @param args any number of p_teca_variant_array instances
158  * @returns a tuple of std::shared_ptr<NT> and NT* one for each
159  * p_teca_variant_array passed in.
160  */
161 template <typename TT, typename... PP>
162 auto get_host_accessible(const const_p_teca_variant_array &va, PP &&... args)
163 {
164  auto tva = static_cast<const TT*>(va.get());
165  auto spva = tva->get_host_accessible();
166  return std::tuple_cat(std::make_tuple
167  (spva, spva.get()), get_host_accessible<TT>(args...));
168 }
169 
170 /** Calls teca_varaint_array_impl<NT>::get_host_accessible on a number of
171  * p_teca_variant_array instances. The instances are first static_cast to
172  * teca_variant_array_impl<NT>*. One should only use this method when one is
173  * certain that this static_cast is appropriate. See va_assert_type for one
174  * way to validate that the types are as expected.
175  *
176  * @tparam TT teca_variant_array_impl<NT>
177  * @tparam PP a paramater pack
178  * @param va a const_p_teca_variant_array instance
179  * @param args any number of p_teca_variant_array instances
180  * @returns a tuple of std::shared_ptr<const NT> and const NT* one for each
181  * p_teca_variant_array passed in.
182  */
183 template <typename TT, typename... V>
184 auto get_host_accessible(const p_teca_variant_array &va, V &&... args)
185 {
186  auto tva = static_cast<TT*>(va.get());
187  auto spva = tva->get_host_accessible();
188  return std::tuple_cat(std::make_tuple
189  (spva, spva.get()), get_host_accessible<TT>(args...));
190 }
191 
192 /// terminates recursion
193 template <typename TT>
195 {
196  return std::make_tuple();
197 }
198 
199 /** Calls teca_varaint_array_impl<NT>::get_cuda_accessible on a number of
200  * p_teca_variant_array instances. The instances are first static_cast to
201  * teca_variant_array_impl<NT>*. One should only use this method when one is
202  * certain that this static_cast is appropriate. See va_assert_type for one
203  * way to validate that the types are as expected.
204  *
205  * @tparam TT teca_variant_array_impl<NT>
206  * @tparam PP a paramater pack
207  * @param va a p_teca_variant_array instance
208  * @param args any number of p_teca_variant_array instances
209  * @returns a tuple of std::shared_ptr<NT> and NT* one for each
210  * p_teca_variant_array passed in.
211  */
212 template <typename TT, typename... PP>
213 auto get_cuda_accessible(const const_p_teca_variant_array &va, PP &&... args)
214 {
215  auto tva = static_cast<const TT*>(va.get());
216  auto spva = tva->get_cuda_accessible();
217  return std::tuple_cat(std::make_tuple
218  (spva, spva.get()), get_cuda_accessible<TT>(args...));
219 }
220 
221 /** Calls teca_varaint_array_impl<NT>::get_cuda_accessible on a number of
222  * p_teca_variant_array instances. The instances are first static_cast to
223  * teca_variant_array_impl<NT>*. One should only use this method when one is
224  * certain that this static_cast is appropriate. See va_assert_type for one
225  * way to validate that the types are as expected.
226  *
227  * @tparam TT teca_variant_array_impl<NT>
228  * @tparam PP a paramater pack
229  * @param va a const_p_teca_variant_array instance
230  * @param args any number of p_teca_variant_array instances
231  * @returns a tuple of std::shared_ptr<const NT> and const NT* one for each
232  * p_teca_variant_array passed in.
233  */
234 template <typename TT, typename... V>
235 auto get_cuda_accessible(const p_teca_variant_array &va, V &&... args)
236 {
237  auto tva = static_cast<TT*>(va.get());
238  auto spva = tva->get_cuda_accessible();
239  return std::tuple_cat(std::make_tuple
240  (spva, spva.get()), get_cuda_accessible<TT>(args...));
241 }
242 
243 /** Calls teca_varaint_array_impl<NT>::data on a number of
244  * p_teca_variant_array instances. The instances are first static_cast to
245  * teca_variant_array_impl<NT>*. One should only use this method when one is
246  * certain that this static_cast is appropriate. See va_assert_type for one
247  * way to validate that the types are as expected.
248  *
249  * @tparam TT teca_variant_array_impl<NT>
250  * @tparam PP a paramater pack
251  * @param args any number of p_teca_variant_array instances
252  * @returns a tuple of NT* one for each p_teca_variant_array passed in.
253  */
254 template <typename TT, typename... V>
255 auto data(V &&... args)
256 {
257  return std::make_tuple(static_cast<TT*>(args.get())->data()...);
258 }
259 
260 /** Allocates a teca_variant_array_impl<NT> instance and returns the newly
261  * allocated array and a pointer to it's memory.
262  *
263  * @tparam TT teca_variant_array_impl<NT>
264  * @param n_elem the size of the array
265  * @param alloc the allocator to use
266  * @returns a tuple of p_teca_variant_array_impl<NT> and NT*
267  */
268 template <typename TT>
269 auto New(size_t n_elem,
270  teca_variant_array::allocator alloc = teca_variant_array::allocator::malloc)
271 {
272  auto out = TT::New(n_elem, alloc);
273  return std::make_tuple(out, out->data());
274 }
275 
276 /** Allocates a teca_variant_array_impl<NT> instance and returns the newly
277  * allocated array and a pointer to it's memory.
278  *
279  * @tparam TT teca_variant_array_impl<NT>
280  * @param n_elem the size of the array
281  * @param init_val a value to initialize the contents of the array to
282  * @param alloc the allocator to use
283  * @returns a tuple of p_teca_variant_array_impl<NT> and NT*
284  */
285 template <typename TT, typename NT = typename TT::element_type>
286 auto New(size_t n_elem, NT init_val,
287  teca_variant_array::allocator alloc = teca_variant_array::allocator::malloc)
288 {
289  auto out = TT::New(n_elem, init_val, alloc);
290  return std::make_tuple(out, out->data());
291 }
292 
293 }
294 #endif
hamr::buffer_allocator allocator
allocator types
Definition: teca_variant_array.h:46
TECA_EXPORT int synchronize_stream()
synchronize the default stream
some functions helping us manipulate teca_variant_array
Definition: teca_variant_array_util.h:14
void synchronize_stream()
synchronize the default stream.
Definition: teca_variant_array_util.h:17
auto get_host_accessible()
terminates recursion
Definition: teca_variant_array_util.h:99
auto New(size_t n_elem, NT init_val, teca_variant_array::allocator alloc=teca_variant_array::allocator::malloc)
Definition: teca_variant_array_util.h:286
auto va_dynamic_cast(PP &&... args)
Definition: teca_variant_array_util.h:66
auto data(V &&... args)
Definition: teca_variant_array_util.h:255
void sync_host_access_any(const array_t &... arrays)
Definition: teca_variant_array_util.h:29
auto New(size_t n_elem, teca_variant_array::allocator alloc=teca_variant_array::allocator::malloc)
Definition: teca_variant_array_util.h:269
auto get_cuda_accessible()
terminates recursion
Definition: teca_variant_array_util.h:194
auto va_static_cast(PP &&... args)
Definition: teca_variant_array_util.h:50
void assert_type()
terminates recursion
Definition: teca_variant_array_util.h:73
#define TECA_FATAL_ERROR(_msg)
Definition: teca_common.h:153
std::shared_ptr< teca_variant_array > p_teca_variant_array
Definition: teca_variant_array.h:27
std::shared_ptr< const teca_variant_array > const_p_teca_variant_array
Definition: teca_variant_array.h:27