From e6dc1c7a5e413cca33b305738ffbe54c79a6aabe Mon Sep 17 00:00:00 2001 From: "w.klijn" <nonoice@gmail.com> Date: Tue, 16 Aug 2016 17:11:40 +0200 Subject: [PATCH] Add the new spike_exchange files. Do some small textual changes --- src/io/exporter.hpp | 37 +++++++++++++ src/io/exporter_spike_file.hpp | 99 ++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 src/io/exporter.hpp create mode 100644 src/io/exporter_spike_file.hpp diff --git a/src/io/exporter.hpp b/src/io/exporter.hpp new file mode 100644 index 00000000..85f7f212 --- /dev/null +++ b/src/io/exporter.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include <random> +#include <string> + +#include <common_types.hpp> +#include <spike.hpp> + +namespace nest { +namespace mc { +namespace io { + +// interface for exporters. +// Exposes one virtual functions: +// do_export(vector<type>) receiving a vector of parameters to export + +template <typename Time, typename CommunicationPolicy> +class exporter { + +public: + using time_type = Time; + using spike_type = spike<cell_member_type, time_type>; + + // Performs the export of the data + virtual void do_export(const std::vector<spike_type>&) = 0; + + // Returns the status of the exporter + virtual bool good() const = 0; + + // Static version of the do_export function for NOP callbacks + static void do_nothing(const std::vector<spike_type>&) + {} +}; + +} //communication +} // namespace mc +} // namespace nest diff --git a/src/io/exporter_spike_file.hpp b/src/io/exporter_spike_file.hpp new file mode 100644 index 00000000..06f26c64 --- /dev/null +++ b/src/io/exporter_spike_file.hpp @@ -0,0 +1,99 @@ +#pragma once + +#include <cstring> +#include <cstdio> +#include <fstream> +#include <iomanip> +#include <memory> +#include <random> +#include <stdexcept> +#include <vector> + +#include <common_types.hpp> +#include <io/exporter.hpp> +#include <spike.hpp> +#include <util.hpp> + +namespace nest { +namespace mc { +namespace io { + +template <typename Time, typename CommunicationPolicy> +class exporter_spike_file : public exporter<Time, CommunicationPolicy> +{ +public: + using time_type = Time; + using spike_type = spike<cell_member_type, time_type>; + using communication_policy_type = CommunicationPolicy; + + // Constructor + // over_write if true will overwrite the specified output file (default = true) + // output_path relative or absolute path + // file_name will be appended with "_x" with x the rank number + // file_extention a seperator will be added automatically + exporter_spike_file(const std::string& file_name, const std::string& path, + const std::string& file_extention, bool over_write=true) + { + auto file_path = + create_output_file_path(file_name, path, file_extention, + communication_policy_.id()); + + //test if the file exist and depending on over_write throw or delete + if (!over_write && file_exists(file_path)) + { + throw std::runtime_error("Tried opening file for writing but it exists and over_write is false: " + + file_path); + } + + file_handle_.open(file_path); + } + + // Performs the a export of the spikes to file + // one id and spike time with 4 decimals after the comma on a + // line space separated + void do_export(const std::vector<spike_type>& spikes) override + { + for (auto spike : spikes) { + char linebuf[45]; + auto n = std::snprintf(linebuf, sizeof(linebuf), "%u %.4f\n", + unsigned{spike.source.gid}, float{spike.time}); + file_handle_.write(linebuf, n); + } + } + + bool good() const override + { + return file_handle_.good(); + } + + // Creates an indexed filename + static std::string create_output_file_path(const std::string& file_name, + const std::string& path, const std::string& file_extention, + unsigned index) + { + // Nest does not produce the indexing for nrank == 0 + // I have the feeling this disrupts consistent output. Id rather + // always put the zero in. it allows a simpler regex when opening + // files + return path + file_name + "_" + std::to_string(index) + "." + + file_extention; + } + +private: + + bool file_exists(const std::string& file_path) + { + std::ifstream fid(file_path); + return fid.good(); + } + + // Handle to opened file handle + std::ofstream file_handle_; + + communication_policy_type communication_policy_; + +}; + +} //communication +} // namespace mc +} // namespace nest -- GitLab