From 5061519c693d77bf92413a7f7caa12c65bfece28 Mon Sep 17 00:00:00 2001 From: Brian Ward Date: Mon, 20 Mar 2023 15:49:35 -0400 Subject: [PATCH 1/2] Standalone GQ: Output NaNs when exception is caught --- src/stan/services/util/gq_writer.hpp | 1 - .../test-models/good/services/test_gq.stan | 4 ++++ .../unit/services/util/gq_writer_test.cpp | 22 +++++++++++++++++-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/stan/services/util/gq_writer.hpp b/src/stan/services/util/gq_writer.hpp index 5d4566773ba..1f656d34d06 100644 --- a/src/stan/services/util/gq_writer.hpp +++ b/src/stan/services/util/gq_writer.hpp @@ -81,7 +81,6 @@ class gq_writer { if (ss.str().length() > 0) logger_.info(ss); logger_.info(e.what()); - return; } if (ss.str().length() > 0) logger_.info(ss); diff --git a/src/test/test-models/good/services/test_gq.stan b/src/test/test-models/good/services/test_gq.stan index c46ec88d534..bb35058df25 100644 --- a/src/test/test-models/good/services/test_gq.stan +++ b/src/test/test-models/good/services/test_gq.stan @@ -16,5 +16,9 @@ generated quantities { vector[2] y_rep; y_rep[1] = normal_rng(y[1], 1); y_rep[2] = normal_rng(y[2], 1); + // trigger exception/nan behavior + if (y[2]>5) + reject("exception in GQ"); + real x2gq = 0.3; } diff --git a/src/test/unit/services/util/gq_writer_test.cpp b/src/test/unit/services/util/gq_writer_test.cpp index 595c45d035b..04b93d9ec38 100644 --- a/src/test/unit/services/util/gq_writer_test.cpp +++ b/src/test/unit/services/util/gq_writer_test.cpp @@ -27,6 +27,7 @@ TEST_F(ServicesUtilGQWriter, t1) { // model test_gq.stan gen quantities block has 3 params: xqg, y_rep.1, // y_rep.2 EXPECT_EQ(count_matches("xgq", sample_ss.str()), 1); + EXPECT_EQ(count_matches("x2gq", sample_ss.str()), 1); EXPECT_EQ(count_matches("y_rep", sample_ss.str()), 2); } @@ -40,6 +41,23 @@ TEST_F(ServicesUtilGQWriter, t2) { draw.push_back(-6.789); stan::services::util::gq_writer writer(sample_writer, logger, 2); writer.write_gq_values(model, rng1, draw); - // model test_gq.stan generates 3 values, 2 commas - EXPECT_EQ(count_matches(",", sample_ss.str()), 2); + // model test_gq.stan generates 4 values, 3 commas + EXPECT_EQ(count_matches(",", sample_ss.str()), 3); + EXPECT_EQ(count_matches("nan", sample_ss.str()), 0); +} + +TEST_F(ServicesUtilGQWriter, TestExceptions) { + stan::callbacks::stream_writer sample_writer(sample_ss, ""); + stan::callbacks::stream_logger logger(logger_ss, logger_ss, logger_ss, + logger_ss, logger_ss); + boost::ecuyer1988 rng1 = stan::services::util::create_rng(0, 1); + std::vector draw; + draw.push_back(2.345); + draw.push_back(6.789); + stan::services::util::gq_writer writer(sample_writer, logger, 2); + writer.write_gq_values(model, rng1, draw); + // model test_gq.stan generates 4 values, 3 commas + EXPECT_EQ(count_matches(",", sample_ss.str()), 3); + + EXPECT_EQ(count_matches("nan", sample_ss.str()), 4); } From 7f78ff07a649c3abf07de669832db324991f9669 Mon Sep 17 00:00:00 2001 From: Brian Ward Date: Mon, 20 Mar 2023 16:07:45 -0400 Subject: [PATCH 2/2] Avoid duplicate logging in exception case --- src/stan/services/util/gq_writer.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stan/services/util/gq_writer.hpp b/src/stan/services/util/gq_writer.hpp index 1f656d34d06..6e3e946435f 100644 --- a/src/stan/services/util/gq_writer.hpp +++ b/src/stan/services/util/gq_writer.hpp @@ -77,13 +77,13 @@ class gq_writer { try { model.write_array(rng, const_cast&>(draw), params_i, values, false, true, &ss); + if (ss.str().length() > 0) + logger_.info(ss); } catch (const std::exception& e) { if (ss.str().length() > 0) logger_.info(ss); logger_.info(e.what()); } - if (ss.str().length() > 0) - logger_.info(ss); std::vector gq_values(values.begin() + num_constrained_params_, values.end());