Revert "build: modify to use arch from user specified version if it exists"
[charm.git] / smart-build.pl
blob86ef4e9953ce837339e60b3f044357b7ebf36670
1 #!/usr/bin/perl
4 # This is an interactive script that knows
5 # common ways to build Charm++ and AMPI.
7 # Authors: dooley, becker
10 # Turn off I/O buffering
11 $| = 1;
15 # A subroutine that reads from input and returns a yes/no/default
16 sub promptUserYN {
17 while($line = <>){
18 chomp $line;
19 if(lc($line) eq "y" || lc($line) eq "yes" ){
20 return "yes";
21 } elsif(lc($line) eq "n" || lc($line) eq "no" ){
22 return "no";
23 } elsif( $line eq "" ){
24 return "default";
30 # The beginning of the good stuff:
31 print "\n============================================================\n";
32 print "\nBegin interactive charm configuration ...\n";
33 print "If you are a poweruser expecting a list of options, please use ./build --help\n";
34 print "\n============================================================\n\n\n";
37 # Use uname to get the cpu type and OS information
38 $os = `uname -s`;
39 $cpu = `uname -m`;
41 #Variables to hold the portions of the configuration:
42 $nobs = "";
43 $arch = "";
44 $compilers = "";
45 $options = "";
47 #remove newlines from these strings:
48 chomp($os);
49 chomp ($cpu);
52 # Determine OS kernel
53 if ($os eq "Linux") {
54 $arch_os = "linux";
55 } elsif ($os eq "Darwin") {
56 $arch_os = "darwin";
57 } elsif ($os =~ m/BSD/ ) {
58 $arch_os = "linux";
59 } elsif ($os =~ m/OSF1/ ) {
60 $arch_os = "linux";
61 } elsif ($os =~ m/AIX/ ) {
62 $arch = "mpi-sp";
63 } elsif ($os =~ m/CYGWIN/ ) {
64 print "Detected a Cygwin system\n";
65 print "This uses the gnu compiler by default,\n";
66 print "To build with Microsoft Visual C++ compiler, use net-win32. Please refer to README.win32 for the details on setting up VC++ under cygwin.\n\n";
67 $arch_os = "cygwin";
72 # Determine architecture (x86, ppc, ...)
73 if($cpu =~ m/i[0-9]86/){
74 $x86 = 1;
75 } elsif($cpu =~ m/x86\_64/){
76 $amd64 = 1;
77 } elsif($cpu =~ m/ia64/){
78 $ia64 = 1;
79 $nobs = "--no-build-shared";
80 } elsif($cpu =~ m/powerpc/){
81 $ppc = 1;
82 } elsif($cpu =~ m/Power Mac/){
83 $ppc = 1;
84 } elsif($cpu =~ m/ppc*/){
85 $ppc = 1;
86 } elsif($cpu =~ m/alpha/){
87 $alpha = 1;
92 # default to net
93 $converse_network_type = "net";
96 # check for MPI
98 $skip_choosing = "false";
100 $mpi_found = "false";
101 $m = system("which mpicc mpiCC > /dev/null 2>/dev/null") / 256;
102 if($m == 0){
103 $mpi_found = "true";
104 $mpioption = "";
106 $m = system("which mpicc mpicxx > /dev/null 2>/dev/null") / 256;
107 if($m == 0){
108 $mpi_found = "true";
109 $mpioption = "mpicxx";
112 # Give option of just using the mpi version if mpicc and mpiCC are found
113 if($mpi_found eq "true"){
114 print "\nI found that you have an mpicc available in your path.\nDo you want to build Charm++ on this MPI? [y/N]: ";
115 $p = promptUserYN();
116 if($p eq "yes"){
117 $converse_network_type = "mpi";
118 $skip_choosing = "true";
119 $options = "$options $mpioption";
123 if($skip_choosing eq "false") {
125 print "\nDo you have a special network interconnect? [y/N]: ";
126 $p = promptUserYN();
127 if($p eq "yes"){
128 print << "EOF";
130 Choose an interconnect from below: [1-11]
131 1) MPI
132 2) Infiniband (native ibverbs alpha version)
133 3) Myrinet GM
134 4) Myrinet MX
135 5) LAPI
136 6) Cray XT3, XT4
137 7) Cray XT5
138 8) Cray XE, XK
139 9) Bluegene/L Native (only at T. J. Watson)
140 10) Bluegene/L MPI
141 11) Bluegene/P Native
142 12) Bluegene/P MPI
143 13) VMI
147 while($line = <>){
148 chomp $line;
149 if($line eq "1"){
150 $converse_network_type = "mpi";
151 last;
152 } elsif($line eq "2"){
153 $converse_network_type = "net";
154 $options = "$options ibverbs ";
155 last;
156 } elsif($line eq "3"){
157 $converse_network_type = "net";
158 $options = $options . "gm ";
159 last;
160 } elsif($line eq "4"){
161 $converse_network_type = "net";
162 $options = $options . "mx ";
163 last;
164 } elsif($line eq "5"){
165 $arch = "lapi";
166 last;
167 } elsif($line eq "6"){
168 $arch = "mpi-crayxt3";
169 last;
170 } elsif($line eq "7"){
171 $arch = "mpi-crayxt";
172 last;
173 } elsif($line eq "8"){
174 $arch = "gemini_gni-crayxe";
175 last;
176 } elsif($line eq "9"){
177 $arch = "bluegenel";
178 $compilers = "xlc ";
179 $nobs = "--no-build-shared";
180 last;
181 } elsif($line eq "10"){
182 $arch = "mpi-bluegenel";
183 $compilers = "xlc ";
184 $nobs = "--no-build-shared";
185 last;
186 } elsif($line eq "11"){
187 $arch = "bluegenep";
188 $compilers = "xlc ";
189 last;
190 } elsif($line eq "12"){
191 $arch = "mpi-bluegenep";
192 $compilers = "xlc ";
193 last;
194 } elsif($line eq "13"){
195 $converse_network_type = "vmi";
196 last;
197 } else {
198 print "Invalid option, please try again :P\n"
205 # construct an $arch string if we did not explicitly set one above
206 if($arch eq ""){
207 $arch = "${converse_network_type}-${arch_os}";
208 if($amd64) {
209 $arch = $arch . "-x86_64";
210 } elsif($ia64){
211 $arch = $arch . "-ia64";
212 } elsif($ppc){
213 $arch = $arch . "-ppc";
214 } elsif($alpha){
215 $arch = $arch . "-axp";
219 # Fixup $arch to match the inconsistent directories in src/archs
221 if($arch eq "net-darwin"){
222 $arch = "net-darwin-x86";
223 } elsif($arch eq "net-ppc-darwin"){
224 $arch = "net-darwin-ppc";
225 } elsif($arch eq "mpi-ppc-darwin"){
226 $arch = "mpi-darwin-ppc";
227 } elsif($arch eq "multicore-linux-x86_64"){
228 $arch = "multicore-linux64";
235 #================ Choose SMP/PXSHM =================================
237 # find what options are available
238 $opts = `./build charm++ $arch help 2>&1 | grep "Supported options"`;
239 $opts =~ m/Supported options: (.*)/;
240 $opts = $1;
243 #always provide multicore and single-threaded versions
244 print << "EOF";
245 How do you want to handle SMP/Multicore: [1-4]
246 1) single-threaded [default]
247 2) multicore(single node only)
250 # only add the smp or pxshm options if they are available
251 $counter = 3; # the next index used in the list
253 $smpIndex = -1;
254 if($opts =~ m/smp/){
255 print " $counter) SMP\n";
256 $smpIndex = $counter;
257 $counter ++;
260 $pxshmIndex = -1;
261 if($opts =~ m/pxshm/){
262 print " $counter) POSIX Shared Memory\n";
263 $pxshmIndex = $counter;
264 $counter ++;
267 while($line = <>){
268 chomp $line;
269 if($line eq "1" || $line eq ""){
270 last;
271 } elsif($line eq "2"){
272 $converse_network_type = "multicore";
273 last;
274 } elsif($line eq $smpIndex){
275 $options = "$options smp ";
276 last;
277 } elsif($line eq $pxshmIndex){
278 $options = "$options pxshm ";
279 last;
289 #================ Choose Compiler =================================
291 # Lookup list of compilers
292 $cs = `./build charm++ $arch help 2>&1 | grep "Supported compilers"`;
293 # prune away beginning of the line
294 $cs =~ m/Supported compilers: (.*)/;
295 $cs = $1;
296 # split the line into an array
297 @c_list = split(" ", $cs);
299 # print list of compilers
300 $numc = @c_list;
302 if ($numc > 0) {
303 print "\nDo you want to specify a compiler? [y/N]";
304 $p = promptUserYN();
305 if($p eq "yes" ){
306 print "Choose a compiler: [1-$numc] \n";
308 $i = 1;
309 foreach $c (@c_list){
310 print "\t$i)\t$c\n";
311 $i++;
314 # Choose compiler
315 while($line = <>){
316 chomp $line;
317 if($line =~ m/([0-9]*)/ && $1 > 0 && $1 <= $numc){
318 $compilers = $c_list[$1-1];
319 last;
320 } else {
321 print "Invalid option, please try again :P\n"
330 #================ Choose Options =================================
332 #Create a hash table containing descriptions of various options
333 %explanations = ();
334 $explanations{"ooc"} = "Out-of-core execution support in Charm++";
335 $explanations{"tcp"} = "Charm++ over TCP instead of UDP for net versions. TCP is slower";
336 $explanations{"ifort"} = "Use Intel's ifort fortran compiler";
337 $explanations{"gfortran"} = "Use gfortran compiler for fortran";
338 $explanations{"g95"} = "Use g95 compiler";
339 $explanations{"ifort"} = "Use Intel's ifort fortran compiler";
340 $explanations{"pgf90"} = "Use Portland Group's pgf90 fortran compiler";
341 $explanations{"ifc"} = "Use Intel's ifc compiler";
342 $explanations{"ammasso"} = "Use native RDMA support on Ammasso interconnect";
343 $explanations{"syncft"} = "Use initial fault tolerance support";
344 $explanations{"mlogft"} = "Use message logging fault tolerance support";
345 $explanations{"causalft"} = "Use causal message logging fault tolerance support";
351 # Produce list of options
353 $opts = `./build charm++ $arch help 2>&1 | grep "Supported options"`;
354 # prune away beginning of line
355 $opts =~ m/Supported options: (.*)/;
356 $opts = $1;
358 @option_list = split(" ", $opts);
361 # Prune out entries that would already have been chosen above, such as smp
362 @option_list_pruned = ();
363 foreach $o (@option_list){
364 if($o ne "smp" && $o ne "ibverbs" && $o ne "gm" && $o ne "mx"){
365 @option_list_pruned = (@option_list_pruned , $o);
369 # sort the list
370 @option_list_pruned = sort @option_list_pruned;
371 if (@option_list_pruned > 0) {
373 print "\nDo you want to specify any Charm++ build options, such as fortran compilers? [y/N]";
374 $special_options = promptUserYN();
376 if($special_options eq "yes"){
378 # print out list for user to select from
379 print "Please enter one or more numbers separated by spaces\n";
380 print "Choices:\n";
381 $i = 1;
382 foreach $o (@option_list_pruned){
383 $exp = $explanations{$o};
384 print "\t$i)\t$o";
385 # pad whitespace before options
386 for($j=0;$j<20-length($o);$j++){
387 print " ";
389 print ": $exp";
390 print "\n";
391 $i++;
393 print "\t$i)\tNone Of The Above\n";
395 $num_options = @option_list_pruned;
397 while($line = <>){
398 chomp $line;
399 $line =~ m/([0-9 ]*)/;
400 @entries = split(" ",$1);
401 @entries = sort(@entries);
403 $additional_options = "";
404 foreach $e (@entries) {
405 if($e>=1 && $e<= $num_options){
406 $estring = $option_list_pruned[$e-1];
407 $additional_options = "$additional_options $estring";
408 } elsif ($e == $num_options+1){
409 # user chose "None of the above"
410 # clear the options we may have seen before
411 $additional_options = " ";
415 # if the user input something reasonable, we can break out of this loop
416 if($additional_options ne ""){
417 $options = "$options ${additional_options} ";
418 last;
433 # Choose compiler flags
434 print << "EOF";
436 Choose a set of compiler flags [1-5]
437 1) none
438 2) debug mode -g -O0
439 3) production build [default] --with-production
440 4) production build w/ projections --with-production --enable-tracing
441 5) custom
445 $compiler_flags = "";
447 while($line = <>){
448 chomp $line;
449 if($line eq "1"){
450 last;
451 } elsif($line eq "2"){
452 $compiler_flags = "-g -O0";
453 last;
454 } elsif($line eq "4" ){
455 $compiler_flags = "--with-production --enable-tracing";
456 last;
457 } elsif($line eq "3" || $line eq ""){
458 $compiler_flags = "--with-production";
459 last;
460 } elsif($line eq "5"){
462 print "Enter compiler options: ";
463 $input_line = <>;
464 chomp($input_line);
465 $compiler_flags = $input_line;
467 last;
468 } else {
469 print "Invalid option, please try again :P\n"
476 # Determine the target to build.
477 # We want this simple so we just give 2 options
478 $target = "";
480 print << "EOF";
482 What do you want to build?
483 1) Charm++ [default] (choose this if you are building NAMD)
484 2) Charm++, AMPI, ParFUM, FEM and other libraries
488 while($line = <>){
489 chomp $line;
490 if($line eq "1" || $line eq ""){
491 $target = "charm++";
492 last;
493 } elsif($line eq "2"){
494 $target = "LIBS";
495 last;
496 } else {
497 print "Invalid option, please try again :P\n"
502 # Determine whether to use a -j flag for faster building
503 $j = "";
504 print << "EOF";
506 Do you want to compile in parallel?
507 1) No
508 2) Build with -j2
509 3) Build with -j4
510 4) Build with -j8
511 5) Build with -j16 [default]
512 6) Build with -j32
513 7) Build with -j
517 while($line = <>) {
518 chomp $line;
519 if($line eq "1"){
520 $j = "";
521 last;
522 } elsif($line eq "2") {
523 $j = "-j2";
524 last;
525 } elsif($line eq "3") {
526 $j = "-j4";
527 last;
528 } elsif($line eq "4") {
529 $j = "-j8";
530 last;
531 } elsif($line eq "5" || $line eq "") {
532 $j = "-j16";
533 last;
534 } elsif($line eq "6") {
535 $j = "-j32";
536 last;
537 } elsif($line eq "7") {
538 $j = "-j";
539 last;
540 } else {
541 print "Invalid option, please try again :P\n";
546 # Compose the build line
547 $build_line = "./build $target $arch $compilers $options $smp $j $nobs ${compiler_flags}\n";
550 # Save the build line in the log
551 open(BUILDLINE, ">>smart-build.log");
552 print BUILDLINE `date`;
553 print BUILDLINE "Using the following build command:\n";
554 print BUILDLINE "$build_line\n";
555 close(BUILDLINE);
558 print "We have determined a suitable build line is:\n";
559 print "\t$build_line\n\n";
562 # Execute the build line if the appropriate architecture directory exists
563 print "Do you want to start the build now? [Y/n]";
564 $p = promptUserYN();
565 if($p eq "yes" || $p eq "default"){
566 if(-e "src/arch/$arch"){
567 print "Building with: ${build_line}\n";
568 # Execute the build line
569 system($build_line);
570 } else {
571 print "We could not figure out how to build charm with those options on this platform, please manually build\n";
572 print "Try something similar to: ${build_line}\n";