2011-06-14 12 views
7

मैं टेम्पलेट कर्नेल बनाने की कोशिश कर रहा हूं लेकिन मुझे अपने प्रोग्राम में उन्हें कुछ परेशानी हो रही है। मैं एक Matrix<T> टेम्पलेट वर्ग है, और कुछ तरीकों इसके अंदर परिभाषितटेम्पलेट को कॉल करते समय समस्या CUDA कर्नेल

Matrix.h:

template <typename T> class Matrix { 
    ... 
    void sum(Matrix<T>& m1, Matrix<T>& m2, Matrix<T>& sum); 
    ... 
} 

#include "Matrix.cu" 

Matrix.cu:

#include "MatrixKernel.h" 

template<typename T> void Matrix<T>::sum(const Matrix<T>& m, Matrix<T>& sum) { 
    ... 
    sumKernel<T><<<dimGrid, dimBlock>>>(Matrix<T> m1, Matrix<T> m2, Matrix<T> sum) 
    ... 
} 

MatrixKernel.h:

template<typename T> __global__ void sumKernel(const Matrix<T> m1, const Matrix<T> m2, Matrix<T> sum) { 
... 
} 

समस्या यह है कि जब मैं योग के अंदर से sumKernel को कॉल करता हूं, तो संकलक मुझे निम्न त्रुटि देता है:

error C2059: syntax error : '<' 

क्या किसी को पता है कि क्या हो रहा है? कोड को कर्नेल कॉल शामिल करने से ठीक पहले कोड संकलित किया गया था।

धन्यवाद।

+0

मुझे नहीं पता था कि आप CUDA और C++ (!) का उपयोग कर सकते हैं। मामूली सुझाव: '' के बीच एक जगह डालने का प्रयास करें और '<<<' उन्हें एक साथ चलाने के मामले में पार्स समस्याओं का कारण बन रहा है। – Rup

+0

क्या संकलक ने आपको बताया कि त्रुटि किस लाइन पर है? कूडा टेम्पलेट कोड में बहुत कुछ है, इसलिए यह किस लाइन को चालू करना है, इसे कम करने के लिए उपयोगी होगा। –

+0

@Rup: हाँ, आप कर सकते हैं। आप वस्तुओं को कर्नेल के तर्क के रूप में भी पास कर सकते हैं (बशर्ते आपने डिवाइस मेमोरी में रुचि के डेटा की प्रतिलिपि बनाई हो)। मैं भी आपके सुझाव का प्रयास करूंगा। @ बोमाडेनो: त्रुटि उस रेखा पर है जो कर्नेल कॉल करता है। – Renan

उत्तर

6

तो, ऐसा लगता है कि आपके पास एक अजीब #include है, जो गलत संकलक द्वारा संकलित कोड को जन्म देता है। Cuda शीर्षकों के लिए .cu.h का उपयोग कर जीपीयू हेडर और सीपीयू हेडर के बीच एक भेद बनाओ। सुनिश्चित करें कि केवल एनवीसीसी .cu और .cu.h फ़ाइलों को संकलित करता है। Cuda फ़ाइलों को कभी भी सीपीपी फाइलों में शामिल नहीं किया जाना चाहिए। कर्नेल और कर्नेल कॉल .cu या .cu.h फ़ाइलों में होना चाहिए, और उन फ़ाइलों को सीपीपीएस में कहीं भी शामिल नहीं किया जाना चाहिए।

क्योंकि आपके .cu को हेडर में शामिल किया जा रहा है जिसे होस्ट कंपाइलर द्वारा संकलित किया जा रहा है, होस्ट कंपाइलर टोकन <<< को टकराने से समाप्त होता है - जिसे यह पहचाना नहीं जाता है। यह शायद टोकन << को समझता है, इसलिए यह एक अप्रत्याशित < छोड़कर इसका उपभोग करता है।

जिन कारणों से काम करना चाहिए ऐसा करने का एक वैकल्पिक तरीका है (इसे करने की कोशिश नहीं है, लेकिन यह कोड हम उपयोग करने के लिए समान है)

(ध्यान दें, यह काम हो सकता है लेकिन यह भी समस्या को हल करने के लिए सही रास्ता नहीं हो सकता है मेरे बॉस इसे एक समाधान के रूप में पसंद नहीं करते हैं और प्रति भिन्नता को कार्यान्वित करना पसंद करेंगे)

अंतर्निहित समस्या होस्ट और डिवाइस कोड के बीच भेद की कमी प्रतीत होती है। मैं अपने समाधान में विस्तार से बाहर निकल रहा हूं - डिवाइस से, और कार्यान्वयन, आदि से परिणामों की प्रतिलिपि बनाने जैसी चीजें

समस्या जिसे मैं हल करने की कोशिश कर रहा हूं, एक निर्माण दिया गया है, आप इसे कैसे टेम्पलेट कर सकते हैं मेजबान और डिवाइस दोनों पर प्रयोग करें?

मैं प्रकार और कार्यान्वयन विस्तार दोनों पर Matrix.h टेम्पलेट करूँगा।

#include "Matrix.h" 

template <typename T> struct HostMatrixSum 
{ 
    void sumImp(Matrix<T>& m1, Matrix<T>& m2, Matrix<T>& sum) 
    { 
     ... 
    } 
} 

