type_dispatcher.hpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2019-2025, NVIDIA CORPORATION.
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #pragma once
7 
9 #include <cudf/types.hpp>
10 #include <cudf/utilities/error.hpp>
14 
15 #include <string>
16 
22 namespace CUDF_EXPORT cudf {
44 template <typename T>
46 {
47  return type_id::EMPTY;
48 };
49 
54 struct type_to_name_impl {
60  template <typename T>
61  inline std::string operator()()
62  {
63  return "void";
64  }
65 };
66 
67 template <cudf::type_id t>
68 struct id_to_type_impl {
69  using type = void;
70 };
80 template <cudf::type_id Id>
81 using id_to_type = typename id_to_type_impl<Id>::type;
82 
97 // clang-format off
98 template <typename T>
100  std::conditional_t<std::is_same_v<numeric::decimal32, T>, int32_t,
101  std::conditional_t<std::is_same_v<numeric::decimal64, T>, int64_t,
102  std::conditional_t<std::is_same_v<numeric::decimal128, T>, __int128_t, T>>>;
103 // clang-format on
104 
120 template <typename T>
121 constexpr inline type_id type_to_id()
122 {
123  return base_type_to_id<std::remove_cv_t<T>>();
124 }
125 
133 #ifndef CUDF_TYPE_MAPPING
134 #define CUDF_TYPE_MAPPING(Type, Id) \
135  template <> \
136  constexpr inline type_id base_type_to_id<Type>() \
137  { \
138  return Id; \
139  } \
140  template <> \
141  inline std::string type_to_name_impl::operator()<Type>() \
142  { \
143  return CUDF_STRINGIFY(Type); \
144  } \
145  template <> \
146  struct id_to_type_impl<Id> { \
147  using type = Type; \
148  };
149 #endif
150 
151 // Defines all of the mappings between C++ types and their corresponding `cudf::type_id` values.
152 CUDF_TYPE_MAPPING(int8_t, type_id::INT8)
153 CUDF_TYPE_MAPPING(int16_t, type_id::INT16)
154 CUDF_TYPE_MAPPING(int32_t, type_id::INT32)
155 CUDF_TYPE_MAPPING(int64_t, type_id::INT64)
156 CUDF_TYPE_MAPPING(uint8_t, type_id::UINT8)
157 CUDF_TYPE_MAPPING(uint16_t, type_id::UINT16)
158 CUDF_TYPE_MAPPING(uint32_t, type_id::UINT32)
159 CUDF_TYPE_MAPPING(uint64_t, type_id::UINT64)
160 CUDF_TYPE_MAPPING(float, type_id::FLOAT32)
161 CUDF_TYPE_MAPPING(double, type_id::FLOAT64)
162 CUDF_TYPE_MAPPING(bool, type_id::BOOL8)
163 CUDF_TYPE_MAPPING(cudf::timestamp_D, type_id::TIMESTAMP_DAYS)
164 CUDF_TYPE_MAPPING(cudf::timestamp_s, type_id::TIMESTAMP_SECONDS)
165 CUDF_TYPE_MAPPING(cudf::timestamp_ms, type_id::TIMESTAMP_MILLISECONDS)
166 CUDF_TYPE_MAPPING(cudf::timestamp_us, type_id::TIMESTAMP_MICROSECONDS)
167 CUDF_TYPE_MAPPING(cudf::timestamp_ns, type_id::TIMESTAMP_NANOSECONDS)
168 CUDF_TYPE_MAPPING(cudf::duration_D, type_id::DURATION_DAYS)
169 CUDF_TYPE_MAPPING(cudf::duration_s, type_id::DURATION_SECONDS)
170 CUDF_TYPE_MAPPING(cudf::duration_ms, type_id::DURATION_MILLISECONDS)
171 CUDF_TYPE_MAPPING(cudf::duration_us, type_id::DURATION_MICROSECONDS)
172 CUDF_TYPE_MAPPING(cudf::duration_ns, type_id::DURATION_NANOSECONDS)
173 CUDF_TYPE_MAPPING(cudf::dictionary32, type_id::DICTIONARY32)
174 CUDF_TYPE_MAPPING(cudf::string_view, type_id::STRING)
175 CUDF_TYPE_MAPPING(cudf::list_view, type_id::LIST)
176 CUDF_TYPE_MAPPING(numeric::decimal32, type_id::DECIMAL32)
177 CUDF_TYPE_MAPPING(numeric::decimal64, type_id::DECIMAL64)
178 CUDF_TYPE_MAPPING(numeric::decimal128, type_id::DECIMAL128)
179 CUDF_TYPE_MAPPING(cudf::struct_view, type_id::STRUCT)
180 
181 
189 template <> // CUDF_TYPE_MAPPING(char,INT8) causes duplicate id_to_type_impl definition
190 constexpr inline type_id base_type_to_id<char>()
191 {
192  return type_id::INT8;
193 }
194 
204 template <typename T>
206 {
207  return (id == type_id::DECIMAL32 && std::is_same_v<T, int32_t>) ||
208  (id == type_id::DECIMAL64 && std::is_same_v<T, int64_t>) ||
209  (id == type_id::DECIMAL128 && std::is_same_v<T, __int128_t>) || id == type_to_id<T>();
210 }
211 
220 template <cudf::type_id Id>
223 };
224 
225 template <typename T>
226 struct type_to_scalar_type_impl {
227  using ScalarType = cudf::scalar;
228 };
229 
236 #ifndef MAP_NUMERIC_SCALAR
237 #define MAP_NUMERIC_SCALAR(Type) \
238  template <> \
239  struct type_to_scalar_type_impl<Type> { \
240  using ScalarType = cudf::numeric_scalar<Type>; \
241  using ScalarDeviceType = cudf::numeric_scalar_device_view<Type>; \
242  };
243 #endif
244 
245 MAP_NUMERIC_SCALAR(int8_t)
246 MAP_NUMERIC_SCALAR(int16_t)
247 MAP_NUMERIC_SCALAR(int32_t)
248 MAP_NUMERIC_SCALAR(int64_t)
249 MAP_NUMERIC_SCALAR(__int128_t)
250 MAP_NUMERIC_SCALAR(uint8_t)
251 MAP_NUMERIC_SCALAR(uint16_t)
252 MAP_NUMERIC_SCALAR(uint32_t)
253 MAP_NUMERIC_SCALAR(uint64_t)
254 MAP_NUMERIC_SCALAR(float)
255 MAP_NUMERIC_SCALAR(double)
256 MAP_NUMERIC_SCALAR(bool)
257 
258 template <>
259 struct type_to_scalar_type_impl<std::string> {
260  using ScalarType = cudf::string_scalar;
261  using ScalarDeviceType = cudf::string_scalar_device_view;
262 };
263 
264 template <>
265 struct type_to_scalar_type_impl<cudf::string_view> {
266  using ScalarType = cudf::string_scalar;
267  using ScalarDeviceType = cudf::string_scalar_device_view;
268 };
269 
270 template <>
271 struct type_to_scalar_type_impl<numeric::decimal32> {
274 };
275 
276 template <>
277 struct type_to_scalar_type_impl<numeric::decimal64> {
280 };
281 
282 template <>
283 struct type_to_scalar_type_impl<numeric::decimal128> {
286 };
287 
288 template <> // TODO: this is a temporary solution for make_pair_iterator
289 struct type_to_scalar_type_impl<cudf::dictionary32> {
290  using ScalarType = cudf::numeric_scalar<int32_t>;
291  using ScalarDeviceType = cudf::numeric_scalar_device_view<int32_t>;
292 };
293 
294 template <> // TODO: this is to get compilation working. list scalars will be implemented at a
295  // later time.
296 struct type_to_scalar_type_impl<cudf::list_view> {
297  using ScalarType = cudf::list_scalar;
298  // using ScalarDeviceType = cudf::list_scalar_device_view;
299 };
300 
301 template <> // TODO: Ditto, likewise.
302 struct type_to_scalar_type_impl<cudf::struct_view> {
303  using ScalarType = cudf::struct_scalar;
304  // using ScalarDeviceType = cudf::struct_scalar_device_view; // CALEB: TODO!
305 };
306 
313 #ifndef MAP_TIMESTAMP_SCALAR
314 #define MAP_TIMESTAMP_SCALAR(Type) \
315  template <> \
316  struct type_to_scalar_type_impl<Type> { \
317  using ScalarType = cudf::timestamp_scalar<Type>; \
318  using ScalarDeviceType = cudf::timestamp_scalar_device_view<Type>; \
319  };
320 #endif
321 
327 
328 
334 #ifndef MAP_DURATION_SCALAR
335 #define MAP_DURATION_SCALAR(Type) \
336  template <> \
337  struct type_to_scalar_type_impl<Type> { \
338  using ScalarType = cudf::duration_scalar<Type>; \
339  using ScalarDeviceType = cudf::duration_scalar_device_view<Type>; \
340  };
341 #endif
342 
348 
349 
354 template <typename T>
356 
362 template <typename T>
363 using scalar_device_type_t = typename type_to_scalar_type_impl<T>::ScalarDeviceType;
364 
457 // This pragma disables a compiler warning that complains about the valid usage
458 // of calling a __host__ functor from this function which is __host__ __device__
459 #ifdef __CUDACC__
460 #pragma nv_exec_check_disable
461 #endif
462 template <template <cudf::type_id> typename IdTypeMap = id_to_type_impl,
463  typename Functor,
464  typename... Ts>
465 CUDF_HOST_DEVICE __forceinline__ constexpr decltype(auto) type_dispatcher(cudf::data_type dtype,
466  Functor f,
467  Ts&&... args)
468 {
469  switch (dtype.id()) {
470  case type_id::INT8:
471  return f.template operator()<typename IdTypeMap<type_id::INT8>::type>(
472  std::forward<Ts>(args)...);
473  case type_id::INT16:
474  return f.template operator()<typename IdTypeMap<type_id::INT16>::type>(
475  std::forward<Ts>(args)...);
476  case type_id::INT32:
477  return f.template operator()<typename IdTypeMap<type_id::INT32>::type>(
478  std::forward<Ts>(args)...);
479  case type_id::INT64:
480  return f.template operator()<typename IdTypeMap<type_id::INT64>::type>(
481  std::forward<Ts>(args)...);
482  case type_id::UINT8:
483  return f.template operator()<typename IdTypeMap<type_id::UINT8>::type>(
484  std::forward<Ts>(args)...);
485  case type_id::UINT16:
486  return f.template operator()<typename IdTypeMap<type_id::UINT16>::type>(
487  std::forward<Ts>(args)...);
488  case type_id::UINT32:
489  return f.template operator()<typename IdTypeMap<type_id::UINT32>::type>(
490  std::forward<Ts>(args)...);
491  case type_id::UINT64:
492  return f.template operator()<typename IdTypeMap<type_id::UINT64>::type>(
493  std::forward<Ts>(args)...);
494  case type_id::FLOAT32:
495  return f.template operator()<typename IdTypeMap<type_id::FLOAT32>::type>(
496  std::forward<Ts>(args)...);
497  case type_id::FLOAT64:
498  return f.template operator()<typename IdTypeMap<type_id::FLOAT64>::type>(
499  std::forward<Ts>(args)...);
500  case type_id::BOOL8:
501  return f.template operator()<typename IdTypeMap<type_id::BOOL8>::type>(
502  std::forward<Ts>(args)...);
503  case type_id::TIMESTAMP_DAYS:
504  return f.template operator()<typename IdTypeMap<type_id::TIMESTAMP_DAYS>::type>(
505  std::forward<Ts>(args)...);
506  case type_id::TIMESTAMP_SECONDS:
507  return f.template operator()<typename IdTypeMap<type_id::TIMESTAMP_SECONDS>::type>(
508  std::forward<Ts>(args)...);
509  case type_id::TIMESTAMP_MILLISECONDS:
510  return f.template operator()<typename IdTypeMap<type_id::TIMESTAMP_MILLISECONDS>::type>(
511  std::forward<Ts>(args)...);
512  case type_id::TIMESTAMP_MICROSECONDS:
513  return f.template operator()<typename IdTypeMap<type_id::TIMESTAMP_MICROSECONDS>::type>(
514  std::forward<Ts>(args)...);
515  case type_id::TIMESTAMP_NANOSECONDS:
516  return f.template operator()<typename IdTypeMap<type_id::TIMESTAMP_NANOSECONDS>::type>(
517  std::forward<Ts>(args)...);
518  case type_id::DURATION_DAYS:
519  return f.template operator()<typename IdTypeMap<type_id::DURATION_DAYS>::type>(
520  std::forward<Ts>(args)...);
521  case type_id::DURATION_SECONDS:
522  return f.template operator()<typename IdTypeMap<type_id::DURATION_SECONDS>::type>(
523  std::forward<Ts>(args)...);
524  case type_id::DURATION_MILLISECONDS:
525  return f.template operator()<typename IdTypeMap<type_id::DURATION_MILLISECONDS>::type>(
526  std::forward<Ts>(args)...);
527  case type_id::DURATION_MICROSECONDS:
528  return f.template operator()<typename IdTypeMap<type_id::DURATION_MICROSECONDS>::type>(
529  std::forward<Ts>(args)...);
530  case type_id::DURATION_NANOSECONDS:
531  return f.template operator()<typename IdTypeMap<type_id::DURATION_NANOSECONDS>::type>(
532  std::forward<Ts>(args)...);
533  case type_id::DICTIONARY32:
534  return f.template operator()<typename IdTypeMap<type_id::DICTIONARY32>::type>(
535  std::forward<Ts>(args)...);
536  case type_id::STRING:
537  return f.template operator()<typename IdTypeMap<type_id::STRING>::type>(
538  std::forward<Ts>(args)...);
539  case type_id::LIST:
540  return f.template operator()<typename IdTypeMap<type_id::LIST>::type>(
541  std::forward<Ts>(args)...);
542  case type_id::DECIMAL32:
543  return f.template operator()<typename IdTypeMap<type_id::DECIMAL32>::type>(
544  std::forward<Ts>(args)...);
545  case type_id::DECIMAL64:
546  return f.template operator()<typename IdTypeMap<type_id::DECIMAL64>::type>(
547  std::forward<Ts>(args)...);
548  case type_id::DECIMAL128:
549  return f.template operator()<typename IdTypeMap<type_id::DECIMAL128>::type>(
550  std::forward<Ts>(args)...);
551  case type_id::STRUCT:
552  return f.template operator()<typename IdTypeMap<type_id::STRUCT>::type>(
553  std::forward<Ts>(args)...);
554  default: {
555 #ifndef __CUDA_ARCH__
556  CUDF_FAIL("Invalid type_id.");
557 #else
558  CUDF_UNREACHABLE("Invalid type_id.");
559 #endif
560  }
561  }
562 }
563 
564 // @cond
565 namespace detail {
566 template <typename T1>
567 struct double_type_dispatcher_second_type {
568 #ifdef __CUDACC__
569 #pragma nv_exec_check_disable
570 #endif
571  template <typename T2, typename F, typename... Ts>
572  CUDF_HOST_DEVICE __forceinline__ decltype(auto) operator()(F&& f, Ts&&... args) const
573  {
574  return f.template operator()<T1, T2>(std::forward<Ts>(args)...);
575  }
576 };
577 
578 template <template <cudf::type_id> typename IdTypeMap>
579 struct double_type_dispatcher_first_type {
580 #ifdef __CUDACC__
581 #pragma nv_exec_check_disable
582 #endif
583  template <typename T1, typename F, typename... Ts>
584  CUDF_HOST_DEVICE __forceinline__ decltype(auto) operator()(cudf::data_type type2,
585  F&& f,
586  Ts&&... args) const
587  {
588  return type_dispatcher<IdTypeMap>(type2,
589  detail::double_type_dispatcher_second_type<T1>{},
590  std::forward<F>(f),
591  std::forward<Ts>(args)...);
592  }
593 };
594 } // namespace detail
595 // @endcond
596 
612 #ifdef __CUDACC__
613 #pragma nv_exec_check_disable
614 #endif
615 template <template <cudf::type_id> typename IdTypeMap = id_to_type_impl, typename F, typename... Ts>
616 CUDF_HOST_DEVICE __forceinline__ constexpr decltype(auto) double_type_dispatcher(
617  cudf::data_type type1, cudf::data_type type2, F&& f, Ts&&... args)
618 {
619  return type_dispatcher<IdTypeMap>(type1,
620  detail::double_type_dispatcher_first_type<IdTypeMap>{},
621  type2,
622  std::forward<F>(f),
623  std::forward<Ts>(args)...);
624 }
625 
635 std::string type_to_name(data_type type);
636  // end of group
638 } // namespace CUDF_EXPORT cudf
Indicator for the logical data type of an element in a column.
Definition: types.hpp:238
A type of scalar_device_view that stores a pointer to a fixed_point value.
An owning class to represent a fixed_point number in device memory.
Definition: scalar.hpp:288
An owning class to represent a list value in device memory.
Definition: scalar.hpp:705
A non-owning, immutable view of device data that represents a list of elements of arbitrary type (inc...
Definition: list_view.hpp:20
A type of scalar_device_view that stores a pointer to a numerical value.
An owning class to represent a numerical value in device memory.
Definition: scalar.hpp:228
An owning class to represent a singular value.
Definition: scalar.hpp:40
A type of scalar_device_view that stores a pointer to a string value.
An owning class to represent a string in device memory.
Definition: scalar.hpp:410
A non-owning, immutable view of device data that is a variable length char array representing a UTF-8...
Definition: string_view.hpp:33
An owning class to represent a struct value in device memory.
Definition: scalar.hpp:771
A non-owning, immutable view of device data that represents a struct with fields of arbitrary types (...
Definition: struct_view.hpp:19
A type for representing a number with a fixed amount of precision.
Concrete type definition for dictionary columns.
Concrete type definitions for int32_t and int64_t durations in varying resolutions.
Class definition for fixed point data type.
dictionary_wrapper< int32_t > dictionary32
32-bit integer indexed dictionary wrapper
Definition: dictionary.hpp:206
fixed_point< int32_t, Radix::BASE_10 > decimal32
32-bit decimal fixed point
fixed_point< int64_t, Radix::BASE_10 > decimal64
64-bit decimal fixed point
fixed_point< __int128_t, Radix::BASE_10 > decimal128
128-bit decimal fixed point
detail::timestamp< cudf::duration_ms > timestamp_ms
Type alias representing a cudf::duration_ms (int64_t) since the unix epoch.
Definition: timestamps.hpp:56
detail::timestamp< cudf::duration_s > timestamp_s
Type alias representing a cudf::duration_s (int64_t) since the unix epoch.
Definition: timestamps.hpp:52
detail::timestamp< cudf::duration_D > timestamp_D
Type alias representing a cudf::duration_D (int32_t) since the unix epoch.
Definition: timestamps.hpp:40
cuda::std::chrono::duration< int64_t, cuda::std::chrono::nanoseconds::period > duration_ns
Type alias representing an int64_t duration of nanoseconds.
Definition: durations.hpp:48
cuda::std::chrono::duration< int32_t, cuda::std::chrono::days::period > duration_D
Type alias representing an int32_t duration of days.
Definition: durations.hpp:24
cuda::std::chrono::duration< int64_t, cuda::std::chrono::milliseconds::period > duration_ms
Type alias representing an int64_t duration of milliseconds.
Definition: durations.hpp:40
cuda::std::chrono::duration< int64_t, cuda::std::chrono::microseconds::period > duration_us
Type alias representing an int64_t duration of microseconds.
Definition: durations.hpp:44
detail::timestamp< cudf::duration_us > timestamp_us
Type alias representing a cudf::duration_us (int64_t) since the unix epoch.
Definition: timestamps.hpp:60
detail::timestamp< cudf::duration_ns > timestamp_ns
Type alias representing a cudf::duration_ns (int64_t) since the unix epoch.
Definition: timestamps.hpp:64
cuda::std::chrono::duration< int64_t, cuda::std::chrono::seconds::period > duration_s
Type alias representing an int64_t duration of seconds.
Definition: durations.hpp:36
#define MAP_TIMESTAMP_SCALAR(Type)
Macro used to define scalar type and scalar device type for cudf::timestamp_scalar template class for...
constexpr CUDF_HOST_DEVICE type_id base_type_to_id()
Maps a C++ type to its corresponding cudf::type_id
std::string type_to_name(data_type type)
Return a name for a given type.
#define MAP_DURATION_SCALAR(Type)
Macro used to define scalar type and scalar device type for cudf::duration_scalar template class for ...
CUDF_HOST_DEVICE constexpr decltype(auto) __forceinline__ type_dispatcher(cudf::data_type dtype, Functor f, Ts &&... args)
Invokes an operator() template with the type instantiation based on the specified cudf::data_type's i...
std::conditional_t< std::is_same_v< numeric::decimal32, T >, int32_t, std::conditional_t< std::is_same_v< numeric::decimal64, T >, int64_t, std::conditional_t< std::is_same_v< numeric::decimal128, T >, __int128_t, T > >> device_storage_type_t
"Returns" the corresponding type that is stored on the device when using cudf::column
typename type_to_scalar_type_impl< T >::ScalarDeviceType scalar_device_type_t
Maps a C++ type to the scalar device type required to hold its value.
constexpr type_id base_type_to_id< char >()
Specialization to map 'char' type to type_id::INT8.
#define CUDF_TYPE_MAPPING(Type, Id)
Macro used to define a mapping between a concrete C++ type and a cudf::type_id enum.
typename type_to_scalar_type_impl< T >::ScalarType scalar_type_t
Maps a C++ type to the scalar type required to hold its value.
constexpr type_id type_to_id()
Maps a C++ type to its corresponding cudf::type_id
CUDF_HOST_DEVICE constexpr decltype(auto) __forceinline__ double_type_dispatcher(cudf::data_type type1, cudf::data_type type2, F &&f, Ts &&... args)
Dispatches two type template parameters to a callable.
typename id_to_type_impl< Id >::type id_to_type
Maps a cudf::type_id to its corresponding concrete C++ type.
constexpr bool type_id_matches_device_storage_type(type_id id)
Checks if fixed_point-like types have template type T matching the column's stored type id.
#define MAP_NUMERIC_SCALAR(Type)
Macro used to define scalar type and scalar device type for cudf::numeric_scalar template class for n...
#define CUDF_FAIL(...)
Indicates that an erroneous code path has been taken.
Definition: error.hpp:182
type_id
Identifies a column's logical element type.
Definition: types.hpp:192
cuDF interfaces
Definition: host_udf.hpp:26
fixed_point and supporting types
Definition: fixed_point.hpp:23
A strongly typed wrapper for indices in a DICTIONARY type column.
Definition: dictionary.hpp:38
Use this specialization on type_dispatcher whenever you only need to operate on the underlying stored...
device_storage_type_t< id_to_type< Id > > type
The underlying type.
Concrete type definitions for int32_t and int64_t timestamps in varying resolutions as durations sinc...
Type declarations for libcudf.
#define CUDF_HOST_DEVICE
Indicates that the function or method is usable on host and device.
Definition: types.hpp:21