Porting ACES II requires two main skills: navigating makefiles and reading man pages. This document assumes the code has not been ported or the existing port is stale; otherwise, you can skip straight to the building document, which outlines the steps to identify the target machine and architecture. The source code is not designed to be user-friendly, and there are no shortcuts.

Step 1: identify the architecture, O/S, and compiler tags

In GNUmakefile, jump down to the section entitled "PORTING VARIABLES" and create new blocks or survey the existing options. The general practice is that CMPLR blocks contain compilers, compiler flags, and pre-processor defines, OPSYS blocks contain archivers and file manipulators, and ARCH is used to further clarify the previous two options. Honestly, the best way to port the code is to try to copy variables from other porting sections. If that fails, you might try building the code with empty sections (using the default options). Do not forget to add a string to MACHSTATS (near the top of the file) identifying the machine name and its configuration.

# bigiron is the name of a speedyvec machine running mynix with
# codechomp compilers
MACHSTATS += bigiron:speedyvec:mynix:codechomp
...
ifeq (${CMPLR},codechomp)
   CC = cc -c
   FC = f77 -c
   LD = f77
endif
ifeq (${OPSYS},mynix)
   CPP = $(shell test -x /usr/ccs/lib/cpp && echo /usr/ccs/lib/cpp || echo cpp)
   CPPFLAGS   = -P -C
   AR_REPLACE = rc
endif

Step 2: solve the C/FORTRAN mixing puzzle

Fortran mangles names of procedures and common blocks, and it can be a chore to figure out how to identify them in C. Fortunately, I have created a little test platform that uses all combinations and prints out the correct one. Incidentally, this platform can be used to test compiler flags for 64-bit integers.

The "ACESII/configure" directory is ignored by the top-level makefile. Edit the first few lines to include the proper compilers and flags. The basic GNU compiler settings look like:

CC  := gcc
F90 := g90
F77 := g77

CFLAGS   :=
F90FLAGS := -fno-second-underscore
F77FLAGS := -fno-second-underscore

If you have access to a Fortran 90 compiler, then remove the file "recl_units.f". Once you are happy with the variables, simply run `gmake` and see what happens. This is the output from our development server:

GNUmakefile:34: warning: overriding commands for target `recl_units.o'
GNUmakefile:31: warning: ignoring old commands for target `recl_units.o'
gcc -c  c_endian.c
gcc -c  c_heap.c
gcc -c  c_sizeof.c
gcc -c  c_sub.c
g77 -c -fno-second-underscore recl_units.f
g77 -c -fno-second-underscore args.f
g77 -c -fno-second-underscore chars.f
g77 -c -fno-second-underscore fortran_names.f
g77 -c -fno-second-underscore int_size.f
g77 -c -fno-second-underscore main.f
g77 -c -fno-second-underscore mem_res.f
g77 -c -fno-second-underscore namelist_format.f
g77 -c -fno-second-underscore shifts.f
g77 -fno-second-underscore -o configure *.o
./configure 2>&1 | tee configure.out

 CONFIGURATION TESTS FOR PORTING ACES II

 ==> integer size test

 integer   is  4 bytes
 integer*1 is  1 bytes
 integer*2 is  2 bytes
 integer*4 is  4 bytes
 integer*8 is  8 bytes
 integer(kind=1) is  4 bytes
 integer(kind=2) is  8 bytes
 integer(kind=4) is  4 bytes
 integer(kind=8) is  4 bytes

 ==> RECL units test

 > ERROR: RECL units cannot be determined without f9x.
 >        remove recl_units.[fo] and remake

 ==> memory address resolution test

 Two consecutive integers are  4 unit(s) apart.
 LOC is in bytes.
 > Remove '-D_PTRS_ARE_WORDS'

 ==> FORTRAN name-mangling test

 C function names are suffixed.
 > Add '-DC_SUFFIX', remove '-DC_UPPER'
 Common block names are suffixed.
 > Add '-DCB_SUFFIX', remove '-DCB_UPPER'

 ==> getarg integer argument test

 getarg uses the default integer.
 > Define INTTYPE in tools/f_getarg as 'integer'

 ==> C data type sizes test

 char   is 1 bytes
 int    is 4 bytes
 long   is 4 bytes
 llong  is 8 bytes
 float  is 4 bytes
 double is 8 bytes
 size_t is 4 bytes
 void * is 4 bytes

 ==> endian test

 Little endian

 ==> C malloc vs. FORTRAN common // test

