-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Connections better use typedefed types Segment, Synapse, ... #331
Changes from all commits
3244350
c6b3696
a5f4b13
09b6f51
4df1210
ca6cee2
6be5eb3
9535b56
7b17674
b8199bd
def0898
858df3b
aa84db2
27511f0
f88416e
bf56929
ac9bfb4
57e4e27
c45e85f
ad9cbea
3b59e36
5537fa2
3a389ad
99a20ff
3a89a7c
0bfd866
3a724ed
3439dc3
558af1c
c8ee571
80bd126
e0e98c4
d55af21
c37d74a
3216f54
ba248fa
533242f
3f849e7
27a7d81
493e308
d02eb76
ccda59c
c034ca3
6609451
e87166e
c1499f7
132d706
d27d9ce
ecb5584
fa9e70d
d37ede8
069ba3c
db49a59
7c5921b
90169f7
c46e4c4
7cbe5b5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -83,11 +83,13 @@ void Connections::unsubscribe(UInt32 token) { | |
|
||
Segment Connections::createSegment(CellIdx cell) { | ||
Segment segment; | ||
if (destroyedSegments_.size() > 0) { | ||
if (!destroyedSegments_.empty() ) { //reuse old, destroyed segs | ||
segment = destroyedSegments_.back(); | ||
destroyedSegments_.pop_back(); | ||
} else { | ||
segment = (Segment)segments_.size(); | ||
} else { //create a new segment | ||
NTA_CHECK(segments_.size() < std::numeric_limits<Segment>::max()) << "Add segment failed: Range of Segment (data-type) insufficinet size." | ||
<< (size_t)segments_.size() << " < " << (size_t)std::numeric_limits<Segment>::max(); | ||
segment = static_cast<Segment>(segments_.size()); | ||
segments_.push_back(SegmentData()); | ||
ctrl-z-9000-times marked this conversation as resolved.
Show resolved
Hide resolved
|
||
segmentOrdinals_.push_back(0); | ||
} | ||
|
@@ -112,11 +114,13 @@ Synapse Connections::createSynapse(Segment segment, | |
Permanence permanence) { | ||
// Get an index into the synapses_ list, for the new synapse to reside at. | ||
Synapse synapse; | ||
if (destroyedSynapses_.size() > 0) { | ||
if (!destroyedSynapses_.empty() ) { | ||
synapse = destroyedSynapses_.back(); | ||
destroyedSynapses_.pop_back(); | ||
} else { | ||
synapse = (UInt)synapses_.size(); | ||
NTA_CHECK(synapses_.size() < std::numeric_limits<Synapse>::max()) << "Add synapse failed: Range of Synapse (data-type) insufficient size." | ||
<< synapses_.size() << " < " << (size_t)std::numeric_limits<Synapse>::max(); | ||
synapse = static_cast<Synapse>(synapses_.size()); | ||
synapses_.push_back(SynapseData()); | ||
synapseOrdinals_.push_back(0); | ||
} | ||
|
@@ -166,7 +170,7 @@ bool Connections::synapseExists_(Synapse synapse) const { | |
* last synapse in the list over this synapse. | ||
*/ | ||
void Connections::removeSynapseFromPresynapticMap_( | ||
const UInt index, | ||
const Synapse index, | ||
vector<Synapse> &preSynapses, | ||
vector<Segment> &preSegments) | ||
{ | ||
|
@@ -267,19 +271,23 @@ void Connections::updateSynapsePermanence(Synapse synapse, | |
permanence = std::max(permanence, minPermanence ); | ||
|
||
auto &synData = synapses_[synapse]; | ||
bool before = synData.permanence >= connectedThreshold_; | ||
bool after = permanence >= connectedThreshold_; | ||
|
||
const bool before = synData.permanence >= connectedThreshold_; | ||
const bool after = permanence >= connectedThreshold_; | ||
synData.permanence = permanence; | ||
|
||
if( before != after ) { | ||
if( before == after ) { //no change | ||
return; | ||
} | ||
const auto &presyn = synData.presynapticCell; | ||
auto &potentialPresyn = potentialSynapsesForPresynapticCell_[presyn]; | ||
auto &potentialPreseg = potentialSegmentsForPresynapticCell_[presyn]; | ||
auto &connectedPresyn = connectedSynapsesForPresynapticCell_[presyn]; | ||
auto &connectedPreseg = connectedSegmentsForPresynapticCell_[presyn]; | ||
const auto &segment = synData.segment; | ||
auto &segmentData = segments_[segment]; | ||
if( after ) { | ||
|
||
if( after ) { //connect | ||
segmentData.numConnected++; | ||
|
||
// Remove this synapse from presynaptic potential synapses. | ||
|
@@ -291,7 +299,7 @@ void Connections::updateSynapsePermanence(Synapse synapse, | |
connectedPresyn.push_back( synapse ); | ||
connectedPreseg.push_back( segment ); | ||
} | ||
else { | ||
else { //disconnected | ||
segmentData.numConnected--; | ||
|
||
// Remove this synapse from presynaptic connected synapses. | ||
|
@@ -304,10 +312,9 @@ void Connections::updateSynapsePermanence(Synapse synapse, | |
potentialPreseg.push_back( segment ); | ||
} | ||
|
||
for (auto h : eventHandlers_) { | ||
for (auto h : eventHandlers_) { //TODO handle callbacks in performance-critical method only in Debug? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this method is a hotspot I found in profiling, do we really need the callbacks here, can be left out only for debug,.. ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea I have no idea why these exist but their part of the public API so I didn't remove them. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll profile w/o the loop, imo this would be a candidate to break the API, if shows performance gain. |
||
h.second->onUpdateSynapsePermanence(synapse, permanence); | ||
} | ||
} | ||
} | ||
|
||
const vector<Segment> &Connections::segmentsForCell(CellIdx cell) const { | ||
|
@@ -358,9 +365,7 @@ const SynapseData &Connections::dataForSynapse(Synapse synapse) const { | |
return synapses_[synapse]; | ||
} | ||
|
||
UInt32 Connections::segmentFlatListLength() const { return (UInt32)segments_.size(); } | ||
|
||
bool Connections::compareSegments(Segment a, Segment b) const { | ||
bool Connections::compareSegments(const Segment a, const Segment b) const { | ||
const SegmentData &aData = segments_[a]; | ||
const SegmentData &bData = segments_[b]; | ||
if (aData.cell < bData.cell) { | ||
|
@@ -385,24 +390,24 @@ Connections::synapsesForPresynapticCell(CellIdx presynapticCell) const { | |
|
||
|
||
void Connections::computeActivity( | ||
vector<UInt32> &numActiveConnectedSynapsesForSegment, | ||
vector<SynapseIdx> &numActiveConnectedSynapsesForSegment, | ||
const vector<CellIdx> &activePresynapticCells) const | ||
{ | ||
NTA_ASSERT(numActiveConnectedSynapsesForSegment.size() == segments_.size()); | ||
|
||
// Iterate through all connected synapses. | ||
for (CellIdx cell : activePresynapticCells) { | ||
for (const auto& cell : activePresynapticCells) { | ||
if (connectedSegmentsForPresynapticCell_.count(cell)) { | ||
for( Segment segment : connectedSegmentsForPresynapticCell_.at(cell)) { | ||
for(const auto& segment : connectedSegmentsForPresynapticCell_.at(cell)) { | ||
++numActiveConnectedSynapsesForSegment[segment]; | ||
} | ||
} | ||
} | ||
} | ||
|
||
void Connections::computeActivity( | ||
vector<UInt32> &numActiveConnectedSynapsesForSegment, | ||
vector<UInt32> &numActivePotentialSynapsesForSegment, | ||
vector<SynapseIdx> &numActiveConnectedSynapsesForSegment, | ||
vector<SynapseIdx> &numActivePotentialSynapsesForSegment, | ||
const vector<CellIdx> &activePresynapticCells) const { | ||
NTA_ASSERT(numActiveConnectedSynapsesForSegment.size() == segments_.size()); | ||
NTA_ASSERT(numActivePotentialSynapsesForSegment.size() == segments_.size()); | ||
|
@@ -416,9 +421,9 @@ void Connections::computeActivity( | |
std::copy( numActiveConnectedSynapsesForSegment.begin(), | ||
numActiveConnectedSynapsesForSegment.end(), | ||
numActivePotentialSynapsesForSegment.begin()); | ||
for (CellIdx cell : activePresynapticCells) { | ||
for (const auto& cell : activePresynapticCells) { | ||
if (potentialSegmentsForPresynapticCell_.count(cell)) { | ||
for( Segment segment : potentialSegmentsForPresynapticCell_.at(cell)) { | ||
for(const auto& segment : potentialSegmentsForPresynapticCell_.at(cell)) { | ||
++numActivePotentialSynapsesForSegment[segment]; | ||
} | ||
} | ||
|
@@ -502,7 +507,7 @@ void Connections::raisePermanencesToThreshold( | |
|
||
// Raise the permance of all synapses in the potential pool uniformly. | ||
for( const auto &syn : synapses ) //TODO vectorize: vector + const to all members | ||
updateSynapsePermanence(syn, synapses_[syn].permanence + increment); | ||
updateSynapsePermanence(syn, synapses_[syn].permanence + increment); //this is performance HOTSPOT | ||
} | ||
|
||
|
||
|
@@ -561,7 +566,7 @@ void Connections::load(std::istream &inStream) { | |
// Check the saved version. | ||
int version; | ||
inStream >> version; | ||
NTA_CHECK(version <= 2); | ||
NTA_CHECK(version == 2); | ||
|
||
// Retrieve simple variables | ||
UInt numCells; | ||
|
@@ -570,22 +575,13 @@ void Connections::load(std::istream &inStream) { | |
inStream >> connectedThreshold; | ||
initialize(numCells, connectedThreshold); | ||
|
||
// This logic is complicated by the fact that old versions of the Connections | ||
// serialized "destroyed" segments and synapses, which we now ignore. | ||
for (UInt cell = 0; cell < numCells; cell++) { | ||
|
||
UInt numSegments; | ||
inStream >> numSegments; | ||
|
||
for (SegmentIdx j = 0; j < numSegments; j++) { | ||
bool destroyedSegment = false; | ||
if (version < 2) { | ||
inStream >> destroyedSegment; | ||
} | ||
|
||
Segment segment = {(UInt32)-1}; | ||
if (!destroyedSegment) | ||
segment = createSegment( cell ); | ||
Segment segment = createSegment( cell ); | ||
|
||
UInt numSynapses; | ||
inStream >> numSynapses; | ||
|
@@ -596,15 +592,6 @@ void Connections::load(std::istream &inStream) { | |
inStream >> presyn; | ||
inStream >> perm; | ||
|
||
if (version < 2) { | ||
bool destroyedSynapse = false; | ||
inStream >> destroyedSynapse; | ||
if( destroyedSynapse ) | ||
continue; | ||
} | ||
if( destroyedSegment ) | ||
continue; | ||
|
||
createSynapse( segment, presyn, perm ); | ||
} | ||
} | ||
|
@@ -615,51 +602,33 @@ void Connections::load(std::istream &inStream) { | |
} | ||
|
||
|
||
CellIdx Connections::numCells() const { return (CellIdx)cells_.size(); } | ||
|
||
UInt Connections::numSegments() const { | ||
return (UInt)(segments_.size() - destroyedSegments_.size()); | ||
} | ||
|
||
UInt Connections::numSegments(CellIdx cell) const { | ||
return (UInt)cells_[cell].segments.size(); | ||
} | ||
|
||
UInt Connections::numSynapses() const { | ||
return (UInt)(synapses_.size() - destroyedSynapses_.size()); | ||
} | ||
|
||
UInt Connections::numSynapses(Segment segment) const { | ||
return (UInt)segments_[segment].synapses.size(); | ||
} | ||
|
||
bool Connections::operator==(const Connections &other) const { | ||
if (cells_.size() != other.cells_.size()) | ||
return false; | ||
|
||
for (CellIdx i = 0; i < cells_.size(); ++i) { | ||
for (CellIdx i = 0; i < static_cast<CellIdx>(cells_.size()); i++) { | ||
const CellData &cellData = cells_[i]; | ||
const CellData &otherCellData = other.cells_[i]; | ||
|
||
if (cellData.segments.size() != otherCellData.segments.size()) { | ||
return false; | ||
} | ||
|
||
for (SegmentIdx j = 0; j < (SegmentIdx)cellData.segments.size(); ++j) { | ||
Segment segment = cellData.segments[j]; | ||
for (SegmentIdx j = 0; j < static_cast<SegmentIdx>(cellData.segments.size()); j++) { | ||
const Segment segment = cellData.segments[j]; | ||
const SegmentData &segmentData = segments_[segment]; | ||
Segment otherSegment = otherCellData.segments[j]; | ||
const Segment otherSegment = otherCellData.segments[j]; | ||
const SegmentData &otherSegmentData = other.segments_[otherSegment]; | ||
|
||
if (segmentData.synapses.size() != otherSegmentData.synapses.size() || | ||
segmentData.cell != otherSegmentData.cell) { | ||
return false; | ||
} | ||
|
||
for (SynapseIdx k = 0; k < (SynapseIdx)segmentData.synapses.size(); ++k) { | ||
Synapse synapse = segmentData.synapses[k]; | ||
for (SynapseIdx k = 0; k < static_cast<SynapseIdx>(segmentData.synapses.size()); k++) { | ||
const Synapse synapse = segmentData.synapses[k]; | ||
const SynapseData &synapseData = synapses_[synapse]; | ||
Synapse otherSynapse = otherSegmentData.synapses[k]; | ||
const Synapse otherSynapse = otherSegmentData.synapses[k]; | ||
const SynapseData &otherSynapseData = other.synapses_[otherSynapse]; | ||
|
||
if (synapseData.presynapticCell != otherSynapseData.presynapticCell || | ||
|
@@ -677,6 +646,3 @@ bool Connections::operator==(const Connections &other) const { | |
return true; | ||
} | ||
|
||
bool Connections::operator!=(const Connections &other) const { | ||
return !(*this == other); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bindings too now use proper typedefs