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

std::vector as generator argument #205

Closed
agerlach opened this issue May 6, 2016 · 2 comments
Closed

std::vector as generator argument #205

agerlach opened this issue May 6, 2016 · 2 comments

Comments

@agerlach
Copy link

agerlach commented May 6, 2016

Denis,
After playing with vex::symbolic some more w/ what we talked about in #203, I am beginning to wonder if there would be an advantage to overloading vex::generator::build_kernel to take std::vector arguments. If you could, I think it would make kernel generation much more flexible. For example, consider the case of solving ODE's. Doing this would allow somebody to write a generic simulation framework that does not have the number of states and system parameters hardcoded, enabling applications where the system may not be known at compile time.

In your symbolic examples you do:

typedef vex::symbolic<double> sym_value;
typedef std::array<sym_value,3> sym_state;
....
sym_state sym_S = {
   sym_value(sym_value::VectorParameter),
   sym_value(sym_value::VectorParameter),
   sym_value(sym_value::VectorParameter)
};

sym_value sym_SysParam1(sym_value::VectorParameter, sym_value::Const);
...
auto kernel vex::generator::build_kernel(ctx,"kernel_name", body.str(),
   sym_S[0], sym_S[1], sym_S[2], sym_SysParam1 ...);
...
vex::vector<double> X(ctx,n);
vex::vector<double> Y(ctx,n);
vex::vector<double> Z(ctx,n);
vex::vector<double> SysParam1(ctx,n);
...
kernel(X,Y,Z,SysParam1...);

I would like to be able to do something like this:

typedef vex::symbolic<double> sym_value;
typedef std::vector<sym_value> sym_vector;
....
sym_vector sym_S;
for(int i = 0; i < numStates; ++i) {
   sym_S.push_back(sym_value(sym_value::VectorParameter));
}

sym_vector sym_Params;
for(int i = 0; i < numParams; ++i ) {
   sym_Params.push_back(sym_value(sym_value::VectorParameter, sym_value::Const));
}

...
auto kernel vex::generator::build_kernel(ctx,"kernel_name", body.str(),
   sym_S, sym_Params ...);
...
std::vector<vex::vector<double>> S;
std::vector<vex::vector<double>> Param;
...
kernel(S,Param...);

I'm not familiar enough with your code to see how to implement this or even if it is possible, but one thought I had is that you could simply "unpack" the states and parameters when calling build_kernel and then pass them to the your existing implementation as vectorArg1[0], vectorArg1[2],...vectorArg2[0], vectorArg2[1],.... The same could be done w/ the resulting kernel object.

ddemidov added a commit that referenced this issue May 7, 2016
@ddemidov
Copy link
Owner

ddemidov commented May 7, 2016

With e2fad48 you should be able to do what you need:

vex::generator::kernel K(ctx, "kernel_name");

// Register symbolic variables as kernel parameters:
K.add_param(sym_X);
K.add_param(sym_Y);

// Pass the recorded body, build the kernel:
K.build(body.str());

// Set the actual parameters, launch the kernel:
K.push_arg(X);
K.push_arg(Y);
K();

The existing API still works, so the above is equivalent to

auto K = vex::generator::build_kernel(ctx, "kernel_name", body.str(), sym_X, sym_Y);
K(X, Y);

@agerlach
Copy link
Author

agerlach commented May 9, 2016

Works great! Thanks again.

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

No branches or pull requests

2 participants