رفتن به مطلب
جامعه‌ی برنامه‌نویسان مُدرن ایران
کامبیز اسدزاده

معرفی و راه‌اندازی OpenCL

پست های پیشنهاد شده

کتابخانه‌ی اوپن سی اِل مخفف Open Computing Language بستری برای برنامه‌هایی که قرار است بر سکو‌های ناهمگن یا تکیه بر پردازنده‌های مرکزی و پردازنده‌های گرافیکی و سایر پردازنده‌ها اجرا شوند. این کتابخانه دارای یک زبان بر پایه‌ی C99 و C++11 برای نوشتن کرنل‌ها و همچنین رابط‌های برنامه‌نویسی برای تعریف و پس از کنترل بستر استفاده شوند را دارا است.

این کتابخانه چند‌پردازندگی را با استفاده از روش‌های وظیفه محور (Task-Based) و داده محور (Data-Based) پشتیبانی می‌کند. اوپن سی اِل توسط هر دو شرکت AMD/ATI و Nvidia پذیرفته شده است. در طراحی اوپن سی اِل، مقدار زیادی از رابطه‌های پردازشی با Cuda و رقیب آن، مایکروسافت دایرکت کامپیوت (Direct-Compute) به اشتراک گذاشته شده است. پیاده سازی‌های مربوطه از طرف Altea, AMD, Apple صورت گرفته شده است که در این میان OpenCL همراه با OpenGL به نفع Metal2 منسوخ شده اند. همچنین IBM, Imagination, Intel, Nvidia, Qualcomm, Samsung, Vivante, Xilinx و Ziilabs آن را پذیرفته‌اند.

این کتابخانه یکی از قدرتمند ترین پلتفرم‌های موجود در بازار در مقابل DirectX می‌باشد گه از سوی کمیته‌ی Khronos Group اعلام شده است که پا به پای DirectX ه فعالیتش ادامه می‌دهد.  جالب است بدانید نسخه‌های جدید این کتابخانه با قدرت بسیار زیادی بر روی PS4 و PS4 Pro استفاده می‌شوند. از آنجایی که PS4 از معماری GCN استفاده می‌کند، قابلیت پشتیبانی از DiectX 12 نیز برای آن فراهم شده است.

 

بهتر است بدانید توسعه اصلی این پلتفرم توسط اپل انجام شده است که در حال حاضر توسط کمیته‌ی Khronos Group اداره می‌شود که بر روی طیف وسیعی از سخت افزار‌های روز و کارت گرافیکی‌های محتلف گرفته تا پردازنده‌های موجود پشتیبانی می‌شود. قدرت روز افزون اوپن سی اِل در حال افزایش است و شاید اگر قدرت و سرمایه‌ی مایکروسافت نبود، OpenCL سلطان بی چون و چرای بازار می‌شد.

 

کودا با وجود انکار انویدیا، فریم ورکی است اختصاصی که در بسیاری از محصولات مورد استفاده قرار می‌گیرد. انویدیا تلاش می‌کند رقبایش را به استفاده از کودا وادار کند، اما تلاشش نتیجه بخش نبوده و می‌بینم که از این فریم ورک بیشتر در توسعه محصولات خودش استفاده می‌شود. از طرفی می‌توان ادعا کرد که Direct Compute هم اختصای است. چون فقط بر روی ویندوز و دایرکت اِکس ۱۱ به بالا اجرا می‌شود. اما OpenCL منبع باز است و بسیاری از شرکت‌های بزرک از جمله Nvidia از آن پشتیبانی می‌کنند.

 

جهت نصب و راه اندازی این کتابخانه برای پردازنده‌های Intel به این بخش مراجعه کرده و نسخه‌ی Amd را در این بخش و برای Nvidia از این صفحه دریافت و استخراج نمایید.

این کتابخانه در قالب SDK شامل include و lib تحت تو معماری x86 و x64 می‌باشد که باید در محیط توسعه‌ی نرم‌افزاری خود آن را معرفی کنید. در محیط Qt Creator طبق آموزش‌های قبل اقدام کنید.

 

با توجه به اینکه ما SDK مربوطه را در مسیر C:/IntelOpenCL/sdk استخراج کرده‌ایم، کُد فایل .pro به صورت زیر خواهد بود:

LIBS += -L$$PWD/../../../../../Intel/OpenCL/sdk/lib/x86/ -lOpenCL

