I'm writing a header which makes use of templates to eliminate code duplication while implementing SIMD-based loops using intrinsics. Here's an example that hopefully makes my intention clear:
#include <type_traits> // std::conditional
#include <immintrin.h>
template<class Treal_t>
struct packed_real
{
using type = typename std::conditional<std::is_same<Treal_t, float>::value, __m256, __m256d>::type;
};
template<class Treal_t>
inline typename packed_real<Treal_t>::type loadu256(const Treal_t* ptr)
{
if constexpr (std::is_same<Treal_t, float>::value)
{
return _mm256_loadu_ps(ptr);
}
else if constexpr (std::is_same<Treal_t, double>::value)
{
return _mm256_loadu_pd(ptr);
}
}
Now, when I compile this using the GNU compiler v11.1.0, with flags -std==c++17;-Wall;-Wextra;-Werror
, I get the following error:
...: error: ignoring attributes on template argument ‘__m256’ [-Werror=ignored-attributes]
| using type = typename std::conditional<std::is_same<Treal_t, float>::value, __m256, __m256d>::type;
| ^
I'm able to suppress this as follows:
template<class Treal_t>
struct packed_real
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wignored-attributes"
using type = typename std::conditional<std::is_same<Treal_t, float>::value, __m256, __m256d>::type;
#pragma GCC diagnostic pop
};
Therefore, this question has more to do with Should I...? than How can I...?.
- Should I proceed this way?
- What are the repercussions of tackling intrinsic functions via templates?
- Is there a more elegant way of achieving my purpose?
Thanks in advance for your thoughts and inputs.
Update: I observed that although it compiles, the higher-level function that uses the above function fails to do what it's supposed to do. So the question is actually more How can I...? than Should I...?.