You copied the Doc URL to your clipboard.

Port your Application

To port your application, follow these steps:

Note

If you encounter any issues with your build, see the section below.

  1. Ensure all your application dependencies have been ported.

    Use of external libraries is increasingly common, and a conscious design choice for many projects. Common dependencies include:

    • IO libraries. For example, HDF5 and NetCDF (C, parallel, and Fortran flavors).

    • Maths libraries and toolkits. For example PETSc, HYPRE, Trilinos, ScaLAPACK, LAPACK and BLAS.

      Note

      Arm Performance Libraries provides optimized LAPACK and BLAS implementations.

    • Fast fourier transforms. For example, FFTW.

      Note

      Arm Performance Libaries provised an optimised FFT implementation which is compatible with FFTW's interface.

    • Communication layers, or execution environments. For example, Open MPI, OpenUCX, and Charm++.

    • 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:

  2. 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
    

    For GCC:

    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
    
  3. Check you are using the right compiler options. Most GCC options are supported by Arm Compiler. It is recommended that you use -mcpu=native in addition to any other options to ensure you get compiled code that is tuned for the micro-architecture of your machine.

  4. Build your application as you would normally.

  5. Run your test suite.

    Warning

    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.

Solution

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

#ifdefs in the makefile are not being set

There may be compiler-dependent #ifdefs in the source which are not being set.

Solution

You might need to update the source to use the _FLANG and _clang macros, or manually set existing compiler macros, such as -D_PGI.

Unsupported language features

Your code might be making use of language features which are not currently supported by Arm Compiler.

Solution

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.

Solution

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.

Note

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.

Solution

It might be necessary to explicitly catch attempted divide-by-zeros in software. For example, if you have an equation such as:

c = a / b

Explicitly catch for b being equal to zero, using:

if b==0 then throw_error("Attempted divide by zero")

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.

Solution

Map your threads to cores using the available mapping devices:

  • OpenMP environment variables​

  • OpenMPI run flags​

  • Numactl

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​.

Solution

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 -fPIC flag.

Note

  • This issue does not occur when using the -fpic flag with Arm compilers for HPC (armflang/armclang/armclang++), and it also does not occur on x86_64 because -fpic operates the same as -fPIC.

  • PIC is code which is suitable for shared libraries.

Cause

Using the -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.

Note

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.

Solution

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 Arm®v7 compiler flags

Some Arm®v7 flags that are needed for Arm®v7, cause errors for Arm®v8 targets. For example, on Arm®v8 Neon is compulsory, so the flag -fp=neon does not exist on Arm®v8. If it is used when compiling for Arm®v8, GCC does not recognize it and causes an error.

Cause Typically, the flags are incorrect in makefiles.

Solution Update your makefiles to only use compatible Arm®v8 compiler flags.

Was this page helpful? Yes No