Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

Profiling in CmdStan

In order to use profiling, you need to use CmdStan 2.26 release candidate. You can download it here.

Consider the following model.

data {
  int<lower=1> k;
  int<lower=0> n;
  matrix[n, k] X;
  int y[n];
}
parameters {
  vector[k] beta;
  real alpha;
}
model {
  target += std_normal_lpdf(beta);
  target += std_normal_lpdf(alpha);
  target += bernoulli_logit_lpmf(y | X * beta + alpha);
}

We are interested in profiling the prior statements and the likelihood separately. So we write the profiling statements as follows:

data {
  int<lower=1> k;
  int<lower=0> n;
  matrix[n, k] X;
  int y[n];
}
parameters {
  vector[k] beta;
  real alpha;
}
model {
  profile("priors") {
    target += std_normal_lpdf(beta);
    target += std_normal_lpdf(alpha);
  }
  profile("likelihood") {
      target += bernoulli_logit_lpmf(y | X * beta + alpha);
  }
}

and run it with data available here where k = 50 and ǹ = 1000.

We then run MCMC sampling with 1000 iterations of warmup and 1000 iterations of sampling with the following command:

./model sample data file=lr.data.json output profile_file=lr_profile.csv

Profiling data is stored in lr_profile.csv. We can then cat the CSV file, but we recommend using

column -t -s, lr_profile.csv

for a nicer output. column is available on Unix operating systems. You can also use any software that can open CSV files.

We observe the following:

name        thread_id        total_time  forward_time  reverse_time  chain_stack  no_chain_stack  autodiff_calls  no_autodiff_calls
likelihood  140686068328256  1.7516      1.43386       0.317739      66561        44374000        22187           1
priors      140686068328256  0.0214298   0.0164321     0.00499765    1131537      0               22187           1

In the output we can see the total time spent in each of the profiles, the time spent in the forward and reverse(backward) passes of reverse mode AD, the amount of the chain and nochain stack used and the number of AD calls. See here for descriptions of all the profile CSV columns.

We can see that each likelihood call stores 66561/22187 = 3 items per AD call on the chain stack and 44374000/22187 = 2000 items per AD call on the no chain stack, while the priors places 1131537/22187 = 51 items on the chain stack and does not use the no chain stack.

Now try changing the likelihood call to use the GLM function and observe the difference in both the execution time and memory consumption. The GLM form is:

target += bernoulli_logit_glm_lpmf(y | X, alpha, beta);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment