diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 88e9a9e387..c1b8072bb3 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -24,4 +24,4 @@ Describe what you expect the output to be. Knowing the correct behavior is also Provide any additional information here. #### Current Version: -v2.32.2 +v2.33.0 diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index d1a5158745..3823d08675 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -5,6 +5,21 @@ Note: these are the release notes for the stan-dev/stan repository. Further changes may arise at the interface level (stan-dev/{rstan, pystan, cmdstan}) and math library level (stan-dev/math). +v2.33.0 (5 September 2023) +====================================================================== + +- Added Pathfinder and Multi-pathfinder to the service APIs. (#3123, #3205) +- Added the `unconstrain_array` method to the model base class as the inverse of `write_array`. (#3179, #3211) +- Support Tuple indices in Stan CSV Header Reader. (#3190) +- Add callback writer to output JSON data for diagnostics. (#3191, #3202) +- Replace use of `boost::lexical_cast` with `std::strol`, etc, and remove spurious header includes. (#3206) +- Fixed several typos in documentation. (#3210) +- Added multi chain service functions for hmc nuts for adapatation and nonadaption for the unit e, diag, and dense metrics. (#3212) +- Made the service functions consistently catch exceptions and favor return codes. (#3214) +- Added a hard copy of the event vector for OpenCL before making a copy to go from a tbb concurrent vector to a standard vector. (#3217) +- Added missing size checks to vectors of Eigen types. (#3218) +- Remove deprecated syntax from remaining tests. (#3220) + v2.32.2 (15 May 2023) ====================================================================== diff --git a/lib/stan_math b/lib/stan_math index bdf281f4e7..5091bf9aa1 160000 --- a/lib/stan_math +++ b/lib/stan_math @@ -1 +1 @@ -Subproject commit bdf281f4e7f8034f47974d14dea7f09e600ac02a +Subproject commit 5091bf9aa1cce0fe69b1cc1a7edef81ac9ebe1e9 diff --git a/src/doxygen/doxygen.cfg b/src/doxygen/doxygen.cfg index f404bc9d45..edd536ec19 100644 --- a/src/doxygen/doxygen.cfg +++ b/src/doxygen/doxygen.cfg @@ -38,7 +38,7 @@ PROJECT_NAME = "Stan" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 2.32.2 +PROJECT_NUMBER = 2.33.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/src/stan/callbacks/json_writer.hpp b/src/stan/callbacks/json_writer.hpp index 54f54bf385..d791b8a737 100644 --- a/src/stan/callbacks/json_writer.hpp +++ b/src/stan/callbacks/json_writer.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -28,7 +29,7 @@ namespace callbacks { * output stream */ template > -class json_writer { +class json_writer final : public structured_writer { private: // Output stream std::unique_ptr output_{nullptr}; @@ -37,30 +38,17 @@ class json_writer { // Depth of records (used to determine whether or not to print comma // separator) int record_depth_ = 0; - // Whether or not the record's parent object needs a comma separator - bool record_needs_comma_ = false; - - /** - * Writes a comma separator for the record's parent object if needed. - */ - void write_record_comma_if_needed() { - if (record_depth_ > 0 && record_needs_comma_) { - *output_ << ",\n"; - record_needs_comma_ = false; - } else { - write_sep(); - } - } /** * Determines whether a record's internal object requires a comma separator */ void write_sep() { if (record_element_needs_comma_) { - *output_ << ", "; + *output_ << ","; } else { record_element_needs_comma_ = true; } + *output_ << "\n"; } /** @@ -109,7 +97,18 @@ class json_writer { * @param[in] key member name. */ void write_key(const std::string& key) { - *output_ << "\"" << process_string(key) << "\" : "; + *output_ << std::string(record_depth_ * 2, ' ') << "\"" + << process_string(key) << "\" : "; + } + + template + void write_int_like(const std::string& key, T value) { + if (output_ == nullptr) { + return; + } + write_sep(); + write_key(key); + *output_ << value; } /** @@ -144,82 +143,10 @@ class json_writer { *output_ << "]"; } - /** - * Writes a set of comma separated strings. - * Strings are cleaned to escape special characters. - * - * @param[in] v Values in a std::vector - */ - void write_vector(const std::vector& v) { - *output_ << "[ "; - if (v.size() > 0) { - auto last = v.end(); - --last; - for (auto it = v.begin(); it != last; ++it) { - *output_ << process_string(*it) << ", "; - } - } - *output_ << v.back() << " ]"; - } - - /** - * Writes a set of comma separated double values. - * - * @param[in] v Values in a std::vector - */ - void write_vector(const std::vector& v) { - *output_ << "[ "; - if (v.size() > 0) { - auto last = v.end(); - --last; - for (auto it = v.begin(); it != last; ++it) { - write_value(*it); - *output_ << ", "; - } - write_value(v.back()); - } - *output_ << " ]"; - } - - /** - * Writes a set of comma separated integer values. - * - * @param[in] v Values in a std::vector - */ - void write_vector(const std::vector& v) { - *output_ << "[ "; - if (v.size() > 0) { - auto last = v.end(); - --last; - for (auto it = v.begin(); it != last; ++it) { - *output_ << *it << ", "; - } - } - *output_ << v.back() << " ]"; - } - - /** - * Writes a set of comma separated complex values. - * - * @param[in] v Values in a std::vector - */ - void write_vector(const std::vector>& v) { - *output_ << "[ "; - if (v.size() > 0) { - size_t last = v.size() - 1; - for (size_t i = 0; i < last; ++i) { - write_complex_value(v[i]); - *output_ << ", "; - } - write_complex_value(v[last]); - } - *output_ << " ]"; - } - /** * Writes the set of comma separated values in an Eigen (row) vector. * - * @param[in] v Values in a std::vector + * @param[in] v Values in an `Eigen::Vector` */ template void write_eigen_vector(const Eigen::DenseBase& v) { @@ -258,15 +185,16 @@ class json_writer { json_writer(json_writer&& other) noexcept : output_(std::move(other.output_)) {} - ~json_writer() {} + virtual ~json_writer() {} /** * Writes "{", initial token of a JSON record. */ void begin_record() { - if (output_ == nullptr) + if (output_ == nullptr) { return; - write_record_comma_if_needed(); + } + write_sep(); *output_ << "{"; record_depth_++; record_element_needs_comma_ = false; @@ -277,10 +205,12 @@ class json_writer { * @param[in] key The name of the record. */ void begin_record(const std::string& key) { - if (output_ == nullptr) + if (output_ == nullptr) { return; - write_record_comma_if_needed(); - *output_ << "\"" << key << "\" : {"; + } + write_sep(); + write_key(key); + *output_ << "{"; record_depth_++; record_element_needs_comma_ = false; } @@ -288,12 +218,13 @@ class json_writer { * Writes "}", final token of a JSON record. */ void end_record() { - if (output_ == nullptr) + if (output_ == nullptr) { return; - *output_ << "}"; + } record_depth_--; + *output_ << "\n" << std::string(record_depth_ * 2, ' ') << "}"; if (record_depth_ > 0) { - record_needs_comma_ = true; + record_element_needs_comma_ = true; } else { *output_ << "\n"; } @@ -305,8 +236,9 @@ class json_writer { * @param key Name of the value pair */ void write(const std::string& key) { - if (output_ == nullptr) + if (output_ == nullptr) { return; + } write_sep(); write_key(key); *output_ << "null"; @@ -318,8 +250,9 @@ class json_writer { * @param value string to write. */ void write(const std::string& key, const std::string& value) { - if (output_ == nullptr) + if (output_ == nullptr) { return; + } std::string processsed_string = process_string(value); write_sep(); write_key(key); @@ -332,8 +265,9 @@ class json_writer { * @param value pointer to chars to write. */ void write(const std::string& key, const char* value) { - if (output_ == nullptr) + if (output_ == nullptr) { return; + } std::string processsed_string = process_string(value); write_sep(); write_key(key); @@ -346,8 +280,9 @@ class json_writer { * @param value bool to write. */ void write(const std::string& key, bool value) { - if (output_ == nullptr) + if (output_ == nullptr) { return; + } write_sep(); write_key(key); *output_ << (value ? "true" : "false"); @@ -358,13 +293,7 @@ class json_writer { * @param key Name of the value pair * @param value int to write. */ - void write(const std::string& key, int value) { - if (output_ == nullptr) - return; - write_sep(); - write_key(key); - *output_ << value; - } + void write(const std::string& key, int value) { write_int_like(key, value); } /** * Write a key-value pair where the value is an `std::size_t`. @@ -372,11 +301,27 @@ class json_writer { * @param value `std::size_t` to write. */ void write(const std::string& key, std::size_t value) { - if (output_ == nullptr) - return; - write_sep(); - write_key(key); - *output_ << value; + write_int_like(key, value); + } + + /** + * Write a key-value pair where the value is an `long long int`. + * @param key Name of the value pair + * @param value `long long int` to write. + */ + void write(const std::string& key, + long long int value // NOLINT(runtime/int) + ) { + write_int_like(key, value); + } + + /** + * Write a key-value pair where the value is an `unsigned int`. + * @param key Name of the value pair + * @param value `unsigned int` to write. + */ + void write(const std::string& key, unsigned int value) { + write_int_like(key, value); } /** @@ -385,8 +330,9 @@ class json_writer { * @param value double to write. */ void write(const std::string& key, double value) { - if (output_ == nullptr) + if (output_ == nullptr) { return; + } write_sep(); write_key(key); write_value(value); @@ -398,8 +344,9 @@ class json_writer { * @param value complex value to write. */ void write(const std::string& key, const std::complex& value) { - if (output_ == nullptr) + if (output_ == nullptr) { return; + } write_sep(); write_key(key); write_complex_value(value); @@ -410,13 +357,95 @@ class json_writer { * @param key Name of the value pair * @param values vector to write. */ - template - void write(const std::string& key, const std::vector& values) { - if (output_ == nullptr) + void write(const std::string& key, const std::vector& values) { + if (output_ == nullptr) { + return; + } + write_sep(); + write_key(key); + + *output_ << "[ "; + if (values.size() > 0) { + auto last = values.end(); + --last; + for (auto it = values.begin(); it != last; ++it) { + *output_ << process_string(*it) << ", "; + } + } + *output_ << values.back() << " ]"; + } + + /** + * Write a key-value pair where the value is a vector to be made a list. + * @param key Name of the value pair + * @param values vector to write. + */ + void write(const std::string& key, const std::vector& values) { + if (output_ == nullptr) { + return; + } + write_sep(); + write_key(key); + + *output_ << "[ "; + if (values.size() > 0) { + auto last = values.end(); + --last; + for (auto it = values.begin(); it != last; ++it) { + write_value(*it); + *output_ << ", "; + } + write_value(values.back()); + } + *output_ << " ]"; + } + + /** + * Write a key-value pair where the value is a vector to be made a list. + * @param key Name of the value pair + * @param values vector to write. + */ + void write(const std::string& key, const std::vector& values) { + if (output_ == nullptr) { + return; + } + write_sep(); + write_key(key); + + *output_ << "[ "; + if (values.size() > 0) { + auto last = values.end(); + --last; + for (auto it = values.begin(); it != last; ++it) { + *output_ << *it << ", "; + } + } + *output_ << values.back() << " ]"; + } + + /** + * Write a key-value pair where the value is a vector to be made a list. + * @param key Name of the value pair + * @param values vector to write. + */ + void write(const std::string& key, + const std::vector>& values) { + if (output_ == nullptr) { return; + } write_sep(); write_key(key); - write_vector(values); + + *output_ << "[ "; + if (values.size() > 0) { + size_t last = values.size() - 1; + for (size_t i = 0; i < last; ++i) { + write_complex_value(values[i]); + *output_ << ", "; + } + write_complex_value(values[last]); + } + *output_ << " ]"; } /** @@ -425,8 +454,9 @@ class json_writer { * @param vec Eigen Vector to write. */ void write(const std::string& key, const Eigen::VectorXd& vec) { - if (output_ == nullptr) + if (output_ == nullptr) { return; + } write_sep(); write_key(key); write_eigen_vector(vec); @@ -438,8 +468,9 @@ class json_writer { * @param vec Eigen Vector to write. */ void write(const std::string& key, const Eigen::RowVectorXd& vec) { - if (output_ == nullptr) + if (output_ == nullptr) { return; + } write_sep(); write_key(key); write_eigen_vector(vec); @@ -451,8 +482,9 @@ class json_writer { * @param mat Eigen Matrix to write. */ void write(const std::string& key, const Eigen::MatrixXd& mat) { - if (output_ == nullptr) + if (output_ == nullptr) { return; + } write_sep(); write_key(key); *output_ << "[ "; diff --git a/src/stan/callbacks/structured_writer.hpp b/src/stan/callbacks/structured_writer.hpp index b3f34857d9..868c4c0cf3 100644 --- a/src/stan/callbacks/structured_writer.hpp +++ b/src/stan/callbacks/structured_writer.hpp @@ -29,23 +29,13 @@ class structured_writer { * Writes key followed by start token of a structured record. * @param[in] key The name of the record. */ - virtual void begin_record(const std::string& key, bool newline = false) {} + virtual void begin_record(const std::string& key) {} /** * Writes end token of a structured record. */ virtual void end_record() {} - /** - * Writes start token of a list. - */ - virtual void begin_list() {} - - /** - * Writes end token of a list. - */ - virtual void end_list() {} - /** * Write a key-value pair to the output stream with a value of null as the * value. @@ -60,11 +50,6 @@ class structured_writer { */ virtual void write(const std::string& key, const std::string& value) {} - /** - * No-op - */ - virtual void write() {} - /** * Write a key-value pair where the value is a bool. * @param key Name of the value pair @@ -86,6 +71,22 @@ class structured_writer { */ virtual void write(const std::string& key, std::size_t value) {} + /** + * Write a key-value pair where the value is an `long long int`. + * @param key Name of the value pair + * @param value `long long int` to write. + */ + virtual void write(const std::string& key, + long long int value // NOLINT(runtime/int) + ) {} + + /** + * Write a key-value pair where the value is an `unsigned int`. + * @param key Name of the value pair + * @param value `unsigned int` to write. + */ + virtual void write(const std::string& key, unsigned int value) {} + /** * Write a key-value pair where the value is a double. * @param key Name of the value pair @@ -105,8 +106,8 @@ class structured_writer { * @param key Name of the value pair * @param values vector to write. */ - virtual void write(const std::string& key, const std::vector values) { - } + virtual void write(const std::string& key, + const std::vector& values) {} /** * Write a key-value pair where the value is a vector of strings to be made a @@ -114,40 +115,51 @@ class structured_writer { * @param key Name of the value pair * @param values vector of strings to write. */ - void write(const std::string& key, const std::vector& values) {} + virtual void write(const std::string& key, + const std::vector& values) {} + + /** + * Write a key-value pair where the value is a vector to be made a list. + * @param key Name of the value pair + * @param values vector to write. + */ + virtual void write(const std::string& key, + const std::vector>& values) {} + + /** + * Write a key-value pair where the value is a vector to be made a list. + * @param key Name of the value pair + * @param values vector to write. + */ + virtual void write(const std::string& key, const std::vector& values) {} /** * Write a key-value pair where the value is an Eigen Matrix. * @param key Name of the value pair * @param mat Eigen Matrix to write. */ - void write(const std::string& key, const Eigen::MatrixXd& mat) {} + virtual void write(const std::string& key, const Eigen::MatrixXd& mat) {} /** * Write a key-value pair where the value is an Eigen Vector. * @param key Name of the value pair * @param vec Eigen Vector to write. */ - void write(const std::string& key, const Eigen::VectorXd& vec) {} + virtual void write(const std::string& key, const Eigen::VectorXd& vec) {} /** * Write a key-value pair where the value is a Eigen RowVector. * @param key Name of the value pair * @param vec Eigen RowVector to write. */ - void write(const std::string& key, const Eigen::RowVectorXd& vec) {} + virtual void write(const std::string& key, const Eigen::RowVectorXd& vec) {} /** * Write a key-value pair where the value is a const char*. * @param key Name of the value pair * @param value pointer to chars to write. */ - void write(const std::string& key, const char* value) {} - - /** - * Reset state - */ - virtual void reset() {} + virtual void write(const std::string& key, const char* value) {} }; } // namespace callbacks diff --git a/src/stan/mcmc/hmc/base_hmc.hpp b/src/stan/mcmc/hmc/base_hmc.hpp index 50154f404a..1d9c922343 100644 --- a/src/stan/mcmc/hmc/base_hmc.hpp +++ b/src/stan/mcmc/hmc/base_hmc.hpp @@ -64,18 +64,18 @@ class base_hmc : public base_mcmc { write_sampler_metric(writer); } - /** * write stepsize and elements of mass matrix as a JSON object */ template > - void write_sampler_state_json(callbacks::json_writer& json_writer) { + void write_sampler_state_json( + callbacks::json_writer& json_writer) { json_writer.begin_record(); json_writer.write("stepsize", get_nominal_stepsize()); json_writer.write("inv_metric", z_.inv_e_metric_); json_writer.end_record(); } - + void get_sampler_diagnostic_names(std::vector& model_names, std::vector& names) { z_.get_param_names(model_names, names); @@ -196,7 +196,7 @@ class base_hmc : public base_mcmc { protected: typename Hamiltonian::PointType z_; - Integrator > integrator_; + Integrator> integrator_; Hamiltonian hamiltonian_; BaseRNG& rand_int_; diff --git a/src/stan/model/model_base_crtp.hpp b/src/stan/model/model_base_crtp.hpp index e0366a2f7a..5a64ced8c0 100644 --- a/src/stan/model/model_base_crtp.hpp +++ b/src/stan/model/model_base_crtp.hpp @@ -137,7 +137,7 @@ class model_base_crtp : public stan::model::model_base { Eigen::VectorXd& vars, bool include_tparams = true, bool include_gqs = true, std::ostream* msgs = 0) const override { - return static_cast(this)->template write_array( + return static_cast(this)->write_array( rng, theta, vars, include_tparams, include_gqs, msgs); } @@ -206,7 +206,7 @@ class model_base_crtp : public stan::model::model_base { std::vector& theta_i, std::vector& vars, bool include_tparams = true, bool include_gqs = true, std::ostream* msgs = 0) const override { - return static_cast(this)->template write_array( + return static_cast(this)->write_array( rng, theta, theta_i, vars, include_tparams, include_gqs, msgs); } diff --git a/src/stan/optimization/bfgs_linesearch.hpp b/src/stan/optimization/bfgs_linesearch.hpp index 312459e378..e2c375a609 100644 --- a/src/stan/optimization/bfgs_linesearch.hpp +++ b/src/stan/optimization/bfgs_linesearch.hpp @@ -195,7 +195,8 @@ int WolfLSZoom(Scalar &alpha, XType &newX, Scalar &newF, XType &newDF, * * @param x1 Final point, equal to \f$ x_0 + \alpha p \f$. * - * @param f1 Final point function value, equal to \f$ f(x_0 + \alpha p) \f$. + * @param func_val Final point function value, equal to \f$ f(x_0 + \alpha p) + *\f$. * * @param gradx1 Final point gradient, equal to \f$ g(x_0 + \alpha p) \f$. * diff --git a/src/stan/services/pathfinder/psis.hpp b/src/stan/services/pathfinder/psis.hpp index cb52c47f78..7a13a80726 100644 --- a/src/stan/services/pathfinder/psis.hpp +++ b/src/stan/services/pathfinder/psis.hpp @@ -262,8 +262,9 @@ inline Eigen::Array psis_weights( } if (smoothed.second > 0.7) { logger.warn(std::string("Pareto k value (") + - std::to_string(smoothed.second) + ") is greater than 0.7 which often" - " indicates model" " misspecification."); + std::to_string(smoothed.second) + ") is greater than 0.7." + " Importance resampling was not able to improve the approximation," + " which may indicate that the approximation itself is poor."); } } } diff --git a/src/stan/services/sample/fixed_param.hpp b/src/stan/services/sample/fixed_param.hpp index f9674f2db3..5a63b3598c 100644 --- a/src/stan/services/sample/fixed_param.hpp +++ b/src/stan/services/sample/fixed_param.hpp @@ -158,7 +158,8 @@ int fixed_param(Model& model, const std::size_t num_chains, samples.emplace_back(cont_vectors[i], 0, 0); dummy_metric_writers.emplace_back( stan::callbacks::json_writer()); - writers.emplace_back(sample_writers[i], diagnostic_writers[i], dummy_metric_writers[i], logger); + writers.emplace_back(sample_writers[i], diagnostic_writers[i], + dummy_metric_writers[i], logger); // Headers writers[i].write_sample_names(samples[i], samplers[i], model); writers[i].write_diagnostic_names(samples[i], samplers[i], model); diff --git a/src/stan/services/sample/hmc_nuts_dense_e_adapt.hpp b/src/stan/services/sample/hmc_nuts_dense_e_adapt.hpp index ab7be4f918..fb21b28783 100644 --- a/src/stan/services/sample/hmc_nuts_dense_e_adapt.hpp +++ b/src/stan/services/sample/hmc_nuts_dense_e_adapt.hpp @@ -104,10 +104,10 @@ int hmc_nuts_dense_e_adapt( sampler.set_window_params(num_warmup, init_buffer, term_buffer, window, logger); - util::run_adaptive_sampler( - sampler, model, cont_vector, num_warmup, num_samples, num_thin, refresh, - save_warmup, rng, interrupt, logger, sample_writer, diagnostic_writer, - metric_writer); + util::run_adaptive_sampler(sampler, model, cont_vector, num_warmup, + num_samples, num_thin, refresh, save_warmup, rng, + interrupt, logger, sample_writer, + diagnostic_writer, metric_writer); return error_codes::OK; } @@ -170,8 +170,8 @@ int hmc_nuts_dense_e_adapt( /** * Runs HMC with NUTS with adaptation using dense Euclidean metric, - * with identity matrix as initial inv_metric and saves adapted tuning parameters - * stepsize and inverse metric. + * with identity matrix as initial inv_metric and saves adapted tuning + * parameters stepsize and inverse metric. * * @tparam Model Model class * @tparam Stream A type with with a valid `operator<<(std::string)` @@ -400,12 +400,11 @@ int hmc_nuts_dense_e_adapt( &sample_writer, &cont_vectors, &diagnostic_writer, &metric_writer](const tbb::blocked_range& r) { for (size_t i = r.begin(); i != r.end(); ++i) { - util::run_adaptive_sampler(samplers[i], model, cont_vectors[i], - num_warmup, num_samples, num_thin, refresh, - save_warmup, rngs[i], interrupt, logger, - sample_writer[i], diagnostic_writer[i], - metric_writer[i], init_chain_id + i, - num_chains); + util::run_adaptive_sampler( + samplers[i], model, cont_vectors[i], num_warmup, num_samples, + num_thin, refresh, save_warmup, rngs[i], interrupt, logger, + sample_writer[i], diagnostic_writer[i], metric_writer[i], + init_chain_id + i, num_chains); } }, tbb::simple_partitioner()); @@ -481,11 +480,10 @@ int hmc_nuts_dense_e_adapt( if (num_chains == 1) { return hmc_nuts_dense_e_adapt( model, *init[0], *init_inv_metric[0], random_seed, init_chain_id, - init_radius, num_warmup, num_samples, num_thin, save_warmup, - refresh, stepsize, stepsize_jitter, max_depth, delta, gamma, - kappa, t0, init_buffer, term_buffer, window, interrupt, logger, - init_writer[0], sample_writer[0], - diagnostic_writer[0], dummy_metric_writer[0]); + init_radius, num_warmup, num_samples, num_thin, save_warmup, refresh, + stepsize, stepsize_jitter, max_depth, delta, gamma, kappa, t0, + init_buffer, term_buffer, window, interrupt, logger, init_writer[0], + sample_writer[0], diagnostic_writer[0], dummy_metric_writer[0]); } return hmc_nuts_dense_e_adapt( model, num_chains, init, init_inv_metric, random_seed, init_chain_id, @@ -497,8 +495,8 @@ int hmc_nuts_dense_e_adapt( /** * Runs multiple chains of NUTS with adaptation using dense Euclidean metric, - * with identity matrix as initial inv_metric and saves adapted tuning parameters - * stepsize and inverse metric. + * with identity matrix as initial inv_metric and saves adapted tuning + * parameters stepsize and inverse metric. * * @tparam Model Model class * @tparam InitContextPtr A pointer with underlying type derived from @@ -566,11 +564,10 @@ int hmc_nuts_dense_e_adapt( if (num_chains == 1) { return hmc_nuts_dense_e_adapt( model, *init[0], *unit_e_metric[0], random_seed, init_chain_id, - init_radius, num_warmup, num_samples, num_thin, save_warmup, - refresh, stepsize, stepsize_jitter, max_depth, delta, gamma, - kappa, t0, init_buffer, term_buffer, window, interrupt, logger, - init_writer[0], sample_writer[0], - diagnostic_writer[0], metric_writer[0]); + init_radius, num_warmup, num_samples, num_thin, save_warmup, refresh, + stepsize, stepsize_jitter, max_depth, delta, gamma, kappa, t0, + init_buffer, term_buffer, window, interrupt, logger, init_writer[0], + sample_writer[0], diagnostic_writer[0], metric_writer[0]); } return hmc_nuts_dense_e_adapt( model, num_chains, init, unit_e_metric, random_seed, init_chain_id, @@ -653,11 +650,10 @@ int hmc_nuts_dense_e_adapt( if (num_chains == 1) { return hmc_nuts_dense_e_adapt( model, *init[0], *unit_e_metric[0], random_seed, init_chain_id, - init_radius, num_warmup, num_samples, num_thin, save_warmup, - refresh, stepsize, stepsize_jitter, max_depth, delta, gamma, - kappa, t0, init_buffer, term_buffer, window, interrupt, logger, - init_writer[0], sample_writer[0], - diagnostic_writer[0], dummy_metric_writer[0]); + init_radius, num_warmup, num_samples, num_thin, save_warmup, refresh, + stepsize, stepsize_jitter, max_depth, delta, gamma, kappa, t0, + init_buffer, term_buffer, window, interrupt, logger, init_writer[0], + sample_writer[0], diagnostic_writer[0], dummy_metric_writer[0]); } return hmc_nuts_dense_e_adapt( model, num_chains, init, unit_e_metric, random_seed, init_chain_id, diff --git a/src/stan/services/sample/hmc_nuts_diag_e_adapt.hpp b/src/stan/services/sample/hmc_nuts_diag_e_adapt.hpp index 8f039430bf..5f4715bcbf 100644 --- a/src/stan/services/sample/hmc_nuts_diag_e_adapt.hpp +++ b/src/stan/services/sample/hmc_nuts_diag_e_adapt.hpp @@ -107,10 +107,10 @@ int hmc_nuts_diag_e_adapt( sampler.set_window_params(num_warmup, init_buffer, term_buffer, window, logger); - util::run_adaptive_sampler( - sampler, model, cont_vector, num_warmup, num_samples, num_thin, refresh, - save_warmup, rng, interrupt, logger, sample_writer, diagnostic_writer, - metric_writer); + util::run_adaptive_sampler(sampler, model, cont_vector, num_warmup, + num_samples, num_thin, refresh, save_warmup, rng, + interrupt, logger, sample_writer, + diagnostic_writer, metric_writer); return error_codes::OK; } @@ -176,8 +176,8 @@ int hmc_nuts_diag_e_adapt( /** * Runs HMC with NUTS with adaptation using diagonal Euclidean metric, - * with identity matrix as initial inv_metric and saves adapted tuning parameters - * stepsize and inverse metric. + * with identity matrix as initial inv_metric and saves adapted tuning + * parameters stepsize and inverse metric. * * @tparam Model Model class * @tparam Stream A type with with a valid `operator<<(std::string)` @@ -408,12 +408,11 @@ int hmc_nuts_diag_e_adapt( &sample_writer, &cont_vectors, &diagnostic_writer, &metric_writer](const tbb::blocked_range& r) { for (size_t i = r.begin(); i != r.end(); ++i) { - util::run_adaptive_sampler(samplers[i], model, cont_vectors[i], - num_warmup, num_samples, num_thin, refresh, - save_warmup, rngs[i], interrupt, logger, - sample_writer[i], diagnostic_writer[i], - metric_writer[i], init_chain_id + i, - num_chains); + util::run_adaptive_sampler( + samplers[i], model, cont_vectors[i], num_warmup, num_samples, + num_thin, refresh, save_warmup, rngs[i], interrupt, logger, + sample_writer[i], diagnostic_writer[i], metric_writer[i], + init_chain_id + i, num_chains); } }, tbb::simple_partitioner()); @@ -489,11 +488,10 @@ int hmc_nuts_diag_e_adapt( if (num_chains == 1) { return hmc_nuts_diag_e_adapt( model, *init[0], *init_inv_metric[0], random_seed, init_chain_id, - init_radius, num_warmup, num_samples, num_thin, save_warmup, - refresh, stepsize, stepsize_jitter, max_depth, delta, gamma, - kappa, t0, init_buffer, term_buffer, window, interrupt, logger, - init_writer[0], sample_writer[0], - diagnostic_writer[0], dummy_metric_writer[0]); + init_radius, num_warmup, num_samples, num_thin, save_warmup, refresh, + stepsize, stepsize_jitter, max_depth, delta, gamma, kappa, t0, + init_buffer, term_buffer, window, interrupt, logger, init_writer[0], + sample_writer[0], diagnostic_writer[0], dummy_metric_writer[0]); } return hmc_nuts_diag_e_adapt( model, num_chains, init, init_inv_metric, random_seed, init_chain_id, @@ -505,8 +503,8 @@ int hmc_nuts_diag_e_adapt( /** * Runs multiple chains of HMC with NUTS with adaptation using diagonal - * with identity matrix as initial inv_metric and saves adapted tuning parameters - * stepsize and inverse metric. + * with identity matrix as initial inv_metric and saves adapted tuning + * parameters stepsize and inverse metric. * * @tparam Model Model class * @tparam InitContextPtr A pointer with underlying type derived from @@ -553,9 +551,9 @@ int hmc_nuts_diag_e_adapt( * @param[in,out] metric_writer std vector of Writers for tuning params * @return error_codes::OK if successful */ -template > +template > int hmc_nuts_diag_e_adapt( Model& model, size_t num_chains, const std::vector& init, unsigned int random_seed, unsigned int init_chain_id, double init_radius, @@ -577,11 +575,10 @@ int hmc_nuts_diag_e_adapt( if (num_chains == 1) { return hmc_nuts_diag_e_adapt( model, *init[0], *unit_e_metric[0], random_seed, init_chain_id, - init_radius, num_warmup, num_samples, num_thin, save_warmup, - refresh, stepsize, stepsize_jitter, max_depth, delta, gamma, - kappa, t0, init_buffer, term_buffer, window, interrupt, logger, - init_writer[0], sample_writer[0], - diagnostic_writer[0], metric_writer[0]); + init_radius, num_warmup, num_samples, num_thin, save_warmup, refresh, + stepsize, stepsize_jitter, max_depth, delta, gamma, kappa, t0, + init_buffer, term_buffer, window, interrupt, logger, init_writer[0], + sample_writer[0], diagnostic_writer[0], metric_writer[0]); } return hmc_nuts_diag_e_adapt( model, num_chains, init, unit_e_metric, random_seed, init_chain_id, @@ -637,8 +634,8 @@ int hmc_nuts_diag_e_adapt( * information of each chain. * @return error_codes::OK if successful */ -template +template int hmc_nuts_diag_e_adapt( Model& model, size_t num_chains, const std::vector& init, unsigned int random_seed, unsigned int init_chain_id, double init_radius, @@ -665,11 +662,10 @@ int hmc_nuts_diag_e_adapt( if (num_chains == 1) { return hmc_nuts_diag_e_adapt( model, *init[0], *unit_e_metric[0], random_seed, init_chain_id, - init_radius, num_warmup, num_samples, num_thin, save_warmup, - refresh, stepsize, stepsize_jitter, max_depth, delta, gamma, - kappa, t0, init_buffer, term_buffer, window, interrupt, logger, - init_writer[0], sample_writer[0], - diagnostic_writer[0], dummy_metric_writer[0]); + init_radius, num_warmup, num_samples, num_thin, save_warmup, refresh, + stepsize, stepsize_jitter, max_depth, delta, gamma, kappa, t0, + init_buffer, term_buffer, window, interrupt, logger, init_writer[0], + sample_writer[0], diagnostic_writer[0], dummy_metric_writer[0]); } return hmc_nuts_diag_e_adapt( model, num_chains, init, unit_e_metric, random_seed, init_chain_id, diff --git a/src/stan/services/sample/hmc_nuts_unit_e_adapt.hpp b/src/stan/services/sample/hmc_nuts_unit_e_adapt.hpp index f0bd6852cd..36e5dd5f42 100644 --- a/src/stan/services/sample/hmc_nuts_unit_e_adapt.hpp +++ b/src/stan/services/sample/hmc_nuts_unit_e_adapt.hpp @@ -86,10 +86,10 @@ int hmc_nuts_unit_e_adapt( sampler.get_stepsize_adaptation().set_kappa(kappa); sampler.get_stepsize_adaptation().set_t0(t0); - util::run_adaptive_sampler( - sampler, model, cont_vector, num_warmup, num_samples, num_thin, refresh, - save_warmup, rng, interrupt, logger, sample_writer, diagnostic_writer, - metric_writer); + util::run_adaptive_sampler(sampler, model, cont_vector, num_warmup, + num_samples, num_thin, refresh, save_warmup, rng, + interrupt, logger, sample_writer, + diagnostic_writer, metric_writer); return error_codes::OK; } @@ -133,11 +133,10 @@ int hmc_nuts_unit_e_adapt( callbacks::writer& sample_writer, callbacks::writer& diagnostic_writer) { callbacks::json_writer dummy_metric_writer; return hmc_nuts_unit_e_adapt( - model, init, random_seed, chain, init_radius, num_warmup, - num_samples, num_thin, save_warmup, refresh, stepsize, stepsize_jitter, - max_depth, delta, gamma, kappa, t0, - interrupt, logger, init_writer, sample_writer, diagnostic_writer, - dummy_metric_writer); + model, init, random_seed, chain, init_radius, num_warmup, num_samples, + num_thin, save_warmup, refresh, stepsize, stepsize_jitter, max_depth, + delta, gamma, kappa, t0, interrupt, logger, init_writer, sample_writer, + diagnostic_writer, dummy_metric_writer); } /** @@ -159,7 +158,8 @@ int hmc_nuts_unit_e_adapt( * @param[in] init An std vector of init var contexts for initialization of each * chain. * @param[in] random_seed random seed for the random number generator - * @param[in] chain chain id to advance the pseudo random number generator + * @param[in] init_chain_id chain id to advance the pseudo random number + * generator * @param[in] init_radius radius to initialize * @param[in] num_warmup Number of warmup samples * @param[in] num_samples Number of samples @@ -184,8 +184,8 @@ int hmc_nuts_unit_e_adapt( * @return error_codes::OK if successful */ template > + typename SampleWriter, typename DiagnosticWriter, typename Stream, + typename Deleter = std::default_delete> int hmc_nuts_unit_e_adapt( Model& model, size_t num_chains, const std::vector& init, unsigned int random_seed, unsigned int init_chain_id, double init_radius, @@ -236,16 +236,14 @@ int hmc_nuts_unit_e_adapt( tbb::blocked_range(0, num_chains, 1), [num_warmup, num_samples, num_thin, refresh, save_warmup, num_chains, init_chain_id, &samplers, &model, &rngs, &interrupt, &logger, - &sample_writer, &cont_vectors, - &diagnostic_writer, &metric_writer](const tbb::blocked_range& r) - { + &sample_writer, &cont_vectors, &diagnostic_writer, + &metric_writer](const tbb::blocked_range& r) { for (size_t i = r.begin(); i != r.end(); ++i) { - util::run_adaptive_sampler(samplers[i], model, cont_vectors[i], - num_warmup, num_samples, num_thin, refresh, - save_warmup, rngs[i], interrupt, logger, - sample_writer[i], diagnostic_writer[i], - metric_writer[i], init_chain_id + i, - num_chains); + util::run_adaptive_sampler( + samplers[i], model, cont_vectors[i], num_warmup, num_samples, + num_thin, refresh, save_warmup, rngs[i], interrupt, logger, + sample_writer[i], diagnostic_writer[i], metric_writer[i], + init_chain_id + i, num_chains); } }, tbb::simple_partitioner()); @@ -312,18 +310,16 @@ int hmc_nuts_unit_e_adapt( } if (num_chains == 1) { return hmc_nuts_unit_e_adapt( - model, *init[0], random_seed, init_chain_id, - init_radius, num_warmup, num_samples, num_thin, save_warmup, - refresh, stepsize, stepsize_jitter, max_depth, delta, gamma, - kappa, t0, interrupt, logger, init_writer[0], sample_writer[0], - diagnostic_writer[0], dummy_metric_writer[0]); + model, *init[0], random_seed, init_chain_id, init_radius, num_warmup, + num_samples, num_thin, save_warmup, refresh, stepsize, stepsize_jitter, + max_depth, delta, gamma, kappa, t0, interrupt, logger, init_writer[0], + sample_writer[0], diagnostic_writer[0], dummy_metric_writer[0]); } return hmc_nuts_unit_e_adapt( - model, num_chains, init, random_seed, init_chain_id, - init_radius, num_warmup, num_samples, num_thin, save_warmup, refresh, - stepsize, stepsize_jitter, max_depth, delta, gamma, kappa, t0, - interrupt, logger, init_writer, sample_writer, diagnostic_writer, - dummy_metric_writer); + model, num_chains, init, random_seed, init_chain_id, init_radius, + num_warmup, num_samples, num_thin, save_warmup, refresh, stepsize, + stepsize_jitter, max_depth, delta, gamma, kappa, t0, interrupt, logger, + init_writer, sample_writer, diagnostic_writer, dummy_metric_writer); } } // namespace sample diff --git a/src/stan/services/sample/hmc_static_dense_e_adapt.hpp b/src/stan/services/sample/hmc_static_dense_e_adapt.hpp index 5d82a65f83..d3619fc97d 100644 --- a/src/stan/services/sample/hmc_static_dense_e_adapt.hpp +++ b/src/stan/services/sample/hmc_static_dense_e_adapt.hpp @@ -99,10 +99,10 @@ int hmc_static_dense_e_adapt( logger); callbacks::json_writer dummy_metric_writer; - util::run_adaptive_sampler( - sampler, model, cont_vector, num_warmup, num_samples, num_thin, refresh, - save_warmup, rng, interrupt, logger, sample_writer, diagnostic_writer, - dummy_metric_writer); + util::run_adaptive_sampler(sampler, model, cont_vector, num_warmup, + num_samples, num_thin, refresh, save_warmup, rng, + interrupt, logger, sample_writer, + diagnostic_writer, dummy_metric_writer); return error_codes::OK; } diff --git a/src/stan/services/sample/hmc_static_diag_e_adapt.hpp b/src/stan/services/sample/hmc_static_diag_e_adapt.hpp index 7e23167151..0ddd93e791 100644 --- a/src/stan/services/sample/hmc_static_diag_e_adapt.hpp +++ b/src/stan/services/sample/hmc_static_diag_e_adapt.hpp @@ -97,12 +97,11 @@ int hmc_static_diag_e_adapt( sampler.set_window_params(num_warmup, init_buffer, term_buffer, window, logger); - callbacks::json_writer dummy_metric_writer; - util::run_adaptive_sampler( - sampler, model, cont_vector, num_warmup, num_samples, num_thin, refresh, - save_warmup, rng, interrupt, logger, sample_writer, diagnostic_writer, - dummy_metric_writer); + util::run_adaptive_sampler(sampler, model, cont_vector, num_warmup, + num_samples, num_thin, refresh, save_warmup, rng, + interrupt, logger, sample_writer, + diagnostic_writer, dummy_metric_writer); return error_codes::OK; } diff --git a/src/stan/services/sample/hmc_static_unit_e_adapt.hpp b/src/stan/services/sample/hmc_static_unit_e_adapt.hpp index b2c67846c7..7d9d6f4ac8 100644 --- a/src/stan/services/sample/hmc_static_unit_e_adapt.hpp +++ b/src/stan/services/sample/hmc_static_unit_e_adapt.hpp @@ -81,10 +81,10 @@ int hmc_static_unit_e_adapt( sampler.get_stepsize_adaptation().set_t0(t0); callbacks::json_writer dummy_metric_writer; - util::run_adaptive_sampler( - sampler, model, cont_vector, num_warmup, num_samples, num_thin, refresh, - save_warmup, rng, interrupt, logger, sample_writer, diagnostic_writer, - dummy_metric_writer); + util::run_adaptive_sampler(sampler, model, cont_vector, num_warmup, + num_samples, num_thin, refresh, save_warmup, rng, + interrupt, logger, sample_writer, + diagnostic_writer, dummy_metric_writer); return error_codes::OK; } diff --git a/src/stan/services/util/run_adaptive_sampler.hpp b/src/stan/services/util/run_adaptive_sampler.hpp index 6d0bbea206..33015e3d89 100644 --- a/src/stan/services/util/run_adaptive_sampler.hpp +++ b/src/stan/services/util/run_adaptive_sampler.hpp @@ -42,18 +42,16 @@ namespace util { * @param[in] num_chains The number of chains used in the program. This * is used in generate transitions to print out the chain number. */ -template > -void run_adaptive_sampler(Sampler& sampler, Model& model, - std::vector& cont_vector, int num_warmup, - int num_samples, int num_thin, int refresh, - bool save_warmup, RNG& rng, - callbacks::interrupt& interrupt, - callbacks::logger& logger, - callbacks::writer& sample_writer, - callbacks::writer& diagnostic_writer, - callbacks::json_writer& metric_writer, - size_t chain_id = 1, size_t num_chains = 1) { +template > +void run_adaptive_sampler( + Sampler& sampler, Model& model, std::vector& cont_vector, + int num_warmup, int num_samples, int num_thin, int refresh, + bool save_warmup, RNG& rng, callbacks::interrupt& interrupt, + callbacks::logger& logger, callbacks::writer& sample_writer, + callbacks::writer& diagnostic_writer, + callbacks::json_writer& metric_writer, size_t chain_id = 1, + size_t num_chains = 1) { Eigen::Map cont_params(cont_vector.data(), cont_vector.size()); @@ -67,7 +65,8 @@ void run_adaptive_sampler(Sampler& sampler, Model& model, return; } - services::util::mcmc_writer writer(sample_writer, diagnostic_writer, metric_writer, logger); + services::util::mcmc_writer writer( + sample_writer, diagnostic_writer, metric_writer, logger); stan::mcmc::sample s(cont_params, 0, 0); // Headers diff --git a/src/stan/version.hpp b/src/stan/version.hpp index e007b63293..f383b43160 100644 --- a/src/stan/version.hpp +++ b/src/stan/version.hpp @@ -12,8 +12,8 @@ #endif #define STAN_MAJOR 2 -#define STAN_MINOR 32 -#define STAN_PATCH 2 +#define STAN_MINOR 33 +#define STAN_PATCH 0 namespace stan { diff --git a/src/test/unit/callbacks/json_writer_test.cpp b/src/test/unit/callbacks/json_writer_test.cpp index 71893db858..bdeb05de5b 100644 --- a/src/test/unit/callbacks/json_writer_test.cpp +++ b/src/test/unit/callbacks/json_writer_test.cpp @@ -23,10 +23,29 @@ class StanInterfaceCallbacksJsonWriter : public ::testing::Test { stan::callbacks::json_writer writer; }; +bool is_whitespace(char c) { return c == ' ' || c == '\n'; } + +std::string output_sans_whitespace(std::stringstream& ss) { + auto out = ss.str(); + out.erase(std::remove_if(out.begin(), out.end(), is_whitespace), out.end()); + return out; +} + TEST_F(StanInterfaceCallbacksJsonWriter, begin_end_record) { writer.begin_record(); writer.end_record(); - EXPECT_EQ("{}\n", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("{}", out); +} + +TEST_F(StanInterfaceCallbacksJsonWriter, begin_end_named_record) { + writer.begin_record(); + writer.begin_record("name"); + writer.end_record(); + writer.write("dummy"); + writer.end_record(); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("{\"name\":{},\"dummy\":null}", out); } TEST_F(StanInterfaceCallbacksJsonWriter, begin_end_record_nested) { @@ -48,12 +67,26 @@ TEST_F(StanInterfaceCallbacksJsonWriter, begin_end_record_nested) { writer.end_record(); // 2.2 writer.end_record(); // 2 writer.end_record(); - EXPECT_EQ( - "{\"1\" : {\"key\" : \"value\"},\n" - "\"2\" : {\"key\" : \"value\"," - " \"2.1\" : {\"key\" : \"value\", \"key\" : \"value\"},\n" - "\"2.2\" : {\"key\" : \"value\", \"key\" : \"value\"}}}\n", - ss.str()); + // one whitespace-sensitive test to show formatting + const char* expected = R"json( +{ + "1" : { + "key" : "value" + }, + "2" : { + "key" : "value", + "2.1" : { + "key" : "value", + "key" : "value" + }, + "2.2" : { + "key" : "value", + "key" : "value" + } + } +} +)json"; + EXPECT_EQ(expected, ss.str()); rapidjson::Document document; ASSERT_FALSE(document.Parse<0>(ss.str().c_str()).HasParseError()); } @@ -66,20 +99,23 @@ TEST_F(StanInterfaceCallbacksJsonWriter, write_double_vector) { x.push_back(n); writer.write(key, x); - EXPECT_EQ("\"key\" : [ 0, 1, 2, 3, 4 ]", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"key\":[0,1,2,3,4]", out); writer.write(key, x); + out = output_sans_whitespace(ss); EXPECT_EQ( - "\"key\" : [ 0, 1, 2, 3, 4 ]" - ", \"key\" : [ 0, 1, 2, 3, 4 ]", - ss.str()); + "\"key\":[0,1,2,3,4]" + ",\"key\":[0,1,2,3,4]", + out); writer.write(key, x); + out = output_sans_whitespace(ss); EXPECT_EQ( - "\"key\" : [ 0, 1, 2, 3, 4 ]" - ", \"key\" : [ 0, 1, 2, 3, 4 ]" - ", \"key\" : [ 0, 1, 2, 3, 4 ]", - ss.str()); + "\"key\":[0,1,2,3,4]" + ",\"key\":[0,1,2,3,4]" + ",\"key\":[0,1,2,3,4]", + out); } TEST_F(StanInterfaceCallbacksJsonWriter, single_member) { @@ -88,7 +124,8 @@ TEST_F(StanInterfaceCallbacksJsonWriter, single_member) { writer.begin_record(); writer.write(key, value); writer.end_record(); - EXPECT_EQ("{\"key\" : \"value\"}\n", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("{\"key\":\"value\"}", out); } TEST_F(StanInterfaceCallbacksJsonWriter, more_members) { @@ -98,12 +135,13 @@ TEST_F(StanInterfaceCallbacksJsonWriter, more_members) { writer.write(key, value); writer.write(key, value); - EXPECT_EQ("{\"key\" : \"value\", \"key\" : \"value\"", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("{\"key\":\"value\",\"key\":\"value\"", out); writer.write(key, value); writer.end_record(); - EXPECT_EQ("{\"key\" : \"value\", \"key\" : \"value\", \"key\" : \"value\"}\n", - ss.str()); + out = output_sans_whitespace(ss); + EXPECT_EQ("{\"key\":\"value\",\"key\":\"value\",\"key\":\"value\"}", out); } TEST_F(StanInterfaceCallbacksJsonWriter, write_double_vector_precision2) { @@ -112,7 +150,8 @@ TEST_F(StanInterfaceCallbacksJsonWriter, write_double_vector_precision2) { const int N = 5; std::vector x{1.23456789, 2.3456789, 3.45678910, 4.567890123}; writer.write(key, x); - EXPECT_EQ("\"key\" : [ 1.2, 2.3, 3.5, 4.6 ]", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"key\":[1.2,2.3,3.5,4.6]", out); } TEST_F(StanInterfaceCallbacksJsonWriter, write_double_vector_nan_inf) { @@ -122,7 +161,8 @@ TEST_F(StanInterfaceCallbacksJsonWriter, write_double_vector_nan_inf) { x.push_back(std::numeric_limits::infinity()); x.push_back(-std::numeric_limits::infinity()); writer.write(key, x); - EXPECT_EQ("\"key\" : [ NaN, Inf, -Inf ]", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"key\":[NaN,Inf,-Inf]", out); } TEST_F(StanInterfaceCallbacksJsonWriter, write_string_special_characters) { @@ -132,7 +172,7 @@ TEST_F(StanInterfaceCallbacksJsonWriter, write_string_special_characters) { "the\\quick\"brown/\bfox\fjumped\nover\rthe\tlazy\vdog\atwotimes"); writer.write(key, x); EXPECT_EQ( - "\"key\" : " + "\n\"key\" : " "\"the\\\\quick\\\"brown\\/" "\\bfox\\fjumped\\nover\\rthe\\tlazy\\vdog\\atwotimes\"", ss.str()); @@ -142,7 +182,8 @@ TEST_F(StanInterfaceCallbacksJsonWriter, write_double_vector_precision3) { std::vector x{1.23456789, 2.3456789, 3.45678910, 4.567890123}; ss.precision(3); writer.write("key", x); - EXPECT_EQ("\"key\" : [ 1.23, 2.35, 3.46, 4.57 ]", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"key\":[1.23,2.35,3.46,4.57]", out); } TEST_F(StanInterfaceCallbacksJsonWriter, write_string_vector) { @@ -152,17 +193,20 @@ TEST_F(StanInterfaceCallbacksJsonWriter, write_string_vector) { x.push_back(std::to_string(n)); writer.write("key", x); - EXPECT_EQ("\"key\" : [ 0, 1, 2, 3, 4 ]", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"key\":[0,1,2,3,4]", out); } TEST_F(StanInterfaceCallbacksJsonWriter, write_null) { writer.write("message"); - EXPECT_EQ("\"message\" : null", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"message\":null", out); } TEST_F(StanInterfaceCallbacksJsonWriter, write_string) { writer.write("key", "value"); - EXPECT_EQ("\"key\" : \"value\"", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"key\":\"value\"", out); } TEST_F(StanInterfaceCallbacksJsonWriter, write_int_vector) { @@ -173,21 +217,24 @@ TEST_F(StanInterfaceCallbacksJsonWriter, write_int_vector) { x.push_back(n); writer.write(key, x); - EXPECT_EQ("\"key\" : [ 0, 1, 2, 3, 4 ]", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"key\":[0,1,2,3,4]", out); } TEST_F(StanInterfaceCallbacksJsonWriter, write_empty_vector) { std::string key("key"); std::vector x; writer.write(key, x); - EXPECT_EQ("\"key\" : [ ]", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"key\":[]", out); } TEST_F(StanInterfaceCallbacksJsonWriter, write_complex) { std::string key("key"); std::complex x(1.110, 2.110); writer.write(key, x); - EXPECT_EQ("\"key\" : [1.11, 2.11]", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"key\":[1.11,2.11]", out); } TEST_F(StanInterfaceCallbacksJsonWriter, write_complex_inf) { @@ -195,7 +242,8 @@ TEST_F(StanInterfaceCallbacksJsonWriter, write_complex_inf) { std::complex x(std::numeric_limits::infinity(), -std::numeric_limits::infinity()); writer.write(key, x); - EXPECT_EQ("\"key\" : [Inf, -Inf]", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"key\":[Inf,-Inf]", out); } TEST_F(StanInterfaceCallbacksJsonWriter, write_complex_vector) { @@ -206,42 +254,48 @@ TEST_F(StanInterfaceCallbacksJsonWriter, write_complex_vector) { x.push_back(std::complex(1.110, 2.110)); writer.write(key, x); - EXPECT_EQ("\"key\" : [ [1.11, 2.11], [1.11, 2.11], [1.11, 2.11] ]", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"key\":[[1.11,2.11],[1.11,2.11],[1.11,2.11]]", out); } TEST_F(StanInterfaceCallbacksJsonWriter, write_eigen_vector) { std::string key("key"); Eigen::VectorXd x{{1.0, 2.0, 3.0, 4.0}}; writer.write(key, x); - EXPECT_EQ("\"key\" : [ 1, 2, 3, 4 ]", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"key\":[1,2,3,4]", out); } TEST_F(StanInterfaceCallbacksJsonWriter, write_empty_eigen_vector) { std::string key("key"); Eigen::VectorXd x; writer.write(key, x); - EXPECT_EQ("\"key\" : [ ]", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"key\":[]", out); } TEST_F(StanInterfaceCallbacksJsonWriter, write_eigen_rowvector) { std::string key("key"); Eigen::RowVectorXd x{{1.0, 2.0, 3.0, 4.0}}; writer.write(key, x); - EXPECT_EQ("\"key\" : [ 1, 2, 3, 4 ]", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"key\":[1,2,3,4]", out); } TEST_F(StanInterfaceCallbacksJsonWriter, write_eigen_matrix) { std::string key("key"); Eigen::MatrixXd x{{1.0, 2.0}, {3.0, 4.0}}; writer.write(key, x); - EXPECT_EQ("\"key\" : [ [ 1, 2 ], [ 3, 4 ] ]", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"key\":[[1,2],[3,4]]", out); } TEST_F(StanInterfaceCallbacksJsonWriter, write_empty_eigen_matrix) { std::string key("key"); Eigen::MatrixXd x; writer.write(key, x); - EXPECT_EQ("\"key\" : [ ]", ss.str()); + auto out = output_sans_whitespace(ss); + EXPECT_EQ("\"key\":[]", out); } TEST_F(StanInterfaceCallbacksJsonWriter, no_op_writer) { diff --git a/src/test/unit/services/sample/hmc_nuts_dense_e_adapt_parallel_match_test.cpp b/src/test/unit/services/sample/hmc_nuts_dense_e_adapt_parallel_match_test.cpp index 896774002b..fe80876048 100644 --- a/src/test/unit/services/sample/hmc_nuts_dense_e_adapt_parallel_match_test.cpp +++ b/src/test/unit/services/sample/hmc_nuts_dense_e_adapt_parallel_match_test.cpp @@ -10,7 +10,6 @@ #include #include - auto&& blah = stan::math::init_threadpool_tbb(); static constexpr size_t num_chains = 4; @@ -59,7 +58,8 @@ class ServicesSampleHmcNutsDenseEAdaptParMatch : public testing::Test { = stan::callbacks::unique_stream_writer; std::vector par_parameters; std::vector seq_parameters; - std::vector> metrics; + std::vector> + metrics; std::vector diagnostics; std::vector> context; std::unique_ptr model; @@ -114,7 +114,7 @@ TEST_F(ServicesSampleHmcNutsDenseEAdaptParMatch, single_multi_match) { } std::vector par_res; - std::vectorpar_metrics; + std::vector par_metrics; for (int i = 0; i < num_chains; ++i) { auto par_str = par_parameters[i].get_stream().str(); auto sub_par_str = par_str.substr(par_str.find("Elements") - 1); @@ -131,7 +131,7 @@ TEST_F(ServicesSampleHmcNutsDenseEAdaptParMatch, single_multi_match) { } std::vector seq_res; - std::vectorseq_metrics; + std::vector seq_metrics; for (int i = 0; i < num_chains; ++i) { auto seq_str = seq_parameters[i].get_stream().str(); auto sub_seq_str = seq_str.substr(seq_str.find("Elements") - 1); diff --git a/src/test/unit/services/sample/hmc_nuts_diag_e_adapt_parallel_match_test.cpp b/src/test/unit/services/sample/hmc_nuts_diag_e_adapt_parallel_match_test.cpp index f6b8412639..7db4677faf 100644 --- a/src/test/unit/services/sample/hmc_nuts_diag_e_adapt_parallel_match_test.cpp +++ b/src/test/unit/services/sample/hmc_nuts_diag_e_adapt_parallel_match_test.cpp @@ -58,7 +58,8 @@ class ServicesSampleHmcNutsDiagEAdaptParMatch : public testing::Test { = stan::callbacks::unique_stream_writer; std::vector par_parameters; std::vector seq_parameters; - std::vector> metrics; + std::vector> + metrics; std::vector diagnostics; std::vector> context; std::unique_ptr model; @@ -112,7 +113,7 @@ TEST_F(ServicesSampleHmcNutsDiagEAdaptParMatch, single_multi_match) { } std::vector par_res; - std::vectorpar_metrics; + std::vector par_metrics; for (int i = 0; i < num_chains; ++i) { auto par_str = par_parameters[i].get_stream().str(); auto sub_par_str = par_str.substr(par_str.find("Diagonal") - 1); @@ -129,7 +130,7 @@ TEST_F(ServicesSampleHmcNutsDiagEAdaptParMatch, single_multi_match) { } std::vector seq_res; - std::vectorseq_metrics; + std::vector seq_metrics; for (int i = 0; i < num_chains; ++i) { auto seq_str = seq_parameters[i].get_stream().str(); auto sub_seq_str = seq_str.substr(seq_str.find("Diagonal") - 1); diff --git a/src/test/unit/services/sample/hmc_nuts_unit_e_adapt_parallel_test.cpp b/src/test/unit/services/sample/hmc_nuts_unit_e_adapt_parallel_test.cpp index ca6fd9dd69..709e1f3c39 100644 --- a/src/test/unit/services/sample/hmc_nuts_unit_e_adapt_parallel_test.cpp +++ b/src/test/unit/services/sample/hmc_nuts_unit_e_adapt_parallel_test.cpp @@ -16,9 +16,8 @@ class ServicesSampleHmcNutsUnitEAdaptPar : public testing::Test { init.push_back(stan::test::unit::instrumented_writer{}); parameter.push_back(stan::test::unit::instrumented_writer{}); diagnostic.push_back(stan::test::unit::instrumented_writer{}); - metric.push_back( - stan::callbacks::json_writer( - std::unique_ptr(nullptr))); + metric.push_back(stan::callbacks::json_writer( + std::unique_ptr(nullptr))); context.push_back(std::make_shared()); } } diff --git a/src/test/unit/services/sample/hmc_nuts_unit_e_parallel_test.cpp b/src/test/unit/services/sample/hmc_nuts_unit_e_parallel_test.cpp index 9cd7d63e21..696595fbe6 100644 --- a/src/test/unit/services/sample/hmc_nuts_unit_e_parallel_test.cpp +++ b/src/test/unit/services/sample/hmc_nuts_unit_e_parallel_test.cpp @@ -16,9 +16,8 @@ class ServicesSampleHmcNutsUnitEPar : public testing::Test { init.push_back(stan::test::unit::instrumented_writer{}); parameter.push_back(stan::test::unit::instrumented_writer{}); diagnostic.push_back(stan::test::unit::instrumented_writer{}); - metric.push_back( - stan::callbacks::json_writer( - std::unique_ptr(nullptr))); + metric.push_back(stan::callbacks::json_writer( + std::unique_ptr(nullptr))); context.push_back(std::make_shared()); } } diff --git a/src/test/unit/services/util/mcmc_writer_test.cpp b/src/test/unit/services/util/mcmc_writer_test.cpp index 586b5becd6..2616c3484c 100644 --- a/src/test/unit/services/util/mcmc_writer_test.cpp +++ b/src/test/unit/services/util/mcmc_writer_test.cpp @@ -163,7 +163,8 @@ class throwing_model : public stan::model::model_base_crtp { class ServicesUtil : public ::testing::Test { public: ServicesUtil() - : mcmc_writer(sample_writer, diagnostic_writer, dummy_metric_writer, logger), + : mcmc_writer(sample_writer, diagnostic_writer, dummy_metric_writer, + logger), model(context, 0, &model_log), throwing_model(context, 0, &model_log) {} diff --git a/src/test/unit/version_test.cpp b/src/test/unit/version_test.cpp index 2017d57e3e..76779cfdaf 100644 --- a/src/test/unit/version_test.cpp +++ b/src/test/unit/version_test.cpp @@ -3,12 +3,12 @@ TEST(Stan, macro) { EXPECT_EQ(2, STAN_MAJOR); - EXPECT_EQ(32, STAN_MINOR); - EXPECT_EQ(2, STAN_PATCH); + EXPECT_EQ(33, STAN_MINOR); + EXPECT_EQ(0, STAN_PATCH); } TEST(Stan, version) { EXPECT_EQ("2", stan::MAJOR_VERSION); - EXPECT_EQ("32", stan::MINOR_VERSION); - EXPECT_EQ("2", stan::PATCH_VERSION); + EXPECT_EQ("33", stan::MINOR_VERSION); + EXPECT_EQ("0", stan::PATCH_VERSION); }