Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 26 additions & 1 deletion Simulator/Connections/Neuro/ConnStatic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,36 @@ 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_,
Recorder::UpdatedType::DYNAMIC);
recorder.registerVariable("destinationVertex", destVertexIndexCurrentEpoch_,
Recorder::UpdatedType::DYNAMIC);
}

bool ConnStatic::updateConnections()
{
Comment on lines +104 to +105

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In particular, see my questions attached to the UpdateConnections() method. A unit test should be able to verify that the ConnStatic data members are indeed copies of those from the Edge class.

// GPU STDP is not implemented, so this only uses the CPU edge data.
WCurrentEpoch_.startNewEpoch();
sourceVertexIndexCurrentEpoch_.startNewEpoch();
destVertexIndexCurrentEpoch_.startNewEpoch();

AllEdges &edges = getEdges();
const vector<unsigned char> &inUse = edges.getInUse();
const vector<BGFLOAT> &weights = edges.getWeights();
const vector<int> &sourceVertices = edges.getSourceVertexIndices();
const vector<int> &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]);
Comment on lines +121 to +123

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two questions:

  1. Why not record the originals in the Edge class?
  2. Alternatively, if it is desirable to copy them to ConnStatic each epoch, I think it will be necessary to first clear the three ConnStatic data members before starting the copy.

Use the CoPilot unit test skill to generate unit tests for this. It should catch the case where these aren't cleared and so aren't copies. Actually, can't you just use the assignment operator, std::copy(), or `vector::assign()?

}
}

return false;
}
3 changes: 3 additions & 0 deletions Simulator/Connections/Neuro/ConnStatic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<BGFLOAT> &getWCurrentEpoch() const
{
Expand Down
26 changes: 25 additions & 1 deletion Simulator/Edges/AllEdges.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,30 @@ class AllEdges {
/// Populate a edge index map.
virtual void createEdgeIndexMap(EdgeIndexMap &edgeIndexMap);

/// Get array of source vertex indices.
const vector<int> &getSourceVertexIndices() const
{
return sourceVertexIndex_;
}

/// Get array of destination vertex indices.
const vector<int> &getDestVertexIndices() const
{
return destVertexIndex_;
}

/// Get array of edge weights.
const vector<BGFLOAT> &getWeights() const
{
return W_;
}

/// Get array of active edge flags.
const vector<unsigned char> &getInUse() const
{
return inUse_;
}

/// Cereal serialization method
template <class Archive> void serialize(Archive &archive);

Expand Down Expand Up @@ -253,4 +277,4 @@ template <class Archive> void AllEdges::serialize(Archive &archive)
cereal::make_nvp("totalEdgeCount", totalEdgeCount_),
cereal::make_nvp("maxEdgesPerVertex", maxEdgesPerVertex_),
cereal::make_nvp("countVertices", countVertices_));
}
}
51 changes: 51 additions & 0 deletions Testing/UnitTesting/ConnStaticTests.cpp
Original file line number Diff line number Diff line change
@@ -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 <memory>
#include <vector>

namespace {

class TestConnStatic : public ConnStatic {
public:
void setEdges(std::unique_ptr<AllEdges> edges)
{
edges_ = std::move(edges);
}
};

TEST(ConnStatic, UpdateConnectionsCopiesActiveEdgesWithoutAccumulating)
{
auto edges = std::make_unique<AllSTDPSynapses>(3, 2);
edges->addEdge(edgeType::EE, 0, 2, 0.001);
edges->addEdge(edgeType::II, 2, 0, 0.001);

const std::vector<int> expectedSources {2, 0};
const std::vector<int> expectedDestinations {0, 2};
const std::vector<BGFLOAT> 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
Loading