Hi everybody,
I’m trying to compile a model using an external C++ code with precomputed gradients in CmdStan following the examples of the PyStan and the RStan interfaces docs.
For that purpose, I’m using the following toy example:
-
external_grad.stan
file:
functions {
real my_func(real A, real B);
}
data {
real B;
}
parameters {
real A;
}
transformed parameters {
real C = my_func(A, B);
}
model {
C ~ std_normal();
}
-
external_manual.hpp
file:
#include <cmath>
#include <ostream>
#include <stan/math.hpp>
namespace external_grad_model_namespace {
using namespace stan::math;
inline double my_func (double A, double B, std::ostream* pstream) {
double C = A*B*B+A;
return C;
}
inline var my_func (const var& A_var, const var& B_var, std::ostream* pstream) {
// Compute the value
double A = A_var.val(),
B = B_var.val(),
C = my_func(A, B, pstream);
// Compute the partial derivatives:
double dC_dA = B*B+1.0,
dC_dB = 2.0*A*B;
// Autodiff wrapper:
return var(new precomp_vv_vari(
C, // The _value_ of the output
A_var.vi_, // The input gradient wrt A
B_var.vi_, // The input gradient wrt B
dC_dA, // The partial introduced by this function wrt A
dC_dB // The partial introduced by this function wrt B
));
}
inline var my_func (double A, const var& B_var, std::ostream* pstream) {
double B = B_var.val(),
C = my_func(A, B, pstream),
dC_dB = 2.0*A*B;
return var(new precomp_v_vari(C, B_var.vi_, dC_dB));
}
inline var my_func (const var& A_var, double B, std::ostream* pstream) {
double A = A_var.val(),
C = my_func(A, B, pstream),
dC_dA = B*B+1.0;
return var(new precomp_v_vari(C, A_var.vi_, dC_dA));
}
}
Unfortunately, the compilation throws the following error:
(stan-env) miguel@miguel-ASUS-Laptop-X407UBR:~/anaconda3/envs/stan-env/bin/cmdstan$ make STANCFLAGS=--allow-undefined USER_HEADER=examples/external_grad/external_manual.hpp examples/external_grad/external_grad
--- Translating Stan model to C++ code ---
bin/stanc --allow-undefined --o=examples/external_grad/external_grad.hpp examples/external_grad/external_grad.stan
--- Compiling, linking C++ code ---
/home/miguel/anaconda3/envs/stan-env/bin/x86_64-conda-linux-gnu-c++ -fvisibility-inlines-hidden -std=c++17 -fmessage-length=0 -march=nocona -mtune=haswell -ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 -ffunction-sections -pipe -isystem /home/miguel/anaconda3/envs/stan-env/include -std=c++1y -D_REENTRANT -Wno-sign-compare -Wno-ignored-attributes -I /home/miguel/anaconda3/envs/stan-env/include/ -O3 -I src -I stan/src -I lib/rapidjson_1.1.0/ -I lib/CLI11-1.9.1/ -I stan/lib/stan_math/ -I stan/lib/stan_math/lib/eigen_3.3.9 -I stan/lib/stan_math/lib/boost_1.75.0 -I stan/lib/stan_math/lib/sundials_5.7.0/include -DNDEBUG -D_FORTIFY_SOURCE=2 -O2 -isystem /home/miguel/anaconda3/envs/stan-env/include -DBOOST_DISABLE_ASSERTS -DTBB_INTERFACE_NEW -DTBB_INTERFACE_NEW -c -include examples/external_grad/external_manual.hpp -x c++ -o examples/external_grad/external_grad.o examples/external_grad/external_grad.hpp
In file included from <command-line>:
./examples/external_grad/external_manual.hpp: In function 'stan::math::var external_grad_model_namespace::my_func(double, const var&, std::ostream*)':
./examples/external_grad/external_manual.hpp:39:14: error: expected primary-expression before '(' token
39 | return var(new precomp_v_vari(C, B_var.vi_, dC_dB));
| ^
./examples/external_grad/external_manual.hpp:39:19: error: expected type-specifier before 'precomp_v_vari'
39 | return var(new precomp_v_vari(C, B_var.vi_, dC_dB));
| ^~~~~~~~~~~~~~
./examples/external_grad/external_manual.hpp: In function 'stan::math::var external_grad_model_namespace::my_func(const var&, double, std::ostream*)':
./examples/external_grad/external_manual.hpp:46:14: error: expected primary-expression before '(' token
46 | return var(new precomp_v_vari(C, A_var.vi_, dC_dA));
| ^
./examples/external_grad/external_manual.hpp:46:19: error: expected type-specifier before 'precomp_v_vari'
46 | return var(new precomp_v_vari(C, A_var.vi_, dC_dA));
| ^~~~~~~~~~~~~~
make: *** [make/program:58: examples/external_grad/external_grad] Error 1
It seems that the precomp_v_vari
class is not founded. By checking the Stan Math Library docs, I’m not able to found that class either, I only found the precomp_vv_vari class.
So my question is, what is the correct way to compile my model in CmdStan?
Additional information:
- Operating System: Ubuntu 18
- CmdStan Version: 2.28.2
- Compiler/Toolkit: g++ 7.5.0