2012-04-29 10 views
31

सवाल यह है कि: क्या कुडा कर्नेल में कक्षा "वेक्टर" का उपयोग करने का कोई तरीका है? जब मैं कोशिश करता हूं तो मुझे निम्न त्रुटि मिलती है:सीयूडीए डिवाइस कोड में std :: वेक्टर का उपयोग

error : calling a host function("std::vector<int, std::allocator<int> > ::push_back") from a __device__/__global__ function not allowed 

तो वैश्विक अनुभाग में वेक्टर का उपयोग करने का कोई तरीका है? मैं हाल ही में निम्नलिखित की कोशिश की:

  1. एक नया Cuda परियोजना
  2. परियोजना के गुणों के लिए जाना बनाने
  3. खुला Cuda C/C++
  4. डिवाइस के लिए "कोड में मूल्य जाना
  5. परिवर्तन पीढ़ी "को इस मान पर सेट किया जाना चाहिए: compute_20, sm_20

........ उसके बाद मैं इसका उपयोग करने में सक्षम था मेरे Cuda कर्नेल में printf मानक पुस्तकालय समारोह।

क्या मानक पुस्तकालय वर्ग vector का उपयोग करने के लिए कोई तरीका है जिस तरह से printf कर्नेल कोड में समर्थित है?

// this code only to count the 3s in an array using Cuda 
//private_count is an array to hold every thread's result separately 

__global__ void countKernel(int *a, int length, int* private_count) 
{ 
    printf("%d\n",threadIdx.x); //it's print the thread id and it's working 

    // vector<int> y; 
    //y.push_back(0); is there a possibility to do this? 

    unsigned int offset = threadIdx.x * length; 
    int i = offset; 
    for(; i < offset + length; i++) 
    { 
     if(a[i] == 3) 
     { 
      private_count[threadIdx.x]++; 
      printf("%d ",a[i]); 
     } 
    } 
} 
+3

+1 पूरी तरह से कानूनी प्रश्न (यकीन नहीं क्यों यह मतदान किया गया था। दुर्भाग्य से इस सवाल का जवाब वर्तमान में कोई है। – harrism

उत्तर

20

आप CUDA में एसटीएल उपयोग नहीं कर सकते, लेकिन आप Thrust library उपयोग करने के लिए आप क्या चाहते हैं ऐसा करने में सक्षम हो सकता है: यह कर्नेल कोड में printf का उपयोग करने का एक उदाहरण है। अन्यथा बस वेक्टर की सामग्री को डिवाइस पर कॉपी करें और सामान्य रूप से इसे चालू करें।

+3

मैं, नहीं दिख रहा है कि यह कैसे मदद करने के लिए माना जाता है, क्योंकि एक 'जोर :: device_vector' नहीं किया जा सकता या तो कर्नेल के अंदर प्रयोग किया जाता है। – thatWiseGuy

7

आप डिवाइस कोड में std::vector का उपयोग नहीं कर सकते हैं, तो आपको इसके बजाय सरणी का उपयोग करना चाहिए।

12

कूडा लाइब्रेरी जोर में, आप डिवाइस पर वेक्टर को परिभाषित करने के लिए thrust::device_vector<classT> का उपयोग कर सकते हैं, और मेजबान एसटीएल वेक्टर और डिवाइस वेक्टर के बीच डेटा स्थानांतरण बहुत सरल है। आप कुछ उपयोगी उदाहरण खोजने के लिए इस उपयोगी लिंक का संदर्भ ले सकते हैं: http://docs.nvidia.com/cuda/thrust/index.html

-1

मुझे लगता है कि आप स्वयं द्वारा एक डिवाइस वेक्टर को कार्यान्वित कर सकते हैं, क्योंकि CUDA डिवाइस कोड में गतिशील स्मृति आवंटन का समर्थन करता है। ऑपरेटर नया/हटा भी समर्थित है। यहां CUDA में डिवाइस वेक्टर का एक बेहद सरल प्रोटोटाइप है, लेकिन यह काम करता है। यह पर्याप्त रूप से परीक्षण नहीं किया गया है।

template<typename T> 
class LocalVector 
{ 
private: 
    T* m_begin; 
    T* m_end; 

    size_t capacity; 
    size_t length; 
    __device__ void expand() { 
     capacity *= 2; 
     size_t tempLength = (m_end - m_begin); 
     T* tempBegin = new T[capacity]; 

     memcpy(tempBegin, m_begin, tempLength * sizeof(T)); 
     delete[] m_begin; 
     m_begin = tempBegin; 
     m_end = m_begin + tempLength; 
     length = static_cast<size_t>(m_end - m_begin); 
    } 
public: 
    __device__ explicit LocalVector() : length(0), capacity(16) { 
     m_begin = new T[capacity]; 
     m_end = m_begin; 
    } 
    __device__ T& operator[] (unsigned int index) { 
     return *(m_begin + index);//*(begin+index) 
    } 
    __device__ T* begin() { 
     return m_begin; 
    } 
    __device__ T* end() { 
     return m_end; 
    } 
    __device__ ~LocalVector() 
    { 
     delete[] m_begin; 
     m_begin = nullptr; 
    } 

    __device__ void add(T t) { 

     if ((m_end - m_begin) >= capacity) { 
      expand(); 
     } 

     new (m_end) T(t); 
     m_end++; 
     length++; 
    } 
    __device__ T pop() { 
     T endElement = (*m_end); 
     delete m_end; 
     m_end--; 
     return endElement; 
    } 

    __device__ size_t getSize() { 
     return length; 
    } 
}; 
संबंधित मुद्दे