Skip to content

Commit

Permalink
remove stringstream from unique stream writer
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveBronder committed Dec 13, 2024
1 parent 3c932f0 commit f1a8e56
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 179 deletions.
150 changes: 1 addition & 149 deletions src/stan/callbacks/unique_stream_writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,6 @@ class unique_stream_writer final : public writer {
return;
write_vector(names);
}
/**
* Writes a set of names on a single line in csv format followed
* by a newline.
*
* Note: the names are not escaped.
*
* @param[in] names Names in a std::vector
* @param[in, out] ss A stringstream to use as a buffer
*/
void operator()(const std::vector<std::string>& names, std::stringstream& ss) {
if (output_ == nullptr)
return;
write_vector(names, ss);
}

/**
* Get the underlying stream
Expand All @@ -91,20 +77,6 @@ class unique_stream_writer final : public writer {
return;
write_vector(values);
}
/**
* Writes a set of values in csv format followed by a newline.
*
* Note: the precision of the output is determined by the settings
* of the stream on construction.
*
* @param[in] values Values in a std::vector
* @param[in, out] ss ignored
*/
void operator()(const std::vector<double>& values, std::stringstream& ss) {
if (output_ == nullptr)
return;
write_vector(values);
}

/**
* Writes multiple rows and columns of values in csv format.
Expand All @@ -116,96 +88,12 @@ class unique_stream_writer final : public writer {
* parameters in the rows and samples in the columns. The matrix is then
* transposed for the output.
*/
void operator()(const Eigen::Matrix<double, -1, -1>& values) {
void operator()(const Eigen::Ref<Eigen::Matrix<double, -1, -1>>& values) {
if (output_ == nullptr)
return;
*output_ << values.transpose().format(CommaInitFmt);
}

/**
* Writes multiple rows and columns of values in csv format.
*
* Note: the precision of the output is determined by the settings
* of the stream on construction.
*
* @param[in] values A matrix of values. The input is expected to have
* parameters in the rows and samples in the columns. The matrix is then
* transposed for the output.
* @param[in, out] ss ignored
*/
void operator()(const Eigen::Matrix<double, -1, -1>& values, std::stringstream& /* ss */) {
if (output_ == nullptr)
return;
*output_ << values.transpose().format(CommaInitFmt);
}

/**
* Writes a row of values in csv format.
*
* Note: the precision of the output is determined by the settings
* of the stream on construction.
*
* @param[in] values A row vector of values. The input is expected to have
* samples in the columns.
* @param[in, out] ss ignored
*/
void operator()(const Eigen::Matrix<double, 1, -1>& values) {
if (output_ == nullptr)
return;
*output_ << values.format(CommaInitFmt);
}

/**
* Writes a row of values in csv format.
*
* Note: the precision of the output is determined by the settings
* of the stream on construction.
*
* @param[in] values A row vector of values. The input is expected to have
* samples in the columns.
* @param[in, out] ss ignored
*/
void operator()(const Eigen::Matrix<double, 1, -1>& values, std::stringstream& /* ss */) {
if (output_ == nullptr)
return;
*output_ << values.format(CommaInitFmt);
}

/**
* Writes a row of values in csv format.
*
* Note: the precision of the output is determined by the settings
* of the stream on construction.
*
* @param[in] values A column vector of values. The input is expected to have
* samples in the rows. The matrix is then
* transposed for the output.
* @param[in, out] ss ignored
*/
void operator()(const Eigen::Matrix<double, -1, 1>& values) {
if (output_ == nullptr)
return;
*output_ << values.transpose().format(CommaInitFmt);
}

/**
* Writes a row of values in csv format.
*
* Note: the precision of the output is determined by the settings
* of the stream on construction.
*
* @param[in] values A column vector of values. The input is expected to have
* samples in the rows. The matrix is then
* transposed for the output.
*/
void operator()(const Eigen::Matrix<double, -1, 1>& values, std::stringstream& /* ss */) {
if (output_ == nullptr)
return;
*output_ << values.transpose().format(CommaInitFmt);
}



/**
* Writes the comment_prefix to the stream followed by a newline.
*/
Expand All @@ -226,18 +114,6 @@ class unique_stream_writer final : public writer {
*output_ << comment_prefix_ << message << std::endl;
}

/**
* Writes the comment_prefix then the message followed by a newline.
*
* @param[in] message A string
@ @param[in, out] ss ignored
*/
void operator()(const std::string& message, std::stringstream& /* ss */) {
if (output_ == nullptr)
return;
*output_ << comment_prefix_ << message << std::endl;
}

private:
/**
* Comma formatter for writing Eigen matrices
Expand Down Expand Up @@ -277,30 +153,6 @@ class unique_stream_writer final : public writer {
}
*output_ << v.back() << std::endl;
}
/**
* Writes a set of values in csv format followed by a newline.
*
* Note: the precision of the output is determined by the settings
* of the stream on construction.
*
* @param[in] v Values in a std::vector
* @param[in, out] ss A stringstream to use as a buffer
*/
template <class T>
void write_vector(const std::vector<T>& v, std::stringstream& ss) {
if (output_ == nullptr)
return;
if (v.empty()) {
return;
}
auto last = v.end();
--last;
for (auto it = v.begin(); it != last; ++it) {
ss << *it << ",";
}
ss << v.back() << std::endl;
*output_ << ss.str();
}
};

} // namespace callbacks
Expand Down
19 changes: 5 additions & 14 deletions src/stan/services/pathfinder/multi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,12 @@ namespace internal {
* @param[in] path_sample_idx The index of the sample to generate
* @param[in] rng A random number generator
* @param[in] param_writer A writer callback for parameter values
* @param[in,out] stream A stream to write the output
*/
template <bool DoAll = false, typename ConstrainFun, typename Model, typename ElboEst, typename RNG, typename ParamWriter>
inline void gen_pathfinder_draw(ConstrainFun&& constrain_fun, Model&& model,
ElboEst&& elbo_est, const Eigen::Index path_num,
const Eigen::Index path_sample_idx,
RNG&& rng, ParamWriter&& param_writer, std::stringstream& stream) {
RNG&& rng, ParamWriter&& param_writer) {
// FIX THESE
auto&& lp_draws = elbo_est.lp_mat;
auto&& new_draws = elbo_est.repeat_draws;
Expand All @@ -61,17 +60,14 @@ namespace internal {
Eigen::Matrix<double, 1, Eigen::Dynamic> sample_row(uc_param_size + 2);
sample_row.head(2) = lp_draws.row(path_sample_idx).matrix();
sample_row.tail(uc_param_size) = approx_samples_constrained_col;
param_writer(sample_row, stream);
param_writer(sample_row);
if constexpr (DoAll) {
for (int i = 1; i < num_samples; ++i) {
unconstrained_col = new_draws.col(i);
constrain_fun(approx_samples_constrained_col, unconstrained_col, model, rng);
sample_row.head(2) = lp_draws.row(path_sample_idx).matrix();
sample_row.tail(uc_param_size) = approx_samples_constrained_col;
param_writer(sample_row, stream);
if (stream.rdbuf()) {
stream.rdbuf()->pubseekpos(0);
}
param_writer(sample_row);
}
}
}
Expand Down Expand Up @@ -198,12 +194,11 @@ inline int pathfinder_lbfgs_multi(
if (psis_resample && calculate_lp) {
elbo_estimates.push_back(std::move(std::get<1>(pathfinder_ret)));
} else {
std::stringstream stream;
stan::rng_t rng = util::create_rng(random_seed, stride_id + iter);
std::lock_guard<std::mutex> lock(write_mutex);
internal::gen_pathfinder_draw<true>(constrain_fun, model,
std::get<1>(pathfinder_ret), 0, 0,
rng, parameter_writer, stream);
rng, parameter_writer);
}
}
});
Expand Down Expand Up @@ -238,18 +233,14 @@ inline int pathfinder_lbfgs_multi(
boost::iterator_range<double*>(
weight_vals.data(),
weight_vals.data() + weight_vals.size())));
std::stringstream stream;
for (size_t i = 0; i <= num_multi_draws - 1; ++i) {
auto draw_idx = rand_psis_idx();
// Calculate which pathfinder the draw came from
Eigen::Index path_num = std::floor(draw_idx / num_draws);
auto path_sample_idx = draw_idx % num_draws;
auto&& elbo_est = elbo_estimates[path_num];
internal::gen_pathfinder_draw(constrain_fun, model, elbo_est,
path_num, path_sample_idx, rng, parameter_writer, stream);
if (stream.rdbuf()) {
stream.rdbuf()->pubseekpos(0);
}
path_num, path_sample_idx, rng, parameter_writer);

}
const auto end_psis_time = std::chrono::steady_clock::now();
Expand Down
16 changes: 0 additions & 16 deletions src/test/unit/services/pathfinder/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,8 @@ class in_memory_writer : public stan::callbacks::stream_writer {
* @param[in] names Names in a std::vector
*/
void operator()(const std::vector<std::string>& names) { names_ = names; }
void operator()(const std::vector<std::string>& names, std::stringstream& /* ss */) { names_ = names; }

void operator()(const std::string& times) { times_.push_back(times); }
void operator()(const std::string& times, std::stringstream& /* ss */) { times_.push_back(times); }
void operator()() { times_.push_back("\n"); }
/**
* Writes a set of values.
Expand All @@ -167,9 +165,6 @@ class in_memory_writer : public stan::callbacks::stream_writer {
void operator()(const std::vector<double>& state) {
states_.push_back(state);
}
void operator()(const std::vector<double>& state, std::stringstream& /* ss */) {
states_.push_back(state);
}
void operator()(
const std::vector<std::tuple<Eigen::VectorXd, Eigen::VectorXd>>& xx) {
for (auto& x_i : xx) {
Expand All @@ -179,26 +174,15 @@ class in_memory_writer : public stan::callbacks::stream_writer {
void operator()(const std::tuple<Eigen::VectorXd, Eigen::VectorXd>& xx) {
optim_path_.push_back(xx);
}

template <typename EigVec, stan::require_eigen_vector_t<EigVec>* = nullptr>
void operator()(const EigVec& vals) {
eigen_states_.push_back(vals);
}
template <typename EigVec, stan::require_eigen_vector_t<EigVec>* = nullptr>
void operator()(const EigVec& vals, std::stringstream& /* ss */) {
eigen_states_.push_back(vals);
}

template <typename EigMat,
stan::require_eigen_matrix_dynamic_t<EigMat>* = nullptr>
void operator()(const EigMat& vals) {
values_ = vals;
}
template <typename EigMat,
stan::require_eigen_matrix_dynamic_t<EigMat>* = nullptr>
void operator()(const EigMat& vals, std::stringstream& /* ss */) {
values_ = vals;
}
};

Eigen::Matrix<double, 10, 100> eight_schools_r_answer() {
Expand Down

0 comments on commit f1a8e56

Please sign in to comment.