line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Simulation::Automate; |
2
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
6385
|
use vars qw( $VERSION ); |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
151
|
|
4
|
|
|
|
|
|
|
$VERSION = "1.0.1"; |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
################################################################################# |
7
|
|
|
|
|
|
|
# # |
8
|
|
|
|
|
|
|
# Copyright (C) 2000,2002-2004 Wim Vanderbauwhede. All rights reserved. # |
9
|
|
|
|
|
|
|
# This program is free software; you can redistribute it and/or modify it # |
10
|
|
|
|
|
|
|
# under the same terms as Perl itself. # |
11
|
|
|
|
|
|
|
# # |
12
|
|
|
|
|
|
|
################################################################################# |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
#headers |
15
|
|
|
|
|
|
|
# |
16
|
|
|
|
|
|
|
#Main module for SynSim simulation automation tool. |
17
|
|
|
|
|
|
|
#The first part creates the module Loops.pm based on the data file; |
18
|
|
|
|
|
|
|
#this module is then called via eval() and used by Simulation::Automate.pm |
19
|
|
|
|
|
|
|
#Loops calls &Automate::main() at every pass through the loops. |
20
|
|
|
|
|
|
|
# |
21
|
|
|
|
|
|
|
#$Id$ |
22
|
|
|
|
|
|
|
# |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
|
25
|
2
|
|
|
2
|
|
14
|
use warnings; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
55
|
|
26
|
2
|
|
|
2
|
|
11
|
use strict; |
|
2
|
|
|
|
|
14
|
|
|
2
|
|
|
|
|
63
|
|
27
|
2
|
|
|
2
|
|
10
|
use Cwd; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
163
|
|
28
|
2
|
|
|
2
|
|
11
|
use Carp; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
129
|
|
29
|
2
|
|
|
2
|
|
10
|
use Exporter; |
|
2
|
|
|
|
|
23
|
|
|
2
|
|
|
|
|
56
|
|
30
|
2
|
|
|
2
|
|
718
|
use lib '.'; |
|
2
|
|
|
|
|
587
|
|
|
2
|
|
|
|
|
13
|
|
31
|
2
|
|
|
2
|
|
7259
|
use Simulation::Automate::Remote; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
1662
|
|
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
@Simulation::Automate::ISA = qw(Exporter); |
34
|
|
|
|
|
|
|
@Simulation::Automate::EXPORT = qw( |
35
|
|
|
|
|
|
|
&synsim |
36
|
|
|
|
|
|
|
&setup |
37
|
|
|
|
|
|
|
&localinstall |
38
|
|
|
|
|
|
|
); |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
#=============================================================================== |
41
|
|
|
|
|
|
|
sub synsim { |
42
|
1
|
|
|
1
|
1
|
5611
|
my $remotehost=&check_for_remote_host(); |
43
|
1
|
50
|
|
|
|
16
|
if($remotehost){ |
44
|
0
|
|
|
|
|
0
|
&run_on_remote_host($remotehost) |
45
|
|
|
|
|
|
|
} else { |
46
|
1
|
|
|
|
|
5
|
&run_local(); # new name for sub synsim |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
#=============================================================================== |
50
|
|
|
|
|
|
|
sub run_local { |
51
|
1
|
|
50
|
1
|
0
|
23
|
my $datafile=shift||'synsim.data'; |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
################################################################################ |
54
|
|
|
|
|
|
|
# |
55
|
|
|
|
|
|
|
# Create module Simulation::Automate::Loops.pm |
56
|
|
|
|
|
|
|
# |
57
|
|
|
|
|
|
|
################################################################################ |
58
|
|
|
|
|
|
|
|
59
|
1
|
|
|
|
|
4
|
my @flags=my ($batch,$interactive,$nosims,$plot,$verbose,$warn)=@{&preprocess_commandline($datafile)}; |
|
1
|
|
|
|
|
94
|
|
60
|
1
|
|
|
|
|
9
|
my $dataset=$datafile; |
61
|
1
|
|
|
|
|
19
|
$dataset=~s/\.data//; |
62
|
1
|
50
|
|
|
|
6
|
print STDERR "\nCreating Loops.pm...\n" if $verbose; |
63
|
|
|
|
|
|
|
|
64
|
1
|
|
|
|
|
14
|
(my $dataref,my $groupedref)=&allow_multiple_sims($datafile); |
65
|
1
|
|
|
|
|
8
|
my $simref=&generate_loop_module($dataref,$groupedref,$dataset,\@flags); |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
################################################################################ |
68
|
|
|
|
|
|
|
# |
69
|
|
|
|
|
|
|
# Do the actual simulations |
70
|
|
|
|
|
|
|
# |
71
|
|
|
|
|
|
|
################################################################################ |
72
|
|
|
|
|
|
|
|
73
|
1
|
50
|
|
|
|
10
|
&execute_loop($datafile,$dataset,$simref,\@flags) && do { |
74
|
1
|
|
|
|
|
164
|
unlink "Loops_$dataset.pm"; |
75
|
|
|
|
|
|
|
}; |
76
|
1
|
50
|
|
|
|
395
|
if($dataset ne 'synsim'){ |
77
|
0
|
|
|
|
|
0
|
print STDERR "\nFinished SynSim run for $dataset.data\n\n"; |
78
|
|
|
|
|
|
|
} else { |
79
|
1
|
|
|
|
|
87
|
print STDERR "\nFinished SynSim run\n\n"; |
80
|
|
|
|
|
|
|
} |
81
|
1
|
|
|
|
|
124
|
return 1; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
#=============================================================================== |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
################################################################################ |
86
|
|
|
|
|
|
|
## |
87
|
|
|
|
|
|
|
## Subroutines |
88
|
|
|
|
|
|
|
## |
89
|
|
|
|
|
|
|
################################################################################ |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub preprocess_commandline { |
92
|
1
|
|
|
1
|
0
|
9
|
my $datafile=$_[0]; |
93
|
1
|
|
|
|
|
7
|
my ($batch,$interactive,$nosims,$plot,$verbose,$warn,$justplot,$list_postprocessors)=(0,0,0,0,0,0,0,0); |
94
|
1
|
|
|
|
|
4
|
my $default=1; |
95
|
1
|
50
|
|
|
|
7
|
if(@ARGV) { |
96
|
0
|
|
|
|
|
0
|
my $dtf=0; |
97
|
0
|
|
|
|
|
0
|
foreach(@ARGV) { |
98
|
0
|
0
|
|
|
|
0
|
if(/-f/){$dtf=1;next} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
99
|
0
|
0
|
|
|
|
0
|
if($dtf==1) { |
100
|
0
|
|
|
|
|
0
|
$_[0]=$_;$datafile=$_;$default=0;$dtf=0; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
101
|
|
|
|
|
|
|
} |
102
|
0
|
0
|
|
|
|
0
|
if(/-b/){$batch=1;next} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
103
|
0
|
0
|
|
|
|
0
|
if(/-i/){$interactive=1;$plot=1;$verbose=1;next} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
104
|
0
|
0
|
|
|
|
0
|
if(/-N/){$nosims=1;next} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
105
|
0
|
0
|
|
|
|
0
|
if(/-p/){$plot=1;next} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
106
|
0
|
0
|
|
|
|
0
|
if(/-v/){$verbose=1;next} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
107
|
0
|
0
|
|
|
|
0
|
if(/-w/){$warn=1;next;} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
108
|
0
|
0
|
|
|
|
0
|
if(/-P/){$justplot=1;next} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
109
|
0
|
0
|
|
|
|
0
|
if(/-A/){$list_postprocessors=1;next} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
110
|
0
|
0
|
|
|
|
0
|
if(/-D/) { |
111
|
0
|
0
|
|
|
|
0
|
(not -d 'TEMPLATES') && mkdir 'TEMPLATES'; |
112
|
0
|
0
|
|
|
|
0
|
(not -d 'TEMPLATES/SIMTYPES') && mkdir 'TEMPLATES/SIMTYPES'; |
113
|
0
|
0
|
|
|
|
0
|
(not -d 'TEMPLATES/DEVTYPES') && mkdir 'TEMPLATES/DEVTYPES'; |
114
|
0
|
0
|
|
|
|
0
|
(not -d 'SOURCES') && mkdir 'SOURCES'; |
115
|
0
|
0
|
|
|
|
0
|
(not -d 'PLUGINS') && mkdir 'PLUGINS'; |
116
|
0
|
|
|
|
|
0
|
die "An empty directory structure has been created\n"; |
117
|
|
|
|
|
|
|
} |
118
|
0
|
0
|
|
|
|
0
|
if(/-h|-\?/) { |
119
|
0
|
|
|
|
|
0
|
my $script=$0; |
120
|
0
|
|
|
|
|
0
|
$script=~s/.*\///; |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
# -f flag now optional |
123
|
|
|
|
|
|
|
# -f [filename]: 'file input'. Expects a file containing info about simulation and device type. |
124
|
|
|
|
|
|
|
|
125
|
0
|
|
|
|
|
0
|
die <<"HELP"; |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
The script must be executed in a subdirectory of the directory |
128
|
|
|
|
|
|
|
containing the script. |
129
|
|
|
|
|
|
|
This directory must contain at least a TEMPLATES/SIMTYPE subdir |
130
|
|
|
|
|
|
|
with the simulation templates, and a data file. See documentation for more information. |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
syntax: ./$script [-h -D -i -p -P -A -v -w -N datafile] |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
Possible switches: |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
none: defaults to -f $datafile |
137
|
|
|
|
|
|
|
-D : Create an empty SynSim directory structure in the current directory |
138
|
|
|
|
|
|
|
-v : 'verbose'. Sends simulator output to STDOUT, otherwise to simlog file |
139
|
|
|
|
|
|
|
-p : plot. This creates the plot, but does not display it |
140
|
|
|
|
|
|
|
-i : interactive. Creates a plot on the screen after every iteration. Implies -p -v |
141
|
|
|
|
|
|
|
-P : Plot. This displays plots created with -p |
142
|
|
|
|
|
|
|
-A : Analysis Templates. Displays a list of all available analysis templates and the man page |
143
|
|
|
|
|
|
|
-w : 'warnings'. Show warnings for undefined variables. |
144
|
|
|
|
|
|
|
-N : 'No simulations'. Does only postprocessing |
145
|
|
|
|
|
|
|
-h, -? : this help |
146
|
|
|
|
|
|
|
HELP |
147
|
|
|
|
|
|
|
} |
148
|
|
|
|
|
|
|
} # foreach @ARGV |
149
|
0
|
0
|
|
|
|
0
|
if($list_postprocessors) { |
150
|
|
|
|
|
|
|
#convenience function to list available postprocessors |
151
|
|
|
|
|
|
|
#so get all subs from PostProcessors |
152
|
|
|
|
|
|
|
|
153
|
0
|
|
|
|
|
0
|
print "\n"; |
154
|
0
|
0
|
|
|
|
0
|
if(-e '../Simulation/Automate.pm') { |
155
|
|
|
|
|
|
|
#This is good for a local SynSim, not for a global one |
156
|
0
|
|
|
|
|
0
|
system("pod2text ../Simulation/Automate.pm | perl -n -e 'print if /^POST/../^DICT/ and !/DICT/' | less"); |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
} else { |
159
|
0
|
|
|
|
|
0
|
system("man Simulation::Automate"); |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
} |
162
|
2
|
|
|
2
|
|
12
|
no strict; |
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
10465
|
|
163
|
0
|
|
|
|
|
0
|
require('../Simulation/Automate/PostProcessors.pm'); |
164
|
0
|
|
|
|
|
0
|
print "\nAvailable postprocessing routines:\n\n"; |
165
|
0
|
|
|
|
|
0
|
foreach my $key (sort keys %Simulation::Automate::PostProcessors::) { |
166
|
|
|
|
|
|
|
|
167
|
0
|
0
|
|
|
|
0
|
if( $key=~/^[A-Z]+[a-z]+/){ |
168
|
0
|
|
|
|
|
0
|
print "$key \n"; |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
} |
171
|
0
|
|
|
|
|
0
|
die "\n"; |
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
#test if the last argument might be the filename (if no -f flag) |
174
|
0
|
0
|
|
|
|
0
|
if($default){ |
175
|
0
|
|
|
|
|
0
|
my $test=$ARGV[@ARGV-1]; |
176
|
0
|
0
|
|
|
|
0
|
if($test!~/^\-/) { |
177
|
0
|
|
|
|
|
0
|
$datafile=$test; |
178
|
0
|
|
|
|
|
0
|
$default=0; |
179
|
0
|
|
|
|
|
0
|
$_[0]=$datafile; |
180
|
|
|
|
|
|
|
} |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
|
183
|
0
|
0
|
|
|
|
0
|
if($default) { |
184
|
0
|
0
|
|
|
|
0
|
print STDERR "Assuming $datafile as input data filename\n" if $verbose; |
185
|
|
|
|
|
|
|
} |
186
|
|
|
|
|
|
|
} else { |
187
|
1
|
50
|
|
|
|
10
|
print STDERR "No command line arguments given. Assuming $datafile as input data filename\n" if $verbose; |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
1
|
50
|
33
|
|
|
64
|
if(not(-e "./TEMPLATES" && -d "./TEMPLATES" && -e "./$datafile")) { |
|
|
|
33
|
|
|
|
|
191
|
0
|
|
|
|
|
0
|
die " |
192
|
|
|
|
|
|
|
The current directory must contain at least a TEMPLATES/SIMTYPE subdir with the simulation templates, and a data file. See documentation for more information. |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
If Simulation::Automate is installed locally, the current directory must be in the same directoy as the Simulation directory. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
"; |
197
|
|
|
|
|
|
|
} |
198
|
1
|
50
|
|
|
|
16
|
if($justplot) { |
199
|
|
|
|
|
|
|
#convenience function to plot results |
200
|
0
|
|
|
|
|
0
|
chomp(my $simtype=`egrep '^SIM(TYPE|NAME|ULATION|TEMPL)|^\ *TEMPLATE' $datafile`); |
201
|
0
|
|
|
|
|
0
|
$simtype=~s/^SIM(TYPE|NAME|ULATION)|^\s*TEMPLATE\s*:\s*//; |
202
|
0
|
|
|
|
|
0
|
$simtype=~s/\s*$//; |
203
|
0
|
|
|
|
|
0
|
$simtype=~s/\..*$//; |
204
|
0
|
|
|
|
|
0
|
chomp(my $anatype=`egrep '^ANA(LYSIS)*_*(TEMPL)*(ATE)*' $datafile`); |
205
|
0
|
|
|
|
|
0
|
$anatype=~s/^ANA(LYSIS)*_*(TEMPL)*(ATE)*\s*:\s*//; |
206
|
0
|
|
|
|
|
0
|
$anatype=~s/\s*$//; |
207
|
0
|
|
|
|
|
0
|
$datafile=~s/\.data//; |
208
|
|
|
|
|
|
|
|
209
|
0
|
|
|
|
|
0
|
chdir "${simtype}-$datafile"; |
210
|
0
|
|
|
|
|
0
|
my $gv='/usr/bin/ggv'; |
211
|
0
|
0
|
0
|
|
|
0
|
if((not -e '/usr/bin/ggv') and ( -e '/usr/X11R6/bin/gv')) { |
212
|
0
|
|
|
|
|
0
|
$gv='/usr/X11R6/bin/gv'; |
213
|
|
|
|
|
|
|
} |
214
|
0
|
|
|
|
|
0
|
system("$gv ${simtype}-$anatype.ps"); |
215
|
0
|
|
|
|
|
0
|
die "Done\n"; |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
|
219
|
1
|
|
|
|
|
10
|
return [$batch,$interactive,$nosims,$plot,$verbose,$warn]; |
220
|
|
|
|
|
|
|
} #END of preprocess_commandline |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
223
|
|
|
|
|
|
|
# |
224
|
|
|
|
|
|
|
# This subroutine takes a reference to %specific as generated by allow_multiple_sims($datafile) and passes it on to fill_data_hash_multi; |
225
|
|
|
|
|
|
|
# It gets back %data, which contains the list of parameters and their value-list for every simtype |
226
|
|
|
|
|
|
|
# |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
sub generate_loop_module { |
229
|
1
|
|
|
1
|
0
|
3
|
my $specificref=shift; #this is the reference to %specific, the hash of arrays of data for each sim |
230
|
1
|
|
|
|
|
2
|
my $groupedref=shift; |
231
|
1
|
|
|
|
|
4
|
my %grouped=%$groupedref; |
232
|
|
|
|
|
|
|
|
233
|
1
|
|
|
|
|
2
|
my $dataset=shift; |
234
|
1
|
|
|
|
|
2
|
my $flagsref=shift; |
235
|
1
|
|
|
|
|
2
|
my ($batch,$interactive,$nosims,$plot,$verbose,$warn)=@{$flagsref}; |
|
1
|
|
|
|
|
2
|
|
236
|
1
|
|
|
|
|
5
|
my $dataref=&fill_data_hash_multi($specificref); |
237
|
1
|
|
|
|
|
2
|
my %data=%{$dataref}; |
|
1
|
|
|
|
|
3
|
|
238
|
1
|
|
|
|
|
91
|
open(MOD,">Loops_$dataset.pm"); |
239
|
|
|
|
|
|
|
|
240
|
1
|
|
|
|
|
21
|
print MOD &strip(<<"ENDHEAD"); |
241
|
|
|
|
|
|
|
*package Loops_$dataset; |
242
|
|
|
|
|
|
|
*# |
243
|
|
|
|
|
|
|
*################################################################################ |
244
|
|
|
|
|
|
|
*# Author: WV # |
245
|
|
|
|
|
|
|
*# Date : 21/11/2000;01/08/2002 # |
246
|
|
|
|
|
|
|
*# # |
247
|
|
|
|
|
|
|
*# Module to support script for SynSim simulations. # |
248
|
|
|
|
|
|
|
*# The subroutine in this module generates the loop to do multiple simulations. # |
249
|
|
|
|
|
|
|
*# This module is generated by Simulation::Automate.pm # |
250
|
|
|
|
|
|
|
*# # |
251
|
|
|
|
|
|
|
*################################################################################ |
252
|
|
|
|
|
|
|
* |
253
|
|
|
|
|
|
|
*use sigtrap qw(die untrapped normal-signals |
254
|
|
|
|
|
|
|
* stack-trace any error-signals); |
255
|
|
|
|
|
|
|
*use strict; |
256
|
|
|
|
|
|
|
* |
257
|
|
|
|
|
|
|
*use FileHandle; |
258
|
|
|
|
|
|
|
*use Exporter; |
259
|
|
|
|
|
|
|
* |
260
|
|
|
|
|
|
|
*\@Loops_${dataset}::ISA = qw(Exporter); |
261
|
|
|
|
|
|
|
*\@Loops_${dataset}::EXPORT = qw( |
262
|
|
|
|
|
|
|
ENDHEAD |
263
|
|
|
|
|
|
|
|
264
|
1
|
|
|
|
|
7
|
foreach my $sim (keys %data) { |
265
|
1
|
|
|
|
|
5
|
print MOD &strip( |
266
|
|
|
|
|
|
|
"* execute_${sim}_loop\n"); |
267
|
|
|
|
|
|
|
} |
268
|
1
|
|
|
|
|
4
|
print MOD &strip(' |
269
|
|
|
|
|
|
|
* ); |
270
|
|
|
|
|
|
|
* |
271
|
|
|
|
|
|
|
'); |
272
|
|
|
|
|
|
|
|
273
|
1
|
|
|
|
|
3
|
my @sims=(); |
274
|
1
|
|
|
|
|
6
|
foreach my $sim (keys %data) { |
275
|
1
|
|
|
|
|
3
|
my $title=$data{$sim}{TITLE}; |
276
|
1
|
|
|
|
|
11
|
delete $data{$sim}{TITLE}; |
277
|
|
|
|
|
|
|
|
278
|
1
|
50
|
|
|
|
63
|
my $nruns=(exists $data{$sim}{NRUNS})?$data{$sim}{NRUNS}:1; |
279
|
1
|
50
|
|
|
|
6
|
if($nruns>1) { |
280
|
0
|
|
|
|
|
0
|
$data{$sim}{__NRUNS}=join(',',(1..$nruns)); |
281
|
|
|
|
|
|
|
} |
282
|
1
|
|
|
|
|
3
|
push @sims,$sim; |
283
|
1
|
|
|
|
|
12
|
print MOD &strip(<<"ENDSUBHEAD"); |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
*use lib '..','../..'; |
286
|
|
|
|
|
|
|
*#use Simulation::Automate::Main; |
287
|
|
|
|
|
|
|
*use Simulation::Automate; |
288
|
|
|
|
|
|
|
*#use Simulation::Automate::PostProcessors; |
289
|
|
|
|
|
|
|
*use Simulation::Automate::PostProcLib; |
290
|
|
|
|
|
|
|
* |
291
|
|
|
|
|
|
|
*sub execute_${sim}_loop { |
292
|
|
|
|
|
|
|
*my \$dataset=shift; |
293
|
|
|
|
|
|
|
*my \$dirname=\"${sim}-\$dataset\"; |
294
|
|
|
|
|
|
|
*my \$flagsref=shift; |
295
|
|
|
|
|
|
|
*my \$i=0; |
296
|
|
|
|
|
|
|
*my \$returnvalue; |
297
|
|
|
|
|
|
|
*my \$resheader=''; |
298
|
|
|
|
|
|
|
*my \%last=(); |
299
|
|
|
|
|
|
|
*my \%sweepeddata=(); |
300
|
|
|
|
|
|
|
*my \$v=$verbose; |
301
|
|
|
|
|
|
|
*my \$leaveloop=0; |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
ENDSUBHEAD |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
#if($data{$sim}{'PREPROCESSOR'}) { |
306
|
|
|
|
|
|
|
#print MOD &strip(' |
307
|
|
|
|
|
|
|
#*my $preprocref=\&Simulation::Automate::PostProcessors::'.$data{$sim}{'PREPROCESSOR'}.'; |
308
|
|
|
|
|
|
|
#'); |
309
|
|
|
|
|
|
|
#} else { |
310
|
|
|
|
|
|
|
#print MOD &strip(' |
311
|
|
|
|
|
|
|
#*my $preprocref; |
312
|
|
|
|
|
|
|
#'); |
313
|
|
|
|
|
|
|
#} |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
# TITLE is treated separately |
316
|
1
|
|
|
|
|
6
|
print MOD &strip( |
317
|
|
|
|
|
|
|
"*my \$TITLE = '$title';\n" |
318
|
|
|
|
|
|
|
); |
319
|
|
|
|
|
|
|
|
320
|
1
|
|
|
|
|
3
|
foreach my $par (sort keys %{$data{$sim}}) { |
|
1
|
|
|
|
|
11
|
|
321
|
2
|
50
|
|
|
|
10
|
$par!~/^\_/ && next; |
322
|
|
|
|
|
|
|
#Here as good as anywhere else |
323
|
|
|
|
|
|
|
#WV 010604 |
324
|
|
|
|
|
|
|
# We must deal with CONDVAR |
325
|
|
|
|
|
|
|
# This is not good: it means some postprocessors require a change to the code! |
326
|
|
|
|
|
|
|
#Anyway |
327
|
0
|
|
|
|
|
0
|
my $conditional =0; |
328
|
0
|
0
|
|
|
|
0
|
if (exists $data{$sim}{CONDVAR}) { |
329
|
|
|
|
|
|
|
#CONDVAR must be the sweepvar |
330
|
0
|
|
|
|
|
0
|
$conditional =1; |
331
|
|
|
|
|
|
|
} |
332
|
|
|
|
|
|
|
|
333
|
0
|
0
|
0
|
|
|
0
|
if ( ( not $conditional and |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
334
|
|
|
|
|
|
|
( |
335
|
|
|
|
|
|
|
(exists $data{$sim}{XVAR} and $par eq $data{$sim}{XVAR}) or (exists $data{$sim}{SWEEPVAR} and $par eq $data{$sim}{SWEEPVAR}) |
336
|
|
|
|
|
|
|
) |
337
|
|
|
|
|
|
|
) or ( $conditional and |
338
|
|
|
|
|
|
|
( $par eq $data{$sim}{CONDVAR}) |
339
|
|
|
|
|
|
|
) |
340
|
|
|
|
|
|
|
) { |
341
|
|
|
|
|
|
|
#the sweep variable, make sure it's ; not , |
342
|
0
|
|
|
|
|
0
|
$data{$sim}{$par}=~s/,/;/g; # a bit rough, comments at end get it as well |
343
|
|
|
|
|
|
|
#make sure grouped variables are treated as well |
344
|
0
|
0
|
|
|
|
0
|
if (exists $grouped{$par}) { |
345
|
0
|
|
|
|
|
0
|
my $leader=$grouped{$par}; |
346
|
0
|
|
|
|
|
0
|
foreach my $gpar (sort keys %grouped) { |
347
|
0
|
0
|
|
|
|
0
|
if( $grouped{$gpar} eq $leader) { |
348
|
0
|
|
|
|
|
0
|
$data{$sim}{$gpar}=~s/,/;/g; |
349
|
0
|
|
|
|
|
0
|
delete $grouped{$gpar}; |
350
|
|
|
|
|
|
|
} |
351
|
|
|
|
|
|
|
} |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
} |
354
|
|
|
|
|
|
|
} |
355
|
|
|
|
|
|
|
# define vars |
356
|
1
|
|
|
|
|
3
|
foreach my $par (sort keys %{$data{$sim}}) { |
|
1
|
|
|
|
|
6
|
|
357
|
2
|
50
|
|
|
|
12
|
if ($data{$sim}{$par}!~/,/) { # if just one item |
358
|
|
|
|
|
|
|
# support for "for..to..step.."-style lists |
359
|
2
|
|
|
|
|
9
|
$data{$sim}{$par}=&expand_list($data{$sim}{$par}); |
360
|
|
|
|
|
|
|
|
361
|
2
|
|
|
|
|
6
|
$data{$sim}{$par}=~s/^\'//; |
362
|
2
|
|
|
|
|
5
|
$data{$sim}{$par}=~s/\'$//; |
363
|
2
|
|
|
|
|
10
|
print MOD &strip( |
364
|
|
|
|
|
|
|
"*my \$${par} = '$data{$sim}{$par}';\n" |
365
|
|
|
|
|
|
|
); |
366
|
|
|
|
|
|
|
} |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
# assign common hash items |
369
|
1
|
|
|
|
|
3
|
print MOD &strip( |
370
|
|
|
|
|
|
|
"*my \%data=();\n" |
371
|
|
|
|
|
|
|
); |
372
|
1
|
|
|
|
|
5
|
print MOD &strip(' |
373
|
|
|
|
|
|
|
* print STDERR "# SynSim configuration variables\n" if $v; |
374
|
|
|
|
|
|
|
* print STDERR "#","-" x 79,"\n# TITLE : '.$title.'\n" if $v; |
375
|
|
|
|
|
|
|
* $resheader.= "# SynSim configuration variables\n"; |
376
|
|
|
|
|
|
|
* $resheader.= "#"."-" x 79; |
377
|
|
|
|
|
|
|
* $resheader.= "\n# TITLE : '.$title.'\n"; |
378
|
|
|
|
|
|
|
'); |
379
|
1
|
|
|
|
|
3
|
print MOD &strip( |
380
|
|
|
|
|
|
|
"*\$data{TITLE}=\$TITLE;\n" |
381
|
|
|
|
|
|
|
); |
382
|
1
|
|
|
|
|
3
|
my $nsims=1; |
383
|
1
|
|
|
|
|
5
|
my $prevkey=''; |
384
|
|
|
|
|
|
|
|
385
|
1
|
|
|
|
|
2
|
foreach my $par (sort keys %{$data{$sim}}) { |
|
1
|
|
|
|
|
5
|
|
386
|
|
|
|
|
|
|
|
387
|
2
|
50
|
33
|
|
|
7
|
if($par=~/^_/ && $prevkey!~/^_/) { |
388
|
0
|
|
|
|
|
0
|
print MOD &strip(' |
389
|
|
|
|
|
|
|
* print STDERR "#","-" x 79,"\n" if $v; |
390
|
|
|
|
|
|
|
* print STDERR "# Static parameters used in the simulation:\n" if $v; |
391
|
|
|
|
|
|
|
* print STDERR "#","-" x 79,"\n" if $v; |
392
|
|
|
|
|
|
|
* $resheader.= "#"."-" x 79; |
393
|
|
|
|
|
|
|
* $resheader.= "\n# Static parameters used in the simulation:\n"; |
394
|
|
|
|
|
|
|
* $resheader.= "#"."-" x 79; |
395
|
|
|
|
|
|
|
* $resheader.= "\n"; |
396
|
|
|
|
|
|
|
'); |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
2
|
50
|
|
|
|
8
|
if ($data{$sim}{$par}!~/,/) { # if just one item, or it might be a sweep |
400
|
2
|
50
|
|
|
|
9
|
if($data{$sim}{$par}=~/(\d+)\s*\.\.\s*(\d+)/) { |
|
|
50
|
|
|
|
|
|
401
|
0
|
|
|
|
|
0
|
my $b=$1; |
402
|
0
|
|
|
|
|
0
|
my $e=$2; |
403
|
0
|
|
|
|
|
0
|
my $patt="$b .. $e"; |
404
|
0
|
|
|
|
|
0
|
$nsims=$e-$b+1; |
405
|
0
|
|
|
|
|
0
|
print MOD &strip( |
406
|
|
|
|
|
|
|
"*my \@tmp$par=($patt); |
407
|
|
|
|
|
|
|
*\$data{$par} = [\@tmp$par]; |
408
|
|
|
|
|
|
|
*print STDERR \"# $par = \$$par\\n\" if \$v; |
409
|
|
|
|
|
|
|
*\$resheader.= \"# $par = \$$par\\n\"; |
410
|
|
|
|
|
|
|
"); |
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
} elsif($data{$sim}{$par}=~/;/) { |
413
|
|
|
|
|
|
|
|
414
|
0
|
|
|
|
|
0
|
my $tmp=$data{$sim}{$par}; |
415
|
0
|
|
|
|
|
0
|
my $tmps=($tmp=~s/;/,/g); |
416
|
0
|
0
|
|
|
|
0
|
if($tmps>=$nsims){$nsims=$tmps+1} |
|
0
|
|
|
|
|
0
|
|
417
|
0
|
|
|
|
|
0
|
print MOD &strip( |
418
|
|
|
|
|
|
|
"*my \@tmp$par=split(/;/,\$$par); |
419
|
|
|
|
|
|
|
*\$data{$par} = [\@tmp$par]; |
420
|
|
|
|
|
|
|
*print STDERR \"# $par = \$$par\\n\" if \$v; |
421
|
|
|
|
|
|
|
*\$resheader.= \"# $par = \$$par\\n\"; |
422
|
|
|
|
|
|
|
"); |
423
|
|
|
|
|
|
|
} else { |
424
|
2
|
50
|
|
|
|
6
|
if($par=~/^_/) { |
425
|
0
|
|
|
|
|
0
|
print MOD &strip( |
426
|
|
|
|
|
|
|
"*\$data{$par} = [\$$par]; |
427
|
|
|
|
|
|
|
*print STDERR \"# $par = \$$par\\n\" if \$v; |
428
|
|
|
|
|
|
|
*\$resheader.= \"# $par = \$$par\\n\"; |
429
|
|
|
|
|
|
|
"); |
430
|
|
|
|
|
|
|
} else { |
431
|
2
|
|
|
|
|
11
|
print MOD &strip( |
432
|
|
|
|
|
|
|
"*\$data{$par} = \$$par; # no reason for array |
433
|
|
|
|
|
|
|
*print STDERR \"# $par : \$$par\\n\" if \$v; # no reason to print |
434
|
|
|
|
|
|
|
*\$resheader.= \"# $par : \$$par\\n\"; # no reason to print |
435
|
|
|
|
|
|
|
"); |
436
|
|
|
|
|
|
|
} |
437
|
|
|
|
|
|
|
} |
438
|
|
|
|
|
|
|
} |
439
|
2
|
|
|
|
|
43
|
$prevkey=$par; |
440
|
|
|
|
|
|
|
} |
441
|
|
|
|
|
|
|
|
442
|
1
|
|
|
|
|
9
|
print MOD &strip( |
443
|
|
|
|
|
|
|
"*my \$nsims=$nsims;\n" |
444
|
|
|
|
|
|
|
); |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
|
447
|
1
|
|
|
|
|
3
|
foreach my $par (sort keys %{$data{$sim}}) { |
|
1
|
|
|
|
|
4
|
|
448
|
|
|
|
|
|
|
|
449
|
2
|
50
|
|
|
|
7
|
if ($data{$sim}{$par}=~/,/) { # if more than one item |
450
|
|
|
|
|
|
|
# support for "for to step"-style lists |
451
|
0
|
|
|
|
|
0
|
$data{$sim}{$par}=&expand_list($data{$sim}{$par}); |
452
|
0
|
|
|
|
|
0
|
my $parlist=$data{$sim}{$par}; |
453
|
0
|
|
|
|
|
0
|
$parlist=~s/,/ /g; |
454
|
|
|
|
|
|
|
#support for "grouped" parameters |
455
|
0
|
0
|
|
|
|
0
|
if(exists $grouped{$par}) { |
456
|
0
|
0
|
|
|
|
0
|
if($grouped{$par} eq $par){ # the "leader" of the group |
457
|
0
|
|
|
|
|
0
|
my $leader=$par; |
458
|
0
|
|
|
|
|
0
|
foreach my $var (sort keys %grouped) { |
459
|
0
|
0
|
|
|
|
0
|
if($grouped{$var} eq $leader){ |
460
|
0
|
|
|
|
|
0
|
my $varlist=$data{$sim}{$var}; |
461
|
0
|
|
|
|
|
0
|
$varlist=~s/,/ /g; |
462
|
0
|
|
|
|
|
0
|
print MOD &strip( |
463
|
|
|
|
|
|
|
"*my \@${var}list = qw($varlist); |
464
|
|
|
|
|
|
|
*\$last{$var}=\$${var}list[\@${var}list-1]; |
465
|
|
|
|
|
|
|
"); |
466
|
|
|
|
|
|
|
} |
467
|
|
|
|
|
|
|
} |
468
|
0
|
|
|
|
|
0
|
print MOD &strip("*foreach my \$${par} (\@${par}list) {\n"); |
469
|
0
|
|
|
|
|
0
|
foreach my $var (sort keys %grouped) { |
470
|
0
|
0
|
|
|
|
0
|
($var eq $par) && next; |
471
|
0
|
0
|
|
|
|
0
|
if($grouped{$var} eq $leader){ |
472
|
0
|
|
|
|
|
0
|
print MOD &strip("*my \$${var}=shift(\@${var}list);\n"); |
473
|
|
|
|
|
|
|
} |
474
|
|
|
|
|
|
|
} |
475
|
|
|
|
|
|
|
} |
476
|
|
|
|
|
|
|
} else { |
477
|
0
|
|
|
|
|
0
|
print MOD &strip( |
478
|
|
|
|
|
|
|
"*my \@${par}list = qw($parlist); |
479
|
|
|
|
|
|
|
*\$last{$par}=\$${par}list[\@${par}list-1]; |
480
|
|
|
|
|
|
|
*foreach my \$${par} (\@${par}list) {\n" |
481
|
|
|
|
|
|
|
); |
482
|
|
|
|
|
|
|
} |
483
|
|
|
|
|
|
|
} |
484
|
|
|
|
|
|
|
} |
485
|
1
|
|
|
|
|
6
|
print MOD &strip( |
486
|
|
|
|
|
|
|
"*\$i++; |
487
|
|
|
|
|
|
|
*open(RES,\">\$dirname\/${sim}_C\$i.res\")|| do {print STDERR \"Can\'t open \$dirname\/${sim}_\$i.res\" if \$v;}; |
488
|
|
|
|
|
|
|
"); |
489
|
1
|
|
|
|
|
4
|
print MOD &strip(' |
490
|
|
|
|
|
|
|
* print STDERR "#","-" x 79,"\n" if $v; |
491
|
|
|
|
|
|
|
* print STDERR "# Parameters for simulation run $i:\n" if $v; |
492
|
|
|
|
|
|
|
* print RES $resheader; |
493
|
|
|
|
|
|
|
* print RES "#"."-" x 79,"\n"; |
494
|
|
|
|
|
|
|
* print RES "# Parameters for simulation run $i:\n"; |
495
|
|
|
|
|
|
|
'); |
496
|
|
|
|
|
|
|
|
497
|
1
|
|
0
|
|
|
7
|
my $simtempl=$data{$sim}{SIMTYPE}||$data{$sim}{SIMNAME}||$data{$sim}{SIMULATION}||$data{$sim}{TEMPLATE}||$data{$sim}{SIMTEMPL}; |
498
|
|
|
|
|
|
|
#$simtempl=~s/\.\w+$//; |
499
|
|
|
|
|
|
|
|
500
|
1
|
|
50
|
|
|
42
|
my $anatempl=$data{$sim}{ANALYSIS_TEMPLATE}||$data{$sim}{ANALYSIS}||$data{$sim}{ANATEMPL}||$data{$sim}{ANALYSIS_TEMPL}||$data{$sim}{ANA_TEMPLATE}||'None';#'NoAnalysisDefined'; |
501
|
1
|
|
|
|
|
2
|
my $subref=$anatempl; |
502
|
|
|
|
|
|
|
|
503
|
1
|
|
|
|
|
4
|
print MOD &strip(' |
504
|
|
|
|
|
|
|
*my $resfilename="'.$sim.'-'.$anatempl.'"; |
505
|
|
|
|
|
|
|
*$data{RESHEADER}=$resheader; |
506
|
|
|
|
|
|
|
'); |
507
|
|
|
|
|
|
|
|
508
|
1
|
|
|
|
|
3
|
foreach my $par (sort keys %{$data{$sim}}) { |
|
1
|
|
|
|
|
7
|
|
509
|
2
|
50
|
|
|
|
8
|
if ($data{$sim}{$par}=~/,/) { # if more than one item |
510
|
0
|
|
|
|
|
0
|
print MOD &strip( |
511
|
|
|
|
|
|
|
"*\$data{$par} = [\$$par]; |
512
|
|
|
|
|
|
|
*\$sweepeddata{$par} = \$$par; |
513
|
|
|
|
|
|
|
*\$resfilename.=\"-${par}-\$$par\"; |
514
|
|
|
|
|
|
|
*print STDERR \"# $par = \$$par\\n\" if \$v; |
515
|
|
|
|
|
|
|
*print RES \"# $par = \$$par\\n\"; |
516
|
|
|
|
|
|
|
"); |
517
|
|
|
|
|
|
|
} |
518
|
|
|
|
|
|
|
} |
519
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
##WV21042003: old, sweep loops internal |
521
|
|
|
|
|
|
|
#print MOD &strip( |
522
|
|
|
|
|
|
|
#"* close RES; |
523
|
|
|
|
|
|
|
#*\$resfilename.='.res'; |
524
|
|
|
|
|
|
|
#*#NEW01072003#rename \"\$dirname\/${sim}_C\$i.res\",\"\$dirname\/\$resfilename\"; |
525
|
|
|
|
|
|
|
#*my \$dataref = [\$nsims,\\\%data]; |
526
|
|
|
|
|
|
|
#*\$returnvalue=&main(\$dataset,\$i,\$dataref,\$resfilename,\$flagsref); |
527
|
|
|
|
|
|
|
#* |
528
|
|
|
|
|
|
|
#"); |
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
#WV21042003: new, sweep loops external |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
#The idea is to evaluate a condition inside the loop, after very sim |
533
|
|
|
|
|
|
|
#If the condition is satisfied, skip the next |
534
|
|
|
|
|
|
|
|
535
|
1
|
|
|
|
|
6
|
print MOD &strip( |
536
|
|
|
|
|
|
|
"* close RES; |
537
|
|
|
|
|
|
|
*my \$dataref = [\$nsims,\\\%data]; |
538
|
|
|
|
|
|
|
*#my \$nsims=&pre_run(\$dataset,\$i,\$dataref,\$flagsref); |
539
|
|
|
|
|
|
|
*\$nsims=&pre_run(\$dataset,\$i,\$dataref,\$flagsref); |
540
|
|
|
|
|
|
|
*my \$dataref_postproc = [\$nsims,\\\%data,\\\%sweepeddata,\\\%last]; |
541
|
|
|
|
|
|
|
*foreach my \$simn (1..\$nsims) { |
542
|
|
|
|
|
|
|
*\$leaveloop && last; |
543
|
|
|
|
|
|
|
*\$returnvalue=&run(\$nsims,\$simn); |
544
|
|
|
|
|
|
|
*#print STDERR \"RET:\$returnvalue=\$nsims,\$simn\\n\"; |
545
|
|
|
|
|
|
|
* |
546
|
|
|
|
|
|
|
*#Call postprocessor inside loop to see if we can leave the loop early |
547
|
|
|
|
|
|
|
*#chdir \$dirname; |
548
|
|
|
|
|
|
|
*#print \"SUBREF:$subref\\n\"; |
549
|
|
|
|
|
|
|
*#\$leaveloop=&Simulation::Automate::PostProcessors::$subref(\$dataset,\$i,\$dataref_postproc,\$flagsref,[\$returnvalue],\$preprocref,2); |
550
|
|
|
|
|
|
|
*#chdir '..'; |
551
|
|
|
|
|
|
|
*#print \"LEAVE: \$leaveloop\\n\"; |
552
|
|
|
|
|
|
|
*} |
553
|
|
|
|
|
|
|
*\$returnvalue=&post_run(); |
554
|
|
|
|
|
|
|
* |
555
|
|
|
|
|
|
|
"); |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
|
558
|
1
|
|
|
|
|
6
|
print MOD &strip(<<"ENDPP"); |
559
|
|
|
|
|
|
|
*chdir \$dirname; |
560
|
|
|
|
|
|
|
*my \$dataref1 = [\$nsims,\\\%data,\\\%sweepeddata,\\\%last]; |
561
|
|
|
|
|
|
|
*#&Simulation::Automate::PostProcessors::$subref(\$dataset,\$i,\$dataref1,\$flagsref,\$returnvalue,\$preprocref); |
562
|
|
|
|
|
|
|
*&prepare(\$dataset,\$i,\$dataref1,\$flagsref,\$returnvalue); |
563
|
|
|
|
|
|
|
*chdir '..'; |
564
|
|
|
|
|
|
|
ENDPP |
565
|
|
|
|
|
|
|
|
566
|
1
|
|
|
|
|
4
|
foreach my $par (reverse sort keys %{$data{$sim}}) { |
|
1
|
|
|
|
|
4
|
|
567
|
2
|
50
|
|
|
|
8
|
if ($data{$sim}{$par}=~/,/) { |
568
|
0
|
0
|
0
|
|
|
0
|
if( not exists $grouped{$par} or (exists $grouped{$par} and ($grouped{$par} eq $par))) { |
|
|
|
0
|
|
|
|
|
569
|
0
|
|
|
|
|
0
|
print MOD &strip( |
570
|
|
|
|
|
|
|
"*} #END of $par\n" |
571
|
|
|
|
|
|
|
); |
572
|
|
|
|
|
|
|
} |
573
|
|
|
|
|
|
|
} |
574
|
|
|
|
|
|
|
} |
575
|
|
|
|
|
|
|
|
576
|
1
|
|
|
|
|
5
|
print MOD &strip(<<"ENDPP"); |
577
|
|
|
|
|
|
|
*chdir \$dirname; |
578
|
|
|
|
|
|
|
*my \$dataref2 = [\$nsims,\\\%data,\\\%sweepeddata,\\\%last]; |
579
|
|
|
|
|
|
|
*#&Simulation::Automate::PostProcessors::$subref(\$dataset,\$i,\$dataref2,\$flagsref,1); |
580
|
|
|
|
|
|
|
*&prepare(\$dataset,\$i,\$dataref2,\$flagsref,1); |
581
|
|
|
|
|
|
|
*chdir '..'; |
582
|
|
|
|
|
|
|
ENDPP |
583
|
|
|
|
|
|
|
|
584
|
1
|
|
|
|
|
4
|
print MOD &strip(<<"ENDTAIL"); |
585
|
|
|
|
|
|
|
* return \$returnvalue; |
586
|
|
|
|
|
|
|
*} #END of execute_${sim}_loop |
587
|
|
|
|
|
|
|
ENDTAIL |
588
|
1
|
|
|
|
|
5
|
$data{$sim}{TITLE}=$title; |
589
|
|
|
|
|
|
|
} #END of loop over sims |
590
|
|
|
|
|
|
|
|
591
|
1
|
|
|
|
|
94
|
close MOD; |
592
|
1
|
50
|
|
|
|
4
|
print STDERR "...Done\n\n" if $verbose; |
593
|
|
|
|
|
|
|
|
594
|
1
|
|
|
|
|
8
|
return \%data; |
595
|
|
|
|
|
|
|
} #END of generate loop module |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
598
|
|
|
|
|
|
|
sub strip { |
599
|
20
|
|
|
20
|
0
|
94
|
my $line=shift; |
600
|
20
|
|
|
|
|
194
|
$line=~s/(^|\n)\*/$1/sg; |
601
|
20
|
|
|
|
|
82
|
return $line; |
602
|
|
|
|
|
|
|
} |
603
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
604
|
|
|
|
|
|
|
# |
605
|
|
|
|
|
|
|
# This subroutine takes a reference to %specific as generated by allow_multiple_sims($datafile) |
606
|
|
|
|
|
|
|
# So %multisimdata is actually %specific |
607
|
|
|
|
|
|
|
# Then, it turns this into a hash of hashes: |
608
|
|
|
|
|
|
|
# for every $sim, there's a hash with as key the parameter name and as value its value-list |
609
|
|
|
|
|
|
|
# This is %data, which is returned to $dataref in generate_loop_module() |
610
|
|
|
|
|
|
|
# |
611
|
|
|
|
|
|
|
sub fill_data_hash_multi { |
612
|
1
|
|
|
1
|
0
|
2
|
my $dataref=shift; # reference to %specific |
613
|
1
|
|
|
|
|
2
|
my %data=(); |
614
|
1
|
|
|
|
|
4
|
my %multisimdata=%$dataref; |
615
|
1
|
|
|
|
|
7
|
foreach my $sim (keys %multisimdata) { |
616
|
|
|
|
|
|
|
|
617
|
1
|
|
|
|
|
3
|
foreach (@{$multisimdata{$sim}}){ |
|
1
|
|
|
|
|
3
|
|
618
|
|
|
|
|
|
|
|
619
|
3
|
50
|
|
|
|
17
|
if(/^\s*_/) { |
|
|
50
|
|
|
|
|
|
620
|
|
|
|
|
|
|
|
621
|
0
|
|
|
|
|
0
|
my @line=();#split(/\s*=\s*/,$_); |
622
|
|
|
|
|
|
|
# changed to allow expressions with "=" |
623
|
0
|
|
|
|
|
0
|
my $line=$_; |
624
|
0
|
0
|
|
|
|
0
|
($line=~s/^([A-Z0-9_]+)?\s*=\s*//)&&($line[0]=$1); |
625
|
0
|
|
|
|
|
0
|
$line[1]=$line; |
626
|
0
|
|
|
|
|
0
|
$line[1]=~s/\s*\,\s*/,/g; |
627
|
0
|
|
|
|
|
0
|
$line[1]=~s/\s*\;\s*/;/g; |
628
|
|
|
|
|
|
|
#13082004:What if we just replace ; by , here? |
629
|
0
|
0
|
|
|
|
0
|
($line[1]!~/[a-zA-Z]/) &&($line[1]=~s/;/,/g); # if there are no expressions |
630
|
|
|
|
|
|
|
|
631
|
0
|
|
|
|
|
0
|
$data{$sim}{$line[0]}=$line[1]; |
632
|
|
|
|
|
|
|
} elsif (/:/) { |
633
|
3
|
|
|
|
|
5
|
my @line=();#split(/\s*:\s*/,$_); |
634
|
|
|
|
|
|
|
# changed to allow expressions with ":" |
635
|
3
|
|
|
|
|
5
|
my $line=$_; |
636
|
3
|
50
|
|
|
|
23
|
($line=~s/^([A-Z0-9_]+)?\s*\:\s*//)&&($line[0]=$1); |
637
|
3
|
|
|
|
|
5
|
$line[1]=$line; |
638
|
|
|
|
|
|
|
#strip trailing spaces |
639
|
3
|
|
|
|
|
9
|
$line[1]=~s/\s+$//; |
640
|
3
|
|
|
|
|
24
|
$data{$sim}{$line[0]}=$line[1]; |
641
|
|
|
|
|
|
|
} #if |
642
|
|
|
|
|
|
|
} # foreach |
643
|
|
|
|
|
|
|
} |
644
|
1
|
|
|
|
|
4
|
return \%data; |
645
|
|
|
|
|
|
|
} #END of fill_data_hash_multi |
646
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
648
|
|
|
|
|
|
|
# |
649
|
|
|
|
|
|
|
# this subroutine splits the datafile into a common part (@common) and a number |
650
|
|
|
|
|
|
|
# of simtype-specific parts ( %specific{$simtype}); then, it pushes @common onto |
651
|
|
|
|
|
|
|
# @{$specific{$simtype}} and returns \%specific |
652
|
|
|
|
|
|
|
# So every key in %specific points to an array with all variables needed for that simtype |
653
|
|
|
|
|
|
|
# |
654
|
|
|
|
|
|
|
sub allow_multiple_sims { |
655
|
1
|
|
|
1
|
0
|
7
|
my $datafile=shift; |
656
|
1
|
|
|
|
|
3
|
my @sims=(); |
657
|
1
|
|
|
|
|
2
|
my $simpart=0; |
658
|
1
|
|
|
|
|
8
|
my $simpatt='NOPATTERN'; |
659
|
1
|
|
|
|
|
4
|
my @common=(); |
660
|
1
|
|
|
|
|
7
|
my %specific=(); |
661
|
1
|
|
|
|
|
22
|
my %grouped=(); |
662
|
1
|
|
|
|
|
7
|
my $simtype='NOKEY'; |
663
|
1
|
|
|
|
|
3
|
my $skip=0; |
664
|
1
|
50
|
|
|
|
63
|
open(DATA,"<$datafile")|| die "Can't open $datafile\n"; |
665
|
|
|
|
|
|
|
|
666
|
1
|
|
|
|
|
35
|
while() { |
667
|
|
|
|
|
|
|
|
668
|
3
|
50
|
|
|
|
14
|
/^\s*\#/ && next; |
669
|
3
|
50
|
|
|
|
21
|
/^\s*$/ && next; |
670
|
3
|
|
|
|
|
5
|
chomp; |
671
|
|
|
|
|
|
|
# allow include files for configuration variables |
672
|
3
|
50
|
|
|
|
9
|
/INCL.*\s*:/ && do { |
673
|
0
|
|
|
|
|
0
|
my $incl=$_; |
674
|
0
|
|
|
|
|
0
|
$incl=~s/^.*\:\s*//; |
675
|
0
|
|
|
|
|
0
|
$incl=~s/\s+$//; |
676
|
0
|
0
|
|
|
|
0
|
my @incl=($incl=~/[,;]/)?split(/\s*[,;]\s*/,$incl):($incl); |
677
|
0
|
|
|
|
|
0
|
foreach my $inclf (@incl) { |
678
|
0
|
0
|
|
|
|
0
|
open(INCL,"<$inclf")|| die $!; |
679
|
0
|
|
|
|
|
0
|
while(my $incl=) { |
680
|
0
|
0
|
|
|
|
0
|
$incl=~/^\s*\#/ && next; |
681
|
0
|
0
|
|
|
|
0
|
$incl=~/^\s*$/ && next; |
682
|
0
|
|
|
|
|
0
|
chomp $incl; |
683
|
|
|
|
|
|
|
# only configuration variables in include files! |
684
|
0
|
0
|
|
|
|
0
|
($incl=~/:/) && do {push @common,$incl}; |
|
0
|
|
|
|
|
0
|
|
685
|
|
|
|
|
|
|
} |
686
|
0
|
|
|
|
|
0
|
close INCL; |
687
|
|
|
|
|
|
|
} |
688
|
|
|
|
|
|
|
}; # END of allow INCL files |
689
|
|
|
|
|
|
|
#print STDERR "$_\n"; |
690
|
3
|
|
|
|
|
8
|
s/(\#.*)//; # strip comments |
691
|
3
|
|
|
|
|
7
|
s/[;,]\s*$//; # be tolerant: remove separators at end of line |
692
|
3
|
100
|
33
|
|
|
125
|
if(/SIM(TYPE|NAME|ULATION|TEMPL)|\bTEMPLATE\s*:/) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
693
|
1
|
|
|
|
|
7
|
my $sims=$_; |
694
|
1
|
|
|
|
|
3
|
s/TEMPLATE/SIMULATION/; |
695
|
1
|
|
|
|
|
2
|
s/\.\w+$//; |
696
|
1
|
|
|
|
|
12
|
(my $par,$simpatt)=split(/\s*:\s*/,$sims); |
697
|
1
|
|
|
|
|
3
|
$simpatt=~s/\s*\,\s*/|/g; |
698
|
1
|
|
|
|
|
3
|
$simpatt=~s/\s+//g; |
699
|
1
|
|
|
|
|
3
|
@sims=split(/\|/,$simpatt); |
700
|
1
|
|
|
|
|
7
|
my $ext=''; |
701
|
1
|
|
|
|
|
7
|
foreach my $sim (@sims){ |
702
|
1
|
|
|
|
|
3
|
$sim=~s/(\.\w+)$//; |
703
|
1
|
|
|
|
|
16
|
$ext=$1; |
704
|
|
|
|
|
|
|
}; |
705
|
1
|
50
|
33
|
|
|
9
|
if($ext && $ext=~/^\./){ |
706
|
0
|
|
|
|
|
0
|
push @common,"TEMPL: $ext\n"; |
707
|
|
|
|
|
|
|
} |
708
|
1
|
|
|
|
|
3
|
$simpatt=join('|',@sims); |
709
|
1
|
|
|
|
|
4
|
$simpatt='('.$simpatt.')'; |
710
|
|
|
|
|
|
|
} elsif(/$simpatt/) { |
711
|
0
|
|
|
|
|
0
|
$skip=0; |
712
|
0
|
|
|
|
|
0
|
$simtype=$1; |
713
|
|
|
|
|
|
|
#$simtype=~s/\.\w+$//; |
714
|
0
|
|
|
|
|
0
|
$simpart=1 |
715
|
|
|
|
|
|
|
} elsif(/^\s*[a-zA-Z]/&&!/:/) { |
716
|
0
|
|
|
|
|
0
|
$simpart=0; |
717
|
0
|
|
|
|
|
0
|
$skip=1; |
718
|
0
|
|
|
|
|
0
|
print STDERR "$_: Not present in simlist. Skipping data.\n"; |
719
|
|
|
|
|
|
|
} |
720
|
3
|
50
|
|
|
|
11
|
/^\s*GROUP\s*:\s*([\_A-Z0-9\,\;\s]+)$/ && do { |
721
|
0
|
|
|
|
|
0
|
my $groupline=$1; |
722
|
|
|
|
|
|
|
#This assumes a single GROUP line with a semicol-separated list of comma-separated values |
723
|
|
|
|
|
|
|
#Too complex. Just allow multiple GROUP lines, one per group |
724
|
|
|
|
|
|
|
#my @grouped=split(/\s*\;\s*/,$groupline); |
725
|
|
|
|
|
|
|
#foreach my $group (@grouped){ |
726
|
|
|
|
|
|
|
#my @groupline=split(/\s*\,\s*/,$group); |
727
|
|
|
|
|
|
|
#foreach my $item (@groupline){ |
728
|
|
|
|
|
|
|
#$grouped{$item}=$groupline[0]; |
729
|
|
|
|
|
|
|
#} |
730
|
|
|
|
|
|
|
#} |
731
|
0
|
|
|
|
|
0
|
my @groupline=split(/\s*[\,\;]\s*/,$groupline); |
732
|
0
|
|
|
|
|
0
|
foreach my $item (@groupline){ |
733
|
0
|
|
|
|
|
0
|
$grouped{$item}=$groupline[0]; |
734
|
|
|
|
|
|
|
} |
735
|
0
|
|
|
|
|
0
|
next; |
736
|
|
|
|
|
|
|
}; |
737
|
3
|
50
|
|
|
|
10
|
if($simpart) { |
|
|
50
|
|
|
|
|
|
738
|
0
|
|
|
|
|
0
|
push @{$specific{$simtype}},$_; |
|
0
|
|
|
|
|
0
|
|
739
|
|
|
|
|
|
|
} elsif(!$skip) { |
740
|
3
|
|
|
|
|
18
|
push @common,$_; |
741
|
|
|
|
|
|
|
} else { |
742
|
0
|
|
|
|
|
0
|
print STDERR "Skipped: $_\n" ; |
743
|
|
|
|
|
|
|
} |
744
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
} #while |
746
|
1
|
|
|
|
|
14
|
close DATA; |
747
|
|
|
|
|
|
|
|
748
|
1
|
|
|
|
|
5
|
foreach my $sim (@sims) { |
749
|
1
|
|
|
|
|
6
|
push @{$specific{$sim}},@common; |
|
1
|
|
|
|
|
9
|
|
750
|
|
|
|
|
|
|
} |
751
|
|
|
|
|
|
|
|
752
|
1
|
|
|
|
|
12
|
return (\%specific,\%grouped); |
753
|
|
|
|
|
|
|
} #END of allow_multiple_sims |
754
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
755
|
|
|
|
|
|
|
# |
756
|
|
|
|
|
|
|
# this subroutine expands for-to-step lists in enumerated lists |
757
|
|
|
|
|
|
|
# |
758
|
|
|
|
|
|
|
sub expand_list { |
759
|
2
|
|
|
2
|
0
|
5
|
my $list=shift; |
760
|
2
|
|
|
|
|
3
|
$list=~s/\#.*$//; |
761
|
2
|
50
|
|
|
|
12
|
my $sep=($list=~/;/)?';':','; # |
762
|
|
|
|
|
|
|
|
763
|
2
|
|
|
|
|
40
|
my @list=split(/\s*$sep\s*/,$list); |
764
|
2
|
50
|
33
|
|
|
11
|
if(@list==3 && $list!~/[a-zA-Z]/) { # |
765
|
0
|
0
|
0
|
|
|
0
|
if( |
|
|
|
0
|
|
|
|
|
766
|
|
|
|
|
|
|
( |
767
|
|
|
|
|
|
|
($list[0]<$list[1] && $list[2]>0)||($list[0]>$list[1] && $list[2]<0) |
768
|
|
|
|
|
|
|
) && ( |
769
|
|
|
|
|
|
|
abs($list[2])
|
770
|
|
|
|
|
|
|
) |
771
|
|
|
|
|
|
|
) { |
772
|
0
|
|
|
|
|
0
|
my $start=$list[0]; |
773
|
0
|
|
|
|
|
0
|
my $stop=$list[1]; |
774
|
0
|
|
|
|
|
0
|
my $step=$list[2]; |
775
|
0
|
|
|
|
|
0
|
$list="$start"; |
776
|
0
|
|
|
|
|
0
|
my $i=$start; |
777
|
0
|
|
0
|
|
|
0
|
while(("$i" ne "$stop")&&((($stop>=0)&&($i<$stop))||(($stop<0)&&($i>$stop)))) { #yes, strange, but Perl says 0.9>0.9 is true! |
|
|
|
0
|
|
|
|
|
778
|
0
|
|
|
|
|
0
|
$i+=$step; |
779
|
0
|
|
|
|
|
0
|
$list.="$sep$i"; |
780
|
|
|
|
|
|
|
} |
781
|
|
|
|
|
|
|
#print "LIST: $list\n"; |
782
|
|
|
|
|
|
|
#die; |
783
|
|
|
|
|
|
|
} |
784
|
|
|
|
|
|
|
} |
785
|
|
|
|
|
|
|
|
786
|
2
|
|
|
|
|
10
|
return $list; |
787
|
|
|
|
|
|
|
} # END of expand_list |
788
|
|
|
|
|
|
|
#=============================================================================== |
789
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
sub execute_loop { |
791
|
1
|
|
|
1
|
0
|
2
|
my $datafilename=shift; |
792
|
1
|
|
|
|
|
3
|
my $dataset=shift; |
793
|
|
|
|
|
|
|
|
794
|
1
|
|
|
|
|
832
|
require "./Loops_$dataset.pm"; |
795
|
|
|
|
|
|
|
#eval(" |
796
|
|
|
|
|
|
|
#use Loops_$dataset; |
797
|
|
|
|
|
|
|
#"); |
798
|
|
|
|
|
|
|
|
799
|
1
|
|
|
|
|
5
|
my $simref=shift; |
800
|
1
|
|
|
|
|
3
|
my @flags=@{shift(@_)}; |
|
1
|
|
|
|
|
4
|
|
801
|
1
|
|
|
|
|
3
|
my $nosims=$flags[2]; |
802
|
1
|
|
|
|
|
2
|
my $verbose=$flags[4]; |
803
|
|
|
|
|
|
|
|
804
|
1
|
|
|
|
|
1
|
foreach my $sim (sort keys %{$simref}) { |
|
1
|
|
|
|
|
7
|
|
805
|
1
|
|
|
|
|
1
|
my $commandline=${$simref}{$sim}->{COMMAND}; |
|
1
|
|
|
|
|
4
|
|
806
|
|
|
|
|
|
|
|
807
|
1
|
50
|
|
|
|
5
|
$commandline && do { |
808
|
1
|
|
|
|
|
5
|
$commandline=~s/inputfile//i; |
809
|
1
|
|
|
|
|
4
|
$commandline=~s/outputfile//i; |
810
|
1
|
|
|
|
|
3
|
$commandline=~s/\s\-+\w+//g; |
811
|
1
|
|
|
|
|
3
|
$commandline=~s/^\s+//; |
812
|
1
|
|
|
|
|
5
|
$commandline=~s/\s+$//; |
813
|
|
|
|
|
|
|
}; |
814
|
1
|
50
|
|
|
|
9
|
my @maybe_files=($commandline)?split(/\s+/,$commandline):(); |
815
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
# extension for template files |
817
|
1
|
|
50
|
|
|
2
|
my $templ=${$simref}{$sim}->{TEMPLEXT}||${$simref}{$sim}->{TEMPL}||'.templ'; |
818
|
1
|
|
50
|
|
|
1
|
my $dev=${$simref}{$sim}->{DEVTYPE}||${$simref}{$sim}->{DEVICE}||''; |
819
|
|
|
|
|
|
|
|
820
|
1
|
|
|
|
|
4
|
my $dirname= "${sim}-$dataset"; |
821
|
|
|
|
|
|
|
|
822
|
1
|
50
|
33
|
|
|
46
|
if(-e $dirname && -d $dirname) { |
823
|
1
|
50
|
|
|
|
4
|
if ($nosims==0) { |
824
|
1
|
50
|
|
|
|
3
|
print STDERR "\n# Removing old $dirname dir\n" if $verbose; |
825
|
1
|
50
|
|
|
|
5
|
if ($verbose) { |
826
|
0
|
|
|
|
|
0
|
print `rm -Rf $dirname`; |
827
|
|
|
|
|
|
|
} else { |
828
|
1
|
|
|
|
|
5963
|
system("rm -Rf $dirname"); |
829
|
|
|
|
|
|
|
} |
830
|
|
|
|
|
|
|
} else { |
831
|
0
|
0
|
|
|
|
0
|
print STDERR "\n# Cleaning up $dirname dir\n" if $verbose; |
832
|
0
|
0
|
|
|
|
0
|
if ($verbose) { |
833
|
0
|
|
|
|
|
0
|
print `rm -f $dirname/$sim-*`; |
834
|
0
|
|
|
|
|
0
|
print `rm -f $dirname/tmp*`; |
835
|
|
|
|
|
|
|
} else { |
836
|
0
|
|
|
|
|
0
|
system("rm -f $dirname/tmp*"); |
837
|
|
|
|
|
|
|
} |
838
|
|
|
|
|
|
|
} |
839
|
|
|
|
|
|
|
} |
840
|
|
|
|
|
|
|
|
841
|
1
|
50
|
33
|
|
|
126
|
if (not -e "TEMPLATES/SIMTYPES/$sim$templ" and not -e "TEMPLATES/$sim$templ" ) { |
842
|
|
|
|
|
|
|
|
843
|
0
|
|
|
|
|
0
|
print STDERR "No templates for simulation $sim. Skipped.\n";# if $verbose; #always warn! |
844
|
0
|
|
|
|
|
0
|
next; |
845
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
} else { |
847
|
|
|
|
|
|
|
#if the template in under TEMPLATES, make a simlink to TEMPLATES/SIMTYPES |
848
|
1
|
50
|
33
|
|
|
47
|
if (-e "TEMPLATES/$sim$templ" and not -l "TEMPLATES/SIMTYPES/$sim$templ" ) { |
849
|
0
|
|
|
|
|
0
|
system("cd TEMPLATES/SIMTYPES && ln -s ../$sim$templ ."); |
850
|
|
|
|
|
|
|
} |
851
|
1
|
|
|
|
|
141
|
mkdir $dirname, 0755; |
852
|
|
|
|
|
|
|
|
853
|
1
|
50
|
|
|
|
28
|
if (-e "TEMPLATES/SIMTYPES/$sim$templ") { |
854
|
1
|
|
|
|
|
10783
|
system("cp TEMPLATES/SIMTYPES/$sim$templ $dirname"); |
855
|
|
|
|
|
|
|
} else { |
856
|
0
|
|
|
|
|
0
|
die "There's no simulation template for $sim in TEMPLATES/SIMTYPES\n"; |
857
|
|
|
|
|
|
|
} |
858
|
1
|
50
|
|
|
|
59
|
if($dev){ |
859
|
0
|
0
|
|
|
|
0
|
if (-e "TEMPLATES/DEVTYPES/$dev$templ") { |
860
|
0
|
|
|
|
|
0
|
system("cp TEMPLATES/DEVTYPES/$dev$templ $dirname"); |
861
|
|
|
|
|
|
|
} else { |
862
|
0
|
0
|
|
|
|
0
|
print STDERR "No device template for $dev in TEMPLATES/DEVTYPES.\n" if $verbose; |
863
|
|
|
|
|
|
|
} |
864
|
|
|
|
|
|
|
} |
865
|
|
|
|
|
|
|
# any file with this pattern is copied to the rundir. |
866
|
1
|
50
|
|
|
|
82
|
if (-d "SOURCES") { |
867
|
1
|
50
|
|
|
|
185
|
if(){ |
868
|
0
|
|
|
|
|
0
|
system("cp SOURCES/$sim* $dirname"); |
869
|
|
|
|
|
|
|
} |
870
|
1
|
|
|
|
|
25
|
foreach my $maybe_file(@maybe_files){ |
871
|
1
|
50
|
33
|
|
|
61
|
if(-e "SOURCES/$maybe_file" and not -e "$dirname/$maybe_file"){ |
872
|
0
|
|
|
|
|
0
|
system("cp SOURCES/$maybe_file $dirname/$maybe_file"); |
873
|
|
|
|
|
|
|
} |
874
|
|
|
|
|
|
|
} |
875
|
|
|
|
|
|
|
} |
876
|
|
|
|
|
|
|
} |
877
|
1
|
50
|
|
|
|
11
|
print STDERR "#" x 80,"\n" if $verbose; |
878
|
1
|
50
|
|
|
|
9
|
print STDERR "#\n" if $verbose; |
879
|
1
|
50
|
|
|
|
7
|
print STDERR "# Simulation type: $sim, device dir ".`pwd`."#\n" if $verbose; |
880
|
1
|
50
|
|
|
|
8
|
print STDERR "#" x 80,"\n" if $verbose; |
881
|
|
|
|
|
|
|
|
882
|
1
|
|
|
|
|
338
|
eval('&Loops_'.$dataset.'::execute_'.$sim.'_loop($dataset,\@flags);'); |
883
|
|
|
|
|
|
|
|
884
|
|
|
|
|
|
|
} #sims |
885
|
1
|
|
|
|
|
36
|
return 1; |
886
|
|
|
|
|
|
|
} #END of &execute_loop |
887
|
|
|
|
|
|
|
#============================================================================== |
888
|
|
|
|
|
|
|
#Routines to support script for simulation automation. |
889
|
|
|
|
|
|
|
#The function &main() is called from the innermost loop of |
890
|
|
|
|
|
|
|
#Loops_*.pm |
891
|
|
|
|
|
|
|
push @Simulation::Automate::EXPORT, qw( |
892
|
|
|
|
|
|
|
main |
893
|
|
|
|
|
|
|
pre_run |
894
|
|
|
|
|
|
|
run |
895
|
|
|
|
|
|
|
post_run |
896
|
|
|
|
|
|
|
); |
897
|
|
|
|
|
|
|
|
898
|
2
|
|
|
2
|
|
1274
|
use Simulation::Automate::Analysis; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
576
|
|
899
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
################################################################################## |
901
|
|
|
|
|
|
|
my $simpid=undef; |
902
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
|
905
|
|
|
|
|
|
|
#======================================================================================== |
906
|
|
|
|
|
|
|
# NEW IMPLEMENTATION TO ALLOW POSTPROCESSING AFTER EVERY ELEMENT IN SWEEP |
907
|
|
|
|
|
|
|
#======================================================================================== |
908
|
|
|
|
|
|
|
my @results=(); |
909
|
|
|
|
|
|
|
my @sweepvarnames=(); |
910
|
|
|
|
|
|
|
my %simdata=(); |
911
|
|
|
|
|
|
|
my $simtype='NO_SIMTYPE'; |
912
|
|
|
|
|
|
|
my $dataset='NO_DATASET'; |
913
|
|
|
|
|
|
|
my $count=0; |
914
|
|
|
|
|
|
|
my $batch; my $interactive; my $nosims; my $plot; my $verbose; my $warn; |
915
|
|
|
|
|
|
|
my $output_filter_pattern= '.*'; |
916
|
|
|
|
|
|
|
my $command='perl inputfile outputfile'; |
917
|
|
|
|
|
|
|
my $dirname= 'NO_DIRNAME'; |
918
|
|
|
|
|
|
|
my $devtype='NO_DEVTYPE'; |
919
|
|
|
|
|
|
|
my $simtitle='NO_TITLE'; |
920
|
|
|
|
|
|
|
my $title="#$devtype $simtype simulation\n"; |
921
|
|
|
|
|
|
|
my $ext='.templ'; |
922
|
|
|
|
|
|
|
my $extin='.pl'; |
923
|
|
|
|
|
|
|
my $workingdir = 'NO_WORKINGDIR'; |
924
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
925
|
|
|
|
|
|
|
|
926
|
|
|
|
|
|
|
sub pre_run { |
927
|
|
|
|
|
|
|
#called as:&pre_run(\$dataset,\$i,\$dataref,\$flagsref); |
928
|
1
|
|
|
1
|
0
|
6
|
$dataset=shift; |
929
|
1
|
|
|
|
|
4
|
$count=shift; |
930
|
1
|
|
|
|
|
1
|
my $dataref=shift; |
931
|
1
|
|
|
|
|
2
|
my $flagsref=shift; |
932
|
|
|
|
|
|
|
|
933
|
2
|
|
|
2
|
|
14
|
use Cwd; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
6786
|
|
934
|
|
|
|
|
|
|
|
935
|
|
|
|
|
|
|
#extract flags from flagsref |
936
|
1
|
|
|
|
|
2
|
($batch,$interactive,$nosims,$plot,$verbose,$warn)=@{$flagsref}; |
|
1
|
|
|
|
|
5
|
|
937
|
|
|
|
|
|
|
#extract number of sims and ref to simdata from dataref |
938
|
1
|
|
|
|
|
2
|
(my $nsims, my $simdataref)=@{$dataref}; |
|
1
|
|
|
|
|
3
|
|
939
|
|
|
|
|
|
|
#put simdata in a hash |
940
|
1
|
|
|
|
|
2
|
%simdata=%{$simdataref}; |
|
1
|
|
|
|
|
10
|
|
941
|
|
|
|
|
|
|
|
942
|
1
|
50
|
|
|
|
5
|
print STDERR '#',"-" x 79, "\n" if $verbose; |
943
|
|
|
|
|
|
|
|
944
|
1
|
|
50
|
|
|
9
|
$command=$simdata{COMMAND}||'perl inputfile outputfile'; |
945
|
1
|
|
50
|
|
|
13
|
$output_filter_pattern=$simdata{OUTPUT_FILTER_PATTERN}|| '.*'; |
946
|
1
|
|
0
|
|
|
10
|
$simtype=$simdata{SIMTYPE}||$simdata{SIMNAME}||$simdata{SIMULATION}||$simdata{TEMPLATE}||$simdata{SIMTEMPL}||''; |
947
|
|
|
|
|
|
|
#$simtype=~s/\.\w+$//; |
948
|
1
|
|
|
|
|
7
|
$dirname= "${simtype}-$dataset"; |
949
|
1
|
|
50
|
|
|
19
|
$devtype=$simdata{DEVTYPE}||$simdata{DEVICE}||$simdata{DEVTEMPL}||''; |
950
|
1
|
|
|
|
|
5
|
$simtitle=$simdata{TITLE}; |
951
|
1
|
|
|
|
|
5
|
@sweepvarnames=(); |
952
|
1
|
|
|
|
|
7
|
foreach my $key (keys %simdata) { |
953
|
4
|
50
|
|
|
|
14
|
($key!~/^_/) && next; |
954
|
0
|
0
|
|
|
|
0
|
($simtitle=~/$key/) && do { |
955
|
0
|
|
|
|
|
0
|
$simtitle=~s/$key/$key:$simdata{$key}/; |
956
|
|
|
|
|
|
|
}; |
957
|
0
|
|
|
|
|
0
|
my $ndata=@{$simdata{$key}}; |
|
0
|
|
|
|
|
0
|
|
958
|
0
|
0
|
|
|
|
0
|
if($ndata>1) { |
959
|
0
|
|
|
|
|
0
|
push @sweepvarnames,$key; |
960
|
|
|
|
|
|
|
} |
961
|
|
|
|
|
|
|
} |
962
|
1
|
|
33
|
|
|
11
|
$title="#$simtitle\n"||"#$devtype $simtype simulation\n"; |
963
|
1
|
|
50
|
|
|
13
|
$ext=$simdata{TEMPLEXT}||$simdata{TEMPL}||'.templ'; |
964
|
1
|
|
50
|
|
|
7
|
$extin=$simdata{EXT}||'.pl'; |
965
|
1
|
|
|
|
|
8765
|
$workingdir =cwd(); |
966
|
1
|
|
|
|
|
64
|
chdir "$workingdir/$dirname"; |
967
|
1
|
|
|
|
|
29
|
return $nsims; |
968
|
|
|
|
|
|
|
} #END of pre_run() |
969
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
970
|
|
|
|
|
|
|
|
971
|
|
|
|
|
|
|
sub run { |
972
|
|
|
|
|
|
|
#called as:&run(\$nsims,\$simn); |
973
|
1
|
|
|
1
|
1
|
3
|
my $nsims=shift; |
974
|
1
|
|
|
|
|
6
|
my $simn=shift; |
975
|
|
|
|
|
|
|
|
976
|
|
|
|
|
|
|
## INPUT FILE CREATION |
977
|
|
|
|
|
|
|
|
978
|
1
|
50
|
|
|
|
15
|
if($nsims==1){$simn=''} else { |
|
1
|
|
|
|
|
11
|
|
979
|
|
|
|
|
|
|
# print STDERR "# Subrun $simn of $nsims \n" if $verbose; |
980
|
0
|
0
|
|
|
|
0
|
if($simn==1){ |
981
|
0
|
0
|
|
|
|
0
|
print STDERR "# Sweep $nsims values for " if $verbose; |
982
|
0
|
|
|
|
|
0
|
foreach my $sweepvarname(@sweepvarnames){ |
983
|
0
|
0
|
|
|
|
0
|
print STDERR "$sweepvarname " if $verbose; |
984
|
|
|
|
|
|
|
} |
985
|
0
|
0
|
|
|
|
0
|
print STDERR ":\n" if $verbose; |
986
|
|
|
|
|
|
|
} |
987
|
0
|
|
|
|
|
0
|
foreach my $sweepvarname(@sweepvarnames){ |
988
|
0
|
0
|
|
|
|
0
|
print STDERR $simdata{$sweepvarname}->[$simn-1],' ' if $verbose; |
989
|
|
|
|
|
|
|
# print STDERR " $sweepvarname = ",$simdata{$sweepvarname}->[$simn-1] if $verbose; |
990
|
|
|
|
|
|
|
} |
991
|
0
|
0
|
|
|
|
0
|
print STDERR " \n" if $verbose; |
992
|
|
|
|
|
|
|
|
993
|
|
|
|
|
|
|
# foreach my $sweepvarname(@sweepvarnames){ |
994
|
|
|
|
|
|
|
# print STDERR " $sweepvarname = ",$simdata{$sweepvarname}->[$simn-1] if $verbose; |
995
|
|
|
|
|
|
|
#} |
996
|
|
|
|
|
|
|
# |
997
|
|
|
|
|
|
|
} |
998
|
1
|
|
|
|
|
13
|
my $inputfile= "${simtype}_${simn}$extin"; |
999
|
1
|
|
|
|
|
8
|
my $outputfile= "${simtype}_C${count}_${simn}.out"; |
1000
|
1
|
|
|
|
|
8
|
my $commandline=$command; |
1001
|
1
|
|
|
|
|
16
|
$commandline=~s/inputfile/$inputfile/ig; |
1002
|
1
|
|
|
|
|
178
|
$commandline=~s/outputfile/$outputfile/ig; |
1003
|
|
|
|
|
|
|
|
1004
|
1
|
|
|
|
|
130
|
open (NEW, ">$inputfile"); |
1005
|
|
|
|
|
|
|
|
1006
|
1
|
|
|
|
|
9
|
foreach my $type ($devtype,$simtype) { |
1007
|
2
|
100
|
|
|
|
12
|
if($type) { |
1008
|
1
|
50
|
|
|
|
4
|
my $nsim=($simn eq '')?0:$simn; |
1009
|
1
|
|
|
|
|
13
|
&gen_sim_script ($nsim-1,"$simtype$ext",\%simdata,\*NEW,$dataset,$warn); |
1010
|
|
|
|
|
|
|
} |
1011
|
|
|
|
|
|
|
} # device and simulation templates |
1012
|
1
|
|
|
|
|
55
|
close (NEW); |
1013
|
|
|
|
|
|
|
|
1014
|
1
|
50
|
|
|
|
5
|
if($nosims==0) { |
1015
|
1
|
50
|
|
|
|
4
|
if($verbose) { |
1016
|
0
|
0
|
|
|
|
0
|
if (!defined($simpid = fork())) { |
|
|
0
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
# fork returned undef, so failed |
1018
|
0
|
|
|
|
|
0
|
die "cannot fork: $!"; |
1019
|
|
|
|
|
|
|
} elsif ($simpid == 0) { |
1020
|
|
|
|
|
|
|
# fork returned 0, so this branch is the child |
1021
|
0
|
|
|
|
|
0
|
exec("$commandline"); |
1022
|
|
|
|
|
|
|
# if the exec fails, fall through to the next statement |
1023
|
0
|
|
|
|
|
0
|
die "can't exec $commandline : $!"; |
1024
|
|
|
|
|
|
|
} else { |
1025
|
|
|
|
|
|
|
# fork returned neither 0 nor undef, |
1026
|
|
|
|
|
|
|
# so this branch is the parent |
1027
|
0
|
|
|
|
|
0
|
waitpid($simpid, 0); |
1028
|
|
|
|
|
|
|
} |
1029
|
|
|
|
|
|
|
} else { # not verbose |
1030
|
1
|
50
|
|
|
|
5
|
print STDERR "\n" if $verbose; |
1031
|
1
|
|
50
|
|
|
3915
|
$simpid = open(SIM, "$commandline 2>&1 |") || die "can't fork: $!"; |
1032
|
1
|
|
|
|
|
118
|
open(LOG,">simlog"); |
1033
|
1
|
|
|
|
|
1317238
|
while () { |
1034
|
6
|
|
|
|
|
36
|
print LOG; |
1035
|
6
|
50
|
|
|
|
55
|
/$output_filter_pattern/ && do { |
1036
|
6
|
|
|
|
|
7165
|
print STDERR;# if $verbose; |
1037
|
|
|
|
|
|
|
}; |
1038
|
|
|
|
|
|
|
} # while sinulation is running |
1039
|
1
|
|
|
|
|
119
|
close LOG; |
1040
|
1
|
|
|
|
|
19
|
my $ppid=getpgrp($simpid); |
1041
|
1
|
50
|
|
|
|
9
|
if(not $ppid) { |
1042
|
0
|
0
|
|
|
|
0
|
close SIM || die "Trouble with $commandline: $! $?"; |
1043
|
|
|
|
|
|
|
} |
1044
|
1
|
50
|
|
|
|
6
|
print STDERR "\n" if $verbose; |
1045
|
|
|
|
|
|
|
} #verbose or not |
1046
|
|
|
|
|
|
|
|
1047
|
1
|
50
|
|
|
|
7
|
if($nsims>1) { |
1048
|
|
|
|
|
|
|
#Postprocessing |
1049
|
0
|
|
|
|
|
0
|
&egrep($output_filter_pattern,"${simtype}_C${count}_${simn}.out",'>>',"${simtype}_C${count}_.out"); |
1050
|
|
|
|
|
|
|
} |
1051
|
|
|
|
|
|
|
} # if simulations not disabled |
1052
|
1
|
50
|
|
|
|
5
|
my $i=($nsims>1)?$simn-1:0; |
1053
|
1
|
|
|
|
|
58
|
open(RES,"<${simtype}_C${count}_${simn}.out"); |
1054
|
1
|
|
|
|
|
30
|
$results[$i]=; |
1055
|
1
|
|
|
|
|
4
|
my $another=; # This takes the next line, if any, |
1056
|
1
|
50
|
|
|
|
7
|
if($another) { # and if there is one, it assigns the filename to $results[$i] |
1057
|
1
|
|
|
|
|
4
|
$results[$i]="${simtype}_C${count}_${simn}.out"; |
1058
|
|
|
|
|
|
|
} |
1059
|
1
|
|
|
|
|
15
|
close RES; |
1060
|
|
|
|
|
|
|
|
1061
|
|
|
|
|
|
|
#no need to return @results, it's a package global now. Maybe return $results[$i], makes more sense. |
1062
|
1
|
|
|
|
|
3
|
my $result= $results[$i]; |
1063
|
1
|
|
|
|
|
5
|
chomp $result; |
1064
|
1
|
|
|
|
|
44
|
return $result; # PostProcessors are only called after &main() exits. |
1065
|
|
|
|
|
|
|
} # END of run() |
1066
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
1067
|
|
|
|
|
|
|
sub post_run { |
1068
|
|
|
|
|
|
|
#called as:&post_run(); |
1069
|
1
|
50
|
|
1
|
0
|
6
|
if($nosims==0){ |
1070
|
|
|
|
|
|
|
#Postprocessing after sweep |
1071
|
1
|
|
|
|
|
21
|
&egrep($output_filter_pattern, "${simtype}_C${count}_.out", '>>', "${simtype}_C$count.res"); |
1072
|
1
|
50
|
|
|
|
23
|
if( $results[0]=~/${simtype}_C\d+.*\.out/) { |
1073
|
1
|
|
|
|
|
28
|
open(RES,"${simtype}_C$count.res"); |
1074
|
1
|
|
|
|
|
21
|
@results=; |
1075
|
1
|
|
|
|
|
11
|
close RES; |
1076
|
|
|
|
|
|
|
} |
1077
|
|
|
|
|
|
|
} |
1078
|
1
|
|
|
|
|
29
|
chdir "$workingdir"; |
1079
|
|
|
|
|
|
|
|
1080
|
1
|
|
|
|
|
6
|
return \@results; # PostProcessors are only called after &main() exits. |
1081
|
|
|
|
|
|
|
|
1082
|
|
|
|
|
|
|
} # END of post_run() |
1083
|
|
|
|
|
|
|
#============================================================================== |
1084
|
|
|
|
|
|
|
|
1085
|
|
|
|
|
|
|
#print STDERR "\n","#" x 80,"\n#\t\t\tSynSim simulation automation tool\n#\n# (c) Wim Vanderbauwhede 2000,2002-2003. All rights reserved.\n# This program is free software; you can redistribute it and/or modify it\n# under the same terms as Perl itself.\n#\n","#" x 80,"\n"; |
1086
|
|
|
|
|
|
|
|
1087
|
|
|
|
|
|
|
#------------------------------------------- |
1088
|
|
|
|
|
|
|
# SUBROUTINES used by main, pre_run, run, post_run |
1089
|
|
|
|
|
|
|
#------------------------------------------- |
1090
|
|
|
|
|
|
|
|
1091
|
|
|
|
|
|
|
#-------------------------------------- |
1092
|
|
|
|
|
|
|
# GENERATION OF THE SIMULATION SCRIPT |
1093
|
|
|
|
|
|
|
#-------------------------------------- |
1094
|
|
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
#WV What happens: the templates for _SIMTYPE are read in |
1096
|
|
|
|
|
|
|
#WV and the variables are substituted with the values from the .data file |
1097
|
|
|
|
|
|
|
|
1098
|
|
|
|
|
|
|
sub gen_sim_script { |
1099
|
|
|
|
|
|
|
|
1100
|
1
|
|
|
1
|
0
|
2
|
my $nsim=shift; |
1101
|
1
|
|
|
|
|
2
|
my $templfilename=shift; |
1102
|
1
|
|
|
|
|
1
|
my $simdataref=shift; |
1103
|
1
|
|
|
|
|
2
|
my %simdata=%{$simdataref}; |
|
1
|
|
|
|
|
28
|
|
1104
|
1
|
|
|
|
|
2
|
my $fh=shift; |
1105
|
1
|
|
|
|
|
2
|
my $dataset=shift; |
1106
|
1
|
|
|
|
|
3
|
my $warn=shift; |
1107
|
1
|
|
|
|
|
2
|
my %exprdata=(); |
1108
|
1
|
|
|
|
|
2
|
my %keywords=(); |
1109
|
1
|
|
|
|
|
10
|
foreach my $key ( sort keys %simdata) { |
1110
|
|
|
|
|
|
|
#make sure substitutions happen in keyword values too |
1111
|
4
|
50
|
|
|
|
12
|
if ($key!~/^_/ ) { |
1112
|
4
|
50
|
|
|
|
12
|
if( $simdata{$key}=~/^_/) { |
1113
|
0
|
|
|
|
|
0
|
my $parameter=$simdata{$key}; |
1114
|
0
|
|
|
|
|
0
|
${$keywords{$parameter}}{$key}=1; |
|
0
|
|
|
|
|
0
|
|
1115
|
|
|
|
|
|
|
} |
1116
|
4
|
|
|
|
|
7
|
next; |
1117
|
|
|
|
|
|
|
} |
1118
|
|
|
|
|
|
|
|
1119
|
0
|
0
|
|
|
|
0
|
if(@{$simdata{$key}}==1) { |
|
0
|
|
|
|
|
0
|
|
1120
|
0
|
|
|
|
|
0
|
$exprdata{$key}=&check_for_expressions(\%simdata,$key,$nsim); |
1121
|
0
|
|
|
|
|
0
|
foreach my $keyword (keys %{$keywords{$key}}) { |
|
0
|
|
|
|
|
0
|
|
1122
|
0
|
|
|
|
|
0
|
$simdata{$keyword}=$exprdata{$key}; |
1123
|
|
|
|
|
|
|
} |
1124
|
|
|
|
|
|
|
} # if..else |
1125
|
|
|
|
|
|
|
} # foreach |
1126
|
|
|
|
|
|
|
|
1127
|
|
|
|
|
|
|
# OPEN TEMPLATE |
1128
|
1
|
50
|
|
|
|
36
|
open (TEMPL, "<$templfilename")||die "Can't open $templfilename\n"; |
1129
|
1
|
|
|
|
|
18
|
while (my $line = ) { |
1130
|
17
|
|
|
|
|
31
|
foreach my $key (keys %simdata) { |
1131
|
68
|
50
|
|
|
|
130
|
($key!~/^_/) && next; |
1132
|
0
|
|
|
|
|
0
|
my $ndata=@{$simdata{$key}}; |
|
0
|
|
|
|
|
0
|
|
1133
|
0
|
0
|
|
|
|
0
|
if($ndata>1) { |
1134
|
0
|
0
|
|
|
|
0
|
if($line =~ s/$key(?!\w)/$simdata{$key}->[$nsim]/g){ |
1135
|
|
|
|
|
|
|
#print STDERR "# $key = ",$simdata{$key}->[$nsim],"\n" if $warn; |
1136
|
|
|
|
|
|
|
} |
1137
|
|
|
|
|
|
|
} else { |
1138
|
|
|
|
|
|
|
#my $simdata=&check_for_expressions(\%simdata,$key,$nsim); |
1139
|
|
|
|
|
|
|
#A dangerous addidtion to make SynSim handle words |
1140
|
0
|
|
0
|
|
|
0
|
$exprdata{$key}||=$simdata{$key}->[0]; |
1141
|
0
|
|
|
|
|
0
|
$line =~ s/$key(?!\w)/$exprdata{$key}/g; |
1142
|
|
|
|
|
|
|
#print STDERR "# $key = ",$simdata{$key}->[0],"\nLINE:$line\n" if $warn; |
1143
|
|
|
|
|
|
|
} # if..else |
1144
|
|
|
|
|
|
|
} # foreach |
1145
|
|
|
|
|
|
|
|
1146
|
|
|
|
|
|
|
# check for undefined variables |
1147
|
17
|
|
33
|
|
|
48
|
while($line=~/\b(_\w+?)\b/&&$line!~/$1\$/) { |
1148
|
0
|
|
|
|
|
0
|
my $nondefvar=$1; |
1149
|
0
|
|
|
|
|
0
|
$line=~s/$nondefvar/0/g; # All undefined vars substituted by 0 |
1150
|
0
|
0
|
|
|
|
0
|
print STDERR "\nWarning: $nondefvar ($templfilename) not defined in $dataset.\n" if $warn; |
1151
|
|
|
|
|
|
|
} # if some parameter is still there |
1152
|
17
|
|
|
|
|
62
|
print $fh $line; |
1153
|
|
|
|
|
|
|
} # while |
1154
|
1
|
|
|
|
|
16
|
close TEMPL; |
1155
|
|
|
|
|
|
|
|
1156
|
|
|
|
|
|
|
} # END OF gen_sim_script |
1157
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
1158
|
|
|
|
|
|
|
sub egrep { |
1159
|
1
|
|
|
1
|
0
|
5
|
my $pattern=shift; |
1160
|
1
|
|
|
|
|
2
|
my $infile=shift; |
1161
|
1
|
|
|
|
|
5
|
my $mode=shift; |
1162
|
1
|
|
|
|
|
1
|
my $outfile=shift; |
1163
|
1
|
|
|
|
|
28
|
open(IN,"<$infile"); |
1164
|
1
|
|
|
|
|
30
|
open(OUT,"$mode$outfile"); |
1165
|
1
|
|
|
|
|
46
|
print OUT grep /$pattern/,; |
1166
|
|
|
|
|
|
|
|
1167
|
1
|
|
|
|
|
13
|
close IN; |
1168
|
1
|
|
|
|
|
25
|
close OUT; |
1169
|
|
|
|
|
|
|
} |
1170
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
1171
|
|
|
|
|
|
|
sub check_for_expressions { |
1172
|
0
|
|
|
0
|
0
|
|
my $dataref=shift; |
1173
|
0
|
|
|
|
|
|
my $key=shift; |
1174
|
0
|
|
|
|
|
|
my $nsim=shift; |
1175
|
0
|
|
|
|
|
|
my %simdata=%{$dataref}; |
|
0
|
|
|
|
|
|
|
1176
|
0
|
|
|
|
|
|
my $expr=$simdata{$key}->[0]; |
1177
|
0
|
0
|
|
|
|
|
if($expr=~/(_[A-Z_]+)/) { # was "if" |
1178
|
0
|
|
|
|
|
|
while($expr=~/(_[A-Z_]+)/) { # was "if" |
1179
|
|
|
|
|
|
|
#variable contains other variables |
1180
|
|
|
|
|
|
|
#_A =3*log(_B)+_C*10-_D**2 |
1181
|
|
|
|
|
|
|
#_A =3 ;log;_B;;_C;10;_D;;2 |
1182
|
0
|
|
|
|
|
|
my @maybevars=split(/[\ \*\+\-\/\^\(\)\[\]\{\}\?\:\=\>\<]+/,$expr); |
1183
|
0
|
|
|
|
|
|
my @vars=(); |
1184
|
0
|
|
|
|
|
|
foreach my $maybevar ( @maybevars){ |
1185
|
0
|
0
|
|
|
|
|
($maybevar=~/_[A-Z]+/)&& push @vars,$maybevar; |
1186
|
|
|
|
|
|
|
} |
1187
|
0
|
|
|
|
|
|
foreach my $var (@vars) { |
1188
|
0
|
0
|
|
|
|
|
my $simn=(@{$simdata{$var}}==1)?0:$nsim; |
|
0
|
|
|
|
|
|
|
1189
|
0
|
|
|
|
|
|
$expr=~s/$var/$simdata{$var}->[$simn]/g; |
1190
|
|
|
|
|
|
|
} |
1191
|
|
|
|
|
|
|
} |
1192
|
|
|
|
|
|
|
#print STDERR "$key=$expr=>",eval($expr),"\n"; |
1193
|
|
|
|
|
|
|
} |
1194
|
0
|
|
|
|
|
|
return eval($expr); |
1195
|
|
|
|
|
|
|
} |
1196
|
|
|
|
|
|
|
|
1197
|
|
|
|
|
|
|
################################################################################ |
1198
|
|
|
|
|
|
|
# |
1199
|
|
|
|
|
|
|
# These routines are not used by synsim |
1200
|
|
|
|
|
|
|
# They are used by make install |
1201
|
|
|
|
|
|
|
# |
1202
|
|
|
|
|
|
|
################################################################################ |
1203
|
|
|
|
|
|
|
|
1204
|
|
|
|
|
|
|
# Create simulation directory etc. |
1205
|
|
|
|
|
|
|
sub setup { |
1206
|
|
|
|
|
|
|
|
1207
|
0
|
|
|
0
|
0
|
|
my $HOME=$ENV{HOME}; |
1208
|
0
|
|
|
|
|
|
print "Local SinSym directory? [$HOME/SynSim]:"; |
1209
|
0
|
|
|
|
|
|
my $synsimroot=; |
1210
|
0
|
|
|
|
|
|
chomp $synsimroot; |
1211
|
0
|
0
|
|
|
|
|
if(not $synsimroot){$synsimroot="$HOME/SynSim"} |
|
0
|
|
|
|
|
|
|
1212
|
0
|
0
|
|
|
|
|
if($synsimroot!~/^\//) { |
1213
|
0
|
|
|
|
|
|
print "The directory $synsimroot will be created in $HOME\n"; |
1214
|
0
|
|
|
|
|
|
$synsimroot="$HOME/$synsimroot" |
1215
|
|
|
|
|
|
|
} |
1216
|
|
|
|
|
|
|
|
1217
|
0
|
0
|
|
|
|
|
if(not -d "$synsimroot"){ |
1218
|
0
|
|
|
|
|
|
mkdir "$synsimroot", 0755; |
1219
|
|
|
|
|
|
|
} |
1220
|
|
|
|
|
|
|
|
1221
|
|
|
|
|
|
|
|
1222
|
0
|
|
|
|
|
|
print "Simulation project directory? [SynSimProject]:"; |
1223
|
0
|
|
|
|
|
|
my $project=; |
1224
|
0
|
|
|
|
|
|
chomp $project; |
1225
|
0
|
0
|
|
|
|
|
if(not $project){$project='SynSimProject'} |
|
0
|
|
|
|
|
|
|
1226
|
|
|
|
|
|
|
|
1227
|
|
|
|
|
|
|
|
1228
|
0
|
|
|
|
|
|
print "Creating $project directory structure in $synsimroot...\n"; |
1229
|
0
|
|
|
|
|
|
mkdir "$synsimroot/$project", 0755; |
1230
|
0
|
|
|
|
|
|
mkdir "$synsimroot/$project/SOURCES", 0755; |
1231
|
0
|
|
|
|
|
|
mkdir "$synsimroot/$project/TEMPLATES", 0755; |
1232
|
0
|
|
|
|
|
|
mkdir "$synsimroot/$project/TEMPLATES/DEVTYPES", 0755; |
1233
|
0
|
|
|
|
|
|
mkdir "$synsimroot/$project/TEMPLATES/SIMTYPES", 0755; |
1234
|
0
|
0
|
|
|
|
|
if(-d "eg"){ |
1235
|
0
|
0
|
|
|
|
|
if(-e "eg/synsim"){ |
1236
|
0
|
|
|
|
|
|
system("cp eg/synsim $synsimroot/$project/synsim"); |
1237
|
|
|
|
|
|
|
} |
1238
|
0
|
0
|
|
|
|
|
if(-e "eg/synsim.data"){ |
1239
|
0
|
|
|
|
|
|
system("cp eg/synsim.data $synsimroot/$project/synsim.data"); |
1240
|
|
|
|
|
|
|
} |
1241
|
|
|
|
|
|
|
|
1242
|
0
|
0
|
|
|
|
|
if(-e "eg/TEMPLATES/test.templ"){ |
1243
|
0
|
|
|
|
|
|
system("cp eg/TEMPLATES/test.templ $synsimroot/$project/TEMPLATES/"); |
1244
|
|
|
|
|
|
|
} |
1245
|
|
|
|
|
|
|
} |
1246
|
|
|
|
|
|
|
|
1247
|
0
|
|
|
|
|
|
&localinstall(0,$synsimroot); |
1248
|
|
|
|
|
|
|
|
1249
|
|
|
|
|
|
|
} # END of setup() |
1250
|
|
|
|
|
|
|
|
1251
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
1252
|
|
|
|
|
|
|
|
1253
|
|
|
|
|
|
|
# Local Simulation::Automate (SynSim) installation |
1254
|
|
|
|
|
|
|
sub localinstall { |
1255
|
0
|
|
0
|
0
|
0
|
|
my $full=shift||1; |
1256
|
0
|
|
0
|
|
|
|
my $synsimroot=shift||''; |
1257
|
|
|
|
|
|
|
|
1258
|
0
|
|
|
|
|
|
my $HOME=$ENV{HOME}; |
1259
|
0
|
0
|
|
|
|
|
if(not $synsimroot) { |
1260
|
0
|
|
|
|
|
|
print "Local SinSym directory? [$HOME/SynSim]:"; |
1261
|
0
|
|
|
|
|
|
$synsimroot=; |
1262
|
0
|
|
|
|
|
|
chomp $synsimroot; |
1263
|
0
|
0
|
|
|
|
|
if(not $synsimroot) {$synsimroot="$HOME/SynSim"} |
|
0
|
|
|
|
|
|
|
1264
|
|
|
|
|
|
|
} |
1265
|
0
|
0
|
|
|
|
|
if(not -d "$synsimroot"){ |
1266
|
0
|
|
|
|
|
|
mkdir "$synsimroot", 0755; |
1267
|
|
|
|
|
|
|
} |
1268
|
0
|
|
|
|
|
|
print "Creating local SynSim directory $synsimroot/Simulation/Automate ...\n"; |
1269
|
0
|
0
|
|
|
|
|
if(not -d "$synsimroot/Simulation") { |
1270
|
0
|
|
|
|
|
|
mkdir "$synsimroot/Simulation", 0755; |
1271
|
|
|
|
|
|
|
} |
1272
|
0
|
0
|
|
|
|
|
if(not -d "$synsimroot/Simulation") { |
1273
|
0
|
|
|
|
|
|
mkdir "$synsimroot/Simulation", 0755; |
1274
|
|
|
|
|
|
|
} |
1275
|
0
|
0
|
|
|
|
|
if(not -d "$synsimroot/Simulation/Automate") { |
1276
|
0
|
|
|
|
|
|
mkdir "$synsimroot/Simulation/Automate", 0755; |
1277
|
|
|
|
|
|
|
} |
1278
|
0
|
0
|
|
|
|
|
if(-d "Automate") { |
1279
|
0
|
|
|
|
|
|
foreach my $module (qw(PostProcessors Dictionary)) { |
1280
|
0
|
0
|
|
|
|
|
if( -e "Automate/$module.pm"){ |
1281
|
0
|
|
|
|
|
|
system("cp Automate/$module.pm $synsimroot/Simulation/Automate/$module.pm"); |
1282
|
|
|
|
|
|
|
} |
1283
|
|
|
|
|
|
|
} |
1284
|
0
|
0
|
|
|
|
|
if($full) { |
1285
|
0
|
|
|
|
|
|
foreach my $module (qw(Remote PostProcLib Analysis)){ |
1286
|
0
|
0
|
|
|
|
|
if( -e "Automate/$module.pm"){ |
1287
|
0
|
|
|
|
|
|
system("cp Automate/$module.pm $synsimroot/Simulation/Automate/$module.pm"); |
1288
|
|
|
|
|
|
|
} |
1289
|
|
|
|
|
|
|
} |
1290
|
0
|
0
|
|
|
|
|
if( -e "Automate.pm"){ |
1291
|
0
|
|
|
|
|
|
system("cp Automate.pm $synsimroot/Simulation/Automate.pm"); |
1292
|
|
|
|
|
|
|
} |
1293
|
|
|
|
|
|
|
} # if full local install |
1294
|
|
|
|
|
|
|
} # if directory Automate exists in current dir. |
1295
|
|
|
|
|
|
|
|
1296
|
|
|
|
|
|
|
} # END of localinstall() |
1297
|
|
|
|
|
|
|
|
1298
|
|
|
|
|
|
|
######################## User Documentation ########################## |
1299
|
|
|
|
|
|
|
|
1300
|
|
|
|
|
|
|
|
1301
|
|
|
|
|
|
|
## To format the following documentation into a more readable format, |
1302
|
|
|
|
|
|
|
## use one of these programs: perldoc; pod2man; pod2html; pod2text. |
1303
|
|
|
|
|
|
|
## For example, to nicely format this documentation for printing, you |
1304
|
|
|
|
|
|
|
## may use pod2man and groff to convert to postscript: |
1305
|
|
|
|
|
|
|
## pod2man Automate.pod | groff -man -Tps > Automate.ps |
1306
|
|
|
|
|
|
|
|
1307
|
|
|
|
|
|
|
|
1308
|
|
|
|
|
|
|
=head1 NAME |
1309
|
|
|
|
|
|
|
|
1310
|
|
|
|
|
|
|
Simulation::Automate - A Simulation Automation Tool |
1311
|
|
|
|
|
|
|
|
1312
|
|
|
|
|
|
|
The set of modules is called B. |
1313
|
|
|
|
|
|
|
|
1314
|
|
|
|
|
|
|
The tool itself is called B, the command C. |
1315
|
|
|
|
|
|
|
|
1316
|
|
|
|
|
|
|
=head1 REQUIREMENTS |
1317
|
|
|
|
|
|
|
|
1318
|
|
|
|
|
|
|
=over 4 |
1319
|
|
|
|
|
|
|
|
1320
|
|
|
|
|
|
|
=item * a unix-like system |
1321
|
|
|
|
|
|
|
|
1322
|
|
|
|
|
|
|
=item * perl 5 |
1323
|
|
|
|
|
|
|
|
1324
|
|
|
|
|
|
|
=item * gnuplot for postprocessing (optional) |
1325
|
|
|
|
|
|
|
|
1326
|
|
|
|
|
|
|
=back |
1327
|
|
|
|
|
|
|
|
1328
|
|
|
|
|
|
|
=head1 SYNOPSIS |
1329
|
|
|
|
|
|
|
|
1330
|
|
|
|
|
|
|
use Simulation::Automate; |
1331
|
|
|
|
|
|
|
|
1332
|
|
|
|
|
|
|
&synsim(); |
1333
|
|
|
|
|
|
|
|
1334
|
|
|
|
|
|
|
=head1 DESCRIPTION |
1335
|
|
|
|
|
|
|
|
1336
|
|
|
|
|
|
|
SynSim is a generic template-driven simulation automation tool. It works with any simulator that accepts text input files and generates text output (and even those that don't. See L"EXAMPLES"> for special cases). It executes thousands of simulations with different input files automatically, and processes the results. Postprocessing facilities include basic statistical analysis and automatic generation of PostScript plots with Gnuplot. SynSim is entirely modular, making it easy to add your own analysis and postprocessing routines. |
1337
|
|
|
|
|
|
|
|
1338
|
|
|
|
|
|
|
=head1 INSTALLATION |
1339
|
|
|
|
|
|
|
|
1340
|
|
|
|
|
|
|
=head2 1. Download and extract the archive |
1341
|
|
|
|
|
|
|
|
1342
|
|
|
|
|
|
|
=over 4 |
1343
|
|
|
|
|
|
|
|
1344
|
|
|
|
|
|
|
=item 1. |
1345
|
|
|
|
|
|
|
Download the gzipped tar file F |
1346
|
|
|
|
|
|
|
|
1347
|
|
|
|
|
|
|
=item 2. |
1348
|
|
|
|
|
|
|
Extract the archive: |
1349
|
|
|
|
|
|
|
|
1350
|
|
|
|
|
|
|
tar -zxvf Simulation-Automate-0.9.5.tar.gz |
1351
|
|
|
|
|
|
|
|
1352
|
|
|
|
|
|
|
=back |
1353
|
|
|
|
|
|
|
|
1354
|
|
|
|
|
|
|
=head2 2. Simple local installation |
1355
|
|
|
|
|
|
|
|
1356
|
|
|
|
|
|
|
This installation procedure will install the Simulation::Automate modules in a directory of your choice, and create a template directory structure for your SynSim project. |
1357
|
|
|
|
|
|
|
|
1358
|
|
|
|
|
|
|
=over 4 |
1359
|
|
|
|
|
|
|
|
1360
|
|
|
|
|
|
|
=item 1. Run the local install script: |
1361
|
|
|
|
|
|
|
|
1362
|
|
|
|
|
|
|
In the main directory of the distribution (i.e. the directory which contains the file C), type: |
1363
|
|
|
|
|
|
|
|
1364
|
|
|
|
|
|
|
perl local_install.pl |
1365
|
|
|
|
|
|
|
|
1366
|
|
|
|
|
|
|
=item 2. Enter the installation directory |
1367
|
|
|
|
|
|
|
|
1368
|
|
|
|
|
|
|
The install script asks for the name of the directory in which it will put SynSim: |
1369
|
|
|
|
|
|
|
|
1370
|
|
|
|
|
|
|
Local SinSym directory? [/local/home/wim/SynSim]: |
1371
|
|
|
|
|
|
|
|
1372
|
|
|
|
|
|
|
If you enter just a name, the installer assumes that the directory is in your home directory. If you want to install SynSim outside your home directory, enter a full path. |
1373
|
|
|
|
|
|
|
|
1374
|
|
|
|
|
|
|
=item 3. Enter the project directory name |
1375
|
|
|
|
|
|
|
|
1376
|
|
|
|
|
|
|
The install script asks for the name of directory where you will run SynSim: |
1377
|
|
|
|
|
|
|
|
1378
|
|
|
|
|
|
|
Simulation project directory? [SynSimProject]: |
1379
|
|
|
|
|
|
|
|
1380
|
|
|
|
|
|
|
This directory is a subdirectory of the local SynSim directory. |
1381
|
|
|
|
|
|
|
|
1382
|
|
|
|
|
|
|
=back |
1383
|
|
|
|
|
|
|
|
1384
|
|
|
|
|
|
|
That's it. Now you can go to your project directory and run the synsim script as a test: |
1385
|
|
|
|
|
|
|
|
1386
|
|
|
|
|
|
|
./synsim |
1387
|
|
|
|
|
|
|
|
1388
|
|
|
|
|
|
|
This will run a simple test. If the installation was succesful, it will display the follwing message: |
1389
|
|
|
|
|
|
|
|
1390
|
|
|
|
|
|
|
SynSim Installation Test |
1391
|
|
|
|
|
|
|
|
1392
|
|
|
|
|
|
|
Simulation::Automate version 0.9.6 |
1393
|
|
|
|
|
|
|
|
1394
|
|
|
|
|
|
|
installed locally in /home/wim/SynSim/Test |
1395
|
|
|
|
|
|
|
|
1396
|
|
|
|
|
|
|
Finished SynSim run |
1397
|
|
|
|
|
|
|
|
1398
|
|
|
|
|
|
|
|
1399
|
|
|
|
|
|
|
=head2 3. Perl-style installation |
1400
|
|
|
|
|
|
|
|
1401
|
|
|
|
|
|
|
This is the typical Makefile.PL-driven installation procedure. It is only required for system-wide installation, but it works for local installation as well. |
1402
|
|
|
|
|
|
|
|
1403
|
|
|
|
|
|
|
=over |
1404
|
|
|
|
|
|
|
|
1405
|
|
|
|
|
|
|
=item 1. |
1406
|
|
|
|
|
|
|
Create the Makefile: |
1407
|
|
|
|
|
|
|
|
1408
|
|
|
|
|
|
|
cd Simulation-Automate-0.9.5 |
1409
|
|
|
|
|
|
|
perl Makefile.PL |
1410
|
|
|
|
|
|
|
|
1411
|
|
|
|
|
|
|
=item 2. |
1412
|
|
|
|
|
|
|
Make Simulation::Automate: |
1413
|
|
|
|
|
|
|
|
1414
|
|
|
|
|
|
|
make |
1415
|
|
|
|
|
|
|
|
1416
|
|
|
|
|
|
|
=item 3. |
1417
|
|
|
|
|
|
|
Test Simulation::Automate: |
1418
|
|
|
|
|
|
|
|
1419
|
|
|
|
|
|
|
make test |
1420
|
|
|
|
|
|
|
|
1421
|
|
|
|
|
|
|
=item 4. |
1422
|
|
|
|
|
|
|
Install Simulation::Automate: |
1423
|
|
|
|
|
|
|
|
1424
|
|
|
|
|
|
|
This requires you to be root: |
1425
|
|
|
|
|
|
|
|
1426
|
|
|
|
|
|
|
su |
1427
|
|
|
|
|
|
|
make install |
1428
|
|
|
|
|
|
|
|
1429
|
|
|
|
|
|
|
or |
1430
|
|
|
|
|
|
|
|
1431
|
|
|
|
|
|
|
sudo make install |
1432
|
|
|
|
|
|
|
|
1433
|
|
|
|
|
|
|
|
1434
|
|
|
|
|
|
|
=item 5. |
1435
|
|
|
|
|
|
|
For a local installation |
1436
|
|
|
|
|
|
|
|
1437
|
|
|
|
|
|
|
This does not require you to be root: |
1438
|
|
|
|
|
|
|
|
1439
|
|
|
|
|
|
|
make localinstall |
1440
|
|
|
|
|
|
|
|
1441
|
|
|
|
|
|
|
or |
1442
|
|
|
|
|
|
|
|
1443
|
|
|
|
|
|
|
perl -e "use Simulation::Automate; |
1444
|
|
|
|
|
|
|
&Simulation::Automate::localinstall();" |
1445
|
|
|
|
|
|
|
|
1446
|
|
|
|
|
|
|
=item 6. |
1447
|
|
|
|
|
|
|
Setup your local SynSim project ( |
1448
|
|
|
|
|
|
|
|
1449
|
|
|
|
|
|
|
SynSim is the name for the tool contained in Simulation::Automate. This step creates the directory structure for your simulations: |
1450
|
|
|
|
|
|
|
|
1451
|
|
|
|
|
|
|
make setup |
1452
|
|
|
|
|
|
|
or |
1453
|
|
|
|
|
|
|
|
1454
|
|
|
|
|
|
|
perl -e "use Simulation::Automate; |
1455
|
|
|
|
|
|
|
&Simulation::Automate::setup();" |
1456
|
|
|
|
|
|
|
|
1457
|
|
|
|
|
|
|
=back |
1458
|
|
|
|
|
|
|
|
1459
|
|
|
|
|
|
|
=head2 4. Archive structure |
1460
|
|
|
|
|
|
|
|
1461
|
|
|
|
|
|
|
The archive structure is as follows: |
1462
|
|
|
|
|
|
|
|
1463
|
|
|
|
|
|
|
README |
1464
|
|
|
|
|
|
|
Makefile.PL |
1465
|
|
|
|
|
|
|
Automate.pm |
1466
|
|
|
|
|
|
|
local_install.pl |
1467
|
|
|
|
|
|
|
Automate/ |
1468
|
|
|
|
|
|
|
Remote.pm |
1469
|
|
|
|
|
|
|
PostProcLib.pm |
1470
|
|
|
|
|
|
|
Analysis.pm |
1471
|
|
|
|
|
|
|
Dictionary.pm |
1472
|
|
|
|
|
|
|
PostProcessors.pm |
1473
|
|
|
|
|
|
|
|
1474
|
|
|
|
|
|
|
eg/ |
1475
|
|
|
|
|
|
|
synsim |
1476
|
|
|
|
|
|
|
synsim.data |
1477
|
|
|
|
|
|
|
ErrorFlags.data |
1478
|
|
|
|
|
|
|
Histogram.data |
1479
|
|
|
|
|
|
|
SweepVar.data |
1480
|
|
|
|
|
|
|
Expressions.data |
1481
|
|
|
|
|
|
|
gnuplot.data |
1482
|
|
|
|
|
|
|
SOURCES/ |
1483
|
|
|
|
|
|
|
bufsim3.cc |
1484
|
|
|
|
|
|
|
MersenneTwister.h |
1485
|
|
|
|
|
|
|
TEMPLATES/ |
1486
|
|
|
|
|
|
|
test.templ |
1487
|
|
|
|
|
|
|
DEVTYPES/ |
1488
|
|
|
|
|
|
|
SIMTYPES/ |
1489
|
|
|
|
|
|
|
bufsim3.templ |
1490
|
|
|
|
|
|
|
PLUGINS/ |
1491
|
|
|
|
|
|
|
|
1492
|
|
|
|
|
|
|
|
1493
|
|
|
|
|
|
|
=head1 CONFIGURATION |
1494
|
|
|
|
|
|
|
|
1495
|
|
|
|
|
|
|
To configure SynSim for use with your simulator, you must create a set of files in your SynSim project directory structure. This paragraph gives an overview of the different types of files and their place in the SynSim project directory structure. |
1496
|
|
|
|
|
|
|
|
1497
|
|
|
|
|
|
|
=head2 SynSim project directory structure |
1498
|
|
|
|
|
|
|
|
1499
|
|
|
|
|
|
|
You can create a SynSim directory structure with C or C (see L"INSTALLATION"> for details). If you already have an existing project, you can do this: |
1500
|
|
|
|
|
|
|
|
1501
|
|
|
|
|
|
|
=over 4 |
1502
|
|
|
|
|
|
|
|
1503
|
|
|
|
|
|
|
=item * |
1504
|
|
|
|
|
|
|
Create a new project directory: |
1505
|
|
|
|
|
|
|
|
1506
|
|
|
|
|
|
|
mkdir NewProject |
1507
|
|
|
|
|
|
|
|
1508
|
|
|
|
|
|
|
=item * |
1509
|
|
|
|
|
|
|
Copy the C script from the old project: |
1510
|
|
|
|
|
|
|
|
1511
|
|
|
|
|
|
|
cp oldProject/synsim NewProject |
1512
|
|
|
|
|
|
|
|
1513
|
|
|
|
|
|
|
=item * |
1514
|
|
|
|
|
|
|
Go to the C directory and run C with the C<-D> option: |
1515
|
|
|
|
|
|
|
|
1516
|
|
|
|
|
|
|
cd NewProject |
1517
|
|
|
|
|
|
|
./synsim -D |
1518
|
|
|
|
|
|
|
|
1519
|
|
|
|
|
|
|
=back |
1520
|
|
|
|
|
|
|
|
1521
|
|
|
|
|
|
|
If you want to create it manually, this is the structure. Directories between square brackets are optional. |
1522
|
|
|
|
|
|
|
|
1523
|
|
|
|
|
|
|
YourProject/ |
1524
|
|
|
|
|
|
|
synsim |
1525
|
|
|
|
|
|
|
YourDataFile.data |
1526
|
|
|
|
|
|
|
[SOURCES/] |
1527
|
|
|
|
|
|
|
TEMPLATES/ |
1528
|
|
|
|
|
|
|
YourSimTempl.templ |
1529
|
|
|
|
|
|
|
[DEVTYPES/] |
1530
|
|
|
|
|
|
|
[SIMTYPES/] |
1531
|
|
|
|
|
|
|
[PLUGINS/] |
1532
|
|
|
|
|
|
|
[Simulation/SynSim/] |
1533
|
|
|
|
|
|
|
[Dictionary.pm] |
1534
|
|
|
|
|
|
|
[PostProcessors.pm] |
1535
|
|
|
|
|
|
|
|
1536
|
|
|
|
|
|
|
The C script is the actual script that runs the DOE. It contains the 2 lines from the L"SYNOPSIS">. |
1537
|
|
|
|
|
|
|
The local Simulation/Automate modules are only required if you want to customize the postprocessing. |
1538
|
|
|
|
|
|
|
|
1539
|
|
|
|
|
|
|
=head2 Source files |
1540
|
|
|
|
|
|
|
|
1541
|
|
|
|
|
|
|
The directory F is optional. It should contain all files which are required "read-only" by your simulator (e.g. header files, library files, wrappers). |
1542
|
|
|
|
|
|
|
|
1543
|
|
|
|
|
|
|
=head2 Template files |
1544
|
|
|
|
|
|
|
|
1545
|
|
|
|
|
|
|
Template files are files in which simulation variables will be substituted by their values to create the input file for your simulator. They must be stored in the F directory, and have by convention the extension C<.templ>. |
1546
|
|
|
|
|
|
|
|
1547
|
|
|
|
|
|
|
B |
1548
|
|
|
|
|
|
|
|
1549
|
|
|
|
|
|
|
The template file format is free, but the variables to be substituted by SynSim I be in uppercase and start with an underscore: |
1550
|
|
|
|
|
|
|
|
1551
|
|
|
|
|
|
|
Examples: |
1552
|
|
|
|
|
|
|
|
1553
|
|
|
|
|
|
|
_VAR1 |
1554
|
|
|
|
|
|
|
_LONG_VARIABLE_NAME |
1555
|
|
|
|
|
|
|
|
1556
|
|
|
|
|
|
|
To create a template file, start from an existing input file for your simulator. Replace the values of the variables to be modified by SynSim by a SynSim variable name (e.g. |
1557
|
|
|
|
|
|
|
var1 = 2.5 => var1 = _VAR1). Put the template files in F. |
1558
|
|
|
|
|
|
|
|
1559
|
|
|
|
|
|
|
|
1560
|
|
|
|
|
|
|
B Relative paths to source files |
1561
|
|
|
|
|
|
|
|
1562
|
|
|
|
|
|
|
SynSim creates a run directory ath the same level as the SOURCES and TEMPLATES directories. All commands (compilations etc.) are executed in that directory. As a consequence, paths to source files (e.g. header files) should be "C<../SOURCES/>I". |
1563
|
|
|
|
|
|
|
|
1564
|
|
|
|
|
|
|
B The F and F subdirectories |
1565
|
|
|
|
|
|
|
|
1566
|
|
|
|
|
|
|
SynSim can create an input file by combining two different template files, generally called device templates and simulation templates. This is useful in case you want to run different types of simulations on different devices, e.g. DC analysis, transient simulations, small-signal and noise analysis on 4 different types of operational amplifiers. In total, this requires 16 different input files, but only 8 different template files (4 for the simulation type, 4 for the device types). If you want to use this approach, device templates should go in F and simulation templates in F. |
1567
|
|
|
|
|
|
|
SynSim will check both directories for files as defined in the datafile. If a matching file is found in F, it will be prepended to the simulation template from F. |
1568
|
|
|
|
|
|
|
|
1569
|
|
|
|
|
|
|
=head2 Datafile |
1570
|
|
|
|
|
|
|
|
1571
|
|
|
|
|
|
|
The datafile is the input file for C. It contains the list of simulation variables and their values to be substituted in the template files, as well as a number of configuration variables. See L"DATAFILE DESCRIPTION"> for more information. |
1572
|
|
|
|
|
|
|
|
1573
|
|
|
|
|
|
|
=head2 Postprocessing and Preprocessing (optional) |
1574
|
|
|
|
|
|
|
|
1575
|
|
|
|
|
|
|
The F module contains routines to perform postprocessing on the simulation results (e.g. plotting, statistical analysis, etc). A number of generic routines are provided, as well as a library of functions to make it easier to develop your own postprocessing routines. See L"POSTPROCESSING"> for a full description). |
1576
|
|
|
|
|
|
|
|
1577
|
|
|
|
|
|
|
Before the raw data are sent to the postprocessor, it is possible (and very easy) to preprocess the raw data. See L"PREROCESSING"> for more details. |
1578
|
|
|
|
|
|
|
|
1579
|
|
|
|
|
|
|
Custom postprocessing and preprocessing routines can either be stored in the F directory (preferred) or directly in the local F module (more intended for modified versions of the generic routines). |
1580
|
|
|
|
|
|
|
|
1581
|
|
|
|
|
|
|
=head2 Dictionary (optional) |
1582
|
|
|
|
|
|
|
|
1583
|
|
|
|
|
|
|
The F module contains descriptions of the parameters used in the simulation. These descriptions are used by the postprocessing routines to make the simulation results more readable. See L"DICTIONARY"> for a full description). |
1584
|
|
|
|
|
|
|
|
1585
|
|
|
|
|
|
|
=head1 DATAFILE DESCRIPTION |
1586
|
|
|
|
|
|
|
|
1587
|
|
|
|
|
|
|
The datafile defines which simulations to run, with which parameter values to use, and how to run the simulation. By convention, it has the extension C<.data>. |
1588
|
|
|
|
|
|
|
|
1589
|
|
|
|
|
|
|
=head2 Syntax |
1590
|
|
|
|
|
|
|
|
1591
|
|
|
|
|
|
|
The datafile is a case-sensitive text file with following syntax: |
1592
|
|
|
|
|
|
|
|
1593
|
|
|
|
|
|
|
=over 4 |
1594
|
|
|
|
|
|
|
|
1595
|
|
|
|
|
|
|
=item Comments and blanks |
1596
|
|
|
|
|
|
|
|
1597
|
|
|
|
|
|
|
Comments are preceded by '#'. |
1598
|
|
|
|
|
|
|
Comments, blanks and empty lines are ignored |
1599
|
|
|
|
|
|
|
|
1600
|
|
|
|
|
|
|
=item Parameters |
1601
|
|
|
|
|
|
|
|
1602
|
|
|
|
|
|
|
Parameters (simulation variables) are in UPPERCASE with a leading '_', and must be separated from their values with a '='. |
1603
|
|
|
|
|
|
|
|
1604
|
|
|
|
|
|
|
=item Keywords |
1605
|
|
|
|
|
|
|
|
1606
|
|
|
|
|
|
|
Keywords (configuration variables) are in UPPERCASE, and must be separated from their values with a ':'. |
1607
|
|
|
|
|
|
|
|
1608
|
|
|
|
|
|
|
=item Lists of values |
1609
|
|
|
|
|
|
|
|
1610
|
|
|
|
|
|
|
Lists of values have one or more items. The list separator is a comma ','. |
1611
|
|
|
|
|
|
|
|
1612
|
|
|
|
|
|
|
Example: |
1613
|
|
|
|
|
|
|
|
1614
|
|
|
|
|
|
|
_PAR1 = 1,1,2,3,5,8,13 |
1615
|
|
|
|
|
|
|
|
1616
|
|
|
|
|
|
|
If a list has 3 elements START,STOP,STEP, then if possible this list will be expanded as a for-loop from START to STOP with step STEP. |
1617
|
|
|
|
|
|
|
|
1618
|
|
|
|
|
|
|
Example: |
1619
|
|
|
|
|
|
|
|
1620
|
|
|
|
|
|
|
_NBUFS = 16,64,8 # from 16 to 64 in steps if 8: 16,24,32,40,48,56,64 |
1621
|
|
|
|
|
|
|
|
1622
|
|
|
|
|
|
|
=item Section headers for multiple simulation types (optional) |
1623
|
|
|
|
|
|
|
|
1624
|
|
|
|
|
|
|
These must be lines containing only the simulation type |
1625
|
|
|
|
|
|
|
|
1626
|
|
|
|
|
|
|
=back |
1627
|
|
|
|
|
|
|
|
1628
|
|
|
|
|
|
|
=head2 Simulation variables |
1629
|
|
|
|
|
|
|
|
1630
|
|
|
|
|
|
|
The main purpose of the datafile is to provide a list of all variables and their values to be substituted in the template files. |
1631
|
|
|
|
|
|
|
|
1632
|
|
|
|
|
|
|
=over 4 |
1633
|
|
|
|
|
|
|
|
1634
|
|
|
|
|
|
|
=item Default behaviour: combine values |
1635
|
|
|
|
|
|
|
|
1636
|
|
|
|
|
|
|
A simulation will be performed for every possible combination of the values for all parameters. |
1637
|
|
|
|
|
|
|
|
1638
|
|
|
|
|
|
|
Example: |
1639
|
|
|
|
|
|
|
|
1640
|
|
|
|
|
|
|
_PAR1 = 1,2 |
1641
|
|
|
|
|
|
|
_PAR2 = 3,4,5 |
1642
|
|
|
|
|
|
|
|
1643
|
|
|
|
|
|
|
defines 6 simulations: (_PAR1,_PAR2)=(1,3),(1,4),(1,5),(2,3),(2,4),(2,5) |
1644
|
|
|
|
|
|
|
|
1645
|
|
|
|
|
|
|
Simulation results for all values in ','-separated list are stored in a separate files. |
1646
|
|
|
|
|
|
|
|
1647
|
|
|
|
|
|
|
|
1648
|
|
|
|
|
|
|
=item Alternative behaviour: group values |
1649
|
|
|
|
|
|
|
|
1650
|
|
|
|
|
|
|
It is possible (See the keyword B under L"Configuration variables">) to define groups of variables. For every parameter in a group, the value list must have the same number of items. The values of all variables at the same position in the list will be used. |
1651
|
|
|
|
|
|
|
|
1652
|
|
|
|
|
|
|
Example: |
1653
|
|
|
|
|
|
|
|
1654
|
|
|
|
|
|
|
GROUP: _PAR1,_PAR2 |
1655
|
|
|
|
|
|
|
|
1656
|
|
|
|
|
|
|
_PAR1 = 0;1;2;4 |
1657
|
|
|
|
|
|
|
_PAR2 = 3;4;5;6 |
1658
|
|
|
|
|
|
|
|
1659
|
|
|
|
|
|
|
defines 4 simulations: (_PAR1,_PAR2)=(0,3);(1,4);(2,5);(4,6) |
1660
|
|
|
|
|
|
|
|
1661
|
|
|
|
|
|
|
=back |
1662
|
|
|
|
|
|
|
|
1663
|
|
|
|
|
|
|
=head2 Configuration variables |
1664
|
|
|
|
|
|
|
|
1665
|
|
|
|
|
|
|
A number of configuration variables ("keywordsw) are provided to configure SynSim's behaviour. There is no mandatory order, but they must appear before the simulation variable. For the default order, see the L"EXAMPLES">. |
1666
|
|
|
|
|
|
|
In alphabetical order, they are: |
1667
|
|
|
|
|
|
|
|
1668
|
|
|
|
|
|
|
=over 4 |
1669
|
|
|
|
|
|
|
|
1670
|
|
|
|
|
|
|
|
1671
|
|
|
|
|
|
|
=item ANALYSIS |
1672
|
|
|
|
|
|
|
|
1673
|
|
|
|
|
|
|
B ANALYSIS_TEMPLATE, ANATEMPL |
1674
|
|
|
|
|
|
|
|
1675
|
|
|
|
|
|
|
Name of the routine to be used for the result analysis (postprocessing). This routine must be defined in PostProcessors.pm or in a file in the F directory. A number of generic routines are provided, see L"POSTPROCESSING">. |
1676
|
|
|
|
|
|
|
|
1677
|
|
|
|
|
|
|
=item COMMAND |
1678
|
|
|
|
|
|
|
|
1679
|
|
|
|
|
|
|
The command line for the program that runs the input file, i.e. the simulator command (default: perl). SynSim looks for the words B and and substitutes them with the actual file names. |
1680
|
|
|
|
|
|
|
|
1681
|
|
|
|
|
|
|
Examples: |
1682
|
|
|
|
|
|
|
|
1683
|
|
|
|
|
|
|
yoursim1 -i INPUTFILE -o OUTPUTFILE |
1684
|
|
|
|
|
|
|
yoursim2 INPUTFILE > OUTPUTFILE |
1685
|
|
|
|
|
|
|
|
1686
|
|
|
|
|
|
|
=item DEVTYPE (optional) |
1687
|
|
|
|
|
|
|
|
1688
|
|
|
|
|
|
|
The name of the device on which to perform the simulation. If defined, SynSim will look in TEMPLATES/DEVTYPES for a file with TEMPL and DEVTYPE, and prepend this file to the simulation template before parsing. This keyword can take a list of values |
1689
|
|
|
|
|
|
|
|
1690
|
|
|
|
|
|
|
=item EXT |
1691
|
|
|
|
|
|
|
|
1692
|
|
|
|
|
|
|
Extension of input file (default: .pl) |
1693
|
|
|
|
|
|
|
|
1694
|
|
|
|
|
|
|
Some simulators expect a particular extension for the input file. This can be specified with the keyword B. |
1695
|
|
|
|
|
|
|
|
1696
|
|
|
|
|
|
|
=item GROUP (optional) |
1697
|
|
|
|
|
|
|
|
1698
|
|
|
|
|
|
|
This keyword can be used to change the default behaviour of creating nested loops for every parameter. |
1699
|
|
|
|
|
|
|
It takes as argument a list of parameters. The behaviour for grouped parameters is to change at the same time. All parameter lists in the group must have the same number of values. More than one group can be created. |
1700
|
|
|
|
|
|
|
|
1701
|
|
|
|
|
|
|
Example: |
1702
|
|
|
|
|
|
|
|
1703
|
|
|
|
|
|
|
# First group: 2 parameters, each 4 values |
1704
|
|
|
|
|
|
|
GROUP: _PAR_A1,_PAR_A2 |
1705
|
|
|
|
|
|
|
# Second group: 3 parameters, each 3 values |
1706
|
|
|
|
|
|
|
GROUP: _PAR_B1,_PAR_B2,_PAR_B3 |
1707
|
|
|
|
|
|
|
# SynSim will run 4*3 simulations (default without groups would be 16*27) |
1708
|
|
|
|
|
|
|
|
1709
|
|
|
|
|
|
|
_PAR_A1 = 0;1;2;4 |
1710
|
|
|
|
|
|
|
_PAR_A2 = 3;4;5;6 |
1711
|
|
|
|
|
|
|
|
1712
|
|
|
|
|
|
|
_PAR_B1 = -1;1;2 |
1713
|
|
|
|
|
|
|
_PAR_B2 = 3;4;7 |
1714
|
|
|
|
|
|
|
_PAR_B3 = 3;6;15 |
1715
|
|
|
|
|
|
|
|
1716
|
|
|
|
|
|
|
=item INCLUDE (optional) |
1717
|
|
|
|
|
|
|
|
1718
|
|
|
|
|
|
|
If the value of INCLUDE is an exisiting filename, this datafile will be included on the spot. |
1719
|
|
|
|
|
|
|
|
1720
|
|
|
|
|
|
|
=item NORMVAR (optional) |
1721
|
|
|
|
|
|
|
|
1722
|
|
|
|
|
|
|
The name of the variable to normalise the results with. The results will be divided by the corresponding value of the variable. |
1723
|
|
|
|
|
|
|
|
1724
|
|
|
|
|
|
|
=item NRUNS (optional) |
1725
|
|
|
|
|
|
|
|
1726
|
|
|
|
|
|
|
|
1727
|
|
|
|
|
|
|
=item OUTPUT_FILTER_PATTERN (optional) |
1728
|
|
|
|
|
|
|
|
1729
|
|
|
|
|
|
|
A Perl regular expression to filter the output of the simulation (default : .*). Tis is very usefull for very verbose simulators. The results file will only contain the filtered output. |
1730
|
|
|
|
|
|
|
|
1731
|
|
|
|
|
|
|
=item PREPROCESSOR (optional) |
1732
|
|
|
|
|
|
|
|
1733
|
|
|
|
|
|
|
The name of a function which modifies C<@results> before the actual postprocessing. Very usefull to "streamline" the raw results for postprocessing. |
1734
|
|
|
|
|
|
|
|
1735
|
|
|
|
|
|
|
=item TEMPLATE |
1736
|
|
|
|
|
|
|
|
1737
|
|
|
|
|
|
|
B SIMULATION, SIMTEMPL, SIMTYPE |
1738
|
|
|
|
|
|
|
|
1739
|
|
|
|
|
|
|
The name of the template file, with or without extension. By convention, this is the same as the type of simulation to be performed. If no extension is given, SynSIm checks for a B keyword; if this is not defined, the extenstion defaults to C<.templ>. SynSim will look for the template file in F and F. |
1740
|
|
|
|
|
|
|
|
1741
|
|
|
|
|
|
|
B Multiple simulation types |
1742
|
|
|
|
|
|
|
|
1743
|
|
|
|
|
|
|
The value of SIMULATION can be a ','-separated list. In this case, SynSim will use the datafile for multiple types of simulations. Every item in the list can be used as a section header, demarkating a section with variables particular to that specific simulation. |
1744
|
|
|
|
|
|
|
|
1745
|
|
|
|
|
|
|
=item TEMPLEXT (optional) |
1746
|
|
|
|
|
|
|
|
1747
|
|
|
|
|
|
|
Extension of template files (default: C<.templ>) |
1748
|
|
|
|
|
|
|
|
1749
|
|
|
|
|
|
|
=item TITLE |
1750
|
|
|
|
|
|
|
|
1751
|
|
|
|
|
|
|
The title of the DOE. This title is used on the plots, but typically it is the first line of the datafile and describes the DOE. |
1752
|
|
|
|
|
|
|
|
1753
|
|
|
|
|
|
|
=item XVAR (optional) |
1754
|
|
|
|
|
|
|
|
1755
|
|
|
|
|
|
|
B SWEEPVAR |
1756
|
|
|
|
|
|
|
|
1757
|
|
|
|
|
|
|
The name of the variable to be sweeped. Mandatory if the postprocessing routine is XYPlot. |
1758
|
|
|
|
|
|
|
|
1759
|
|
|
|
|
|
|
The number of times the simulation has to be performed. For statistical work. |
1760
|
|
|
|
|
|
|
|
1761
|
|
|
|
|
|
|
=item XCOL (optional) |
1762
|
|
|
|
|
|
|
|
1763
|
|
|
|
|
|
|
The column in the output file which contains the X-values. |
1764
|
|
|
|
|
|
|
|
1765
|
|
|
|
|
|
|
=item YCOL (optional) |
1766
|
|
|
|
|
|
|
|
1767
|
|
|
|
|
|
|
B DATACOL |
1768
|
|
|
|
|
|
|
|
1769
|
|
|
|
|
|
|
The column in the output file which contains the simulation results (default: 2). Mandatory if using any of the generic postprocessing routines. |
1770
|
|
|
|
|
|
|
|
1771
|
|
|
|
|
|
|
=item XLABEL, YLABEL, LOGSCALE, PLOTSTYLE, XTICS, YTICS, XSTART, XSTOP, YSTART, YSTOP (optional) |
1772
|
|
|
|
|
|
|
|
1773
|
|
|
|
|
|
|
Variables to allow more flexibility in the customization of the plots. They are identical to the corresponding (lowercase) C keywords, see the gnuplot documentation for details. The most commonly used, XLABEL and YLABEL are the X and Y axis labels. LOGSCALE is either X, Y or XY, and results in a logarithmic scale for the chosen axis. |
1774
|
|
|
|
|
|
|
|
1775
|
|
|
|
|
|
|
=back |
1776
|
|
|
|
|
|
|
|
1777
|
|
|
|
|
|
|
=head2 Expressions |
1778
|
|
|
|
|
|
|
|
1779
|
|
|
|
|
|
|
The SynSim datafile has support for expressions, i.e. it is possible to express the value list of a variable in terms of the values of other variables. |
1780
|
|
|
|
|
|
|
|
1781
|
|
|
|
|
|
|
Example: |
1782
|
|
|
|
|
|
|
|
1783
|
|
|
|
|
|
|
# average packet length for IP dist |
1784
|
|
|
|
|
|
|
_MEANPL = ((_AGGREGATE==0)?2784:9120) |
1785
|
|
|
|
|
|
|
# average gap width |
1786
|
|
|
|
|
|
|
_MEANGW= int(_MEANPL*(1/_LOAD-1)) |
1787
|
|
|
|
|
|
|
# average load |
1788
|
|
|
|
|
|
|
_LOAD = 0.1;0.2;0.3;0.4;0.5;0.6;0.7;0.8;0.9 |
1789
|
|
|
|
|
|
|
# aggregate |
1790
|
|
|
|
|
|
|
_AGGREGATE = 0,12000 |
1791
|
|
|
|
|
|
|
|
1792
|
|
|
|
|
|
|
The variables used in the expressions must be defined in the datafile, although not upfront. Using circular references will not work. |
1793
|
|
|
|
|
|
|
The expression syntax is Perl syntax, so any Perl function can be used. Due to the binding rules, it is necessary to enclose expressions using the ternary operator ?: with brackets (see example). |
1794
|
|
|
|
|
|
|
|
1795
|
|
|
|
|
|
|
=head1 RUNNING SYNSIM |
1796
|
|
|
|
|
|
|
|
1797
|
|
|
|
|
|
|
The SynSim script must be executed in a subdirectory of the SynSim |
1798
|
|
|
|
|
|
|
directory which contains the TEMPLATES subdir and the datafile (like the Example directory in the distribution). |
1799
|
|
|
|
|
|
|
|
1800
|
|
|
|
|
|
|
The command line is as follows: |
1801
|
|
|
|
|
|
|
|
1802
|
|
|
|
|
|
|
./synsim [-h -D -i -p -P -v -N ] [datafile] [remote hostname] |
1803
|
|
|
|
|
|
|
|
1804
|
|
|
|
|
|
|
The C script supports following command line options: |
1805
|
|
|
|
|
|
|
|
1806
|
|
|
|
|
|
|
none: defaults to -f synsim.data |
1807
|
|
|
|
|
|
|
-D : Create an empty SynSim directory structure in the current directory. |
1808
|
|
|
|
|
|
|
-v : 'verbose'. Sends simulator output to STDOUT |
1809
|
|
|
|
|
|
|
-i : interactive. Calls gv or ggv to display a plot of the results. |
1810
|
|
|
|
|
|
|
Implies -p -v. |
1811
|
|
|
|
|
|
|
-p : plot. This enables generation of postscript plots via gnuplot. |
1812
|
|
|
|
|
|
|
A postprocessing routine is required to generate the plots. |
1813
|
|
|
|
|
|
|
-P : Plot. This option can be used to display plots created with -p. |
1814
|
|
|
|
|
|
|
-w : 'warnings'. Show warnings about undefined variables. |
1815
|
|
|
|
|
|
|
-N : 'No simulations'. Performs only postprocessing. |
1816
|
|
|
|
|
|
|
-h, -? : short help message |
1817
|
|
|
|
|
|
|
|
1818
|
|
|
|
|
|
|
If [remote hostname] is provided, SynSim will try to run the simulation on the remote host. |
1819
|
|
|
|
|
|
|
|
1820
|
|
|
|
|
|
|
The current implementation requires: |
1821
|
|
|
|
|
|
|
|
1822
|
|
|
|
|
|
|
-ssh access to remote host |
1823
|
|
|
|
|
|
|
|
1824
|
|
|
|
|
|
|
-scp access to remote host |
1825
|
|
|
|
|
|
|
|
1826
|
|
|
|
|
|
|
-rsync server on the local host |
1827
|
|
|
|
|
|
|
|
1828
|
|
|
|
|
|
|
-or,alternatively, an NFS mounted home directory |
1829
|
|
|
|
|
|
|
|
1830
|
|
|
|
|
|
|
-as such, it will (probably) only work on Linux and similar systems |
1831
|
|
|
|
|
|
|
|
1832
|
|
|
|
|
|
|
|
1833
|
|
|
|
|
|
|
=head1 POSTPROCESSING |
1834
|
|
|
|
|
|
|
|
1835
|
|
|
|
|
|
|
Postprocessing of the simulation results is handled by routines in the C module. This module uses the C and optionally C and C. |
1836
|
|
|
|
|
|
|
|
1837
|
|
|
|
|
|
|
=head2 Generic Postprocessors |
1838
|
|
|
|
|
|
|
|
1839
|
|
|
|
|
|
|
SynSim comes with a number of generic postprocessing routines. |
1840
|
|
|
|
|
|
|
|
1841
|
|
|
|
|
|
|
=over 4 |
1842
|
|
|
|
|
|
|
|
1843
|
|
|
|
|
|
|
=item XYPlot |
1844
|
|
|
|
|
|
|
|
1845
|
|
|
|
|
|
|
Required configuration variables: C |
1846
|
|
|
|
|
|
|
|
1847
|
|
|
|
|
|
|
Creates a plot using C as X-axis and all other variables as parameters. This routine is completely generic. |
1848
|
|
|
|
|
|
|
|
1849
|
|
|
|
|
|
|
=item CondXYPlot |
1850
|
|
|
|
|
|
|
|
1851
|
|
|
|
|
|
|
Required configuration variables: C,C and C. |
1852
|
|
|
|
|
|
|
|
1853
|
|
|
|
|
|
|
Creates a plot using C as X-axis; C is checked against the condition C (or C). The first value of C that meets the condition is plotted. All other variables are parameters. This routine is completely generic. |
1854
|
|
|
|
|
|
|
|
1855
|
|
|
|
|
|
|
=item XYPlotErrorBars |
1856
|
|
|
|
|
|
|
|
1857
|
|
|
|
|
|
|
Required configuration variables: C, C |
1858
|
|
|
|
|
|
|
|
1859
|
|
|
|
|
|
|
Optional configuration variables: C |
1860
|
|
|
|
|
|
|
|
1861
|
|
|
|
|
|
|
Creates a plot using C as X-axis and all other variables as paramters. Calculates average and 95% confidence intervals for C simulation runs and plots error flags. This routine is fully generic, the confidence interval (95% by default) can be set with NSIGMAS. See eg/ErrorFlags.data for an example datafile. |
1862
|
|
|
|
|
|
|
|
1863
|
|
|
|
|
|
|
=item Histogram |
1864
|
|
|
|
|
|
|
|
1865
|
|
|
|
|
|
|
Required configuration variables: C |
1866
|
|
|
|
|
|
|
|
1867
|
|
|
|
|
|
|
Optional configuration variables: C, C, C |
1868
|
|
|
|
|
|
|
|
1869
|
|
|
|
|
|
|
Creates a histogram of the simulation results. This requires the simulator to produce raw data for the histograms in a tabular format. When specifying logscale X or XY for the plot, the histogram bins will be logarithmic. See eg/Histogram.data for an example. |
1870
|
|
|
|
|
|
|
The number of bins in the histogram must be specified via C. The width of the bins can be set with C, in which case C and C will be calculated. When C or C are set, C is calculated. It is possible to specify either C or C, the undefine value will be calculated. |
1871
|
|
|
|
|
|
|
|
1872
|
|
|
|
|
|
|
=back |
1873
|
|
|
|
|
|
|
|
1874
|
|
|
|
|
|
|
=head2 Preprocessing the raw results |
1875
|
|
|
|
|
|
|
|
1876
|
|
|
|
|
|
|
All of the above routines have hooks for simple functions that modify the C<@results> array. To call these functions, include them in the datafile with the C variable. e.g: |
1877
|
|
|
|
|
|
|
|
1878
|
|
|
|
|
|
|
PREPROCESSOR : modify_results |
1879
|
|
|
|
|
|
|
|
1880
|
|
|
|
|
|
|
All functions must be put in the PLUGINS folder or in the PostProcessors.pm module, and the template could be like this: |
1881
|
|
|
|
|
|
|
|
1882
|
|
|
|
|
|
|
sub modify_results { |
1883
|
|
|
|
|
|
|
foreach my $results_line (@results) { |
1884
|
|
|
|
|
|
|
#Do whatever is required |
1885
|
|
|
|
|
|
|
} |
1886
|
|
|
|
|
|
|
|
1887
|
|
|
|
|
|
|
} # End of modify_results |
1888
|
|
|
|
|
|
|
|
1889
|
|
|
|
|
|
|
=head1 DICTIONARY |
1890
|
|
|
|
|
|
|
|
1891
|
|
|
|
|
|
|
The F module contains descriptions of the parameters used in the simulation. These descriptions are used by the postprocessing routines to make the simulation results more readable. The dictionary is stored in an associative array called C. The description of the variable is stored in a field called 'title'; Descriptions of values are stored in fields indexed by the values. |
1892
|
|
|
|
|
|
|
|
1893
|
|
|
|
|
|
|
Following example illustrates the syntax: |
1894
|
|
|
|
|
|
|
|
1895
|
|
|
|
|
|
|
# Translate the parameter names and values into something meaningful |
1896
|
|
|
|
|
|
|
%Dictionary::make_nice=( |
1897
|
|
|
|
|
|
|
|
1898
|
|
|
|
|
|
|
_BUFTYPE => { |
1899
|
|
|
|
|
|
|
title=>'Buffer type', |
1900
|
|
|
|
|
|
|
0=>'Adjustable', |
1901
|
|
|
|
|
|
|
1=>'Fixed-length', |
1902
|
|
|
|
|
|
|
2=>'Multi-exit', |
1903
|
|
|
|
|
|
|
}, |
1904
|
|
|
|
|
|
|
_YOURVAR1 => { |
1905
|
|
|
|
|
|
|
title=>'Your description for variable 1', |
1906
|
|
|
|
|
|
|
}, |
1907
|
|
|
|
|
|
|
|
1908
|
|
|
|
|
|
|
_YOURVAR2 => { |
1909
|
|
|
|
|
|
|
title=>'Your description for variable 2', |
1910
|
|
|
|
|
|
|
'val1' => 'First value of _YOURVAR2', |
1911
|
|
|
|
|
|
|
'val3' => 'Second value of _YOURVAR2', |
1912
|
|
|
|
|
|
|
}, |
1913
|
|
|
|
|
|
|
|
1914
|
|
|
|
|
|
|
); |
1915
|
|
|
|
|
|
|
|
1916
|
|
|
|
|
|
|
=head1 OUTPUT FILES |
1917
|
|
|
|
|
|
|
|
1918
|
|
|
|
|
|
|
SynSim creates a run directory C<{SIMTYPE}->I<[datafile without .data]>. It copies all necessary template files and source files to this directory; all output files are generated in this directory. |
1919
|
|
|
|
|
|
|
|
1920
|
|
|
|
|
|
|
SynSim generates following files: |
1921
|
|
|
|
|
|
|
|
1922
|
|
|
|
|
|
|
=over 4 |
1923
|
|
|
|
|
|
|
|
1924
|
|
|
|
|
|
|
=item * |
1925
|
|
|
|
|
|
|
|
1926
|
|
|
|
|
|
|
Output files for all simulation runs. |
1927
|
|
|
|
|
|
|
|
1928
|
|
|
|
|
|
|
The names of these files are are C<{SIMTYPE}_C>I<[counter]_[simulation number]>C<.out> |
1929
|
|
|
|
|
|
|
|
1930
|
|
|
|
|
|
|
I is increased with every new combination of variables except for C. |
1931
|
|
|
|
|
|
|
|
1932
|
|
|
|
|
|
|
I is the position of the value in the C- list. |
1933
|
|
|
|
|
|
|
|
1934
|
|
|
|
|
|
|
=item * |
1935
|
|
|
|
|
|
|
|
1936
|
|
|
|
|
|
|
Combined output file for all values in a ';'-separated list. |
1937
|
|
|
|
|
|
|
|
1938
|
|
|
|
|
|
|
The names of these files are are C<{SIMTYPE}_C>I<[counter]>C<_.out> |
1939
|
|
|
|
|
|
|
|
1940
|
|
|
|
|
|
|
I is increased with every new combination of variables in ','-separated lists. |
1941
|
|
|
|
|
|
|
|
1942
|
|
|
|
|
|
|
Only the lines matching C (treated as a Perl regular expression) are put in this file. |
1943
|
|
|
|
|
|
|
|
1944
|
|
|
|
|
|
|
=item * |
1945
|
|
|
|
|
|
|
|
1946
|
|
|
|
|
|
|
Combined output file for all values in a ';'-separated list, with a header detailing all values for all variables. |
1947
|
|
|
|
|
|
|
|
1948
|
|
|
|
|
|
|
The names of these files are are C<{SIMTYPE}_C>I<[counter]>C<.res>, |
1949
|
|
|
|
|
|
|
|
1950
|
|
|
|
|
|
|
I is increased with every new combination of variables in ','-separated lists. |
1951
|
|
|
|
|
|
|
|
1952
|
|
|
|
|
|
|
Only the lines in the C<.out> files matching C (treated as a Perl regular expression) are put in this file. |
1953
|
|
|
|
|
|
|
|
1954
|
|
|
|
|
|
|
|
1955
|
|
|
|
|
|
|
=item * |
1956
|
|
|
|
|
|
|
|
1957
|
|
|
|
|
|
|
Separate input files for every item in a ';'-separated list. |
1958
|
|
|
|
|
|
|
|
1959
|
|
|
|
|
|
|
The names of these files are are C<{SIMTYPE}_>I<[simulation number]>C<.{EXT}> |
1960
|
|
|
|
|
|
|
|
1961
|
|
|
|
|
|
|
I is the position of the value in the list. |
1962
|
|
|
|
|
|
|
|
1963
|
|
|
|
|
|
|
These files are overwritten for every combination of variables in ','-separated lists. |
1964
|
|
|
|
|
|
|
|
1965
|
|
|
|
|
|
|
=back |
1966
|
|
|
|
|
|
|
|
1967
|
|
|
|
|
|
|
|
1968
|
|
|
|
|
|
|
=head1 WRITING POSTPROCESSING ROUTINES |
1969
|
|
|
|
|
|
|
|
1970
|
|
|
|
|
|
|
In a lot of cases you will want to create your own postprocessing routines. First of all, it is important to understand the SynSim output, so make sure you have read L"OUTPUT FILES">. Apart from that, there is a very simple API. |
1971
|
|
|
|
|
|
|
|
1972
|
|
|
|
|
|
|
=head2 PostProcLib |
1973
|
|
|
|
|
|
|
|
1974
|
|
|
|
|
|
|
=over |
1975
|
|
|
|
|
|
|
|
1976
|
|
|
|
|
|
|
=item * |
1977
|
|
|
|
|
|
|
All variables from the datafile are exported in a hash called C<%simdata> |
1978
|
|
|
|
|
|
|
|
1979
|
|
|
|
|
|
|
The value list for every variable is a Perl list. This means that you can access the values like this: |
1980
|
|
|
|
|
|
|
|
1981
|
|
|
|
|
|
|
my @importantvars = @{$simdata{_VAR1}} |
1982
|
|
|
|
|
|
|
|
1983
|
|
|
|
|
|
|
or |
1984
|
|
|
|
|
|
|
|
1985
|
|
|
|
|
|
|
my $importantvar = $simdata{_VAR1}[0] |
1986
|
|
|
|
|
|
|
|
1987
|
|
|
|
|
|
|
The same holds for configuration variables, but in general they only have a single value, so: |
1988
|
|
|
|
|
|
|
|
1989
|
|
|
|
|
|
|
my $x_variable = $simdata{XVAR} |
1990
|
|
|
|
|
|
|
|
1991
|
|
|
|
|
|
|
=item * |
1992
|
|
|
|
|
|
|
Easy-typing names |
1993
|
|
|
|
|
|
|
|
1994
|
|
|
|
|
|
|
Furthermore, every variable can be accessed using a short name. Instead of |
1995
|
|
|
|
|
|
|
|
1996
|
|
|
|
|
|
|
$simdata{_VAR} |
1997
|
|
|
|
|
|
|
|
1998
|
|
|
|
|
|
|
you can use |
1999
|
|
|
|
|
|
|
|
2000
|
|
|
|
|
|
|
$_var |
2001
|
|
|
|
|
|
|
|
2002
|
|
|
|
|
|
|
This is especially handy for configuration variables, e.g. |
2003
|
|
|
|
|
|
|
|
2004
|
|
|
|
|
|
|
$plotstyle |
2005
|
|
|
|
|
|
|
|
2006
|
|
|
|
|
|
|
instead of |
2007
|
|
|
|
|
|
|
|
2008
|
|
|
|
|
|
|
$simdata{PLOTSTYLE} |
2009
|
|
|
|
|
|
|
|
2010
|
|
|
|
|
|
|
=item * |
2011
|
|
|
|
|
|
|
Current set of values for the DOE |
2012
|
|
|
|
|
|
|
|
2013
|
|
|
|
|
|
|
The current set of values for the DOE is available in the hash C<%current_set_vals>. The keys are the variable names, the values the current value for the variable. |
2014
|
|
|
|
|
|
|
|
2015
|
|
|
|
|
|
|
Example: A simple DOE with 2 variables. |
2016
|
|
|
|
|
|
|
|
2017
|
|
|
|
|
|
|
_VAR1=1,2,3 |
2018
|
|
|
|
|
|
|
_VAR2=3,4 |
2019
|
|
|
|
|
|
|
|
2020
|
|
|
|
|
|
|
This DOE has 6 sets. After the fourth run, the values of the set will be: |
2021
|
|
|
|
|
|
|
|
2022
|
|
|
|
|
|
|
$current_set_vals{_VAR1}==2 |
2023
|
|
|
|
|
|
|
$current_set_vals{_VAR1}==4 |
2024
|
|
|
|
|
|
|
|
2025
|
|
|
|
|
|
|
The current set is also available in string format through C<$current_set_str>: |
2026
|
|
|
|
|
|
|
|
2027
|
|
|
|
|
|
|
$current_set_str eq '_VAR1-2-_VAR2-4' |
2028
|
|
|
|
|
|
|
|
2029
|
|
|
|
|
|
|
This is useful because this string is part of the name of the results file. |
2030
|
|
|
|
|
|
|
|
2031
|
|
|
|
|
|
|
If the configuration variable C is defined, there is an additional string C<$current_set_except_setvar_str>, which contains the current set except the C. This is usefull for conditional postprocessing, see e.g. CondXYPlot in PostProcessors.pm. |
2032
|
|
|
|
|
|
|
|
2033
|
|
|
|
|
|
|
=item * |
2034
|
|
|
|
|
|
|
Raw results |
2035
|
|
|
|
|
|
|
|
2036
|
|
|
|
|
|
|
The raw results of the last simulation run are available in the array C<@results>. Every element in this array is identical to the corresponding line in the output file for the given simulation run. |
2037
|
|
|
|
|
|
|
|
2038
|
|
|
|
|
|
|
It is also possible to access the results files: C<$results_file_name> contains the filename of the current results file, and C<@all_results_file_names> is a list of all results files so far. |
2039
|
|
|
|
|
|
|
|
2040
|
|
|
|
|
|
|
=item * |
2041
|
|
|
|
|
|
|
Deciding when to call the postprocessor. |
2042
|
|
|
|
|
|
|
|
2043
|
|
|
|
|
|
|
SynSim allows to call your postprocessing routine after every run. However, postprocessing generally only makes sense at certain points in the execution of the DOE. SynSim provide two variables: C<$last>, which indicates the end of a sweep, C<$verylast> which indicates the end of the DOE. |
2044
|
|
|
|
|
|
|
|
2045
|
|
|
|
|
|
|
=back |
2046
|
|
|
|
|
|
|
|
2047
|
|
|
|
|
|
|
In summary, following variables are exported: |
2048
|
|
|
|
|
|
|
|
2049
|
|
|
|
|
|
|
%simdata # contains all datafile variables |
2050
|
|
|
|
|
|
|
#and their values/value lists |
2051
|
|
|
|
|
|
|
@results # memory image of the results file |
2052
|
|
|
|
|
|
|
%current_set_vals # values for the current set |
2053
|
|
|
|
|
|
|
$current_set_str # same in string format |
2054
|
|
|
|
|
|
|
$current_set_except_setvar_str |
2055
|
|
|
|
|
|
|
$results_file_name |
2056
|
|
|
|
|
|
|
@all_results_file_names |
2057
|
|
|
|
|
|
|
$last # indicates end of a sweep |
2058
|
|
|
|
|
|
|
$verylast # indicates end of the DOE |
2059
|
|
|
|
|
|
|
|
2060
|
|
|
|
|
|
|
An example of how all this is used: |
2061
|
|
|
|
|
|
|
|
2062
|
|
|
|
|
|
|
sub YourRoutine { |
2063
|
|
|
|
|
|
|
|
2064
|
|
|
|
|
|
|
## Define your own variables. |
2065
|
|
|
|
|
|
|
## As every variable can have a list of values, |
2066
|
|
|
|
|
|
|
## $simdata{'_YOURVAR1'} is an array reference. |
2067
|
|
|
|
|
|
|
|
2068
|
|
|
|
|
|
|
my $yourvar=${$simdata{'_YOURVAR1'}}[0]; |
2069
|
|
|
|
|
|
|
|
2070
|
|
|
|
|
|
|
my @sweepvarvals=@{$simdata{$sweepvar}}; |
2071
|
|
|
|
|
|
|
|
2072
|
|
|
|
|
|
|
## $verylast indicates the end of all simulations |
2073
|
|
|
|
|
|
|
if(not $verylast) { |
2074
|
|
|
|
|
|
|
|
2075
|
|
|
|
|
|
|
## what to do for all simulations |
2076
|
|
|
|
|
|
|
|
2077
|
|
|
|
|
|
|
## $last indicates the end of a sweep |
2078
|
|
|
|
|
|
|
if($last) { |
2079
|
|
|
|
|
|
|
# Do something at the end of every sweep |
2080
|
|
|
|
|
|
|
} # if last |
2081
|
|
|
|
|
|
|
} else { |
2082
|
|
|
|
|
|
|
## On the very last run, collect the results into one nice plot |
2083
|
|
|
|
|
|
|
&gnuplot_combined($firstplotline,$plotlinetempl); |
2084
|
|
|
|
|
|
|
} |
2085
|
|
|
|
|
|
|
|
2086
|
|
|
|
|
|
|
} #END of YourRoutine() |
2087
|
|
|
|
|
|
|
|
2088
|
|
|
|
|
|
|
|
2089
|
|
|
|
|
|
|
=head2 Statistical analysis |
2090
|
|
|
|
|
|
|
|
2091
|
|
|
|
|
|
|
A module for basic statistical analysis is also available (C). Currently, the module provides 2 routines: |
2092
|
|
|
|
|
|
|
|
2093
|
|
|
|
|
|
|
=over 4 |
2094
|
|
|
|
|
|
|
|
2095
|
|
|
|
|
|
|
=item calc_statistics(): |
2096
|
|
|
|
|
|
|
|
2097
|
|
|
|
|
|
|
To calculate average, standard deviation, min. and max. of a set of values. |
2098
|
|
|
|
|
|
|
|
2099
|
|
|
|
|
|
|
Arguments: |
2100
|
|
|
|
|
|
|
|
2101
|
|
|
|
|
|
|
C<$file>: name of the results file. The routine requires the data to be in whitespace-separated columns. |
2102
|
|
|
|
|
|
|
|
2103
|
|
|
|
|
|
|
C<$par>: Determines if the data will be differentiated before processing ($par='DIFF') or not (any other value for $par). |
2104
|
|
|
|
|
|
|
Differentiation is defined as subtracting the previous value in the |
2105
|
|
|
|
|
|
|
array form the current value. A '0' is prepended to the array to avoid |
2106
|
|
|
|
|
|
|
an undefined first point. |
2107
|
|
|
|
|
|
|
|
2108
|
|
|
|
|
|
|
C<$datacol>: column to use for data |
2109
|
|
|
|
|
|
|
|
2110
|
|
|
|
|
|
|
C<$title>: optional, a title for the histogram |
2111
|
|
|
|
|
|
|
|
2112
|
|
|
|
|
|
|
C<$log>: optional, log of values before calculating histogram or not ('LOG' or '') |
2113
|
|
|
|
|
|
|
|
2114
|
|
|
|
|
|
|
|
2115
|
|
|
|
|
|
|
Use: |
2116
|
|
|
|
|
|
|
my $file="your_results_file.res"; |
2117
|
|
|
|
|
|
|
my $par='YOURPAR'; |
2118
|
|
|
|
|
|
|
my $datacol=2; |
2119
|
|
|
|
|
|
|
my %stats=%{&calc_statistics($file,[$par, $datacol])}; |
2120
|
|
|
|
|
|
|
|
2121
|
|
|
|
|
|
|
my $avg=$stats{$par}{AVG}; # average |
2122
|
|
|
|
|
|
|
my $stdev=$stats{$par}{STDEV}; # standard deviation |
2123
|
|
|
|
|
|
|
my $min=$stats{$par}{MIN}; # min. value in set |
2124
|
|
|
|
|
|
|
my $max=$stats{$par}{MAX}; # max. value in set |
2125
|
|
|
|
|
|
|
|
2126
|
|
|
|
|
|
|
=item build_histograms(): |
2127
|
|
|
|
|
|
|
|
2128
|
|
|
|
|
|
|
To build histograms. There are 3 extra arguments: |
2129
|
|
|
|
|
|
|
|
2130
|
|
|
|
|
|
|
$nbins: number of bins in the histogram |
2131
|
|
|
|
|
|
|
$min: force the value of the smallest bin (optional) |
2132
|
|
|
|
|
|
|
$max: force the value of the largest bin (optional) |
2133
|
|
|
|
|
|
|
|
2134
|
|
|
|
|
|
|
use: |
2135
|
|
|
|
|
|
|
my $par='DATA'; |
2136
|
|
|
|
|
|
|
my %hists=%{&build_histograms("your_results_file.res", |
2137
|
|
|
|
|
|
|
[$par,$datacol],$title,$log,$nbins,$min,$max)}; |
2138
|
|
|
|
|
|
|
|
2139
|
|
|
|
|
|
|
NOTE: Because the extra arguments are last, the $title and $log arguments can not be omitted. If not needed, supply ''. |
2140
|
|
|
|
|
|
|
|
2141
|
|
|
|
|
|
|
=back |
2142
|
|
|
|
|
|
|
|
2143
|
|
|
|
|
|
|
=head1 EXAMPLES |
2144
|
|
|
|
|
|
|
|
2145
|
|
|
|
|
|
|
Here are some examples of how to use SynSim for different types of simulators. |
2146
|
|
|
|
|
|
|
|
2147
|
|
|
|
|
|
|
=head2 1. Typical SPICE simulator |
2148
|
|
|
|
|
|
|
|
2149
|
|
|
|
|
|
|
Normal use: spice -b circuit.sp > circuit.out |
2150
|
|
|
|
|
|
|
|
2151
|
|
|
|
|
|
|
With SynSim: |
2152
|
|
|
|
|
|
|
|
2153
|
|
|
|
|
|
|
=over 4 |
2154
|
|
|
|
|
|
|
|
2155
|
|
|
|
|
|
|
=item 1. Create a template file |
2156
|
|
|
|
|
|
|
|
2157
|
|
|
|
|
|
|
Copy circuit.sp to TEMPLATES/SIMTYPE/circuit.templ |
2158
|
|
|
|
|
|
|
Replace all variable values with SynSim variable names. |
2159
|
|
|
|
|
|
|
|
2160
|
|
|
|
|
|
|
e.g. a MOS device line in SPICE: |
2161
|
|
|
|
|
|
|
|
2162
|
|
|
|
|
|
|
M1 VD VG VS VB nch w=10u l=10u |
2163
|
|
|
|
|
|
|
|
2164
|
|
|
|
|
|
|
becomes |
2165
|
|
|
|
|
|
|
|
2166
|
|
|
|
|
|
|
M1 VD VG VS VB _MODEL w=_WIDTH l=_LENGTH |
2167
|
|
|
|
|
|
|
|
2168
|
|
|
|
|
|
|
=item 2. Create a data file (e.g. circuit.data) |
2169
|
|
|
|
|
|
|
|
2170
|
|
|
|
|
|
|
TITLE: MOS drain current vs. length |
2171
|
|
|
|
|
|
|
SIMTYPE : circuit |
2172
|
|
|
|
|
|
|
COMMAND : spice -b inputfile > outputfile |
2173
|
|
|
|
|
|
|
|
2174
|
|
|
|
|
|
|
# Required for postprocessing |
2175
|
|
|
|
|
|
|
OUTPUT_FILTER_PATTERN : Id # keep only the drain current on the output file |
2176
|
|
|
|
|
|
|
ANALYSIS_TEMPLATE : SweepVar # default template for simple sweep |
2177
|
|
|
|
|
|
|
SWEEPVAR : _L # we sweep the length, the other variables are parameters |
2178
|
|
|
|
|
|
|
DATACOL: 2 # first col is the name |
2179
|
|
|
|
|
|
|
|
2180
|
|
|
|
|
|
|
_L = 1u,2u,5u,10u,20u,50u |
2181
|
|
|
|
|
|
|
_W = 10u,100u |
2182
|
|
|
|
|
|
|
_MODEL = nch |
2183
|
|
|
|
|
|
|
|
2184
|
|
|
|
|
|
|
There are more possible keywords, cf. L"DATAFILE DESCRIPTION">. |
2185
|
|
|
|
|
|
|
|
2186
|
|
|
|
|
|
|
=item 3. Now run synsim |
2187
|
|
|
|
|
|
|
|
2188
|
|
|
|
|
|
|
./synsim -p -i -v -f IDvsL.data |
2189
|
|
|
|
|
|
|
|
2190
|
|
|
|
|
|
|
-p to create plots |
2191
|
|
|
|
|
|
|
-i means interactive, so the plots are displayed during simulation |
2192
|
|
|
|
|
|
|
-v for verbose output |
2193
|
|
|
|
|
|
|
-f because the filename is not the default name |
2194
|
|
|
|
|
|
|
|
2195
|
|
|
|
|
|
|
SynSim will run 12 SPICE simulations and produce 1 plot with all results. |
2196
|
|
|
|
|
|
|
|
2197
|
|
|
|
|
|
|
=item 4. Results |
2198
|
|
|
|
|
|
|
|
2199
|
|
|
|
|
|
|
All results are stored in the run directory, in this case: |
2200
|
|
|
|
|
|
|
|
2201
|
|
|
|
|
|
|
circuit-IDvsL |
2202
|
|
|
|
|
|
|
|
2203
|
|
|
|
|
|
|
=back |
2204
|
|
|
|
|
|
|
|
2205
|
|
|
|
|
|
|
=head2 2. Simulator with command-line input and fixed output file |
2206
|
|
|
|
|
|
|
|
2207
|
|
|
|
|
|
|
Normal use: simplesim -a50 -b100 -c0.7 |
2208
|
|
|
|
|
|
|
|
2209
|
|
|
|
|
|
|
Output is saved in out.txt. |
2210
|
|
|
|
|
|
|
|
2211
|
|
|
|
|
|
|
With SynSim: |
2212
|
|
|
|
|
|
|
|
2213
|
|
|
|
|
|
|
=over 4 |
2214
|
|
|
|
|
|
|
|
2215
|
|
|
|
|
|
|
=item 1. Create a template file |
2216
|
|
|
|
|
|
|
|
2217
|
|
|
|
|
|
|
As simplesim does not take an input file, we create a wrapper simplesim.templ in TEMPLATES/SIMTYPE. |
2218
|
|
|
|
|
|
|
This file is actually a template for a simple perl script: |
2219
|
|
|
|
|
|
|
|
2220
|
|
|
|
|
|
|
system("simplesim -a_VAR1 -b_VAR2 -c_VAR3"); |
2221
|
|
|
|
|
|
|
system("cp out.txt $ARGV[0]"); |
2222
|
|
|
|
|
|
|
|
2223
|
|
|
|
|
|
|
=item 2. Create a data file (e.g. test.data) |
2224
|
|
|
|
|
|
|
|
2225
|
|
|
|
|
|
|
TITLE: simplesim test |
2226
|
|
|
|
|
|
|
SIMTYPE : simplesim |
2227
|
|
|
|
|
|
|
COMMAND : perl inputfile outputfile |
2228
|
|
|
|
|
|
|
|
2229
|
|
|
|
|
|
|
=item 3. Now run synsim |
2230
|
|
|
|
|
|
|
|
2231
|
|
|
|
|
|
|
./synsim -f test.data |
2232
|
|
|
|
|
|
|
|
2233
|
|
|
|
|
|
|
SynSim will run without any messages and produce no plots. |
2234
|
|
|
|
|
|
|
|
2235
|
|
|
|
|
|
|
=item 4. Results |
2236
|
|
|
|
|
|
|
|
2237
|
|
|
|
|
|
|
All results are stored in the run directory, in this case: |
2238
|
|
|
|
|
|
|
|
2239
|
|
|
|
|
|
|
simplesim-test |
2240
|
|
|
|
|
|
|
|
2241
|
|
|
|
|
|
|
=back |
2242
|
|
|
|
|
|
|
|
2243
|
|
|
|
|
|
|
=head2 3. Simulator without input file, configured at compile time |
2244
|
|
|
|
|
|
|
|
2245
|
|
|
|
|
|
|
Normal use: Modify values for #if and #ifdef constants in the header file; then compile and run. |
2246
|
|
|
|
|
|
|
|
2247
|
|
|
|
|
|
|
e.g.: |
2248
|
|
|
|
|
|
|
|
2249
|
|
|
|
|
|
|
vi bufsim3.h |
2250
|
|
|
|
|
|
|
g++ -o bufsim3 bufsim3.cc |
2251
|
|
|
|
|
|
|
./bufsim3 > outputfile |
2252
|
|
|
|
|
|
|
|
2253
|
|
|
|
|
|
|
With SynSim: |
2254
|
|
|
|
|
|
|
|
2255
|
|
|
|
|
|
|
=over 4 |
2256
|
|
|
|
|
|
|
|
2257
|
|
|
|
|
|
|
=item 1. Put the source code (bufsim3.cc) in SOURCES |
2258
|
|
|
|
|
|
|
|
2259
|
|
|
|
|
|
|
=item 2. Create a template file |
2260
|
|
|
|
|
|
|
|
2261
|
|
|
|
|
|
|
As bufsim3 does not take an input file, we create a wrapper bufsim3.templ in TEMPLATES/SIMTYPE. |
2262
|
|
|
|
|
|
|
This file is actually a template for a perl script that writes the header file, compiles and runs the code: |
2263
|
|
|
|
|
|
|
|
2264
|
|
|
|
|
|
|
open(HEADER,">bufsim3.h"); |
2265
|
|
|
|
|
|
|
print HEADER <<"ENDH"; |
2266
|
|
|
|
|
|
|
#define NBUFS _NBUFS |
2267
|
|
|
|
|
|
|
#define NPACKETS _NPACK |
2268
|
|
|
|
|
|
|
#AGGREGATE _AGGREGATE |
2269
|
|
|
|
|
|
|
ENDH |
2270
|
|
|
|
|
|
|
close HEADER; |
2271
|
|
|
|
|
|
|
|
2272
|
|
|
|
|
|
|
system("g++ -o bufsim3 bufsim3.cc"); |
2273
|
|
|
|
|
|
|
system("./bufsim3 $ARGV[0]"); |
2274
|
|
|
|
|
|
|
|
2275
|
|
|
|
|
|
|
=item 3. Create a datafile (e.g. Aggregate.data) |
2276
|
|
|
|
|
|
|
|
2277
|
|
|
|
|
|
|
TITLE: bufsim3 test (_NBUFS, _NPACK) # will be substituted by the values |
2278
|
|
|
|
|
|
|
SIMTYPE : bufsim3 |
2279
|
|
|
|
|
|
|
COMMAND : perl inputfile outputfile |
2280
|
|
|
|
|
|
|
|
2281
|
|
|
|
|
|
|
=item 4. Run synsim |
2282
|
|
|
|
|
|
|
|
2283
|
|
|
|
|
|
|
./synsim -w -v -f Aggregate.data |
2284
|
|
|
|
|
|
|
|
2285
|
|
|
|
|
|
|
SynSim will run verbose and flag all variables not defined in the datafile. |
2286
|
|
|
|
|
|
|
|
2287
|
|
|
|
|
|
|
=item 4. Results |
2288
|
|
|
|
|
|
|
|
2289
|
|
|
|
|
|
|
All results are stored in the run directory, in this case: |
2290
|
|
|
|
|
|
|
|
2291
|
|
|
|
|
|
|
bufsim3-Aggregate |
2292
|
|
|
|
|
|
|
|
2293
|
|
|
|
|
|
|
=back |
2294
|
|
|
|
|
|
|
|
2295
|
|
|
|
|
|
|
=head2 4. Circuit simulator which produces binary files. |
2296
|
|
|
|
|
|
|
|
2297
|
|
|
|
|
|
|
Normal use: spectre circuit.scs -raw circuit.raw |
2298
|
|
|
|
|
|
|
|
2299
|
|
|
|
|
|
|
With SynSim: |
2300
|
|
|
|
|
|
|
|
2301
|
|
|
|
|
|
|
=over 4 |
2302
|
|
|
|
|
|
|
|
2303
|
|
|
|
|
|
|
=item 1. Create a template file |
2304
|
|
|
|
|
|
|
|
2305
|
|
|
|
|
|
|
Copy circuit.scs to TEMPLATES/SIMTYPE/circuit.templ |
2306
|
|
|
|
|
|
|
Replace all variable values with SynSim variable names. |
2307
|
|
|
|
|
|
|
|
2308
|
|
|
|
|
|
|
=item 2. Create a data file |
2309
|
|
|
|
|
|
|
|
2310
|
|
|
|
|
|
|
The .raw file is a binary file, so it should not be touched. SynSim creates output files with extension .out, and combines these with the headers etc. (cf. L"OUTPUT FILES">). By keeping the extension .raw, the simulator output files will not be touched. |
2311
|
|
|
|
|
|
|
|
2312
|
|
|
|
|
|
|
In the datafile: |
2313
|
|
|
|
|
|
|
|
2314
|
|
|
|
|
|
|
TITLE: Spectre simulation with SPF output |
2315
|
|
|
|
|
|
|
EXT: .scs |
2316
|
|
|
|
|
|
|
COMMAND: spectre inputfile -raw outputfile.raw > outputfile |
2317
|
|
|
|
|
|
|
|
2318
|
|
|
|
|
|
|
=item 3. Run synsim |
2319
|
|
|
|
|
|
|
|
2320
|
|
|
|
|
|
|
SynSim will process C, but not C. |
2321
|
|
|
|
|
|
|
|
2322
|
|
|
|
|
|
|
=item 4. Postprocessing |
2323
|
|
|
|
|
|
|
|
2324
|
|
|
|
|
|
|
To access the binary files, you will have to write your own postprocessing routines. Most likely they will rely on an external tool to process the binary data. The files will be found in the run directory, and have names as described in L"OUTPUT FILES">, with the extra extension .raw. |
2325
|
|
|
|
|
|
|
|
2326
|
|
|
|
|
|
|
=back |
2327
|
|
|
|
|
|
|
|
2328
|
|
|
|
|
|
|
=head1 WRAPPERS |
2329
|
|
|
|
|
|
|
|
2330
|
|
|
|
|
|
|
If the simulator command line does not follow the format required by SynSim, a simple shell or perl wrapper is enough to make SynSim understand it. |
2331
|
|
|
|
|
|
|
The wrapper script must be stored under F; it should be written such that all relative paths are correct when it is executed under F. That is because SynSim runs in a subdirectory fo the project directory. This means that, if the command line contains relative paths to a subdirectory, these paths must be prepended with '../'. |
2332
|
|
|
|
|
|
|
|
2333
|
|
|
|
|
|
|
=head2 1. No is wrapper required if the simulator takes input from a file with an arbitrary name and sends output in any way to a file with an arbitrary name: |
2334
|
|
|
|
|
|
|
|
2335
|
|
|
|
|
|
|
$ simulator INPUTFILE OUTPUTFILE |
2336
|
|
|
|
|
|
|
$ simulator --o OUTPUTFILE INPUTFILE |
2337
|
|
|
|
|
|
|
$ simulator -i INPUTFILE > OUTPUTFILE |
2338
|
|
|
|
|
|
|
$ simulator < INPUTFILE > OUTPUTFILE |
2339
|
|
|
|
|
|
|
|
2340
|
|
|
|
|
|
|
=head2 2. Simulators with fixed input file name: |
2341
|
|
|
|
|
|
|
|
2342
|
|
|
|
|
|
|
Example: |
2343
|
|
|
|
|
|
|
|
2344
|
|
|
|
|
|
|
$ simulator sim.conf > sim.out |
2345
|
|
|
|
|
|
|
|
2346
|
|
|
|
|
|
|
Wrapper: |
2347
|
|
|
|
|
|
|
|
2348
|
|
|
|
|
|
|
$ simulator_wrapper.sh INPUTFILE > OUTPUTFILE |
2349
|
|
|
|
|
|
|
|
2350
|
|
|
|
|
|
|
The file C contains 2 lines: |
2351
|
|
|
|
|
|
|
|
2352
|
|
|
|
|
|
|
mv $1 sim.conf |
2353
|
|
|
|
|
|
|
simulator sim.conf |
2354
|
|
|
|
|
|
|
|
2355
|
|
|
|
|
|
|
=head2 3. Simulator with a fixed output file name: |
2356
|
|
|
|
|
|
|
|
2357
|
|
|
|
|
|
|
Example: |
2358
|
|
|
|
|
|
|
|
2359
|
|
|
|
|
|
|
$ simulator INPUTFILE |
2360
|
|
|
|
|
|
|
|
2361
|
|
|
|
|
|
|
The outputfile is called C. |
2362
|
|
|
|
|
|
|
|
2363
|
|
|
|
|
|
|
Wrapper: |
2364
|
|
|
|
|
|
|
|
2365
|
|
|
|
|
|
|
$ simulator_wrapper.sh INPUTFILE OUTPUTFILE |
2366
|
|
|
|
|
|
|
|
2367
|
|
|
|
|
|
|
The file C contains 2 lines: |
2368
|
|
|
|
|
|
|
|
2369
|
|
|
|
|
|
|
simulator $1 |
2370
|
|
|
|
|
|
|
mv output.txt $2 |
2371
|
|
|
|
|
|
|
|
2372
|
|
|
|
|
|
|
=head2 4. Simulator takes input file from a subdirectory |
2373
|
|
|
|
|
|
|
|
2374
|
|
|
|
|
|
|
Example: |
2375
|
|
|
|
|
|
|
|
2376
|
|
|
|
|
|
|
$ simulator ../Config/INPUTFILE > OUTPUTFILE |
2377
|
|
|
|
|
|
|
|
2378
|
|
|
|
|
|
|
The F directory is in this case at the same level of project directory. |
2379
|
|
|
|
|
|
|
|
2380
|
|
|
|
|
|
|
Wrapper: |
2381
|
|
|
|
|
|
|
|
2382
|
|
|
|
|
|
|
$ simulator_wrapper.sh INPUTFILE > OUTPUTFILE |
2383
|
|
|
|
|
|
|
|
2384
|
|
|
|
|
|
|
The file C contains 2 lines. Note the '../' prepended to the paths: |
2385
|
|
|
|
|
|
|
|
2386
|
|
|
|
|
|
|
cp $1 ../../Config |
2387
|
|
|
|
|
|
|
simulator ../../Config/INPUTFILE |
2388
|
|
|
|
|
|
|
|
2389
|
|
|
|
|
|
|
=head2 5. Simulator produces output in a subdirectory |
2390
|
|
|
|
|
|
|
|
2391
|
|
|
|
|
|
|
Example: |
2392
|
|
|
|
|
|
|
|
2393
|
|
|
|
|
|
|
$ simulator INPUTFILE OUTPUTFILE |
2394
|
|
|
|
|
|
|
|
2395
|
|
|
|
|
|
|
The C is generated in the F subdirectory. |
2396
|
|
|
|
|
|
|
|
2397
|
|
|
|
|
|
|
Wrapper: |
2398
|
|
|
|
|
|
|
|
2399
|
|
|
|
|
|
|
$ simulator_wrapper.sh INPUTFILE OUTPUTFILE |
2400
|
|
|
|
|
|
|
|
2401
|
|
|
|
|
|
|
The file C contains 2 lines. Note the '../' prepended to the path: |
2402
|
|
|
|
|
|
|
|
2403
|
|
|
|
|
|
|
simulator $1 $2 |
2404
|
|
|
|
|
|
|
cp ../Results/$2 . |
2405
|
|
|
|
|
|
|
|
2406
|
|
|
|
|
|
|
=head2 6. Simulator with command-line input and fixed output file |
2407
|
|
|
|
|
|
|
|
2408
|
|
|
|
|
|
|
$ simulator -a50 -b100 -c0.7 |
2409
|
|
|
|
|
|
|
|
2410
|
|
|
|
|
|
|
Output is saved in out.txt. |
2411
|
|
|
|
|
|
|
|
2412
|
|
|
|
|
|
|
In this case, there is no actual wrapper script. We will create a simple shell script simulator.templ in TEMPLATES/. This script will act as the input file. |
2413
|
|
|
|
|
|
|
|
2414
|
|
|
|
|
|
|
Wrapper: |
2415
|
|
|
|
|
|
|
|
2416
|
|
|
|
|
|
|
$ bash INPUTFILE OUTPUTFILE |
2417
|
|
|
|
|
|
|
|
2418
|
|
|
|
|
|
|
We need the explicit call to bash because the INPUTFILE does not have the -x flag set. |
2419
|
|
|
|
|
|
|
|
2420
|
|
|
|
|
|
|
The file simulator.templ in TEMPLATES/ contains 2 lines: |
2421
|
|
|
|
|
|
|
|
2422
|
|
|
|
|
|
|
simulator -a_VAR1 -b_VAR2 -c_VAR3 |
2423
|
|
|
|
|
|
|
cp out.txt $1 |
2424
|
|
|
|
|
|
|
|
2425
|
|
|
|
|
|
|
SynSim will create simulator.sh from this template file, and then will call bash to execute this shell script. |
2426
|
|
|
|
|
|
|
|
2427
|
|
|
|
|
|
|
=head2 7. Simulator requires multiple input files |
2428
|
|
|
|
|
|
|
|
2429
|
|
|
|
|
|
|
Example: |
2430
|
|
|
|
|
|
|
|
2431
|
|
|
|
|
|
|
$ simulator config.in topo.in > out.res |
2432
|
|
|
|
|
|
|
|
2433
|
|
|
|
|
|
|
Wrapper: |
2434
|
|
|
|
|
|
|
|
2435
|
|
|
|
|
|
|
$ perl INPUTFILE OUTPUTFILE |
2436
|
|
|
|
|
|
|
|
2437
|
|
|
|
|
|
|
Again, there is no actual wrapper script. The C template is in this case a perl script which contains itself templates for both input files. The script will create both input files, then run the simulator. |
2438
|
|
|
|
|
|
|
|
2439
|
|
|
|
|
|
|
A possible implementation of simulator.templ: |
2440
|
|
|
|
|
|
|
|
2441
|
|
|
|
|
|
|
#!/usr/bin/perl |
2442
|
|
|
|
|
|
|
#Template for simulator with multiple input files |
2443
|
|
|
|
|
|
|
my $config_templ=<<"ENDCONF"; |
2444
|
|
|
|
|
|
|
/* This is the config.in template */ |
2445
|
|
|
|
|
|
|
int var1 = _VAR1; |
2446
|
|
|
|
|
|
|
|
2447
|
|
|
|
|
|
|
... |
2448
|
|
|
|
|
|
|
|
2449
|
|
|
|
|
|
|
ENDCONF |
2450
|
|
|
|
|
|
|
|
2451
|
|
|
|
|
|
|
my $topo_templ=<<"ENDTOPO"; |
2452
|
|
|
|
|
|
|
;;This is the topo.in template |
2453
|
|
|
|
|
|
|
var2 = _VAR2 |
2454
|
|
|
|
|
|
|
|
2455
|
|
|
|
|
|
|
... |
2456
|
|
|
|
|
|
|
|
2457
|
|
|
|
|
|
|
ENDTOPO |
2458
|
|
|
|
|
|
|
|
2459
|
|
|
|
|
|
|
open CONF,">config.in"; |
2460
|
|
|
|
|
|
|
print CONF $config_templ; |
2461
|
|
|
|
|
|
|
close CONF; |
2462
|
|
|
|
|
|
|
|
2463
|
|
|
|
|
|
|
open TOPO, ">topo.in"; |
2464
|
|
|
|
|
|
|
print TOPO $topo_templ; |
2465
|
|
|
|
|
|
|
close TOPO; |
2466
|
|
|
|
|
|
|
|
2467
|
|
|
|
|
|
|
system("simulator config.in topo.in > $ARGV[0]"); |
2468
|
|
|
|
|
|
|
|
2469
|
|
|
|
|
|
|
#END of simulator.templ |
2470
|
|
|
|
|
|
|
|
2471
|
|
|
|
|
|
|
SynSim will create C and then will call C to run the script |
2472
|
|
|
|
|
|
|
|
2473
|
|
|
|
|
|
|
=head1 TO DO |
2474
|
|
|
|
|
|
|
|
2475
|
|
|
|
|
|
|
This module is still Alpha, a lot of work remains to be done to make it more user-friendly. The main tasks is to add a GUI. A prototype can be found on my web site, it is already useful but too early to include here. The next version will also make it easier to create your own postprocessing routines. |
2476
|
|
|
|
|
|
|
|
2477
|
|
|
|
|
|
|
=head1 AUTHOR |
2478
|
|
|
|
|
|
|
|
2479
|
|
|
|
|
|
|
Wim Vanderbauwhede |
2480
|
|
|
|
|
|
|
|
2481
|
|
|
|
|
|
|
=head1 COPYRIGHT |
2482
|
|
|
|
|
|
|
|
2483
|
|
|
|
|
|
|
Copyright (c) 2000,2002-2003 Wim Vanderbauwhede. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. |
2484
|
|
|
|
|
|
|
|
2485
|
|
|
|
|
|
|
=head1 SEE ALSO |
2486
|
|
|
|
|
|
|
|
2487
|
|
|
|
|
|
|
gnuplot L |
2488
|
|
|
|
|
|
|
|
2489
|
|
|
|
|
|
|
=cut |