INCLUDEPATH += $$PWD/../../../../../Intel/OpenCL/sdk/include
DEPENDPATH += $$PWD/../../../../../Intel/OpenCL/sdk/include

جهت آزمایش عملکرد کتابخانه توجه داشته باشید که فایل‌های هدر در پلتفرم macOS در پوشه‌ی OpenCL و در محیط‌های ویندوز و لینوکس در مسیر CL موجود می‌باشند.

#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/cl.hpp>
#endif

در ادامه کد زیر نتیجه‌ی جمع دو آرایه با یکدیگر را تحت OpenCL اجرا خواهد گرد:

#include <iostream>
#include <vector>

#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/cl.hpp>
#include <CL/opencl.h>
#endif

using namespace std;

int main(){
    //get all platforms (drivers)
    std::vector<cl::Platform> all_platforms;
    cl::Platform::get(&all_platforms);
    if(all_platforms.size()==0){
        std::cout<<" No platforms found. Check OpenCL installation!\n";
        exit(1);
    }
    cl::Platform default_platform=all_platforms[0];
    std::cout << "Using platform: "<<default_platform.getInfo<CL_PLATFORM_NAME>()<<"\n";

    //get default device of the default platform
    std::vector<cl::Device> all_devices;
    default_platform.getDevices(CL_DEVICE_TYPE_ALL, &all_devices);
    if(all_devices.size()==0){
        std::cout<<" No devices found. Check OpenCL installation!\n";
        exit(1);
    }
    cl::Device default_device=all_devices[0];
    std::cout<< "Using device: "<<default_device.getInfo<CL_DEVICE_NAME>()<<"\n";


    cl::Context context({default_device});

    cl::Program::Sources sources;

    // kernel calculates for each element C=A+B
    std::string kernel_code=
            "   void kernel simple_add(global const int* A, global const int* B, global int* C){       "
            "       C[get_global_id(0)]=A[get_global_id(0)]+B[get_global_id(0)];                 "
            "   }                                                                               ";
    sources.push_back({kernel_code.c_str(),kernel_code.length()});

    cl::Program program(context,sources);
    if(program.build({default_device})!=CL_SUCCESS){
        std::cout<<" Error building: "<<program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(default_device)<<"\n";
        exit(1);
    }


    // create buffers on the device
    cl::Buffer buffer_A(context,CL_MEM_READ_WRITE,sizeof(int)*10);
    cl::Buffer buffer_B(context,CL_MEM_READ_WRITE,sizeof(int)*10);
    cl::Buffer buffer_C(context,CL_MEM_READ_WRITE,sizeof(int)*10);

    int A[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int B[] = {0, 1, 2, 0, 1, 2, 0, 1, 2, 0};

    //create queue to which we will push commands for the device.
    cl::CommandQueue queue(context,default_device);

    //write arrays A and B to the device
    queue.enqueueWriteBuffer(buffer_A,CL_TRUE,0,sizeof(int)*10,A);
    queue.enqueueWriteBuffer(buffer_B,CL_TRUE,0,sizeof(int)*10,B);


    //run the kernel
    //alternative way to run the kernel
    cl::Kernel kernel_add=cl::Kernel(program,"simple_add");
    kernel_add.setArg(0,buffer_A);
    kernel_add.setArg(1,buffer_B);
    kernel_add.setArg(2,buffer_C);
    queue.enqueueNDRangeKernel(kernel_add,cl::NullRange,cl::NDRange(10),cl::NullRange);
    queue.finish();

    int C[10];
    //read result C from the device to array C
    queue.enqueueReadBuffer(buffer_C,CL_TRUE,0,sizeof(int)*10,C);

    std::cout<<" result: \n";
    for(int i=0;i<10;i++){
        std::cout<<C[i]<<" ";
    }

    return 0;
}

نتیجه خروجی جمع دو آرایه با یکدیگر و همچنین شناسایی پلتفرم‌های قابل پشتیبانی در OpenCL

Using platform: Intel(R) OpenCL
Using device: Intel(R) HD Graphics 4400
result: 02435768109

 

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر
مهمان
این موضوع برای عدم ارسال قفل گردیده است.

  • کاربران آنلاین در این صفحه   0 کاربر

    هیچ کاربر عضوی،در حال مشاهده این صفحه نیست.

×