Hi,

I am trying to wrap around OpenCL.
But I am running into some problems when I try to return pointers to
R. Later I want to be able to use these pointers in other c functions.
As an example I have the following code:

#include "createContext.h"
#include <CL/opencl.h>
#include <Rcpp.h>

// Stuff to expose the cl_platform_id to R
static void cl_platform_idObjFinalizer(SEXP ref){
        if(TYPEOF(ref) == EXTPTRSXP){
                cl_platform_id *o = static_cast<cl_platform_id*> 
(R_ExternalPtrAddr(ref));
                if (o) delete o;
        }
}

SEXP cl_platform_id2EXP(cl_platform_id *o){
        SEXP xp = R_MakeExternalPtr(o, R_NilValue, R_NilValue);
        R_RegisterCFinalizerEx(xp, cl_platform_idObjFinalizer, TRUE);
        return xp;
}

cl_platform_id *SEXP2cl_platform_id(SEXP o){
        if(TYPEOF(o) != EXTPTRSXP)
                Rf_error("invalid object");
        return (cl_platform_id*) R_ExternalPtrAddr(o);
}

This bit I have found posted on this mailing list earlier.
This is to expose a pointer to a cl_platform_id object in memory (and
this should also take care of the clean up).

Now I have the following method to get a list of platform_ids:

SEXP getPlatformIDs(){
        //returns a list of platform ids
        cl_uint num_platforms = 0;
        clGetPlatformIDs(0, 0, &num_platforms);
        std::vector<cl_platform_id> platforms(num_platforms);
        clGetPlatformIDs(num_platforms, platforms.empty() ? NULL :
&platforms.front(), &num_platforms);
        //for each platform in platforms add its pointer to the return list
        Rcpp::List result(platforms.size());
        for (int i=0; i<platforms.size(); i++){
        cl_platform_id tempPlatformID = platforms[i];
                result[i] = cl_platform_id2EXP(&tempPlatformID);
        }
        return result;
}

And I want to get the name of the platform as follows:

SEXP getPlatformName(SEXP sPlatformID){
    char cBuffer[1024];
    cl_platform_id platformID = *SEXP2cl_platform_id(sPlatformID);
    clGetPlatformInfo (platformID, CL_PLATFORM_NAME, sizeof(cBuffer),
cBuffer, NULL);
    Rcpp::CharacterVector ab(1);
    ab[0] = cBuffer;
    return ab;
}

The whole lot compiles, but gives a runtime error. When I try the
following in R:
library(ROpenCL)
platformIDs <- getPlatformIDs()
print(getPlatformName(platformIDs[[1]]))

*** caught segfault ***
address 0x51, cause 'memory not mapped'

Now when I put all this together in one method which just returns the
platform name, it works:

SEXP getPlatformIDs2(){
        //returns a list of platform ids
        cl_uint num_platforms = 0;
        clGetPlatformIDs(0, 0, &num_platforms);
        std::vector<cl_platform_id> platforms(num_platforms);
        clGetPlatformIDs(num_platforms, platforms.empty() ? NULL :
&platforms.front(), &num_platforms);
        char cBuffer[1024];
    clGetPlatformInfo (platforms[0], CL_PLATFORM_NAME,
sizeof(cBuffer), cBuffer, NULL);
    Rcpp::CharacterVector ab(1);
    ab[0] = cBuffer;
    return ab;
}

This results in:
getPlatformIDs2()
[1] "NVIDIA CUDA"

Could someone check if I am taking the pointer to and from R in the correct way?
Thanks in advance,

Willem Ligtenberg
_______________________________________________
Rcpp-devel mailing list
Rcpp-devel@lists.r-forge.r-project.org
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

Reply via email to