2013-04-06 39 views
5

Tôi cố gắng để sử dụng OpenCL C++ wrapper API cho các chương trình sau đây:OpenCL 1.2 C++ Wrapper - tài liệu tham khảo không xác định để clReleaseDevice

#define __CL_ENABLE_EXCEPTIONS 


#include <CL/cl.hpp> 
#include <cstdio> 
#include <cstdlib> 
#include <iostream> 

const char helloStr [] = "__kernel void " 
          "hello(void) " 
          "{ " 
          " " 
          "} "; 

int 
main(void) 
{ 
    cl_int err = CL_SUCCESS; 
    try { 

     std::vector<cl::Platform> platforms; 
     cl::Platform::get(&platforms); 
     if (platforms.size() == 0) { 
      std::cout << "Platform size 0\n"; 
      return -1; 
     } 

     cl_context_properties properties[] = 
     { CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0}; 
     cl::Context context(CL_DEVICE_TYPE_CPU, properties); 

     std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>(); 

     cl::Program::Sources source(1, 
      std::make_pair(helloStr,strlen(helloStr))); 
     cl::Program program_ = cl::Program(context, source); 
     program_.build(devices); 

     cl::Kernel kernel(program_, "hello", &err); 

     cl::Event event; 
     cl::CommandQueue queue(context, devices[0], 0, &err); 
     queue.enqueueNDRangeKernel(
      kernel, 
      cl::NullRange, 
      cl::NDRange(4,4), 
      cl::NullRange, 
      NULL, 
      &event); 

     event.wait(); 
    } 
    catch (cl::Error err) { 
     std::cerr 
      << "ERROR: " 
      << err.what() 
      << "(" 
      << err.err() 
      << ")" 
      << std::endl; 
    } 

    return EXIT_SUCCESS; 
} 

tôi sử dụng tập tin kernel cùng từ đó bài đăng blog, mà dù sao không phải là vấn đề vì tôi không thể có được quá trình biên dịch.

Tôi đang biên soạn chương trình với lệnh sau:

g++ example.cpp -o example -l OpenCL 

và tôi nhận được thông báo lỗi sau: thứ

/tmp/ccbUf7dB.o: In function `cl::detail::ReferenceHandler<_cl_device_id*>::release(_cl_device_id*)': 
example.cpp:(.text._ZN2cl6detail16ReferenceHandlerIP13_cl_device_idE7releaseES3_[_ZN2cl6detail16ReferenceHandlerIP13_cl_device_idE7releaseES3_]+0x14): undefined reference to `clReleaseDevice' 
collect2: error: ld returned 1 exit status 

Tôi đã đọc về clReleaseDevice không làm việc cho các thiết bị di sản (xem ví dụ this question), nhưng card đồ họa của tôi là khá gần đây (NVidia GTX 660 Ti, hỗ trợ OpenCL 1.2). Tôi có thể đi từ đâu?

Tôi đang chạy ứng dụng này trên Ubuntu 13.04 x64 với nvidia-opencl-dev và opencl-headers được cài đặt từ kho ubuntu.

+0

Thử thêm '-DCL_USE_DEPRECATED_OPENCL_1_1_APIS' vào tệp makefile của bạn. – Thomas

+0

Không thay đổi bất cứ điều gì .. Tôi duyệt tệp CL/cl.hpp và mã đi kèm với xác định này dường như không liên quan đến lệnh gọi hàm này. – levesque

+0

Điều gì sẽ xảy ra nếu bạn đặt '#define CL_USE_DEPRECATED_OPENCL_1_1_APIS; #include "CL/cl.h"; #undef CL_VERSION_1_2; #define __CL_ENABLE_EXCEPTIONS; #include "cl-1.2.hpp" 'Điều đó có hiệu quả không? Tôi đã thử nó trên Amazon AWS nvidia, với ubuntu 14.04, và có vẻ làm việc ok? –

Trả lời

10

Nguyên nhân gốc

Vấn đề là thư viện OpenCL mà bạn đang liên kết không hỗ trợ OpenCL 1.2. Nói chung, cho đến khi triển khai OpenCL hỗ trợ phiên bản bạn muốn sử dụng sẽ có sẵn cho một nền tảng cụ thể, bạn sẽ gặp phải vấn đề này khi liên kết với thư viện chia sẻ OpenCL được cung cấp cùng với nó. Có hai giải pháp:

  • Tải xuống phiên bản cl.hpp từ Khronos khớp với phiên bản OpenCL do phần cứng bạn chọn cung cấp và tiếp tục sử dụng thư viện do nhà sản xuất thiết bị của bạn cung cấp.
  • Liên kết với thư viện chia sẻ OpenCL triển khai chuẩn OpenCL mới nhất, nhưng viết nhiều đường dẫn mã - một cho mỗi phiên bản OpenCL, đảm bảo rằng mỗi đường dẫn mã chỉ sử dụng các chức năng OpenCL được hỗ trợ bởi phiên bản đó. Tuyến đường này khó hơn và tôi không biết làm thế nào bạn có thể làm điều đó với trình bao bọc C++. Nếu bạn cố gắng gọi hàm OpenCL 1.2 trên nền tảng không hỗ trợ OpenCL 1.2, bạn sẽ nhận được một segfault, đó là lý do tại sao các đường dẫn mã khác nhau là cần thiết.

