CUDA初学者-Thrust - Algorithms - Prefix Sums(3)

本人 CUDA小白一枚,要是有什么不对,还望各位大佬指点。
本文及后面的几篇将分别从几个方面来大概阐述一下Thrust的一些接口。原来的网址在这里

1.Algorithms

1.3 Prefix Sums
1.3.1 inclusive_scan

template <typename DerivedPolicy, typename InputIterator, typename OutputIterator>
__host__ __device__ OutputIterator thrust::inclusive_scan(
	const thrust::detail::execution_policy_base< DerivedPolicy > & exec,
  	InputIterator first,
  	InputIterator last,
  	OutputIterator result
);

template <typename InputIterator, typename OutputIterator>
OutputIterator thrust::inclusive_scan(
  	InputIterator first,
  	InputIterator last,
  	OutputIterator result
);

template <typename DerivedPolicy, typename InputIterator, typename OutputIterator, typename AssociativeOperator>
__host__ __device__ OutputIterator thrust::inclusive_scan(
	const thrust::detail::execution_policy_base< DerivedPolicy > & exec,
  	InputIterator first,
  	InputIterator last,
  	OutputIterator result,
  	AssociativeOperator binary_op
);

template <typename InputIterator, typename OutputIterator, typename AssociativeOperator>
OutputIterator thrust::inclusive_scan(
  	InputIterator first,
  	InputIterator last,
  	OutputIterator result,
  	AssociativeOperator binary_op
);

将[first, last)中每个index对应的result的结果为[first, index]之间的数值进行操作,默认为求和,可以指定特殊的操作。
例子:

int data[6] = {1, 0, 2, 2, 1, 3};
thrust::inclusive_scan(thrust::host, data, data + 6, data);
// thrust::inclusive_scan(data, data + 6, data);
// data中的结果为{1, 1, 3, 5, 6, 9}

int data2[10] = {-5, 0, 2, -3, 2, 4, 0, -1, 2, 8};
thrust::maximum<int> binary_op;   // 取最大值
thrust::inclusive_scan(thrust::host, data2, data2+ 6, data2);
// thrust::inclusive_scan(thrust::host, data2, data2+ 6, data2);
// data2中的结果为{-5, 0, 2, 2, 2,4, 4, 4, 4, 8}

1.3.2 exclusive_scan

template <typename DerivedPolicy, typename InputIterator, typename OutputIterator>
__host__ __device__ OutputIterator thrust::exclusive_scan(
	const thrust::detail::execution_policy_base< DerivedPolicy > & exec,
  	InputIterator first,
  	InputIterator last,
  	OutputIterator result
);

template <typename InputIterator, typename OutputIterator>
OutputIterator thrust::exclusive_scan(
  	InputIterator first,
  	InputIterator last,
  	OutputIterator result
);

template <typename DerivedPolicy, typename InputIterator, typename OutputIterator, typename T>
__host__ __device__ OutputIterator thrust::exclusive_scan(
	const thrust::detail::execution_policy_base< DerivedPolicy > & exec,
  	InputIterator first,
  	InputIterator last,
  	OutputIterator result,
  	T init
);

template <typename InputIterator, typename OutputIterator, typename T>
OutputIterator thrust::exclusive_scan(
  	InputIterator first,
  	InputIterator last,
  	OutputIterator result,
  	T init
);

template <typename DerivedPolicy, typename InputIterator, typename OutputIterator, typename T, typename AssociativeOperator>
__host__ __device__ OutputIterator thrust::exclusive_scan(
	const thrust::detail::execution_policy_base< DerivedPolicy > & exec,
  	InputIterator first,
  	InputIterator last,
  	OutputIterator result,
  	T init,
  	AssociativeOperator binary_op
);

template <typename InputIterator, typename OutputIterator, typename T, typename AssociativeOperator>
OutputIterator thrust::exclusive_scan(
  	InputIterator first,
  	InputIterator last,
  	OutputIterator result,
  	T init,
  	AssociativeOperator binary_op
);

将[first, last)中每个index对应的result的结果为[first, index)之间的数值进行操作,默认为求和,可以指定特殊的操作,也可以指定初始化的值。与exclusive唯一的区别在于当前index是否包含在内。指定的初始化值主要是针对第一个index的时候,相当于在原来的数组前增加一个值。

int data[6] = {1, 0, 2, 2, 1, 3};
thrust::exclusive_scan(thrust::host, data, data + 6, data);
// thrust::exclusive_scan(data, data + 6, data);
// data输出 {0, 1, 1, 3, 5, 6}

int data2[6] = {1, 0, 2, 2, 1, 3};
thrust::exclusive_scan(thrust::host, data, data + 6, data, 4);
// thrust::exclusive_scan(data, data + 6, data, 4);
// data2 {4, 5, 5, 7, 9, 10}

int data3[10] = {-5, 0, 2, -3, 2, 4, 0, -1, 2, 8};
thrust::maximum<int> binary_op;
thrust::exclusive_scan(thrust::host, data, data + 10, data, 1, binary_op);
// thrust::exclusive_scan(data, data + 10, data, 1, binary_op);
// data3 {1, 1, 1, 2, 2, 2, 4, 4, 4, 4}

1.3.3 inclusive_scan_by_key

template <typename DerivedPolicy, typename InputIterator1, typename InputIterator2, typename OutputIterator>
__host__ __device__ OutputIterator thrust::inclusive_scan_by_key(
	const thrust::detail::execution_policy_base< DerivedPolicy > & exec,
 	InputIterator1 first1,
  	InputIterator1 last1,
  	InputIterator2 first2,
  	OutputIterator result
);

template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
OutputIterator thrust::inclusive_scan_by_key(
 	InputIterator1 first1,
  	InputIterator1 last1,
  	InputIterator2 first2,
  	OutputIterator result
);

template <typename DerivedPolicy, typename InputIterator1, typename InputIterator2, typename OutputIterator, typename BinaryPredicate>
__host__ __device__ OutputIterator thrust::inclusive_scan_by_key(
	const thrust::detail::execution_policy_base< DerivedPolicy > & exec,
 	InputIterator1 first1,
  	InputIterator1 last1,
  	InputIterator2 first2,
  	OutputIterator result,
  	BinaryPredicate binary_pred
);

template <typename InputIterator1, typename InputIterator2, typename OutputIterator,  typename BinaryPredicate>
OutputIterator thrust::inclusive_scan_by_key(
 	InputIterator1 first1,
  	InputIterator1 last1,
  	InputIterator2 first2,
  	OutputIterator result,
  	BinaryPredicate binary_pred
);

template <typename DerivedPolicy, typename InputIterator1, typename InputIterator2, typename OutputIterator, typename BinaryPredicate, typename AssociativeOperator>
__host__ __device__ OutputIterator thrust::inclusive_scan_by_key(
	const thrust::detail::execution_policy_base< DerivedPolicy > & exec,
 	InputIterator1 first1,
  	InputIterator1 last1,
  	InputIterator2 first2,
  	OutputIterator result,
  	BinaryPredicate binary_pred,
  	AssociativeOperator binary_op
);

template <typename InputIterator1, typename InputIterator2, typename OutputIterator,  typename BinaryPredicate, typename AssociativeOperator>
OutputIterator thrust::inclusive_scan_by_key(
 	InputIterator1 first1,
  	InputIterator1 last1,
  	InputIterator2 first2,
  	OutputIterator result,
  	BinaryPredicate binary_pred,
  	AssociativeOperator binary_op
);

针对[first1, last1)中的数值如果出现连续相同的数值,称为一个segment。每一个segment中执行inclusive的操作。可以指定segment定义的方法,也可以指定同一个segment中需要完成的操作。
例子:

