ERROR: clBuildProgram(CL_BUILD_PROGRAM_FAILURE)

ERROR: clBuildProgram(CL_BUILD_PROGRAM_FAILURE)

本文关键字:BUILD PROGRAM FAILURE CL clBuildProgram ERROR      更新时间:2023-10-16

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

从.cl文件加载时,我遇到了构建失败。然而,当我从constchar*内核加载时,它是有效的。

// 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 1n";
}
catch (cl::Error err) {
Rcpp::Rcout << "Exceptionn";
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 2n";
}
catch (cl::Error err) {
Rcpp::Rcout << "Exceptionn";
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 3n";
}
catch (cl::Error err) {
Rcpp::Rcout << "Exceptionn";
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() {};

测试_内核.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];
}
}

测试_内核.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安装测试示例.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 1n";
}
catch (cl::Error err) {
std::cout << "Exceptionn";
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 2n";
}
catch (cl::Error err) {
std::cout << "Exceptionn";
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 3n";
}
catch (cl::Error err) {
std::cout << "Exceptionn";
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 1n";
}
catch (cl::Error err) {
Rcpp::Rcout << "Exceptionn";
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 2n";
}
catch (cl::Error err) {
Rcpp::Rcout << "Exceptionn";
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 3n";
}
catch (cl::Error err) {
Rcpp::Rcout << "Exceptionn";
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()