Porting A Code to Another Platform
Software Differences | Same
Code, Same Data | Compiler and Loader Option
Tracking Problems with Preprocessor, Compiler, and Loader
The problems encountered when porting a code to another machine are usually
due to different software (preprocessor, compiler, loader, operating system,
environment) or hardware. These software differences can cause:
- Operations executed in a slightly different manner.
- Values stored differently.
- Exceptions handled differently.
- Problems due to a previously unknown bug in the code.
- Slightly different or vastly different results.
When a problem is encountered in porting a code, the best solution is to read
the documentation and then begin debugging the code.
When porting a code between two machines from different vendors, there is
always the possibility of encountering problems or locating bugs not previously
known in a code. This can also happen when porting a code to a different machine
or environment using the same vendor.
Verify That You Are Testing the Same Code with the Same
- Do not begin rewriting sections of the code to take advantage of the machine
to which you are porting until after you have successfully ported a plain-vanilla
version of the code that works identically on both the original and new platform.
- Do not try new compilers or features available on the new platform. Use
the default compilers and features, or those most similar to the platform from
which you are porting. The time to try new options, compilers, and features is
after you have had success in porting the code.
- Do not begin parallelizing a code on a new platform when the code hasn't
been first ported in a serial version, if possible.
- You may want to start with a completely unoptimized code on both platforms
as a baseline for the port.
- Do not make even minor changes to the data that you are "sure will not
affect anything." Whenever possible, test your port on the identical data
used to test the code on the original platform. If the original test case cannot
be used on the new platform, try to develop a new test case that can be used
to test the port on both platforms.
Compiler and Loader Option Differences
- Check all the options used to preprocess, compile, load, and execute the
code on both the old and new architectures to make sure the same default behavior
is being targeted. This may involve checking your environment variables, path,
and if it exists, the libpath setting.
- Make sure you thoroughly understand each of the options used. Use of an option
can change the way the code is built and can change the behavior of the code.
Make sure all the options used are interpreted in the same way on the different
- Check the level of precision, e.g., how many bits are being used in integer
arithmetic, and how many bits used for real and double precision arithmetic.
Are there options to override the precision specified within the code? Consider
using the same precision on both architectures to see if it solves the problem.
- Are default levels of optimization being overridden? Although in most cases
optimization levels should not cause different behavior, it is worth checking.
You might consider lowering the level of optimization on both architectures to
the most limited level or no optimization.
- Check how string constants are handled (Hollerith or character string).
- Are variables being initialized (or not initialized) during the building
of the code (e.g., setting default values to zero, null, or another value)?
- Check how logical values are determined (e.g., will the same values be evaluated
to true and false on both platforms)?
- Are there exception handlers that are or are not enabled by default (e.g.,
overflow, divide by zero, etc.)? Do the exception handlers that are enabled behave
in the same manner (e.g., are overflows and underflows ignored or is an error
- Is stack or static storage of variable values used? If two different methods
are being used, this can cause different initialization of variables within routines.
- Are any options used that might cause parallel execution using threads or
other parallel execution models? Try porting a serial version of the code first,
and if that is not possible, try porting a version that runs on a minimum number
- Are there any options or default behaviors that could cause different rounding
methods to be used? For example, rounding of constants at compile time or execute
time and rounding algorithms for numeric operations.
- Is the architecture being specified when the code is being built? If this
type of option is being used, make sure a valid architecture is being specified,
and check if the target architecture being ported to is supported on the machine
on which the code is running (this is most useful when porting to a machine from
the same vendor).
- Options that set or change the level of the language standard or which change
or more strictly enforce the standard exist in some software. Make sure the software
is using the same standard or style (ISO, ANSI, POSIX, K&R, etc.).
Tracking Problems with Preprocessor, Compiler, and
- Bounds checking.
- Display extra levels of error and warning messages, at all severity levels.
Carefully check all messages.
- Change the level of optimization, starting with no optimization on both platforms
and working up to the default optimization before moving on to a higher level
- If possible, get and read the load map, checking which libraries are loaded
and verifying that an unexpected library or routines from an unexpected library
are not being used. If a load map is not available, try explicitly specifying
the libraries you expect to use on your compile or load execute line. Use the
LC findentry utility to locate which library contains
particular routines. A nice feature of findentry is
that it will tell you if a routine is found in more than one library, which is
sometimes the cause of a problem.
- If you are explicitly specifying libraries, do so very carefully and as a
last resort, because loading libraries in an incorrect order can cause problems.
C Language Considerations
Some of the LC machines provide a default C compiler that supports the ANSI
standard, while the default on other machines is a KAI version of the C compiler.
- cc and xlc are KAI style C.
Use the genproto=\<parmnames\> option to
produce ANSI prototypes from KAI function definitions.
The Intel C++ compiler, icc, is designed to preprocess, compile, assemble,
and link C and C++ programs on systems based on Intel architecture.
-ansi-alias -ansi -strict-ansi -c99 -std=c99
C language object files created with the Intel C++ compiler are binary compatible
with the GNU gcc compiler and glibc, the GNU C language library. See the icc
man page for details and a summary of the compiler options.
Different vendors provide different implementations of MPI. While they should
all produce the same results, in reality different buffer sizes and methods and
different default or limit values may affect results.
If there is an MPI implementation available on both platforms that is not
vendor dependent (e.g., MPICH) and if using it does not require too many coding
changes, first try using the software available on both platforms. Once ported
and verified, try using the vendor-supported MPI.