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:
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 an int32_t. For decimal64, the storage type is an int64_t. For decimal128, 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

template<typename T>
using scalar_type_t = typename type_to_scalar_type_impl<T>::ScalarType#

Maps a C++ type to the scalar type required to hold its value.

Template Parameters:

T – The concrete C++ type to map

template<typename T>
using scalar_device_type_t = typename type_to_scalar_type_impl<T>::ScalarDeviceType#

Maps a C++ type to the scalar device type required to hold its value.

Template Parameters:

T – The concrete C++ type to map

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 type T 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 column type_id

Returns:

false If T does not match the stored column type_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 specified cudf::data_type’s id().

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 uses cudf::type_to_id<t> to provide a default mapping of cudf::type_ids to dispatched C++ types. However, this mapping may be customized by explicitly specifying a user-defined trait struct for the IdTypeMap. For example, to always dispatch int32_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 or double when invoked with either of those types, else it prints unhandled 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 prints integral or floating 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++ type

  • Functor – The callable object’s type

  • Ts – Variadic parameter pack type

Parameters:
  • dtype – The cudf::data_type whose id() determines which template instantiation is invoked

  • f – The callable whose operator() template is invoked

  • args – 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 an operator() template accepting two typename template parameters T1 and T2.

Parameters:
  • type1 – The data_type used to dispatch a type for the first template parameter of the callable F

  • type2 – The data_type used to dispatch a type for the second template parameter of the callable F

  • f – The callable whose operator() template is invoked

  • args – Parameter pack forwarded to the operator() invocation F.

Returns:

The result of invoking f.template operator<T1, T2>(args)

std::string type_to_name(data_type type)#

Return a name for a given type.

The returned type names are intended for error messages and are not guaranteed to be stable.

Parameters:

type – The data_type

Returns:

Name of the type

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 uses cudf::type_dispatcher<dispatch_storage_type>(...). cudf::gather in gather.cuh also uses cudf::type_dispatcher<dispatch_storage_type>(...). However, reductions needs both data_type and underlying type, so cannot use this.

Public Types

using type = device_storage_type_t<id_to_type<Id>>#

The underlying type.