Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Find a way to expose ufuncs/rvectorize #11

Open
wolfv opened this issue Jul 9, 2017 · 5 comments
Open

Find a way to expose ufuncs/rvectorize #11

wolfv opened this issue Jul 9, 2017 · 5 comments

Comments

@wolfv
Copy link
Member

wolfv commented Jul 9, 2017

We have the (working) rvectorize, but afaik there is no way to expose just a function pointer with RCpp (without the decorations).
Maybe @eddelbuettel has a hint?

I.e. this is corresponding code for xtensor-python, where the result of xt::pyvectorize get's bound to a function name in python.

#include "pybind11/pybind11.h"
#include "xtensor-python/pyvectorize.hpp"
#include <numeric>
#include <cmath>

namespace py = pybind11;

double scalar_func(double i, double j)
{
    return std::sin(i) - std::cos(j);
}

PYBIND11_PLUGIN(xtensor_python_test)
{
    py::module m("xtensor_python_test", "Test module for xtensor python bindings");

    m.def("vectorized_func", xt::pyvectorize(scalar_func), "");

    return m.ptr();
}
@eddelbuettel
Copy link
Contributor

Hm, not sure I really understand what you are asking but here is one attempt:

Rcpp can be used to marshall types which R itself has (in its C API); this includes Rcpp::XPtr. See for example this write-up at the Rcpp Gallery.

If I misunderstand what you're asking, never mind :) I got up on another continent today...

@wolfv
Copy link
Member Author

wolfv commented Jul 11, 2017

I think what I am trying to say is that for // [[Rcpp::export]] to work, the following line always has to contain the signature of the function, right?

Because, with e.g. pybind11, the signature of the function is found "by the compiler" and not by preprocessing, and that is what enables the xt::pyvectorize which creates a rvectorizer struct with operator() and returns that.

So technically, it would be cool to be able to do:

double scalar_func(double i, double j)
{
    return std::sin(i) - std::cos(j);
}

// [[Rcpp::export(name=".vectorized_func"]]
rvectorize(scalar_func);

Currently what would be possible is (I guess):

double scalar_func(double i, double j)
{
    return std::sin(i) - std::cos(j);
}

static auto f = rvectorize(scalar_func);

// [[Rcpp::export(name=".vectorized_func"]]
auto vectorized_func(rarray<double> a, rarray<double> b) {
    return  f(a, b);
}

(Please consider this pseudocode as I didn't try to compile it).

Cheers,

Wolf

@eddelbuettel
Copy link
Contributor

Yes, what you say in paragraph one is correct for what we call 'Rcpp Attributes'.

You have another option with what we call 'Rcpp Modules'. That is older, more declarative and modelled after Boost.Python. You may be able to tweak it. Its internal code is however more or less a dead end.

@wolfv
Copy link
Member Author

wolfv commented Jul 11, 2017

Oh, I see. Rcpp Modules actually does look a lot more like Boost.Python/pybind11/Cxxwrap.jl so it would be more "familiar" for users of the full xtensor suite.

But the use of Rcpp Modules is generally discouraged?

@eddelbuettel
Copy link
Contributor

It's complicated. It was a stroke of genius by Romain, but he himself no longer seems to like it (ie when he did his [ultimately not that successful] Rcpp11 he didn't do modules) and he no longer works on Rcpp. Nobody else has a real handle on the code.

It is still used. But the code is less well maintained than the rest of Rcpp. Waits for someone to adopt it. If you want to earn some R karma ... ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants