c++ - 错误 : clBuildProgram(CL_BUILD_PROGRAM_FAILURE)

标签 c++ opencl rcpp

我正在使用 C++、Rcpp 和 OpenCL 为 R 开发一个包。

我在从 .cl 文件加载时遇到构建失败。 但是,当我从 const char * 内核加载时它可以工作。

// code build fails 
  std::ifstream sourceFile("Kernels.cl");
    std::string sourceCode( std::istreambuf_iterator<char(sourceFile), (std::istreambuf_iterator<char>()));

cl::Program::Sources  source(1, std::make_pair(sourceCode.c_str(), sourceCode.length()));  
// code build passes

cl::Program::Sources  source(1, std::make_pair(vadd, strlen(vadd)));
cl::Program program2 = cl::Program(context,source);

在 rcpp 和 OpenCL 之间加载 OpenCL 是否有问题?

最小示例(所有处理 R 包): 测试.cpp

#define __CL_ENABLE_EXCEPTIONS
/* Modified from https://github.com/HandsOnOpenCL/Exercises-Solutions; Simon McIntosh-Smith and Tom Deakin from the University of Bristol*/

#include < /Users/5kd/Documents/TestExample/src/err_code.h >  
#include < /Users/5kd/Documents/TestExample/src/cl.hpp >
#include < vector >
#include < stdio >
#include < cstdlib >
#include < string >
#include < iostream >
#include < stream >
#include < /Users/5kd/Documents/TestExample/src/Test_Kernels.h >
#ifndef DEVICE
#define DEVICE CL_DEVICE_TYPE_DEFAULT
#endif 


void TestVal1(){
        try{
                cl::Context context(DEVICE);
                cl_int err;
                std::ifstream sourceFile("Test_Kernels.cl");
                std::string sourceCode( std::istreambuf_iterator<char>(sourceFile), (std::istreambuf_iterator<char>()));
                cl::Program::Sources  source1(1, std::make_pair(sourceCode.c_str(), sourceCode.length()));
                cl::Program program1(context,source1 );
                std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
                program1.build(devices);
                Rcpp::Rcout << "pass 1\n";
        }
        catch (cl::Error err) {
                Rcpp::Rcout << "Exception\n";
                 Rcpp::Rcout << "ERROR: "<< err.what() << "("  << err_code(err.err()) << ")"  << "\n";
    }
};
void TestVal2(){
        try{
                cl::Context context(DEVICE);
                cl_int err;
                std::ifstream sourceFile2("vadd.cl");
                std::string sourceCode2( std::istreambuf_iterator<char>(sourceFile2), (std::istreambuf_iterator<char>()));
                cl::Program::Sources  source2(1, std::make_pair(sourceCode2.c_str(), sourceCode2.length()));
                cl::Program program2(context,source2 );
                std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
                program2.build(devices);
                Rcpp::Rcout << "pass 2\n";
        }
        catch (cl::Error err) {
                Rcpp::Rcout << "Exception\n";
                 Rcpp::Rcout << "ERROR: "<< err.what() << "("  << err_code(err.err()) << ")"  << "\n";
    }
};
void TestVal3(){
        try{
                cl::Context context(DEVICE);
                cl_int err;
                cl::Program::Sources source3(1, std::make_pair(VAdd, strlen(VAdd)));
                cl::Program program3(context,source3 );
                std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
                program3.build(devices);
                Rcpp::Rcout << "pass 3\n";
         }
        catch (cl::Error err) {
                Rcpp::Rcout << "Exception\n";
                 Rcpp::Rcout << "ERROR: "<< err.what() << "("  << err_code(err.err()) << ")"  << "\n";
    }
};
SEXP solve_(){
  Test opt;
  int soln = opt.region(5);
  return List::create();
}

int Test::region(int p){
  TestVal1();
  TestVal2();
  TestVal3();

  return(p);
};

Test::Test() {};

Test_Kernels.cl

kernel void vadd2( global const float *a , global const float * b ,global float *c ){

        int index= get_global_id(0);
        c]index] = a[index] + b[index];
}

vadd.cl

