Skip to content
This repository has been archived by the owner on Sep 1, 2023. It is now read-only.

Commit

Permalink
Merge pull request #1182 from vitaly-krugl/nup2306-serialize-delayed-…
Browse files Browse the repository at this point in the history
…link-info

NUP-2306 Delayed Link serialization
  • Loading branch information
vitaly-krugl authored Jan 11, 2017
2 parents fef2fd6 + 100e1a5 commit eb6a966
Show file tree
Hide file tree
Showing 14 changed files with 703 additions and 82 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -----------------------------------------------------------------------------
# Numenta Platform for Intelligent Computing (NuPIC)
# Copyright (C) 2015, Numenta, Inc. Unless you have purchased from
# Copyright (C) 2015-2017, Numenta, Inc. Unless you have purchased from
# Numenta, Inc. a separate commercial license for this software code, the
# following terms and conditions apply:
#
Expand Down
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ endif()
# List all .capnp files here. The C++ files will be generated and included
# when compiling later on.
set(src_capnp_specs_rel
nupic/proto/ArrayProto.capnp
nupic/proto/BitHistory.capnp
nupic/proto/ClaClassifier.capnp
nupic/proto/ConnectionsProto.capnp
Expand Down Expand Up @@ -374,6 +375,7 @@ set(src_nupiccore_srcs
nupic/regions/VectorFileSensor.cpp
nupic/types/BasicType.cpp
nupic/types/Fraction.cpp
nupic/utils/ArrayProtoUtils.cpp
nupic/utils/LoggingException.cpp
nupic/utils/LogItem.cpp
nupic/utils/MovingAverage.cpp
Expand Down
18 changes: 17 additions & 1 deletion src/nupic/bindings/engine_internal.i
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* ---------------------------------------------------------------------
* Numenta Platform for Intelligent Computing (NuPIC)
* Copyright (C) 2013, Numenta, Inc. Unless you have an agreement
* Copyright (C) 2013-2017, Numenta, Inc. Unless you have an agreement
* with Numenta, Inc., for a separate license for this software code, the
* following terms and conditions apply:
*
Expand Down Expand Up @@ -46,6 +46,8 @@
* ----------------------------------------------------------------------
*/

#include <nupic/engine/Input.hpp>
#include <nupic/engine/Link.hpp>

#include <nupic/types/Types.hpp>
#include <nupic/types/Types.h>
Expand Down Expand Up @@ -170,8 +172,10 @@
%}
}


%extend nupic::Region
{

PyObject * getSelf()
{
nupic::Handle h = self->getParameterHandle("self");
Expand All @@ -188,6 +192,18 @@
{
return nupic::PyArrayRef<nupic::Byte>(self->getOutputData(name)).asNumpyArray();
}

// Purge heads of the region's input link buffers
void purgeInputLinkBufferHeads()
{
for (auto & input : self->getInputs())
{
for (auto link : input.second->getLinks())
{
link->purgeBufferHead();
}
}
}
}

%extend nupic::Network
Expand Down
7 changes: 3 additions & 4 deletions src/nupic/engine/Input.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* ---------------------------------------------------------------------
* Numenta Platform for Intelligent Computing (NuPIC)
* Copyright (C) 2013, Numenta, Inc. Unless you have an agreement
* Copyright (C) 2013-2017, Numenta, Inc. Unless you have an agreement
* with Numenta, Inc., for a separate license for this software code, the
* following terms and conditions apply:
*
Expand Down Expand Up @@ -53,9 +53,9 @@ Input::~Input()
}
}


void
Input::addLink(const std::string& linkType, const std::string& linkParams,
Output* srcOutput, const size_t propagationDelay)
Input::addLink(Link* link, Output* srcOutput)
{
if (initialized_)
NTA_THROW << "Attempt to add link to input " << name_
Expand All @@ -74,7 +74,6 @@ Input::addLink(const std::string& linkType, const std::string& linkParams,
}
}

auto link = new Link(linkType, linkParams, srcOutput, this, propagationDelay);
links_.push_back(link);

