Added descriptions for some options
[charm.git] / smart-build.pl
1 #!/usr/bin/perl
2
3
4 # This is an interactive script that knows
5 # common ways to build Charm++ and AMPI.
6 #
7 # Authors: dooley, becker
8
9
10 # Turn off I/O buffering
11 $| = 1;
12
13 print "\nBegin interactive charm configuration\n";
14 print "If you are a poweruser expecting a list of options, please use ./build --help\n\n\n";
15
16
17
18 # Use uname to get the cpu type and OS information
19 $os = `uname -s`;
20 $cpu = `uname -m`;
21
22 #Variables to hold the portions of the configuration:
23 $nobs = "";
24 $arch = "";
25 $compilers = "";
26 $options = "";
27
28 #remove newlines from these strings:
29 chomp($os);
30 chomp ($cpu);
31
32
33 # Determine OS kernel
34 if ($os eq "Linux") {
35   print "Detected a linux kernel\n";
36   $arch_os = "linux";
37 } elsif ($os eq "Darwin") {
38   print "Detected a darwin kernel\n";
39   $arch_os = "darwin";
40 } elsif ($os =~ m/BSD/ ) {
41   print "Detected a BSD kernel\n";
42   $arch_os = "linux";
43 } elsif ($os =~ m/OSF1/ ) {
44   print "Detected an OSF1 kernel\n";
45   $arch_os = "linux";
46 } elsif ($os =~ m/AIX/ ) {
47   print "Detected an AIX kernel\n";
48   $arch = "mpi-sp";
49 }
50
51
52
53 # Determine architecture (x86, ppc, ...)
54 if($cpu =~ m/i[0-9]86/){
55   print "Detected architecture x86\n";
56   $x86 = 1;
57 } elsif($cpu =~ m/x86\_64/){
58   print "Detected architecture x86_64\n";
59   $amd64 = 1;
60 } elsif($cpu =~ m/ia64/){
61   print "Detected architecture ia64\n";
62   $ia64 = 1;
63   $nobs = "--no-build-shared";
64 } elsif($cpu =~ m/powerpc/){
65   print "Detected architecture ppc\n";
66   $ppc = 1;
67 } elsif($cpu =~ m/Power Mac/){
68   print "Detected architecture ppc\n";
69   $ppc = 1;
70 } elsif($cpu =~ m/alpha/){
71   print "Detected architecture alpha\n";
72   $alpha = 1;
73 }
74
75 # Determine converse architecture (net, mpi, ...)
76 print "Do you have a special network interconnect? [y/N]";
77 $special_network = "false";
78 while($line = <>){
79         chomp $line;
80         if(lc($line) eq "y" || lc($line) eq "yes" ){
81                 $special_network = "true";
82                 last;
83         } elsif(lc($line) eq "n" || lc($line) eq "no" || $line eq "" ){
84                 last;
85         }
86 }
87
88 # default to net
89 $converse_network_type = "net";
90         
91 if($special_network eq "true"){
92         print << "EOF";
93         
94 Choose an interconnect from below: [1-11]
95          1) MPI
96          2) Infiniband (native ibverbs alpha version)
97          3) Myrinet GM
98          4) Myrinet MX
99          5) LAPI
100          6) Cray XT3, XT4 (not yet tested on CNL)
101          7) Bluegene/L Native (only at T. J. Watson)
102          8) Bluegene/L MPI
103          9) Bluegene/P Native (only at T. J. Watson)
104         10) Bluegene/P MPI
105         11) VMI
106
107 EOF
108         
109         while($line = <>){
110                 chomp $line;
111                 if($line eq "1"){
112                         $converse_network_type = "mpi";
113                         last;
114                 } elsif($line eq "2"){
115                         $converse_network_type = "net";
116                         $options = "$options ibverbs ";
117                         last;
118                 } elsif($line eq "3"){
119                         $converse_network_type = "net";
120                         $options = $options . "gm ";
121                         last;
122                 } elsif($line eq "4"){
123                         $converse_network_type = "net";
124                         $options = $options . "mx ";
125                         last;
126                 } elsif($line eq "5"){
127                         $arch = "lapi";
128                         last;
129                 } elsif($line eq "6"){
130                         $arch = "mpi-crayxt3";
131                         last;
132                 } elsif($line eq "7"){
133                         $arch = "bluegenel";
134                         $compilers = "xlc ";
135                         $nobs = "--no-build-shared";
136                         last;
137                 } elsif($line eq "8"){
138                     $arch = "mpi-bluegenel";
139                         $compilers = "xlc ";
140                         $nobs = "--no-build-shared";
141                         last;
142                 } elsif($line eq "9"){
143                     $arch = "bluegenep";
144                         $compilers = "xlc ";
145                         last;
146                 } elsif($line eq "10"){
147                     $arch = "mpi-bluegenep";
148                         $compilers = "xlc ";
149                         last;
150                   } elsif($line eq "11"){
151                         $converse_network_type = "vmi";
152                         last;
153                 } else {
154                         print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
155                 }
156         }       
157 }
158
159
160 if($arch eq ""){
161           $arch = "${converse_network_type}-${arch_os}";
162           if($amd64) {
163                 $arch = $arch . "-amd64";
164           } elsif($ia64){
165                 $arch = $arch . "-ia64";
166           } elsif($ppc){
167                 $arch = $arch . "-ppc";
168           } elsif($alpha){
169                 $arch = $arch . "-axp";
170           }
171 }
172   
173 #Cleanup the architectures to match the horrible real world inconsistent src/archs
174
175 if($arch eq "net-darwin"){
176         $arch = "net-darwin-x86";
177 } elsif($arch eq "net-darwin-ppc"){
178         $arch = "net-ppc-darwin";
179 } elsif($arch eq "mpi-darwin-ppc"){
180         $arch = "mpi-ppc-darwin";
181
182
183
184
185
186
187 # Determine whether to support SMP / Multicore
188 print "Do you want SMP or multicore support? [y/N]";
189 $smp = "";
190 while($line = <>){
191         chomp $line;
192         if(lc($line) eq "y" || lc($line) eq "yes" ){
193                 $options = "$options smp ";
194                 last;
195         } elsif(lc($line) eq "n" || lc($line) eq "no" || $line eq ""){
196                 last;
197         } else {
198                 print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
199         }
200 }
201
202
203 #================ Choose Compiler =================================
204
205
206 print "Do you want to specify a compiler? [y/N]";
207 $special_compiler = "false";
208 while($line = <>){
209         chomp $line;
210         if(lc($line) eq "y" || lc($line) eq "yes" ){
211                 $special_compiler = "true";
212                 last;
213         } elsif(lc($line) eq "n" || lc($line) eq "no" || $line eq ""){
214                 last;
215         } else {
216                 print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
217         }
218 }
219
220
221
222 # Produce list of compilers
223
224 $cs = `./build charm++ $arch help | grep "Supported compilers"`;
225 # prune away beginning of the line
226 $cs =~ m/Supported compilers: (.*)/;
227 $cs = $1;
228 # split the line into an array
229 @c_list = split(" ", $cs);
230
231
232 # Choose compiler
233 if($special_compiler eq "true"){
234     $numc = @c_list;
235         print "Choose a compiler: [1-$numc] \n";
236
237         $i = 1;
238         foreach $c (@c_list){
239           print "\t$i)\t$c\n";
240           $i++;
241         }
242
243         while($line = <>){
244           chomp $line;
245           if($line =~ m/([0-9]*)/ && $1 > 0 && $1 <= $numc){
246                 $compilers = $c_list[$1-1];
247                 last;
248           } else {
249                 print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
250           }
251         }
252 }
253
254
255
256
257 #================ Choose Options =================================
258
259 %explanations = ();
260
261 $explanations{"ooc"} = "Out-of-core execution support in Charm++";
262 $explanations{"tcp"} = "Charm++ over TCP instead of UDP for net versions. TCP is slower";
263 $explanations{"ifort"} = "Use Intel's ifort fortran compiler";
264 $explanations{"gfortran"} = "Use gfortran compiler for fortran";
265 $explanations{"g95"} = "Use g95 compiler";
266 $explanations{"ifort"} = "Use Intel's ifort fortran compiler";
267 $explanations{"pgf90"} = "Use Portland Group's pgf90 fortran compiler";
268 $explanations{"ifc"} = "Use Intel's ifc compiler";
269 $explanations{"ammasso"} = "Use native RDMA support on Ammasso interconnect";
270
271
272
273
274
275 print "Do you want to specify any Charm++ build options such as fortran compilers? [y/N]";
276 $special_options = "false";
277 while($line = <>){
278         chomp $line;
279         if(lc($line) eq "y" || lc($line) eq "yes" ){
280                 $special_options = "true";
281                 last;
282         } elsif(lc($line) eq "n" || lc($line) eq "no" || $line eq ""){
283                 last;
284         } else {
285                 print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
286         }
287 }
288
289
290 if($special_options eq "true"){
291
292   # Produce list of options
293
294   $opts = `./build charm++ $arch help | grep "Supported options"`;
295   # prune away beginning of line
296   $opts =~ m/Supported options: (.*)/;
297   $opts = $1;
298
299   @option_list = split(" ", $opts);
300   
301   print "Please enter one or more numbers separated by spaces\n";
302   print "Choices:\n";
303
304   # Prune out entries that would already have been chosen above, such as smp
305   @option_list_pruned = ();
306   foreach $o (@option_list){
307         if($o ne "smp" && $o ne "ibverbs" && $o ne "gm" && $o ne "mx"){
308           @option_list_pruned = (@option_list_pruned , $o);
309         }
310   }
311
312   # sort the list
313   @option_list_pruned = sort @option_list_pruned;
314
315   # print out list for user to select from
316   $i = 1;
317   foreach $o (@option_list_pruned){
318         $exp = $explanations{$o};
319         print "\t$i)\t$o";
320         for($j=0;$j<20-length($o);$j++){
321           print " ";
322         }
323     print ": $exp";
324         print "\n";
325         $i++;
326   }
327   print "\t$i)\tNone Of The Above\n";
328
329   $num_options = @option_list_pruned;
330
331   while($line = <>){
332         chomp $line;
333     $line =~ m/([0-9 ]*)/;
334     @entries = split(" ",$1);
335     @entries = sort(@entries);
336
337         $additional_options = "";
338         foreach $e (@entries) {
339           if($e>=1 && $e<= $num_options){
340                 $estring = $option_list_pruned[$e-1];
341                 $additional_options = "$additional_options $estring";
342           } elsif ($e == $num_options+1){
343                 # user chose "None of the above"
344                 # clear the options we may have seen before
345                 $additional_options = " ";
346           }
347         }
348
349         # if the user input something reasonable, we can break out of this loop
350         if($additional_options ne ""){
351           $options = "$options ${additional_options} ";
352           last;
353         }
354
355   }
356
357 }
358
359
360
361
362 # Choose compiler flags
363 print << "EOF";
364         
365 Choose a set of compiler flags [1-4]
366         1) none
367         2) debug
368         3) optimized [default]
369         4) optimized + projections
370         5) custom
371         
372 EOF
373
374 $compiler_flags = "";
375
376 while($line = <>){
377         chomp $line;
378         if($line eq "1"){
379                 last;
380         } elsif($line eq "2"){
381                 $compiler_flags = "-g -O0";
382                 last;
383         } elsif($line eq "3" || $line eq ""){
384                 $compiler_flags = "-O2 -DCMK_OPTIMIZE";
385                 last;
386         } elsif($line eq "4"){ 
387                 $compiler_flags = "-O2"; 
388                 last; 
389         }  elsif($line eq "5"){
390
391                 print "Enter compiler options: ";
392                 $input_line = <>;
393                 chomp($input_line);
394                 $compiler_flags = $input_line;
395                 
396                 last;
397         } else {
398                 print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
399         }
400 }
401
402
403
404
405 # Determine the target to build.
406 # We want this simple so we just give 2 options
407 $target = "";
408
409 print << "EOF";
410
411 What do you want to build?
412         1) Charm++ [default] (choose this if you are building NAMD)
413         2) Charm++, AMPI, ParFUM, FEM and other libraries
414
415 EOF
416
417 while($line = <>){
418         chomp $line;
419         if($line eq "1" || $line eq ""){
420                 $target = "charm++";
421                 last;
422         } elsif($line eq "2"){
423                 $target = "LIBS";
424                 last;
425         } else {
426                 print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
427         }
428         
429 }
430
431 # Determine whether to use a -j4 flag for faster building
432 # Currently LIBS cannot be safely built with -j4
433 if($target eq "charm++"){
434         print "Do you want to do a parallel build (-j4)?[Y/n]";
435         while($line = <>){
436                 chomp $line;
437                 if(lc($line) eq "y" || lc($line) eq "yes" || $line eq ""){
438                         $j = "-j4";
439                   last;
440                 } elsif(lc($line) eq "n" || lc($line) eq "no" ){
441                         $j = "";
442                         last;
443                 } else {
444                         print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
445                 }
446         }
447 }
448
449
450 # Compose the build line
451 $build_line = "./build $target $arch $compilers $options $smp $j ${compiler_flags}\n";
452
453
454 # Save the build line in the log
455 open(BUILDLINE, ">>smart-build.log");
456 print BUILDLINE `date`;
457 print BUILDLINE "Using the following build command:\n";
458 print BUILDLINE "$build_line\n";
459 close(BUILDLINE);
460
461
462 print "We have determined a suitable build line is:\n";
463 print "\t$build_line\n\n";
464
465
466 # Execute the build line if the appropriate architecture directory exists
467 print "Do you want to start the build now? [Y/n]";
468 while($line = <>){
469   chomp $line;
470   if(lc($line) eq "y" || lc($line) eq "yes" || $line eq ""){
471         
472         if(-e "src/arch/$arch"){
473           print "Building with: ${build_line}\n";       
474           # Execute the build line
475           system($build_line);
476         } else {
477           print "We could not figure out how to build charm with those options on this platform, please manually build\n";
478           print "Try something similar to: ${build_line}\n";
479         }
480         
481         last;
482   } elsif(lc($line) eq "n" || lc($line) eq "no" ){
483         last;
484   } else {
485         print "Invalid option, DOES NOT COMPUTE, please try again :P\n"
486   }
487 }
488
489
490