__kernel void vadd(
   __global float* a,
   __global float* b,
   __global float* c,
   const unsigned int count)
{
   int i = get_global_id(0);
   if(i < count)  {
       c[i] = a[i] + b[i];
   }
 }

Test_Kernels.h

const char * VAdd =" kernel void vadd( global const  float *a, global const float *b, global float* c){ int i = get_global_id(0);  c[i] = a[i] + b[i];         }";

    }

RcppExports.cpp

#include <RcppEigen.h>
#include <Rcpp.h>

using namespace Rcpp;

// solve_
SEXP solve_();
RcppExport SEXP TestExample_solve_() {
BEGIN_RCPP
    SEXP __sexp_result;
    {
        Rcpp::RNGScope __rngScope;
        SEXP __result = solve_();
        PROTECT(__sexp_result = Rcpp::wrap(__result));
    }
    UNPROTECT(1);
    return __sexp_result;
END_RCPP
}

RcppExports.R

solve_ <- function() {
    .Call('TestExample_solve_', PACKAGE = 'TestExample')
}

测试解决.R

Test_solve <- function() {

  opt_ <- get_Test_opts()

  .Call('TestExample_solve_', PACKAGE = 'TestExample')
}

主要运行: 测试.R

require(RcppEigen)
require(Matrix)
require(TestExample)


t <- Test_solve()

构建使用: R CMD 构建测试示例 R CMD 安装 TestExample.tar.gz 运行: R -f 测试.R

Output from my run:
> require(RcppEigen)
Loading required package: RcppEigen
> require(Matrix)
Loading required package: Matrix
> require(TestExample)
Loading required package: TestExample
Loading required package: Rcpp
> 
> 
> t <- Test_solve()

Exception
ERROR: clBuildProgram(CL_BUILD_PROGRAM_FAILURE)
Exception
ERROR: clBuildProgram(CL_BUILD_PROGRAM_FAILURE)
pass 3

最佳答案

我没有看到与 Rcpp 的关系,因为我能够使用普通的 C++ 程序重现编译错误:

#define __CL_ENABLE_EXCEPTIONS

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

void TestVal1(){
  try{
    cl::Context context(CL_DEVICE_TYPE_DEFAULT);
    std::ifstream sourceFile("Test_Kernels.cl");
    std::string sourceCode( std::istreambuf_iterator<char>(sourceFile), (std::istreambuf_iterator<char>()));
    cl::Program::Sources  source1(1, std::make_pair(sourceCode.c_str(), sourceCode.length()));
    cl::Program program1(context, source1);
    std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
    program1.build(devices);
    std::cout << "pass 1\n";
  }
  catch (cl::Error err) {
    std::cout << "Exception\n";
    std::cout << "ERROR: "<< err.what() << "("  << err.err() << ")"  << "\n";
  }
}
void TestVal2(){
  try{
    cl::Context context(CL_DEVICE_TYPE_DEFAULT);
    std::ifstream sourceFile("vadd.cl");
    std::string sourceCode( std::istreambuf_iterator<char>(sourceFile), (std::istreambuf_iterator<char>()));
    cl::Program::Sources  source2(1, std::make_pair(sourceCode.c_str(), sourceCode.length()));
    cl::Program program2(context, source2);
    std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
    program2.build(devices);
    std::cout << "pass 2\n";
  }
  catch (cl::Error err) {
    std::cout << "Exception\n";
    std::cout << "ERROR: "<< err.what() << "("  << err.err() << ")"  << "\n";
  }
}
void TestVal3(){
  try{
    cl::Context context(CL_DEVICE_TYPE_DEFAULT);
    const char * VAdd =" kernel void vadd( global const  float *a, global const float *b, global float* c){ int i = get_global_id(0);  c[i] = a[i] + b[i];         }";
    cl::Program::Sources source3(1, std::make_pair(VAdd, strlen(VAdd)));
    cl::Program program3(context, source3);
    std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
    program3.build(devices);
    std::cout << "pass 3\n";
  }
  catch (cl::Error err) {
    std::cout << "Exception\n";
    std::cout << "ERROR: "<< err.what() << "("  << err.err() << ")"  << "\n";
  }
}

int main(){
  TestVal1();
  TestVal2();
  TestVal3();
}

我在这两种情况下都存在内核中的简单语法错误。使用

kernel void vadd2( global const float *a , global const float * b ,global float *c ){

        int index= get_global_id(0);
        c[index] = a[index] + b[index]; // [ instead of ]
}

__kernel void vadd(
   __global float* a,
   __global float* b,
   __global float* c,
   const unsigned int count)
{
   int i = get_global_id(0);
   if(i < count)  {
       c[i] = a[i] + b[i];
   }
} // missing

该示例构建并运行良好,同样来自 Rcpp:

#define __CL_ENABLE_EXCEPTIONS

#include <Rcpp.h>
#include <CL/cl.hpp>
#include <fstream>

void TestVal1(){
  try{
    cl::Context context(CL_DEVICE_TYPE_DEFAULT);
    std::ifstream sourceFile("Test_Kernels.cl");
    std::string sourceCode( std::istreambuf_iterator<char>(sourceFile), (std::istreambuf_iterator<char>()));
    cl::Program::Sources  source1(1, std::make_pair(sourceCode.c_str(), sourceCode.length()));
    cl::Program program1(context,source1 );
    std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
    program1.build(devices);
    Rcpp::Rcout << "pass 1\n";
  }
  catch (cl::Error err) {
    Rcpp::Rcout << "Exception\n";
    Rcpp::Rcout << "ERROR: "<< err.what() << "("  << err.err() << ")"  << "\n";
  }
}
void TestVal2(){
  try{
    cl::Context context(CL_DEVICE_TYPE_DEFAULT);
    std::ifstream sourceFile2("vadd.cl");
    std::string sourceCode2( std::istreambuf_iterator<char>(sourceFile2), (std::istreambuf_iterator<char>()));
    cl::Program::Sources  source2(1, std::make_pair(sourceCode2.c_str(), sourceCode2.length()));
    cl::Program program2(context,source2 );
    std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
    program2.build(devices);
    Rcpp::Rcout << "pass 2\n";
  }
  catch (cl::Error err) {
    Rcpp::Rcout << "Exception\n";
    Rcpp::Rcout << "ERROR: "<< err.what() << "("  << err.err() << ")"  << "\n";
  }
}
void TestVal3(){
  try{
    cl::Context context(CL_DEVICE_TYPE_DEFAULT);
    const char * VAdd =" kernel void vadd( global const  float *a, global const float *b, global float* c){ int i = get_global_id(0);  c[i] = a[i] + b[i];         }";
    cl::Program::Sources source3(1, std::make_pair(VAdd, strlen(VAdd)));
    cl::Program program3(context,source3 );
    std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
    program3.build(devices);
    Rcpp::Rcout << "pass 3\n";
  }
  catch (cl::Error err) {
    Rcpp::Rcout << "Exception\n";
    Rcpp::Rcout << "ERROR: "<< err.what() << "("  << err.err() << ")"  << "\n";
  }
}

// [[Rcpp::export]]
void tests(){
  TestVal1();
  TestVal2();
  TestVal3();
}

要编译和运行这个文件,我使用:

Sys.setenv(PKG_LIBS = "-lOpenCL")
Rcpp::sourceCpp("kernel_test.cpp")
tests()

关于c++ - 错误 : clBuildProgram(CL_BUILD_PROGRAM_FAILURE),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51616518/

相关文章:

c++ - std::tuple 中的括号和大括号有什么区别?

c++ - OpenCL - 从缓冲区读取时出现 CL_INVALID_VALUE

解决 Solaris 上未声明的 -llapack 依赖性问题

c++ - 在 R 中使用外部共享库

c++ - 如果在类模板中使用,fstream 是否会在编译期间通过读写访问硬盘驱动器?

c++ - 定义从类到 double 的转换

c++ - 缩放 CBitmap - 我做错了什么?

unity3d - 如何为 xbox 编写程序并使用其 GPU?

c - OpenCL 原子不执行任何操作

r - 无法加载 Rcpp 包