2012-06-22 31 views
5

Tôi đang gặp một chút rắc rối khi hiểu cách gửi một mảng 2D tới Cuda. Tôi có một chương trình phân tích một tệp lớn với 30 điểm dữ liệu trên mỗi dòng. Tôi đọc khoảng 10 hàng tại một thời điểm và sau đó tạo ma trận cho mỗi dòng và mục (trong ví dụ của tôi gồm 10 hàng với 30 điểm dữ liệu, nó sẽ là int list[10][30]; Mục tiêu của tôi là gửi mảng này đến kernal của tôi và có từng quá trình khối một hàng (tôi đã nhận được điều này để làm việc hoàn hảo trong C bình thường, nhưng Cuda đã được một chút khó khăn hơn).Gửi mảng 2D tới Cuda Kernel

Đây là những gì tôi đang làm cho đến nay nhưng không có may mắn (lưu ý: sizeofbucket = rows, và sizeOfBucketsHoldings = items trong hàng ... tôi biết tôi nên giành chiến thắng một giải thưởng cho tên biến lẻ):

int list[sizeOfBuckets][sizeOfBucketsHoldings]; //this is created at the start of the file and I can confirmed its filled with the correct data 
#define sizeOfBuckets 10 //size of buckets before sending to process list 
#define sizeOfBucketsHoldings 30 
    //Cuda part 
       //define device variables 
       int *dev_current_list[sizeOfBuckets][sizeOfBucketsHoldings]; 
       //time to malloc the 2D array on device 
       size_t pitch; 
       cudaMallocPitch((int**)&dev_current_list, (size_t *)&pitch, sizeOfBucketsHoldings * sizeof(int), sizeOfBuckets); 

       //copy data from host to device 
       cudaMemcpy2D(dev_current_list, pitch, list, sizeOfBuckets * sizeof(int), sizeOfBuckets * sizeof(int), sizeOfBucketsHoldings * sizeof(int),cudaMemcpyHostToDevice); 

       process_list<<<count,1>>> (sizeOfBuckets, sizeOfBucketsHoldings, dev_current_list, pitch); 
       //free memory of device 
       cudaFree(dev_current_list); 


    __global__ void process_list(int sizeOfBuckets, int sizeOfBucketsHoldings, int *current_list, int pitch) { 
     int tid = blockIdx.x; 
     for (int r = 0; r < sizeOfBuckets; ++r) { 
      int* row = (int*)((char*)current_list + r * pitch); 
      for (int c = 0; c < sizeOfBucketsHoldings; ++c) { 
       int element = row[c]; 
      } 
     } 

Các lỗi tôi nhận được là:

main.cu(266): error: argument of type "int *(*)[30]" is incompatible with parameter of type "int *" 
1 error detected in the compilation of "/tmp/tmpxft_00003f32_00000000-4_main.cpp1.ii". 

dòng 266 là cuộc gọi hạt nhân process_list<<<count,1>>> (count, countListItem, dev_current_list, pitch); Tôi nghĩ rằng vấn đề là tôi đang cố gắng để tạo mảng của tôi trong chức năng của tôi như int * nhưng làm thế nào khác tôi có thể tạo ra nó? Trong mã C thuần túy của tôi, tôi sử dụng int current_list[num_of_rows][num_items_in_row] hoạt động nhưng tôi không thể có được kết quả tương tự để làm việc trong Cuda.

Mục tiêu cuối cùng của tôi rất đơn giản Tôi chỉ muốn mỗi khối xử lý mỗi hàng (sizeOfBuckets) và sau đó có vòng lặp qua tất cả các mục trong hàng đó (sizeOfBucketHoldings). Tôi orginally chỉ làm một cudamalloc bình thường và cudaMemcpy nhưng nó không hoạt động vì vậy tôi nhìn xung quanh và tìm hiểu về MallocPitch và 2dcopy (cả hai đều không có trong cuốn sách cuda by example) và tôi đã cố gắng nghiên cứu các ví dụ nhưng chúng dường như cho tôi cùng một lỗi (Tôi hiện đang đọc hướng dẫn lập trình CUDA_C tìm thấy ý tưởng này trên trang 22 nhưng vẫn không có may mắn). Bất kỳ ý tưởng? hoặc gợi ý về nơi để tìm?

Chỉnh sửa: Để kiểm tra điều này, tôi chỉ muốn thêm giá trị của mỗi hàng lại với nhau (tôi đã sao chép logic từ cuda bằng ví dụ về mảng ví dụ). hạt nhân của tôi:

__global__ void process_list(int sizeOfBuckets, int sizeOfBucketsHoldings, int *current_list, size_t pitch, int *total) { 
    //TODO: we need to flip the list as well 
    int tid = blockIdx.x; 
    for (int c = 0; c < sizeOfBucketsHoldings; ++c) { 
     total[tid] = total + current_list[tid][c]; 
    } 
} 

Đây là cách tôi khai báo mảng tổng trong chính của tôi:

int *dev_total; 
cudaMalloc((void**)&dev_total, sizeOfBuckets * sizeof(int)); 

Trả lời

3

Bạn có một số sai lầm trong mã của bạn.

  • Sau đó, bạn sao chép mảng máy chủ vào thiết bị, bạn nên chuyển con trỏ máy chủ một chiều. Hãy xem function signature.
  • Bạn không cần phân bổ mảng 2D tĩnh cho bộ nhớ thiết bị. Nó tạo ra mảng tĩnh trong bộ nhớ máy chủ sau đó bạn tạo lại nó như mảng thiết bị. Hãy nhớ rằng nó cũng phải là mảng một chiều. Xem trang này function signature.

Ví dụ này sẽ giúp bạn với cấp phát bộ nhớ:

__global__ void process_list(int sizeOfBucketsHoldings, int* total, int* current_list, int pitch) 
{ 
    int tid = blockIdx.x; 
    total[tid] = 0; 
    for (int c = 0; c < sizeOfBucketsHoldings; ++c) 
    { 
     total[tid] += *((int*)((char*)current_list + tid * pitch) + c); 
    } 
} 

int main() 
{ 
    size_t sizeOfBuckets   = 10; 
    size_t sizeOfBucketsHoldings = 30; 

    size_t width = sizeOfBucketsHoldings * sizeof(int);//ned to be in bytes 
    size_t height = sizeOfBuckets; 

    int* list = new int [sizeOfBuckets * sizeOfBucketsHoldings];// one dimensional 
    for (int i = 0; i < sizeOfBuckets; i++) 
     for (int j = 0; j < sizeOfBucketsHoldings; j++) 
      list[i *sizeOfBucketsHoldings + j] = i; 

    size_t pitch_h = sizeOfBucketsHoldings * sizeof(int);// always in bytes 

    int* dev_current_list; 
    size_t pitch_d; 
    cudaMallocPitch((int**)&dev_current_list, &pitch_d, width, height); 

    int *test; 
    cudaMalloc((void**)&test, sizeOfBuckets * sizeof(int)); 
    int* h_test = new int[sizeOfBuckets]; 

    cudaMemcpy2D(dev_current_list, pitch_d, list, pitch_h, width, height, cudaMemcpyHostToDevice); 

    process_list<<<10, 1>>>(sizeOfBucketsHoldings, test, dev_current_list, pitch_d); 
    cudaDeviceSynchronize(); 

    cudaMemcpy(h_test, test, sizeOfBuckets * sizeof(int), cudaMemcpyDeviceToHost); 

    for (int i = 0; i < sizeOfBuckets; i++) 
     printf("%d %d\n", i , h_test[i]); 
    return 0; 
} 

Để truy cập vào mảng 2D của bạn trong kernel bạn nên sử dụng mô hình base_addr + y * pitch_d + x. CẢNH BÁO: allways pitvh tính theo byte. Bạn cần đưa con trỏ đến byte*.

+0

Cảm ơn bạn luôn là Marina. Tôi đã thử các thiết lập của bạn nhưng tôi vẫn gặp lỗi tương tự khi tôi cố gắng khởi động hạt nhân 'error: đối số của kiểu" int * (*) [sizeOfBucketsHoldings] "không tương thích với tham số kiểu" int * "' tôi gửi mảng đúng không? – Lostsoul

+0

xin lỗi, tôi nghĩ rằng tôi hiểu những gì bạn đang làm bây giờ ..Tôi đã thay đổi máy chủ thành danh sách và không gặp lỗi khi biên dịch, nhưng có lỗi 'Phân đoạn: 11' nhưng có thể liên quan đến hạt nhân thử nghiệm của tôi .. – Lostsoul

+0

Vui lòng cập nhật mã của bạn để hỏi thông tin về nơi bạn hiện tại vấn đề được đặt. – geek