diff --git a/src/cmdstan/arguments/arg_output.hpp b/src/cmdstan/arguments/arg_output.hpp index ef014f2341..ff8b642cac 100644 --- a/src/cmdstan/arguments/arg_output.hpp +++ b/src/cmdstan/arguments/arg_output.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -19,6 +20,7 @@ class arg_output : public categorical_argument { _subarguments.push_back(new arg_diagnostic_file()); _subarguments.push_back(new arg_refresh()); _subarguments.push_back(new arg_output_sig_figs()); + _subarguments.push_back(new arg_profile_file()); } }; diff --git a/src/cmdstan/arguments/arg_profile_file.hpp b/src/cmdstan/arguments/arg_profile_file.hpp new file mode 100644 index 0000000000..bcada5e839 --- /dev/null +++ b/src/cmdstan/arguments/arg_profile_file.hpp @@ -0,0 +1,23 @@ +#ifndef CMDSTAN_ARGUMENTS_ARG_PROFILE_FILE_HPP +#define CMDSTAN_ARGUMENTS_ARG_PROFILE_FILE_HPP + +#include + +namespace cmdstan { + +class arg_profile_file : public string_argument { + public: + arg_profile_file() : string_argument() { + _name = "profile_file"; + _description = "File to store profiling information"; + _validity = "Valid path and write acces to the folder"; + _default = "\"\""; + _default_value = "profile.csv"; + _constrained = false; + _good_value = "profile.csv"; + _value = _default_value; + } +}; + +} // namespace cmdstan +#endif diff --git a/src/cmdstan/command.hpp b/src/cmdstan/command.hpp index 99bee95c4b..4c9913e8d3 100644 --- a/src/cmdstan/command.hpp +++ b/src/cmdstan/command.hpp @@ -7,12 +7,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -62,6 +64,7 @@ // forward declaration for function defined in another translation unit stan::model::model_base &new_model(stan::io::var_context &data_context, unsigned int seed, std::ostream *msg_stream); +stan::math::profile_map &get_stan_profile_data(); namespace cmdstan { @@ -871,7 +874,19 @@ int command(int argc, const char *argv[]) { init_writer, sample_writer, diagnostic_writer); } } - + stan::math::profile_map &profile_data = get_stan_profile_data(); + if (profile_data.size() > 0) { + std::string profile_file_name + = dynamic_cast( + parser.arg("output")->arg("profile_file")) + ->value(); + std::fstream profile_stream(profile_file_name.c_str(), std::fstream::out); + if (!sig_figs_arg->is_default()) { + profile_stream << std::setprecision(sig_figs_arg->value()); + } + write_profiling(profile_stream, profile_data); + profile_stream.close(); + } output_stream.close(); diagnostic_stream.close(); for (size_t i = 0; i < valid_arguments.size(); ++i) diff --git a/src/cmdstan/write_profiling.hpp b/src/cmdstan/write_profiling.hpp new file mode 100644 index 0000000000..27d8d8c827 --- /dev/null +++ b/src/cmdstan/write_profiling.hpp @@ -0,0 +1,36 @@ +#ifndef CMDSTAN_WRITE_PROFILING_HPP +#define CMDSTAN_WRITE_PROFILING_HPP + +#include +#include +#include +#include +#include + +namespace cmdstan { + +/** + * Writes the data from the map of profiles in a CSV format + * to the output. + * + * @param output stream to write output to + * @param p reference to the map of profiles + */ +void write_profiling(std::ostream& output, stan::math::profile_map& p) { + stan::math::profile_map::iterator it; + + output << "name,thread_id,total_time,forward_time,reverse_time,chain_" + "stack,no_chain_stack,autodiff_calls,no_autodiff_calls" + << std::endl; + for (it = p.begin(); it != p.end(); it++) { + output << it->first.first << "," << it->first.second << "," + << (it->second.get_fwd_time() + it->second.get_rev_time()) << "," + << it->second.get_fwd_time() << "," << it->second.get_rev_time() + << "," << it->second.get_chain_stack_used() << "," + << it->second.get_nochain_stack_used() << "," + << it->second.get_num_rev_passes() << "," + << it->second.get_num_no_AD_fwd_passes() << std::endl; + } +} +} // namespace cmdstan +#endif