2010-03-11 20 views
10

में कस्टम प्रकार क्या ओपनसीएल कर्नेल जैसे जीएमपी प्रकार (mpz_t, mpq_t, ...) में कस्टम प्रकारों का उपयोग करना संभव है? clBuildProgram की (विकल्पों) चौथे पैरामीटर के लिए अलग अलग तर्क जोड़करओपनसीएल कर्नेल

 
#include <gmp.h> 
__kernel square(
    __global mpz_t* input, 
    __global mpz_t number, 
    __global int* output, 
    const unsigned int count) 
{ 
    int i = get_global_id(0); 
    if(i < count) 
     output[i] = mpz_divisible_p(number,input[i]); 
} 

शायद:

कुछ इस तरह (इस गिरी बस #include <gmp.h> की वजह से निर्माण नहीं करता है) करवाने के लिए?

या ओपनसीएल में पहले से ही ऐसे प्रकार हैं जो बड़े नंबरों को संभाल सकते हैं?

उत्तर

4

आप कस्टम प्रकारों का उपयोग कर सकते हैं लेकिन कर्नेल में उपयोग की जाने वाली किसी भी चीज़ को विशेष रूप से ओपनसीएल के लिए लिखा जाना चाहिए। FP128

संपादित करें:: NVIDIA के CUDA एसडीके है एक जटिल संख्या डेटा प्रकार, यह आदर्श है, लेकिन आप कैसे वे इसके बारे में जाने पर कुछ विचार दे सकते हैं, OpenCL समान होना चाहिए कि कैसे बड़े सटीक संख्या को लागू करने के लिए शायद इस वेबसाइट की जाँच करें ।

18

आम तौर पर आप ओपनसीएल प्रोग्राम में किसी भी प्रकार का उपयोग कर सकते हैं। लेकिन चूंकि आयात काम नहीं करते हैं, इसलिए आपको उन्हें एक ही कार्यक्रम में फिर से परिभाषित करना होगा। उदाहरण के लिए:

typedef char my_char[8]; 

typedef struct tag_my_struct 
{ 
    long int  id; 
    my_char   chars[2]; 
    int    numerics[4] 
    float   decimals[4]; 
} my_struct; 

__kernel void foo(__global my_struct * input, 
        __global int * output) 
{ 
    int gid = get_global_id(0); 
    output[gid] = input[gid].numerics[3]== 2 ? 1 : 0; 
} 

हालांकि, आपको स्पष्ट रूप से ओपनसीएल के अंदर और बाहर परिभाषाओं को रखने की आवश्यकता है। यह भी सुनिश्चित करें कि प्रकार के डिवाइस और होस्ट दोनों पर समान आकार है (sizeof(my_struct) का उपयोग करके चाल चलाना चाहिए)। कुछ मामलों में मुझे मिलान आकार रखने के लिए परिभाषाओं को समायोजित करना पड़ा।

+4

समान रूप से आकार प्रकार सुनिश्चित करने के लिए यह एक अच्छा विचार है मेजबान कोड (cl_int, cl_long, cl_float2, आदि) में cl_ प्रकार का उपयोग करने *। – dietr

+1

@dietr यह कोड स्पष्टता के साथ भी मदद करता है, जैसा कि "यह चर" कर्नेल को पास करने के लिए है " – Thomas

4

मैंने अपना काम करने के लिए VHristov के उत्तर और आहारकर्ता की टिप्पणी का उपयोग किया। इस कोड को OpenCL 1.2 में मेरे लिए काम करता

गिरी

typedef struct tag_my_struct{ 
    int a; 
    char b; 
}my_struct; 

__kernel void myKernel(__global my_struct *myStruct) 
{ 
    int gid = get_global_id(0); 
    (myStruct+gid)->a = gid; 
    (myStruct+gid)->b = gid + 1; 
} 

मेजबान

typedef struct tag_my_struct{ 
    cl_int a; 
    cl_char b; 
}my_struct; 

void runCode() 
{ 
    cl_int status = 0; 
    my_struct* ms = new my_struct[5]; 

    cl_mem mem = clCreateBuffer(*context, 0, sizeof(my_struct)*5, NULL, &status); 
    clEnqueueWriteBuffer(*queue, mem, CL_TRUE, 0, sizeof(my_struct)*5, &ms, 0, NULL, NULL); 

    status = clSetKernelArg(*kernel, 0, sizeof(ms), &mem); 

    size_t global[] = {5}; 
    status = clEnqueueNDRangeKernel(*queue, *kernel, 1, NULL, global, NULL, 0, NULL, NULL); 

    status = clEnqueueReadBuffer(*queue, mem, CL_TRUE, 0, sizeof(my_struct)*5, ms, 0, NULL, NULL); 

    for(int i = 0; i < 5; i++) 
     cout << (ms+i)->a << " " << (ms+i)->b << endl; 
} 

उत्पादन

0 ☺

1 ☻

2 ♥

3 ♦

4 ♣

+5

' mystruct [gid] .a = के बजाय '(myStruct + gid) -> a = gid;' का उपयोग क्यों करें gid; '। यह मेरे लिए बदसूरत लग रहा है (हालांकि, एक ही परिणाम देगा) – DarkZeros

3

आप कर्नेल फ़ाइल में हेडर फाइल शामिल करना चाहते हैं, तो आप के लिए एक तर्क के रूप -l dir जोड़ सकते हैं clBuildProgram, जहां dir शीर्षलेख फ़ाइलों के साथ निर्देशिका है।

अधिक यहाँ स्पष्टीकरण: include headers to OpenCL .cl file

स्रोत: http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clBuildProgram.html

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