From 265c5abe526f10aff8d6a96d79b41dc4e8f93f20 Mon Sep 17 00:00:00 2001 From: Brian Ward Date: Mon, 25 Nov 2024 11:11:14 -0500 Subject: [PATCH] stan_csv_reader: fix trying to read non-existant metric for size-0 HMC --- src/stan/io/stan_csv_reader.hpp | 4 + src/test/unit/io/stan_csv_reader_test.cpp | 13 ++ .../io/test_csv_files/no_parameters_hmc.csv | 157 ++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 src/test/unit/io/test_csv_files/no_parameters_hmc.csv diff --git a/src/stan/io/stan_csv_reader.hpp b/src/stan/io/stan_csv_reader.hpp index 22a11947a4..0ca732e32b 100644 --- a/src/stan/io/stan_csv_reader.hpp +++ b/src/stan/io/stan_csv_reader.hpp @@ -250,6 +250,10 @@ class stan_csv_reader { int rows = lines - 3; int cols = std::count(line.begin(), line.end(), ',') + 1; + if (cols == 1) { + // model has no parameters + return; + } adaptation.metric.resize(rows, cols); char comment; // Buffer for comment indicator, # diff --git a/src/test/unit/io/stan_csv_reader_test.cpp b/src/test/unit/io/stan_csv_reader_test.cpp index 864bd1512e..9a84ce8ccd 100644 --- a/src/test/unit/io/stan_csv_reader_test.cpp +++ b/src/test/unit/io/stan_csv_reader_test.cpp @@ -30,6 +30,8 @@ class StanIoStanCsvReader : public testing::Test { "src/test/unit/io/test_csv_files/bernoulli_warmup.csv"); fixed_param_stream.open( "src/test/unit/io/test_csv_files/fixed_param_output.csv"); + no_params_stream.open( + "src/test/unit/io/test_csv_files/no_parameters_hmc.csv"); } void TearDown() { @@ -46,6 +48,7 @@ class StanIoStanCsvReader : public testing::Test { bernoulli_thin_stream.close(); bernoulli_warmup_stream.close(); fixed_param_stream.close(); + no_params_stream.close(); } std::ifstream blocker0_stream, epil0_stream; @@ -58,6 +61,7 @@ class StanIoStanCsvReader : public testing::Test { std::ifstream bernoulli_thin_stream; std::ifstream bernoulli_warmup_stream; std::ifstream fixed_param_stream; + std::ifstream no_params_stream; }; TEST_F(StanIoStanCsvReader, read_metadata1) { @@ -570,6 +574,14 @@ TEST_F(StanIoStanCsvReader, fixed_param) { ASSERT_EQ(10, fixed_param.samples.rows()); } +TEST_F(StanIoStanCsvReader, no_parameters) { + stan::io::stan_csv no_parameters_hmc; + std::stringstream out; + no_parameters_hmc = stan::io::stan_csv_reader::parse(no_params_stream, &out); + ASSERT_EQ(100, no_parameters_hmc.samples.rows()); + ASSERT_EQ(0, no_parameters_hmc.adaptation.metric.size()); +} + TEST_F(StanIoStanCsvReader, no_samples) { std::ifstream no_samples_stream; no_samples_stream.open( @@ -590,4 +602,5 @@ TEST_F(StanIoStanCsvReader, variational) { = stan::io::stan_csv_reader::parse(variational_stream, &out); variational_stream.close(); ASSERT_EQ(1000, variational.metadata.num_samples); + ASSERT_EQ(0, variational.adaptation.metric.size()); } diff --git a/src/test/unit/io/test_csv_files/no_parameters_hmc.csv b/src/test/unit/io/test_csv_files/no_parameters_hmc.csv new file mode 100644 index 0000000000..35dc61f1ac --- /dev/null +++ b/src/test/unit/io/test_csv_files/no_parameters_hmc.csv @@ -0,0 +1,157 @@ +# stan_version_major = 2 +# stan_version_minor = 35 +# stan_version_patch = 0 +# model = sim_model +# start_datetime = 2024-11-25 16:05:51 UTC +# method = sample (Default) +# sample +# num_samples = 100 +# num_warmup = 100 +# save_warmup = false (Default) +# thin = 1 (Default) +# adapt +# engaged = true (Default) +# gamma = 0.05 (Default) +# delta = 0.8 (Default) +# kappa = 0.75 (Default) +# t0 = 10 (Default) +# init_buffer = 75 (Default) +# term_buffer = 50 (Default) +# window = 25 (Default) +# save_metric = false (Default) +# algorithm = hmc (Default) +# hmc +# engine = nuts (Default) +# nuts +# max_depth = 10 (Default) +# metric = diag_e (Default) +# metric_file = (Default) +# stepsize = 1 (Default) +# stepsize_jitter = 0 (Default) +# num_chains = 1 (Default) +# id = 1 (Default) +# data +# file = (Default) +# init = 2 (Default) +# random +# seed = 1799096017 (Default) +# output +# file = output.csv (Default) +# diagnostic_file = (Default) +# refresh = 100 (Default) +# sig_figs = -1 (Default) +# profile_file = profile.csv (Default) +# save_cmdstan_config = false (Default) +# num_threads = 1 (Default) +# stanc_version = %%NAME%%3 %%VERSION%% +# stancflags = +lp__,accept_stat__,stepsize__,treedepth__,n_leapfrog__,divergent__,energy__,x +# Adaptation terminated +# Step size = 1.35996e+14 +# Diagonal elements of inverse mass matrix: +# +0,1,1.35996e+14,1,1,0,0,8.57152 +0,1,1.35996e+14,1,1,0,0,-4.56101 +0,1,1.35996e+14,1,1,0,0,9.30019 +0,1,1.35996e+14,1,1,0,0,-14.6254 +0,1,1.35996e+14,1,1,0,0,8.30123 +0,1,1.35996e+14,1,1,0,0,19.2067 +0,1,1.35996e+14,1,1,0,0,12.6027 +0,1,1.35996e+14,1,1,0,0,-5.70173 +0,1,1.35996e+14,1,1,0,0,3.04002 +0,1,1.35996e+14,1,1,0,0,-8.28215 +0,1,1.35996e+14,1,1,0,0,3.20386 +0,1,1.35996e+14,1,1,0,0,-6.45707 +0,1,1.35996e+14,1,1,0,0,-5.29269 +0,1,1.35996e+14,1,1,0,0,5.1527 +0,1,1.35996e+14,1,1,0,0,-3.69775 +0,1,1.35996e+14,1,1,0,0,-1.77925 +0,1,1.35996e+14,1,1,0,0,-13.7562 +0,1,1.35996e+14,1,1,0,0,-0.789554 +0,1,1.35996e+14,1,1,0,0,-14.0911 +0,1,1.35996e+14,1,1,0,0,-4.71911 +0,1,1.35996e+14,1,1,0,0,-12.7874 +0,1,1.35996e+14,1,1,0,0,15.029 +0,1,1.35996e+14,1,1,0,0,-6.30709 +0,1,1.35996e+14,1,1,0,0,3.50805 +0,1,1.35996e+14,1,1,0,0,9.01495 +0,1,1.35996e+14,1,1,0,0,5.9809 +0,1,1.35996e+14,1,1,0,0,11.02 +0,1,1.35996e+14,1,1,0,0,9.68621 +0,1,1.35996e+14,1,1,0,0,-4.20659 +0,1,1.35996e+14,1,1,0,0,-7.71128 +0,1,1.35996e+14,1,1,0,0,-13.6125 +0,1,1.35996e+14,1,1,0,0,0.541567 +0,1,1.35996e+14,1,1,0,0,-6.96969 +0,1,1.35996e+14,1,1,0,0,2.49902 +0,1,1.35996e+14,1,1,0,0,8.31074 +0,1,1.35996e+14,1,1,0,0,13.4856 +0,1,1.35996e+14,1,1,0,0,-4.60591 +0,1,1.35996e+14,1,1,0,0,6.84733 +0,1,1.35996e+14,1,1,0,0,-16.8676 +0,1,1.35996e+14,1,1,0,0,4.43181 +0,1,1.35996e+14,1,1,0,0,-10.6785 +0,1,1.35996e+14,1,1,0,0,-5.56113 +0,1,1.35996e+14,1,1,0,0,-0.95401 +0,1,1.35996e+14,1,1,0,0,11.2198 +0,1,1.35996e+14,1,1,0,0,3.43417 +0,1,1.35996e+14,1,1,0,0,-11.2942 +0,1,1.35996e+14,1,1,0,0,-14.3029 +0,1,1.35996e+14,1,1,0,0,3.69492 +0,1,1.35996e+14,1,1,0,0,0.319324 +0,1,1.35996e+14,1,1,0,0,-5.95097 +0,1,1.35996e+14,1,1,0,0,5.99333 +0,1,1.35996e+14,1,1,0,0,-6.59629 +0,1,1.35996e+14,1,1,0,0,14.1795 +0,1,1.35996e+14,1,1,0,0,-7.58818 +0,1,1.35996e+14,1,1,0,0,4.89377 +0,1,1.35996e+14,1,1,0,0,4.63195 +0,1,1.35996e+14,1,1,0,0,-4.62905 +0,1,1.35996e+14,1,1,0,0,-11.4145 +0,1,1.35996e+14,1,1,0,0,4.03017 +0,1,1.35996e+14,1,1,0,0,-10.0459 +0,1,1.35996e+14,1,1,0,0,-11.8674 +0,1,1.35996e+14,1,1,0,0,-0.161997 +0,1,1.35996e+14,1,1,0,0,-5.75037 +0,1,1.35996e+14,1,1,0,0,-13.3027 +0,1,1.35996e+14,1,1,0,0,4.86817 +0,1,1.35996e+14,1,1,0,0,11.1937 +0,1,1.35996e+14,1,1,0,0,13.918 +0,1,1.35996e+14,1,1,0,0,-12.2423 +0,1,1.35996e+14,1,1,0,0,22.3588 +0,1,1.35996e+14,1,1,0,0,-8.30628 +0,1,1.35996e+14,1,1,0,0,-6.87127 +0,1,1.35996e+14,1,1,0,0,12.721 +0,1,1.35996e+14,1,1,0,0,-7.86135 +0,1,1.35996e+14,1,1,0,0,-8.56196 +0,1,1.35996e+14,1,1,0,0,-4.04709 +0,1,1.35996e+14,1,1,0,0,-21.6766 +0,1,1.35996e+14,1,1,0,0,-19.6485 +0,1,1.35996e+14,1,1,0,0,1.99421 +0,1,1.35996e+14,1,1,0,0,11.2645 +0,1,1.35996e+14,1,1,0,0,-9.35154 +0,1,1.35996e+14,1,1,0,0,-3.37081 +0,1,1.35996e+14,1,1,0,0,2.46874 +0,1,1.35996e+14,1,1,0,0,7.28248 +0,1,1.35996e+14,1,1,0,0,19.3846 +0,1,1.35996e+14,1,1,0,0,-4.92502 +0,1,1.35996e+14,1,1,0,0,-11.4687 +0,1,1.35996e+14,1,1,0,0,3.12818 +0,1,1.35996e+14,1,1,0,0,-5.79636 +0,1,1.35996e+14,1,1,0,0,12.2196 +0,1,1.35996e+14,1,1,0,0,5.59427 +0,1,1.35996e+14,1,1,0,0,-22.9084 +0,1,1.35996e+14,1,1,0,0,2.70951 +0,1,1.35996e+14,1,1,0,0,-0.604509 +0,1,1.35996e+14,1,1,0,0,1.06201 +0,1,1.35996e+14,1,1,0,0,-3.10986 +0,1,1.35996e+14,1,1,0,0,6.57804 +0,1,1.35996e+14,1,1,0,0,9.0426 +0,1,1.35996e+14,1,1,0,0,3.30854 +0,1,1.35996e+14,1,1,0,0,8.85378 +0,1,1.35996e+14,1,1,0,0,-1.71584 +# +# Elapsed Time: 0 seconds (Warm-up) +# 0 seconds (Sampling) +# 0 seconds (Total) +#