agenium-scale / nsimd

Agenium Scale vectorization library for CPUs and GPUs
MIT License
325 stars 28 forks source link

Provide a constexpr size function #94

Open eschnett opened 3 years ago

eschnett commented 3 years ago

I could not find a way to use the size() function of the C++ pack structure in a constexpr manner. For example, this fails:

constexpr int vsize = pack<double>().size();

because the constructor pack<double>() is not constexpr.

I believe one way to obtain the size of a fixed-size container is via tuple_size. This works e.g. for std::array as well. One could then write

constexpr size_t vsize = std::tuple_size_v<pack<double>>;
gquintin commented 3 years ago

This is because of SVE basically where the size of SIMD vectors is not known at compile time but only at runtime. That's why none of the NSIMD constructs are constexpr. If you look at the headers you will see the use NSIMD_STRUCT so that when compiling for SVE this macro will be __sizeless_struct which is currently supported by Armclang and the Fujitsu compiler.

May I ask in which construct you need the size at compile time?

eschnett commented 3 years ago

I was defining a std::array where the size is rounded up to the next vector size, as in:

constexpr size_t vsize = pack<double>().size();
constexpr size_t N = (2*order+1 + vsize - 1) / vsize * vsize;
array<T,N> tmp;

I am currently using sizeof(pack<double>) / size(double) as a work-around.

gquintin commented 3 years ago

Ah ok, in this case maybe nsimd::max_len will be of use to you (from nsimd.h)

#if NSIMD_CXX >= 2014
template <NSIMD_CONCEPT_VALUE_TYPE T>
constexpr int max_len = max_len_t<T>::value;
#endif

The downside is that its value is huge (namely (2048 bits) / bits(T)) for two reasons:

In any case be careful with sizeof(pack<T>) as this code won't compile when you will target an SVE architecture. I don't know about Arm's plans but my guess is that you will find SVE everywhere in the near future including Apple's computers. (https://www.arm.com/blogs/blueprint/armv9)

eschnett commented 3 years ago

Thanks. I'm using the value only for a temporary array, so I don't have a need for an architecture-independent value.