Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ CUDA推力-如何使用不同大小的多个设备向量编写函数?_C++_Cuda_Gpu_Thrust - Fatal编程技术网

C++ CUDA推力-如何使用不同大小的多个设备向量编写函数?

C++ CUDA推力-如何使用不同大小的多个设备向量编写函数?,c++,cuda,gpu,thrust,C++,Cuda,Gpu,Thrust,我一直在试图找出如何使用四个推力装置矢量进行简单的熵计算 我有四个设备向量,代表两个键值对。第一对向量包含键和键出现的次数。第二对包含与用于计算熵的容器配对的密钥。在第二个向量对中,键出现多次,每个实例表示不同的bin 它看起来像这样: 设备向量对1 凯瓦尔689 计数1 3 2 设备向量对2 键值68899 宾瓦尔1 2 1 结果向量(包含计算的熵结果) 基瓦尔8 熵0.602 我计划做的是使用第一个向量对检查一个键是否出现足够的次数来计算熵。如果计数足够大,则第二个向量对将用于使用该键的bi

我一直在试图找出如何使用四个推力装置矢量进行简单的熵计算

我有四个设备向量,代表两个键值对。第一对向量包含键和键出现的次数。第二对包含与用于计算熵的容器配对的密钥。在第二个向量对中,键出现多次,每个实例表示不同的bin

它看起来像这样:

设备向量对1

凯瓦尔689

计数1 3 2

设备向量对2

键值68899

宾瓦尔1 2 1

结果向量(包含计算的熵结果)

基瓦尔8

熵0.602

我计划做的是使用第一个向量对检查一个键是否出现足够的次数来计算熵。如果计数足够大,则第二个向量对将用于使用该键的bin值计算熵。我需要使用该特定键的所有bin值。例如,如果我想计算至少出现3次的键的熵,我会在第一个向量对中发现KeyVal 8已经就绪。然后,我将在第二对中搜索KeyVal 8的所有实例,并使用它们对应的BinVal计算熵。熵的计算很简单,只需要将每个相关值的BinVal*Log(BinVal)相加。在我的例子中,它将是熵=1*log(1)+2*log(2)

然而,我不知道如何使这部分工作。我已经尝试使用推力::for_each来查找所有出现足够次数以进行测试的键,但我认为不可能在第二个向量对中搜索键并在for_each函数中执行计算

有人对实现这一目标的其他方法有什么建议吗


谢谢你的帮助。

我考虑的两个想法是:

