NEURON
parallel.cpp
Go to the documentation of this file.
1
#include <../../nrnconf.h>
2
/* /local/src/master/nrn/src/oc/parallel.cpp,v 1.5 1997/03/13 14:18:17 hines Exp */
3
#if MAC
4
#define OCSMALL 1
5
#define WIN32 1
6
#endif
7
8
#if !OCSMALL
9
#include <stdlib.h>
10
#if HAVE_UNISTD_H
11
#include <unistd.h>
12
#endif
13
#if defined(__APPLE__)
14
#include <crt_externs.h>
15
#endif
16
#include "
hoc.h
"
17
#include "parse.hpp"
/* OBJECTVAR */
18
19
static
int
parallel_seen
;
20
21
static
double
*
pval
;
/* pointer to loop counter value */
22
static
double
end_val
;
/* value to assign loop counter upon completion of loop */
23
24
#define NUM_ARGS 256
25
static
char
*
parallel_argv
;
26
static
char
*
parallel_envp
;
27
static
int
sargv
=0,
senvp
=0;
28
#endif
/*!OCSMALL*/
29
30
int
parallel_sub
=0;
31
int
parallel_val
;
/* for use with parallel neuron (see hoc.cpp) */
32
33
/*
34
stack has final, initial, symbol
35
and should contain these on exit in order to execute the following shortfor
36
*/
37
38
39
40
void
hoc_parallel_begin
(
void
) {
41
#if !OCSMALL
42
Symbol
*sym;
43
double
first
, last;
44
char
*method;
45
int
i
,
j
;
46
47
48
last =
xpop
();
49
first =
xpop
();
50
sym =
spop
();
51
pushs
(sym);
52
53
method =
getenv
(
"NEURON_PARALLEL_METHOD"
);
54
if
(!method) {
55
pushx
(first);
56
pushx
(last);
57
return
;
58
}
59
if
(
parallel_seen
++) {
60
hoc_warning
(
"Only one parallel loop per batch run allowed."
,
61
"This loop is being executed serially"
);
62
pushx
(first);
63
pushx
(last);
64
return
;
65
}
66
67
if
(!
parallel_sub
) {
/* if 0 then master */
68
/* the master instance executes the following portion of the loop */
69
for
(i = ((
int
) first) + 1; i <= (
int
) last; i++) {
70
char
buf
[10], *pnt =
parallel_argv
;
71
72
/* increment pnt to "00000" */
73
for
(j = 0; j < 2; j++) {
74
/*EMPTY*/
75
while
(*pnt++);
76
}
77
78
/* replace "00000" with actual value */
79
sprintf
(buf,
"%5d"
, i);
80
strcpy(pnt, buf);
81
82
/* farm-out all but the first instance of the loop */
83
#if LINDA
84
/* place arguments for eval() into tuple space, Linda
85
doesn't seem to want to let the fxn in an eval take
86
arrays as args */
87
__linda_out(
"parallel sargs"
,
sargv
,
senvp
);
88
__linda_out(
"parallel args"
,
parallel_argv
:
sargv
,
parallel_envp
:
senvp
);
89
__linda_eval(
"parallel run"
,
parallel_hoc_main
(i), i);
90
#endif
91
}
92
93
#if LINDA
94
/* do first pass though loop on master node (first to first) */
95
pushx
(first);
96
pushx
(first);
97
#else
98
/* run in serial if not LINDA */
99
pushx
(first);
100
pushx
(last);
101
#endif
102
103
/* block until all instances of loop have finished */
104
#if LINDA
105
i = (
int
)last - (
int
)
first
;
106
while
(i-- > 0) {
107
int
err_val, err_num;
108
109
__linda_in(
"parallel run"
, ?err_val, ?err_num);
110
/* could test err_val != 0 but currently will always equal 0 */
111
}
112
#endif
113
114
/* assign value of symbol to last+1 as would be upon exiting a serial loop */
115
if
(!
ISARRAY
(sym)) {
116
if
(sym->
subtype
==
USERDOUBLE
) {
117
pval
= sym->
u
.
pval
;
118
}
else
{
119
pval
=
OPVAL
(sym);
120
}
121
}
else
{
122
if
(sym->
subtype
==
USERDOUBLE
) {
123
pval
= sym->
u
.
pval
+
araypt
(sym,
SYMBOL
);
124
}
else
{
125
pval
=
OPVAL
(sym) +
araypt
(sym, OBJECTVAR);
126
}
127
}
128
end_val
= last + 1;
129
130
}
else
{
131
/* the subsidiary instances do remaining contiguous blocks of the loop */
132
133
/* only do "parallel_val" pass though loop */
134
pushx
((
double
)
parallel_val
);
135
pushx
((
double
) parallel_val);
136
137
}
138
#endif
139
}
140
141
void
hoc_parallel_end
(
void
) {
142
#if !OCSMALL
143
/* need to exit after for-loop for all sub-processes */
144
if
(
parallel_sub
) {
145
hoc_final_exit
();
146
#if LINDA
147
lexit(0);
148
#else
149
exit(0);
150
#endif
151
152
}
else
{
153
/* assign loop counter the proper end value */
154
*
pval
=
end_val
;
155
}
156
#endif
157
}
158
159
160
int
parallel_hoc_main
(
int
i
) {
161
#if !OCSMALL
162
/*ARGSUSED*/
163
const
char
**_largv, **_lenvp;
164
const
char
* pnt;
165
char
*targv, *tenvp;
166
int
j
, _largc;
167
_largv =
static_cast<
const
char
**
>
(
emalloc
(
NUM_ARGS
*
sizeof
(
char
*)));
168
_lenvp =
static_cast<
const
char
**
>
(
emalloc
(
NUM_ARGS
*
sizeof
(
char
*)));
169
#if LINDA
170
char
name
[20];
171
172
gethostname(name, 20);
173
Fprintf
(stderr,
"\nLaunching sub-process on %s.\n\t1\n"
, name);
174
175
__linda_in(
"parallel sargs"
, ?
sargv
, ?
senvp
);
176
#endif
177
targv =
static_cast<
char
*
>
(
emalloc
(
sargv
));
178
tenvp =
static_cast<
char
*
>
(
emalloc
(
senvp
));
179
/* pointers need to point to memory that will be filled by __linda_in() */
180
#if LINDA
181
__linda_in(
"parallel args"
, ?targv:, ?tenvp:);
182
#endif
183
184
pnt = targv;
185
for
(j = 0; *pnt; j++) {
186
_largv[
j
] = pnt;
187
/*EMPTY*/
188
while
(*pnt++);
189
}
190
_largc =
j
;
191
192
pnt = tenvp;
193
for
(j = 0; *pnt; j++) {
194
_lenvp[
j
] = pnt;
195
/*EMPTY*/
196
while
(*pnt++);
197
}
198
199
/* run is killed at end of parallel for-loop (hoc_parallel_end()) */
200
hoc_main1
(_largc, _largv, _lenvp);
201
#endif
202
return
0;
203
}
204
205
void
save_parallel_argv
(
int
argc
,
const
char
**
argv
) {
206
/* first arg is program, save 2 & 3 for -parallel flags */
207
#if !defined(WIN32)
208
const
char
*pnt;
209
int
j
;
210
211
/* count how long the block of memory should be */
212
for
(j = 0; j < argc && (strcmp(argv[j],
"-"
) != 0); j++) {
213
pnt = argv[
j
];
214
while
(*pnt++) {
sargv
++; }
215
sargv
++;
/* add room for '\0' */
216
}
217
sargv
+= 16;
/* add 10 for "-parallel" and 6 for val ("00000") */
218
219
/* need room for extra '\0' at end, each space is of size (char) */
220
sargv
= (
sargv
+ 1) *
sizeof
(
char
);
221
222
/* malloc blocks of memory */
223
parallel_argv
=
static_cast<
char
*
>
(
emalloc
(
sargv
));
224
225
#if 0
226
/* place the strings into the memory block separated by '\0' */
227
strcpy((pnt =
parallel_argv
), argv[0]);
228
/*EMPTY*/
229
while
(*pnt++);
230
strcpy(pnt,
"-parallel 0"
);
/* pad val with 00000 (assume max int) */
231
pnt += 16;
232
for
(j = 1; j < argc && (strcmp(argv[j],
"-"
) != 0); j++) {
233
if
(strcmp(argv[j],
"-parallel"
) == 0) {
234
/* if sub-process then get val, increment past "-parallel" and "val" */
235
parallel_sub
= 1;
236
parallel_val
= atoi(argv[++j]);
237
238
}
else
{
239
strcpy(pnt, argv[j]);
240
/*EMPTY*/
241
while
(*pnt++);
242
}
243
}
244
*pnt =
'\0'
;
/* place extra '\0' at end */
245
#endif
246
#endif
247
}
248
249
void
save_parallel_envp
(
void
) {
250
#if LINDA
251
#if !defined(__APPLE__)
252
extern
char
** environ;
253
char
** envp = environ;
254
#endif
255
#if defined(__APPLE__)
256
char
** envp = (*_NSGetEnviron());
257
#endif
258
char
*pnt;
259
int
j
;
260
char
** envp = environ;
261
262
/* count how long the block of memory should be */
263
for
(j = 0; envp[
j
]; j++) {
264
pnt = envp[
j
];
265
while
(*pnt++) {
senvp
++; }
266
senvp
++;
/* add room for '\0' */
267
}
268
269
/* need room for extra '\0' at end, each space is of size (char) */
270
senvp
= (
senvp
+ 1) *
sizeof
(
char
);
271
272
/* malloc blocks of memory */
273
parallel_envp
=
static_cast<
char
*
>
(
emalloc
(
senvp
));
274
275
/* place the strings into the memory block separated by '\0' */
276
pnt =
parallel_envp
;
277
for
(j = 0; envp[
j
]; j++) {
278
strcpy(pnt, envp[j]);
279
/*EMPTY*/
280
while
(*pnt++);
281
}
282
*pnt =
'\0'
;
/* place extra '\0' at end */
283
#endif
284
}
hoc_final_exit
void hoc_final_exit()
Definition:
hoc.cpp:1130
end_val
static double end_val
Definition:
parallel.cpp:22
parallel_sub
int parallel_sub
Definition:
parallel.cpp:30
pushx
void pushx(double d)
Definition:
code.cpp:641
parallel_val
int parallel_val
Definition:
parallel.cpp:31
parallel_seen
static int parallel_seen
Definition:
parallel.cpp:19
save_parallel_envp
void save_parallel_envp(void)
Definition:
parallel.cpp:249
araypt
int araypt(Symbol *sp, int type)
Definition:
code.cpp:2402
first
static int first
Definition:
fmenu.cpp:186
Fprintf
#define Fprintf
Definition:
model.h:249
SYMBOL
#define SYMBOL
Definition:
model.h:102
sprintf
sprintf(buf," if (secondorder) {\ " int _i;\" " for(_i=0;_i< %d;++_i) {\" " _p[_slist%d[_i]]+=dt *_p[_dlist%d[_i]];\" " }}\", numeqn, listnum, listnum)
senvp
static int senvp
Definition:
parallel.cpp:27
pval
static double * pval
Definition:
parallel.cpp:21
pushs
void pushs(Symbol *d)
Definition:
code.cpp:708
spop
Symbol * spop(void)
Definition:
code.cpp:835
parallel_argv
static char * parallel_argv
Definition:
parallel.cpp:25
int
int
Definition:
nrnmusic.cpp:71
hoc_warning
void hoc_warning(const char *, const char *)
hoc_parallel_end
void hoc_parallel_end(void)
Definition:
parallel.cpp:141
ISARRAY
#define ISARRAY(arg)
Definition:
hocdec.h:163
hoc_parallel_begin
void hoc_parallel_begin(void)
Definition:
parallel.cpp:40
parallel_hoc_main
int parallel_hoc_main(int i)
Definition:
parallel.cpp:160
Symbol::pval
double * pval
Definition:
hocdec.h:136
getenv
char * getenv(const char *s)
Definition:
macprt.cpp:67
j
size_t j
Definition:
nrngsl_real_radix2.cpp:56
USERDOUBLE
#define USERDOUBLE
Definition:
hocdec.h:93
Symbol
Definition:
model.h:57
name
char * name
Definition:
init.cpp:16
xpop
double xpop(void)
Definition:
code.cpp:777
emalloc
char * emalloc(unsigned n)
Definition:
list.cpp:189
NUM_ARGS
#define NUM_ARGS
Definition:
parallel.cpp:24
OPVAL
#define OPVAL(sym)
Definition:
hocdec.h:304
Symbol::subtype
long subtype
Definition:
model.h:59
parallel_envp
static char * parallel_envp
Definition:
parallel.cpp:26
sargv
static int sargv
Definition:
parallel.cpp:27
hoc.h
i
#define i
Definition:
md1redef.h:12
buf
char buf[512]
Definition:
init.cpp:13
hoc_main1
int hoc_main1(int, const char **, const char **)
Definition:
hoc.cpp:972
argc
static int argc
Definition:
inithoc.cpp:53
Symbol::u
union Symbol::@18 u
argv
static char ** argv
Definition:
inithoc.cpp:54
save_parallel_argv
void save_parallel_argv(int argc, const char **argv)
Definition:
parallel.cpp:205
src
oc
parallel.cpp