From 21bb338da4ea35e2ed08278dec9d79332491c19c Mon Sep 17 00:00:00 2001 From: camierjs Date: Mon, 28 Dec 2020 09:38:49 -0800 Subject: [PATCH] A64fx setup --- config/config.hpp | 8 +- linalg/simd.hpp | 29 +++-- linalg/simd/sve.hpp | 17 +++ linalg/simd/sve512.hpp | 246 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 284 insertions(+), 16 deletions(-) create mode 100644 linalg/simd/sve.hpp create mode 100644 linalg/simd/sve512.hpp diff --git a/config/config.hpp b/config/config.hpp index 9aed248ed2..21f1e6c4fd 100644 --- a/config/config.hpp +++ b/config/config.hpp @@ -9,7 +9,6 @@ // terms of the BSD-3 license. We welcome feedback and contributions, see file // CONTRIBUTING.md for details. - // Support out-of-source builds: if MFEM_CONFIG_FILE is defined, include it. // // Otherwise, use the local file: _config.hpp. @@ -25,7 +24,8 @@ // Common configuration macros -#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) || defined(__clang__) +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) || \ + defined(__clang__) #define MFEM_HAVE_GCC_PRAGMA_DIAGNOSTIC #endif @@ -66,6 +66,6 @@ #ifdef MFEM_USE_PUMI #error Building with PUMI (MFEM_USE_PUMI=YES) requires MPI (MFEM_USE_MPI=YES) #endif -#endif // MFEM_USE_MPI not defined +#endif // MFEM_USE_MPI not defined -#endif // MFEM_CONFIG_HPP +#endif // MFEM_CONFIG_HPP diff --git a/linalg/simd.hpp b/linalg/simd.hpp index 26df56f0da..6676c5c39a 100644 --- a/linalg/simd.hpp +++ b/linalg/simd.hpp @@ -17,9 +17,11 @@ // --- AutoSIMD + specializations with intrinsics #include "simd/auto.hpp" #ifdef MFEM_USE_SIMD -#if defined(__VSX__) +#if defined(__aarch64__) +#include "simd/sve.hpp" +#elif defined(__VSX__) #include "simd/vsx.hpp" -#elif defined (__bgq__) +#elif defined(__bgq__) #include "simd/qpx.hpp" #elif defined(__x86_64__) || defined(_M_X64) || defined(_M_IX86) #include "simd/x86.hpp" @@ -42,6 +44,9 @@ #elif defined(__AVX512F__) #define MFEM_SIMD_BYTES 64 #define MFEM_ALIGN_BYTES 64 +#elif defined(__AARCH64EL__) +#define MFEM_SIMD_BYTES 64 +#define MFEM_ALIGN_BYTES 64 #elif defined(__AVX__) || defined(__VECTOR4DOUBLE__) #define MFEM_SIMD_BYTES 32 #define MFEM_ALIGN_BYTES 32 @@ -54,14 +59,14 @@ #endif // derived macros -#define MFEM_ROUNDUP(val,base) ((((val)+(base)-1)/(base))*(base)) -#define MFEM_ALIGN_SIZE(size,type) \ - MFEM_ROUNDUP(size,(MFEM_ALIGN_BYTES)/sizeof(type)) +#define MFEM_ROUNDUP(val, base) ((((val) + (base)-1) / (base)) * (base)) +#define MFEM_ALIGN_SIZE(size, type) \ + MFEM_ROUNDUP(size, (MFEM_ALIGN_BYTES) / sizeof(type)) namespace mfem { -template +template struct AutoSIMDTraits { static const int block_size = MFEM_TEMPLATE_BLOCK_SIZE; @@ -71,14 +76,14 @@ struct AutoSIMDTraits static const int batch_size = 1; - static const int simd_size = MFEM_SIMD_BYTES/sizeof(real_t); + static const int simd_size = MFEM_SIMD_BYTES / sizeof(real_t); typedef AutoSIMD vcomplex_t; typedef AutoSIMD vreal_t; - typedef AutoSIMD vint_t; + typedef AutoSIMD vint_t; }; -template +template struct NoSIMDTraits { static const int block_size = MFEM_TEMPLATE_BLOCK_SIZE; @@ -92,9 +97,9 @@ struct NoSIMDTraits typedef AutoSIMD vcomplex_t; typedef AutoSIMD vreal_t; - typedef AutoSIMD vint_t; + typedef AutoSIMD vint_t; }; -} // mfem namespace +} // namespace mfem -#endif // MFEM_SIMD_HPP +#endif // MFEM_SIMD_HPP diff --git a/linalg/simd/sve.hpp b/linalg/simd/sve.hpp new file mode 100644 index 0000000000..c613783b17 --- /dev/null +++ b/linalg/simd/sve.hpp @@ -0,0 +1,17 @@ +// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced +// at the Lawrence Livermore National Laboratory. All Rights reserved. See files +// LICENSE and NOTICE for details. LLNL-CODE-806117. +// +// This file is part of the MFEM library. For more information and source code +// availability visit https://mfem.org. +// +// MFEM is free software; you can redistribute it and/or modify it under the +// terms of the BSD-3 license. We welcome feedback and contributions, see file +// CONTRIBUTING.md for details. + +#ifndef MFEM_SIMD_SVE_HPP +#define MFEM_SIMD_SVE_HPP + +#include "sve512.hpp" + +#endif // MFEM_SIMD_SVE_HPP diff --git a/linalg/simd/sve512.hpp b/linalg/simd/sve512.hpp new file mode 100644 index 0000000000..e7585ef587 --- /dev/null +++ b/linalg/simd/sve512.hpp @@ -0,0 +1,246 @@ +// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced +// at the Lawrence Livermore National Laboratory. All Rights reserved. See files +// LICENSE and NOTICE for details. LLNL-CODE-806117. +// +// This file is part of the MFEM library. For more information and source code +// availability visit https://mfem.org. +// +// MFEM is free software; you can redistribute it and/or modify it under the +// terms of the BSD-3 license. We welcome feedback and contributions, see file +// CONTRIBUTING.md for details. + +#ifndef MFEM_SIMD_SVE512_HPP +#define MFEM_SIMD_SVE512_HPP + +#if defined(__AARCH64EL__) || 1 + +#include "../../config/tconfig.hpp" + +namespace mfem +{ + +template struct AutoSIMD; + +template <> struct AutoSIMD +{ + typedef double scalar_type; + static constexpr int size = 2; + static constexpr int align_bytes = 16; + + union + { + vector double vd; + double vec[size]; + }; + + inline MFEM_ALWAYS_INLINE double &operator[](int i) + { + return vec[i]; + } + + inline MFEM_ALWAYS_INLINE const double &operator[](int i) const + { + return vec[i]; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD &operator=(const AutoSIMD &v) + { + vd = v.vd; + return *this; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD &operator=(const double &e) + { + vd = vec_splats(e); + return *this; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD &operator+=(const AutoSIMD &v) + { + vd = vec_add(vd,v.vd); + return *this; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD &operator+=(const double &e) + { + vd = vec_add(vd,vec_splats(e)); + return *this; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD &operator-=(const AutoSIMD &v) + { + vd = vec_sub(vd,v.vd); + return *this; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD &operator-=(const double &e) + { + vd = vec_sub(vd,vec_splats(e)); + return *this; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD &operator*=(const AutoSIMD &v) + { + vd = vec_mul(vd,v.vd); + return *this; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD &operator*=(const double &e) + { + vd = vec_mul(vd,vec_splats(e)); + return *this; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD &operator/=(const AutoSIMD &v) + { + vd = vec_div(vd,v.vd); + return *this; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD &operator/=(const double &e) + { + vd = vec_div(vd,vec_splats(e)); + return *this; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD operator-() const + { + AutoSIMD r; + r.vd = vec_neg(vd); + return r; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD operator+(const AutoSIMD &v) const + { + AutoSIMD r; + r.vd = vec_add(vd,v.vd); + return r; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD operator+(const double &e) const + { + AutoSIMD r; + r.vd = vec_add(vd, vec_splats(e)); + return r; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD operator-(const AutoSIMD &v) const + { + AutoSIMD r; + r.vd = vec_sub(vd,v.vd); + return r; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD operator-(const double &e) const + { + AutoSIMD r; + r.vd = vec_sub(vd, vec_splats(e)); + return r; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD operator*(const AutoSIMD &v) const + { + AutoSIMD r; + r.vd = vec_mul(vd,v.vd); + return r; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD operator*(const double &e) const + { + AutoSIMD r; + r.vd = vec_mul(vd, vec_splats(e)); + return r; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD operator/(const AutoSIMD &v) const + { + AutoSIMD r; + r.vd = vec_div(vd,v.vd); + return r; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD operator/(const double &e) const + { + AutoSIMD r; + r.vd = vec_div(vd, vec_splats(e)); + return r; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD &fma(const AutoSIMD &v, const AutoSIMD &w) + { + vd = vec_madd(w.vd,vd,v.vd); + return *this; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD &fma(const AutoSIMD &v, const double &e) + { + vd = vec_madd(v.vd,vec_splats(e),vd); + return *this; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD &fma(const double &e, const AutoSIMD &v) + { + vd = vec_madd(vec_splats(e),v.vd,vd); + return *this; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD &mul(const AutoSIMD &v, const AutoSIMD &w) + { + vd = vec_mul(v.vd,w.vd); + return *this; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD &mul(const AutoSIMD &v, const double &e) + { + vd = vec_mul(v.vd,vec_splats(e)); + return *this; + } + + inline MFEM_ALWAYS_INLINE AutoSIMD &mul(const double &e, const AutoSIMD &v) + { + vd = vec_mul(vec_splats(e),v.vd); + return *this; + } +}; + +inline MFEM_ALWAYS_INLINE +AutoSIMD operator+(const double &e, + const AutoSIMD &v) +{ + AutoSIMD r; + r.vd = vec_add(vec_splats(e),v.vd); + return r; +} + +inline MFEM_ALWAYS_INLINE +AutoSIMD operator-(const double &e, + const AutoSIMD &v) +{ + AutoSIMD r; + r.vd = vec_sub(vec_splats(e),v.vd); + return r; +} + +inline MFEM_ALWAYS_INLINE +AutoSIMD operator*(const double &e, + const AutoSIMD &v) +{ + AutoSIMD r; + r.vd = vec_mul(vec_splats(e),v.vd); + return r; +} + +inline MFEM_ALWAYS_INLINE +AutoSIMD operator/(const double &e, + const AutoSIMD &v) +{ + AutoSIMD r; + r.vd = vec_div(vec_splats(e),v.vd); + return r; +} + +} // namespace mfem + +#endif // __AARCH64EL__ + +#endif // MFEM_SIMD_SVE512_HPP