@@ -104,11 +104,12 @@ void Hdf5Recorder::term()
104104}
105105
106106// create the dataset for constant variable and store the data to dataset
107- void Hdf5Recorder::saveSimData (const AllVertices &neurons )
107+ void Hdf5Recorder::saveSimData ()
108108{
109109 // Initialize datasets for constant variables
110110 for (auto &variableInfo : variableTable_) {
111- if (variableInfo.variableType_ == UpdatedType::CONSTANT) {
111+ if (variableInfo.variableLocation_ .getNumElements () > 0
112+ && variableInfo.variableType_ == UpdatedType::CONSTANT) {
112113 // Define dimensions for the constant dataset
113114 hsize_t constantDims[1 ]
114115 = {static_cast <hsize_t >(variableInfo.variableLocation_ .getNumElements ())};
@@ -122,6 +123,97 @@ void Hdf5Recorder::saveSimData(const AllVertices &neurons)
122123 }
123124}
124125
126+ // Processes and updates HDF5 datasets for variables marked as DYNAMIC
127+ void Hdf5Recorder::compileHistories ()
128+ {
129+ // Define the maximum chunk size for datasets to optimize storage and access
130+ // This defines the maximum number of elements per chunk
131+ // If the dataset size exceeds this value, HDF5 will create multiple chunks to store the data
132+ const hsize_t max_chunk_size = 1024 ;
133+
134+ // Iterate over each variableInfo object in the variable table
135+ for (auto &variableInfo : variableTable_) {
136+ // Process only variables marked as DYNAMIC, which change over time
137+ if (variableInfo.variableType_ == UpdatedType::DYNAMIC) {
138+ // Check if there are elements to process
139+ if (variableInfo.variableLocation_ .getNumElements () > 0 ) {
140+ // Determine the new dimensions for the dataset based on the number of elements
141+ hsize_t newDims[1 ]
142+ = {static_cast <hsize_t >(variableInfo.variableLocation_ .getNumElements ())};
143+
144+ // Create the dataset if it does not already exist
145+ if (!H5Iis_valid (variableInfo.hdf5DataSet_ .getId ())) {
146+ // Create initial dataspace with unlimited maximum dimensions
147+ hsize_t maxDims[1 ] = {H5S_UNLIMITED};
148+ DataSpace initialSpace (1 , newDims, maxDims);
149+
150+ // Create dataset creation properties and set chunk size for efficiency
151+ DSetCreatPropList cparms;
152+ hsize_t chunk_dims[1 ] = {std::min (newDims[0 ], max_chunk_size)};
153+ cparms.setChunk (1 , chunk_dims);
154+
155+ // Create the dataset with specified name, datatype, initial space, and properties
156+ variableInfo.hdf5DataSet_ = resultOut_->createDataSet (
157+ variableInfo.variableName_ , variableInfo.hdf5Datatype_ , initialSpace, cparms);
158+
159+ // Write the initial data to the dataset
160+ variableInfo.captureData ();
161+ } else {
162+ // Handle the case where the dataset already exists
163+
164+ // Get the current dimensions of the dataset
165+ DataSpace currentSpace = variableInfo.hdf5DataSet_ .getSpace ();
166+ hsize_t currentDims[1 ];
167+ currentSpace.getSimpleExtentDims (currentDims, nullptr );
168+
169+ // Calculate the new dimensions after appending the new data
170+ hsize_t appendDims[1 ] = {currentDims[0 ] + newDims[0 ]};
171+ variableInfo.hdf5DataSet_ .extend (appendDims);
172+
173+ // Select the hyperslab in the extended portion of the dataset
174+ DataSpace fileSpace = variableInfo.hdf5DataSet_ .getSpace ();
175+ hsize_t offset[1 ] = {currentDims[0 ]};
176+ fileSpace.selectHyperslab (H5S_SELECT_SET, newDims, offset);
177+
178+ // Create a memory dataspace for the new data
179+ DataSpace memSpace (1 , newDims);
180+
181+ // Prepare the data buffer and write the new data to the dataset
182+ if (variableInfo.hdf5Datatype_ == PredType::NATIVE_FLOAT) {
183+ vector<float > dataBuffer (variableInfo.variableLocation_ .getNumElements ());
184+ for (size_t i = 0 ; i < variableInfo.variableLocation_ .getNumElements (); ++i) {
185+ dataBuffer[i] = get<float >(variableInfo.variableLocation_ .getElement (i));
186+ }
187+ variableInfo.hdf5DataSet_ .write (dataBuffer.data (), variableInfo.hdf5Datatype_ ,
188+ memSpace, fileSpace);
189+ } else if (variableInfo.hdf5Datatype_ == PredType::NATIVE_INT) {
190+ vector<int > dataBuffer (variableInfo.variableLocation_ .getNumElements ());
191+ for (size_t i = 0 ; i < variableInfo.variableLocation_ .getNumElements (); ++i) {
192+ dataBuffer[i] = get<int >(variableInfo.variableLocation_ .getElement (i));
193+ }
194+ variableInfo.hdf5DataSet_ .write (dataBuffer.data (), variableInfo.hdf5Datatype_ ,
195+ memSpace, fileSpace);
196+ } else if (variableInfo.hdf5Datatype_ == PredType::NATIVE_UINT64) {
197+ vector<uint64_t > dataBuffer (variableInfo.variableLocation_ .getNumElements ());
198+ for (size_t i = 0 ; i < variableInfo.variableLocation_ .getNumElements (); ++i) {
199+ dataBuffer[i] = get<uint64_t >(variableInfo.variableLocation_ .getElement (i));
200+ }
201+ variableInfo.hdf5DataSet_ .write (dataBuffer.data (), variableInfo.hdf5Datatype_ ,
202+ memSpace, fileSpace);
203+ } else {
204+ // Throw an exception if the data type is unsupported
205+ throw runtime_error (" Unsupported data type for variable: "
206+ + variableInfo.variableName_ );
207+ }
208+ }
209+ }
210+ }
211+
212+ // Call startNewEpoch() to prepare for new data input
213+ variableInfo.variableLocation_ .startNewEpoch ();
214+ }
215+ }
216+
125217// / Receives a recorded variable entity from the variable owner class
126218// / used when the return type from recordable variable is supported by Recorder
127219/* *
0 commit comments