-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcircuit_t.cpp
272 lines (237 loc) · 9.35 KB
/
circuit_t.cpp
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
//------------------------------------------------------------------------------
#include <stdio.h>
#include "circuit_t.h"
//==============================================================================
Circuit_t::Circuit_t()
{
stop = EvTime_t(0);
sMon = 0;
}
//------------------------------------------------------------------------------
Circuit_t::~Circuit_t()
{
// Kill all the devices
WALKPDIGRAPHNODES(string,Device_t *,string,Device_t *,string,C_pin *,G,i)
delete G.NodeData(i);
}
//------------------------------------------------------------------------------
void Circuit_t::ChkInteg()
// (Try) to make sure the circuit makes sense:
{
// 1. Device referenced but not defined?
WALKPDIGRAPHNODES(string,Device_t *,string,Device_t *,string,C_pin *,G,i) {
Device_t * pD = G.NodeData(i);
if (pD->sParam.empty()) throw(E(__FILE__,__LINE__));
}
printf("Neurons : %u\n",G.SizeNodes());
printf("Synapses: %u\n",G.SizeArcs());
}
//------------------------------------------------------------------------------
void Circuit_t::Dump()
{
printf("----------------------------------------\n"
"Circuit %s dump:\n",name.c_str());
G.Dump();
printf("-------------------------\nInitial parameter sets:");
for(map<string,vector<string> >::iterator i=params.begin();i!=params.end();i++){
printf("\nSet %s\n",(*i).first.c_str());
WALKVECTOR(string,(*i).second,j) {
printf(" %s\n",(*j).c_str());
}
}
printf("-------------------------\n");
WALKPDIGRAPHNODES(string,Device_t *,string,Device_t *,string,C_pin *,G,i)
G.NodeData(i)->Dump();
printf("Recovered stop time %e\n",stop);
printf("----------------------------------------\n\n");
}
//------------------------------------------------------------------------------
void Circuit_t::OutAns()
// Walk the results store in each device a(as necessary) and dump it to a file
// in a scratch directory
{
string cmd = OS_RMDIR+name; // Kill the scratch directory quietly:
printf("--> %s\n",cmd.c_str()); // Tell the user
int code = system(cmd.c_str()); // Actually do it
printf("--> System call %s\n",code==0 ? "OK" : "failed");
cmd = OS_MKDIR + name; // Make a new subdirectory
long t = Timer();
while(Timer(t)<5); // (Wait while the disk heads move...)
printf("--> %s\n",cmd.c_str()); // Tell the user
code = system(cmd.c_str()); // And do it
printf("--> System call %s\n",code==0 ? "OK" : "failed");
WALKPDIGRAPHNODES(string,Device_t *,string,Device_t *,string,C_pin *,G,i) {
Device_t * pD = G.NodeData(i);
pD->OutAns(name);
}
}
//------------------------------------------------------------------------------
void Circuit_t::Parse(string ifile)
{
FileName FN(ifile);
name = FN.FNBase();
printf("Circuit_t::Parsing %s\n",ifile.c_str());
Device_t::par = this; // Device->circuit backpointer
G.SetND_CB(Device_t::ND_cb);
G.SetNK_CB(Device_t::NK_cb);
G.SetAD_CB(Device_t::ND_cb);
G.SetAK_CB(Device_t::NK_cb);
Lx.SetFile((char *)ifile.c_str()); // Point the lexer at it
// And away we go...
for(;;) {
Lex::tokdat Td;
Lx.GetTokNC(Td); // Get the next token...
switch (Td.t) {
case Lex::Sy_EOR : continue;
case Lex::Sy_EQ : ParseStop(); break;
case Lex::Sy_dqut :
case Lex::Sy_STR : ParseNeuron(Td); break;
case Lex::Sy_LT : ParseSink(); break;
case Lex::Sy_GT : ParseSource(); break;
case Lex::Sy_mult : ParseClock(); break;
case Lex::Sy_plng : ParseParams(); break;
case Lex::Sy_EOF : break;
default : Td.Dump();
throw(E(__FILE__,__LINE__));
}
if (Td.t==Lex::Sy_EOF) break;
}
Lx.SetFile(); // Close the circuit file
ChkInteg(); // Check circuit integrity
// Load parameters from parameter library
WALKPDIGRAPHNODES(string,Device_t *,string,Device_t *,string,C_pin *,G,i)
G.NodeData(i)->Elaborate();
}
//------------------------------------------------------------------------------
void Circuit_t::ParseClock()
// Parse the rest of the clock record
{
Lex::tokdat Td;
Lx.GetTokNC(Td); // Next token
if (!Lex::IsStr(Td.t)) throw(E(__FILE__,__LINE__));
string name = Td.s; // Device name
//printf("Circuit_t::ParseClock %s\n",name.c_str());
Lx.GetTokNC(Td);
if (!Lex::IsStr(Td.t)) throw(E(__FILE__,__LINE__));
string par = Td.s; // Parameters
// Chuck away all else
while (Td.t!=Lex::Sy_EOR) Lx.GetTokNC(Td);
// Already there?
if (G.FindNode(name)!=0) throw(E(__FILE__,__LINE__));
// Nope - create it
G.InsertNode(name,new C_clock(name,par));
}
//------------------------------------------------------------------------------
void Circuit_t::ParseNeuron(Lex::tokdat Td)
// Parse the rest of the neuron record
{
string src = Td.s; // Source neuron name
//printf("Circuit_t::ParseNeuron %s\n",src.c_str());
Lx.GetTokNC(Td); // Next token
if (!Lex::IsStr(Td.t)) throw(E(__FILE__,__LINE__));
string par = Td.s; // Parameters
Device_t ** pSrc = G.FindNode(src); // Already there?
// Nope - create it
if (pSrc==0) G.InsertNode(src,new C_neuron(src,par));
else { // Already there as a base class
delete *pSrc; // Sling it out
(*pSrc) = new C_neuron(src,par); // Upcast
}
while (Td.t!=Lex::Sy_EOR) {
Lx.GetTokNC(Td);
if (Lex::IsStr(Td.t)) { // It's a driven device
string tgt = Td.s; // Target device exist?
Device_t ** pD = G.FindNode(tgt);
// No, create it
if (pD==0) G.InsertNode(tgt,new Device_t(tgt));
string sarc = UniS("axon_");
string p_fr = UniS("p_fr");
string p_to = UniS("p_to");
G.InsertArc(sarc,src,tgt);
}
}
}
//------------------------------------------------------------------------------
void Circuit_t::ParseParams()
// And the rest of the parameter record
{
Lex::tokdat Td;
Lx.GetTokNC(Td); // Next token
if (!Lex::IsStr(Td.t)) throw(E(__FILE__,__LINE__));
string name = Td.s; // Model name
//printf("Circuit_t::ParseParams %s\n",name.c_str());
string par; // Parameter name
string sign;
while (Td.t!=Lex::Sy_EOR) { // Loop through the rest of the record
Lx.GetTokNC(Td);
if (Td.t==Lex::Sy_sub) sign = "-"; // Handle negative strings
if (Lx.IsStr(Td.t)) {
par = sign + Td.s;
sign.clear();
params[name].push_back(par);
}
}
}
//------------------------------------------------------------------------------
void Circuit_t::ParseSink()
// Just the same - almost - as a neuron
{
Lex::tokdat Td;
Lx.GetTokNC(Td); // Pull in sink name
string sink = Td.s; // Sink name
//printf("Circuit_t::ParseSink %s\n",sink.c_str());
Lx.GetTokNC(Td); // Pull in parameter pack
if (!Lex::IsStr(Td.t)) throw(E(__FILE__,__LINE__));
string par = Td.s; // Parameters
Device_t ** pSink = G.FindNode(sink); // Already there?
// Nope - create it
if (pSink==0) G.InsertNode(sink,new C_sink(sink,par));
else { // Already there as a base class
delete *pSink; // Sling it out
(*pSink) = new C_sink(sink,par); // Upcast
}
// Nothing else to do....
while (Td.t!=Lex::Sy_EOR) Lx.GetTokNC(Td);
}
//------------------------------------------------------------------------------
void Circuit_t::ParseSource()
// Just the same - almost - as a neuron
{
Lex::tokdat Td;
Lx.GetTokNC(Td); // Pull in source name
string src = Td.s; // Source name
//printf("Circuit_t::ParseSource %s\n",src.c_str());
Lx.GetTokNC(Td); // Pull in parameter pack
if (!Lex::IsStr(Td.t)) throw(E(__FILE__,__LINE__));
string par = Td.s; // Parameters
Device_t ** pSrc = G.FindNode(src); // Already there?
// Nope - create it
if (pSrc==0) G.InsertNode(src,new C_source(src,par));
else (*pSrc)->SetParam(par);
while (Td.t!=Lex::Sy_EOR) {
Lx.GetTokNC(Td);
if (Lex::IsStr(Td.t)) { // It's a driven device
string tgt = Td.s; // Target device exist?
Device_t ** pD = G.FindNode(tgt);
// No, create it
if (pD==0) G.InsertNode(tgt,new Device_t(tgt));
string sarc = UniS("axon_");
string p_fr = UniS("p_fr");
string p_to = UniS("p_to");
G.InsertArc(sarc,src,tgt);
}
}
}
//------------------------------------------------------------------------------
void Circuit_t::ParseStop()
// Uncool, but then the whole input thing is pretty crap.
// Found a stop command (==)
{
//printf("Circuit_t::ParseStop\n");
Lex::tokdat Td;
Lx.GetTokNC(Td); // Next token is the stop time
if (!Lex::IsStr(Td.t)) throw(E(__FILE__,__LINE__));
stop = str2dble(Td.s); // Stop time
while (Td.t!=Lex::Sy_EOR) Lx.GetTokNC(Td);
}
//==============================================================================