source: ThirdParty/mpqc_open/src/bin/mpqc/ccarun.in@ 860145

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_ChronosMutex Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion GeometryObjects Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg ThirdParty_MPQC_rebuilt_buildsystem TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since 860145 was 860145, checked in by Frederik Heber <heber@…>, 8 years ago

Merge commit '0b990dfaa8c6007a996d030163a25f7f5fc8a7e7' as 'ThirdParty/mpqc_open'

  • Property mode set to 100755
File size: 12.1 KB
Line 
1#!/usr/bin/env perl
2#eval 'exec perl $0 $*'
3# if 0;
4
5$prefix = '@prefix@';
6$exec_prefix = "@exec_prefix@";
7$bindir = "@bindir@";
8$scdatadir = "@scdatadir@";
9
10$pwd = `pwd`;
11chomp $pwd;
12$pwd =~ s/\/$//;
13
14use POSIX;
15
16# The path to the ccaffiene executable
17$ccafe = "@CCAFE_BIN@/ccafe-batch";
18
19# The threadgrp specialization
20$threadgrp = "none";
21
22# The mpi launch command
23$launch = "@CCALAUNCH@";
24
25# The number of tasks
26$ntask = 1;
27
28# A filename with a list of nodes.
29$nodefile = "";
30
31# A command line argument with a list of nodes.
32$nodes = "";
33
34# A format string to convert a node number to a node name
35$nodename = "%d";
36
37# The number of nodes each job will use.
38$nnodeperjob = "nnode";
39
40# The number of threads each process will use.
41$nthreadperproc = 1;
42
43# The number of processes to run on each node.
44$nprocpernode = 1;
45
46# The directory where the input file is to be found.
47$inputprefix = "";
48
49# The directory where the output file is to be placed.
50$outputprefix = "";
51
52# If true, then print out help info and exit
53$help = 0;
54
55# If true, then don't actually run anything
56$debug = 0;
57
58# If true, then print out extra info.
59$verbose = 0;
60
61# If true, then overwrite output files that seem up-to-date
62$rerun = 0;
63
64# If true, then do not overwrite any output file.
65$onlynew = 0;
66
67######################################################################
68
69use Getopt::Long;
70
71if (!GetOptions("launch=s" => \$launch,
72 "threadgrp=s" => \$threadgrp,
73 "nnodeperjob=i" => \$nnodeperjob,
74 "nthreadperproc=i" => \$nthreadperproc,
75 "nprocpernode=i" => \$nprocpernode,
76 "outputprefix=s" => \$outputprefix,
77 "inputprefix=s" => \$inputprefix,
78 "nodefile=s" => \$nodefile,
79 "nodes=s" => \$nodes,
80 "nodename=s" => \$nodename,
81 "help!" => \$help,
82 "rerun!" => \$rerun,
83 "onlynew!" => \$onlynew,
84 "debug!" => \$debug,
85 "verbose!" => \$verbose,
86 )) {
87 $help=1;
88}
89
90if ("$launch" eq "@" . "CCALAUNCH@") {
91 $launch = "mpirun [-hf %NODEFILE%] -n %NPROC% %CCARUNPROC% %CCAFE% --ccafe-rc %INPUT% --ccafe-remap-stdio --ccafe-outputdir %OUTPUT%";
92}
93
94$outputprefix =~ s/\/$//;
95$inputprefix =~ s/\/$//;
96
97######################################################################
98
99if ($help) {
100 print "Usage: $ARGV[0] [options] [rcfile1.in] [rcfile2.in] ...\n";
101 print "Options:\n";
102 print " --nnodeperjob n run with n nodes per job (value: $nnodeperjob)\n";
103 print " --nprocpernode n run with n procs per node (value: $nprocpernode)\n";
104 print " --nthreadperproc n use n threads per process (value: $nthreadperproc)\n";
105 print " --threadgrp grp use the given threading layer (value: $threadgrp)\n";
106 print " none: uses MPQC's default\n";
107 print " proc: does a single threaded run\n";
108 print " posix: use POSIX threads\n";
109 printf " --launch cmd use the given cmd to launch jobs--see below (value: %s)\n",
110 (($launch eq "")?"<not set>":$launch);
111 printf " --nodefile file a file listing nodes to use (value: %s)\n",
112 (($nodefile eq "")?"<not set>":$nodefile);
113 printf " --nodes nodes a command line list of machines to use (value: %s)\n",
114 (($nodes eq "")?"<not set>":$nodes);
115 printf " groups can be given as 8-10,12,15-17 for example\n";
116 printf " --nodename fmt converts node num to name (value: %s)\n", $nodename;
117 print " --rerun overwrite output file, even if up-to-date\n";
118 print " --onlynew do not overwrite output file, even if not up-to-date\n";
119 print " --inputprefix dir path to prefix input files with\n";
120 print " --outputprefix dir path to prefix output files with\n";
121 print " --debug don't actually run mpqc\n";
122 print " --help print this help\n";
123 print "\n";
124 print "The launch command can contain special strings that will be substituted.\n";
125 print "These are:\n";
126 print " %NPROC% The number of processes to start.\n";
127 print " %NODEFILE% The name of a file containing the node names.\n";
128 print " %NODELIST% A comma separated list of node names.\n";
129 print " For these last two, if they are contained within square brackets\n";
130 print " and a substitution is not available, then everything within the\n";
131 print " the brackets is removed.\n";
132 print "Examples of the launch argument:\n";
133 print " mpirun [-hf %NODEFILE%] -n %NPROC% %CCAFE% --ccafe-rc %INPUT% --ccafe-remap-stdio --ccafe-outp
134utdir %OUTPUT%\n";
135 print " mpirun [-H %NODELIST%] -n %NPROC% %CCAFE% --ccafe-rc %INPUT% --ccafe-remap-stdio --ccafe-outp
136utdir %OUTPUT%\n";
137 exit 0;
138}
139
140######################################################################
141
142@nodelist = ();
143if ($nodes ne "") {
144 $nodes =~ s/-/../g;
145 foreach my $i (eval $nodes) {
146 $nodelist[$#nodelist + 1] = sprintf "$nodename", $i;
147 }
148}
149elsif ("$nodefile" eq "" && exists($ENV{"PBS_NODEFILE"})) {
150 $nodefile=$ENV{"PBS_NODEFILE"};
151}
152if ("$nodefile" ne "" && -f "$nodefile") {
153 my %nodesfound = {};
154 open(NODEFILE,"<$nodefile");
155 while(<NODEFILE>) {
156 if (/(\S+)/) {
157 my $nodename = $1;
158 if (!exists($nodesfound{$nodename})) {
159 $nodelist[$#nodelist + 1] = $nodename;
160 $nodesfound{$nodename} = 1;
161 }
162 }
163 }
164 close(NODEFILE);
165}
166
167if ($#nodelist == -1) {
168 $nnode = 1;
169}
170else {
171 $nnode = $#nodelist + 1;
172}
173
174if ($nnodeperjob eq "nnode") {
175 $nnodeperjob = $nnode;
176}
177
178$nprocperjob = $nnodeperjob * $nprocpernode;
179
180$nnodeperjob = POSIX::ceil($nprocperjob / $nprocpernode);
181
182@jobnodes = ();
183%jobnnodes = {};
184%nodelist = {};
185%nodefile = {};
186$maxjobs = 0;
187while (($maxjobs + 1) * $nnodeperjob <= $nnode) {
188 $jobnnodes[$maxjobs++] = $nnodeperjob;
189}
190
191if ($maxjobs == 0) {
192 die "requested $nnodeperjob nodes but have $nnode nodes";
193}
194
195$nodesbegin = 0;
196foreach my $i (0..$maxjobs-1) {
197 my $nodesend = $nodesbegin + $jobnnodes[$i];
198 my @slice = (@nodelist)[$nodesbegin..($nodesend-1)];
199 $jobnodes{$i} = \@slice;
200 $nodesbegin = $nodesend;
201 foreach my $j (@slice) {
202 if ($nodelist{$i} eq "") { $nodelist{$i} = $j; }
203 else { $nodelist{$i} = sprintf "%s,%s", $nodelist{$i}, $j; }
204 }
205 $nodefile{$i} = ".tmp.nodefile.$$.$i";
206 open(NODEFILE,">" . $nodefile{$i});
207 foreach my $j (@slice) {
208 printf NODEFILE "%s\n", $j;
209 }
210 close(NODEFILE);
211}
212
213######################################################################
214
215if ($threadgrp eq "none" && $nthreadperproc > 1) {
216 $threadgrp = "posix";
217}
218
219if ($threadgrp eq "proc") {
220 $ENV{"THREADGRP"} = "<ProcThreadGrp>:()";
221}
222elsif ($threadgrp eq "posix") {
223 $ENV{"THREADGRP"} = "<PthreadThreadGrp>:(num_threads=$nthreadperproc)";
224}
225
226######################################################################
227
228$usingthreads = 0;
229if ($maxjobs > 1) {
230 require threads;
231 require threads::shared;
232 $usingthreads = 1;
233}
234
235######################################################################
236
237# autoflush output
238$| = 1;
239
240@allfiles = reverse(get_file_list());
241
242my @seqfiles : shared = ();
243my @files : shared = ();
244foreach my $file (@allfiles) {
245 $files[$#files+1] = $file;
246}
247
248printf "Running a maximum of %d jobs at a time.\n", $maxjobs;
249printf "Running %d processes per job.\n", $nprocperjob;
250printf "Running %d threads per process.\n", $nthreadperproc;
251foreach my $i (0..$maxjobs-1) {
252 print "Nodes in slot $i:";
253 foreach my $j (@{$jobnodes{$i}}) {
254 printf " \"%s\"", $j;
255 }
256 print "\n";
257}
258printenvvar("MESSAGEGRP");
259printenvvar("THREADGRP");
260printenvvar("MEMORYGRP");
261printenvvar("SCLIBDIR");
262printenvvar("INTEGRAL");
263
264$thecount = 0;
265$n = 0;
266
267if ($usingthreads) {
268 @threads = ();
269
270 foreach my $jobnum (0..$maxjobs-1) {
271 my $thr = threads->new(\&jobrunner, $jobnum);
272 $threads[$#threads+1] = $thr;
273 }
274
275 foreach my $thr (@threads) {
276 $thr->join();
277 }
278
279 @threads = ();
280}
281else {
282 foreach my $jobnum (0..$maxjobs-1) {
283 jobrunner($jobnum);
284 }
285}
286
287foreach $i (values(%nodefile)) {
288 unlink "$i";
289}
290
291sub get_next_file {
292 my $jobnum = shift;
293 lock(@seqfiles) if ($usingthreads);
294 if ($#seqfiles >= 0 && $jobnum == 0) {
295 return pop(@seqfiles);
296 }
297 lock(@files) if ($usingthreads);
298 if ($#files >= 0) {
299 return pop(@files);
300 }
301 return "";
302}
303
304sub jobrunner {
305 my $jobslot = shift;
306
307 my $file;
308
309 while ( ($file = get_next_file($jobslot)) ne "") {
310 $file =~ s/\.in//;
311 $tmp_out = "$pwd/$outputprefix/$file.tmp";
312 $ENV{"CCACHEM_RESULTS_DIR"} = "$tmp_out";
313 my $in = "$inputprefix/$file.in";
314 my $cmd = "$launch";
315 $cmd =~ s/%CCAFE%/$ccafe/;
316 $cmd =~ s/%NPROC%/$nprocperjob/;
317 $cmd =~ s/%INPUT%/$in/;
318
319 my $ccarunproc = "$scdatadir/ccarunproc $ccafe";
320 if (exists($ENV{THREADGRP})) {
321 $ccarunproc = "$ccarunproc " . &isoencode("$ENV{THREADGRP}");
322 }
323 else {
324 $ccarunproc = "$ccarunproc none";
325 }
326 # no mem/message groups for now
327 $ccarunproc = "$ccarunproc none none";
328 #results dir
329 $ccarunproc = "$ccarunproc " . &isoencode("$ENV{CCACHEM_RESULTS_DIR}");
330
331 $cmd =~ s|%CCARUNPROC%|$ccarunproc|;
332
333 $cmd = substitute_optional_parameter($cmd, "%OUTPUT%", "$tmp_out");
334 $cmd = substitute_optional_parameter($cmd, "%NODELIST%", $nodelist{$jobslot});
335 $cmd = substitute_optional_parameter($cmd, "%NODEFILE%", $nodefile{$jobslot});
336
337 mkdir $tmp_out;
338 printf "starting in slot %d: %s\n", $jobslot, "$cmd";
339 $cmd = "true" if ($debug);
340 $pid = fork();
341 if ($pid == 0) {
342 exec("$cmd");
343 die "exec returned";
344 }
345 waitpid($pid,'');
346
347 rename "$tmp_out/pOut0", "$pwd/$outputprefix/$file.out";
348 unlink "$tmp_out/pErr0";
349 rename "$tmp_out/results.txt", "$pwd/$outputprefix/$file.results";
350 rmdir "$tmp_out";
351 }
352}
353
354sub get_file_list {
355 my @dirfiles;
356 my @argfiles;
357
358 if ($readdir ne "") {
359 opendir(DIR,"$readdir");
360 @tdirfiles = sort(readdir(DIR));
361 foreach my $j (@tdirfiles) {
362 if ($j =~ /\.in$/) {
363 $dirfiles[$#dirfiles+1] = $j;
364 }
365 }
366 closedir(DIR);
367 }
368
369 @argfiles = sort(@ARGV);
370
371 my @allfiles = (@dirfiles, @argfiles);
372
373 my @files;
374
375 foreach my $infile (@allfiles) {
376 my $out = outfile("$infile");
377 $out = "$outputprefix$out";
378 $in = "$inputprefix$infile";
379 if (!$rerun
380 && (-f "$out")
381 && ($onlynew
382 || (-M "$out" < -M "$in" && (! -f "$ccafe" || -M "$out" < -M "$mpqc")))) {
383 if ($verbose) {
384 print "$in: skipping: $out up-to-date\n";
385 }
386 }
387 else {
388 if ($verbose) {
389 print "$in: will be run\n";
390 }
391 $files[$#files+1] = "$infile";
392 }
393 }
394
395 return @files;
396}
397
398sub outfile {
399 my $in = shift;
400
401 my $outbase = "$in";
402 $outbase =~ s/\.[^.]*$//;
403 $outbase = sprintf "%s.out", "$outbase";
404 my $out;
405
406 if ($uniqout) {
407 $out = "$outbase";
408 my $outversion = 1;
409 while (-f "$out") {
410 $outversion++;
411 $out = sprintf "%s.%02d", "$outbase", $outversion;
412 }
413 }
414
415 return "$out";
416}
417
418sub printenvvar {
419 my $envvar = shift;
420 if (exists($ENV{$envvar})) {
421 printf "Using %s = \"%s\"\n", $envvar, $ENV{$envvar};
422 }
423}
424
425sub substitute_optional_parameter {
426 my $str = shift;
427 my $name = shift;
428 my $value = shift;
429 if ($value ne "") {
430 $str =~ s/\[([^[]*$name[^[]*)\]/$1/;
431 $str =~ s/$name/$value/;
432 }
433 else {
434 $str =~ s/\[([^[]*$name[^[]*)\]//;
435 }
436 return $str;
437}
438
439sub isoencode {
440 my $str = shift;
441 $str =~ s/ /%20/g;
442 $str =~ s/\</%3c/g;
443 $str =~ s/\>/%3e/g;
444 $str =~ s/\[/%5b/g;
445 $str =~ s/\]/%5d/g;
446 $str =~ s/\$/%24/g;
447 $str =~ s/:/%38/g;
448 $str =~ s/\(/%28/g;
449 $str =~ s/\)/%29/g;
450 return $str;
451}
Note: See TracBrowser for help on using the repository browser.