Traditional access a[i][j]k] seems missing
It looks like the current proposal does not have the usual a[j][j][k] syntax.
Since it cannot be an omission :-) , what are the reasons for this absence?
It is available in std::valarray, https://www.boost.org/doc/libs/release/libs/multi_array/ and so on.
Since I have not attended many recent ISO C++ meetings about array_ref or mdspan, I do not remember this discussion.
If I understand the good honey pot of a(i,j,k)syntax for Fortran programmers, it seems strange or repulsive for C/C++ programmers. It also prevents writing generic code taking either a multidimensional C++ array or a mdspan.
AFAICT this was omitted for simplicity, since it can be added later. subspan does exactly this, essentially, and we could have operator[] call subspan in the case where rank() > 1, but I don't think most of my coauthors trust the optimizer to get things right through that many layers of abstraction (I'd personally be fine with it, though, especially if we could produce an implementation that benchmarked favorably compared to the a(i,j,k) syntax).
Thank you for the feedback. While I understand that it would cause a happiness overdose to have in C++20 a Fortran 1957 feature ;-) (OK, to be fair it is closer to Fortran8x feature), I am also thinking to the fact that people will be very disappointed by waiting for C++23 for this C/C++ classic syntax... :-(
With -O3 and aggressive inlining, I am rather optimistic.
But it would be nice to implement before San Diego meeting and to look at the generated assembly code.
With
-O3and aggressive inlining, I am rather optimistic.
Agreed. I believe the Kokkos team has done some analogous benchmarks, but some time has passed since then and we ought to be able to due better if we consider only the subset that includes more modern C++ compilers.
From abstraction perspective, a[i][j][k] is syntax for array of array of array vs. multidimensional array. From implementation perspective, reasonable performance with layout extensibility requires incredibly delicate template meta-programming and aggressive optimization. @dsunder on the Kokkos team has the prototyping experience.
From user perspective, multidimensional arrays are fall in the applied mathematics domain and over the lifetime of Kokkos and precursors to Kokkos users were happy with the multidimensional array syntax and didn't even ask for the array of array of array syntax.
From abstraction perspective,
a[i][j][k]is syntax for array of array of array vs. multidimensional array.
In many domains (certainly all the domains I've interacted with directly), these abstractions are synonymous enough to be used interchangably.
From implementation perspective, reasonable performance with layout extensibility requires incredibly delicate template meta-programming and aggressive optimization.
But this is already a requirement of achieving constexpr-correctness in mdspan. If a modern compiler can't elide constant expressions in the construction and subsequent dereference of a subspan, then it's probably a sign that the implementation is not propagating constexpr correctly. There shouldn't be any template metaprogramming involved — only constexpr programming, which is already a requirement of any standard library facility.
@dsunder on the Kokkos team has the prototyping experience.
From the conversations I've had with Dan, most of the issues involved in these prototypes involved legacy compiler support (@dsunder can confirm, though). Given that this feature is not even going in to C++20, I think we can safely assume that C++23-compliant compilers will elide constant expressions at least as well as C++17-compliant compilers do.
Kokkos users were happy with the multidimensional array syntax and didn't even ask for the array of array of array syntax.
But Ronan is asking for it. More importantly, libraries like Boost.MultiArray with much larger user bases did ask for it, and the user base of the standard library is much broader still. I'm still not saying it's a version 1 feature, but it's a request we should take seriously.
It is not too hard to implement (I had a working prototype for Kokkos circa 2010 using c++98), but the requisite nested types quickly became problematic and optimized poorly on existing compilers at that time. If a compiler elides intermediate temporaries and the nested types do not count towards the max inline depth for the optimizer then this feature could be supported with minimal overhead.
If a compiler elides intermediate temporaries and the nested types do not count towards the max inline depth for the optimizer then this feature could be supported with minimal overhead.
Since all of the intermediate temporaries would have constexpr constructors, this should be the case. I don't believe modern implementations count constexpr functions towards their maximum inline depth (though I'm not sure of this). Inline depth shouldn't be an issue, though, since each invocation of [] returns to the caller before invoking the next [], right?
P0009 has passed through LEWG for the next library TS without the array of array of array dereference. Introduce a new paper to add the interface once it in the TS.
@hcedwar If we introduce the changes you want to make to the accessor, we'll have to go back to LEWG anyway, so we might as well think about what else needs to be changed while we're there.
The accessor policy changes introduced from R5 to R6 were never reviewed with LEWG and thus already necessitate revisit with LEWG, unless stripped out entirely and submitted as a follow on paper.
@hcedwar http://wiki.edg.com/bin/view/Wg21jacksonville2018/P0900 here are the notes on that discussion in LEWG. I think you weren't there for that meeting, and the notes are under another paper number because that paper's discussion got turned into the Accessor discussion. The room voted in favor of @brycelelbach's proposal for an Accessor abstraction "akin to Allocator design" (3-4-5-1-0, which the chair indicated was consensus) along the lines of what Bryce presented in a slide deck. The version of Accessor in the current draft (pre-pull requests) is exactly what Bryce presented to that room, couched in the formatting of concepts in the standard. If we change that, we'll have to go back and get another vote, but as it stands we have a straw poll indicating consensus on the current design.
If the current pull request is accepted, I believe we will have to go back to LEWG, at which point it makes sense IMHO to also discuss this @keryell's issue here.
Significant extrapolation has been taken with the "akin to Allocator design" parenthetical in straw polls regarding variadic vs. non-variadic accessor property.
@hcedwar The design that LEWG approved is here, in the section Accessor Policy Requirements. This is what was up on the screen when we voted. Please let me know where I've made significant extrapolations from this model so that I can correct those errors; my only intention was to present exactly that which was already approved in a form that could meet the rigor requirements of LWG.
- The straw polls were for variadic or not properties, with accessor policy as a single template parameter.
- D0454r1 was a draft version that did not appear in the pre-meeting mailing and was not the topic of the LEWG session.
- D0454r1 accessor policy was not templated on the scalar type, had a nested type for the
accessor_typeseparate from the pointer type as per PR #55, did not specify random access iterator operational semantics as per PR #55 , and as such appears to be much closer to PR #55 than what showed up in R6.
The straw polls were for variadic or not properties, with accessor policy as a single template parameter.
The straw poll I quoted was specifically for the design that was not variadic. The straw poll for the variadic version was 1-2-2-6-2, right below that.
D0454r1 accessor policy was not templated on the scalar type, had a nested type for the accessor_type separate from the pointer type
The fact that the nested type structure is not needed for AccessorPolicy was noted in the room, though I don't see it recorded in the notes. The "akin to allocator" hints at it, since allocator doesn't have the nested design either. LWG feedback was along the same lines ("GR: Everywhere else we make the user fill in the concrete type.")
D0454r1 was a draft version that did not appear in the pre-meeting mailing and was not the topic of the LEWG session.
The chair addressed this and the room voted to hear discussion on D0454 anyway. Titus and LEWG are within their rights to do this.
accessor_type separate from the pointer type
I don't see this in the paper anywhere. accessor_type is just the nested type, akin to mapping in LayoutPolicy. The pointer type isn't independent.
did not specify random access iterator operational semantics
This change was made in response to feedback from LWG that p[i] is an illegal operation on a completely unconstrained type and that the accessor was underspecified. To fix this, we can invent a new type constraint and term of art (which would require returning to LWG) or use an existing one (like RandomAccessIterator) that fits with the other semantics in the paper (allocator_basic::pointer = T* and p[i]), which is an editorial change rather than a design change. Going that direction doesn't stop anyone from writing a follow up paper that would relax that restriction.
Bottom line: I just want to get mdspan in to a working draft. We can write papers that change things (like relax the accessor to meet your requirements) after that. But if that's not what we're going to do, other design changes should be on the table as well.
The idea to have another paper targeting C++ programmers and keeping this paper for Fortran programmers as is sounds good. :-)
While the discussion about efficient implementation without magic is a concern to demonstrate the concept, since the goal is to have it into std:: where all the compiler magic can happen, removing for example some in-lining usual restriction for some internal library construct is not the hardest part...
Please see P2128R5 for the latest progress and discussion.
Thank you for the update.
On my side I updated triSYCL to use the latest mdspan implementation instead of Boost.MultiArray and I have meta-programmed the [][][] syntax.
This is mainly implemented around https://github.com/triSYCL/triSYCL/blob/master/include/triSYCL/accessor/mixin/accessor.hpp#L180 to provide the SYCL accessor [][][] syntax.
Perhaps this is some new piece of information for https://wg21.link/p2128r5.
@keryell Thanks for your update!