4 # This is an interactive script that knows
5 # common ways to build Charm++ and AMPI.
7 # Authors: dooley, becker
12 # Turn off I/O buffering
17 # A subroutine that reads from input and returns a yes/no/default
21 if(lc($line) eq "y" || lc($line) eq "yes" ){
23 } elsif(lc($line) eq "n" || lc($line) eq "no" ){
25 } elsif( $line eq "" ){
32 # The beginning of the good stuff:
33 print "\n============================================================\n";
34 print "\nBegin interactive charm configuration ...\n";
35 print "If you are a poweruser expecting a list of options, please use ./build --help\n";
36 print "\n============================================================\n\n\n";
39 # Use uname to get the cpu type and OS information
43 #Variables to hold the portions of the configuration:
49 #remove newlines from these strings:
57 } elsif ($os eq "Darwin") {
59 } elsif ($os =~ m/BSD/ ) {
61 } elsif ($os =~ m/OSF1/ ) {
63 } elsif ($os =~ m/AIX/ ) {
65 } elsif ($os =~ m/CYGWIN/ ) {
66 print "Detected a Cygwin system\n";
67 print "This uses the gnu compiler by default,\n";
68 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";
78 # Determine architecture (x86, ppc, ...)
79 if($cpu =~ m/i[0-9]86/){
81 } elsif($cpu =~ m/x86\_64/){
83 } elsif($cpu =~ m/ia64/){
85 $nobs = "--no-build-shared";
86 } elsif($cpu =~ m/powerpc/){
88 } elsif($cpu =~ m/Power Mac/){
90 } elsif($cpu =~ m/ppc*/){
92 } elsif($cpu =~ m/alpha/){
99 my $converse_network_type = "net";
100 my $skip_choosing = "false";
102 print "Are you building to run just on the local machine, and not across multiple nodes? [";
103 if($arch_os eq "darwin") {
109 my $p = promptUserYN
();
110 if($p eq "yes" || ($arch_os eq "darwin" && $p eq "default")){
111 $converse_network_type = "multicore";
112 $skip_choosing = "true";
118 my $mpi_found = "false";
119 my $m = system("which mpicc mpiCC > /dev/null 2>/dev/null") / 256;
125 $m = system("which mpicc mpicxx > /dev/null 2>/dev/null") / 256;
128 $mpioption = "mpicxx";
131 # Give option of just using the mpi version if mpicc and mpiCC are found
132 if($skip_choosing eq "false" && $mpi_found eq "true"){
133 print "\nI found that you have an mpicc available in your path.\nDo you want to build Charm++ on this MPI? [y/N]: ";
134 my $p = promptUserYN
();
136 $converse_network_type = "mpi";
137 $skip_choosing = "true";
138 $options = "$options $mpioption";
142 if($skip_choosing eq "false") {
144 print "\nDo you have a special network interconnect? [y/N]: ";
145 my $p = promptUserYN
();
149 Choose an interconnect from below
: [1-10]
151 2) Infiniband
(ibverbs
)
158 9) Blue Gene
/P Native
164 while(my $line = <>){
167 $converse_network_type = "mpi";
169 } elsif($line eq "2"){
170 $converse_network_type = "net";
171 $options = "$options ibverbs ";
173 } elsif($line eq "3"){
174 $converse_network_type = "net";
175 $options = $options . "gm ";
177 } elsif($line eq "4"){
178 $converse_network_type = "net";
179 $options = $options . "mx ";
181 } elsif($line eq "5"){
184 } elsif($line eq "6"){
185 $arch = "mpi-crayxt";
187 } elsif($line eq "7"){
188 $arch = "gni-crayxe";
190 } elsif($line eq "8"){
191 $arch = "gni-crayxc";
193 } elsif($line eq "9"){
197 } elsif($line eq "10"){
198 $arch = "mpi-bluegenep";
201 } elsif($line eq "11"){
202 $arch = "pamilrts-bluegeneq";
205 print "Invalid option, please try again :P\n"
212 # construct an $arch string if we did not explicitly set one above
214 $arch = "${converse_network_type}-${arch_os}";
216 $arch = $arch . "-x86_64";
218 $arch = $arch . "-ia64";
220 $arch = $arch . "-ppc";
222 $arch = $arch . "-axp";
226 # Fixup $arch to match the inconsistent directories in src/archs
228 if($arch eq "net-darwin"){
229 $arch = "net-darwin-x86";
230 } elsif($arch eq "net-ppc-darwin"){
231 $arch = "net-darwin-ppc";
232 } elsif($arch eq "mpi-ppc-darwin"){
233 $arch = "mpi-darwin-ppc";
234 } elsif($arch eq "multicore-linux-x86_64"){
235 $arch = "multicore-linux64";
239 #================ Choose SMP/PXSHM =================================
241 # find what options are available
242 my $opts = `./build charm++ $arch help 2>&1 | grep "Supported options"`;
243 $opts =~ m/Supported options: (.*)/;
246 my $smp_opts = <<EOF;
247 1) single-threaded [default]
250 # only add the smp or pxshm options if they are available
251 my $counter = 1; # the last index used in the list
256 $smp_opts = $smp_opts . " $counter) SMP\n";
257 $smpIndex = $counter;
261 if($opts =~ m/pxshm/){
263 $smp_opts = $smp_opts . " $counter) POSIX Shared Memory\n";
264 $pxshmIndex = $counter;
268 print "How do you want to handle SMP/Multicore: [1-$counter]\n";
271 while(my $line = <>){
273 if($line eq "" || $line eq "1"){
275 } elsif($line eq $smpIndex){
276 $options = "$options smp ";
278 } elsif($line eq $pxshmIndex){
279 $options = "$options pxshm ";
286 #================ Choose Compiler =================================
288 # Lookup list of compilers
289 my $cs = `./build charm++ $arch help 2>&1 | grep "Supported compilers"`;
290 # prune away beginning of the line
291 $cs =~ m/Supported compilers: (.*)/;
293 # split the line into an array
294 my @c_list = split(" ", $cs);
296 # print list of compilers
300 print "\nDo you want to specify a compiler? [y/N]";
301 my $p = promptUserYN
();
303 print "Choose a compiler: [1-$numc] \n";
306 foreach my $c (@c_list){
312 while(my $line = <>){
314 if($line =~ m/([0-9]*)/ && $1 > 0 && $1 <= $numc){
315 $compilers = $c_list[$1-1];
318 print "Invalid option, please try again :P\n"
327 #================ Choose Options =================================
329 #Create a hash table containing descriptions of various options
330 my %explanations = ();
331 $explanations{"ooc"} = "Out-of-core execution support in Charm++";
332 $explanations{"tcp"} = "Charm++ over TCP instead of UDP for net versions. TCP is slower";
333 $explanations{"ifort"} = "Use Intel's ifort fortran compiler";
334 $explanations{"gfortran"} = "Use gfortran compiler for fortran";
335 $explanations{"g95"} = "Use g95 compiler";
336 $explanations{"ifort"} = "Use Intel's ifort fortran compiler";
337 $explanations{"pgf90"} = "Use Portland Group's pgf90 fortran compiler";
338 $explanations{"ifc"} = "Use Intel's ifc compiler";
339 $explanations{"ammasso"} = "Use native RDMA support on Ammasso interconnect";
340 $explanations{"syncft"} = "Use initial fault tolerance support";
341 $explanations{"mlogft"} = "Use message logging fault tolerance support";
342 $explanations{"causalft"} = "Use causal message logging fault tolerance support";
348 # Produce list of options
350 $opts = `./build charm++ $arch help 2>&1 | grep "Supported options"`;
351 # prune away beginning of line
352 $opts =~ m/Supported options: (.*)/;
355 my @option_list = split(" ", $opts);
358 # Prune out entries that would already have been chosen above, such as smp
359 my @option_list_pruned = ();
360 foreach my $o (@option_list){
361 if($o ne "smp" && $o ne "ibverbs" && $o ne "gm" && $o ne "mx"){
362 @option_list_pruned = (@option_list_pruned , $o);
367 @option_list_pruned = sort @option_list_pruned;
368 if (@option_list_pruned > 0) {
370 print "\nDo you want to specify any Charm++ build options, such as fortran compilers? [y/N]";
371 my $special_options = promptUserYN
();
373 if($special_options eq "yes"){
375 # print out list for user to select from
376 print "Please enter one or more numbers separated by spaces\n";
379 foreach my $o (@option_list_pruned){
380 my $exp = $explanations{$o};
382 # pad whitespace before options
383 for(my $j=0;$j<20-length($o);$j++){
390 print "\t$i)\tNone Of The Above\n";
392 my $num_options = @option_list_pruned;
394 while(my $line = <>){
396 $line =~ m/([0-9 ]*)/;
397 my @entries = split(" ",$1);
398 @entries = sort(@entries);
400 my $additional_options = "";
401 foreach my $e (@entries) {
402 if($e>=1 && $e<= $num_options){
403 my $estring = $option_list_pruned[$e-1];
404 $additional_options = "$additional_options $estring";
405 } elsif ($e == $num_options+1){
406 # user chose "None of the above"
407 # clear the options we may have seen before
408 $additional_options = " ";
412 # if the user input something reasonable, we can break out of this loop
413 if($additional_options ne ""){
414 $options = "$options ${additional_options} ";
423 # Choose compiler flags
426 Choose a set of compiler flags
[1-5]
429 3) production build
[default] --with
-production
430 4) production build w
/ projections
--with
-production
--enable
-tracing
435 my $compiler_flags = "";
437 while(my $line = <>){
441 } elsif($line eq "2"){
442 $compiler_flags = "-g -O0";
444 } elsif($line eq "4" ){
445 $compiler_flags = "--with-production --enable-tracing";
447 } elsif($line eq "3" || $line eq ""){
448 $compiler_flags = "--with-production";
450 } elsif($line eq "5"){
452 print "Enter compiler options: ";
455 $compiler_flags = $input_line;
459 print "Invalid option, please try again :P\n"
466 # Determine the target to build.
467 # We want this simple so we just give 2 options
472 What
do you want to build?
473 1) Charm
++ [default] (choose this
if you are building NAMD
)
474 2) Charm
++, AMPI
, ParFUM
, FEM
and other libraries
478 while(my $line = <>){
480 if($line eq "1" || $line eq ""){
483 } elsif($line eq "2"){
487 print "Invalid option, please try again :P\n"
492 # Determine whether to use a -j flag for faster building
496 Do you want to compile
in parallel?
501 5) Build with
-j16
[default]
507 while(my $line = <>) {
512 } elsif($line eq "2") {
515 } elsif($line eq "3") {
518 } elsif($line eq "4") {
521 } elsif($line eq "5" || $line eq "") {
524 } elsif($line eq "6") {
527 } elsif($line eq "7") {
531 print "Invalid option, please try again :P\n";
536 # Compose the build line
537 my $build_line = "./build $target $arch $compilers $options $j $nobs ${compiler_flags}\n";
540 # Save the build line in the log
541 open(BUILDLINE
, ">>smart-build.log");
542 print BUILDLINE
`date`;
543 print BUILDLINE
"Using the following build command:\n";
544 print BUILDLINE
"$build_line\n";
548 print "We have determined a suitable build line is:\n";
549 print "\t$build_line\n\n";
552 # Execute the build line if the appropriate architecture directory exists
553 print "Do you want to start the build now? [Y/n]";
554 my $p = promptUserYN
();
555 if($p eq "yes" || $p eq "default"){
556 if(-e
"src/arch/$arch"){
557 print "Building with: ${build_line}\n";
558 # Execute the build line
561 print "We could not figure out how to build charm with those options on this platform, please manually build\n";
562 print "Try something similar to: ${build_line}\n";