Compile error when passing local variable as function data argument to map_rect() or algebra_solver()

Hi,

[I’m using {cmdstanr} with CmdStan version 2.26.1]

 
vector map_find_fixedpoint_solution(vector benefit_cost, vector mu_rep, 
                                     real v_mu, vector lambda, vector mix_mean, real v_sd, vector mix_sd, real total_error_sd, real u_sd,
                                     data int num_mix, data int use_u_in_delta, data real alg_sol_rel_tol, data real alg_sol_f_tol, data real alg_sol_max_steps) {
  int num_clusters = num_elements(benefit_cost);
  vector[3 * num_mix + 4] phi = append_row(v_mu, append_row(lambda, append_row(mix_mean, append_row(v_sd, append_row(mix_sd, [total_error_sd, u_sd]')))));
  vector[2] thetas[num_clusters];
  real x_rs[num_clusters, 3] = rep_array({ alg_sol_rel_tol, alg_sol_f_tol, alg_sol_max_steps }, num_clusters);
  int x_is[num_clusters, 2] = rep_array({ num_mix, use_u_in_delta }, num_clusters);
  
  for (cluster_index in 1:num_clusters) {
    thetas[cluster_index] = [ benefit_cost[cluster_index], mu_rep[cluster_index] ]';
  }
  
  // return map_rect(find_fixedpoint_solution_rect, phi, thetas, x_rs, x_is);
  return map_rect(find_fixedpoint_solution_rect, phi, thetas, rep_array({ alg_sol_rel_tol, alg_sol_f_tol, alg_sol_max_steps }, num_clusters) , x_is);
}

This is probably not a map_rect issue but a more general function call issue (I see this with an algebra_solver call). I’m trying to call map_rect as shown above and I’m trying to pass it x_rs and x_is but first I need to construct them (here using rep_array). When I use the x_rs defined below (as in the line commented out) I get a compile error. Weirdly, this only happens with the real[] argument and not the int[] argument. I’m new to map_rect so I wasn’t sure if there is a better way to pass data that is shared across parallel calls (as with the phi parameter).

Semantic error in '/home/karim/Code/takeup/stan_models/takeup_functions.stan', line 235, column 9, included from
'/home/karim/Code/rtemp/RtmpZYhz7M/model-35d4c13ab44f7.stan', line 2, column 0:
   -------------------------------------------------
   233:    }
   234:    
   235:    return map_rect(find_fixedpoint_solution_rect, phi, thetas, x_rs, x_is);
                  ^
   236:  }
   237:  
   -------------------------------------------------

Ill-typed arguments supplied to function 'map_rect'. Available signatures: 
((vector, vector, data real[], data int[]) => vector, vector, vector[], data real[,], data int[,]) => vector
Instead supplied arguments of incompatible type: (vector, vector, data real[], data int[]) => vector, vector, vector[], real[,], int[,].

make: *** [make/program:53: /home/karim/Code/rtemp/RtmpZYhz7M/model-35d4c13ab44f7.hpp] Error 1
Error: An error occured during compilation! See the message above for more information.
1 Like

Can’t help directly as I have little experience with paralellization, but maybe @rok_cesnovar would know?

Thanks for the tag.

First lets look at the error message. First line is what it expects, second what it found:

(vector, vector, data real[], data int[]) => vector, vector, vector[], data real[,], data int[,]
(vector, vector, data real[], data int[]) => vector, vector, vector[], real[,], int[,]

So the last two args are not data cause they are built in udf. When calling higher-order functions inside user-defined functions, special care needs to be take with data-only args.

What you will need to do is build

rep_array({ alg_sol_rel_tol, alg_sol_f_tol, alg_sol_max_steps }, num_clusters)

and

x_is before passing them to map_find_fixedpoint_solution. Not ideal, I know.

This is a bit annoying with map_rect especially, unfortunately. Annoying because an int array is obviously data but the compiler doesnt figure that one out. We are aware of this issue and inconvenience and working to get rid of it but for now this is how it is.

1 Like

Since

data int num_mix, data int use_u_in_delta, data real alg_sol_rel_tol, data real alg_sol_f_tol, data real alg_sol_max_steps and num_elements(benefit_cos)

are all data and constants I would suggest building

rep_array({ alg_sol_rel_tol, alg_sol_f_tol, alg_sol_max_steps }, num_clusters)
and   int x_is[num_clusters, 2] = rep_array({ num_mix, use_u_in_delta }, num_clusters);
rep_array({ alg_sol_rel_tol, alg_sol_f_tol, alg_sol_max_steps }, num_clusters)
int x_is[num_clusters, 2] = rep_array({ num_mix, use_u_in_delta }, num_clusters);

in transformed data actually. No need to rebuild them every call.

1 Like

Thanks, guys. I was able to work around it, but this is helpful. I just wanted to flag it in case it points to some issue with the compiler.

3 Likes