The FAQ has some guidance for RStan users on profiling.
The Stan model I'd like to profile is attached, along with pickled sample of the data and a python script to compile and run.
Along with advice on how to profile it myself, expert opinions on improving efficiency are very welcome!
data {
int N; // number of samples
int K; // number of intercepts
int L; // number of categoricals predictors
int C[L]; // position of last coefficient in each category
int M; // number of non-zero values in sparse design matrix for intercepts
vector[M] c_w; // design matrix in compressed row storage where c_w[i]
int c_v[M]; // is a value from column c_v[i], row j values begin
int c_u[N + 1]; // at position c_u[j] in c_w, and c_u[N + 1] = M.
int P; // number of covariates
matrix[N, P] x; // covariates
int R; // number of non-zero rows in sample matrix augmented with totals
int W; // number of non-zero values in sparse matrix A
//vector[W] A_w; // A in compressed row storage where every A_w[i]
int A_v[W]; // is one, it's from column A_v[i], row j values
int A_u[R + 1]; // begin at position A_u[j] in A_w, and A_u[R + 1] = W
int Q; // number of non-zero values in sparse sample matrix
vector[Q] y; // response value, from sparse matrix,
int y_i[Q]; // such that y[k] reports have more than
vector[Q] y_j; // y_j[k] animals from market:county y_i[k]
}
parameters {
vector[K] alpha;
vector[P] beta;
real<lower=0> sigma; // SD for market-level random effect
}
transformed parameters {
vector[N] log_a;
log_a <- csr_matrix_times_vector(N, K, c_w, c_v, c_u, alpha) + x * beta;
}
model {
// Priors
alpha[C[1]] ~ normal(0, 10);
alpha[(C[2] + 1):C[3]] ~ normal(0, 10);
beta ~ normal(0, 10);
sigma ~ cauchy(0, 2.5);
// Hierarchies
alpha[(C[1] + 1):C[2]] ~ normal(0, sigma);
// Likelihood
{
vector[N] a;
vector[R] b;
int j;
a <- exp(log_a);
b <- rep_vector(0, R);
j <- 1;
// implement csr_matrix_times_vector for binary matrix
// doesn't do any better or worse than the function, though
for (i in 1:R) {
while (j < A_u[i + 1]) {
b[i] <- b[i] + a[A_v[j]];
j <- j + 1;
}
}
increment_log_prob(dot_product(log(b[y_i] + y_j), y));
}
}