Makefile confusion...solutions?

Hi!

I recently was very confused by getting things I haven’t ordered from cmdstan. So I was playing with the optimizations and had

STAN_CPP_OPTIMS=true

in my make/local. That caused the optimizations to throw my macbook over… ok, so I wanted to get rid of it and changed the above to

STAN_CPP_OPTIMS=false

but this did not disable the feature!!! CmdStan was still applying the C++ optimizations which I did not order! The culprit is that our makefiles do only test for the variable being defined or not like so:

ifdef STAN_CPP_OPTIMS

    do stuff

endif

And hence it does not matter what value I write into the variable. Once the variable is defined we are going to turn on the feature. The same is true for STAN_THREADS, STAN_MPI and maybe others.

This really confused me, I would prefer a check like

ifeq ($(STAN_CPP_OPTIMS), true)

   do stuf

endif

This way the feature would only be enabled when the variable is set to true. In any other case it would be disabled (including 1, TRUE or any variation of that).

The thing is that this would break backwards-compatibility… what do others think and can we improve the situation. Having STAN_THREADS=false in my makefile, but still get threads is awkward to me.

Best,
Sebastian

3 Likes

I think the most backwards-compatible thing is checking that it is defined and not false. That way, defining it to something like 1 would still work, but the very specific definition STAN_THREADS=false would disable it.

Would that work?

3 Likes

Note that there was some minimal discussion of how to handle stan_threads = something in cmdstanr in the PR here. In this case the problem and fix were both entirely on the R side, but the behavior was similar.

1 Like

that sounds like a plan! So we do

ifneq ($(STAN_CPP_OPTIMS),false)

...
endif

Right?

I think it will evaluate to “” if not set, right? Which will be not equal to false? I’m not a make expert but I think it would need to be

ifdef STAN_CPP_OPTIMS
    ifneq ($(STAN_CPP_OPTIMS),false)
        ...
    endif 
endif

Possible theres a shorter idiom for this

1 Like

There might be a case for also checking FALSE, False, and F since R and Python users without c++ background occasionally find their way into the makefiles. Especially since these same users might have been using TRUE, True or T to turn things on, and seen behavior that “confirmed their expectations”.

But I totally understand if you prefer to assume that anybody tinkering in makefiles except with copy-paste should have some minimal clue of what they’re doing.

2 Likes

That would be nice… any idea how to code that with less code in makefiles?

(emphasis mine)

I hit this with STAN_THREADS. the way makefile variables work / our makefiles are written, this is probably true everywhere.

the CmdStanPy and CmdStanR users can set the makefile variables from the interfaces, so you should expect that they would use any of these. cf: https://mc-stan.org/cmdstanpy/workflow.html#compile-the-stan-model

to parallelize running the NUTS-HMC sampler across chains, the Stan model must be compiled with C++ compiler flag STAN_THREADS . While any value can be used, we recommend the value True ,