0

I am working on a package for R using C++, Rcpp and OpenCL.

I am having a build failure when loading from a .cl file. However, when I load from a const char * kernel it works.

// 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);

Is there an issue with loading OpenCL between rcpp and OpenCL?

Minimal Example( all dealing with an R package): 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')
}

Main running: Test.R

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


t <- Test_solve()

Build Using: R CMD build TestExample R CMD INSTALL TestExample.tar.gz Run: 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
8
  • Can you bring this as a minimal example to rcpp-devel? Charles Determan may be able to help you, not sure he'll spot it here. I only played with OpenCL indirectly via (Rcpp)ArrayFire. Commented Jul 31, 2018 at 15:20
  • I can try and bring a minimal example but most what I am working on can't be shown. Commented Jul 31, 2018 at 15:28
  • 2
    Understood, many of us are in a similar situation. That does not stop most of us from being able to mock the full issue with a small yet salient reproducible example. Commented Jul 31, 2018 at 15:32
  • Thank you so much for fast replay! Commented Jul 31, 2018 at 15:49
  • A minimal reproducible example would be useful. Right now the only people able to answer your question are those that have encountered it before. Those that are willing to investigate are left out. Commented Aug 1, 2018 at 15:22

1 Answer 1

1

I don't see an relation to Rcpp, since I am able to reproduce the compilation errors using a plain C++ program:

#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();
}

I both cases there where simple syntax errors in the kernels. Using

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 ]
}

and

__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

the example builds and runs fine, also from 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();
}

To compile and run this file I use:

Sys.setenv(PKG_LIBS = "-lOpenCL")
Rcpp::sourceCpp("kernel_test.cpp")
tests()
Sign up to request clarification or add additional context in comments.

8 Comments

The example case is broken down not to use the Rcpp info that is need, but the structure is the same. Will update the add kernel ( as it does the the last } ) int my case. also added the fix for the vadd2 kernel. Both still fail.
Most of the all of the code relate to Rcpp I can not show.
@Kirsten I have added my working Rcpp code. Without an example that demonstrates the error we won't be able to help you.
So its a non reproducible error for you. With the example I gave. However, it is a example of the error on my end that. Were you using gnu compilers?
@Kirsten I am using GCC 6.3.0 on Debian stable together with R 3.5.1 and Rcpp 0.12.18. What du you use? Do my examples (plain C++ and Rcpp) work for you?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.