Nvidia cụ

Nvidia đã rất chậm trong việc cung cấp 1.2 hỗ trợ OpenCL. Do đó, thư viện OpenCL của họ không cung cấp các chức năng OpenCL 1.2 mà trình liên kết đang tìm kiếm, dẫn đến lỗi.

Vào cuối tháng 5 năm 2015, Nvidia đã phát hành các trình điều khiển hỗ trợ OpenCL 1.2, xem các bình luận của Z Boson bên dưới. Cập nhật trình điều khiển của bạn nên giải quyết lỗi trình liên kết. Thẻ GeForce GTX 6xx trở lên (ngoại trừ việc đổi tên các thế hệ trước) hỗ trợ OpenCL 1.2. Bạn có thể kiểm tra số conformant products list trên trang web Khronos OpenCL để đảm bảo. GTX 660 Ti được liệt kê để bạn may mắn.

+0

Tôi nhận được hỗ trợ OpenCL 1.2 từ một chút googling, nhưng có vẻ như tôi đã sai! Cảm ơn. – levesque

+0

Cảm ơn vì điều này - chỉ gặp phải vấn đề tương tự! –

+2

Nvidia hiện hỗ trợ OpenCL 1.2 trên Linux và Windows http://www.phoronix.com/scan.php?page=article&item=amdnv-phoronix-11&num=5 "Gần đây, NVIDIA cũng đã thêm hỗ trợ OpenCL 1.2 cho trình điều khiển Linux độc quyền của họ . " và https://devtalk.nvidia.com/default/topic/540773/opencl-1-2-support-in-nvidia-drivers/ "Có, trình điều khiển Win10 mới nhất từ ​​NVIDIA 352.84 & 352.63 bao gồm hỗ trợ OpenCL 1.2". –

0

Vâng. Tôi chưa bao giờ thấy OpenCL 1.2 trên các thiết bị Nvidia. Biên dịch điều này trên hệ thống của bạn và xem "Phiên bản OpenCL C":

#include <iostream> 
#include <vector> 
#include <CL/cl.hpp> 

int main() { 

    // Get the platforms 
    std::vector<cl::Platform> platforms; 
    cl::Platform::get(&platforms); 

    // Loop over the number of platforms 
    for (size_t i = 0; i < platforms.size(); ++i) { 

     // Display the platform information 
     std::cout << "Platform " << i+1 << ": " 
          << platforms[i].getInfo<CL_PLATFORM_NAME>() 
     << "\n----------------------------------------------" 
     << "\nVendor : " << platforms[i].getInfo<CL_PLATFORM_VENDOR>() 
     << "\nVersion : " << platforms[i].getInfo<CL_PLATFORM_VERSION>(); 

     // Get the devices on the current platform 
     std::vector <cl::Device> devices; 
     platforms[i].getDevices(CL_DEVICE_TYPE_ALL , & devices); 

     // Loop over the devices 
     std::cout << "\n----------------------------------------------\n"; 
     for (size_t j = 0; j < devices.size(); ++j) { 

      // Display the device information 
      std::cout 
      << "\n Device " << j+1 << ": " 
      <<   devices[j].getInfo<CL_DEVICE_NAME>() 
      << "\n\t Device Version  : " 
      <<   devices[j].getInfo<CL_DEVICE_VERSION>() 
      << "\n\t OpenCL C Version : " 
      <<   devices[j].getInfo<CL_DEVICE_OPENCL_C_VERSION>() 
      << "\n\t Compute Units  : " 
      <<   devices[j].getInfo<CL_DEVICE_MAX_COMPUTE_UNITS>() 
      << "\n\t Max Work Group Size: " 
      <<   devices[j].getInfo<CL_DEVICE_MAX_WORK_GROUP_SIZE>() 
      << "\n\t Clock Frequency : " 
      <<   devices[j].getInfo<CL_DEVICE_MAX_CLOCK_FREQUENCY>() 
      << "\n\t Local Memory Size : " 
      <<   devices[j].getInfo<CL_DEVICE_LOCAL_MEM_SIZE>() 
      << "\n\t Global Memory Size : " 
      <<   devices[j].getInfo<CL_DEVICE_GLOBAL_MEM_SIZE>(); 

      // Check if the device supports double precision 
      std::string str = devices[j].getInfo<CL_DEVICE_EXTENSIONS>(); 
      size_t found = str.find("cl_khr_fp64"); 
      std::cout << "\n\t Double Precision : "; 
      if (found != std::string::npos){ std::cout << "yes\n"; } 
      else {        std::cout << "no\n"; } 
     } 
     std::cout << "\n----------------------------------------------\n"; 
    } 
// std::cin.ignore(); 
    return 0; 
} 
Các vấn đề liên quan