From 575ff7777a1fb74978ccb1c39117cb6b5152cfdd Mon Sep 17 00:00:00 2001 From: Scott Purdy Date: Mon, 12 Jun 2017 09:44:26 -0700 Subject: [PATCH 1/3] tmp --- src/nupic/algorithms/Cells4.hpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/nupic/algorithms/Cells4.hpp b/src/nupic/algorithms/Cells4.hpp index 2762a03fff..ad756b7ab2 100644 --- a/src/nupic/algorithms/Cells4.hpp +++ b/src/nupic/algorithms/Cells4.hpp @@ -26,9 +26,11 @@ #include #include #include -#include #include #include +#include +#include +#include #include #include @@ -262,7 +264,7 @@ namespace nupic { CBasicActivity _seg; }; - class Cells4 + class Cells4 : public Serializable { public: @@ -1073,6 +1075,20 @@ namespace nupic { return tmp.str().size(); } + //---------------------------------------------------------------------- + /** + * Write the state to a proto or file + */ + using Serializable::write; + virtual void write(Cells4Proto::Builder& proto) const override; + + //---------------------------------------------------------------------- + /** + * Read the state into a proto or file + */ + using Serializable::read; + virtual void read(Cells4Proto::Reader& proto) override; + //---------------------------------------------------------------------- /** * Save the state to the given file From 7517329f54261e6ad05c6332d6e410e5c1e47122 Mon Sep 17 00:00:00 2001 From: Scott Purdy Date: Tue, 13 Jun 2017 10:57:16 -0700 Subject: [PATCH 2/3] Adds serialization for Cells4, Cell, SegmentUpdate, CState, CStateIndexed, Segment, plus unit tests for Cells4 serialization --- src/CMakeLists.txt | 4 + src/nupic/algorithms/Cell.cpp | 29 +++++ src/nupic/algorithms/Cell.hpp | 12 +- src/nupic/algorithms/Cells4.cpp | 150 +++++++++++++++++++++++- src/nupic/algorithms/Cells4.hpp | 2 +- src/nupic/algorithms/Segment.hpp | 92 ++++++++++++++- src/nupic/algorithms/SegmentUpdate.hpp | 39 +++++- src/nupic/proto/Cell.capnp | 7 ++ src/nupic/proto/Cells4.capnp | 55 +++++++++ src/nupic/proto/Segment.capnp | 33 ++++++ src/nupic/proto/SegmentUpdate.capnp | 12 ++ src/test/unit/algorithms/Cells4Test.cpp | 42 +++++++ 12 files changed, 468 insertions(+), 9 deletions(-) create mode 100644 src/nupic/proto/Cell.capnp create mode 100644 src/nupic/proto/Cells4.capnp create mode 100644 src/nupic/proto/Segment.capnp create mode 100644 src/nupic/proto/SegmentUpdate.capnp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1d00ee56f4..2a3379547d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -214,6 +214,8 @@ set(src_py_support_files set(src_capnp_specs_rel nupic/proto/ArrayProto.capnp nupic/proto/BitHistory.capnp + nupic/proto/Cell.capnp + nupic/proto/Cells4.capnp nupic/proto/ClaClassifier.capnp nupic/proto/ConnectionsProto.capnp nupic/proto/LinkProto.capnp @@ -222,6 +224,8 @@ set(src_capnp_specs_rel nupic/proto/PyRegionProto.capnp nupic/proto/RandomProto.capnp nupic/proto/RegionProto.capnp + nupic/proto/Segment.capnp + nupic/proto/SegmentUpdate.capnp nupic/proto/SparseBinaryMatrixProto.capnp nupic/proto/SparseMatrixProto.capnp nupic/proto/SpatialPoolerProto.capnp diff --git a/src/nupic/algorithms/Cell.cpp b/src/nupic/algorithms/Cell.cpp index 29f324de4d..cda1e1a0bb 100644 --- a/src/nupic/algorithms/Cell.cpp +++ b/src/nupic/algorithms/Cell.cpp @@ -20,6 +20,7 @@ * --------------------------------------------------------------------- */ +#include #include using namespace nupic::algorithms::Cells4; @@ -121,6 +122,34 @@ void Cell::updateDutyCycle(UInt iterations) } } +//----------------------------------------------------------------------------- +void Cell::write(CellProto::Builder& proto) const +{ + auto segmentsProto = proto.initSegments(_segments.size()); + for (UInt i = 0; i < _segments.size(); ++i) + { + auto segProto = segmentsProto[i]; + _segments[i].write(segProto); + } +} + +//----------------------------------------------------------------------------- +void Cell::read(CellProto::Reader& proto) +{ + auto segmentsProto = proto.getSegments(); + _segments.resize(segmentsProto.size()); + _freeSegments.resize(0); + for (UInt i = 0; i < segmentsProto.size(); ++i) + { + auto segProto = segmentsProto[i]; + _segments[i].read(segProto); + if (_segments[i].empty()) + { + _freeSegments.push_back(i); + } + } +} + //----------------------------------------------------------------------------- void Cell::save(std::ostream& outStream) const { diff --git a/src/nupic/algorithms/Cell.hpp b/src/nupic/algorithms/Cell.hpp index 66e96becdf..299ad40ef3 100644 --- a/src/nupic/algorithms/Cell.hpp +++ b/src/nupic/algorithms/Cell.hpp @@ -24,6 +24,8 @@ #define NTA_CELL_HPP #include +#include +#include #include #include @@ -44,7 +46,7 @@ namespace nupic { * mismatches in unit testing when comparing the Python TP to the C++ down to the * segment level. */ - class Cell + class Cell : Serializable { private: std::vector< Segment > _segments; // both 'active' and 'inactive' segments @@ -252,6 +254,14 @@ namespace nupic { return buff.str().size(); } + //---------------------------------------------------------------------- + using Serializable::write; + virtual void write(CellProto::Builder& proto) const override; + + //---------------------------------------------------------------------- + using Serializable::read; + virtual void read(CellProto::Reader& proto) override; + //---------------------------------------------------------------------- void save(std::ostream& outStream) const; diff --git a/src/nupic/algorithms/Cells4.cpp b/src/nupic/algorithms/Cells4.cpp index ac66a3ed22..467918f772 100644 --- a/src/nupic/algorithms/Cells4.cpp +++ b/src/nupic/algorithms/Cells4.cpp @@ -35,14 +35,14 @@ #include #include #include -#include // is_in -#include // binary_save +#include #include #include -#include +#include // is_in +#include // binary_save #include - #include +#include using namespace nupic::algorithms::Cells4; @@ -1931,6 +1931,148 @@ void Cells4::reset() //} } + +//-------------------------------------------------------------------------------- +void Cells4::write(Cells4Proto::Builder& proto) const +{ + proto.setVersion(version()); + proto.setOwnsMemory(_ownsMemory); + auto randomProto = proto.initRng(); + _rng.write(randomProto); + proto.setNColumns(_nColumns); + proto.setNCellsPerCol(_nCellsPerCol); + proto.setActivationThreshold(_activationThreshold); + proto.setMinThreshold(_minThreshold); + proto.setNewSynapseCount(_newSynapseCount); + proto.setNIterations(_nIterations); + proto.setNLrnIterations(_nLrnIterations); + proto.setSegUpdateValidDuration(_segUpdateValidDuration); + proto.setInitSegFreq(_initSegFreq); + proto.setPermInitial(_permInitial); + proto.setPermConnected(_permConnected); + proto.setPermMax(_permMax); + proto.setPermDec(_permDec); + proto.setPermInc(_permInc); + proto.setGlobalDecay(_globalDecay); + proto.setDoPooling(_doPooling); + proto.setPamLength(_pamLength); + proto.setMaxInfBacktrack(_maxInfBacktrack); + proto.setMaxLrnBacktrack(_maxLrnBacktrack); + proto.setMaxSeqLength(_maxSeqLength); + proto.setLearnedSeqLength(_learnedSeqLength); + proto.setAvgLearnedSeqLength(_avgLearnedSeqLength); + proto.setMaxAge(_maxAge); + proto.setVerbosity(_verbosity); + proto.setMaxSegmentsPerCell(_maxSegmentsPerCell); + proto.setMaxSynapsesPerSegment(_maxSynapsesPerSegment); + proto.setCheckSynapseConsistency(_checkSynapseConsistency); + proto.setResetCalled(_resetCalled); + proto.setAvgInputDensity(_avgInputDensity); + proto.setPamCounter(_pamCounter); + + auto learnActiveStateTProto = proto.initLearnActiveStateT(); + _learnActiveStateT.write(learnActiveStateTProto); + auto learnActiveStateT1Proto = proto.initLearnActiveStateT1(); + _learnActiveStateT1.write(learnActiveStateT1Proto); + auto learnPredictedStateTProto = proto.initLearnPredictedStateT(); + _learnPredictedStateT.write(learnPredictedStateTProto); + auto learnPredictedStateT1Proto = proto.initLearnPredictedStateT1(); + _learnPredictedStateT1.write(learnPredictedStateT1Proto); + + auto cellListProto = proto.initCells(_nCells); + for (UInt i = 0; i < _nCells; ++i) + { + auto cellProto = cellListProto[i]; + _cells[i].write(cellProto); + } + + auto segmentUpdatesListProto = proto.initSegmentUpdates( + _segmentUpdates.size()); + for (UInt i = 0; i < _segmentUpdates.size(); ++i) + { + auto segmentUpdateProto = segmentUpdatesListProto[i]; + _segmentUpdates[i].write(segmentUpdateProto); + } +} + + +//-------------------------------------------------------------------------------- +void Cells4::read(Cells4Proto::Reader& proto) +{ + NTA_CHECK(proto.getVersion() == 2); + _ownsMemory = proto.getOwnsMemory(); + auto randomProto = proto.getRng(); + _rng.read(randomProto); + _nColumns = proto.getNColumns(); + _nCellsPerCol = proto.getNCellsPerCol(); + _activationThreshold = proto.getActivationThreshold(); + _minThreshold = proto.getMinThreshold(); + _newSynapseCount = proto.getNewSynapseCount(); + _nIterations = proto.getNIterations(); + _nLrnIterations = proto.getNLrnIterations(); + _segUpdateValidDuration = proto.getSegUpdateValidDuration(); + _initSegFreq = proto.getInitSegFreq(); + _permInitial = proto.getPermInitial(); + _permConnected = proto.getPermConnected(); + _permMax = proto.getPermMax(); + _permDec = proto.getPermDec(); + _permInc = proto.getPermInc(); + _globalDecay = proto.getGlobalDecay(); + _doPooling = proto.getDoPooling(); + _pamLength = proto.getPamLength(); + _maxInfBacktrack = proto.getMaxInfBacktrack(); + _maxLrnBacktrack = proto.getMaxLrnBacktrack(); + _maxSeqLength = proto.getMaxSeqLength(); + _learnedSeqLength = proto.getAvgLearnedSeqLength(); + _avgLearnedSeqLength = proto.getAvgLearnedSeqLength(); + _maxAge = proto.getMaxAge(); + _verbosity = proto.getVerbosity(); + _maxSegmentsPerCell = proto.getMaxSegmentsPerCell(); + _maxSynapsesPerSegment = proto.getMaxSynapsesPerSegment(); + _checkSynapseConsistency = proto.getCheckSynapseConsistency(); + + _resetCalled = proto.getResetCalled(); + + _avgInputDensity = proto.getAvgInputDensity(); + _pamCounter = proto.getPamCounter(); + + auto learnActiveStateTProto = proto.getLearnActiveStateT(); + _learnActiveStateT.read(learnActiveStateTProto); + auto learnActiveStateT1Proto = proto.getLearnActiveStateT1(); + _learnActiveStateT1.read(learnActiveStateT1Proto); + auto learnPredictedStateTProto = proto.getLearnPredictedStateT(); + _learnPredictedStateT.read(learnPredictedStateTProto); + auto learnPredictedStateT1Proto = proto.getLearnPredictedStateT1(); + _learnPredictedStateT1.read(learnPredictedStateT1Proto); + + auto cellListProto = proto.getCells(); + _nCells = cellListProto.size(); + _cells.resize(_nCells); + for (UInt i = 0; i < cellListProto.size(); ++i) + { + auto cellProto = cellListProto[i]; + _cells[i].read(cellProto); + } + + auto segmentUpdatesListProto = proto.getSegmentUpdates(); + _segmentUpdates.clear(); + _segmentUpdates.resize(segmentUpdatesListProto.size()); + for (UInt i = 0; i < segmentUpdatesListProto.size(); ++i) + { + auto segmentUpdateProto = segmentUpdatesListProto[i]; + _segmentUpdates[i].read(segmentUpdateProto); + } + + rebuildOutSynapses(); + if (_checkSynapseConsistency || (_nCells * _maxSegmentsPerCell < 100000)) + { + NTA_CHECK(invariants(true)); + } + + _version = VERSION; +} + + //-------------------------------------------------------------------------------- void Cells4::save(std::ostream& outStream) const { diff --git a/src/nupic/algorithms/Cells4.hpp b/src/nupic/algorithms/Cells4.hpp index ad756b7ab2..5ae8efc8f1 100644 --- a/src/nupic/algorithms/Cells4.hpp +++ b/src/nupic/algorithms/Cells4.hpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/nupic/algorithms/Segment.hpp b/src/nupic/algorithms/Segment.hpp index bf3bbfe7a2..441a03172d 100644 --- a/src/nupic/algorithms/Segment.hpp +++ b/src/nupic/algorithms/Segment.hpp @@ -33,6 +33,8 @@ #include // is_sorted #include // binary_save +#include +#include #include @@ -88,7 +90,7 @@ namespace nupic { /** * Encapsulate the arrays used to maintain per-cell state. */ - class CState + class CState : Serializable { public: static const UInt VERSION = 1; @@ -165,6 +167,29 @@ namespace nupic { outStream << std::endl << "end" << std::endl; } + using Serializable::write; + virtual void write(CStateProto::Builder& proto) const override + { + proto.setVersion(VERSION); + proto.setFMemoryAllocatedByPython(_fMemoryAllocatedByPython); + auto pDataProto = proto.initPData(_nCells); + for (UInt i = 0; i < _nCells; ++i) + { + pDataProto[i] = _pData[i]; + } + } + using Serializable::read; + virtual void read(CStateProto::Reader& proto) override + { + NTA_CHECK(proto.getVersion() == 1); + _fMemoryAllocatedByPython = proto.getFMemoryAllocatedByPython(); + auto pDataProto = proto.getPData(); + _nCells = pDataProto.size(); + for (UInt i = 0; i < _nCells; ++i) + { + _pData[i] = pDataProto[i]; + } + } void load(std::istream& inStream) { UInt version; @@ -271,6 +296,27 @@ namespace nupic { } outStream << "end" << std::endl; } + void write(CStateProto::Builder& proto) const override + { + CState::write(proto); + proto.setCountOn(_countOn); + auto cellsOnProto = proto.initCellsOn(_cellsOn.size()); + for (UInt i = 0; i < _cellsOn.size(); ++i) + { + cellsOnProto.set(i, _cellsOn[i]); + } + } + void read(CStateProto::Reader& proto) override + { + CState::read(proto); + _countOn = proto.getCountOn(); + auto cellsOnProto = proto.getCellsOn(); + _cellsOn.resize(cellsOnProto.size()); + for (UInt i = 0; i < cellsOnProto.size(); ++i) + { + _cellsOn[i] = cellsOnProto[i]; + } + } void load(std::istream& inStream) { UInt version; @@ -334,7 +380,7 @@ namespace nupic { //----------------------------------------------------------------------- - class Segment + class Segment : Serializable { public: typedef std::vector< InSynapse > InSynapses; @@ -812,6 +858,48 @@ namespace nupic { return buff.str().size(); } + //---------------------------------------------------------------------- + using Serializable::write; + void write(SegmentProto::Builder& proto) const override + { + NTA_ASSERT(invariants()); + proto.setSeqSegFlag(_seqSegFlag); + proto.setFrequency(_frequency); + proto.setNConnected(_nConnected); + proto.setTotalActivations(_totalActivations); + proto.setPositiveActivations(_positiveActivations); + proto.setLastActiveIteration(_lastActiveIteration); + proto.setLastPosDutyCycle(_lastPosDutyCycle); + proto.setLastPosDutyCycleIteration(_lastPosDutyCycleIteration); + auto synapsesProto = proto.initSynapses(size()); + for (UInt i = 0; i < size(); ++i) + { + auto inSynapseProto = synapsesProto[i]; + inSynapseProto.setSrcCellIdx(_synapses[i].srcCellIdx()); + inSynapseProto.setPermanence(_synapses[i].permanence()); + } + } + + //---------------------------------------------------------------------- + using Serializable::read; + void read(SegmentProto::Reader& proto) override + { + _seqSegFlag = proto.getSeqSegFlag(); + _frequency = proto.getFrequency(); + _nConnected = proto.getNConnected(); + _totalActivations = proto.getTotalActivations(); + _positiveActivations = proto.getPositiveActivations(); + _lastActiveIteration = proto.getLastActiveIteration(); + _lastPosDutyCycle = proto.getLastPosDutyCycle(); + _lastPosDutyCycleIteration = proto.getLastPosDutyCycleIteration(); + _synapses.clear(); + for (auto inSynapseProto : proto.getSynapses()) + { + _synapses.emplace_back(inSynapseProto.getSrcCellIdx(), + inSynapseProto.getPermanence()); + } + } + //---------------------------------------------------------------------- inline void save(std::ostream& outStream) const { diff --git a/src/nupic/algorithms/SegmentUpdate.hpp b/src/nupic/algorithms/SegmentUpdate.hpp index 22acdfb0c3..a3711a3eb4 100644 --- a/src/nupic/algorithms/SegmentUpdate.hpp +++ b/src/nupic/algorithms/SegmentUpdate.hpp @@ -23,6 +23,8 @@ #ifndef NTA_SEGMENTUPDATE_HPP #define NTA_SEGMENTUPDATE_HPP +#include +#include #include #include using namespace nupic; @@ -43,7 +45,7 @@ namespace nupic { * than the iteration they were created in. SegmentUpdates have a timeStamp, * and they are discarded without being applied if they become 'stale'. */ - class SegmentUpdate + class SegmentUpdate : Serializable { public: typedef std::vector::const_iterator const_iterator; @@ -110,6 +112,41 @@ namespace nupic { */ bool invariants(Cells4* cells =nullptr) const; + //--------------------------------------------------------------------- + using Serializable::write; + void write(SegmentUpdateProto::Builder& proto) const override + { + proto.setSequenceSegment(_sequenceSegment); + proto.setCellIdx(_cellIdx); + proto.setSegIdx(_segIdx); + proto.setTimestamp(_timeStamp); + auto synapsesProto = proto.initSynapses(_synapses.size()); + for (UInt i = 0; i < _synapses.size(); ++i) + { + synapsesProto.set(i, _synapses[i]); + } + proto.setPhase1Flag(_phase1Flag); + proto.setWeaklyPredicting(_weaklyPredicting); + } + + //--------------------------------------------------------------------- + using Serializable::read; + void read(SegmentUpdateProto::Reader& proto) override + { + _sequenceSegment = proto.getSequenceSegment(); + _cellIdx = proto.getCellIdx(); + _segIdx = proto.getSegIdx(); + _timeStamp = proto.getTimestamp(); + auto synapsesProto = proto.getSynapses(); + _synapses.resize(synapsesProto.size()); + for (UInt i = 0; i < synapsesProto.size(); ++i) + { + _synapses[i] = synapsesProto[i]; + } + _phase1Flag = proto.getPhase1Flag(); + _weaklyPredicting = proto.getWeaklyPredicting(); + } + //--------------------------------------------------------------------- void save(std::ostream& outStream) const { diff --git a/src/nupic/proto/Cell.capnp b/src/nupic/proto/Cell.capnp new file mode 100644 index 0000000000..f95a9f9f63 --- /dev/null +++ b/src/nupic/proto/Cell.capnp @@ -0,0 +1,7 @@ +@0xcf9698b0f93fc8e4; + +using import "/nupic/proto/Segment.capnp".SegmentProto; + +struct CellProto { + segments @0 :List(SegmentProto); +} diff --git a/src/nupic/proto/Cells4.capnp b/src/nupic/proto/Cells4.capnp new file mode 100644 index 0000000000..045b3f7fd1 --- /dev/null +++ b/src/nupic/proto/Cells4.capnp @@ -0,0 +1,55 @@ +@0xd5c4908fa0384eda; + +using import "/nupic/proto/Cell.capnp".CellProto; +using import "/nupic/proto/RandomProto.capnp".RandomProto; +using import "/nupic/proto/Segment.capnp".CStateProto; +using import "/nupic/proto/SegmentUpdate.capnp".SegmentUpdateProto; + +# Next ID: 39 +struct Cells4Proto { + version @0 :UInt16; + ownsMemory @1 :Bool; + rng @2 :RandomProto; + nColumns @3 :UInt32; + nCellsPerCol @4 :UInt32; + activationThreshold @5 :UInt32; + minThreshold @6 :UInt32; + newSynapseCount @7 :UInt32; + nIterations @8 :UInt32; + nLrnIterations @9 :UInt32; + segUpdateValidDuration @10 :UInt32; + initSegFreq @11 :Float32; + permInitial @12 :Float32; + permConnected @13 :Float32; + permMax @14 :Float32; + permDec @15 :Float32; + permInc @16 :Float32; + globalDecay @17 :Float32; + doPooling @18 :Bool; + pamLength @19 :UInt32; + maxInfBacktrack @20 :UInt32; + maxLrnBacktrack @21 :UInt32; + maxSeqLength @22 :UInt32; + learnedSeqLength @23 :UInt32; + avgLearnedSeqLength @24 :Float32; + maxAge @25 :UInt32; + verbosity @26 :UInt8; + maxSegmentsPerCell @27 :UInt32; + maxSynapsesPerSegment @28 :UInt32; + checkSynapseConsistency @29 :Bool; + + # Internal variables + resetCalled @30 :Bool; + + avgInputDensity @31 :Float32; + pamCounter @32 :UInt32; + + # The various inference and learning states + learnActiveStateT @33 :CStateProto; + learnActiveStateT1 @34 :CStateProto; + learnPredictedStateT @35 :CStateProto; + learnPredictedStateT1 @36 :CStateProto; + + cells @37 :List(CellProto); + segmentUpdates @38 :List(SegmentUpdateProto); +} diff --git a/src/nupic/proto/Segment.capnp b/src/nupic/proto/Segment.capnp new file mode 100644 index 0000000000..b6d5720662 --- /dev/null +++ b/src/nupic/proto/Segment.capnp @@ -0,0 +1,33 @@ +@0xf2eaadec04697984; + +# Next ID: 2 +struct InSynapseProto { + srcCellIdx @0 :UInt32; + permanence @1 :Float32; +} + +# Next ID: 9 +struct SegmentProto { + seqSegFlag @0 :Bool; + frequency @1 :Float32; + nConnected @2 :UInt32; + totalActivations @3 :UInt32; + positiveActivations @4 :UInt32; + lastActiveIteration @5 :UInt32; + lastPosDutyCycle @6 :Float32; + lastPosDutyCycleIteration @7 :UInt32; + synapses @8 :List(InSynapseProto); +} + +# Next ID: 5 +struct CStateProto { + version @0 :UInt16; + fMemoryAllocatedByPython @1 :Bool; + # length of list is stored as nCells in class + pData @2 :Data; + + # CStateIndexed additional variables. If not using CStateIndexed, these + # values should be ignored. + countOn @3 :UInt32; + cellsOn @4 :List(UInt32); +} diff --git a/src/nupic/proto/SegmentUpdate.capnp b/src/nupic/proto/SegmentUpdate.capnp new file mode 100644 index 0000000000..3a1ae7c5dc --- /dev/null +++ b/src/nupic/proto/SegmentUpdate.capnp @@ -0,0 +1,12 @@ +@0xe7a17ea776969175; + +# Next ID: 7 +struct SegmentUpdateProto { + sequenceSegment @0 :Bool; + cellIdx @1 :UInt32; + segIdx @2 :UInt32; + timestamp @3 :UInt32; + synapses @4 :List(UInt32); + phase1Flag @5 :Bool; + weaklyPredicting @6 :Bool; +} diff --git a/src/test/unit/algorithms/Cells4Test.cpp b/src/test/unit/algorithms/Cells4Test.cpp index 5cd2b0c93d..89e9ffee39 100644 --- a/src/test/unit/algorithms/Cells4Test.cpp +++ b/src/test/unit/algorithms/Cells4Test.cpp @@ -27,11 +27,15 @@ #include #include +#include +#include +#include #include #include #include #include // is_in +#include using namespace nupic::algorithms::Cells4; @@ -78,6 +82,44 @@ std::vector _getOrderedSynapseIndexesForSrcCells(const Segment& segment, } +TEST(Cells4Test, capnpSerialization) +{ + Cells4 cells( + 10, 2, 1, 1, 1, 1, 0.5, 0.8, 1, 0.1, 0.1, 0, false, -1, true, false); + std::vector input(10, 0.0); + input[1] = 1.0; + input[4] = 1.0; + input[5] = 1.0; + input[9] = 1.0; + std::vector output(10*2); + cells.compute(&input.front(), &output.front(), true, true); + + Cells4 secondCells( + 10, 2, 1, 1, 1, 1, 0.5, 0.8, 1, 0.1, 0.1, 0, false, -1, true, false); + { + capnp::MallocMessageBuilder message1; + Cells4Proto::Builder cells4Builder = message1.initRoot(); + cells.write(cells4Builder); + std::stringstream ss; + kj::std::StdOutputStream out(ss); + capnp::writeMessage(out, message1); + + kj::std::StdInputStream in(ss); + capnp::InputStreamMessageReader message2(in); + Cells4Proto::Reader cells4Reader = message2.getRoot(); + secondCells.read(cells4Reader); + } + + std::vector secondOutput(10*2); + cells.compute(&input.front(), &output.front(), true, true); + secondCells.compute(&input.front(), &secondOutput.front(), true, true); + for (UInt i = 0; i < 10; ++i) + { + ASSERT_EQ(output[i], secondOutput[i]) << "Outputs differ at index " << i; + } +} + + /* * Test Cells4::_generateListsOfSynapsesToAdjustForAdaptSegment. From 687e517e93d364c88bf60fb03863f66fd467fd58 Mon Sep 17 00:00:00 2001 From: Scott Purdy Date: Tue, 13 Jun 2017 11:32:44 -0700 Subject: [PATCH 3/3] Code review feedback --- src/nupic/algorithms/Cells4.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nupic/algorithms/Cells4.cpp b/src/nupic/algorithms/Cells4.cpp index 467918f772..7656349825 100644 --- a/src/nupic/algorithms/Cells4.cpp +++ b/src/nupic/algorithms/Cells4.cpp @@ -2023,7 +2023,7 @@ void Cells4::read(Cells4Proto::Reader& proto) _maxInfBacktrack = proto.getMaxInfBacktrack(); _maxLrnBacktrack = proto.getMaxLrnBacktrack(); _maxSeqLength = proto.getMaxSeqLength(); - _learnedSeqLength = proto.getAvgLearnedSeqLength(); + _learnedSeqLength = proto.getLearnedSeqLength(); _avgLearnedSeqLength = proto.getAvgLearnedSeqLength(); _maxAge = proto.getMaxAge(); _verbosity = proto.getVerbosity();