GSOC Week 2
This week features an attempt to provide reticulate wrappers for the C++ constructs provided by the libcpp_test script of autowrap tool which automates generation of python bindings by making use of pxd files which contain cython declarations of c++ classes and methods.
The libcpp_test file has some classes and in particular their is one, LibCppTest which provides several numbered functions prefixed as “process”. These functions make use of diverse C++ data structures and so to test the possibility of wrapping these in R, I created reticulate wrappers till process 11 and for process26 which used nested vector type.
The script containing these wrappers is available here.
For simple data types like vector or pair of of objects are straight forward to wrap, we first simply convert any R class object if any in our argument to their corresponding python types and then we invoke the python function passing the argument. Reticulate automatically does the r to python data type conversion for arguments with automatic conversion enabled.
Here is an example of process3 function
This function checks that the argument passed it should be a list of length 2 containing an integer object and LibCppTest object. Then it converts the LibCppTest R6 object to its underlying python object. Later after calling the python calling, it again wraps the python object and returns the list.
When we need to wrap a process function dealing with a std::set data structure, it is a little tricky to do so as there is no native set data type in R. For this reason, we can even consider taking a list and ensuring that its elements are unique.
A possible workaround for the above problem can be seen in process9 function
Here, we first create a python list object “o1” and convert this into a set. We then invoke the python function, passing this set object. Finally, we convert back the returned set to python list and this list is returned back as R list. Before, doing all this conversion we need to ensure that the list passed to our function doesn’t contain duplicate entries. To achieve this we can do a small check and throw error if it is not so.
For nested containers like for example: a vector of vector of “Int” type, we can just iterate over our list and convert the Int R6 objects to the underlying python object.
An Example of above would be the process26 function
This function takes as input as doubly nested list containing R6 objects of Int class. We only need to convert the R6 objects to the underlying python objects and we are good to go. Then, we can simply invoke the python function using this list.
- Generate reticulate bindings for all the process functions to see if there is difficulty in wrapping some data structures.
- Generating reticulate bindings for libcpp_test automatically to compare similarity with the manually generated wrappers.