srcOutput->addLink(link);
Expand Down
20 changes: 5 additions & 15 deletions src/nupic/engine/Input.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* ---------------------------------------------------------------------
* Numenta Platform for Intelligent Computing (NuPIC)
* Copyright (C) 2013, Numenta, Inc. Unless you have an agreement
* Copyright (C) 2013-2017, Numenta, Inc. Unless you have an agreement
* with Numenta, Inc., for a separate license for this software code, the
* following terms and conditions apply:
*
Expand Down Expand Up @@ -97,25 +97,15 @@ namespace nupic
const std::string& getName() const;

/**
* Create a new Link between this input and the @a srcOutput.
* Add the given link to this input and to the list of links on the output
*
* The link will be added to this input and added to the list
* of links on the output
*
* @param linkType
* The type of the link
* @param linkParams
* The parameters of the link
* @param link
* The link to add.
* @param srcOutput
* The output of previous Region, which is also the source of the input
* @param propagationDelay
* Propagation delay of the link as number of network run
* iterations involving the link as input; the delay vectors, if
* any, are initially populated with 0's. Defaults to 0=no delay
*/
void
addLink(const std::string& linkType, const std::string& linkParams,
Output* srcOutput, const size_t propagationDelay=0);
addLink(Link* link, Output* srcOutput);

