1 #ifndef teca_variant_array_impl_h
2 #define teca_variant_array_impl_h
6 #if defined(__CUDACC__)
7 #pragma nv_diag_suppress = partial_override
10 #include "teca_config.h"
13 #include "teca_binary_stream.h"
14 #include "teca_bad_cast.h"
17 #include <hamr_buffer.h>
26 #include <type_traits>
31 #if defined(TECA_HAS_CUDA)
32 #include <thrust/device_ptr.h>
33 #include <thrust/functional.h>
34 #include <thrust/reduce.h>
43 using p_teca_string_array = std::shared_ptr<teca_variant_array_impl<std::string>>;
44 using const_p_teca_string_array = std::shared_ptr<const teca_variant_array_impl<std::string>>;
47 using p_teca_float_array = std::shared_ptr<teca_variant_array_impl<float>>;
48 using const_p_teca_float_array = std::shared_ptr<const teca_variant_array_impl<float>>;
51 using p_teca_double_array = std::shared_ptr<teca_variant_array_impl<double>>;
52 using const_p_teca_double_array = std::shared_ptr<const teca_variant_array_impl<double>>;
55 using p_teca_char_array = std::shared_ptr<teca_variant_array_impl<char>>;
56 using const_p_teca_char_array = std::shared_ptr<const teca_variant_array_impl<char>>;
59 using p_teca_unsigned_char_array = std::shared_ptr<teca_variant_array_impl<unsigned char>>;
60 using const_p_teca_unsigned_char_array = std::shared_ptr<const teca_variant_array_impl<unsigned char>>;
63 using p_teca_short_array = std::shared_ptr<teca_variant_array_impl<short>>;
64 using const_p_teca_short_array = std::shared_ptr<const teca_variant_array_impl<short>>;
67 using p_teca_unsigned_short_array = std::shared_ptr<teca_variant_array_impl<unsigned short>>;
68 using const_p_teca_unsigned_short_array = std::shared_ptr<const teca_variant_array_impl<unsigned short>>;
71 using p_teca_int_array = std::shared_ptr<teca_variant_array_impl<int>>;
72 using const_p_teca_int_array = std::shared_ptr<const teca_variant_array_impl<int>>;
75 using p_teca_unsigned_int_array = std::shared_ptr<teca_variant_array_impl<unsigned int>>;
76 using const_p_teca_unsigned_int_array = std::shared_ptr<const teca_variant_array_impl<unsigned int>>;
79 using p_teca_long_array = std::shared_ptr<teca_variant_array_impl<long>>;
80 using const_p_teca_long_array = std::shared_ptr<const teca_variant_array_impl<long>>;
83 using p_teca_unsigned_long_array = std::shared_ptr<teca_variant_array_impl<unsigned long>>;
84 using const_p_teca_unsigned_long_array = std::shared_ptr<const teca_variant_array_impl<unsigned long>>;
87 using p_teca_long_long_array = std::shared_ptr<teca_variant_array_impl<long long>>;
88 using const_p_teca_long_long_array = std::shared_ptr<const teca_variant_array_impl<long long>>;
91 using p_teca_unsigned_long_long_array = std::shared_ptr<teca_variant_array_impl<unsigned long long>>;
92 using const_p_teca_unsigned_long_long_array = std::shared_ptr<const teca_variant_array_impl<unsigned long long>>;
95 using p_teca_size_t_array = std::shared_ptr<teca_variant_array_impl<size_t>>;
96 using const_p_teca_size_t_array = std::shared_ptr<const teca_variant_array_impl<size_t>>;
104 template <
typename T>
113 template <
typename T>
115 std::integral_constant<bool,
116 std::is_arithmetic<T>::value>
120 template <
typename T>
122 std::integral_constant<bool,
123 !std::is_arithmetic<T>::value>
139 #define TEMPLATE_DISPATCH_CASE(tt, nt, p, body) \
140 if (dynamic_cast<tt<nt>*>(p)) \
162 #define NESTED_TEMPLATE_DISPATCH_CASE(tt, nt, p, i, body) \
163 if (dynamic_cast<tt<nt>*>(p)) \
165 using TT##i = tt<nt>; \
171 #define TEMPLATE_DISPATCH_FP(t, p, body) \
172 TEMPLATE_DISPATCH_CASE(t, float, p, body) \
173 else TEMPLATE_DISPATCH_CASE(t, double, p, body)
176 #define TEMPLATE_DISPATCH_SI(t, p, body) \
177 TEMPLATE_DISPATCH_CASE(t, long long, p, body) \
178 else TEMPLATE_DISPATCH_CASE(t, long, p, body) \
179 else TEMPLATE_DISPATCH_CASE(t, int, p, body) \
180 else TEMPLATE_DISPATCH_CASE(t, short int, p, body) \
181 else TEMPLATE_DISPATCH_CASE(t, char, p, body)
184 #define TEMPLATE_DISPATCH_FP_SI(t, p, body) \
185 TEMPLATE_DISPATCH_CASE(t, float, p, body) \
186 else TEMPLATE_DISPATCH_CASE(t, double, p, body) \
187 else TEMPLATE_DISPATCH_SI(t, p, body)
190 #define TEMPLATE_DISPATCH_I(t, p, body) \
191 TEMPLATE_DISPATCH_CASE(t, long long, p, body) \
192 else TEMPLATE_DISPATCH_CASE(t, unsigned long long, p, body) \
193 else TEMPLATE_DISPATCH_CASE(t, long, p, body) \
194 else TEMPLATE_DISPATCH_CASE(t, int, p, body) \
195 else TEMPLATE_DISPATCH_CASE(t, unsigned int, p, body) \
196 else TEMPLATE_DISPATCH_CASE(t, unsigned long, p, body) \
197 else TEMPLATE_DISPATCH_CASE(t, short int, p, body) \
198 else TEMPLATE_DISPATCH_CASE(t, short unsigned int, p, body) \
199 else TEMPLATE_DISPATCH_CASE(t, char, p, body) \
200 else TEMPLATE_DISPATCH_CASE(t, unsigned char, p, body)
209 #define TEMPLATE_DISPATCH(t, p, body) \
210 TEMPLATE_DISPATCH_FP(t, p, body) \
211 else TEMPLATE_DISPATCH_I(t, p, body)
220 #define TEMPLATE_DISPATCH_OBJ(t, p, body) \
221 TEMPLATE_DISPATCH_CASE(t, std::string, p, body) \
222 else TEMPLATE_DISPATCH_CASE(t, teca_metadata, p, body)
231 #define TEMPLATE_DISPATCH_PTR(t, p, body) \
232 TEMPLATE_DISPATCH_CASE(t, const_p_teca_variant_array, p, body) \
233 else TEMPLATE_DISPATCH_CASE(t, p_teca_variant_array, p, body)
243 #define NESTED_TEMPLATE_DISPATCH_FP(t, p, i, body) \
244 NESTED_TEMPLATE_DISPATCH_CASE(t, float, p, i, body) \
245 else NESTED_TEMPLATE_DISPATCH_CASE(t, double, p, i, body)
255 #define NESTED_TEMPLATE_DISPATCH_I(t, p, i, body) \
256 NESTED_TEMPLATE_DISPATCH_CASE(t, long long, p, i, body) \
257 else NESTED_TEMPLATE_DISPATCH_CASE(t, unsigned long long, p, i, body) \
258 else NESTED_TEMPLATE_DISPATCH_CASE(t, long, p, i, body) \
259 else NESTED_TEMPLATE_DISPATCH_CASE(t, int, p, i, body) \
260 else NESTED_TEMPLATE_DISPATCH_CASE(t, unsigned int, p, i, body) \
261 else NESTED_TEMPLATE_DISPATCH_CASE(t, unsigned long, p, i, body) \
262 else NESTED_TEMPLATE_DISPATCH_CASE(t, short int, p, i, body) \
263 else NESTED_TEMPLATE_DISPATCH_CASE(t, short unsigned int, p, i, body) \
264 else NESTED_TEMPLATE_DISPATCH_CASE(t, char, p, i, body) \
265 else NESTED_TEMPLATE_DISPATCH_CASE(t, unsigned char, p, i, body)
276 #define NESTED_TEMPLATE_DISPATCH(t, p, i, body) \
277 NESTED_TEMPLATE_DISPATCH_FP(t, p, i, body) \
278 else NESTED_TEMPLATE_DISPATCH_I(t, p, i, body)
285 : std::integral_constant<bool,
286 std::is_arithmetic<T>::value ||
287 std::is_same<T, std::string>::value>
292 struct pack_object_ptr
293 : std::integral_constant<bool,
294 (std::is_pointer<T>::value ||
295 std::is_same<T, p_teca_variant_array>::value) &&
296 !pack_array<T>::value>
302 : std::integral_constant<bool,
303 !pack_array<T>::value &&
304 !std::is_pointer<T>::value &&
305 !pack_object_ptr<T>::value>
325 static std::shared_ptr<teca_variant_array_impl<T>>
331 static std::shared_ptr<teca_variant_array_impl<T>>
332 New(allocator alloc);
338 static std::shared_ptr<teca_variant_array_impl<T>>
339 New(
size_t n) {
return New(n, allocator::malloc); }
345 static std::shared_ptr<teca_variant_array_impl<T>>
346 New(
size_t n, allocator alloc);
352 template <
typename U>
353 static std::shared_ptr<teca_variant_array_impl<T>>
354 New(
size_t n,
const U &v) {
return New(n, v, allocator::malloc); }
360 template <
typename U>
361 static std::shared_ptr<teca_variant_array_impl<T>>
362 New(
size_t n,
const U &v, allocator alloc);
368 template <
typename U>
369 static std::shared_ptr<teca_variant_array_impl<T>>
370 New(
size_t n,
const U *v) {
return New(n, v, allocator::malloc); }
376 template <
typename U>
377 static std::shared_ptr<teca_variant_array_impl<T>>
378 New(
size_t n,
const U *v, allocator alloc);
397 template <
typename delete_func_t>
398 static std::shared_ptr<teca_variant_array_impl<T>>
399 New(
size_t n, T *ptr, allocator alloc,
int owner, delete_func_t df);
419 int set_allocator(allocator alloc) override;
422 std::
string get_class_name() const override;
425 void initialize()
override
444 void get(
size_t i, U &val)
const
446 this->
get(i, &val, 0, 1);
453 this->
get(i, &val, 0, 1);
459 void get(std::vector<U> &dest)
const
461 size_t n_elem = this->
size();
463 this->
get(0, dest.data(), 0, n_elem);
468 void get(
size_t src_start, U *dest,
size_t dest_start,
size_t n_elem)
const
470 assert(this->
size() >= (src_start + n_elem));
471 this->get_dispatch(src_start, dest, dest_start, n_elem);
477 this->
get(0, dest, 0, this->
size());
488 size_t dest_start,
size_t n_elem)
const override
490 assert(this->
size() >= (src_start + n_elem));
491 this->get_dispatch<T>(src_start, dest, dest_start, n_elem);
495 template <
typename U>
498 this->
get(0, dest, 0, this->
size());
508 template <
typename U>
510 size_t dest_start,
size_t n_elem)
const
512 assert(this->
size() >= (src_start + n_elem));
513 this->get_dispatch<T>(src_start, dest, dest_start, n_elem);
526 void set(
size_t i,
const U &val)
528 this->
set(i, &val, 0, 1);
533 void set(
const std::vector<U> &src)
535 this->
set(0, src.data(), 0, src.size());
546 void set(
size_t dest_start,
const U *src,
size_t src_start,
size_t n_elem)
548 assert(this->
size() >= (dest_start + n_elem));
549 this->set_dispatch(dest_start, src, src_start, n_elem);
555 this->
set(0, src, 0, src->size());
566 size_t src_start,
size_t n_elem)
override
568 assert(this->
size() >= (dest_start + n_elem));
569 this->set_dispatch(dest_start, src, src_start, n_elem);
573 template <
typename U>
576 this->
set(0, src, 0, src->size());
586 template <
typename U>
588 size_t src_start,
size_t n_elem)
590 assert(this->
size() >= (dest_start + n_elem));
591 this->set_dispatch(dest_start, src, src_start, n_elem);
605 this->
assign(src.data(), 0, src.size());
610 void assign(
const U *src,
size_t src_start,
size_t n_elem)
612 this->assign_dispatch(src, src_start, n_elem);
618 this->
assign(src, 0, src->size());
623 size_t src_start,
size_t n_elem)
override
625 this->assign_dispatch(src, src_start, n_elem);
629 template <
typename U>
632 this->
assign(src, 0, src->size());
636 template <
typename U>
644 template <
typename U>
646 size_t src_start,
size_t n_elem)
648 this->assign_dispatch(src, src_start, n_elem);
652 template <
typename U>
655 this->
assign(src, 0, src->size());
659 template <
typename U>
661 size_t src_start,
size_t n_elem)
663 this->assign_dispatch(src, src_start, n_elem);
684 this->
append(vals.data(), 0, vals.size());
689 void append(
const U *src,
size_t src_start,
size_t n_elem)
691 this->append_dispatch(src, src_start, n_elem);
697 this->
append(src, 0, src->size());
702 size_t src_start,
size_t n_elem)
override
704 this->append_dispatch(src, src_start, n_elem);
708 template <
typename U>
711 this->
append(src, 0, src->size());
715 template <
typename U>
723 template <
typename U>
725 size_t src_start,
size_t n_elem)
727 this->append_dispatch(src, src_start, n_elem);
739 {
return m_data.get_cpu_accessible(); }
741 const std::shared_ptr<const T> get_cpu_accessible()
const
742 {
return m_data.get_cpu_accessible(); }
744 std::shared_ptr<T> get_cuda_accessible()
745 {
return m_data.get_cuda_accessible(); }
747 const std::shared_ptr<const T> get_cuda_accessible()
const
748 {
return m_data.get_cuda_accessible(); }
759 unsigned long size() const noexcept override;
762 void resize(
unsigned long n) override;
763 void resize(
unsigned long n, const T &val);
766 void reserve(
unsigned long n) override;
769 void clear() noexcept override;
780 this->to_binary<T>(s);
787 this->from_binary<T>(s);
794 this->to_ascii<T>(s);
801 this->from_ascii<T>(s);
806 template <
typename U = T>
807 void debug_print(
typename std::enable_if< std::is_arithmetic<U>::value >::type* = 0)
const
811 template <
typename U = T>
812 void debug_print(
typename std::enable_if<!std::is_arithmetic<U>::value>::type* = 0)
const
814 TECA_WARNING(
"Failed to print the buffer for T=" <<
typeid(T).name() <<
sizeof(T))
838 m_data(alloc, n_elem) {}
842 m_data(alloc, n_elem, val) {}
845 template <
typename U>
847 m_data(alloc, n_elem, vals) {}
853 m_data(alloc, other->m_data) {}
856 template <
typename delete_func_t>
858 T *ptr, delete_func_t df) : m_data(alloc, size, owner, ptr, df) {}
862 template <
typename U = T>
863 void get_dispatch(
size_t src_start,
868 template <
typename U = T>
869 void get_dispatch(
size_t src_start,
874 template <
typename U = T>
875 void set_dispatch(
size_t dest_start,
880 template <
typename U = T>
881 void set_dispatch(
size_t dest_start,
886 template <
typename U = T>
888 size_t src_start,
size_t n_elem,
892 template <
typename U = T>
894 size_t src_start,
size_t n_elem,
898 template <
typename U = T>
900 size_t src_start,
size_t n_elem,
904 template <
typename U = T>
906 size_t src_start,
size_t n_elem,
910 template <
typename U = T>
911 void get_dispatch(
size_t src_start,
916 template <
typename U = T>
917 void get_dispatch(
size_t src_start,
922 template <
typename U = T>
923 void set_dispatch(
size_t dest_start,
928 template <
typename U = T>
929 void set_dispatch(
size_t dest_start,
934 template <
typename U = T>
936 size_t src_start,
size_t n_elem,
940 template <
typename U = T>
942 size_t src_start,
size_t n_elem,
946 template <
typename U = T>
948 size_t src_start,
size_t n_elem,
952 template <
typename U = T>
954 size_t src_start,
size_t n_elem,
958 template <
typename U = T>
959 void get_dispatch(
size_t src_start,
960 U *dest,
size_t dest_start,
size_t n_elem,
964 template <
typename U = T>
965 void get_dispatch(
size_t src_start,
966 U *dest,
size_t dest_start,
size_t n_elem,
970 template <
typename U = T>
971 void set_dispatch(
size_t dest_start,
972 const U *src,
size_t src_start,
size_t n_elem,
976 template <
typename U = T>
977 void set_dispatch(
size_t dest_start,
978 const U *src,
size_t src_start,
size_t n_elem,
982 template <
typename U = T>
983 void assign_dispatch(
const U *src,
984 size_t src_start,
size_t n_elem,
988 template <
typename U = T>
989 void assign_dispatch(
const U *src,
990 size_t src_start,
size_t n_elem,
994 template <
typename U = T>
995 void append_dispatch(
const U *src,
996 size_t src_start,
size_t n_elem,
1000 template <
typename U = T>
1001 void append_dispatch(
const U *src,
1002 size_t src_start,
size_t n_elem,
1008 template <
typename U = T>
1010 typename std::enable_if<pack_array<U>::value, U>::type* = 0)
1013 template <
typename U = T>
1015 typename std::enable_if<pack_array<U>::value, U>::type* = 0);
1018 template <
typename U = T>
1020 typename std::enable_if<pack_object<U>::value, U>::type* = 0)
1023 template <
typename U = T>
1025 typename std::enable_if<pack_object<U>::value, U>::type* = 0);
1028 template <
typename U = T>
1030 typename std::enable_if<pack_object_ptr<U>::value, U>::type* = 0)
1033 template <
typename U = T>
1035 typename std::enable_if<pack_object_ptr<U>::value, U>::type* = 0);
1038 template <
typename U = T>
1039 void to_ascii(std::ostream &s,
1040 typename std::enable_if<pack_array<U>::value, U>::type* = 0)
1043 template <
typename U = T>
1044 void from_ascii(std::ostream &s,
1045 typename std::enable_if<pack_array<U>::value, U>::type* = 0);
1048 template <
typename U = T>
1049 void to_ascii(std::ostream &s,
1050 typename std::enable_if<pack_object<U>::value, U>::type* = 0)
1053 template <
typename U = T>
1054 void from_ascii(std::ostream &s,
1055 typename std::enable_if<pack_object<U>::value, U>::type* = 0);
1058 template <
typename U = T>
1059 void to_ascii(std::ostream &s,
1060 typename std::enable_if<pack_object_ptr<U>::value, U>::type* = 0)
1063 template <
typename U = T>
1064 void from_ascii(std::ostream &s,
1065 typename std::enable_if<pack_object_ptr<U>::value, U>::type* = 0);
1068 unsigned int type_code() const noexcept override;
1073 return std::static_pointer_cast
1075 (teca_variant_array::shared_from_this());
1081 return std::static_pointer_cast
1083 (teca_variant_array::shared_from_this());
1087 hamr::buffer<T> m_data;
1096 #pragma GCC diagnostic ignored "-Wunknown-pragmas"
1097 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
1100 template<
typename T>
1103 this->get_dispatch(i, val);
1107 template<
typename T>
1111 this->get_dispatch(i, val);
1116 template<
typename T>
1119 this->get_dispatch(vals);
1123 template<
typename T>
1126 this->get_dispatch(src_start, dest, dest_start, n_elem);
1130 template<
typename T>
1133 this->set_dispatch(i, val);
1137 template<
typename T>
1140 this->set_dispatch(src);
1144 template<
typename T>
1147 this->set_dispatch(dest_start, src, src_start, n_elem);
1151 template<
typename T>
1154 this->assign_dispatch(src);
1158 template<
typename T>
1161 this->
assign(src, src_start, n_elem);
1165 template<
typename T>
1168 this->append_dispatch(val);
1172 template<
typename T>
1175 this->append_dispatch(src);
1179 template<
typename T>
1182 this->append_dispatch(src, src_start, n_elem);
1186 template<
typename T>
1187 void teca_variant_array::get_dispatch(
unsigned long i, T &val,
1197 ptthis->
get(i, val);
1203 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1208 template<
typename T>
1209 void teca_variant_array::get_dispatch(
unsigned long i, T &val,
1215 TT *ptthis =
dynamic_cast<TT*
>(
this);
1216 ptthis->
get(i, val);
1222 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1227 template<
typename T>
1228 void teca_variant_array::get_dispatch(std::vector<T> &vals,
1244 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1249 template<
typename T>
1250 void teca_variant_array::get_dispatch(std::vector<T> &vals,
1256 TT *ptthis =
dynamic_cast<TT*
>(
this);
1263 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1268 template<
typename T>
1269 void teca_variant_array::get_dispatch(
size_t src_start, T *dest,
size_t dest_start,
size_t n_elem,
1279 ptthis->
get(src_start, dest, dest_start, n_elem);
1285 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1290 template<
typename T>
1291 void teca_variant_array::get_dispatch(
size_t src_start, T *dest,
size_t dest_start,
size_t n_elem,
1297 TT *ptthis =
dynamic_cast<TT*
>(
this);
1298 ptthis->
get(src_start, dest, dest_start, n_elem);
1304 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1309 template<
typename T>
1310 void teca_variant_array::set_dispatch(
unsigned long i,
const T &val,
1320 ptthis->
set(i, val);
1326 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1331 template<
typename T>
1332 void teca_variant_array::set_dispatch(
unsigned long i,
const T &val,
1338 TT *ptthis =
dynamic_cast<TT*
>(
this);
1339 ptthis->
set(i, val);
1345 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1350 template<
typename T>
1351 void teca_variant_array::set_dispatch(
const std::vector<T> &src,
1367 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1372 template<
typename T>
1373 void teca_variant_array::set_dispatch(
const std::vector<T> &src,
1379 TT *ptthis =
dynamic_cast<TT*
>(
this);
1386 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1391 template<
typename T>
1392 void teca_variant_array::set_dispatch(
size_t dest_start,
1393 const T *src,
size_t src_start,
size_t n_elem,
1403 ptthis->
set(dest_start, src, src_start, n_elem);
1409 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1414 template<
typename T>
1415 void teca_variant_array::set_dispatch(
size_t dest_start,
1416 const T *src,
size_t src_start,
size_t n_elem,
1422 TT *ptthis =
dynamic_cast<TT*
>(
this);
1423 ptthis->
set(dest_start, src, src_start, n_elem);
1429 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1434 template<
typename T>
1435 void teca_variant_array::assign_dispatch(
const std::vector<T> &src,
1451 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1456 template<
typename T>
1457 void teca_variant_array::assign_dispatch(
const std::vector<T> &src,
1463 TT *ptthis =
dynamic_cast<TT*
>(
this);
1470 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1475 template<
typename T>
1476 void teca_variant_array::assign_dispatch(
const T *src,
size_t src_start,
1486 ptthis->
assign(src, src_start, n_elem);
1492 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1497 template<
typename T>
1498 void teca_variant_array::assign_dispatch(
const T *src,
size_t src_start,
size_t n_elem,
1504 TT *ptthis =
dynamic_cast<TT*
>(
this);
1505 ptthis->
assign(src, src_start, n_elem);
1511 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1516 template<
typename T>
1517 void teca_variant_array::append_dispatch(
const T &val,
1533 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1538 template<
typename T>
1539 void teca_variant_array::append_dispatch(
const T &val,
1545 TT *ptthis =
dynamic_cast<TT*
>(
this);
1552 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1557 template<
typename T>
1558 void teca_variant_array::append_dispatch(
const std::vector<T> &src,
1574 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1579 template<
typename T>
1580 void teca_variant_array::append_dispatch(
const std::vector<T> &src,
1586 TT *ptthis =
dynamic_cast<TT*
>(
this);
1593 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1598 template<
typename T>
1599 void teca_variant_array::append_dispatch(
const T *src,
size_t src_start,
size_t n_elem,
1609 ptthis->
append(src, src_start, n_elem);
1615 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1620 template<
typename T>
1621 void teca_variant_array::append_dispatch(
const T *src,
size_t src_start,
size_t n_elem,
1627 TT *ptthis =
dynamic_cast<TT*
>(
this);
1628 ptthis->
append(src, src_start, n_elem);
1634 <<
typeid(T).name() <<
sizeof(T) <<
" to " << this->
get_class_name()
1642 template<
typename T>
1649 template<
typename T>
1652 return std::make_shared<teca_variant_array_impl<T>>(alloc);
1656 template<
typename T>
1659 return std::make_shared<teca_variant_array_impl<T>>(alloc, n);
1663 template<
typename T>
1664 template<
typename U>
1666 const U &v, allocator alloc)
1668 return std::make_shared<teca_variant_array_impl<T>>(alloc, n, v);
1672 template<
typename T>
1673 template<
typename U>
1675 const U *v, allocator alloc)
1677 return std::make_shared<teca_variant_array_impl<T>>(alloc, n, v);
1681 template<
typename T>
1682 template <
typename delete_func_t>
1684 T *ptr, allocator alloc,
int owner, delete_func_t df)
1686 return std::make_shared<teca_variant_array_impl<T>>
1687 (alloc, n, owner, ptr, df);
1691 template<
typename T>
1694 if (alloc == allocator::same)
1695 alloc =
static_cast<allocator
>(m_data.get_allocator());
1697 return std::make_shared<teca_variant_array_impl<T>>
1698 (alloc, this->shared_from_this());
1702 template<
typename T>
1704 size_t n_elem, allocator alloc)
const
1706 if (alloc == allocator::same)
1707 alloc =
static_cast<allocator
>(m_data.get_allocator());
1710 std::make_shared<teca_variant_array_impl<T>>
1713 this->
get(src_start, dest, 0, n_elem);
1719 template<
typename T>
1722 if (alloc == allocator::same)
1723 alloc =
static_cast<allocator
>(m_data.get_allocator());
1725 return std::make_shared<teca_variant_array_impl<T>>(alloc);
1729 template<
typename T>
1731 allocator alloc)
const
1733 if (alloc == allocator::same)
1734 alloc =
static_cast<allocator
>(m_data.get_allocator());
1736 return std::make_shared<teca_variant_array_impl<T>>(alloc, n);
1740 template<
typename T>
1744 if (this->m_data.get_allocator() == alloc)
1748 hamr::buffer<T> tmp(alloc, m_data);
1749 m_data = std::move(tmp);
1755 template<
typename T>
1759 std::dynamic_pointer_cast<teca_variant_array_impl<T>>(other);
1763 m_data.swap(pt_other->m_data);
1767 << other->get_class_name() <<
sizeof(T) <<
" to " << this->get_class_name()
1772 template<
typename T>
1775 const char *element_name =
typeid(T).name();
1776 size_t element_size =
sizeof(T);
1777 std::ostringstream oss;
1778 oss <<
"teca_variant_array_impl<" << element_name
1779 << element_size <<
">";
1784 template<
typename T>
1787 return m_data.size();
1791 template<
typename T>
1798 template<
typename T>
1801 m_data.resize(n, val);
1805 template<
typename T>
1812 template<
typename T>
1819 template <
typename T>
1820 template <
typename U>
1827 std::dynamic_pointer_cast<teca_variant_array_impl<T>>(dest);
1831 m_data.
get(src_start, tp_dest->m_data, dest_start, n_elem);
1836 << dest->get_class_name() <<
" to " << this->get_class_name()
1841 template <
typename T>
1842 template <
typename U>
1847 assert(dest->size() >= dest_start + n_elem);
1848 assert(this->
size() >= src_start + n_elem);
1849 m_data.get(src_start, dest->m_data, dest_start, n_elem);
1853 template <
typename T>
1854 template <
typename U>
1861 std::dynamic_pointer_cast<const teca_variant_array_impl<T>>(src);
1865 m_data.
set(dest_start, tp_src->m_data, src_start, n_elem);
1871 << src->get_class_name() <<
" to " << this->get_class_name()
1876 template <
typename T>
1877 template <
typename U>
1882 m_data.
set(dest_start, src->m_data, src_start, n_elem);
1886 template <
typename T>
1887 template <
typename U>
1894 std::dynamic_pointer_cast<const teca_variant_array_impl<T>>(src);
1898 m_data.assign(tp_src->m_data, src_start, n_elem);
1903 << src->get_class_name() <<
" to " << this->get_class_name()
1908 template <
typename T>
1909 template <
typename U>
1914 m_data.
assign(src->m_data, src_start, n_elem);
1918 template <
typename T>
1919 template <
typename U>
1926 std::dynamic_pointer_cast<const teca_variant_array_impl<T>>(src);
1930 m_data.append(tp_src->m_data, src_start, n_elem);
1935 << src->get_class_name() <<
" to " << this->get_class_name()
1940 template <
typename T>
1941 template <
typename U>
1946 m_data.
append(src->m_data, src_start, n_elem);
1950 template <
typename T>
1951 template <
typename U>
1958 std::dynamic_pointer_cast<teca_variant_array_impl<T>>(dest);
1962 this->get_dispatch(src_start, tp_dest, dest_start, n_elem);
1967 << dest->get_class_name() <<
" to " << this->get_class_name()
1972 template <
typename T>
1973 template <
typename U>
1980 std::shared_ptr<TT> tp_dest = std::static_pointer_cast<TT>(dest);
1981 this->get_dispatch(src_start, tp_dest, dest_start, n_elem);
1986 << dest->get_class_name() <<
" to " << this->get_class_name()
1991 template <
typename T>
1992 template <
typename U>
1999 std::dynamic_pointer_cast<const teca_variant_array_impl<T>>(src);
2003 this->set_dispatch(dest_start, tp_src, src_start, n_elem);
2008 << src->get_class_name() <<
" to " << this->get_class_name()
2013 template <
typename T>
2014 template <
typename U>
2024 this->set_dispatch(dest_start, tp_src, src_start, n_elem);
2029 << src->get_class_name() <<
" to " << this->get_class_name()
2034 template <
typename T>
2035 template <
typename U>
2042 std::dynamic_pointer_cast<const teca_variant_array_impl<T>>(src);
2046 this->assign_dispatch(tp_src, src_start, n_elem);
2051 << src->get_class_name() <<
" to " << this->get_class_name()
2056 template <
typename T>
2057 template <
typename U>
2064 std::shared_ptr<TT> tp_src = std::static_pointer_cast<TT>(src);
2065 this->assign_dispatch(tp_src, src_start, n_elem);
2070 << src->get_class_name() <<
" to " << this->get_class_name()
2075 template <
typename T>
2076 template <
typename U>
2083 std::dynamic_pointer_cast<const teca_variant_array_impl<T>>(src);
2087 this->append_dispatch(tp_src, src_start, n_elem);
2092 << src->get_class_name() <<
" to " << this->get_class_name()
2097 template <
typename T>
2098 template <
typename U>
2105 std::shared_ptr<TT> tp_src = std::static_pointer_cast<TT>(src);
2106 this->append_dispatch(tp_src, src_start, n_elem);
2111 << src->get_class_name() <<
" to " << this->get_class_name()
2116 template <
typename T>
2117 template <
typename U>
2119 U *dest,
size_t dest_start,
size_t n_elem,
2128 thisu->m_data.get(src_start, dest, dest_start, n_elem);
2133 << safe_class_name(
this) <<
" to " << safe_pointer_name(dest)
2138 template <
typename T>
2139 template <
typename U>
2141 U *dest,
size_t dest_start,
size_t n_elem,
2144 m_data.
get(src_start, dest, dest_start, n_elem);
2148 template <
typename T>
2149 template <
typename U>
2151 const U *src,
size_t src_start,
size_t n_elem,
2160 thisu->m_data.set(dest_start, src, src_start, n_elem);
2165 << safe_class_name(
this) <<
" to " << safe_pointer_name(src)
2170 template <
typename T>
2171 template <
typename U>
2173 const U *src,
size_t src_start,
size_t n_elem,
2176 m_data.
set(dest_start, src, src_start, n_elem);
2180 template <
typename T>
2181 template <
typename U>
2183 const U *src,
size_t src_start,
size_t n_elem,
2192 thisu->m_data.assign(src, src_start, n_elem);
2197 << safe_class_name(
this) <<
" to " << safe_pointer_name(src)
2202 template <
typename T>
2203 template <
typename U>
2205 const U *src,
size_t src_start,
size_t n_elem,
2208 m_data.
assign(src, src_start, n_elem);
2212 template <
typename T>
2213 template <
typename U>
2215 const U *src,
size_t src_start,
size_t n_elem,
2224 thisu->m_data.append(src, src_start, n_elem);
2229 << safe_class_name(
this) <<
" to " << safe_pointer_name(src)
2234 template <
typename T>
2235 template <
typename U>
2237 const U *src,
size_t src_start,
size_t n_elem,
2240 m_data.
append(src, src_start, n_elem);
2247 template<
typename T>
2252 const TT *other_t =
dynamic_cast<const TT*
>(other.get());
2255 size_t n_elem = this->
size();
2257 if (n_elem != other_t->size())
2261 const NT *pthis = spthis.get();
2263 auto spother = other_t->get_cpu_accessible();
2264 const NT *pother = spother.get();
2266 for (
size_t i = 0; i < n_elem; ++i)
2268 if (pthis[i] != pother[i])
2275 << safe_class_name(other.get()) <<
" to " << safe_class_name(
this)
2281 template<
typename T>
2282 template <
typename U>
2284 typename std::enable_if<pack_array<U>::value, U>::type*)
const
2287 unsigned long long n_elem = this->
size();
2292 s.pack(pdata.get(), n_elem);
2296 template<
typename T>
2297 template <
typename U>
2299 typename std::enable_if<pack_array<U>::value, U>::type*)
2302 unsigned long long n_elem = 0;
2306 hamr::buffer<T> tmp(allocator::malloc, n_elem);
2307 std::shared_ptr<T> sptmp = tmp.get_cpu_accessible();
2310 s.unpack(sptmp.get(), n_elem);
2313 m_data = std::move(tmp);
2317 template<
typename T>
2318 template <
typename U>
2320 typename std::enable_if<pack_object<U>::value, U>::type*)
const
2323 unsigned long long n_elem = this->
size();
2328 const T *pdata = data.get();
2329 for (
unsigned long long i = 0; i < n_elem; ++i)
2331 pdata[i].to_stream(s);
2336 template<
typename T>
2337 template <
typename U>
2340 typename std::enable_if<pack_object<U>::value, U>::type*)
2343 unsigned long long n_elem = 0;
2347 std::vector<T> tmp(n_elem);
2348 for (
unsigned long long i = 0; i < n_elem; ++i)
2350 tmp[i].from_stream(s);
2354 m_data.assign(tmp.data(), 0, n_elem);
2358 template<
typename T>
2359 template <
typename U>
2362 typename std::enable_if<pack_object_ptr<U>::value, U>::type*)
const
2365 unsigned long long n_elem = this->
size();
2370 const T *pdata = data.get();
2371 for (
unsigned long long i = 0; i < n_elem; ++i)
2373 pdata[i]->to_stream(s);
2378 template<
typename T>
2379 template <
typename U>
2382 typename std::enable_if<pack_object_ptr<U>::value, U>::type*)
2385 unsigned long long n_elem = 0;
2389 std::vector<T> tmp(n_elem);
2390 for (
unsigned long long i=0; i < n_elem; ++i)
2392 tmp[i]->from_stream(s);
2396 m_data.assign(tmp.data(), 0, n_elem);
2399 #define STR_DELIM(_a, _b) \
2400 (std::is_same<T, std::string>::value ? _a : _b)
2403 template<
typename T>
2404 template <
typename U>
2407 typename std::enable_if<pack_array<U>::value, U>::type*)
const
2409 size_t n_elem = this->
size();
2414 const T *pdata = data.get();
2416 s << STR_DELIM(
"\"",
"") << pdata[0] << STR_DELIM(
"\"",
"");
2418 for (
size_t i = 1; i < n_elem; ++i)
2420 s << STR_DELIM(
", \"",
", ") << pdata[i] << STR_DELIM(
"\"",
"");
2426 template<
typename T>
2427 template <
typename U>
2430 typename std::enable_if<pack_array<U>::value, U>::type*)
2436 template<
typename T>
2437 template <
typename U>
2440 typename std::enable_if<pack_object<U>::value, U>::type*)
const
2442 size_t n_elem = this->m_data.
size();
2447 const T *pdata = data.get();
2450 pdata[0].to_stream(s);
2452 for (
size_t i = 1; i < n_elem; ++i)
2455 pdata[i].to_stream(s);
2462 template<
typename T>
2463 template <
typename U>
2466 typename std::enable_if<pack_object<U>::value, U>::type*)
2472 template<
typename T>
2473 template <
typename U>
2476 typename std::enable_if<pack_object_ptr<U>::value, U>::type*)
const
2478 size_t n_elem = this->m_data.
size();
2483 const T *pdata = data.get();
2486 pdata[0]->to_stream(s);
2488 for (
size_t i = 1; i < n_elem; ++i)
2491 pdata[i]->to_stream(s);
2498 template<
typename T>
2499 template <
typename U>
2502 typename std::enable_if<pack_object_ptr<U>::value, U>::type*)
2508 template <
typename T>
2511 template <
unsigned int I>
2514 template <
unsigned int I>
2517 #define TECA_VARIANT_ARRAY_TT_SPEC(T, v) \
2519 struct teca_variant_array_code<T> \
2521 static constexpr unsigned int get() \
2525 struct teca_variant_array_new<v> \
2527 using allocator = teca_variant_array::allocator; \
2529 static p_teca_variant_array_impl<T> New(allocator alloc) \
2530 { return teca_variant_array_impl<T>::New(alloc); } \
2533 struct teca_variant_array_type<v> \
2537 static constexpr const char *name() \
2541 #define TECA_VARIANT_ARRAY_FACTORY_NEW(_v) \
2543 return teca_variant_array_new<_v>::New(alloc);
2545 #include "teca_metadata.h"
2548 TECA_VARIANT_ARRAY_TT_SPEC(
char, 1)
2549 TECA_VARIANT_ARRAY_TT_SPEC(
unsigned char, 2)
2550 TECA_VARIANT_ARRAY_TT_SPEC(
int, 3)
2551 TECA_VARIANT_ARRAY_TT_SPEC(
unsigned int, 4)
2552 TECA_VARIANT_ARRAY_TT_SPEC(
short int, 5)
2553 TECA_VARIANT_ARRAY_TT_SPEC(
short unsigned int, 6)
2554 TECA_VARIANT_ARRAY_TT_SPEC(
long, 7)
2555 TECA_VARIANT_ARRAY_TT_SPEC(
unsigned long, 8)
2556 TECA_VARIANT_ARRAY_TT_SPEC(
long long, 9)
2557 TECA_VARIANT_ARRAY_TT_SPEC(
unsigned long long, 10)
2558 TECA_VARIANT_ARRAY_TT_SPEC(
float, 11)
2559 TECA_VARIANT_ARRAY_TT_SPEC(
double, 12)
2560 TECA_VARIANT_ARRAY_TT_SPEC(std::
string, 13)
2578 allocator alloc = allocator::malloc)
2582 TECA_VARIANT_ARRAY_FACTORY_NEW(1)
2583 TECA_VARIANT_ARRAY_FACTORY_NEW(2)
2584 TECA_VARIANT_ARRAY_FACTORY_NEW(3)
2585 TECA_VARIANT_ARRAY_FACTORY_NEW(4)
2586 TECA_VARIANT_ARRAY_FACTORY_NEW(5)
2587 TECA_VARIANT_ARRAY_FACTORY_NEW(6)
2588 TECA_VARIANT_ARRAY_FACTORY_NEW(7)
2589 TECA_VARIANT_ARRAY_FACTORY_NEW(8)
2590 TECA_VARIANT_ARRAY_FACTORY_NEW(9)
2591 TECA_VARIANT_ARRAY_FACTORY_NEW(10)
2592 TECA_VARIANT_ARRAY_FACTORY_NEW(11)
2593 TECA_VARIANT_ARRAY_FACTORY_NEW(12)
2594 TECA_VARIANT_ARRAY_FACTORY_NEW(13)
2595 TECA_VARIANT_ARRAY_FACTORY_NEW(14)
2596 TECA_VARIANT_ARRAY_FACTORY_NEW(15)
2598 TECA_ERROR(
"Failed to create a teca_variant_array,"
2599 " unknown code " << type_code)
2606 #define CODE_DISPATCH_CASE(_v, _c, _code) \
2609 using NT = teca_variant_array_type<_c>::type; \
2610 using TT = teca_variant_array_impl<NT>; \
2614 #define CODE_DISPATCH_I(_v, _code) \
2615 CODE_DISPATCH_CASE(_v, 1, _code) \
2616 else CODE_DISPATCH_CASE(_v, 2, _code) \
2617 else CODE_DISPATCH_CASE(_v, 3, _code) \
2618 else CODE_DISPATCH_CASE(_v, 4, _code) \
2619 else CODE_DISPATCH_CASE(_v, 5, _code) \
2620 else CODE_DISPATCH_CASE(_v, 6, _code) \
2621 else CODE_DISPATCH_CASE(_v, 7, _code) \
2622 else CODE_DISPATCH_CASE(_v, 8, _code) \
2623 else CODE_DISPATCH_CASE(_v, 9, _code) \
2624 else CODE_DISPATCH_CASE(_v, 10, _code)
2626 #define CODE_DISPATCH_FP(_v, _code) \
2627 CODE_DISPATCH_CASE(_v, 11, _code) \
2628 else CODE_DISPATCH_CASE(_v, 12, _code)
2630 #define CODE_DISPATCH_CLASS(_v, _code) \
2631 CODE_DISPATCH_CASE(_v, 13, _code) \
2632 else CODE_DISPATCH_CASE(_v, 14, _code) \
2633 else CODE_DISPATCH_CASE(_v, 15, _code)
2635 #define CODE_DISPATCH(_v, _code) \
2636 CODE_DISPATCH_I(_v, _code) \
2637 else CODE_DISPATCH_FP(_v, _code)
2642 template <
typename T>
2645 return teca_variant_array_code<T>::get();
2649 template <
typename T>
2653 size_t n_elem = a->size();
2654 T mn = std::numeric_limits<T>::max();
2655 #if defined(TECA_HAS_CUDA)
2656 if (a->cuda_accessible())
2658 std::shared_ptr<const T> data = a->get_cuda_accessible();
2659 thrust::device_ptr<const T> pdata(data.get());
2660 mn = thrust::reduce(pdata, pdata + n_elem, mn, thrust::minimum<T>());
2665 std::shared_ptr<const T> data = a->get_cuda_accessible();
2666 const T *pdata = data.get();
2667 for (
size_t i = 0; i < n_elem; ++i)
2668 mn = mn > pdata[i] ? pdata[i] : mn;
2669 #if defined(TECA_HAS_CUDA)
2676 template <
typename T>
2684 template <
typename T>
2688 size_t n_elem = a->size();
2689 T mx = std::numeric_limits<T>::lowest();
2690 #if defined(TECA_HAS_CUDA)
2691 if (a->cuda_accessible())
2693 std::shared_ptr<const T> data = a->get_cuda_accessible();
2694 thrust::device_ptr<const T> pdata(data.get());
2695 mx = thrust::reduce(pdata, pdata + n_elem, mx, thrust::maximum<T>());
2700 std::shared_ptr<const T> data = a->get_cuda_accessible();
2701 const T *pdata = data.get();
2702 for (
size_t i = 0; i < n_elem; ++i)
2703 mx = mx < pdata[i] ? pdata[i] : mx;
2704 #if defined(TECA_HAS_CUDA)
2711 template <
typename T>
2718 #if defined(__CUDACC__)
2719 #pragma nv_diag_default = partial_override