想法A:

  • 计算所有熵
  • 选择符合条件的
  • 想法B:

  • 选择符合条件的传入数据
  • 计算熵
  • 想法A似乎在做不必要的工作——计算可能需要或可能不需要的熵。然而,当我完成构思B的过程时,我最终添加了很多步骤(例如计算前缀和)来完成构思B的步骤1,这似乎并不更好。因此,我现在将提出一个想法。也许m.s.或其他人会来发布更好的东西

    想法A的第1步由
    推力::按_键减少_
    以及适当的函子处理,以计算特定的熵函数

    想法A的第2步由
    asch::copy\u(如果

    $ cat t827.cu
    #include <iostream>
    #include <thrust/device_vector.h>
    #include <thrust/copy.h>
    #include <thrust/reduce.h>
    #include <thrust/iterator/zip_iterator.h>
    #include <thrust/iterator/transform_iterator.h>
    #include <thrust/iterator/discard_iterator.h>
    #include <math.h>
    
    // THRESH determines the minimum Counts value required for a KeyVal Entropy calculation to occur
    #define THRESH 2
    
    using namespace thrust::placeholders;
    
    
    struct my_entropy : public thrust::unary_function<float, float>
    {
      __host__ __device__
      float operator()(float val){
        return val*log10f(val);}  // if you want napierian log, change this to logf
    };
    
    int main(){
    
      int KeyVal1[]={6, 8, 9};
      int Counts[] ={1, 3, 2};
      int KeyVal2[]={6, 8, 8, 9, 9};
      float BinVal[] ={1, 1, 2, 1, 1};
    
      int dsize1 = sizeof(KeyVal1)/sizeof(int);
      int dsize2 = sizeof(KeyVal2)/sizeof(int);
    
      thrust::device_vector<int> d_KeyVal1(KeyVal1, KeyVal1+dsize1);
      thrust::device_vector<int> d_Counts(Counts, Counts+dsize1);
      thrust::device_vector<int> d_KeyVal2(KeyVal2, KeyVal2+dsize2);
      thrust::device_vector<float> d_BinVal(BinVal, BinVal+dsize2);
    
    
      // method 1 - just compute all entropies, then select the desired ones
      thrust::device_vector<float> entropies(dsize2);
      thrust::reduce_by_key(d_KeyVal2.begin(), d_KeyVal2.end(), thrust::make_transform_iterator(d_BinVal.begin(), my_entropy()), thrust::make_discard_iterator(), entropies.begin());
      thrust::device_vector<int> res_keys(dsize1);
      thrust::device_vector<float>res_ent(dsize1);
      int res_size = thrust::copy_if(thrust::make_zip_iterator(thrust::make_tuple(d_KeyVal1.begin(), entropies.begin())), thrust::make_zip_iterator(thrust::make_tuple(d_KeyVal1.end(), entropies.end())), d_Counts.begin(), thrust::make_zip_iterator(thrust::make_tuple(res_keys.begin(), res_ent.begin())), _1 >= THRESH) - thrust::make_zip_iterator(thrust::make_tuple(res_keys.begin(), res_ent.begin()));
      std::cout << "Counts threshold: " << THRESH << std::endl <<  "selected keys: " << std::endl;
      thrust::copy_n(res_keys.begin(), res_size, std::ostream_iterator<int>(std::cout, ","));
      std::cout << std::endl << "calculated entropies: " << std::endl;
      thrust::copy_n(res_ent.begin(), res_size, std::ostream_iterator<float>(std::cout, ","));
      std::cout << std::endl;
    
      return 0;
    }
    [bob@cluster1 misc]$ nvcc -o t827 t827.cu
    $ ./t827
    Counts threshold: 2
    selected keys:
    8,9,
    calculated entropies:
    0.60206,0,
    $
    
    $cat t827.cu
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    //THRESH确定进行KeyVal熵计算所需的最小计数值
    #定义阈值2
    使用命名空间推力::占位符;
    结构my_熵:公共推力::一元函数
    {
    __主机设备__
    浮点运算符()(浮点值){
    返回val*log10f(val);}//如果需要napierian日志,请将其更改为logf
    };
    int main(){
    int KeyVal1[]={6,8,9};
    整数计数[]={1,3,2};
    int-KeyVal2[]={6,8,8,9,9};
    float BinVal[]={1,1,2,1,1};
    int dsize1=sizeof(KeyVal1)/sizeof(int);
    int dsize2=sizeof(KeyVal2)/sizeof(int);
    推力:设备向量d_KeyVal1(KeyVal1,KeyVal1+dsize1);
    推力:设备矢量d_计数(计数,计数+dsize1);
    推力:设备向量d_KeyVal2(KeyVal2,KeyVal2+dsize2);
    推力:设备向量d_BinVal(BinVal,BinVal+dsize2);
    //方法1-只需计算所有熵,然后选择所需的熵
    推力:装置矢量熵(dsize2);
    推力::按键减少(d_KeyVal2.begin(),d_KeyVal2.end(),推力::生成变换迭代器(d_BinVal.begin(),my_熵()),推力::生成丢弃迭代器(),熵.begin());
    推力:设备矢量恢复键(dsize1);
    推力:设备矢量(dsize1);
    int res\u size=struct::copy\u if(struct::make\u-zip\u迭代器(struct::make\u-tuple(d\u-KeyVal1.begin(),entropies.begin()),struct::make\u-zip\u迭代器(struct::make\u-tuple(d\u-KeyVal1.end(),entropies.end()),d\u-Counts.begin()),struct::make\u-zip\u迭代器(推力:make_tuple(res_keys.begin(),res_ent.begin());
    
    std::你能完成你的描述吗?提供一个完整的向量序列,包括你的示例所需的结果向量。特别是,你说“然后,我将在第二对中搜索KeyVal 8的所有实例,并使用它们对应的BinVal计算熵”这意味着什么?您希望对与KeyVal 8相对应的BinVal(即,在您的示例中为BinVal 1和2)执行的算术是什么?对不起,我应该包括这一点。计算很简单,它只是将每个相关值的BinVal*Log(BinVal)相加。在我的示例中,它将是熵=1*Log(1)+2*Log(2)。KeyVal向量是否已排序?如果未排序,则可能会像键一样分组在一起?我是否希望键在每个向量中以相同的顺序出现?如果某个特定的KeyVal出现在第一个KeyVal向量中,是否有可能在第二个KeyVal向量中没有它的条目?KeyVal向量将按类似于组合在一起的键。如果某个特定的KeyVal出现在第一个KeyVal向量中,是否有可能在第二个KeyVal向量中没有它的条目?谢谢!我已经用我的代码测试了Idea,并验证了它为我的数据提供了正确的熵。