forked from numenta/nupic.core-legacy
-
Notifications
You must be signed in to change notification settings - Fork 83
Expand file tree
/
Copy pathNetwork.hpp
More file actions
477 lines (414 loc) · 12.7 KB
/
Copy pathNetwork.hpp
File metadata and controls
477 lines (414 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
/* ---------------------------------------------------------------------
* HTM Community Edition of NuPIC
* Copyright (C) 2013-2017, Numenta, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero Public License for more details.
*
* You should have received a copy of the GNU Affero Public License
* along with this program. If not, see http://www.gnu.org/licenses.
* --------------------------------------------------------------------- */
/** @file
* Interface for the Network class
*/
#ifndef NTA_NETWORK_HPP
#define NTA_NETWORK_HPP
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <htm/engine/Region.hpp>
#include <htm/engine/Link.hpp>
#include <htm/ntypes/Collection.hpp>
#include <htm/types/Serializable.hpp>
#include <htm/types/Types.hpp>
#include <htm/utils/Log.hpp>
namespace htm {
class Region;
class Dimensions;
class RegisteredRegionImpl;
class Link;
/**
* Represents an HTM network. A network is a collection of regions.
*
* @nosubgrouping
*/
class Network : public Serializable
{
public:
/**
* @name Construction and destruction
* @{
*/
/**
*
* Create an new Network
*
*/
Network();
Network(const std::string& filename);
/**
* Cannot copy or assign a Network object. But can be moved.
*/
Network(Network &&) noexcept; // move is allowed
Network(const Network&) = delete;
void operator=(const Network&) = delete;
/**
* Destructor.
*
*/
~Network();
/**
* Initialize all elements of a network so that it can run.
*
* @note This can be called after the Network structure has been set and
* before Network.run(). However, if you don't call it, Network.run() will
* call it for you. Also sets up various memory buffers etc. once the Network
* structure has been finalized.
*/
void initialize();
/**
* @}
*
* @name Internal Serialization methods
* @{
*/
/**
* saveToFile(path) Open a file and stream to it. (Binary)
* save(ostream f [, fmt]) Stream to your stream.
* f << net; Output human readable text.
*
* loadFromFile(path)
* load(istream f [, fmt])
*
* @path The filename into which to save/load the streamed serialization.
* @f The stream with which to save/load the serialization.
* @fmt Format: One of following from enum SerializableFormat
* BINARY - A binary format which is the fastest but not portable between platforms (default).
* PORTABLE - Another Binary format, not quite as fast but is portable between platforms.
* JSON - Human readable JSON text format. Slow.
* XML - Human readable XML text format. Even slower.
*
* See Serializable base class for more details.
*/
CerealAdapter; // see Serializable.hpp
// FOR Cereal Serialization
template<class Archive>
void save_ar(Archive& ar) const {
const std::vector<std::shared_ptr<Link>> links = getLinks();
std::string phases = phasesToString();
std::string name = "Network";
ar(cereal::make_nvp("name", name));
ar(cereal::make_nvp("iteration", iteration_));
ar(cereal::make_nvp("Regions", regions_));
ar(cereal::make_nvp("links", links));
ar(cereal::make_nvp("phases", phases));
}
// FOR Cereal Deserialization
template<class Archive>
void load_ar(Archive& ar) {
std::vector<std::shared_ptr<Link>> links;
std::string name, phases;
ar(cereal::make_nvp("name", name)); // ignore value
ar(cereal::make_nvp("iteration", iteration_));
ar(cereal::make_nvp("Regions", regions_));
ar(cereal::make_nvp("links", links));
ar(cereal::make_nvp("phases", phases));
post_load(links);
phasesFromString(phases);
}
/**
* @}
*
* @name Region and Link operations
*
* @{
*/
/**
* Create a new region in a network.
*
* @param name
* Name of the region, Must be unique in the network
* @param nodeType
* Type of node in the region, e.g. "FDRNode"
* @param nodeParams
* A JSON-encoded string specifying writable params
*
* @returns A pointer to the newly created Region
*/
std::shared_ptr<Region> addRegion(const std::string &name,
const std::string &nodeType,
const std::string &nodeParams);
/**
* Add a region in a network from deserialized region
*
* @param Region shared_ptr
*
* @returns A pointer to the newly created Region
*/
std::shared_ptr<Region> addRegion(std::shared_ptr<Region>& region);
/**
* Removes an existing region from the network.
*
* @param name
* Name of the Region
*/
void removeRegion(const std::string &name);
/**
* Create a link and add it to the network.
*
* @param srcName
* Name of the source region
* @param destName
* Name of the destination region
* @param linkType
* Type of the link
* @param linkParams
* Parameters of the link
* @param srcOutput
* Name of the source output
* @param destInput
* Name of the destination 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
*/
std::shared_ptr<Link> link(const std::string &srcName, const std::string &destName,
const std::string &linkType="", const std::string &linkParams="",
const std::string &srcOutput = "",
const std::string &destInput = "",
const size_t propagationDelay = 0);
/**
* Removes a link.
*
* @param srcName
* Name of the source region
* @param destName
* Name of the destination region
* @param srcOutputName
* Name of the source output
* @param destInputName
* Name of the destination input
*/
void removeLink(const std::string &srcName, const std::string &destName,
const std::string &srcOutputName = "",
const std::string &destInputName = "");
/**
* @}
*
* @name Access to components
*
* @{
*/
/**
* Get all regions.
*
* @returns A Collection of Region objects in the network
* Note: this is a copy of the region list.
*/
const Collection<std::shared_ptr<Region> > getRegions() const;
std::shared_ptr<Region> getRegion(const std::string& name) const;
/**
* Get all links between regions
*
* @returns A Collection of Link objects in the network
*/
std::vector<std::shared_ptr<Link>> getLinks() const;
/**
* Set phases for a region.
*
* @param name
* Name of the region
* @param phases
* A tuple of phases (must be positive integers)
*/
void setPhases(const std::string &name, std::set<UInt32> &phases);
/**
* Get phases for a region.
*
* @param name
* Name of the region
*
* @returns Set of phases for the region
*/
std::set<UInt32> getPhases(const std::string &name) const;
/**
* Get minimum phase for regions in this network. If no regions, then min = 0.
*
* @returns Minimum phase
*/
UInt32 getMinPhase() const;
/**
* Get maximum phase for regions in this network. If no regions, then max = 0.
*
* @returns Maximum phase
*/
UInt32 getMaxPhase() const;
/**
* Set the minimum enabled phase for this network.
*
* @param minPhase Minimum enabled phase
*/
void setMinEnabledPhase(UInt32 minPhase);
/**
* Set the maximum enabled phase for this network.
*
* @param minPhase Maximum enabled phase
*/
void setMaxEnabledPhase(UInt32 minPhase);
/**
* Get the minimum enabled phase for this network.
*
* @returns Minimum enabled phase for this network
*/
UInt32 getMinEnabledPhase() const;
/**
* Get the maximum enabled phase for this network.
*
* @returns Maximum enabled phase for this network
*/
UInt32 getMaxEnabledPhase() const;
/**
* @}
*
* @name Running
*
* @{
*/
/**
* Run the network for the given number of iterations of compute for each
* Region in the correct order.
*
* For each iteration, Region.compute() is called.
*
* @param n Number of iterations
*/
void run(int n);
/**
* The type of run callback function.
*
* You can attach a callback function to a network, and the callback function
* is called after every iteration of run().
*
* To attach a callback, just get a reference to the callback
* collection with getCallbacks() , and add a callback.
*/
typedef void (*runCallbackFunction)(Network *, UInt64 iteration, void *);
/**
* Type definition for a callback item, combines a @c runCallbackFunction and
* a `void*` pointer to the associated data.
*/
typedef std::pair<runCallbackFunction, void *> callbackItem;
/**
* Get reference to callback Collection.
*
* @returns Reference to callback Collection
*/
Collection<callbackItem> &getCallbacks();
/**
* @}
*
* @name Profiling
*
* @{
*/
/**
* Start profiling for all regions of this network.
*/
void enableProfiling();
/**
* Stop profiling for all regions of this network.
*/
void disableProfiling();
/**
* Reset profiling timers for all regions of this network.
*/
void resetProfiling();
/**
* Set one of the debug levels: LogLevel_None = 0, LogLevel_Minimal, LogLevel_Normal, LogLevel_Verbose
*/
static LogLevel setLogLevel(LogLevel level) {
LogLevel prev = NTA_LOG_LEVEL;
NTA_LOG_LEVEL = level;
return prev;
}
/**
* @}
*/
/*
* Adds a region implementation to the RegionImplFactory's list of packages
*
* NOTE: Built-in C++ regions are automatically registered by the factory
* so this function does not need to be called.
*
* NOTE: How does C++ register a custom C++ implemented region?
* Allocate a templated wrapper RegisteredRegionImplCpp class
* and pass it to this function with the name of the region type.
* Network::registerRegion("MyRegion", new RegisteredRegionImplCpp<MyRegion>());
*
* NOTE: How does Python register a .py implemented region?
* Python code should call Network.registerPyRegion(module, className).
* The python bindings will actually call the static function
* htm::RegisteredRegionImplPy::registerPyRegion(module, className);
* which will register the C++ class PyBindRegion as the stand-in for the
* python implementation.
*/
static void registerRegion(const std::string name, RegisteredRegionImpl *wrapper);
/*
* Removes a region implementation from the RegionImplFactory's list of packages
*/
static void unregisterRegion(const std::string name);
/*
* Removes all region registrations in RegionImplFactory.
* Used in unit tests to setup for next test.
*/
static void cleanup();
bool operator==(const Network &other) const;
inline bool operator!=(const Network &other) const {
return !operator==(other);
}
friend std::ostream &operator<<(std::ostream &, const Network &);
private:
// Both constructors use this common initialization method
void commonInit();
// perform actions after serialization load
void post_load();
void post_load(std::vector<std::shared_ptr<Link>>& links);
// internal method using region pointer instead of name
void setPhases_(Region *r, std::set<UInt32> &phases);
// default phase assignment for a new region
void setDefaultPhase_(Region *region);
// whenever we modify a network or change phase
// information, we set enabled phases to min/max for
// the network
void resetEnabledPhases_();
std::string phasesToString() const;
void phasesFromString(const std::string& phaseString);
bool initialized_;
/**
* The list of regions registered with the Network.
* Internally this is a map so it is easy to serialize
* but externally this is a Collection object so it
* retains API compatability.
*/
std::map<std::string, std::shared_ptr<Region>> regions_;
UInt32 minEnabledPhase_;
UInt32 maxEnabledPhase_;
// This is main data structure used to choreograph
// network computation
std::vector<std::set<Region *> > phaseInfo_;
// we invoke these callbacks at every iteration
Collection<callbackItem> callbacks_;
// number of elapsed iterations
UInt64 iteration_;
};
} // namespace htm
#endif // NTA_NETWORK_HPP