On 3 August 2011 at 14:18, Willem Ligtenberg wrote: | Hi Dirk (and list), | | Yes, the above does help. | Although, I actually got the toy example to work about 5 minutes ago. :) | And just 1 minute ago also the OpenCL method. :D | At this moment I am a very happy person! | | And for future reference I change the methods into this: | SEXP getIntPointer(){ | int *test = new int;
Please keep all the warning in the 'Writing R Extensions' about not to mix new/delete and the R allocations. Also, this looks like a resource leak, no? test never gets freed. That said, as a proof of concept for wrapping an int pointer, it is probably good enough. Dirk | *test = 6; | SEXP retVal = int2EXP(test); | int test2 = *SEXP2int(retVal); | return retVal; | } | | SEXP doubleIntPointer(SEXP test){ | int test2 = *SEXP2int(test); | return Rcpp::wrap(test2*2); | } | | Kind regards, | | Willem | | On Wed, Aug 3, 2011 at 14:03, Dirk Eddelbuettel <e...@debian.org> wrote: | > | > Hi Willem, | > | > On 3 August 2011 at 12:13, Willem Ligtenberg wrote: | > | 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) | > | > Toy examples are good. | > | > | // 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); | > | > Isn't &test now the address of a temp object in the function getIntPointer ? | > That memory space doesn't persist after the call. | > | > Maybe you should take the address of a global (static) variable, or allocate | > memory. | > | > | 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? | > | > Does the above help? | > | > Cheers, Dirk | > | > | 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 | > | > -- | > 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 -- 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