Closed bob-carpenter closed 4 years ago
Thank you Bob!!!
Suggest no trade off between readability and speed. Include most readable code as comment before fastest code actually run.
Uses will need BOTH.
First, let me say this is all minor details. So no worries no matter how commenting is done!
@dentarthur says:
Suggest no trade off between readability and speed.
There's always a tradeoff because one needs to at least verify in the code that the comments are true. The code never lies about what it's doing, but it's very easy for comments to get stale. Adding complex code with comments thus adds overhead for any programmer trying to modify the code.
I like the advice from Google's C++ style guide:
Do not state the obvious. In particular, don't literally describe what code does, unless the behavior is nonobvious to a reader who understands C++ well. Instead, provide higher level comments that describe why the code does what it does, or make the code self describing.
@dentarthur also says:
Include most readable code as comment before fastest code actually run.
I've found that's not always so easy in Stan code if the optimizations split things across blocks or loops (this will partly be mitigated when we allow inline variable declarations in the near future). When a lot of comments start piling up, code gets hard to read and it can be easier to pull the algorithm descriptions out of the inner guts of the code and into a higher-level doc. We do that in Stan code with marginalizations of discrete parameters, which can require a fair bit of algebra that's too distracting inline.
@bob-carpenter thank you for the helpful comments! I have linked a draft pull request.
@bob-carpenter Thanks for clear explanation/rebuttal
I am sure you are right about what won't work. In any case I certainly don't know.
But I will briefly elaborate on "Uses need both" although there is no need for you to spend time explaining if this is not helpful.
I think there will be three uses of the Stan code and its comments or other annotations (including possible separate code generators/macro processors etc eg for profiling to ensure speedups are actually useful and tests to confirm they do produce same results as readable versions. All of which might be added earlier, later or never.
Running Jupyter notebookks and other apps that use it eg multiple runs with varying paramaters by public health analysts in large numbers of countries and regions (without any interest in modifying Stan code). They will be doing a lot of runs on ordinary PCs and will find the code slow even if the fastest possible version is used.
Maintaining, and enhancing the Stan code for related analysis. Some of this will be done by public health analysts with little familiarity concerning modeling techniques Stan is used for and developers with less. They will (hopefully) be using the readable Stan code together with the Imperial College response team paper and its references and the Stan docs and the Bayesian texts recommended in the Stan docs to understand enough to attempt the changes they wish to make.
Technical documentation writers helping fend off individual queries from large numbers of public health analysts in many regions by writing docs that answer questions already being asked here and do so by actually rather than just "hopefully" studying the readable Stan code in whatever form it is available as well as the rest mentioned under "hopefully" above. Same use as category 2 but doing it in advance for documentation. Need for that is emerging now with questions arriving here at code repo that should end up in being in docs section about docs, not about code.
Whatever method suits the coders the documenters can learn to live with as long as there is some way to be able to find readable versions of the code to understand and explain without raising issues to coders.
@dentarthur : I forgot that you're getting a lot of readers of this who may not be Stan coders. So the usual doc rules don't make as much sense here.
I would still urge some kind of stand-off annotation rather than filling the code with comments, but as you say, that makes it hard to make sure everyone who gets the code also gets the comments.
Good luck!
Edit: forgot to mention that this is the same problem we run into with our tutorials. How to gently introduce the model concepts using simple language constructs yet not have people use those as the basis for saying "Stan is slow".
@bob-carpenter good luck to you and to harrison and rest of the team actually working on it.
I'm just a fly on the wall, but here is a link to related issue offline from here to keep out of the way:
Stan GPU speedup (and ABM CSXMs with SYCL/DPC++) https://github.com/thecapitalistcycle/covid19model/issues/3
Hi @bob-carpenter thanks a lot for useful comments. We are working now to incorporate the changes.
Solved with the commit 865806ff6f7afb393 and other commit by @MansMeg
Is your feature request related to a problem? Please describe.
The issue is related to making the Stan code more efficient and readable.
Describe the solution you'd like
Ideally, someone codes the suggested changes. With some feedback, I can code the changes myself, but I didn't want to make a massive PR that the original developers didn't like.
Describe alternatives you've considered
Remove variable
x
because it's not used. (We're developing a lint mode that'll flag issues like unused variables.)Remove transformed data variable
delta
because it's not used.Rename
covariate1
, ...,covariate6
tox1
, ...,x6
becausex
is conventional for covariates and the term "covariate" doesn't convey much information. Giving these meaningful names would be another possibility.Clarify comment on
N2
as to what days of observed data is. Is itmax(N)
?First, rewrite
Rt[ , m]
for readability:Then rearrange and move to declare/define style followed by an increment for the intercept
For readability, I'd sacrifice a bit of speed and use
instead of
Keep
tau
itself on unit scale for more efficient adaptation:The convolution code can be simplified from
to
It's a bit counter-intuitive, but the loop is faster because it doesn't require a new vector copy on the right hand side and loops without autodiff are very fast in Stan. Given that
preciction[j, m]
was just defined to bey[m]
, that can be used directly to cut down on memory access in the loop.I assume the centered parameterization
works better than the non-centered one, given that other parameters are non-centered. Otherwise, this needs to be rewritten in terms of
and
phi
andkappa
can be put on unit scales,The magic number
1e-9
needs doc in the definition ofE_deaths[1, m]
.E_deaths
shows up in the negative binomial likelihood as a rate parmeter. Is it never used because ofEpidemicStart
? If it's not intended to use, filling unused bits ofE_deaths
with NaN will make sure they raise an error if they're accidentally used somewhere in the target density.Put
rep_matrix
in generated data so it's only done once.The magic number
1000
in the definition ofmatrix_1000
should be documented.One way to document constants is to define them as generated data variables with meaningful names.
The
E_deaths
loop can be pulled up into a function.And then the blocks of code can be replaced by
Also,
f
is an unusual symbol for a matrix.I'm working on getting ragged arrays into the language---sorry we don't have those yet or the indexing would be much simpler!