错误:clBuildProgram(CL_BUILD_PROGRAM_FAILURE)

时间:2018-07-31 15:03:44

标签: 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包):     Test.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')
}

Test_solve.R

Test_solve <- function() {

  opt_ <- get_Test_opts()

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

主要运行:      Test.R

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


t <- Test_solve()

构建使用: R CMD构建TestExample R CMD安装TestExample.tar.gz 跑: R -f Test.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

1 个答案:

答案 0 :(得分:1)

我看不到与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()