33 *
44 * @ingroup Simulator/Core
55 *
6- * @brief Handles implementation details of serialization and deserialization of synapses .
6+ * @brief Provides serialization and deserialization functionality using the Cereal library .
77 *
8- * Serialize and Deserialize synapse weights, source vertices, destination vertices,
9- * maxEdgesPerVertex, totalVertices and radii.
8+ * This class handles the serialization and deserialization of all member variables
9+ * in the Connections, Layout, Edges, Vertices, and associated helper classes such as
10+ * EdgeIndexMap, Model, RecordableBase, RecordableVector, Matrix, RNG and EventBuffer.
11+ * Note that Recorder class is not serialized or deserialized.
12+ *
13+ * The serialization and deserialization process typically begins with the Model class,
14+ * which internally calls the serialization of the Connections and Layout classes.
15+ * Connections, in turn, handle the serialization of Edges, while Layout handles
16+ * the serialization of Vertices. This ensures a comprehensive serialization of
17+ * the entire simulation structure.
18+ *
19+ * @note As of September 2024, serialization support is currently available
20+ * for CPU-based Neuron simulations. While GPU-based Neuron serialization is functional,
21+ * the output result files differ, and this is being addressed in [Issue #701].
22+ * Serialization support for NG911 will be extended in the future [Issue #700].
23+ *
1024 */
1125
1226#include " Serializer.h"
1327#include " ConnGrowth.h"
14- #include " Connections.h"
1528#include " GPUModel.h"
16- #include " Simulator.h"
1729#include < fstream>
1830
19- // Displays Graphitti as top most element instead of the default Cereal
20- // CEREAL_XML_STRING_VALUE should be placed before defining cereal archives library
31+ // About CEREAL_XML_STRING_VALUE
32+ // 1. Displays Graphitti as top most element instead of the default Cereal in the serialized xml file.
33+ // 2. It should be placed before defining cereal archives library
2134#define CEREAL_XML_STRING_VALUE " Graphitti"
2235#include < cereal/archives/binary.hpp>
2336#include < cereal/archives/xml.hpp>
2437
25- // / Deserializes synapse weights, source vertices, destination vertices,
26- // / maxEdgesPerVertex, totalVertices.
27- // / if running a connGrowth model and radii is in serialization file, deserializes radii as well
38+ // / Deserializes all member variables of the
39+ // / Connections, Layout, Edges, Vertices, and associated helper classes.
2840// /
2941// / @returns true if successful, false otherwise.
30- bool Serializer::deserializeSynapses ()
42+ bool Serializer::deserialize ()
3143{
3244 Simulator &simulator = Simulator::getInstance ();
3345
@@ -47,59 +59,24 @@ bool Serializer::deserializeSynapses()
4759 cereal::XMLInputArchive archive (memory_in);
4860 // cereal::BinaryInputArchive archive(memory_in);
4961
50- Connections &connections = simulator.getModel ().getConnections ();
51- // Layout &layout = simulator.getModel().getLayout();
52-
53- // Deserializes synapse weights along with each synapse's source vertex and destination vertex
54- // Uses "try catch" to catch any cereal exception
55- // try {
56- // archive(dynamic_cast<AllEdges &>(connections.getEdges()));
57- // } catch (cereal::Exception e) {
58- // cerr << e.what() << endl
59- // << "Failed to deserialize synapse weights, source vertices, and/or destination vertices."
60- // << endl;
61- // return false;
62- // }
63-
64- // Creates synapses from weight
65- // connections->createSynapsesFromWeights(simulator.getTotalVertices(), layout.get(),
66- // (layout->getVertices()), (connections->getEdges()));
67-
68-
69- // Uses "try catch" to catch any cereal exception
70- try {
71- archive (connections);
72- } catch (cereal::Exception e) {
73- cerr << e.what () << endl << " Failed to deserialize radii." << endl;
62+ if (!processArchive (archive, simulator)) {
63+ cerr << " Failed to deserialize" << endl;
7464 return false ;
7565 }
7666
77- // Creates synapses from weight
78- // connections.createSynapsesFromWeights();
79-
80-
81- #if defined(USE_GPU)
82- // Copies CPU Synapse data to GPU after deserialization, if we're doing
83- // a GPU-based simulation.
84- simulator.copyCPUSynapseToGPU ();
85- #endif // USE_GPU
86-
87- // Creates synapse index map (includes copy CPU index map to GPU)
88- // connections.createEdgeIndexMap();
8967
9068#if defined(USE_GPU)
9169 GPUModel &gpuModel = static_cast <GPUModel &>(simulator.getModel ());
92- gpuModel.copySynapseIndexMapHostToDevice (connections .getEdgeIndexMap (),
70+ gpuModel.copySynapseIndexMapHostToDevice (simulator. getModel (). getConnections () .getEdgeIndexMap (),
9371 simulator.getTotalVertices ());
9472#endif // USE_GPU
9573
9674 return true ;
9775}
9876
99- // / Serializes synapse weights, source vertices, destination vertices,
100- // / maxEdgesPerVertex, totalVertices.
101- // / if running a connGrowth model serializes radii as well.
102- void Serializer::serializeSynapses ()
77+ // / Serializes all member variables of the
78+ // / Connections, Layout, Edges, Vertices, and associated helper classes.
79+ void Serializer::serialize ()
10380{
10481 Simulator &simulator = Simulator::getInstance ();
10582
@@ -108,29 +85,27 @@ void Serializer::serializeSynapses()
10885 ofstream memory_out (simulator.getSerializationFileName ().c_str ());
10986 cout << " Please find the serialized file in " << simulator.getSerializationFileName ().c_str ();
11087
111- // Options parameter are optional which sets
112- // 1. Sets the Preceision of floating point number to 30
113- // 2. Keeps indedntaion in XML file,
114- // 3. Displays output type of element values in XML eg. float
115- // 4. Displays if the size of a node in XML is dynamic or not.
116- cereal::XMLOutputArchive archive (memory_out, cereal::XMLOutputArchive::Options ()
117- .precision (30 )
118- .indent (true )
119- .outputType (false )
120- .sizeAttributes (true ));
88+ cereal::XMLOutputArchive archive (memory_out);
12189 // ofstream memory_out (simInfo->memOutputFileName.c_str(), std::ios::binary);
12290 // cereal::BinaryOutputArchive archive(memory_out);
12391
124- #if defined(USE_GPU)
125- // Copies GPU Synapse props data to CPU for serialization
126- simulator.copyGPUSynapseToCPU ();
127- #endif // USE_GPU
128-
129- Model &model = simulator.getModel ();
130-
131- // Serializes synapse weights along with each synapse's source vertex and destination vertex
132- // archive(
133- // cereal::make_nvp("AllEdges", dynamic_cast<AllEdges &>(model.getConnections().getEdges())));
92+ if (!processArchive (archive, simulator)) {
93+ cerr << " Failed to serialize" << endl;
94+ }
95+ }
13496
135- archive (cereal::make_nvp (" Connections" , model.getConnections ()));
97+ template <typename Archive> bool Serializer::processArchive (Archive &archive, Simulator &simulator)
98+ {
99+ try {
100+ // Starts the serialization/deserialization process from the Model class.
101+ // Note that the Model object gets sliced, and only
102+ // the `serialize` function of the base Model class is called.
103+ archive (simulator.getModel ());
104+ // Serialize/Deserialize required global variables
105+ archive (initRNG, noiseRNG, g_simulationStep);
106+ } catch (cereal::Exception e) {
107+ cerr << e.what () << endl;
108+ return false ;
109+ }
110+ return true ;
136111}
0 commit comments