stan-dev / stan-dev/rstantools

rstan_package_skeleton: multiple translation units

Open
#14 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
R
Stars
48
Forks
24
Avg merge
1h 17m
Merged PRs (30d)
1

Description

I am using rstantools::rstan_package_skeleton to implement a dozen stan models in an R package. While tools/make_cpp.R creates multiple .cc files in src, the cleanup file has the lines

cat src/*.cc > src/Modules.cpp
rm src/*.cc

effectively leading to one translation unit. This means when I modify any of the stan models they all need to be recompiled, which makes development burdensome.

Unfortunately, removing the lines above (i.e., multiple translation units) leads to "duplicate symbols" linker errors. To my understanding, this is because stan declares + defines functions inside namespaces inside header files only, for which header guarding + inline keyword does not seem to prevent symbol duplication.

I'd like to fix this issue and can think of two ways of going about it:

  1. Modify the stan library so as to somehow nest the stan namespace within each model. I'm reluctant to do this, and have tried many many ways around this, including:
    • creating separate src/include/models.hpp files for each model. Didn't work, as stan/model/model.hpp goes into each .o which all get linked into one .so.
    • something like
      namespace myModel {
        #include "src/include/models.hpp"
        // ...
      }
      
      I.e., I'm trying to nest the stan namespace into the namespace for each model. Unfortunately this doesn't work either because within the stan namespace there are using declarations which no longer refer to the right things when you nest them.
  2. A different approach is to build the stan models when the package is installed, and then save them as .RData files in the data folder. Then later when the installed package gets loaded, the models aren't rebuilt.

Perhaps I should point out that I implemented approach 2 long before rstantools was released. It worked perfectly until I had to install on a multi-architecture Windows platform. There the models only got built on one platform, and of course R crashed when I tried to load them from the other.

I thought about this some more and I believe the problem can be resolved by building architecture-dependent .RData files at install time, and sealing the objects into the package namespace at load time. However, I don't want to veer off from the stan-supported way of doing things, so I'm asking for advice/feedback on how to proceed.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with tools/make_cpp.R and the cleanup file, focusing on how src/*.cc is combined into src/Modules.cpp and removed. Reproduce the duplicate-symbol linker errors with separate translation units, then verify that the eventual approach supports architecture-dependent package installation without rebuilding every model for unrelated changes.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, r
Domain
build-system, developer-experience
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.