2013-01-24 19 views
5

Tôi đã viết hạt nhân OpenCL trong tệp .cl. Nó cố gắng để #include một số tiêu đề.bao gồm tiêu đề cho tệp OpenCL .cl

Biên dịch của nó không thành công, vì các tệp tiêu đề được bao gồm "không tìm thấy". Tôi biết rằng clBuildProgram có thể thực hiện tùy chọn -I dir, thêm thư mục dir vào danh sách các thư mục cần tìm kiếm các tệp tiêu đề.

Trong diễn đàn trang web khronus bài đăng này http://www.khronos.org/message_boards/viewtopic.php?f=37&t=2535 nói về vấn đề này.

Chúng đề xuất sử dụng clCreateProgramWithSource chỉ định tất cả các nguồn (bao gồm tệp .h).

Tôi có một câu hỏi liên quan đến vấn đề này:

  1. Những lựa chọn tốt hơn? (clBuildProgramclCreateProgramWithSource, như được mô tả ở trên)
  2. Nếu tôi sử dụng clCreateProgramWithSource trình biên dịch biết phải bao gồm những gì? Ý tôi là, nguồn nào viết tắt bao gồm tên tệp?
  3. Nếu tôi sử dụng clBuildProgram và có một số thư mục có tệp bao gồm, làm cách nào để chỉ định chúng?

Trả lời

5

OpenCL yêu cầu bạn sử dụng clCreateProgramWithSource() Tiếp theo clBuildProgram().

ClCreateProgramWithSource() tạo và trả về đối tượng cl_program.

Đối tượng cl_program được nhập vào clBuildProgram().

clBuildProgram() cho phép bạn chỉ định tùy chọn trình biên dịch bao gồm tệp bao gồm thư mục. Trong trường hợp của bạn, đối với tệp tiêu đề bao gồm, nó sẽ là một cái gì đó giống như chuỗi:

-I myincludedir1 -I myincludedir2 ... 

Trình biên dịch sử dụng là trình biên dịch OpenCL nội trong OpenCL SDK bạn đang sử dụng. Vì vậy, nếu bạn đang sử dụng SDK AMD của AMD, thì Trình biên dịch AMD OpenCL là một phần của OpenCL SDK sẽ được sử dụng. Tương tự như vậy đối với Nvidia hoặc Intel.

Điều quan trọng là kiểm tra mã trạng thái OpenCL cho các cuộc gọi chức năng của ALL OpenCL. Điều này là bắt buộc đối với clCreateProgramWithSource()clBuildProrgam() để nhận mọi lỗi hoặc thông báo của trình biên dịch. Có một mã bit hoàn toàn khác để viết để nhận được kích thước của thư và sau đó truy xuất thư.

2

Trình điều khiển thiết bị Nvidia OpenCL có lỗi khi sử dụng -Tôi với số lượng bao gồm và độ dài mã nhất định. AMD và Intel không có vấn đề này. Giải pháp của tôi là thay thế tất cả các tệp .cl thành một tệp lớn khi chạy.Điểm bất lợi của điều này là trong việc gỡ lỗi mã số dòng của lỗi tương ứng với tệp .cl nối tiếp và không phải trong tệp .cl riêng lẻ.

Tôi nghi ngờ Nvidia sẽ sửa lỗi này. Họ không quan tâm đến OpenCL nhiều nữa.

+0

AMD APP có vấn đề với -Tôi quá từ kinh nghiệm của tôi (nó chỉ đơn giản không hoạt động), mặc dù Intel xử lý nó một cách hoàn hảo. – Thomas

+0

Thật thú vị. Tôi mặc dù tôi đã thử nghiệm nó trên CPU. Tôi không có GPU AMD nên tôi không thể thử nghiệm trên GPU. Có lẽ đó là vấn đề về GPU và CPU? –

+0

Không, tôi đã thử nó dưới cả hai thiết bị trong Windows, trình biên dịch đơn giản dường như không xử lý các đường dẫn tương đối bao gồm. Về cơ bản, tôi có "-I cl /" trong dòng lệnh trình biên dịch của mình, và các hạt nhân của tôi được sắp xếp gọn gàng trong thư mục cl /, và trong khi nó hoạt động tốt dưới Intel/Linux, AMD sẽ không có bất kỳ thứ gì. những gì tôi thử và giải pháp duy nhất tôi tìm thấy là mã hóa đường dẫn tuyệt đối * của mỗi tệp .cl trong #include chỉ thị hoặc thêm cl/thư mục của tôi vào hệ thống $ PATH. Nó có thể là cài đặt của tôi bị hỏng mặc dù, tôi không duy trì hệ thống Windows của tôi nhiều như Linux của tôi. – Thomas

0

Có một thủ thuật bẩn khác: bạn nên mô phỏng bao gồm chính mình (ví dụ: một cái gì đó như hợp nhất thủ công). Nó không phải là rất rõ ràng cho mã hóa, nhưng nó hoạt động nếu trình biên dịch OpenCL của bạn không hỗ trợ (hoặc hỗ trợ không chính xác) -I chỉ thị. Cách tiếp cận này không hoàn hảo (ví dụ, bạn làm mất cú pháp tô sáng), nhưng có thể giúp cho các trình biên dịch OpenCL cũ hoặc lỗi.

nhỏ ví dụ đơn giản về khả năng này:

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)