/**
* Locate an existing Link to the input.
Expand Down
110 changes: 78 additions & 32 deletions src/nupic/engine/Link.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* ---------------------------------------------------------------------
* Numenta Platform for Intelligent Computing (NuPIC)
* Copyright (C) 2013, Numenta, Inc. Unless you have an agreement
* Copyright (C) 2013-2017, Numenta, Inc. Unless you have an agreement
* with Numenta, Inc., for a separate license for this software code, the
* following terms and conditions apply:
*
Expand All @@ -25,6 +25,7 @@
*/
#include <cstring> // memcpy,memset
#include <nupic/engine/Link.hpp>
#include <nupic/utils/ArrayProtoUtils.hpp>
#include <nupic/utils/Log.hpp>
#include <nupic/engine/LinkPolicyFactory.hpp>
#include <nupic/engine/LinkPolicy.hpp>
Expand All @@ -37,7 +38,6 @@
namespace nupic
{


Link::Link(const std::string& linkType, const std::string& linkParams,
const std::string& srcRegionName, const std::string& destRegionName,
const std::string& srcOutputName, const std::string& destInputName,
Expand All @@ -53,7 +53,7 @@ Link::Link(const std::string& linkType, const std::string& linkParams,

Link::Link(const std::string& linkType, const std::string& linkParams,
Output* srcOutput, Input* destInput, const size_t propagationDelay):
srcBuffer_()
srcBuffer_(0)
{
commonConstructorInit_(linkType, linkParams,
srcOutput->getRegion().getName(),
Expand All @@ -66,6 +66,13 @@ Link::Link(const std::string& linkType, const std::string& linkParams,
// Note -- link is not usable until we set the destOffset, which happens at initialization time
}


Link::Link():
srcBuffer_(0)
{
}


void Link::commonConstructorInit_(const std::string& linkType, const std::string& linkParams,
const std::string& srcRegionName, const std::string& destRegionName,
const std::string& srcOutputName, const std::string& destInputName,
Expand Down Expand Up @@ -94,6 +101,38 @@ Link::~Link()
delete impl_;
}


void Link::initPropagationDelayBuffer_(size_t propagationDelay,
NTA_BasicType dataElementType,
size_t dataElementCount)
{
if (srcBuffer_.capacity() != 0)
{
// Already initialized; e.g., as result of de-serialization
return;
}

// Establish capacity for the requested delay data elements plus one slot for
// the next output element
srcBuffer_.set_capacity(propagationDelay + 1);

// Initialize delay data elements
size_t dataBufferSize = dataElementCount *
BasicType::getSize(dataElementType);

for(size_t i=0; i < propagationDelay; i++)
{
Array arrayTemplate(dataElementType);

srcBuffer_.push_back(arrayTemplate);

// Allocate 0-initialized data for current element
srcBuffer_[i].allocateBuffer(dataElementCount);
::memset(srcBuffer_[i].getBuffer(), 0, dataBufferSize);
}
}


void Link::initialize(size_t destinationOffset)
{
// Make sure all information is specified and
Expand Down Expand Up @@ -170,31 +209,9 @@ void Link::initialize(size_t destinationOffset)
// ---
// Initialize the propagation delay buffer
// ---

// Establish capacity for the requested delay data elements plus one slot for
// the next output element
srcBuffer_.set_capacity(propagationDelay_ + 1);

// Initialize delay data elements
const Array & srcArray = src_->getData();
size_t dataElementCount = srcArray.getCount();
auto dataElementType = srcArray.getType();
size_t dataBufferSize = dataElementCount *
BasicType::getSize(dataElementType);

Array arrayTemplate(dataElementType);

for(size_t i = 0; i < propagationDelay_; i++)
{
srcBuffer_.push_back(arrayTemplate);

if(dataElementCount != 0)
{
// Allocate 0-initialized data for current element
srcBuffer_[i].allocateBuffer(dataElementCount);
::memset(srcBuffer_[i].getBuffer(), 0, dataBufferSize);
}
}
initPropagationDelayBuffer_(propagationDelay_,
src_->getData().getType(),
src_->getData().getCount());

initialized_ = true;

Expand Down Expand Up @@ -290,16 +307,13 @@ const std::string Link::toString() const
return ss.str();
}

// called only by Input::addLink()
void Link::connectToNetwork(Output *src, Input *dest)
{
NTA_CHECK(src != nullptr);
NTA_CHECK(dest != nullptr);

src_ = src;
dest_ = dest;


}


Expand Down Expand Up @@ -396,17 +410,49 @@ void Link::write(LinkProto::Builder& proto) const
proto.setSrcOutput(srcOutputName_.c_str());
proto.setDestRegion(destRegionName_.c_str());
proto.setDestInput(destInputName_.c_str());

// Save delayed outputs
auto delayedOutputsBuilder = proto.initDelayedOutputs(propagationDelay_);
for (size_t i=0; i < propagationDelay_; ++i)
{
ArrayProtoUtils::copyArrayToArrayProto(srcBuffer_[i],
delayedOutputsBuilder[i]);
}
}


void Link::read(LinkProto::Reader& proto)
{
const auto delayedOutputsReader = proto.getDelayedOutputs();

commonConstructorInit_(
proto.getType().cStr(), proto.getParams().cStr(),
proto.getSrcRegion().cStr(), proto.getDestRegion().cStr(),
proto.getSrcOutput().cStr(), proto.getDestInput().cStr(),
0/*propagationDelay ZZZ TODO get from proto*/);
delayedOutputsReader.size()/*propagationDelay*/);

if (delayedOutputsReader.size())
{
// Initialize the propagation delay buffer with delay array buffers having 0
// elements that deserialization logic will replace with appropriately-sized
// buffers.
initPropagationDelayBuffer_(
propagationDelay_,
ArrayProtoUtils::getArrayTypeFromArrayProtoReader(delayedOutputsReader[0]),
0);

// Populate delayed outputs

for (size_t i=0; i < propagationDelay_; ++i)
{
ArrayProtoUtils::copyArrayProtoToArray(delayedOutputsReader[i],
srcBuffer_[i],
true/*allocArrayBuffer*/);
}
}
}


namespace nupic
{
std::ostream& operator<<(std::ostream& f, const Link& link)
Expand Down
16 changes: 15 additions & 1 deletion src/nupic/engine/Link.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* ---------------------------------------------------------------------
* Numenta Platform for Intelligent Computing (NuPIC)
* Copyright (C) 2013, Numenta, Inc. Unless you have an agreement
* Copyright (C) 2013-2017, Numenta, Inc. Unless you have an agreement
* with Numenta, Inc., for a separate license for this software code, the
* following terms and conditions apply:
*
Expand Down Expand Up @@ -119,6 +119,16 @@ namespace nupic
const std::string& destInputName="",
const size_t propagationDelay=0);

/**
* De-serialization use case. Creates a "blank" link. The caller must follow
* up with Link::read and Link::connectToNetwork
*
* @param proto
* LinkProto::Reader
*/
Link();


/**
* Initialization Phase 2: connecting inputs/outputs to
* the Network.
Expand Down Expand Up @@ -458,6 +468,10 @@ namespace nupic
const std::string& destInputName,
const size_t propagationDelay);

void initPropagationDelayBuffer_(size_t propagationDelay,
NTA_BasicType dataElementType,
size_t dataElementCount);

// TODO: The strings with src/dest names are redundant with
// the src_ and dest_ objects. For unit testing links,
// and for deserializing networks, we need to be able to create
Expand Down
Loading

0 comments on commit eb6a966

Please sign in to comment.