[Rcpp-devel] Pointer troubles

Willem Ligtenberg willem.ligtenberg at openanalytics.eu
Tue Aug 2 11:45:19 CEST 2011


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


More information about the Rcpp-devel mailing list