2012-04-29 37 views
31

Câu hỏi đặt ra là: có cách nào để sử dụng lớp "vector" trong hạt nhân Cuda không? Khi tôi thử, tôi nhận được lỗi sau:Sử dụng std :: vector trong mã thiết bị CUDA

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

Vì vậy, có cách nào để sử dụng vectơ trong phần toàn cầu? Gần đây tôi đã thử như sau:

  1. tạo một dự án CUDA mới
  2. đi đến tài sản của dự án
  3. mở CUDA C/C++
  4. đi đến Device
  5. thay đổi giá trị trong "Mã Thế hệ "được đặt thành giá trị này: compute_20, sm_20

........ sau đó tôi có thể sử dụng chức năng thư viện chuẩn printf trong hạt nhân Cuda của tôi.

có cách nào để sử dụng lớp thư viện chuẩn vector trong cách printf được hỗ trợ trong mã hạt nhân không? Đây là một ví dụ của việc sử dụng printf trong mã kernel:

// 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 câu hỏi hoàn toàn hợp pháp (không chắc chắn lý do tại sao nó được bình chọn xuống. Thật không may là câu trả lời hiện nay chưa có. – harrism

Trả lời

20

Bạn không thể sử dụng STL trong CUDA, nhưng bạn có thể sử dụng Thrust library để làm những gì bạn muốn. Nếu không, chỉ cần sao chép nội dung của vectơ vào thiết bị và hoạt động bình thường.

+3

Tôi không thấy thế nào điều này có nghĩa vụ phải giúp đỡ, bởi vì một 'lực đẩy :: device_vector' không thể cũng được sử dụng bên trong hạt nhân. – thatWiseGuy

7

bạn không thể sử dụng std::vector trong mã thiết bị, bạn nên sử dụng mảng thay thế.

12

Trong lực đẩy thư viện cuda, bạn có thể sử dụng thrust::device_vector<classT> để xác định vectơ trên thiết bị và chuyển dữ liệu giữa máy chủ lưu trữ vector STL và vector thiết bị rất đơn giản. bạn có thể tham khảo liên kết hữu ích này: http://docs.nvidia.com/cuda/thrust/index.html để tìm một số ví dụ hữu ích.

-1

Tôi nghĩ bạn có thể tự mình triển khai vectơ thiết bị, vì CUDA hỗ trợ phân bổ bộ nhớ động trong mã thiết bị. Toán tử mới/xóa cũng được hỗ trợ. Đây là một nguyên mẫu cực kỳ đơn giản của vector thiết bị trong CUDA, nhưng nó hoạt động. Nó chưa được kiểm tra đầy đủ.

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; 
    } 
}; 
Các vấn đề liên quan