簡體   English   中英

在設備向量上設置類型為int數組的每個主機向量的數據元素

[英]Setting each host vector's data element of type int array on device vector

我正在嘗試在CUDA Thrust上實現以下C ++函數:

void setFragment( vector< Atom * > &vStruct, vector< Fragment * > &vFragment ) {
    Fragment *frag;

    int n = vStruct.size();

    for( int i = 0 ; i < n-2 ; i++ ){
        frag = new Fragment();
        frag->index[0] = i;
        frag->index[1] = i+1;   
        frag->index[2] = i+2;   

        vFragment.push_back( frag );    
    }
}

為此,我創建了一個仿函數,可以通過以下方式設置每個Fragment向量的索引:

struct setFragment_functor
{
    const int n;

    setFragment_functor(int _n) : n(_n) {}

    __host__ __device__
    void operator() (Fragment *frag) {
        frag->index[0] = n;
        frag->index[1] = n+1;
        frag->index[2] = n+2;       
    }
};

void setFragment( vector< Atom * > &vStruct, vector< Fragment * > &vFragment ) {
    int n = vStruct.size();
    thrust::device_vector<Fragment *> d_vFragment(n-2);

    thrust::transform( d_vFragment.begin(), d_vFragment.end(), setFragment_functor( thrust::counting_iterator<int>(0) ) );

    thrust::copy(d_vFragment.begin(), d_vFragment.end(), vFragment.begin());        
}

但是,對於我應用的轉換,我遇到了以下錯誤:

1) error: no instance of constructor "setFragment_functor::setFragment_functor" matches the argument list
            argument types are: (thrust::counting_iterator<int, thrust::use_default, thrust::use_default, thrust::use_default>) 
2) error: no instance of overloaded function "thrust::transform" matches the argument list
        argument types are: (thrust::detail::normal_iterator<thrust::device_ptr<Fragment *>>, thrust::detail::normal_iterator<thrust::device_ptr<Fragment *>>, <error-type>)

我是CUDA的新手。 如果有人可以幫助我在CUDA上實現C ++函數,我將不勝感激。

坦率地說,您編寫的代碼有幾個明顯的問題,永遠無法以您想像的方式工作。 除此之外,我猜想首先要在GPU上運行像這樣的功能的原因是因為分析顯示它非常慢。 之所以這么慢,是因為它的設計非常差,並且對於一個大小合適的輸入數組,可能會調用newpush_back數百萬次。 無法在GPU上加速這些功能。 它們比較 ,而不是更快。 使用GPU來構建這種類型的結構數組,僅將它們復制回主機的想法與試圖使用推力來加速文件I / O一樣不合邏輯。 從根本上講,沒有什么硬件或問題的大小比執行原始主機代碼要快。 GPU上的延遲和GPU與主機之間的互連帶寬保證了這一點。

使用推力初始化GPU內存中的結構數組的元素很簡單。 tabulate轉換可以與像這樣的函子一起使用:

#include <thrust/device_vector.h>
#include <thrust/tabulate.h>
#include <iostream>

struct Fragment
{
   int index[3];
   Fragment() = default;
};

struct functor
{
    __device__ __host__
    Fragment operator() (const int &i) const { 
        Fragment f; 
        f.index[0] = i; f.index[1] = i+1; f.index[2] = i+2; 
        return f;
    }
};


int main()
{
    const int N = 10;
    thrust::device_vector<Fragment> dvFragment(N);
    thrust::tabulate(dvFragment.begin(), dvFragment.end(), functor());

    for(auto p : dvFragment) {
        Fragment f = p;
        std::cout << f.index[0] << " " << f.index[1] << " " << f.index[2] << std::endl;
    }

    return 0;
}    

像這樣運行:

$ nvcc -arch=sm_52 -std=c++14 -ccbin=g++-7 -o mobasher Mobasher.cu 
$ cuda-memcheck ./mobasher 
========= CUDA-MEMCHECK
0 1 2
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
8 9 10
9 10 11
========= ERROR SUMMARY: 0 errors

但這不是您問題中原始主機代碼的直接翻譯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM