Skip to content

External c++ example fails #1119

Description

@andrjohns

Summary:

Attempting to run the external c++ example fails with:

andrew@Andrews-MacBook-Air cmdstan-2.30.1 % make STANCFLAGS=--allow-undefined USER_HEADER=examples/bernoulli/make_odds.hpp examples/bernoulli/bernoulli # on Windows add .exe

--- Translating Stan model to C++ code ---
bin/stanc --allow-undefined --o=examples/bernoulli/bernoulli.hpp examples/bernoulli/bernoulli.stan

--- Compiling, linking C++ code ---
clang++ -std=c++1y -Wno-unknown-warning-option -Wno-tautological-compare -Wno-sign-compare -D_REENTRANT -Wno-ignored-attributes      -I stan/lib/stan_math/lib/tbb_2020.3/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.78.0 -I stan/lib/stan_math/lib/sundials_6.1.1/include -I stan/lib/stan_math/lib/sundials_6.1.1/src/sundials    -DBOOST_DISABLE_ASSERTS          -c -include-pch stan/src/stan/model/model_header.hpp.gch -include examples/bernoulli/make_odds.hpp -x c++ -o examples/bernoulli/bernoulli.o examples/bernoulli/bernoulli.hpp
examples/bernoulli/bernoulli.hpp:24:62: error: template parameter redefines default argument
          stan::require_all_t<stan::is_stan_scalar<T0__>>* = nullptr>
                                                             ^
./examples/bernoulli/make_odds.hpp:6:62: note: previous default template argument defined here
          stan::require_all_t<stan::is_stan_scalar<T0__>>* = nullptr>

Not sure whether this is a stanc3 or cmdstan issue sorry!

Current Version:

v2.30.1

Activity

  1. WardBrian commented on Sep 23, 2022

    @WardBrian
    Member

    I can't reproduce this using gcc on Ubuntu 20.01, it's possible that this is compiler dependent. @rok-cesnovar - do you recall?

  2. rok-cesnovar commented on Sep 23, 2022

    @rok-cesnovar
    Member

    I think it may be a Mac issue - maybe clang? Will take a look over the weekend.

  3. WardBrian commented on Oct 5, 2022

    @WardBrian
    Member

    I seem to recall this being an issue with gcc being more permissive than clang in terms of multiple declarations.

    There is a way around this (I believe) if you separate the compilation into multiple steps. If you add the manual template expansion

    template double make_odds<double, nullptr>(const double&, std::ostream*);

    to make_odds.hpp, you can then compile this to make_odds.o, then insert make_odds.o before bernoulli.o src/cmdstan/main.o in the final compile command. This should link properly, without the need to have two declarations in the same translation unit.

    Full example:

    1. Add the above line to make_odds.hpp
    2. Run stanc --allow-undefined bernoulli.stan
    3. Compile bernoulli.hpp to bernoulli.o (this is the first step cmdstan does, see what command it uses)
    4. Compile make_odds.hpp to make_odds.o. This will probably use an almost identical command to the previous step, just with the files swapped out
    5. Compile the final executable, adding model.o to the list of sources. This is the second step cmdstan does.

    On my machine, in full, the commands are (working from the top-level cmdstan directory with the model and header copied there):

    bin/stanc --allow-undefined --o=bernoulli.hpp bernoulli.stan
    
    g++ -std=c++1y -pthread -D_REENTRANT -Wno-sign-compare -Wno-ignored-attributes      -I stan/lib/stan_math/lib/tbb_2020.3/include    -O3 -I src -I stan/src -I stan/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.78.0 -I stan/lib/stan_math/lib/sundials_6.1.1/include -I stan/lib/stan_math/lib/sundials_6.1.1/src/sundials    -DBOOST_DISABLE_ASSERTS          -c -Wno-ignored-attributes   -x c++ -o bernoulli.o bernoulli.hpp
    
    g++ -std=c++1y -pthread -D_REENTRANT -Wno-sign-compare -Wno-ignored-attributes      -I stan/lib/stan_math/lib/tbb_2020.3/include    -O3 -I src -I stan/src -I stan/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.78.0 -I stan/lib/stan_math/lib/sundials_6.1.1/include -I stan/lib/stan_math/lib/sundials_6.1.1/src/sundials    -DBOOST_DISABLE_ASSERTS          -c -Wno-ignored-attributes   -x c++ -o make_odds.o make_odds.hpp
    
    g++ -std=c++1y -pthread -D_REENTRANT -Wno-sign-compare -Wno-ignored-attributes      -I stan/lib/stan_math/lib/tbb_2020.3/include    -O3 -I src -I stan/src -I stan/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.78.0 -I stan/lib/stan_math/lib/sundials_6.1.1/include -I stan/lib/stan_math/lib/sundials_6.1.1/src/sundials    -DBOOST_DISABLE_ASSERTS                -Wl,-L,"/home/brian/Dev/cpp/cmdstan/stan/lib/stan_math/lib/tbb" -Wl,-rpath,"/home/brian/Dev/cpp/cmdstan/stan/lib/stan_math/lib/tbb"    make_odds.o  bernoulli.o src/cmdstan/main.o        -Wl,-L,"/home/brian/Dev/cpp/cmdstan/stan/lib/stan_math/lib/tbb" -Wl,-rpath,"/home/brian/Dev/cpp/cmdstan/stan/lib/stan_math/lib/tbb"   stan/lib/stan_math/lib/sundials_6.1.1/lib/libsundials_nvecserial.a stan/lib/stan_math/lib/sundials_6.1.1/lib/libsundials_cvodes.a stan/lib/stan_math/lib/sundials_6.1.1/lib/libsundials_idas.a stan/lib/stan_math/lib/sundials_6.1.1/lib/libsundials_kinsol.a  stan/lib/stan_math/lib/tbb/libtbb.so.2 -o bernoulli

    Edit: As an added bonus, since you're manually expanding the template here you don't really need to do the SNIFAE-style require magic. The following header will also compile just file:

    #include <stan/model/model_header.hpp>
    #include <ostream>
    
    namespace bernoulli_model_namespace {
    template <typename T0__, void* = nullptr>
    stan::promote_args_t<T0__> make_odds(const T0__& theta,
                                         std::ostream* pstream__) {
      return theta / (1 - theta);
    }
    
    template double make_odds<double>(const double&, std::ostream*);
    
    }  // namespace bernoulli_model_namespace
    
  4. linked a pull request that will close this issueUpdate page on external C++ #626on Mar 23, 2023
  5. WardBrian commented on Mar 23, 2023

    @WardBrian
    Member

    @andrjohns if you have a local copy which has develop cmdstan / master stanc, would you mind trying the updated examples from stan-dev/docs#626?

  6. andrjohns commented on Mar 23, 2023

    @andrjohns
    ContributorAuthor

    @andrjohns if you have a local copy which has develop cmdstan / master stanc, would you mind trying the updated examples from stan-dev/docs#626?

    Brilliant! Both the templated make_odds and the my_dot_self derivative overloads are compiling without issue

  7. WardBrian commented on Mar 23, 2023

    @WardBrian
    Member

    Great!

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions