实用程序调度器#

group utility_dispatcher

定义

CUDF_TYPE_MAPPING(Type, Id)#

用于定义具体C++类型与cudf::type_id枚举之间映射的宏。

Parameters:
MAP_NUMERIC_SCALAR(Type)#

用于为cudf::numeric_scalar模板类定义标量类型和标量设备类型的宏,适用于数值C++类型。

Parameters:
  • 类型 – 数值类型的C++类型

MAP_TIMESTAMP_SCALAR(Type)#

用于为cudf::timestamp_scalar模板类定义标量类型和标量设备类型的宏,适用于时间戳C++类型。

Parameters:
  • 类型 – 时间戳的C++类型

MAP_DURATION_SCALAR(Type)#

用于为cudf::duration_scalar模板类定义标量类型和标量设备类型的宏,适用于C++中的持续时间类型。

Parameters:
  • 类型 – 持续时间 C++ 类型

类型定义

template<cudf::type_id Id>
using id_to_type = typename id_to_type_impl<Id>::type#

cudf::type_id 映射到其对应的具体 C++ 类型。

示例:

static_assert(std::is_same<int32_t, id_to_type<id_type::INT32>);

Template Parameters:

t – 要映射的 cudf::type_id

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>>>#

“返回”使用cudf::column时存储在设备上的相应类型

对于decimal32,存储类型是int32_t。对于decimal64,存储类型是int64_t。对于decimal128,存储类型是__int128_t

使用此“类型函数”与using类型别名:

using Type = device_storage_type_t<Element>;

Template Parameters:

T – 存储在主机上的字面类型

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

将C++类型映射到保存其值所需的标量类型。

Template Parameters:

T – 要映射的具体C++类型

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

将C++类型映射到保存其值所需的标量设备类型。

Template Parameters:

T – 要映射的具体C++类型

函数

template<typename T>
inline constexpr type_id type_to_id()#

将C++类型映射到其对应的cudf::type_id

当明确传递给定类型的模板参数时,返回指定C++类型的适当type_id枚举。

例如:

return cudf::type_to_id<int32_t>();        // Returns INT32
Template Parameters:

T – 要映射到的类型 cudf::type_id

Returns:

与指定类型对应的 cudf::type_id

template<typename T>
constexpr bool type_id_matches_device_storage_type(type_id id)#

检查fixed_point类类型是否具有与列的存储类型ID匹配的模板类型T

Template Parameters:

T – 存储在设备上的类型

Parameters:

id – 列的 data_type::id

Returns:

true 如果 T 匹配存储的列 type_id

Returns:

false 如果 T 不匹配存储的列 type_id

template<>
inline constexpr type_id type_to_id<char>()#

将‘char’类型映射到type_id::INT8的特化。

在将device_uvector传递给列构造函数时需要。可能在合并PR 14202时可以移除。

Returns:

‘char’ 类型的 id

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)#

调用一个operator()模板,其类型实例化基于指定的cudf::data_typeid()

使用一个返回调度类型大小的函子的示例用法:

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

type_dispatcher 使用 cudf::type_to_id 来提供 cudf::type_id 到派发的 C++ 类型的默认映射。然而,可以通过为 IdTypeMap 显式指定用户定义的特征结构来自定义此映射。例如,始终派发 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);

有时需要为不同类型自定义派发的函子的operator()。这可以通过几种方式完成。

第一种方法是使用显式模板特化。这对于为单一类型特化行为非常有用。例如,一个仿函数在被调用时打印int32_tdouble,否则它会打印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"; }

第二种方法是使用SFINAE与std::enable_if_t。这对于专门化一组共享某些属性的类型非常有用。例如,一个打印integralfloating point的函数对象,用于整数或浮点类型:

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"; }
};

有关SFINAE和std::enable_if的更多信息,请参见https://eli.thegreenplace.net/2014/sfinae-and-enable_if/

所有模板实例化的函子的“operator()”lambda的返回类型必须相同,否则会出现编译器错误,因为你试图从同一个函数返回不同的类型。

Template Parameters:
  • id_to_type_impl – 将 cudf::type_id 映射到其分派的 C++ 类型

  • Functor – 可调用对象的类型

  • Ts – 可变参数包类型

Parameters:
  • dtypecudf::data_typeid() 决定了调用哪个模板实例化

  • f – 调用其 operator() 模板的可调用对象

  • args – 转发给 operator() 调用的参数包

Returns:

无论可调用对象的 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)#

将两个类型模板参数分派给可调用对象。

此函数期望一个可调用的f,其operator()模板接受两个类型名模板参数T1T2

Parameters:
  • type1 – 用于为可调用对象 F 的第一个模板参数分派类型的 data_type

  • type2 – 用于为可调用对象 F 的第二个模板参数分派类型的 data_type

  • f – 调用其 operator() 模板的可调用对象

  • args – 参数包转发到 operator() 调用 F

Returns:

调用 f.template operator T2>(args) 的结果

std::string type_to_name(data_type type)#

返回给定类型的名称。

返回的类型名称用于错误信息,并不保证是稳定的。

Parameters:

typedata_type 类型

Returns:

类型的名称

template<cudf::type_id Id>
struct dispatch_storage_type#
#include <type_dispatcher.hpp>

当您只需要操作底层存储类型时,请在 type_dispatcher 上使用此专门化。

例如,cudf::sort 在 sort.cu 中使用 cudf::type_dispatcher<dispatch_storage_type>(...)cudf::gather 在 gather.cuh 中也使用 cudf::type_dispatcher<dispatch_storage_type>(...)。然而,归约操作需要 data_type 和底层类型,因此不能使用这个。

公共类型

using type = device_storage_type_t<id_to_type<Id>>#

基础类型。