// Copyright (c) 2010-2023, 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_HPP #define MFEM_SIMD_HPP #include "../config/tconfig.hpp" // --- AutoSIMD + specializations with intrinsics #include "simd/auto.hpp" #ifdef MFEM_USE_SIMD #if defined(__aarch64__) && defined(__ARM_FEATURE_SVE) #include "simd/sve.hpp" #elif defined(__VSX__) #include "simd/vsx.hpp" #elif defined (__bgq__) #include "simd/qpx.hpp" #elif defined(__x86_64__) || defined(_M_X64) || defined(_M_IX86) #include "simd/x86.hpp" #elif !defined(_MSC_VER) #warning Unknown SIMD architecture #else #pragma message("warning: Unknown SIMD architecture") #endif #endif // MFEM_SIMD_BYTES is the default SIMD size used by MFEM, see e.g. class // TBilinearForm and the default traits class AutoSIMDTraits. // MFEM_ALIGN_BYTES determines the padding used in TVector when its 'align' // template parameter is set to true -- it ensures that the size of such TVector // types is a multiple of MFEM_ALIGN_BYTES. MFEM_ALIGN_BYTES must be a multiple // of MFEM_SIMD_BYTES. #if !defined(MFEM_USE_SIMD) #define MFEM_SIMD_BYTES 8 #define MFEM_ALIGN_BYTES 32 #elif defined(__AVX512F__) #define MFEM_SIMD_BYTES 64 #define MFEM_ALIGN_BYTES 64 #elif defined(__aarch64__) && defined(__ARM_FEATURE_SVE) #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 #elif defined(__SSE2__) || defined(__VSX__) #define MFEM_SIMD_BYTES 16 #define MFEM_ALIGN_BYTES 32 #else #define MFEM_SIMD_BYTES 8 #define MFEM_ALIGN_BYTES 32 #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)) namespace mfem { template struct AutoSIMDTraits { static const int block_size = MFEM_TEMPLATE_BLOCK_SIZE; // Alignment for arrays of vcomplex_t and vreal_t static const int align_bytes = MFEM_SIMD_BYTES; static const int batch_size = 1; static const int simd_size = MFEM_SIMD_BYTES/sizeof(real_t); typedef AutoSIMD vcomplex_t; typedef AutoSIMD vreal_t; typedef AutoSIMD vint_t; }; template struct NoSIMDTraits { static const int block_size = MFEM_TEMPLATE_BLOCK_SIZE; // Alignment for arrays of vcomplex_t and vreal_t static const int align_bytes = sizeof(real_t); static const int batch_size = 1; static const int simd_size = 1; typedef AutoSIMD vcomplex_t; typedef AutoSIMD vreal_t; typedef AutoSIMD vint_t; }; } // mfem namespace #endif // MFEM_SIMD_HPP