Specify the compiler used to install pyStan

I’m trying to install PyStan on a raspberry pi 3b+ and it’s obviously struggling to manage the compilation of all the stan libraries. I can successfully compile using distcc from the pi to my macbook and I’d like to do the same for the stan compilation to enable pystan.

I can see there are instructions for using a custom compiler; to export CC, CXX, and include anaconda on path. In may case it would be miniconda, though in any case I am not using miniconda so I have passed on this step.

I wonder if this is something that anyone has experience with? I’m also not sure if there’s a smarter way to achieve the initial installation as I’d like to pursue this path so that I can handoff compilation for models using the same distcc environment later also.

I can export as instructed, then I can immediately compile a hello world program using the $CC and or $CXX compiler as I wish, though when I run sudo pip3 install pystan -vvv I can see the files copy into place and then something like…

  Make sure that Python modules winreg, win32api or win32con are installed.
  C compiler: gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC

  creating build/temp.linux-armv7l-3.6
  creating build/temp.linux-armv7l-3.6/pystan
  creating build/temp.linux-armv7l-3.6/pystan/stan
  creating build/temp.linux-armv7l-3.6/pystan/stan/src
  creating build/temp.linux-armv7l-3.6/pystan/stan/src/stan
  creating build/temp.linux-armv7l-3.6/pystan/stan/src/stan/lang
  creating build/temp.linux-armv7l-3.6/pystan/stan/src/stan/lang/grammars
  compile options: '-DBOOST_DISABLE_ASSERTS -DBOOST_NO_DECLTYPE -DBOOST_PHOENIX_NO_VARIADIC_EXPRESSION -DBOOST_RESULT_OF_USE_TR1 -DFUSION_MAX_VECTOR_SIZE=12 -I./pystan -Ipystan/stan/src -Ipystan/stan/lib/stan_math/ -Ipystan/stan/lib/stan_math/lib/eigen_3.3.3 -Ipystan/stan/lib/stan_math/lib/boost_1.69.0 -Ipystan/stan/lib/stan_math/lib/sundials_4.1.0/include -I/usr/local/include/python3.6m -c'
  extra options: '-Os -ftemplate-depth-256 -Wno-unused-function -Wno-uninitialized -std=c++1y'
  gcc: pystan/stan/src/stan/lang/ast_def.cpp
  gcc: pystan/stan/src/stan/lang/grammars/bare_type_grammar_inst.cpp
  gcc: pystan/_api.cpp
  gcc: pystan/stan/src/stan/lang/grammars/block_var_decls_grammar_inst.cpp
  cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
  cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
  cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
  cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++

It picks up the /usr/lib/… compiler which I have taken off the path, so I’mm assuming it launches in another process/environment and picks up default path. So at this stage before affecting change in default paths just to test I thought I’d see if anyone has been down this… path … before?

Update:   <this turned out to be a dead end, distutil don't support a gcc option>
I can control the compiler with the distutil.cfg tip found [here](https://stackoverflow.com/questions/3297254/how-to-use-mingws-gcc-compiler-when-installing-python-package-using-pip).
Though I'm now investigating how to resolve the compiler inspection which I assume is occuring to give;     
```
error: don't know how to compile C/C++ code on platform 'posix' with '/usr/lib/distcc/gcc' compiler
```
The referenced /usr/lib/distcc/gcc is a symlink to the distcc command so I expect this is whats going on.

I’ll update when I know more, but if someone can see a ray of light for me I’m very happy to hear of it!

Thanks!

wow! does this thing actually have enough memory to compile and run a Stan model?

this is what we’re recommending (from the CmdStan manual)

hardware powerful enough to build and execute the models. Ideally, that will be a 64-bit computer with at least 4GB of memory and multiple processor cores.

Haha, yep you’re right it definitely isn’t powerful. And if I’m able to offload the builds to be cross-compiled as I’m aiming for, then the actual execution of the model isn’t something I’m too worried about. I figure the sampling might take 2-30 minutes for the models I am interested in, and this just sits on my kitchen bench and I’m ok with that time.

So the important part is managing to redirect the pi3b+ calls to gcc to instead be passed to the macbook compiling in an Rpi toolchain and then handed back once built. This is the deep end for me though as I’m ok at the modelling, I scrape by in developing, but weakest of all using build tools. It would make my little punnet of raspberries very fun though.

Current plan of action is to close everything and come back to it with a fresh state and see what options I’ve inadvertently altered in my efforts so far…

Try to add extra_compiler_args=['-flto'] to StanModel call

Thanks for the response, that’s just ahead of where I am currently at. I’m trying to get stan/pystan to install by this regime before I can worry about model compilation, though I hope a few good lessons learned for when I get to this step!

Getting some progress…

building 'pystan._api' extension
Warning: Can't read registry to find the necessary compiler setting
Make sure that Python modules winreg, win32api or win32con are installed.
C compiler: /usr/lib/distcc/gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC

But I can see local gcc processes running, so I think I need to look at the distcc set up next.

Ok I have something working…
Now just dealing with particulars of the toolchain I think;

    /usr/bin/ld: error: build/lib.linux-armv7l-3.6/pystan/_api.cpython-36m-arm-linux-gnueabihf.so uses VFP register arguments, build/temp.linux-armv7l-3.6/pystan/_api.o does not

do you have Python3 on pi3b+? have you considered CmdStanPy?

have you seen these articles on installing c++ on pi3b+?

if you can get a modern c++ toolchain on the pi, CmdStanPy will do the CmdStan install for you.

Thanks for this, I hadn’t, I’ll take a look this morning!

I’m hoping to move the build off of the pi, but these are nicely written and very clear compared to what I’ve been finding so will be helpful, thanks!

Successful distributed cross compile this morning… I think?!
Yet to test it out, but I have seen this;

Created wheel for pystan: filename=pystan-2.19.1.1-cp36-cp36m-linux_armv7l.whl size=61729169 sha256=fe3128828fb1835949604dfdd48fff33108b64dbc218be3517dee5354cb3f885
  Stored in directory: /home/pi/.cache/pip/wheels/f9/f0/61/aad9389fd15dcc68708cde417fa24d2dc9762674b8f454df5b
Successfully built pystan
Installing collected packages: pystan

These were the compile times, mbp did the heavy lifting;

distccd[49188] (dcc_job_summary) client: 192.168.1.96:33218 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:128395ms gcc pystan/stan/src/stan/lang/ast_def.cpp
distccd[49183] (dcc_job_summary) client: 192.168.1.96:33220 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:178099ms gcc pystan/stan/src/stan/lang/grammars/bare_type_grammar_inst.cpp
distccd[49186] (dcc_job_summary) client: 192.168.1.96:33216 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:214629ms gcc pystan/_api.cpp
distccd[49187] (dcc_job_summary) client: 192.168.1.96:33382 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:69253ms gcc pystan/stan/src/stan/lang/grammars/expression07_grammar_inst.cpp
distccd[49185] (dcc_job_summary) client: 192.168.1.96:33410 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:69634ms gcc pystan/stan/src/stan/lang/grammars/expression_grammar_inst.cpp
distccd[49183] (dcc_job_summary) client: 192.168.1.96:33478 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:65247ms gcc pystan/stan/src/stan/lang/grammars/indexes_grammar_inst.cpp
distccd[49184] (dcc_job_summary) client: 192.168.1.96:33214 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:294158ms gcc pystan/stan/src/stan/lang/grammars/block_var_decls_grammar_inst.cpp
distccd[49188] (dcc_job_summary) client: 192.168.1.96:33452 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:85447ms gcc pystan/stan/src/stan/lang/grammars/functions_grammar_inst.cpp
distccd[49186] (dcc_job_summary) client: 192.168.1.96:33504 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:80153ms gcc pystan/stan/src/stan/lang/grammars/local_var_decls_grammar_inst.cpp
distccd[49185] (dcc_job_summary) client: 192.168.1.96:33552 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:82081ms gcc pystan/stan/src/stan/lang/grammars/semantic_actions_def.cpp
distccd[49183] (dcc_job_summary) client: 192.168.1.96:33554 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:83101ms gcc pystan/stan/src/stan/lang/grammars/statement_2_grammar_inst.cpp
distccd[49187] (dcc_job_summary) client: 192.168.1.96:33550 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:116279ms gcc pystan/stan/src/stan/lang/grammars/program_grammar_inst.cpp
distccd[49186] (dcc_job_summary) client: 192.168.1.96:33652 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:55041ms gcc pystan/stan/src/stan/lang/grammars/whitespace_grammar_inst.cpp
distccd[49184] (dcc_job_summary) client: 192.168.1.96:33600 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:141802ms gcc pystan/stan/src/stan/lang/grammars/statement_grammar_inst.cpp
distccd[49188] (dcc_job_summary) client: 192.168.1.96:33638 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:158939ms gcc pystan/stan/src/stan/lang/grammars/term_grammar_inst.cpp
distccd[49185] (dcc_job_summary) client: 192.168.1.96:34044 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:20705ms gcc pystan/_chains.cpp
distccd[49183] (dcc_job_summary) client: 192.168.1.96:34068 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:6371ms gcc pystan/_misc.cpp

Success!

Successfully installed pystan-2.19.1.1

I’ll report back how the model compilation works out later, maybe tonight…

I have also managed to get the stan model compilation distributed, 8 schools pystan example;

distccd[49184] (dcc_job_summary) client: 192.168.1.96:40578 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:178792ms gcc /tmp/pystan_3tfidowu/stanfit4anon_model_19a09b474d1901f191444eaf8a6b8ce2_791731648.cpp

And local (rpi) sampling was really very fast for this with 1000 its and 4 chains, <1min.

1 Like

If I was to write up what worked I would retrace a lot of the steps in this quite useful guide for anyone wanting to do the same.

Can you share steps how you make it work on Raspi ?
Thank you