多项目更换在cuda推力 [英] multi item replacing in cuda thrust

查看:152
本文介绍了多项目更换在cuda推力的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个设备向量A,B,C如下。

I have a device vector A,B,C as following.

A = [1,1,3,3,3,4,4,5,5]
B = [1,3,5]
C = [2,8,6]

所以我要用a中的相应元素替换a中的每一个。
Eg:

So I want to replace each of B in a with corresponding element in C. Eg:


  • 1替换为2,

  • 3替换为8,

  • / li>
  • 1 is replaced by 2,
  • 3 is replaced by 8,
  • 5 is replaced by 6

,以获得以下结果

Result = [2,2,8,8,8,4,4,6,6]

我如何实现这在cuda推力或任何方式实现它在cuda C ++。我发现thrust :: replace一次性替换单个元素。由于我需要替换大量的数据,它成为瓶颈,每次替换一个。

How do I achieve this in cuda thrust or any way of implementing it in cuda C++. I found thrust::replace which replaces single element at once. Since I need to replace huge amount of data, it becomes bottleneck to replace one at a time.

推荐答案

首先构建一个地图,然后应用查询地图的自定义函子。

This can be done efficiently by first building a map and then applying a custom functor which queries the map.

示例代码执行以下步骤:

The example code does the following steps:


  1. 获取 C 中最大的元素。这假设您的数据已排序。

  1. Get the largest element of C. This assumes that your data is already sorted.

创建大小 largest_element 的地图向量。

Create a map vector of size largest_element. Copy the new values at the position of the old ones.

mapper 函数应用于 A 。该函数从映射向量中读取 new_value 。如果此 new_value 0 ,则 A 替换为新值。这假设 C 永远不会包含 0 。如果它可以包含 0 ,则必须使用其他条件,例如。使用 -1 初始化地图向量并检查 new_value!= -1

Apply the mapper functor to A. This functor reads new_value from the map vector. If this new_value is not 0, the value in A is replaced by the new value. This assumes that C will never contain 0. If it can contain 0, you must use another condition, e.g. initialize the map vector with -1 and check if new_value != -1







#include <thrust/device_vector.h>
#include <thrust/iterator/permutation_iterator.h>
#include <thrust/copy.h>
#include <thrust/for_each.h>
#include <thrust/scatter.h>
#include <iostream>


#define PRINTER(name) print(#name, (name))
template <template <typename...> class V, typename T, typename ...Args>
void print(const char* name, const V<T,Args...> & v)
{
    std::cout << name << ":\t";
    thrust::copy(v.begin(), v.end(), std::ostream_iterator<T>(std::cout, "\t"));
    std::cout << std::endl;
}


template <typename T>
struct mapper
{
    mapper(thrust::device_ptr<const T> map) : map(map)
    {
    }

    __host__ __device__
    void operator()(T& value) const
    {
       const T& new_value = map[value]; 
       if (new_value)
       {
          value = new_value;
       }
    }

    thrust::device_ptr<const T> map;
};

int main()
{
    using namespace thrust::placeholders;

    int A[] = {1,1,3,3,3,4,4,5,5};
    int B[] = {1,3,5};
    int C[] = {2,8,6};

    int size_data    = sizeof(A)/sizeof(A[0]);
    int size_replace = sizeof(B)/sizeof(B[0]);

    // copy demo data to GPU
    thrust::device_vector<int> d_A (A, A+size_data);
    thrust::device_vector<int> d_B (B, B+size_replace);
    thrust::device_vector<int> d_C (C, C+size_replace);

    PRINTER(d_A);
    PRINTER(d_B);
    PRINTER(d_C);

    int largest_element = d_C.back();

    thrust::device_vector<int> d_map(largest_element);

    thrust::scatter(d_C.begin(), d_C.end(), d_B.begin(), d_map.begin());
    PRINTER(d_map);

    thrust::for_each(d_A.begin(), d_A.end(), mapper<int>(d_map.data()));
    PRINTER(d_A);

    return 0;
}

输出

d_A:    1   1   3   3   3   4   4   5   5   
d_B:    1   3   5   
d_C:    2   8   6   
d_map:  0   2   0   8   0   6   
d_A:    2   2   8   8   8   4   4   6   6   

这篇关于多项目更换在cuda推力的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