Skip to content
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

Memory footprint #534

Merged
merged 9 commits into from
Jul 6, 2019
14 changes: 7 additions & 7 deletions src/examples/hotgym/HelloSPTP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Real64 BenchmarkHotgym::run(UInt EPOCHS, bool useSPlocal, bool useSPglobal, bool
SpatialPooler spLocal(enc.dimensions, vector<UInt>{COLS}); // Spatial pooler with local inh
spGlobal.setGlobalInhibition(true);
spLocal.setGlobalInhibition(false);
Random rnd(1); //uses fixed seed for deterministic output checks
Random rnd(42); //uses fixed seed for deterministic output checks
Copy link

Choose a reason for hiding this comment

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

Ah, back to 42 ... "the meaning of life" 👍


TemporalMemory tm(vector<UInt>{COLS}, CELLS);

Expand Down Expand Up @@ -166,29 +166,29 @@ Real64 BenchmarkHotgym::run(UInt EPOCHS, bool useSPlocal, bool useSPglobal, bool
// check deterministic SP, TM output
SDR goldEnc({DIM_INPUT});
const SDR_sparse_t deterministicEnc{
0, 4, 13, 21, 24, 30, 32, 37, 40, 46, 47, 48, 50, 51, 64, 68, 79, 81, 89, 97, 99, 114, 120, 135, 136, 140, 141, 143, 144, 147, 151, 155, 161, 162, 164, 165, 169, 172, 174, 179, 181, 192, 201, 204, 205, 210, 213, 226, 237, 242, 247, 249, 254, 255, 262, 268, 271, 282, 283, 295, 302, 306, 307, 317, 330, 349, 353, 366, 368, 380, 393, 399, 404, 409, 410, 420, 422, 441,446, 447, 456, 458, 464, 468, 476, 497, 499, 512, 521, 528, 531, 534, 538, 539, 541, 545, 550, 557, 562, 565, 575, 581, 589, 592, 599, 613, 617, 622, 647, 652, 686, 687, 691, 699, 704, 710, 713, 716, 722, 729, 736, 740, 747, 749, 753, 754, 758, 766, 778, 790, 791, 797, 800, 808, 809, 812, 815, 826, 828, 830, 837, 838, 852, 853, 856, 863, 864, 873, 878, 882, 885, 893, 894, 895, 905, 906, 914, 915, 920, 924, 927, 937, 939, 944, 947, 951, 954, 956, 967, 968, 969, 973, 975, 976, 981, 991, 998
0, 4, 13, 21, 24, 30, 32, 37, 40, 46, 47, 48, 50, 51, 64, 68, 79, 81, 89, 97, 99, 114, 120, 135, 136, 140, 141, 143, 144, 147, 151, 155, 161, 162, 164, 165, 169, 172, 174, 179, 181, 192, 201, 204, 205, 210, 213, 226, 227, 237, 242, 247, 249, 254, 255, 262, 268, 271, 282, 283, 295, 302, 306, 307, 317, 330, 349, 353, 366, 380, 383, 393, 404, 409, 410, 420, 422, 441,446, 447, 456, 458, 464, 468, 476, 497, 499, 512, 521, 528, 531, 534, 538, 539, 541, 545, 550, 557, 562, 565, 575, 581, 589, 592, 599, 613, 617, 622, 647, 652, 686, 687, 691, 699, 704, 710, 713, 716, 722, 729, 736, 740, 747, 749, 753, 754, 758, 766, 778, 790, 791, 797, 800, 808, 809, 812, 815, 826, 828, 830, 837, 852, 853, 856, 863, 864, 873, 878, 882, 885, 893, 894, 895, 905, 906, 914, 915, 920, 924, 927, 937, 939, 944, 947, 951, 954, 956, 967, 968, 969, 973, 975, 976, 979, 981, 991, 998
Copy link
Member Author

Choose a reason for hiding this comment

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

encoder changed, because I had to change seed; otherwise TM gave no output in this configuration.
Proper fix queued.

};
goldEnc.setSparse(deterministicEnc);

SDR goldSP({COLS});
const SDR_sparse_t deterministicSP{
72, 75, 284, 303, 305, 317, 329, 525, 1095, 2027
72, 308, 337, 1512, 1518, 1956, 1965, 1975, 1994, 2008
};
goldSP.setSparse(deterministicSP);

SDR goldSPlocal({COLS});
const SDR_sparse_t deterministicSPlocal{
6, 12, 26, 57, 63, 72, 75, 76, 77, 80, 82, 103, 105, 124, 135, 154, 171, 174, 175, 185, 192, 193, 195, 198, 263, 284, 296, 302, 303, 305, 313, 317, 319, 320, 356, 363, 364, 401, 403, 404, 410, 413, 425, 426, 428, 449, 491, 496, 511, 515, 516, 518, 520, 525, 529, 536, 550, 556, 574, 583, 592, 597, 598, 603, 609, 622, 626, 636, 645, 652, 704, 706, 722, 726, 727, 728, 729, 747, 751, 766, 779, 808, 833, 837, 838, 840, 848, 850, 853, 860, 908, 912, 918, 919, 923, 927, 929, 930, 931, 932, 970, 989, 1006, 1038, 1066, 1082, 1085, 1087, 1092, 1094, 1095, 1113, 1115, 1125, 1128, 1174, 1179, 1180, 1182, 1185, 1205, 1206, 1232, 1236, 1238, 1239, 1240, 1245, 1271, 1292, 1295, 1300, 1303, 1307, 1311, 1319, 1320, 1322, 1382, 1401, 1412, 1415, 1421, 1426, 1431, 1434, 1438, 1470, 1474, 1492, 1501, 1511, 1521, 1524, 1525, 1530, 1532, 1537, 1540, 1600, 1617, 1620, 1622, 1632, 1638, 1641, 1667, 1672, 1680, 1684, 1686, 1690, 1699, 1702, 1742, 1744, 1745, 1746, 1765, 1770, 1774, 1801, 1807, 1808, 1816, 1830, 1834, 1849, 1861, 1867, 1871, 1882, 1902, 1907, 1943, 1945, 1955, 1956, 1966, 1968, 1969, 1971, 1986, 2018, 2025, 2027
12, 17, 36, 39, 62, 71, 72, 74, 75, 82, 83, 85, 93, 102, 131, 147, 171, 179, 186, 188, 189, 192, 194, 201, 260, 263, 277, 287, 298, 308, 319, 322, 323, 326, 334, 337, 340, 355, 365, 407, 422, 423, 425, 427, 429, 432, 434, 443, 445, 493, 494, 498, 502, 508, 513, 523, 534, 540, 542, 554, 559, 580, 585, 586, 610, 611, 612, 629, 631, 637, 644, 645, 646, 647, 691, 697, 698, 702, 703, 707, 709, 746, 749, 767, 806, 809, 810, 811, 825, 832, 833, 838, 839, 847, 889, 906, 920, 923, 928, 929, 931, 934, 935, 936, 952, 989, 1003, 1005, 1018, 1073, 1076, 1078, 1089, 1094, 1095, 1100, 1102, 1114, 1115, 1133, 1134, 1147, 1168, 1169, 1184, 1193, 1196, 1203, 1204, 1209, 1232, 1233, 1236, 1244, 1253, 1254, 1268, 1278, 1284, 1294, 1297, 1298, 1303, 1306, 1310, 1331, 1342, 1402, 1410, 1415, 1423, 1427, 1428, 1430, 1434, 1463, 1487, 1488, 1494, 1507, 1508, 1512, 1515, 1518, 1532, 1547, 1550, 1561, 1563, 1564, 1612, 1622, 1623, 1624, 1626, 1627, 1630, 1640, 1647, 1651, 1689, 1691, 1694, 1703, 1711, 1714, 1729, 1745, 1746, 1760, 1771, 1797, 1803, 1804, 1805, 1812, 1827, 1828, 1831, 1858, 1859, 1860, 1861, 1862, 1880, 1918, 1929, 1937, 1956, 1961, 1965, 1967, 1971, 1980, 1985, 1994, 2008, 2011, 2013
};
goldSPlocal.setSparse(deterministicSPlocal);

SDR goldTM({COLS});
const SDR_sparse_t deterministicTM{
26, 75 //FIXME this is a really bad representation -> improve the params
1965 //FIXME this is a really bad representation -> improve the params
};
goldTM.setSparse(deterministicTM);

const float goldAn = 0.8f;
const float goldAn = 1.0f;

if(EPOCHS == 5000) { //these hand-written values are only valid for EPOCHS = 5000 (default), but not for debug and custom runs.
NTA_CHECK(input == goldEnc) << "Deterministic output of Encoder failed!\n" << input << "should be:\n" << goldEnc;
Expand All @@ -197,7 +197,7 @@ Real64 BenchmarkHotgym::run(UInt EPOCHS, bool useSPlocal, bool useSPglobal, bool
NTA_CHECK(outTM == goldTM) << "Deterministic output of TM failed!\n" << outTM << "should be:\n" << goldTM;
NTA_CHECK(static_cast<UInt>(an *10000.0f) == static_cast<UInt>(goldAn *10000.0f)) //compare to 4 decimal places
<< "Deterministic output of Anomaly failed! " << an << "should be: " << goldAn;
NTA_CHECK(avgAnom10.getCurrentAvg() <= 0.82f) << "Deterministic average anom score failed:" << avgAnom10.getCurrentAvg();
NTA_CHECK(avgAnom10.getCurrentAvg() <= 0.8f) << "Deterministic average anom score failed:" << avgAnom10.getCurrentAvg();
}

// check runtime speed
Expand Down
2 changes: 1 addition & 1 deletion src/htm/algorithms/Connections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ void Connections::destroySegment(Segment segment) {
const auto segmentOnCell =
std::lower_bound(cellData.segments.begin(), cellData.segments.end(),
segment, [&](Segment a, Segment b) {
return segmentOrdinals_[a] < segmentOrdinals_[b];
return segmentOrdinals_[a] < segmentOrdinals_[b]; //TODO will this be slow if ordinals moved to SegmentData?
Copy link
Member Author

Choose a reason for hiding this comment

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

? My idea is to get rid of the *Ordinals_ arrays in Conn, and keep that number in SegmentData

});

NTA_ASSERT(segmentOnCell != cellData.segments.end());
Expand Down
8 changes: 4 additions & 4 deletions src/htm/algorithms/Connections.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#ifndef NTA_CONNECTIONS_HPP
#define NTA_CONNECTIONS_HPP

#include <climits>
#include <map>
#include <set>
#include <utility>
Expand All @@ -36,9 +35,10 @@
namespace htm {

//TODO instead of typedefs, use templates for proper type-checking?
//TODO profile to use better (smaller?) types
using CellIdx = htm::ElemSparse; // CellIdx must match with ElemSparse, defined in Sdr.hpp
using SegmentIdx= UInt16; /** Index of segment in cell. */
using SynapseIdx= UInt16; /** Index of synapse in segment. */ //TODO profile to use better (smaller?) types
using SegmentIdx= unsigned char; /** Index of segment in cell. */
using SynapseIdx= unsigned char; /** Index of synapse in segment. */
Copy link
Member Author

Choose a reason for hiding this comment

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

the new type, only 1B!. If should overflow we have check to inform

Copy link
Member Author

Choose a reason for hiding this comment

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

thanks for calling me out on this! Reverted back to UInt16, as it's more usable for many potential synapses. Also the UInt16 actually runs faster.

using Segment = UInt32; /** Index of segment's data. */
using Synapse = UInt32; /** Index of synapse's data. */
using Permanence= Real32; //TODO experiment with half aka float16
Expand Down Expand Up @@ -631,7 +631,7 @@ class Connections : public Serializable
Permanence connectedThreshold_; //TODO make const

// Extra bookkeeping for faster computing of segment activity.
std::map<CellIdx, std::vector<Synapse>> potentialSynapsesForPresynapticCell_;
std::map<CellIdx, std::vector<Synapse>> potentialSynapsesForPresynapticCell_; //TODO use unordered_map
std::map<CellIdx, std::vector<Synapse>> connectedSynapsesForPresynapticCell_;
std::map<CellIdx, std::vector<Segment>> potentialSegmentsForPresynapticCell_;
std::map<CellIdx, std::vector<Segment>> connectedSegmentsForPresynapticCell_;
Expand Down
23 changes: 7 additions & 16 deletions src/htm/algorithms/SpatialPooler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ void SpatialPooler::getConnectedSynapses(UInt column,
void SpatialPooler::getConnectedCounts(UInt connectedCounts[]) const {
for(UInt seg = 0; seg < numColumns_; seg++) {
const auto &segment = connections_.dataForSegment( seg );
connectedCounts[ seg ] = segment.numConnected;
connectedCounts[ seg ] = segment.numConnected; //TODO numConnected only used here, rm from SegmentData and compute for each segment.synapses?
breznak marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down Expand Up @@ -398,7 +398,7 @@ void SpatialPooler::initialize(
NTA_CHECK(numColumns_ > 0);
NTA_CHECK(numInputs_ > 0);

// 1D input produces 1D output; 2D => 2D, etc.
// 1D input produces 1D output; 2D => 2D, etc. //TODO allow nD -> mD conversion
NTA_CHECK(inputDimensions_.size() == columnDimensions_.size());

NTA_CHECK((numActiveColumnsPerInhArea > 0 && localAreaDensity < 0) ||
Expand Down Expand Up @@ -429,12 +429,7 @@ void SpatialPooler::initialize(
iterationNum_ = 0u;
iterationLearnNum_ = 0u;

tieBreaker_.resize(numColumns_);
for (Size i = 0; i < numColumns_; i++) {
tieBreaker_[i] = (Real)(0.01 * rng_.getReal64());
}

overlapDutyCycles_.assign(numColumns_, 0);
overlapDutyCycles_.assign(numColumns_, 0); //TODO make all these sparse or rm to reduce footprint
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we can get rid of overlapDutyCycles_ altogether. IIRC it is a boosting method? We have better/stronger boosting methods. I don't think that this even ever kicks in? But that needs to be checked before removing it, an issue for a different PR

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it's used for something...bumpupWeakSegments or so.. I have waiting another PR that puts all of boosting code into 2 methods: one for boosting overlaps, other for weak columns (and shows the "weak columns" is not really useful, on the limited mnist, hotgym tests) But yes, another PR

activeDutyCycles_.assign(numColumns_, 0);
minOverlapDutyCycles_.assign(numColumns_, 0.0);
boostFactors_.assign(numColumns_, 1);
Expand Down Expand Up @@ -854,11 +849,6 @@ void SpatialPooler::inhibitColumnsGlobal_(const vector<Real> &overlaps,
NTA_ASSERT(!overlaps.empty());
NTA_ASSERT(density > 0.0f && density <= 1.0f);

// Add a tiebreaker to the overlaps so that the output is deterministic.
vector<Real> overlaps_(overlaps.begin(), overlaps.end());
for(UInt i = 0; i < numColumns_; i++)
overlaps_[i] += tieBreaker_[i];
Copy link
Member Author

Choose a reason for hiding this comment

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

removed tieBreakers.

  • saves memory
  • makes inhibition faster


activeColumns.clear();
const UInt numDesired = (UInt)(density * numColumns_);
NTA_CHECK(numDesired > 0) << "Not enough columns (" << numColumns_ << ") "
Expand All @@ -869,8 +859,10 @@ void SpatialPooler::inhibitColumnsGlobal_(const vector<Real> &overlaps,
for(UInt i = 0; i < numColumns_; i++)
activeColumns.push_back(i);
// Compare the column indexes by their overlap.
auto compare = [&overlaps_](const UInt &a, const UInt &b) -> bool
{return (overlaps_[a] == overlaps_[b]) ? a > b : overlaps_[a] > overlaps_[b];};
auto compare = [&overlaps](const UInt &a, const UInt &b) -> bool
{return (overlaps[a] == overlaps[b]) ? a > b : overlaps[a] > overlaps[b];}; //for determinism if overlaps match (tieBreaker does not solve that),
//otherwise we'd return just `return overlaps[a] > overlaps[b]`.

// Do a partial sort to divide the winners from the losers. This sort is
// faster than a regular sort because it stops after it partitions the
// elements about the Nth element, with all elements on their correct side of
Expand Down Expand Up @@ -1043,7 +1035,6 @@ bool SpatialPooler::operator==(const SpatialPooler& o) const{
if (overlapDutyCycles_ != o.overlapDutyCycles_) return false;
if (activeDutyCycles_ != o.activeDutyCycles_) return false;
if (minOverlapDutyCycles_ != o.minOverlapDutyCycles_) return false;
if (tieBreaker_ != o.tieBreaker_) return false;

// compare connections
if (connections_ != o.connections_) return false;
Expand Down
3 changes: 0 additions & 3 deletions src/htm/algorithms/SpatialPooler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,6 @@ class SpatialPooler : public Serializable
ar(CEREAL_NVP(overlapDutyCycles_));
ar(CEREAL_NVP(activeDutyCycles_));
ar(CEREAL_NVP(minOverlapDutyCycles_));
ar(CEREAL_NVP(tieBreaker_));
Copy link

Choose a reason for hiding this comment

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

Since tieBreaker is deterministic it does not need to be saved so this is correct. But are you sure it is regenerated after the restore? If it should be different then answers will eventually drift off of the correct set on subsequent iterations.

Copy link
Member Author

Choose a reason for hiding this comment

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

no, tie breakers are totally removed and not used, as they did not have 100% the effect we expected. And you've obsoleted them in the long-dragging Deterministic builds PR 👍 where you figured we need to add the a > b to the segment ordering algorithm.

This is because tie breakers sometimes work and break ties:
{1,1} + {0, 0.01} -> L < R

but sometimes they just break (we apply tie breaks flat out to all, for performance reasons)
{1, 0.99} + {0, 0.01} -> L ? R broken

TL;DR this PR removes tieBreakers altogether because those are not needed (we do deterministic sort)

Copy link
Member Author

Choose a reason for hiding this comment

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

see the removal #534 (comment)

Copy link

Choose a reason for hiding this comment

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

Oh, somehow I missed the fact that they were removed. I like that you did that.

ar(CEREAL_NVP(connections_));
ar(CEREAL_NVP(rng_));
}
Expand Down Expand Up @@ -322,7 +321,6 @@ class SpatialPooler : public Serializable
ar(CEREAL_NVP(overlapDutyCycles_));
ar(CEREAL_NVP(activeDutyCycles_));
ar(CEREAL_NVP(minOverlapDutyCycles_));
ar(CEREAL_NVP(tieBreaker_));
ar(CEREAL_NVP(connections_));
ar(CEREAL_NVP(rng_));

Expand Down Expand Up @@ -1233,7 +1231,6 @@ class SpatialPooler : public Serializable
vector<SynapseIdx> overlaps_;
vector<Real> overlapsPct_;
vector<Real> boostedOverlaps_;
vector<Real> tieBreaker_;


UInt version_;
Expand Down
4 changes: 4 additions & 0 deletions src/htm/algorithms/TemporalMemory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,13 @@ class TemporalMemory : public Serializable
*
* @param maxSegmentsPerCell
* The maximum number of segments per cell.
* The value you can choose here is limited by the type SegmentIdx
* in Connections.hpp, change it if you need larger values.
*
* @param maxSynapsesPerSegment
* The maximum number of synapses per segment.
* The value you can choose here is limited by the type SynapseIdx
* in Connections.hpp, change it there if you needed to use large values.
*
* @param checkInputs
* Whether to check that the activeColumns are sorted without
Expand Down
8 changes: 5 additions & 3 deletions src/test/unit/algorithms/SpatialPoolerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1816,7 +1816,7 @@ TEST(SpatialPoolerTest, ZeroOverlap_NoStimulusThreshold_LocalInhibition) {
SDR activeColumns( {nColumns} );
sp.compute(input, true, activeColumns);

EXPECT_EQ(activeColumns.getSum(), 4u);
EXPECT_EQ(activeColumns.getSum(), 3u);
}

TEST(SpatialPoolerTest, ZeroOverlap_StimulusThreshold_LocalInhibition) {
Expand Down Expand Up @@ -2079,14 +2079,16 @@ TEST(SpatialPoolerTest, testConstructorVsInitialize) {
TEST(SpatialPoolerTest, ExactOutput) {
// Silver is an SDR that is loaded by direct initalization from a vector.
SDR silver_sdr({ 200 });
SDR_sparse_t data = {23, 71, 113, 118, 129, 172, 178, 182, 185, 190};
SDR_sparse_t data = {
4, 64, 74, 78, 85, 113, 125, 126, 127, 153
};
silver_sdr.setSparse(data);


// Gold tests initalizing an SDR from a manually created string in JSON format.
// hint: you can generate this string using
// silver_sdr.save(std::cout, JSON);
string gold = "{\"dimensions\": [200],\"sparse\": [23,71,113,118,129,172,178,182,185,190]}";
string gold = "{\"dimensions\": [200],\"sparse\": [4, 64, 74, 78, 85, 113, 125, 126, 127, 153]}";
std::stringstream gold_stream( gold );
SDR gold_sdr;
gold_sdr.load( gold_stream, JSON );
Expand Down
6 changes: 3 additions & 3 deletions src/test/unit/engine/CppRegionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,11 @@ TEST(CppRegionTest, testCppLinkingSDR) {

const Array r2OutputArray = region2->getOutputData("bottomUpOut");
EXPECT_EQ(r2OutputArray.getType(), NTA_BasicType_SDR);
EXPECT_TRUE(r2OutputArray.getSDR().dimensions == r2dims)
EXPECT_EQ(r2OutputArray.getSDR().dimensions, r2dims)
<< "Expected dimensions on the output to match dimensions on the buffer.";
VERBOSE << r2OutputArray << "\n";
std::vector<Byte> expected_output = {0, 1, 0, 1, 0, 1};
EXPECT_TRUE(r2OutputArray == expected_output);
std::vector<Byte> expected_output = {1, 0, 1, 0, 1, 0};
EXPECT_TRUE(r2OutputArray == expected_output) << "expected " << r2OutputArray;

}

Expand Down
32 changes: 19 additions & 13 deletions src/test/unit/regions/TMRegionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,10 @@ TEST(TMRegionTest, testLinking) {
EXPECT_TRUE(r3InputArray.getType() == NTA_BasicType_SDR);
VERBOSE << " " << r3InputArray << "\n";
std::vector<Byte> expected3in = VectorHelpers::sparseToBinary<Byte>(
{ 1, 2, 3, 5, 6, 8, 11, 13, 17, 19 }, (UInt32)r3InputArray.getCount());
EXPECT_TRUE(r3InputArray == expected3in);
{
0, 2, 3, 4, 6, 7, 10, 11, 14, 17
}, (UInt32)r3InputArray.getCount());
EXPECT_TRUE(r3InputArray == expected3in) << r3InputArray;

VERBOSE << " TMRegion output "
<< region3->getOutputDimensions("bottomUpOut") << "\n";
Expand All @@ -288,11 +290,14 @@ TEST(TMRegionTest, testLinking) {
EXPECT_TRUE(r3OutputArray.getType() == NTA_BasicType_SDR);
VERBOSE << " " << r3OutputArray << "\n";
std::vector<Byte> expected3out = VectorHelpers::sparseToBinary<Byte>(
{ 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 14u, 15u, 16u, 17u, 18u, 19u,
25u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 40u, 41u, 42u, 43u,
44u, 55u, 56u, 57u, 58u, 59u, 65u, 66u, 67u, 68u, 69u, 85u, 86u, 87u,
88u, 89u, 95u, 96u, 97u, 98u, 99u }, (UInt32)r3OutputArray.getCount());
EXPECT_TRUE(r3OutputArray == expected3out);
{
0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 70,
71, 72, 73, 74, 85, 86, 87, 88, 890, 1, 2, 3, 4, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 50, 51, 52, 53,
54, 55, 56, 57, 58, 59, 70, 71, 72, 73, 74, 85, 86, 87, 88, 89
}, (UInt32)r3OutputArray.getCount());
Copy link

Choose a reason for hiding this comment

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

Good, you corrected the paste error :)

EXPECT_TRUE(r3OutputArray == expected3out) << r3OutputArray;
EXPECT_EQ(r3OutputArray.getSDR().getSparse().size(), 50u);

// execute TMRegion several more times and check that it has output.
Expand All @@ -308,19 +313,20 @@ TEST(TMRegionTest, testLinking) {
<< numberOfCols << " * " << cellsPerColumn;
VERBOSE << " " << r3OutputArray << ")\n";
std::vector<Byte> expected3outa = VectorHelpers::sparseToBinary<Byte>(
{20u, 21u, 22u, 23u, 24u, 25u, 26u, 27u, 28u, 29u, 35u, 36u, 37u, 38u,
39u, 45u, 46u, 47u, 48u, 49u, 50u, 51u, 52u, 53u, 54u, 60u, 61u, 62u,
63u, 64u, 70u, 71u, 72u, 73u, 74u, 80u, 81u, 82u, 83u, 84u, 90u, 91u,
92u, 93u, 94u, 95u, 96u, 97u, 98u, 99u}, (UInt32)r3OutputArray.getCount());
EXPECT_TRUE(r3OutputArray == expected3outa);
{
10, 11, 12, 13, 14, 30, 31, 32, 33, 34, 45, 46, 47, 48, 49, 55, 56, 57, 58,
59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90, 91, 92,93, 94, 95, 96, 97, 98, 99
}, (UInt32)r3OutputArray.getCount());
EXPECT_TRUE(r3OutputArray == expected3outa) << r3OutputArray;


VERBOSE << " Input to VectorFileEffector "
<< region4->getInputDimensions("dataIn") << "\n";
Array r4InputArray = region4->getInputData("dataIn");
EXPECT_TRUE(r4InputArray.getType() == NTA_BasicType_Real32);
VERBOSE << " " << r4InputArray << "\n";
EXPECT_TRUE(r4InputArray == expected3outa);
EXPECT_TRUE(r4InputArray == expected3outa) << r4InputArray;

// cleanup
region3->executeCommand({"closeFile"});
Expand Down