GpuMatrixSum.cu.h है, मैट्रिक्स अपलोड योग करते हैं और परिणाम वसूल करेगा:: फिर

#include "Matrix.h" 

template <typename T> struct GpuMatrixSum 
{ 
    template<typename T> __global__ void sumKernel(const Matrix<T> m1, const Matrix<T> m2, Matrix<T> sum) 
    { 
     ... 
    } 

    void sumImp(Matrix<T>& m1, Matrix<T>& m2, Matrix<T>& sum) 
    { 
     ... 
     sumKernel<T> <<< dimGrid, dimBlock >>> (m1,m2); 
     ... 
    } 
} 

template <typename T, typename Implementation<T> > class Matrix { 
    void sum(Matrix<T>& m1, Matrix<T>& m2, Matrix<T>& sum) 
    { 
     Implementation.sumImp(m1, m2, sum); 
    } 
} 

मेजबान कार्यान्वयन, HostMatrixSum.h CPU पर काम करेंगे जब हम होस्ट कोड से मैट्रिक्स का उपयोग करने के लिए आते हैं तो हम मेजबान योग कार्यान्वयन पर टेम्पलेट और किसी भी cuda विनिर्देशों को देखने की आवश्यकता नहीं है:

#include "Matrix.h" 
#include "HostMatrixSum.h" 

Matrix<int, HostMatrixSum> m1 = Matrix<int>(...); 
Matrix<int, HostMatrixSum> m2 = Matrix<int>(...); 
Matrix<int, HostMatrixSum> result; 
Matrix.sum(m1,m2,result); 

और यदि हम GPU पर काम कर रहे हैं हम योग का त्वरित GPU कार्यान्वयन का उपयोग कर सकते हैं:

#include "Matrix.h" 
#include "GpuMatrixSum.cu.h" 

Matrix<int, GpuMatrixSum> m1 = Matrix<int>(...); 
Matrix<int, GpuMatrixSum> m2 = Matrix<int>(...); 
Matrix<int, GpuMatrixSum> result; 
Matrix.sum(m1,m2,result); 

आशा है कि आप के लिए काम करता है! त्रुटि C2059: सिंटेक्स त्रुटि:

+0

मैं कोशिश करने जा रहा हूं। लेकिन साथ ही यह अजीब लगता है कि MatrixKernel.h में, उदाहरण के लिए, कंपाइलर __global__ कीवर्ड के बारे में शिकायत नहीं करता है (जिसका अर्थ केवल एनवीसीसी इसे संकलित कर रहा है, है ना?) एक और बात: यदि आप वास्तव में क्या कहते हैं समस्या है, मैं योग विधि कहां लागू करूं? यदि मैं '# शामिल "Matrix.cu"' Matrix.h "के अंदर '# शामिल नहीं' लिखता हूं, तो एक लिंक त्रुटि होगी, क्योंकि टेम्पलेट को उसी फ़ाइल पर घोषित और परिभाषित किया जाना चाहिए ... – Renan

+0

मुझे लगता है कि आप सही थे , मुझे मैट्रिक्स को टेम्पलेट क्लास के रूप में कार्यान्वित करने के बारे में भूलना पड़ा, क्योंकि ऐसा कोई रास्ता नहीं था जिससे मैं इसे इस तरह से काम कर सकूं। यदि मैं उदाहरण के लिए हेडर पर एक .cu फ़ाइल शामिल करता हूं, तो मैट्रिक्स हेडर समेत प्रत्येक अन्य फ़ाइल में .cu, even .cpp वाले भी शामिल होंगे, जो अनिवार्य रूप से संकलन त्रुटि को जन्म देगी। टेम्पलेट कर्नेल का उपयोग करना ठीक है, लेकिन सी ++ विधियों को बनाने के लिए जो उन्हें टेम्पलेट्स कहते हैं, भी संभव नहीं है क्योंकि मैंने अभी समझाया है। यह सब कुछ के बाद थोड़ा घुमावदार है ... – Renan

+0

क्योंकि MatrixKernel.h केवल एक cu फ़ाइल द्वारा शामिल किया गया है, केवल nvcc में कभी भी शामिल है। यदि आपने होस्ट सीपीपी फ़ाइल में MatrixKernel.h शामिल किया है, तो मुझे संदेह है कि यह खत्म हो जाएगा। मैं cuda विशिष्ट शीर्षलेखों का नाम देता हूं। Cu.h यह स्पष्ट करने के लिए कि यह केवल .cu फ़ाइलों से शामिल करने के लिए है। मैं प्रश्न के हिस्से को 'इसे कैसे करें' के उत्तर पर काम कर रहा हूं - एक सुरुचिपूर्ण समाधान का काम करने की कोशिश कर रहा हूं :) –

1

मैं एक ही समस्या थी '<'

पहले, मैंने पाया एक अच्छा यहाँ सेट अप/ट्यूटोरियल (के लिए दृश्य एक्सप्रेस 2010 और CUDA 4.0): http://www.stevenmarkford.com/installing-nvidia-cuda-with-visual-studio-2010/

How do I start a CUDA app in Visual Studio 2010?

विशेष रूप से, ऐसा है कि * .cu फ़ाइल की संपत्ति को बदलने: और सिंटेक्स त्रुटि समस्या को हल करने, इस प्रकार इसे हल करने के लिए "CUDA C/C++"

सेट किया गया है

अंततः मेरे लिए काम किया।

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