Fix stride(0) ordering, bound incx, reject incx == 0, deduce the CBLAS index type, detect padded layouts, and build the CBLAS path in CI - #334
Conversation
This is for discussion of issue kokkos#328.
mhoemmen
left a comment
There was a problem hiding this comment.
Thanks for the contribution! : - )
The code inside #ifdef __cpp_lib_submdspan ... #endif is not well formed. This suggests that we don't have test coverage for that case. Would you consider adding tests for layout_left_padded and layout_right_padded? The tests should not be gated on __cpp_lib_submdspan, for the reasons explained in the comment on that part of the code. Thanks!
| // AMK 5/20/26 - layout_left_padded and layout_right_padded were added in C++26. | ||
| // According to cppreference, padded layouts are covered by the same feature test as submdspan. | ||
| #ifdef __cpp_lib_submdspan | ||
| std::is_same_v<Layout, layout_left_padded> || | ||
| std::is_same_v<Layout, layout_right_padded> || | ||
| #endif |
There was a problem hiding this comment.
#include <mdspan/mdspan.hpp> will pull in the reference implementation of mdspan. That doesn't use the Standard feature test macros. Thus, this part of the code would never get tested with the current CI workflow.
In fact, this code is not well formed, because layout_left_padded and layout_right_padded are class templates that take a size_t constant template parameter, unlike layout_left and layout_right that are ordinary class types without a template parameter.
Here's one way to fix this.
- Given that we've only ever tested with the reference mdspan implementation, we could simply remove the macro test.
- Define
is_padded_layout_vtraits for any specializations oflayout_left_paddedandlayout_right_padded. - Use
is_padded_layout_vhere.
It would take some header file and macro refactoring for the reference std::linalg implementation to be able to use the actual <mdspan> header from an implementation like GCC's or Clang's.
There was a problem hiding this comment.
Done in 110831f3: drop the __cpp_lib_submdspan test, add an is_padded_layout_v trait that matches any specialization of layout_left_padded and layout_right_padded, and use that instead.
I think __cpp_lib_aligned_accessor has the same problem
If aligned_accessor is used without std::, the name is looked up in Kokkos and not std so reference mdspan has no aligned_accessor so blas_helpers.hpp breaks and <experimental/linalg> is unincludable
So also removed __cpp_lib_aligned_accessor , is_aligned_accessor_v and its term in is_blas_accessor_type_v.
Build 6a94735 with -D__cpp_lib_aligned_accessor=202411L :
In file included from include/experimental/__p1673_bits/blas1_scale.hpp:21,
from include/experimental/linalg:40,
from tests/native/./gtest_fixtures.hpp:31,
from tests/native/scale.cpp:1:
include/experimental/__p1673_bits/blas_helpers.hpp:77:38: error: ‘aligned_accessor’ was not declared in this scope; did you mean ‘is_aligned_accessor_v’?
77 | constexpr bool is_aligned_accessor_v<aligned_accessor<ElementType, ByteAlignment>> = true;
| ^~~~~~~~~~~~~~~~
| is_aligned_accessor_v
include/experimental/__p1673_bits/blas_helpers.hpp:77:16: error: parse error in template argument list
77 | constexpr bool is_aligned_accessor_v<aligned_accessor<ElementType, ByteAlignment>> = true;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/experimental/__p1673_bits/blas_helpers.hpp:77:16: error: wrong number of template arguments (2, should be 1)
include/experimental/__p1673_bits/blas_helpers.hpp:73:16: note: provided for ‘template<class Accessor> constexpr const bool Kokkos::Experimental::__p1673_version_0::linalg::impl::is_aligned_accessor_v<Accessor>’
73 | constexpr bool is_aligned_accessor_v = false;
| ^~~~~~~~~~~~~~~~~~~~~
| return blas_value_type && blas_layout && blas_accessor; | ||
| } | ||
|
|
||
| // Return true if the BLAS call was successfull, false otherwise. |
There was a problem hiding this comment.
| // Return true if the BLAS call was successfull, false otherwise. | |
| // Return true if a BLAS routine could be called to scale the vector, false otherwise. |
The comment suggests that the BLAS could be called unsuccessfully, but the BLAS functions that could be called here don't have a failure mode.
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #334 +/- ##
==========================================
- Coverage 97.36% 97.15% -0.21%
==========================================
Files 70 70
Lines 5276 5347 +71
Branches 561 569 +8
==========================================
+ Hits 5137 5195 +58
- Misses 116 128 +12
- Partials 23 24 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
874710c to
6a94735
Compare
|
I've been working through the changes you requested, but ended up pushing more to my fork's branch than I meant to, some of it was experimentation that really belongs on a separate branch. I've force pushed the branch back to 6a94735, the commit you reviewed. |
|
@georgemalerbo wrote:
Thanks for working on this! Did you have any questions about the requested changes? |
…, drop is_aligned_accessor_v
Rather than raise the minimum cmake we can keep it at 3.12 and opt into CMP0077 and CMP0126, so a user of stdBLAS with a version of cmake 3.21 or newer can configure their project easily: set(LINALG_ENABLE_BLAS ON)
set(LINALG_CXX_STANDARD 20)
add_subdirectory(stdBLAS)
A user doing the ordinary thing against the tree as it was before this commit: cmake_minimum_required(VERSION 3.12)
project(app CXX)
add_subdirectory(stdBLAS)
add_executable(app main.cpp)
target_link_libraries(app linalg)// main.cpp
#include <experimental/linalg>
int main() {}$ cmake -S . -B build && cmake --build build
In file included from stdBLAS/include/experimental/linalg:35,
from main.cpp:1:
stdBLAS/include/experimental/__p1673_bits/blas1_givens.hpp:81:16: error: ‘is_inline_exec_v’ is not a member of ‘Kokkos::Experimental::__p1673_version_0::linalg::impl’
81 | && ! impl::is_inline_exec_v<Exec>
| ^~~~~~~~~~~~~~~~and with this commit in, the same project unchanged: $ cmake -S . -B build && cmake --build build
-- The CXX compiler identification is GNU 13.3.0
-- Detected support for C++23 standard
-- Using "-fconcepts" to enable concepts support
-- No installed mdspan found, fetching from Github
-- Build include directory: build/stdBLAS/include/experimental
-- Configuring done (2.9s)
-- Generating done (0.0s)
-- Build files have been written to: build
[ 50%] Building CXX object CMakeFiles/app.dir/main.cpp.o
[100%] Linking CXX executable app
[100%] Built target app
A user who adds
States that what it enables is calling CBLAS, and that the header can be named when the provider does not call it
|
|
@georgemalerbo The original title of this PR was "Fix stride(0) ordering, bound incx, reject incx == 0 and deduce the CBLAS index type." You've done that, no? Why not call that victory, get the PR merged, and create a new PR with the CI changes? What motivates combining those previous changes with the CI changes into a single PR? Reviewers need to be able to understand what's going on. It's easier to do that if each PR fixes one thing. |
Applies what @mhoemmen suggested in #331 x.stride(0) is now only called after x.is_strided() is confirmed, incx is bounded by the index type's max, and incx == 0 returns false so generic fallback handles it.
Also implemented the deduction of the BLAS integer index type discussed in #328: a variadic function template declaration, used only inside decltype, extracts the type of cblas_dscal's first parameter