diff --git a/CMakeLists.txt b/CMakeLists.txt index be871596c..973efffa0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -484,6 +484,7 @@ add_executable(tests Testing/UnitTesting/OperationManagerTestingClass.h Testing/UnitTesting/VerticesFactoryTests.cpp Testing/UnitTesting/ConnectionsFactoryTests.cpp + Testing/UnitTesting/ConnStaticTests.cpp Testing/UnitTesting/EdgesFactoryTests.cpp Testing/UnitTesting/LayoutFactoryTests.cpp Testing/UnitTesting/RecorderFactoryTests.cpp diff --git a/Simulator/Connections/Neuro/ConnStatic.cpp b/Simulator/Connections/Neuro/ConnStatic.cpp index 3f2f712fa..a1ab392cc 100644 --- a/Simulator/Connections/Neuro/ConnStatic.cpp +++ b/Simulator/Connections/Neuro/ConnStatic.cpp @@ -93,7 +93,6 @@ void ConnStatic::printParameters() const void ConnStatic::registerHistoryVariables() { // Register the following variables to be recorded - // Note: There may be potential duplicate weight, source, destination vertices Recorder &recorder = Simulator::getInstance().getModel().getRecorder(); recorder.registerVariable("weight", WCurrentEpoch_, Recorder::UpdatedType::DYNAMIC); recorder.registerVariable("sourceVertex", sourceVertexIndexCurrentEpoch_, @@ -101,3 +100,29 @@ void ConnStatic::registerHistoryVariables() recorder.registerVariable("destinationVertex", destVertexIndexCurrentEpoch_, Recorder::UpdatedType::DYNAMIC); } + +bool ConnStatic::updateConnections() +{ + // GPU STDP is not implemented, so this only uses the CPU edge data. + WCurrentEpoch_.startNewEpoch(); + sourceVertexIndexCurrentEpoch_.startNewEpoch(); + destVertexIndexCurrentEpoch_.startNewEpoch(); + + AllEdges &edges = getEdges(); + const vector &inUse = edges.getInUse(); + const vector &weights = edges.getWeights(); + const vector &sourceVertices = edges.getSourceVertexIndices(); + const vector &destVertices = edges.getDestVertexIndices(); + + // Copy one value per active edge into parallel recorder vectors. + // Entries at the same index describe the same edge. + for (BGSIZE iEdg = 0; iEdg < inUse.size(); iEdg++) { + if (inUse[iEdg]) { + WCurrentEpoch_.push_back(weights[iEdg]); + sourceVertexIndexCurrentEpoch_.push_back(sourceVertices[iEdg]); + destVertexIndexCurrentEpoch_.push_back(destVertices[iEdg]); + } + } + + return false; +} diff --git a/Simulator/Connections/Neuro/ConnStatic.h b/Simulator/Connections/Neuro/ConnStatic.h index 67d0a8fb6..fbb7bbc44 100644 --- a/Simulator/Connections/Neuro/ConnStatic.h +++ b/Simulator/Connections/Neuro/ConnStatic.h @@ -64,6 +64,9 @@ class ConnStatic : public Connections { /// Registers history variables for recording during simulation virtual void registerHistoryVariables() override; + /// Populates edge history variables for recording during the current epoch. + virtual bool updateConnections() override; + /// Get array of vertex weights const vector &getWCurrentEpoch() const { diff --git a/Simulator/Edges/AllEdges.h b/Simulator/Edges/AllEdges.h index ccc49308a..b726cdfec 100644 --- a/Simulator/Edges/AllEdges.h +++ b/Simulator/Edges/AllEdges.h @@ -59,6 +59,30 @@ class AllEdges { /// Populate a edge index map. virtual void createEdgeIndexMap(EdgeIndexMap &edgeIndexMap); + /// Get array of source vertex indices. + const vector &getSourceVertexIndices() const + { + return sourceVertexIndex_; + } + + /// Get array of destination vertex indices. + const vector &getDestVertexIndices() const + { + return destVertexIndex_; + } + + /// Get array of edge weights. + const vector &getWeights() const + { + return W_; + } + + /// Get array of active edge flags. + const vector &getInUse() const + { + return inUse_; + } + /// Cereal serialization method template void serialize(Archive &archive); @@ -253,4 +277,4 @@ template void AllEdges::serialize(Archive &archive) cereal::make_nvp("totalEdgeCount", totalEdgeCount_), cereal::make_nvp("maxEdgesPerVertex", maxEdgesPerVertex_), cereal::make_nvp("countVertices", countVertices_)); -} \ No newline at end of file +} diff --git a/Testing/UnitTesting/ConnStaticTests.cpp b/Testing/UnitTesting/ConnStaticTests.cpp new file mode 100644 index 000000000..dfd3d0c3f --- /dev/null +++ b/Testing/UnitTesting/ConnStaticTests.cpp @@ -0,0 +1,51 @@ +/** + * @file ConnStaticTests.cpp + * + * @brief Unit tests for ConnStatic. + * + * @ingroup Testing/UnitTesting + */ + +#include "AllSTDPSynapses.h" +#include "ConnStatic.h" +#include "gtest/gtest.h" +#include +#include + +namespace { + + class TestConnStatic : public ConnStatic { + public: + void setEdges(std::unique_ptr edges) + { + edges_ = std::move(edges); + } + }; + + TEST(ConnStatic, UpdateConnectionsCopiesActiveEdgesWithoutAccumulating) + { + auto edges = std::make_unique(3, 2); + edges->addEdge(edgeType::EE, 0, 2, 0.001); + edges->addEdge(edgeType::II, 2, 0, 0.001); + + const std::vector expectedSources {2, 0}; + const std::vector expectedDestinations {0, 2}; + const std::vector expectedWeights {-10.0e-9, 10.0e-9}; + + TestConnStatic connections; + connections.setEdges(std::move(edges)); + + connections.updateConnections(); + + EXPECT_EQ(expectedSources, connections.getSourceVertexIndexCurrentEpoch()); + EXPECT_EQ(expectedDestinations, connections.getDestVertexIndexCurrentEpoch()); + EXPECT_EQ(expectedWeights, connections.getWCurrentEpoch()); + + connections.updateConnections(); + + EXPECT_EQ(expectedSources, connections.getSourceVertexIndexCurrentEpoch()); + EXPECT_EQ(expectedDestinations, connections.getDestVertexIndexCurrentEpoch()); + EXPECT_EQ(expectedWeights, connections.getWCurrentEpoch()); + } + +} // namespace