gpt4 book ai didi

c++ - 使用推力根据索引更改某些元素的值

转载 作者:行者123 更新时间:2023-12-02 10:22:16 25 4
gpt4 key购买 nike

  • 问题描述:
    我想使用推力根据另一个索引数组设置数组中某些元素的值。下面显示了一个简单的示例:
  • // input:
    int array[10] = {1,9,9,6,0,1,1,6,1,4};
    int set_num = -1;
    int index[4] = {0,2,4,6};
    // output:
    array[10] = {-1,9,-1,6,-1,1,-1,6,1,4};
  • 我的想法:
    我不知道如何使用推力来完成它,所以我编写了自己的内核。该代码段如下所示:
  • #include <cstdlib>
    #include <iostream>
    #include <cstdio>

    #include "cuda_runtime.h"
    #include "device_launch_parameters.h"


    #include <thrust/host_vector.h>
    #include <thrust/device_vector.h>
    #include <thrust/execution_policy.h>
    #include <thrust/copy.h>
    #include <thrust/sequence.h>
    #include <thrust/functional.h>

    // kernel function
    template <typename T>
    __global__ void setNumInArray(T *arrays, int *index, T set_num, int num_index)
    {
    unsigned int tid = threadIdx.x + blockDim.x * blockIdx.x;
    if (tid > num_index)
    return;
    arrays[index[tid]] = set_num;
    }

    int main()
    {
    const unsigned int vec_length = 4069; // length of the array
    thrust::device_vector<int>vec(vec_length);
    thrust::sequence(thrust::device, vec.begin(), vec.end(), 1); // the values are generated by thrust::sequence
    const int num_index = 16; // length of the index array
    thrust::device_vector<int>index(num_index); // the index array is generated by thrust::sequence
    thrust::sequence(thrust::device, index.begin(), index.end(), 64,10);

    // type convert: thrust->normal device pointer
    int *d_vec = reinterpret_cast<int*>(thrust::raw_pointer_cast(vec.data()));
    int *d_index = reinterpret_cast<int*>(thrust::raw_pointer_cast(index.data()));

    int set_num = 0; // the value I want to set

    int block_size = 64;
    setNumInArray<int> <<<1, block_size >>> (d_vec, d_index, set_num, num_index);

    thrust::host_vector<int>h_vec(vec_length); // check the result
    h_vec = vec;
    for (int ii = 0; ii < vec_length; ii++) {
    printf("%d: %d\n",ii+1,h_vec[ii]);
    }

    return 0;
    }

    该程序可以输出正确的答案。但是,我想避免在推力变量和通用设备变量之间进行类型转换(我在项目的其他部分中使用了很多推力函数),并且还避免了调整块/网格大小以实现更好的性能。那么,如何才能实现目标呢?
  • 工作环境:
  • 操作系统:Windows10
  • GPU:RTX2060
  • CUDA:10.2
  • IDE:VS2015
  • 其他问题:
  • 代码片段中的类型转换方法正确吗?会引起一些潜在的问题吗?
  • 为什么编译器(VS2015)找不到cudaOccupancyMaxPotentialBlockSizes?我想用它来确定最佳的块大小。
  • 最佳答案

    您可以将推力::: for_each与lambda函数一起使用。但是我还没有对此进行基准测试,也许您的内核更快。

    int main()
    {
    const unsigned int vec_length = 4069;
    thrust::device_vector<int>vec(vec_length);
    thrust::sequence(thrust::device, vec.begin(), vec.end(), 1);
    const int num_index = 16;
    thrust::device_vector<int>index(num_index);
    thrust::sequence(thrust::device, index.begin(), index.end(), 64,10);
    int *d_vec = thrust::raw_pointer_cast(vec.data());
    int set_num = 0;

    auto changeValue = [=] __device__(int y) { d_vec[y] = set_num; };
    thrust::for_each(thrust::device, index.begin(), index.end(), changeValue);

    thrust::host_vector<int>h_vec(vec_length);
    h_vec = vec;
    for (int ii = 0; ii < vec_length; ii++) {
    if(h_vec[ii] == set_num)
    printf("%d: %d\n",ii+1,h_vec[ii]);
    }
    return 0;
    }

    关于c++ - 使用推力根据索引更改某些元素的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59589360/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com