blank common is at 0x8056a18
heap         is at 0x805d000
size_t offset   is 26088 bytes
llong  offset   is 3261 long longs
long   offset   is 6522 longs
int    offset   is 6522 ints

 ==> character intrinsic functions test

 iachar('A') =  65 (should be 65)
  ichar('A') =  65 ( could be 65)
  achar( 65) = 'A' (should be 'A')
   char( 65) = 'A' ( could be 'A')

 ==> bit shifting intrinsic functions test

 rshift(2, 1) =  1 (should be 1)
  ishft(2,-1) =  1 (should be 1)
  ishft(2, 1) =  4 (should be 4)
 lshift(2, 1) =  4 (should be 4)

 ==> namelist formatting test

&STRUCT
 NML0 = 0,
 NML1 = 1,
 NML2 = 2,
 NML3 = 3,
 NML4 = 4/

These results are cached in configure.out

For now, the important things to note are the pre-processor defines. The output tells you whether you need to use suffixes (Add '-DC_SUFFIX'), convert the common blocks to upper case (Add '-DCB_UPPER'), or use single-unit pointer math (Add '-D_PTRS_ARE_WORDS'). All of these options would go under the DEFINES variable in the porting section. The other sections are more FYI but can reveal fundamental problems like huge malloc offsets or lack of the getarg Fortran function.

ifeq (${CMPLR},codechomp)
   DEFINES := -DC_SUFFIX -DCB_SUFFIX
...

Step 3: pick an integer precision

If you can use 64-bit integers, then the configure platform should be used to find the appropiate combination of C and Fortran flags to ensure proper type matching. It helps to read the entire cc and f77 man pages for 64-bit computing options. You MUST use the 64BIT=1 GNUmakefile variable.

Step 4: choose the appropriate numerical libraries

ACES II contains off-the-shelf BLAS, LAPACK, LINPACK, and EISPACK routines from netlib that will build and run like the rest of the program. If you can use vendor-tuned libraries, then the link flags should be specified with the LDFLAGS_NUMLIB variable. WARNING: Most vendor libraries do not have 64-bit integer argument interfaces. If you use 64-bit integers, you might have to use the default netlib libraries.

ifeq (${CMPLR},codechomp)
...
   LDFLAGS_NUMLIBS := -llinpack -leispack # -llb
   LDFLAGS_NUMLIBS += -L/usr/local/lib -llapack -lblas
...

Step 5: figure out any parallel capabilities

Good luck. It seems every vendor has their own combination of compilers, flags, and libraries that are needed to properly build parallel programs. Furthermore, the default mpif.h include file might come from multiple locations depending on thread safety and 64-bit integers. My advice is to try to learn from the existing parallel ports (xl, cray, and digital) and copy those sections.

# from the IBM/xl section
MPCC = mpcc_r -c
MPFC = xlf_r -F:mpxlf_r -c
MPLD = xlf_r -F:mpxlf_r
ifeq (${64BIT},1)
   DIR_MPIINC := /usr/lpp/ppe.poe/include/thread64
else
   DIR_MPIINC := /usr/lpp/ppe.poe/include/thread
endif
DIR_MPIINC += /usr/lpp/ppe.poe/include

Step 6: build the code

Follow the instructions on the building page and see if it works! Most likely, you will have to go back to step 2 and keep iterating until the code builds from beginning to end. There are three places that the build process typically breaks: immediately, joda, and vcc. If there is anything fundamentally wrong with the compiler flags or archiver settings, then the first library will not build. If that passes, then the first binary that is linked is xjoda. If there is any problem with namespaces or finding objects, then it will show up here. Finally, vcc is the main coupled-cluster program that requires a lot of numerical library support. If vcc builds, then everything else should build as well.

If this fails, use `gmake debug` in the failing directory. The debug output shows exactly how C and Fortran files are created and compiled, how libraries are archived, and how binaries are linked. `gmake debug` is your best friend! If you contact the TECHSUPPORT email address, then you should include the screen dump of `gmake debug` at the very least.

Step 7: regression tests

Assuming everything is built, the final step is to make sure it works. The new ACES II binaries must be included in the default login path (usually set in the shell resource file). Change into ACESII/test and simply run `gmake`. The output should look something like this:

ACESII binary: /scr/yau/ACESII/bin/xaces2

zmat.001a:      PASSED
zmat.001b:      PASSED
...

If you are unlucky, then it will look like this:

ACESII binary: /scr/yau/ACESII/bin/xaces2

zmat.001a:      FAILED in xaces2
zmat.001b:      FAILED in xaces2
...

Examine out.zmat.001a and try to use the error condition to fix step 2 of this procedure.