type_dispatcher.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019-2021, 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 
19 #include <cudf/detail/utilities/release_assert.cuh>
21 #include <cudf/types.hpp>
22 #include <cudf/utilities/error.hpp>
26 
27 #include <string>
28 
34 namespace cudf {
55 template <typename T>
56 inline constexpr type_id type_to_id()
57 {
58  return type_id::EMPTY;
59 };
60 
61 struct type_to_name {
62  template <typename T>
63  inline std::string operator()()
64  {
65  return "void";
66  }
67 };
68 
69 template <cudf::type_id t>
71  using type = void;
72 };
82 template <cudf::type_id Id>
83 using id_to_type = typename id_to_type_impl<Id>::type;
84 
98 // clang-format off
99 template <typename T>
101  std::conditional_t<std::is_same<numeric::decimal32, T>::value, int32_t,
102  std::conditional_t<std::is_same<numeric::decimal64, T>::value, int64_t, T>>;
103 // clang-format on
104 
112 {
113  switch (id) {
114  case type_id::DECIMAL32: return type_id::INT32;
115  case type_id::DECIMAL64: return type_id::INT64;
116  default: return id;
117  }
118 }
119 
129 template <typename T>
131 {
132  return (id == type_id::DECIMAL32 && std::is_same<T, int32_t>::value) ||
133  (id == type_id::DECIMAL64 && std::is_same<T, int64_t>::value) || id == type_to_id<T>();
134 }
135 
143 #ifndef CUDF_TYPE_MAPPING
144 #define CUDF_TYPE_MAPPING(Type, Id) \
145  template <> \
146  constexpr inline type_id type_to_id<Type>() \
147  { \
148  return Id; \
149  } \
150  template <> \
151  inline std::string type_to_name::operator()<Type>() \
152  { \
153  return CUDF_STRINGIFY(Type); \
154  } \
155  template <> \
156  struct id_to_type_impl<Id> { \
157  using type = Type; \
158  }
159 #endif
160 
165 CUDF_TYPE_MAPPING(bool, type_id::BOOL8);
166 CUDF_TYPE_MAPPING(int8_t, type_id::INT8);
167 CUDF_TYPE_MAPPING(int16_t, type_id::INT16);
168 CUDF_TYPE_MAPPING(int32_t, type_id::INT32);
169 CUDF_TYPE_MAPPING(int64_t, type_id::INT64);
170 CUDF_TYPE_MAPPING(uint8_t, type_id::UINT8);
171 CUDF_TYPE_MAPPING(uint16_t, type_id::UINT16);
172 CUDF_TYPE_MAPPING(uint32_t, type_id::UINT32);
173 CUDF_TYPE_MAPPING(uint64_t, type_id::UINT64);
174 CUDF_TYPE_MAPPING(float, type_id::FLOAT32);
175 CUDF_TYPE_MAPPING(double, type_id::FLOAT64);
176 CUDF_TYPE_MAPPING(cudf::string_view, type_id::STRING);
177 CUDF_TYPE_MAPPING(cudf::timestamp_D, type_id::TIMESTAMP_DAYS);
178 CUDF_TYPE_MAPPING(cudf::timestamp_s, type_id::TIMESTAMP_SECONDS);
179 CUDF_TYPE_MAPPING(cudf::timestamp_ms, type_id::TIMESTAMP_MILLISECONDS);
180 CUDF_TYPE_MAPPING(cudf::timestamp_us, type_id::TIMESTAMP_MICROSECONDS);
181 CUDF_TYPE_MAPPING(cudf::timestamp_ns, type_id::TIMESTAMP_NANOSECONDS);
182 CUDF_TYPE_MAPPING(cudf::duration_D, type_id::DURATION_DAYS);
183 CUDF_TYPE_MAPPING(cudf::duration_s, type_id::DURATION_SECONDS);
184 CUDF_TYPE_MAPPING(cudf::duration_ms, type_id::DURATION_MILLISECONDS);
185 CUDF_TYPE_MAPPING(cudf::duration_us, type_id::DURATION_MICROSECONDS);
186 CUDF_TYPE_MAPPING(cudf::duration_ns, type_id::DURATION_NANOSECONDS);
187 CUDF_TYPE_MAPPING(dictionary32, type_id::DICTIONARY32);
188 CUDF_TYPE_MAPPING(cudf::list_view, type_id::LIST);
189 CUDF_TYPE_MAPPING(numeric::decimal32, type_id::DECIMAL32);
190 CUDF_TYPE_MAPPING(numeric::decimal64, type_id::DECIMAL64);
191 CUDF_TYPE_MAPPING(cudf::struct_view, type_id::STRUCT);
192 
193 template <typename T>
195  using ScalarType = cudf::scalar;
196 };
197 
198 #ifndef MAP_NUMERIC_SCALAR
199 #define MAP_NUMERIC_SCALAR(Type) \
200  template <> \
201  struct type_to_scalar_type_impl<Type> { \
202  using ScalarType = cudf::numeric_scalar<Type>; \
203  using ScalarDeviceType = cudf::numeric_scalar_device_view<Type>; \
204  };
205 #endif
206 
207 MAP_NUMERIC_SCALAR(int8_t)
208 MAP_NUMERIC_SCALAR(int16_t)
209 MAP_NUMERIC_SCALAR(int32_t)
210 MAP_NUMERIC_SCALAR(int64_t)
211 MAP_NUMERIC_SCALAR(uint8_t)
212 MAP_NUMERIC_SCALAR(uint16_t)
213 MAP_NUMERIC_SCALAR(uint32_t)
214 MAP_NUMERIC_SCALAR(uint64_t)
215 MAP_NUMERIC_SCALAR(float)
216 MAP_NUMERIC_SCALAR(double)
217 MAP_NUMERIC_SCALAR(bool);
218 
219 template <>
220 struct type_to_scalar_type_impl<std::string> {
223 };
224 
225 template <>
229 };
230 
231 template <>
232 struct type_to_scalar_type_impl<numeric::decimal32> {
235 };
236 
237 template <>
238 struct type_to_scalar_type_impl<numeric::decimal64> {
241 };
242 
243 template <> // TODO: this is a temporary solution for make_pair_iterator
247 };
248 
249 template <> // TODO: this is to get compilation working. list scalars will be implemented at a
250  // later time.
252  using ScalarType = cudf::list_scalar;
253  // using ScalarDeviceType = cudf::list_scalar_device_view;
254 };
255 
256 template <> // TODO: Ditto, likewise.
258  using ScalarType = cudf::struct_scalar;
259  // using ScalarDeviceType = cudf::struct_scalar_device_view; // CALEB: TODO!
260 };
261 
262 #ifndef MAP_TIMESTAMP_SCALAR
263 #define MAP_TIMESTAMP_SCALAR(Type) \
264  template <> \
265  struct type_to_scalar_type_impl<Type> { \
266  using ScalarType = cudf::timestamp_scalar<Type>; \
267  using ScalarDeviceType = cudf::timestamp_scalar_device_view<Type>; \
268  };
269 #endif
270 
271 MAP_TIMESTAMP_SCALAR(timestamp_D)
272 MAP_TIMESTAMP_SCALAR(timestamp_s)
273 MAP_TIMESTAMP_SCALAR(timestamp_ms)
274 MAP_TIMESTAMP_SCALAR(timestamp_us)
275 MAP_TIMESTAMP_SCALAR(timestamp_ns)
276 
277 #ifndef MAP_DURATION_SCALAR
278 #define MAP_DURATION_SCALAR(Type) \
279  template <> \
280  struct type_to_scalar_type_impl<Type> { \
281  using ScalarType = cudf::duration_scalar<Type>; \
282  using ScalarDeviceType = cudf::duration_scalar_device_view<Type>; \
283  };
284 #endif
285 
286 MAP_DURATION_SCALAR(duration_D)
287 MAP_DURATION_SCALAR(duration_s)
288 MAP_DURATION_SCALAR(duration_ms)
289 MAP_DURATION_SCALAR(duration_us)
290 MAP_DURATION_SCALAR(duration_ns)
291 
292 
297 template <typename T>
299 
300 template <typename T>
301 using scalar_device_type_t = typename type_to_scalar_type_impl<T>::ScalarDeviceType;
302 
395 // This pragma disables a compiler warning that complains about the valid usage
396 // of calling a __host__ functor from this function which is __host__ __device__
397 #pragma nv_exec_check_disable
398 template <template <cudf::type_id> typename IdTypeMap = id_to_type_impl,
399  typename Functor,
400  typename... Ts>
401 CUDA_HOST_DEVICE_CALLABLE constexpr decltype(auto) type_dispatcher(cudf::data_type dtype,
402  Functor f,
403  Ts&&... args)
404 {
405  switch (dtype.id()) {
406  case type_id::BOOL8:
407  return f.template operator()<typename IdTypeMap<type_id::BOOL8>::type>(
408  std::forward<Ts>(args)...);
409  case type_id::INT8:
410  return f.template operator()<typename IdTypeMap<type_id::INT8>::type>(
411  std::forward<Ts>(args)...);
412  case type_id::INT16:
413  return f.template operator()<typename IdTypeMap<type_id::INT16>::type>(
414  std::forward<Ts>(args)...);
415  case type_id::INT32:
416  return f.template operator()<typename IdTypeMap<type_id::INT32>::type>(
417  std::forward<Ts>(args)...);
418  case type_id::INT64:
419  return f.template operator()<typename IdTypeMap<type_id::INT64>::type>(
420  std::forward<Ts>(args)...);
421  case type_id::UINT8:
422  return f.template operator()<typename IdTypeMap<type_id::UINT8>::type>(
423  std::forward<Ts>(args)...);
424  case type_id::UINT16:
425  return f.template operator()<typename IdTypeMap<type_id::UINT16>::type>(
426  std::forward<Ts>(args)...);
427  case type_id::UINT32:
428  return f.template operator()<typename IdTypeMap<type_id::UINT32>::type>(
429  std::forward<Ts>(args)...);
430  case type_id::UINT64:
431  return f.template operator()<typename IdTypeMap<type_id::UINT64>::type>(
432  std::forward<Ts>(args)...);
433  case type_id::FLOAT32:
434  return f.template operator()<typename IdTypeMap<type_id::FLOAT32>::type>(
435  std::forward<Ts>(args)...);
436  case type_id::FLOAT64:
437  return f.template operator()<typename IdTypeMap<type_id::FLOAT64>::type>(
438  std::forward<Ts>(args)...);
439  case type_id::STRING:
440  return f.template operator()<typename IdTypeMap<type_id::STRING>::type>(
441  std::forward<Ts>(args)...);
442  case type_id::TIMESTAMP_DAYS:
443  return f.template operator()<typename IdTypeMap<type_id::TIMESTAMP_DAYS>::type>(
444  std::forward<Ts>(args)...);
445  case type_id::TIMESTAMP_SECONDS:
446  return f.template operator()<typename IdTypeMap<type_id::TIMESTAMP_SECONDS>::type>(
447  std::forward<Ts>(args)...);
448  case type_id::TIMESTAMP_MILLISECONDS:
449  return f.template operator()<typename IdTypeMap<type_id::TIMESTAMP_MILLISECONDS>::type>(
450  std::forward<Ts>(args)...);
451  case type_id::TIMESTAMP_MICROSECONDS:
452  return f.template operator()<typename IdTypeMap<type_id::TIMESTAMP_MICROSECONDS>::type>(
453  std::forward<Ts>(args)...);
454  case type_id::TIMESTAMP_NANOSECONDS:
455  return f.template operator()<typename IdTypeMap<type_id::TIMESTAMP_NANOSECONDS>::type>(
456  std::forward<Ts>(args)...);
457  case type_id::DURATION_DAYS:
458  return f.template operator()<typename IdTypeMap<type_id::DURATION_DAYS>::type>(
459  std::forward<Ts>(args)...);
460  case type_id::DURATION_SECONDS:
461  return f.template operator()<typename IdTypeMap<type_id::DURATION_SECONDS>::type>(
462  std::forward<Ts>(args)...);
463  case type_id::DURATION_MILLISECONDS:
464  return f.template operator()<typename IdTypeMap<type_id::DURATION_MILLISECONDS>::type>(
465  std::forward<Ts>(args)...);
466  case type_id::DURATION_MICROSECONDS:
467  return f.template operator()<typename IdTypeMap<type_id::DURATION_MICROSECONDS>::type>(
468  std::forward<Ts>(args)...);
469  case type_id::DURATION_NANOSECONDS:
470  return f.template operator()<typename IdTypeMap<type_id::DURATION_NANOSECONDS>::type>(
471  std::forward<Ts>(args)...);
472  case type_id::DICTIONARY32:
473  return f.template operator()<typename IdTypeMap<type_id::DICTIONARY32>::type>(
474  std::forward<Ts>(args)...);
475  case type_id::LIST:
476  return f.template operator()<typename IdTypeMap<type_id::LIST>::type>(
477  std::forward<Ts>(args)...);
478  case type_id::DECIMAL32:
479  return f.template operator()<typename IdTypeMap<type_id::DECIMAL32>::type>(
480  std::forward<Ts>(args)...);
481  case type_id::DECIMAL64:
482  return f.template operator()<typename IdTypeMap<type_id::DECIMAL64>::type>(
483  std::forward<Ts>(args)...);
484  case type_id::STRUCT:
485  return f.template operator()<typename IdTypeMap<type_id::STRUCT>::type>(
486  std::forward<Ts>(args)...);
487  default: {
488 #ifndef __CUDA_ARCH__
489  CUDF_FAIL("Unsupported type_id.");
490 #else
491  release_assert(false && "Unsupported type_id.");
492 
493  // The following code will never be reached, but the compiler generates a
494  // warning if there isn't a return value.
495 
496  // Need to find out what the return type is in order to have a default
497  // return value and solve the compiler warning for lack of a default
498  // return
499  using return_type = decltype(f.template operator()<int8_t>(std::forward<Ts>(args)...));
500  return return_type();
501 #endif
502  }
503  }
504 }
505 
506 namespace detail {
507 template <typename T1>
509 #pragma nv_exec_check_disable
510  template <typename T2, typename F, typename... Ts>
511  CUDA_HOST_DEVICE_CALLABLE decltype(auto) operator()(F&& f, Ts&&... args) const
512  {
513  return f.template operator()<T1, T2>(std::forward<Ts>(args)...);
514  }
515 };
516 
517 template <template <cudf::type_id> typename IdTypeMap>
519 #pragma nv_exec_check_disable
520  template <typename T1, typename F, typename... Ts>
521  CUDA_HOST_DEVICE_CALLABLE decltype(auto) operator()(cudf::data_type type2,
522  F&& f,
523  Ts&&... args) const
524  {
525  return type_dispatcher<IdTypeMap>(type2,
527  std::forward<F>(f),
528  std::forward<Ts>(args)...);
529  }
530 };
531 } // namespace detail
532 
545 #pragma nv_exec_check_disable
546 template <template <cudf::type_id> typename IdTypeMap = id_to_type_impl, typename F, typename... Ts>
547 CUDA_HOST_DEVICE_CALLABLE constexpr decltype(auto) double_type_dispatcher(cudf::data_type type1,
548  cudf::data_type type2,
549  F&& f,
550  Ts&&... args)
551 {
552  return type_dispatcher<IdTypeMap>(type1,
554  type2,
555  std::forward<F>(f),
556  std::forward<Ts>(args)...);
557 }
558  // end of group
560 } // namespace cudf
cudf::type_dispatcher
constexpr decltype(auto) CUDA_HOST_DEVICE_CALLABLE 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...
Definition: type_dispatcher.hpp:401
cudf::type_to_name
Definition: type_dispatcher.hpp:61
cudf::device_storage_type_id
type_id device_storage_type_id(type_id id)
Returns the corresponding type_id of type stored on device for a given type_id
Definition: type_dispatcher.hpp:111
fixed_point.hpp
Class definition for fixed point data type.
durations.hpp
Concrete type definitions for int32_t and int64_t durations in varying resolutions.
numeric::fixed_point
A type for representing a number with a fixed amount of precision.
Definition: fixed_point.hpp:212
cudf::string_scalar_device_view
A type of scalar_device_view that stores a pointer to a string value.
Definition: scalar_device_view.cuh:230
cudf::type_to_scalar_type_impl
Definition: type_dispatcher.hpp:194
cudf::type_id
type_id
Identifies a column's logical element type.
Definition: types.hpp:196
cudf::duration_s
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:39
types.hpp
Type declarations for libcudf.
cudf::string_view
A non-owning, immutable view of device data that is a variable length char array representing a UTF-8...
Definition: string_view.hpp:63
cudf::type_id_matches_device_storage_type
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.
Definition: type_dispatcher.hpp:130
CUDF_FAIL
#define CUDF_FAIL(reason)
Indicates that an erroneous code path has been taken.
Definition: error.hpp:80
cudf::duration_D
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
cudf::id_to_type
typename id_to_type_impl< Id >::type id_to_type
Maps a cudf::type_id to it's corresponding concrete C++ type.
Definition: type_dispatcher.hpp:83
cudf::detail::timestamp
Definition: timestamps.hpp:35
cudf::duration_ns
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:51
cudf::double_type_dispatcher
constexpr decltype(auto) CUDA_HOST_DEVICE_CALLABLE double_type_dispatcher(cudf::data_type type1, cudf::data_type type2, F &&f, Ts &&... args)
Dispatches two type template parameters to a callable.
Definition: type_dispatcher.hpp:547
cudf::device_storage_type_t
std::conditional_t< std::is_same< numeric::decimal32, T >::value, int32_t, std::conditional_t< std::is_same< numeric::decimal64, T >::value, int64_t, T > > device_storage_type_t
"Returns" the corresponding type that is stored on the device when using cudf::column
Definition: type_dispatcher.hpp:102
cudf::dictionary_wrapper
A strongly typed wrapper for indices in a DICTIONARY type column.
Definition: dictionary.hpp:48
cudf::CUDF_TYPE_MAPPING
CUDF_TYPE_MAPPING(bool, type_id::BOOL8)
Defines all of the mappings between C++ types and their corresponding cudf::type_id values.
cudf::id_to_type_impl
Definition: type_dispatcher.hpp:70
cudf::scalar
An owning class to represent a singular value.
Definition: scalar.hpp:51
cudf::numeric_scalar
An owning class to represent a numerical value in device memory.
Definition: scalar.hpp:223
dictionary.hpp
Concrete type definition for dictionary columns.
cudf::data_type
Indicator for the logical data type of an element in a column.
Definition: types.hpp:235
cudf::numeric_scalar_device_view
A type of scalar_device_view that stores a pointer to a numerical value.
Definition: scalar_device_view.cuh:200
cudf::fixed_point_scalar
An owning class to represent a fixed_point number in device memory.
Definition: scalar.hpp:273
cudf::scalar_type_t
typename type_to_scalar_type_impl< T >::ScalarType scalar_type_t
Maps a C++ type to the scalar type required to hold its value.
Definition: type_dispatcher.hpp:298
cudf::detail::double_type_dispatcher_second_type
Definition: type_dispatcher.hpp:508
cudf
cuDF interfaces
Definition: aggregation.hpp:34
cudf::detail::double_type_dispatcher_first_type
Definition: type_dispatcher.hpp:518
cudf::struct_view
A non-owning, immutable view of device data that represents a struct with fields of arbitrary types (...
Definition: struct_view.hpp:30
cudf::fixed_point_scalar_device_view
A type of scalar_device_view that stores a pointer to a fixed_point value.
Definition: scalar_device_view.cuh:212
cudf::list_view
A non-owning, immutable view of device data that represents a list of elements of arbitrary type (inc...
Definition: list_view.cuh:29
cudf::string_scalar
An owning class to represent a string in device memory.
Definition: scalar.hpp:394
timestamps.hpp
Concrete type definitions for int32_t and int64_t timestamps in varying resolutions as durations sinc...
cudf::duration_us
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:47
cudf::type_to_id
constexpr type_id type_to_id()
Maps a C++ type to it's corresponding cudf::type_id
Definition: type_dispatcher.hpp:56
cudf::duration_ms
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:43
numeric
fixed_point and supporting types
Definition: fixed_point.hpp:32
error.hpp