Hi Dirk and list, Indeed it might have been a bit too complicated. I think I have another example, which explains my troubles without requiring OpenCL. In this case, I want to return a pointer to an integer value to R and the double the integer value in another function. (I know this is stupid to do, but it is a toy example)
// Stuff to expose the int to R static void intObjFinalizer(SEXP ref){ if(TYPEOF(ref) == EXTPTRSXP){ int *o = static_cast<int*> (R_ExternalPtrAddr(ref)); if (o) delete o; } } SEXP int2EXP(int *o){ SEXP xp = R_MakeExternalPtr(o, R_NilValue, R_NilValue); R_RegisterCFinalizerEx(xp, intObjFinalizer, TRUE); return xp; } int *SEXP2int(SEXP o){ if(TYPEOF(o) != EXTPTRSXP) Rf_error("invalid object"); return (int*) R_ExternalPtrAddr(o); } SEXP getIntPointer(){ int test = 6; SEXP retVal = int2EXP(&test); std::cout << test << "\n"; int test2 = *SEXP2int(retVal); std::cout << test2 << "\n"; return retVal; } SEXP doubleIntPointer(SEXP test){ int test2 = *SEXP2int(test); std::cout << test2; return Rcpp::wrap(test2*2); } By the way, I use a module to expose these functions: RCPP_MODULE(ropencl){ using namespace Rcpp ; function( "getIntPointer" , &getIntPointer , "getIntPointer" ) ; function( "doubleIntPointer" , &doubleIntPointer , "doubleIntPointer" ) ; } When I now execute getIntPointer() from R, it seems to work fine, both the initial integer and the value that I get back from *SEXP2int(retVal); are 6. (Although when I exit R after only this call I get the following: *** glibc detected *** /usr/lib64/R/bin/exec/R: free(): invalid pointer: 0x00007fffd1a587cc ***) However, when I now use doubleIntPointer(getIntPointer()) in R, I get some wrong result (a different value each time I restart R). Does this make it a bit more clear what I want to do, or the problems that I am facing? Kind regards, Willem On Tue, Aug 2, 2011 at 15:24, Dirk Eddelbuettel <e...@debian.org> wrote: > > Hi Willem, > > Thanks a pretty long and complicated post. Could we possibly break it down > into smaller pieces? > > On 2 August 2011 at 11:45, Willem Ligtenberg wrote: > | 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; > > You could use wrap() on std::string or char* if you just want to return a > single string. No need for a CharacterVector of size 1. > > | } > | > | 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? > > I can't as I do not know the OpenCL API. > > One thought is that maybe you do not you really need external pointers as you > are just copying IDs around. Can you simplify what you are trying to do? > > Cheers, Dirk > > -- > Gauss once played himself in a zero-sum game and won $50. > -- #11 at http://www.gaussfacts.com > _______________________________________________ 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