int A[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
int B[10] = {2, 1, 2, 2, 3, 4, 5, 5, 5, 5};
thrust::inclusive_scan_by_key(thrust::host, B, B + 10, A, A);
// thrust::inclusive_scan_by_key(B, B + 10, A, A);
// A的结果为 {1, 1, 1, 2, 1, 1, 1, 2, 3, 4}
// 如果 A[10] = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0};
// 则对应的输出结果为 {1, 0, 1, 1, 1, 0, 1, 1, 2, 2}

int C[10] = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0};
thrust::equal_to<int> binary_pred;
thrust::inclusive_scan_by_key(thrust::host, B, B + 10, C, C, binary_pred);
// thrust::inclusive_scan_by_key(B, B + 10, C, C, binary_pred);
// C的结果为{1, 0, 1, 1, 1, 0, 1, 1, 2, 2}

int D[10] = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0};
thrust::plus<int> binary_op;
thrust::inclusive_scan_by_key(thrust::host, B, B + 10, C, C, binary_pred, binary_op);
// thrust::inclusive_scan_by_key(B, B + 10, C, C, binary_pred, binary_op);
// C的结果为{1, 0, 1, 1, 1, 0, 1, 1, 2, 2}

1.3.4 exclusive_scan_by_key

template <typename DerivedPolicy, typename InputIterator1, typename InputIterator2, typename OutputIterator>
__host__ __device__ OutputIterator thrust::exclusive_scan_by_key(
	const thrust::detail::execution_policy_base< DerivedPolicy > & exec,
 	InputIterator1 first1,
  	InputIterator1 last1,
  	InputIterator2 first2,
  	OutputIterator result
);

template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
OutputIterator thrust::exclusive_scan_by_key(
 	InputIterator1 first1,
  	InputIterator1 last1,
  	InputIterator2 first2,
  	OutputIterator result
);

template <typename DerivedPolicy, typename InputIterator1, typename InputIterator2, typename OutputIterator, typename T>
__host__ __device__ OutputIterator thrust::exclusive_scan_by_key(
	const thrust::detail::execution_policy_base< DerivedPolicy > & exec,
 	InputIterator1 first1,
  	InputIterator1 last1,
  	InputIterator2 first2,
  	OutputIterator result,
  	T init
);

template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename T>
OutputIterator thrust::exclusive_scan_by_key(
 	InputIterator1 first1,
  	InputIterator1 last1,
  	InputIterator2 first2,
  	OutputIterator result,
  	T init
);

template <typename DerivedPolicy, typename InputIterator1, typename InputIterator2, typename OutputIterator, typename T, typename BinaryPredicate>
__host__ __device__ OutputIterator thrust::exclusive_scan_by_key(
	const thrust::detail::execution_policy_base< DerivedPolicy > & exec,
 	InputIterator1 first1,
  	InputIterator1 last1,
  	InputIterator2 first2,
  	OutputIterator result,
  	T init,
  	BinaryPredicate binary_pred
);

template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename T, typename BinaryPredicate>
OutputIterator thrust::exclusive_scan_by_key(
 	InputIterator1 first1,
  	InputIterator1 last1,
  	InputIterator2 first2,
  	OutputIterator result,
  	T init,
  	BinaryPredicate binary_pred
);

template <typename DerivedPolicy, typename InputIterator1, typename InputIterator2, typename OutputIterator, typename T, typename BinaryPredicate, typename AssociativeOperator>
__host__ __device__ OutputIterator thrust::exclusive_scan_by_key(
	const thrust::detail::execution_policy_base< DerivedPolicy > & exec,
 	InputIterator1 first1,
  	InputIterator1 last1,
  	InputIterator2 first2,
  	OutputIterator result,
  	T init,
  	BinaryPredicate binary_pred,
  	AssociativeOperator binary_op
);

template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename T, typename BinaryPredicate, typename AssociativeOperator>
OutputIterator thrust::exclusive_scan_by_key(
 	InputIterator1 first1,
  	InputIterator1 last1,
  	InputIterator2 first2,
  	OutputIterator result,
  	T init,
  	BinaryPredicate binary_pred,
  	AssociativeOperator binary_op
);

原理同inclusive_scan_by_key,同样可以指定segment的划分方法,同一个segment中需要执行的操作,以及同一个segment中初始的值。
例子:

int keys[10] = {0, 0, 0, 1, 1, 2, 3, 3, 3, 3};
int vals[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
thrust::exclusive_scan_by_key(thrust::host, key, key + 10, vals, vals);
// thrust::exclusive_scan_by_key(key, key + 10, vals, vals);
// vals的值为 {0, 1, 2, 0, 1, 0, 0, 1, 2, 3}

int vals2[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
int init = 5;
thrust::exclusive_scan_by_key(thrust::host, key, key + 10, vals2, vals2, init);
// thrust::exclusive_scan_by_key(key, key + 10, vals, vals, init);
// vals的值为 {5, 6, 7, 5, 6, 5, 5, 6, 7, 8}

int vals3[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
thrust::equal_to<int> binary_op;
thrust::exclusive_scan_by_key(thrust::host, key, key + 10, vals3, vals3, init, binary_op);
// thrust::exclusive_scan_by_key(key, key + 10, vals, vals, init, binary_op);
// vals的值为 {5, 6, 7, 5, 6, 5, 5, 6, 7, 8}

1.3.5 transform_inclusive_scan

template <typename DerivedPolicy, typename InputIterator, typename OutputIterator, typename UnaryFunction, typename AssociativeOperator>
__host__ __device__ OutputIterator thrust::transform_inclusive_scan(
	const thrust::detail::execution_policy_base< DerivedPolicy > & exec,
  	InputIterator first,
  	InputIterator last,
  	OutputIterator result,
  	UnaryFunction unary_op,
  	AssociativeOperator binary_op
);

template <typename InputIterator, typename OutputIterator, typename UnaryFunction, typename AssociativeOperator>
OutputIterator thrust::transform_inclusive_scan(
  	InputIterator first,
  	InputIterator last,
  	OutputIterator result,
  	UnaryFunction unary_op,
  	AssociativeOperator binary_op
);

在原先inclusive_scan的基础上增加了transform的操作。
例子:

int data[8] = {1, 0, 2, 2, 1, 3};
thrust::negate<int> unary_op;
thrust::plus<int> binary_op;
thrust::transform_inclusive_scan(thrust::host, data, data + 6, data, unary_op, binary_op);
// thrust::transform_inclusive_scan(data, data + 6, data, unary_op, binary_op);
// data  {-1, -1, -3, -5, -6, -9}

1.3.6 transform_exclusive_scan

template <typename DerivedPolicy, typename InputIterator, typename OutputIterator, typename UnaryFunction, typename T, typename AssociativeOperator>
__host__ __device__ OutputIterator thrust::transform_exclusive_scan(
	const thrust::detail::execution_policy_base< DerivedPolicy > & exec,
  	InputIterator first,
  	InputIterator last,
  	OutputIterator result,
  	UnaryFunction unary_op,
  	T init,
  	AssociativeOperator binary_op
);

template <typename InputIterator, typename OutputIterator, typename UnaryFunction, typename T, typename AssociativeOperator>
OutputIterator thrust::transform_exclusive_scan(
  	InputIterator first,
  	InputIterator last,
  	OutputIterator result,
  	UnaryFunction unary_op,
  	T init,
  	AssociativeOperator binary_op
);

在exclusive_scan的基础上增加了transform的操作。
例子:

int data[6] = {1, 0, 2, 2, 1, 3};
thrust::negate<int> unary_op;
thrust::plus<int> binary_op;

thrust::transform_exclusive_scan(thrust:host, data, data + 6, data, unary_op, 4, binary_op);
// thrust::transform_exclusive_scan(data, data + 6, data, unary_op, 4, binary_op);
// data的值为 {4, 3, 3, 1, -1, -2}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值