2012-06-22 17 views
5

पर 2 डी सरणी भेजना मुझे समझ में कुछ परेशानी हो रही है कि कैसे Cuda को 2 डी सरणी भेजनी है। मेरे पास एक प्रोग्राम है जो प्रत्येक पंक्ति पर 30 डेटा पॉइंट्स वाली एक बड़ी फ़ाइल को पार करता है। मैंने एक समय में लगभग 10 पंक्तियां पढ़ीं और फिर प्रत्येक पंक्ति और वस्तुओं के लिए एक मैट्रिक्स बनाएं (इसलिए 30 डेटा पॉइंट्स के साथ 10 पंक्तियों के मेरे उदाहरण में, यह int list[10][30]; होगा मेरा लक्ष्य इस सरणी को मेरे कर्नल में भेजना है और प्रत्येक ब्लॉक प्रक्रिया है एक पंक्ति (मुझे यह सामान्य सी में पूरी तरह से काम करने के लिए मिला है, लेकिन क्यूडा थोड़ा और चुनौतीपूर्ण रहा है)कुडा कर्नेल

यहां मैं अभी तक क्या कर रहा हूं लेकिन कोई किस्मत नहीं है (नोट: sizeofbucket = पंक्तियां, और आकारऑफबकेट्स होल्डिंग्स = आइटम पंक्ति में ... मैं जानता हूँ कि मैं अजीब चर नाम के लिए एक पुरस्कार) जीत चाहिए:

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]; 
      } 
     } 

त्रुटि मैं हो रही है:

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". 

लाइन 266 कर्नेल कॉल process_list<<<count,1>>> (count, countListItem, dev_current_list, pitch); है मुझे लगता है कि समस्या यह है कि मैं अपने कार्य में int * के रूप में अपनी सरणी बनाने की कोशिश कर रहा हूं लेकिन मैं इसे और कैसे बना सकता हूं? मेरे शुद्ध सी कोड में, मैं int current_list[num_of_rows][num_items_in_row] का उपयोग करता हूं जो काम करता है लेकिन मुझे क्यूडा में काम करने के लिए एक ही परिणाम नहीं मिल सकता है।

मेरा अंतिम लक्ष्य सरल है, मैं बस प्रत्येक पंक्ति को प्रत्येक पंक्ति (sizeOfBuckets) को संसाधित करने के लिए प्राप्त करना चाहता हूं और फिर उस पंक्ति में सभी वस्तुओं (sizeOfBucketHoldings) के माध्यम से लूप प्राप्त करना चाहता हूं। मैंने orginally सिर्फ एक सामान्य cudamalloc और cudaMemcpy किया था, लेकिन यह काम नहीं कर रहा था इसलिए मैंने चारों ओर देखा और मॉलोक पिच और 2 डीकॉपी के बारे में पता चला (दोनों जिनमें से मेरी cuda by example पुस्तक में नहीं थे) और मैं उदाहरणों का अध्ययन करने की कोशिश कर रहा हूं लेकिन वे प्रतीत होते हैं मुझे एक ही त्रुटि दे रही है (मैं वर्तमान में CUDA_C प्रोग्रामिंग मार्गदर्शिका पढ़ रहा हूं पृष्ठ 2222 पर यह विचार पाया लेकिन अभी भी कोई भाग्य नहीं है)। कोई विचार? या कहां देखना है?

संपादित करें: इसका परीक्षण करने के लिए, मैं सिर्फ एक साथ प्रत्येक पंक्ति का मूल्य जोड़ना चाहता हूं (मैंने उदाहरण के अतिरिक्त उदाहरण उदाहरण के द्वारा तर्क को कॉपी किया है)। मेरे गिरी:

__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]; 
    } 
} 

यहाँ कैसे मैं अपने मुख्य में कुल सरणी की घोषणा है:

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

उत्तर

3

अपने कोड में कुछ गलतियां की है।

  • तो फिर तुम डिवाइस के लिए मेजबान सरणी कॉपी आप एक आयामी मेजबान function signature pointer.See पास करना चाहिए।
  • आपको डिवाइस मेमोरी के लिए स्थिर 2 डी सरणी आवंटित करने की आवश्यकता नहीं है। यह होस्ट मेमोरी में स्थिर सरणी बनाता है फिर आप इसे डिवाइस सरणी के रूप में पुन: बनाते हैं। ध्यान रखें कि यह एक आयामी सरणी भी होनी चाहिए। यह function signature देखें।

यह उदाहरण स्मृति आवंटन के साथ आप की मदद करनी चाहिए:

__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; 
} 

कर्नेल में अपने 2 डी सरणी का उपयोग करने के लिए आप पैटर्न base_addr + y * pitch_d + x उपयोग करना चाहिए। चेतावनी: पिटव्स बाइट्स में सभी रास्ते। आपको अपने पॉइंटर को byte* पर डालना होगा।

+0

हमेशा मरीना के रूप में धन्यवाद। मैंने आपकी सेटिंग्स की कोशिश की लेकिन मुझे तब भी वही त्रुटि मिलती है जब मैं कर्नेल 'त्रुटि शुरू करने का प्रयास करता हूं: प्रकार का तर्क "int * (*) [sizeOfBucketsHoldings]" प्रकार "int *" प्रकार के पैरामीटर के साथ असंगत है, मैं सरणी भेज रहा हूं सही ढंग से? – Lostsoul

+0

क्षमा करें, मुझे लगता है कि मैं समझता हूं कि अब आप क्या कर रहे थे ..मैंने होस्ट को सूची में बदल दिया और संकलन करते समय कोई त्रुटि नहीं मिली, लेकिन 'सेगमेंटेशन गलती: 11' मिली लेकिन यह मेरे टेस्ट कर्नेल से संबंधित हो सकता है .. – Lostsoul

+0

कृपया, मुझे अपना कोड प्राप्त करने के लिए प्रश्न में अपना कोड अपडेट करें जहां आपका वर्तमान मुद्दा स्थित है। – geek

संबंधित मुद्दे