Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a constexpr size function #94

Open
eschnett opened this issue Apr 6, 2021 · 4 comments
Open

Provide a constexpr size function #94

eschnett opened this issue Apr 6, 2021 · 4 comments
Labels
question Further information is requested

Comments

@eschnett
Copy link
Contributor

eschnett commented Apr 6, 2021

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
Copy link
Contributor

gquintin commented Apr 6, 2021

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?

@gquintin gquintin added the question Further information is requested label Apr 6, 2021
@eschnett
Copy link
Contributor Author

eschnett commented Apr 6, 2021

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
Copy link
Contributor

gquintin commented Apr 6, 2021

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:

  • it is the maximum size of an SVE vector according to the SVE standard and
  • we wanted a common value for all architectures in case, by some matters of facts, this value is (most probably indirectly) used as a parameter to code that is executed on different architectures (eg. serialization of data, computations on heterogeneous environments via MPI...)

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
Copy link
Contributor Author

eschnett commented Apr 6, 2021

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants