推力收集/过滤

问题描述 投票:0回答:1

我想做的是在向量上创建一个过滤器,以便删除未通过谓词测试的元素;但不太确定我该怎么做。

我根据谓词评估输入向量中的每个元素,例如在我的代码中,在 device_vector 向量中的 is_even 函子。如果通过测试则为 true,如果未通过测试则为 false。

现在我陷入困境,因为我现在有了这个布尔向量,并且我想收集通过此谓词测试的元素。我将其存储在布尔向量中,因为我想保留结果以过滤其他向量。

#include ...

template<typename T>
struct is_even : thrust::unary_function<T, bool>
{
    __host__ __device__
    bool operator()(const T &x)
    {
        return (x%2)==0;
    }
};

int main(void)
{
    std::cout << "Loading test!" << std::endl;
    const int N = 1000000;
    thrust::device_vector<int> col1(N);
    thrust::device_vector<float> col2(N, 1); 
    thrust::sequence(col1.begin(), col1.end());

    thrust::device_vector<bool> filter(N);
    thrust::transform(col1.begin(), col1.end(), filter.begin(), is_even<int>());

    // filter col1 and col2 based on filter

    return 0;
}
cuda thrust
1个回答
5
投票

流压缩组中,您可能会对

thrust::copy_if

感兴趣

我们可以直接使用您定义的谓词将偶数元素选择到新向量中,而无需制作中间

filter
向量:

thrust::copy_if(col1.begin(), col1.end(), result.begin(), is_even<int>());

result
应该是与
col1
类型相同的向量,并且已经定义为长度等于或大于
col1
,因为不知道有多少元素将通过谓词测试。)

如果您想使用您创建的

filter
矢量,请使用 copy_if
模板版本

这是一个根据您的评论使用模板方法的有效示例:

$ cat t267.cu
#include <iostream>
#include <thrust/device_vector.h>
#include <thrust/sequence.h>
#include <thrust/transform.h>
#include <thrust/copy.h>

template<typename T>
struct is_even : thrust::unary_function<T, bool>
{
    __host__ __device__
    bool operator()(const T &x)
    {
        return (x%2)==0;
    }
};


struct is_true : thrust::unary_function<bool, bool>
{
    __host__ __device__
    bool operator()(const bool &x)
    {
        return x;
    }
};

int main(void)
{
    std::cout << "Loading test!" << std::endl;
    const int N = 1000000;
    thrust::device_vector<int> col1(N);
    thrust::device_vector<float> col2(N, 1);
    thrust::sequence(col1.begin(), col1.end());

    thrust::device_vector<bool> filter(N);
    thrust::device_vector<int> result(N);
    thrust::transform(col1.begin(), col1.end(), filter.begin(), is_even<int>());
    // filter col1 based on filter
    thrust::device_vector<int>::iterator end = thrust::copy_if(col1.begin(), col1.end(), filter.begin(), result.begin(), is_true());
    int len = end - result.begin();
    thrust::host_vector<int> h_result(len);
    thrust::copy_n(result.begin(), len, h_result.begin());
    thrust::copy_n(h_result.begin(), 10, std::ostream_iterator<int>(std::cout, "\n"));


    return 0;
}
$ nvcc -arch=sm_20 -o t267 t267.cu
$ ./t267
Loading test!
0
2
4
6
8
10
12
14
16
18
$
© www.soinside.com 2019 - 2024. All rights reserved.