2013-01-24 49 views
5

में शामिल किया गया है मैंने .cl फ़ाइल में एक ओपनसीएल कर्नेल लिखा है। यह कई शीर्षलेखों को #include करने का प्रयास करता है।में हेडर को ओपनसीएल .cl फ़ाइल

इसका संकलन विफल रहता है, क्योंकि शामिल हेडर फाइलें "नहीं मिली" हैं। मुझे पता है कि clBuildProgram-I dir विकल्प ले सकता है, जो शीर्षलेख फ़ाइलों के लिए खोज की जाने वाली निर्देशिकाओं की सूची में dir निर्देशिका को जोड़ता है।

ख्रोनस साइट फोरम में इस पोस्ट http://www.khronos.org/message_boards/viewtopic.php?f=37&t=2535 इस मुद्दे के बारे में बात करता है।

वे clCreateProgramWithSource का उपयोग करने का प्रस्ताव करते हैं जो सभी स्रोतों (.h फ़ाइलों सहित) निर्दिष्ट करता है।

  1. कौन-सा विकल्प बेहतर है:

    मैंने इस समस्या पर एक प्रश्न हैं? (clBuildProgram बनाम clCreateProgramWithSource, ऊपर वर्णित अनुसार)

  2. यदि मैं clCreateProgramWithSource का उपयोग करता हूं तो संकलक को कैसे शामिल करना है? मेरा मतलब है, कौन सा स्रोत है जिसके लिए फ़ाइल नाम शामिल है?
  3. यदि मैं clBuildProgram का उपयोग करता हूं और फाइलों को शामिल करने वाली कई निर्देशिकाएं हैं, तो मैं उन्हें कैसे निर्दिष्ट करूं?

उत्तर

5

OpenCL आप clCreateProgramWithSource()clBuildProgram() के बाद का उपयोग की आवश्यकता है।

ClCreateProgramWithSource()cl_program ऑब्जेक्ट बनाता है और देता है।

cl_program ऑब्जेक्ट clBuildProgram() में इनपुट है।

clBuildProgram() आपको संकलक विकल्पों को निर्दिष्ट करने की अनुमति देता है जिनमें फ़ाइल निर्देशिका शामिल हैं।

-I myincludedir1 -I myincludedir2 ... 

इस्तेमाल किया संकलक OpenCL एसडीके प्रयोग कर रहे हैं में आंतरिक OpenCL संकलक है: आपके मामले में, के लिए हेडर फाइल भी शामिल है, यह स्ट्रिंग की तरह कुछ हो जाएगा। तो अगर आप एएमडी के एसडीके, का उपयोग कर रहे एएमडी OpenCL संकलक कि उनके OpenCL एसडीके का हिस्सा है इस्तेमाल किया जाएगा। इसी प्रकार एनवीडिया या इंटेल के लिए।

सभी ओपनसीएल फ़ंक्शन कॉल के लिए ओपनसीएल स्थिति कोड की जांच करना महत्वपूर्ण है। clCreateProgramWithSource() और clBuildProrgam() के लिए किसी भी कंपाइलर त्रुटियों या संदेशों को प्राप्त करने के लिए यह अनिवार्य है। संदेशों का आकार प्राप्त करने के लिए लिखने के लिए एक और अन्य बिट कोड है और फिर संदेशों को स्वयं पुनर्प्राप्त करें।

2

एनवीडिया ओपनसीएल डिवाइस ड्राइवरों का उपयोग करते समय एक बग है- I की एक निश्चित संख्या और कोड लंबाई के साथ। एएमडी और इंटेल को यह समस्या नहीं है। मेरे समाधान यह है कि सभी .cl फ़ाइलों को रनटाइम पर एक बड़े में जोड़ दें।इसका नुकसान यह है कि डीबगिंग कोड में त्रुटि की रेखा संख्या concatentated .cl फ़ाइल से मेल खाती है और व्यक्तिगत .cl फ़ाइलों में नहीं।

मुझे संदेह है कि एनवीडिया इसे कभी भी ठीक करेगा। उन्हें ओपनसीएल के बारे में ज्यादा परवाह नहीं है।

+0

एएमडी एपीपी, मैं के साथ समस्याओं भी मेरे अनुभव से (यह बस काम नहीं करता है) है। – Thomas

+0

यह दिलचस्प है। हालांकि मैंने इसे सीपीयू पर परीक्षण किया। मेरे पास एएमडी जीपीयू नहीं है इसलिए मैं इसे GPU पर परीक्षण नहीं कर सकता। शायद यह एक जीपीयू बनाम सीपीयू मुद्दा है? –

+0

नहीं, मैंने विंडोज़ के तहत दोनों उपकरणों के तहत इसे आजमाया, संकलक बस सापेक्ष शामिल पथों को संभालने में प्रतीत नहीं होता है। असल में, मेरे पास मेरे कंपाइलर कमांड लाइन में "-आई क्ल /" है, और मेरे कर्नेल को क्ल/निर्देशिका में व्यवस्थित ढंग से व्यवस्थित किया गया है, और यह इंटेल/लिनक्स के तहत ठीक काम करता है, एएमडी में इसमें से कोई भी नहीं होगा, कोई फर्क नहीं पड़ता मैं क्या कोशिश करता हूं, और मुझे मिला एकमात्र समाधान या तो # .cle निर्देशों में प्रत्येक .cl फ़ाइल के * पूर्ण पथ * को हार्डकोड करना था, या सिस्टम/पथ में मेरा क्ल/फ़ोल्डर जोड़ें। यह मेरी स्थापना हो सकती है जो टूट गई है, हालांकि, मैं अपने विंडोज सिस्टम को जितना ज्यादा अपने लिनक्स के रूप में नहीं रखता हूं। – Thomas

0

एक और गंदे चाल है: आपको स्वयं को शामिल करना चाहिए (i। ई। मैन्युअल समामेलन की तरह कुछ)। यह कोडिंग के लिए बहुत स्पष्ट नहीं है, लेकिन यह तब काम करता है जब आपका ओपनसीएल कंपाइलर -I निर्देशों का समर्थन नहीं करता (या गलत तरीके से समर्थन करता है)। यह दृष्टिकोण सही नहीं है (उदाहरण के लिए, आप सिंटैक्स हाइलाइटिंग खो देते हैं), लेकिन पुरानी या छोटी ओपनसीएल कंपाइलर्स के लिए मदद कर सकते हैं।

इस संभावना के छोटे सरल उदाहरण: हालांकि इंटेल यह पूरी तरह संभालती

std::string load_file(const std::string &file_name, int max_size = 0x100000) 
{ 
    FILE *fp = fopen(file_name.c_str(), "rb"); 
    if (!fp) 
    { 
     // print some error or throw exception here 
     return std::string(); 
    } 
    char *source = new char[max_size]; 
    size_t source_size = fread(source, 1, max_size, fp); 
    fclose(fp); 
    if (!source_size) 
    { 
     delete[] source; 
     // print some error or throw exception here 
     return std::string(); 
    } 
    std::string result(source); 
    delete[] source; 
    return result; 
} 

// errors checks are omitted for simplification 
std::string full_source = load_file("header.h"); 
full_source += load_file("source.cl"); 

const char *source_ptr = full_source.c_str(); 
size_t source_size = full_source.size(); 
cl_int_status = CL_SUCCESS; 
cl_program program = clCreateProgramWithSource(context, 1, 
     (const char **)&source_ptr, (const size_t *)&source_size, &ret); 
// check status for CL_SUCCESS here 
// now you have your program (include + source)