type_dispatcher.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019-2025, NVIDIA CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
20 #include <cudf/types.hpp>
21 #include <cudf/utilities/error.hpp>
25 
26 #include <string>
27 
33 namespace CUDF_EXPORT cudf {
55 template <typename T>
57 {
58  return type_id::EMPTY;
59 };
60 
65 struct type_to_name_impl {
71  template <typename T>
72  inline std::string operator()()
73  {
74  return "void";
75  }
76 };
77 
78 template <cudf::type_id t>
79 struct id_to_type_impl {
80  using type = void;
81 };
91 template <cudf::type_id Id>
92 using id_to_type = typename id_to_type_impl<Id>::type;
93 
108 // clang-format off
109 template <typename T>
111  std::conditional_t<std::is_same_v<numeric::decimal32, T>, int32_t,
112  std::conditional_t<std::is_same_v<numeric::decimal64, T>, int64_t,
113  std::conditional_t<std::is_same_v<numeric::decimal128, T>, __int128_t, T>>>;
114 // clang-format on
115 
131 template <typename T>
132 constexpr inline type_id type_to_id()
133 {
134  return base_type_to_id<std::remove_cv_t<T>>();
135 }
136 
144 #ifndef CUDF_TYPE_MAPPING
145 #define CUDF_TYPE_MAPPING(Type, Id) \
146  template <> \
147  constexpr inline type_id base_type_to_id<Type>() \
148  { \
149  return Id; \
150  } \
151  template <> \
152  inline std::string type_to_name_impl::operator()<Type>() \
153  { \
154  return CUDF_STRINGIFY(Type); \
155  } \
156  template <> \
157  struct id_to_type_impl<Id> { \
158  using type = Type; \
159  };
160 #endif
161 
162 // Defines all of the mappings between C++ types and their corresponding `cudf::type_id` values.
163 CUDF_TYPE_MAPPING(int8_t, type_id::INT8)
164 CUDF_TYPE_MAPPING(int16_t, type_id::INT16)
165 CUDF_TYPE_MAPPING(int32_t, type_id::INT32)
166 CUDF_TYPE_MAPPING(int64_t, type_id::INT64)
167 CUDF_TYPE_MAPPING(uint8_t, type_id::UINT8)
168 CUDF_TYPE_MAPPING(uint16_t, type_id::UINT16)
169 CUDF_TYPE_MAPPING(uint32_t, type_id::UINT32)
170 CUDF_TYPE_MAPPING(uint64_t, type_id::UINT64)
171 CUDF_TYPE_MAPPING(float, type_id::FLOAT32)
172 CUDF_TYPE_MAPPING(double, type_id::FLOAT64)
173 CUDF_TYPE_MAPPING(bool, type_id::BOOL8)
174 CUDF_TYPE_MAPPING(cudf::timestamp_D, type_id::TIMESTAMP_DAYS)
175 CUDF_TYPE_MAPPING(cudf::timestamp_s, type_id::TIMESTAMP_SECONDS)
176 CUDF_TYPE_MAPPING(cudf::timestamp_ms, type_id::TIMESTAMP_MILLISECONDS)
177 CUDF_TYPE_MAPPING(cudf::timestamp_us, type_id::TIMESTAMP_MICROSECONDS)
178 CUDF_TYPE_MAPPING(cudf::timestamp_ns, type_id::TIMESTAMP_NANOSECONDS)
179 CUDF_TYPE_MAPPING(cudf::duration_D, type_id::DURATION_DAYS)
180 CUDF_TYPE_MAPPING(cudf::duration_s, type_id::DURATION_SECONDS)
181 CUDF_TYPE_MAPPING(cudf::duration_ms, type_id::DURATION_MILLISECONDS)
182 CUDF_TYPE_MAPPING(cudf::duration_us, type_id::DURATION_MICROSECONDS)
183 CUDF_TYPE_MAPPING(cudf::duration_ns, type_id::DURATION_NANOSECONDS)
184 CUDF_TYPE_MAPPING(cudf::dictionary32, type_id::DICTIONARY32)
185 CUDF_TYPE_MAPPING(cudf::string_view, type_id::STRING)
186 CUDF_TYPE_MAPPING(cudf::list_view, type_id::LIST)
187 CUDF_TYPE_MAPPING(numeric::decimal32, type_id::DECIMAL32)
188 CUDF_TYPE_MAPPING(numeric::decimal64, type_id::DECIMAL64)
189 CUDF_TYPE_MAPPING(numeric::decimal128, type_id::DECIMAL128)
190 CUDF_TYPE_MAPPING(cudf::struct_view, type_id::STRUCT)
191 
192 
200 template <> // CUDF_TYPE_MAPPING(char,INT8) causes duplicate id_to_type_impl definition
201 constexpr inline type_id base_type_to_id<char>()
202 {
203  return type_id::INT8;
204 }
205 
215 template <typename T>
217 {
218  return (id == type_id::DECIMAL32 && std::is_same_v<T, int32_t>) ||
219  (id == type_id::DECIMAL64 && std::is_same_v<T, int64_t>) ||
220  (id == type_id::DECIMAL128 && std::is_same_v<T, __int128_t>) || id == type_to_id<T>();
221 }
222 
231 template <cudf::type_id Id>
234 };
235 
236 template <typename T>
237 struct type_to_scalar_type_impl {
238  using ScalarType = cudf::scalar;
239 };
240 
247 #ifndef MAP_NUMERIC_SCALAR
248 #define MAP_NUMERIC_SCALAR(Type) \
249  template <> \
250  struct type_to_scalar_type_impl<Type> { \
251  using ScalarType = cudf::numeric_scalar<Type>; \
252  using ScalarDeviceType = cudf::numeric_scalar_device_view<Type>; \
253  };
254 #endif
255 
256 MAP_NUMERIC_SCALAR(int8_t)
257 MAP_NUMERIC_SCALAR(int16_t)
258 MAP_NUMERIC_SCALAR(int32_t)
259 MAP_NUMERIC_SCALAR(int64_t)
260 MAP_NUMERIC_SCALAR(__int128_t)
261 MAP_NUMERIC_SCALAR(uint8_t)
262 MAP_NUMERIC_SCALAR(uint16_t)
263 MAP_NUMERIC_SCALAR(uint32_t)
264 MAP_NUMERIC_SCALAR(uint64_t)
265 MAP_NUMERIC_SCALAR(float)
266 MAP_NUMERIC_SCALAR(double)
267 MAP_NUMERIC_SCALAR(bool)
268 
269 template <>
270 struct type_to_scalar_type_impl<std::string> {
271  using ScalarType = cudf::string_scalar;
272  using ScalarDeviceType = cudf::string_scalar_device_view;
273 };
274 
275 template <>
276 struct type_to_scalar_type_impl<cudf::string_view> {
277  using ScalarType = cudf::string_scalar;
278  using ScalarDeviceType = cudf::string_scalar_device_view;
279 };
280 
281 template <>
282 struct type_to_scalar_type_impl<numeric::decimal32> {
285 };
286 
287 template <>
288 struct type_to_scalar_type_impl<numeric::decimal64> {
291 };
292 
293 template <>
294 struct type_to_scalar_type_impl<numeric::decimal128> {
297 };
298 
299 template <> // TODO: this is a temporary solution for make_pair_iterator
300 struct type_to_scalar_type_impl<cudf::dictionary32> {
301  using ScalarType = cudf::numeric_scalar<int32_t>;
302  using ScalarDeviceType = cudf::numeric_scalar_device_view<int32_t>;
303 };
304 
305 template <> // TODO: this is to get compilation working. list scalars will be implemented at a
306  // later time.
307 struct type_to_scalar_type_impl<cudf::list_view> {
308  using ScalarType = cudf::list_scalar;
309  // using ScalarDeviceType = cudf::list_scalar_device_view;
310 };
311 
312 template <> // TODO: Ditto, likewise.
313 struct type_to_scalar_type_impl<cudf::struct_view> {
314  using ScalarType = cudf::struct_scalar;
315  // using ScalarDeviceType = cudf::struct_scalar_device_view; // CALEB: TODO!
316 };
317 
324 #ifndef MAP_TIMESTAMP_SCALAR
325 #define MAP_TIMESTAMP_SCALAR(Type) \
326  template <> \
327  struct type_to_scalar_type_impl<Type> { \
328  using ScalarType = cudf::timestamp_scalar<Type>; \
329  using ScalarDeviceType = cudf::timestamp_scalar_device_view<Type>; \
330  };
331 #endif
332 
338 
339 
345 #ifndef MAP_DURATION_SCALAR
346 #define MAP_DURATION_SCALAR(Type) \
347  template <> \
348  struct type_to_scalar_type_impl<Type> { \
349  using ScalarType = cudf::duration_scalar<Type>; \
350  using ScalarDeviceType = cudf::duration_scalar_device_view<Type>; \
351  };
352 #endif
353 
359 
360 
365 template <typename T>
367 
373 template <typename T>
374 using scalar_device_type_t = typename type_to_scalar_type_impl<T>::ScalarDeviceType;
375 
468 // This pragma disables a compiler warning that complains about the valid usage
469 // of calling a __host__ functor from this function which is __host__ __device__
470 #ifdef __CUDACC__
471 #pragma nv_exec_check_disable
472 #endif
473 template <template <cudf::type_id> typename IdTypeMap = id_to_type_impl,
474  typename Functor,
475  typename... Ts>
476 CUDF_HOST_DEVICE __forceinline__ constexpr decltype(auto) type_dispatcher(cudf::data_type dtype,
477  Functor f,
478  Ts&&... args)
479 {
480  switch (dtype.id()) {
481  case type_id::INT8:
482  return f.template operator()<typename IdTypeMap<type_id::INT8>::type>(
483  std::forward<Ts>(args)...);
484  case type_id::INT16:
485  return f.template operator()<typename IdTypeMap<type_id::INT16>::type>(
486  std::forward<Ts>(args)...);
487  case type_id::INT32:
488  return f.template operator()<typename IdTypeMap<type_id::INT32>::type>(
489  std::forward<Ts>(args)...);
490  case type_id::INT64:
491  return f.template operator()<typename IdTypeMap<type_id::INT64>::type>(
492  std::forward<Ts>(args)...);
493  case type_id::UINT8:
494  return f.template operator()<typename IdTypeMap<type_id::UINT8>::type>(
495  std::forward<Ts>(args)...);
496  case type_id::UINT16:
497  return f.template operator()<typename IdTypeMap<type_id::UINT16>::type>(
498  std::forward<Ts>(args)...);
499  case type_id::UINT32:
500  return f.template operator()<typename IdTypeMap<type_id::UINT32>::type>(
501  std::forward<Ts>(args)...);
502  case type_id::UINT64:
503  return f.template operator()<typename IdTypeMap<type_id::UINT64>::type>(
504  std::forward<Ts>(args)...);
505  case type_id::FLOAT32:
506  return f.template operator()<typename IdTypeMap<type_id::FLOAT32>::type>(
507  std::forward<Ts>(args)...);
508  case type_id::FLOAT64:
509  return f.template operator()<typename IdTypeMap<type_id::FLOAT64>::type>(
510  std::forward<Ts>(args)...);
511  case type_id::BOOL8:
512  return f.template operator()<typename IdTypeMap<type_id::BOOL8>::type>(
513  std::forward<Ts>(args)...);
514  case type_id::TIMESTAMP_DAYS:
515  return f.template operator()<typename IdTypeMap<type_id::TIMESTAMP_DAYS>::type>(
516  std::forward<Ts>(args)...);
517  case type_id::TIMESTAMP_SECONDS:
518  return f.template operator()<typename IdTypeMap<type_id::TIMESTAMP_SECONDS>::type>(
519  std::forward<Ts>(args)...);
520  case type_id::TIMESTAMP_MILLISECONDS:
521  return f.template operator()<typename IdTypeMap<type_id::TIMESTAMP_MILLISECONDS>::type>(
522  std::forward<Ts>(args)...);
523  case type_id::TIMESTAMP_MICROSECONDS:
524  return f.template operator()<typename IdTypeMap<type_id::TIMESTAMP_MICROSECONDS>::type>(
525  std::forward<Ts>(args)...);
526  case type_id::TIMESTAMP_NANOSECONDS:
527  return f.template operator()<typename IdTypeMap<type_id::TIMESTAMP_NANOSECONDS>::type>(
528  std::forward<Ts>(args)...);
529  case type_id::DURATION_DAYS:
530  return f.template operator()<typename IdTypeMap<type_id::DURATION_DAYS>::type>(
531  std::forward<Ts>(args)...);
532  case type_id::DURATION_SECONDS:
533  return f.template operator()<typename IdTypeMap<type_id::DURATION_SECONDS>::type>(
534  std::forward<Ts>(args)...);
535  case type_id::DURATION_MILLISECONDS:
536  return f.template operator()<typename IdTypeMap<type_id::DURATION_MILLISECONDS>::type>(
537  std::forward<Ts>(args)...);
538  case type_id::DURATION_MICROSECONDS:
539  return f.template operator()<typename IdTypeMap<type_id::DURATION_MICROSECONDS>::type>(
540  std::forward<Ts>(args)...);
541  case type_id::DURATION_NANOSECONDS:
542  return f.template operator()<typename IdTypeMap<type_id::DURATION_NANOSECONDS>::type>(
543  std::forward<Ts>(args)...);
544  case type_id::DICTIONARY32:
545  return f.template operator()<typename IdTypeMap<type_id::DICTIONARY32>::type>(
546  std::forward<Ts>(args)...);
547  case type_id::STRING:
548  return f.template operator()<typename IdTypeMap<type_id::STRING>::type>(
549  std::forward<Ts>(args)...);
550  case type_id::LIST:
551  return f.template operator()<typename IdTypeMap<type_id::LIST>::type>(
552  std::forward<Ts>(args)...);
553  case type_id::DECIMAL32:
554  return f.template operator()<typename IdTypeMap<type_id::DECIMAL32>::type>(
555  std::forward<Ts>(args)...);
556  case type_id::DECIMAL64:
557  return f.template operator()<typename IdTypeMap<type_id::DECIMAL64>::type>(
558  std::forward<Ts>(args)...);
559  case type_id::DECIMAL128:
560  return f.template operator()<typename IdTypeMap<type_id::DECIMAL128>::type>(
561  std::forward<Ts>(args)...);
562  case type_id::STRUCT:
563  return f.template operator()<typename IdTypeMap<type_id::STRUCT>::type>(
564  std::forward<Ts>(args)...);
565  default: {
566 #ifndef __CUDA_ARCH__
567  CUDF_FAIL("Invalid type_id.");
568 #else
569  CUDF_UNREACHABLE("Invalid type_id.");
570 #endif
571  }
572  }
573 }
574 
575 // @cond
576 namespace detail {
577 template <typename T1>
578 struct double_type_dispatcher_second_type {
579 #ifdef __CUDACC__
580 #pragma nv_exec_check_disable
581 #endif
582  template <typename T2, typename F, typename... Ts>
583  CUDF_HOST_DEVICE __forceinline__ decltype(auto) operator()(F&& f, Ts&&... args) const
584  {
585  return f.template operator()<T1, T2>(std::forward<Ts>(args)...);
586  }
587 };
588 
589 template <template <cudf::type_id> typename IdTypeMap>
590 struct double_type_dispatcher_first_type {
591 #ifdef __CUDACC__
592 #pragma nv_exec_check_disable
593 #endif
594  template <typename T1, typename F, typename... Ts>
595  CUDF_HOST_DEVICE __forceinline__ decltype(auto) operator()(cudf::data_type type2,
596  F&& f,
597  Ts&&... args) const
598  {
599  return type_dispatcher<IdTypeMap>(type2,
600  detail::double_type_dispatcher_second_type<T1>{},
601  std::forward<F>(f),
602  std::forward<Ts>(args)...);
603  }
604 };
605 } // namespace detail
606 // @endcond
607 
623 #ifdef __CUDACC__
624 #pragma nv_exec_check_disable
625 #endif
626 template <template <cudf::type_id> typename IdTypeMap = id_to_type_impl, typename F, typename... Ts>
627 CUDF_HOST_DEVICE __forceinline__ constexpr decltype(auto) double_type_dispatcher(
628  cudf::data_type type1, cudf::data_type type2, F&& f, Ts&&... args)
629 {
630  return type_dispatcher<IdTypeMap>(type1,
631  detail::double_type_dispatcher_first_type<IdTypeMap>{},
632  type2,
633  std::forward<F>(f),
634  std::forward<Ts>(args)...);
635 }
636 
646 std::string type_to_name(data_type type);
647  // end of group
649 } // namespace CUDF_EXPORT cudf
Indicator for the logical data type of an element in a column.
Definition: types.hpp:243
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:299
An owning class to represent a list value in device memory.
Definition: scalar.hpp:716
A non-owning, immutable view of device data that represents a list of elements of arbitrary type (inc...
Definition: list_view.hpp:32
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:239
An owning class to represent a singular value.
Definition: scalar.hpp:51
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:421
A non-owning, immutable view of device data that is a variable length char array representing a UTF-8...
Definition: string_view.hpp:44
An owning class to represent a struct value in device memory.
Definition: scalar.hpp:782
A non-owning, immutable view of device data that represents a struct with fields of arbitrary types (...
Definition: struct_view.hpp:30
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:217
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:67
detail::timestamp< cudf::duration_s > timestamp_s
Type alias representing a cudf::duration_s (int64_t) since the unix epoch.
Definition: timestamps.hpp:63
detail::timestamp< cudf::duration_D > timestamp_D
Type alias representing a cudf::duration_D (int32_t) since the unix epoch.
Definition: timestamps.hpp:51
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:59
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:35
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:51
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:55
detail::timestamp< cudf::duration_us > timestamp_us
Type alias representing a cudf::duration_us (int64_t) since the unix epoch.
Definition: timestamps.hpp:71
detail::timestamp< cudf::duration_ns > timestamp_ns
Type alias representing a cudf::duration_ns (int64_t) since the unix epoch.
Definition: timestamps.hpp:75
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:47
#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:217
type_id
Identifies a column's logical element type.
Definition: types.hpp:203
cuDF interfaces
Definition: host_udf.hpp:37
fixed_point and supporting types
Definition: fixed_point.hpp:33
A strongly typed wrapper for indices in a DICTIONARY type column.
Definition: dictionary.hpp:49
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:32