Port your Application
To port your application, follow these steps:
If you encounter any issues with your build, see the section below.
Ensure that all of your application dependencies have been ported.
To ensure that the Fortran interface is compatible with your application, you must compile the application dependencies with the same toolchain that you use to compile your application.
Use of external libraries is increasingly common, and a conscious design choice for many projects. Common dependencies include:
Maths libraries and toolkits. For example PETSc, HYPRE, Trilinos, ScaLAPACK, LAPACK and BLAS.
Arm Performance Libraries provides optimized LAPACK and BLAS implementations.
Fast fourier transforms. For example, FFTW.
Arm Performance Libaries provised an optimised FFT implementation which is compatible with FFTW's interface.
Libraries providing performance portability and memory abstraction. For example, Kokkos and RAJA.
In most cases you will find that these dependencies have been built on Arm before, with the Arm and GNU toolchains:
Check you are using the correct compiler.
During your build configuration, specify which C, C++, and Fortran compilers to use. For example, for Arm Compiler you would typically set:
CC=armclang CXX=armclang++ FC=armflang F77=armflang
CC=gcc CXX=g++ FC=gfortran F77=gfortran
For MPI builds (for example, Open MPI) you might need to use the MPI wrappers. These are usually the same for all compilers:
CC=mpicc CXX=mpicxx FC=mpifort
Check you are using the right compiler options. Most GCC options are supported by Arm Compiler. It is recommended that you use
-mcpu=nativein addition to any other options to ensure you get compiled code that is tuned for the micro-architecture of your machine.
Build your application as you would normally.
Run your test suite.
Regression tests that rely on bit-wise identical answers might not be portable between architectures.
Porting - troubleshooting
Here are some problems you might encounter while porting your application:
Configure is unable to identify your platform
This may be due to the
config.guess supplied with the application being out of date. This can also be true for a
config.guess already installed on your system and used by some configure scripts.
To fix this problem, obtain up-to-date versions:
wget 'http://git.savannah.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' -O config.guess wget 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' -O config.sub
Libtool fails to link Fortran applications or interfaces
Libtool does not recognize Arm Compiler as a Fortran compiler. Therefore, it is unable to set the correct flags for linking the binary.
Ensure Libtool uses the correct compiler options with Arm Compiler by modifying it after running configure:
sed -i -e 's#wl=""#wl="-Wl,"#g' libtool sed -i -e 's#pic_flag=""#pic_flag=" -fPIC -DPIC"#g' libtool
Some widely used applications and libraries, for example Open MPI, have already incorporated a fix to address this issue at the configure stage.
#ifdefs in the makefile are not being set
There may be compiler-dependent
#ifdefs in the source which are not being set.
You might need to update the source to use the
_clang macros, or manually set existing compiler macros, such as
Unsupported language features
Your code might be making use of language features which are not currently supported by Arm Compiler.
Check the support status of the compiler, for:
You are experiencing a race condition you have not encountered before
AArch64 adopts a weak memory model. This means that read and writes can be re-ordered. In some cases it means that explicit memory barriers are needed on AArch64 that were not required on other architectures.
Implement explicit memory barriers for AArch64. These are described in Barriers in the Arm Cortex-A Series Programmer's guide for Armv8-A, and in Appendix J of the ARM Architecture Reference Manual ARMv8, for ARMv8-A archictecture profile.
Do you have an integer divide by zero?
On AArch64, an integer divide by zero does not generate an error; instead it returns as zero.
This is not the case for floating-point divide by zero.
On rare occasions, an undetected divide by zero might be allowing an application to run erroneously when it should fail.
It might be necessary to explicitly catch attempted divide-by-zeros in software. For example, if you have:
c = a / b
b==0 before executing the divide, and generate a warning or adjust the program flow accordingly.
Thread mapping and pinning on Arm
Arm chips can have lots of cores. It is very important to manage how your threads get mapped to the cores, and how they are pinned.
Map your threads to cores using the available mapping devices:
OpenMP environment variables
OpenMPI run flags
Segmentation fault when calling an Arm Performance Libaries function
Segmentation faults can occur when you are linking against the wrong version of the library with either 32-bit integers or 64-bit integers.
Compile and link for 32-bit integers (
-armpl=lp64) or for 64-bit integers (
-armpl=ipl64), as required.
Building Position Independent Code (PIC) on AArch64
Failure can occur at the linking stage when building Position-Independent Code (PIC) on AArch64 using the lower-case
-fpic compiler flag with GCC compilers (gfortran, gcc, g++), in preference to using the upper-case
This issue does not occur when using the
-fpicflag with Arm compilers for HPC (armflang/armclang/armclang++), and it also does not occur on x86_64 because
-fpicoperates the same as
PIC is code which is suitable for shared libraries.
-fpic compiler flag with GCC compilers on AArch64 causes the compiler to generate one less instruction per address computation in the code, and can provide code size and performance benefits. However, it also sets a limit of 32k for the Global Offset Table (GOT), and the build can fail at the executable linking stage because the GOT overflows.
When building PIC with Arm Compiler for HPC on AArch64, or building PIC on x86_64,
-fpic does not set a limit for the GOT, and this issue does not occur.
Consider using the
-fPIC compiler flag with GCC compilers on AArch64, because it ensures that the size of the GOT for a dynamically linked executable will be large enough to allow the entries to be resolved by the dynamic loader.
Applications supporting GCC builds on Arm - but use Armv-7 compiler flags
Some Arm®v7 flags that are needed for Armv7, cause errors for Armv8 targets. For example, on Armv8 NEON™ is compulsory, so the flag
-fp=neon does not exist on Armv8. If it is used when compiling for Armv8, GCC does not recognize it and causes an error.
Typically, the flags are incorrect in makefiles.
Update your makefiles to only use compatible Armv8 compiler flags.