Utility Dispatcher#
- group utility_dispatcher
Defines
-
CUDF_TYPE_MAPPING(Type, Id)#
Macro used to define a mapping between a concrete C++ type and a
cudf::type_id
enum.- Parameters:
Type – The concrete C++ type
Id – The
cudf::type_id
enum
-
MAP_NUMERIC_SCALAR(Type)#
Macro used to define scalar type and scalar device type for
cudf::numeric_scalar
template class for numeric C++ types.- Parameters:
Type – The numeric C++ type
-
MAP_TIMESTAMP_SCALAR(Type)#
Macro used to define scalar type and scalar device type for
cudf::timestamp_scalar
template class for timestamp C++ types.- Parameters:
Type – The timestamp C++ type
-
MAP_DURATION_SCALAR(Type)#
Macro used to define scalar type and scalar device type for
cudf::duration_scalar
template class for duration C++ types.- Parameters:
Type – The duration C++ type
Typedefs
-
template<cudf::type_id Id>
using id_to_type = typename id_to_type_impl<Id>::type# Maps a
cudf::type_id
to its corresponding concrete C++ type.Example:
static_assert(std::is_same<int32_t, id_to_type<id_type::INT32>);
- Template Parameters:
t – The
cudf::type_id
to map
-
template<typename T>
using device_storage_type_t = 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>>># “Returns” the corresponding type that is stored on the device when using
cudf::column
For
decimal32
, the storage type is anint32_t
. Fordecimal64
, the storage type is anint64_t
. Fordecimal128
, the storage type is an__int128_t
.Use this “type function” with the
using
type alias:using Type = device_storage_type_t<Element>;
- Template Parameters:
T – The literal type that is stored on the host
Functions
-
template<typename T>
inline constexpr type_id type_to_id()# Maps a C++ type to its corresponding
cudf::type_id
When explicitly passed a template argument of a given type, returns the appropriate
type_id
enum for the specified C++ type.For example:
return cudf::type_to_id<int32_t>(); // Returns INT32
- Template Parameters:
T – The type to map to a
cudf::type_id
- Returns:
The
cudf::type_id
corresponding to the specified type
-
template<typename T>
constexpr bool type_id_matches_device_storage_type(type_id id)# Checks if
fixed_point
-like types have template typeT
matching the column’s stored type id.- Template Parameters:
T – The type that is stored on the device
- Parameters:
id – The
data_type::id
of the column- Returns:
true
If T matches the stored columntype_id
- Returns:
false
If T does not match the stored columntype_id
-
template<>
inline constexpr type_id type_to_id<char>()# Specialization to map ‘char’ type to type_id::INT8.
Required when passing device_uvector<char> to column constructor. Possibly can be removed when PR 14202 is merged.
- Returns:
id for ‘char’ type
-
template<template<cudf::type_id> typename IdTypeMap = id_to_type_impl, typename Functor, typename ...Ts>
constexpr type_dispatcher(cudf::data_type dtype, Functor f, Ts&&... args)# Invokes an
operator()
template with the type instantiation based on the specifiedcudf::data_type
’sid()
.Example usage with a functor that returns the size of the dispatched type:
struct size_of_functor{ template <typename T> int operator()(){ return sizeof(T); } }; cudf::data_type t{INT32}; cudf::type_dispatcher(t, size_of_functor{}); // returns 4
The
type_dispatcher
usescudf::type_to_id<t>
to provide a default mapping ofcudf::type_id
s to dispatched C++ types. However, this mapping may be customized by explicitly specifying a user-defined trait struct for theIdTypeMap
. For example, to always dispatchint32_t
template<cudf::type_id t> struct always_int{ using type = int32_t; } // This will always invoke operator()<int32_t> cudf::type_dispatcher<always_int>(data_type, f);
It is sometimes necessary to customize the dispatched functor’s
operator()
for different types. This can be done in several ways.The first method is to use explicit template specialization. This is useful for specializing behavior for single types. For example, a functor that prints
int32_t
ordouble
when invoked with either of those types, else it printsunhandled type
:struct type_printer { template <typename ColumnType> void operator()() { std::cout << "unhandled type\n"; } }; // Due to a bug in g++, explicit member function specializations need to be // defined outside of the class definition template <> void type_printer::operator()<int32_t>() { std::cout << "int32_t\n"; } template <> void type_printer::operator()<double>() { std::cout << "double\n"; }
A second method is to use SFINAE with
std::enable_if_t
. This is useful for specializing for a set of types that share some property. For example, a functor that printsintegral
orfloating point
for integral or floating point types:struct integral_or_floating_point { template <typename ColumnType, std::enable_if_t<not std::is_integral_v<ColumnType> and not std::is_floating_point_v<ColumnType> >* = nullptr> void operator()() { std::cout << "neither integral nor floating point\n "; } template <typename ColumnType, std::enable_if_t<std::is_integral_v<ColumnType> >* = nullptr> void operator()() { std::cout << "integral\n"; } template <typename ColumnType, std::enable_if_t<std::is_floating_point_v<ColumnType> >* = nullptr> void operator()() { std::cout << "floating point\n"; } };
For more info on SFINAE and
std::enable_if
, see https://eli.thegreenplace.net/2014/sfinae-and-enable_if/The return type for all template instantiations of the functor’s “operator()” lambda must be the same, else there will be a compiler error as you would be trying to return different types from the same function.
- Template Parameters:
id_to_type_impl – Maps a
cudf::type_id
its dispatched C++ typeFunctor – The callable object’s type
Ts – Variadic parameter pack type
- Parameters:
dtype – The
cudf::data_type
whoseid()
determines which template instantiation is invokedf – The callable whose
operator()
template is invokedargs – Parameter pack of arguments forwarded to the
operator()
invocation
- Returns:
Whatever is returned by the callable’s
operator()
-
template<template<cudf::type_id> typename IdTypeMap = id_to_type_impl, typename F, typename ...Ts>
constexpr double_type_dispatcher(cudf::data_type type1, cudf::data_type type2, F &&f, Ts&&... args)# Dispatches two type template parameters to a callable.
This function expects a callable
f
with anoperator()
template accepting two typename template parametersT1
andT2
.- Parameters:
type1 – The
data_type
used to dispatch a type for the first template parameter of the callableF
type2 – The
data_type
used to dispatch a type for the second template parameter of the callableF
f – The callable whose
operator()
template is invokedargs – Parameter pack forwarded to the
operator()
invocationF
.
- Returns:
The result of invoking
f.template operator<T1, T2>(args)
-
template<cudf::type_id Id>
struct dispatch_storage_type# - #include <type_dispatcher.hpp>
Use this specialization on
type_dispatcher
whenever you only need to operate on the underlying stored type.For example,
cudf::sort
in sort.cu usescudf::type_dispatcher<dispatch_storage_type>(...)
.cudf::gather
in gather.cuh also usescudf::type_dispatcher<dispatch_storage_type>(...)
. However, reductions needs bothdata_type
and underlying type, so cannot use this.Public Types
-
using type = device_storage_type_t<id_to_type<Id>>#
The underlying type.
-
using type = device_storage_type_t<id_to_type<Id>>#
-
CUDF_TYPE_MAPPING(Type, Id)#