sytrd_sb2st_hh.hh
Go to the documentation of this file.
1#pragma once
2
3// Stage-2 band -> tridiagonal by Householder bulge chasing, reflectors RETAINED for Z := Q2 Z
4// (the Givens sytrd_sb2st discards Q2). Reflector k acts on rows [start_k, start_k + len_k);
5// Q = H_1 ... H_m in generation order, so the back-transform applies them in REVERSE.
6// evidence: docs/perf/sytrd.md#sytrd-the-householder-chase-against-the-givens-chase
7
8#include <src/util/internal-api.hh>
13
14#include <cstdint>
15#include <vector>
16
17namespace batchlas {
18namespace internal {
19
20// One stored reflector. `sweep` is kept because one sweep's reflectors act on disjoint
21// row ranges (starts stride by kd, length <= kd) and can be applied concurrently.
23 int32_t start;
24 int32_t len;
25 int32_t sweep;
26};
27
28// The chase schedule depends only on (n, kd), so one host replay serves every batch item.
29inline std::vector<Sb2stHhRefl> build_sb2st_hh_schedule(int32_t n, int32_t kd) {
30 std::vector<Sb2stHhRefl> out;
31 if (n <= 2 || kd <= 1) return out;
32
33 for (int32_t st = 0; st + 2 < n; ++st) {
34 int32_t r0 = st + 1;
35 int32_t r1 = (st + kd < n - 1) ? (st + kd) : (n - 1);
36 if (r1 <= r0) continue;
37
38 // Annihilate column st below the subdiagonal, then chase the bulge down the band.
39 out.push_back(Sb2stHhRefl{r0, r1 - r0 + 1, st});
40 while (true) {
41 const int32_t p0 = r1 + 1;
42 const int32_t p1 = (r1 + kd < n - 1) ? (r1 + kd) : (n - 1);
43 if (p0 > p1) break;
44 out.push_back(Sb2stHhRefl{p0, p1 - p0 + 1, st});
45 r0 = p0;
46 r1 = p1;
47 }
48 }
49 return out;
50}
51
52inline int32_t sb2st_hh_num_reflectors(int32_t n, int32_t kd) {
53 return static_cast<int32_t>(build_sb2st_hh_schedule(n, kd).size());
54}
55
56// A length-kd reflector applied symmetrically fills up to kd rows below the band: hold 2*kd.
57inline int32_t sb2st_hh_work_bandwidth(int32_t n, int32_t kd) {
58 const int32_t want = 2 * kd;
59 const int32_t cap = (n > 0) ? (n - 1) : 0;
60 return (want < cap) ? want : cap;
61}
62
63// ab_in: (kd+1) x n lower band, read-only. ab_tri_out: 2 x n, diagonal and SIGNED subdiagonal
64// (build_phase_from_kd1_band consumes it unchanged). d_out/e_out: real diagonal, |subdiagonal|.
65// v_out: kd x nrefl, reflector k in column k with v[0] = 1, zero-padded; tau_out: nrefl, where
66// nrefl == build_sb2st_hh_schedule(n, kd).size().
67template <Backend B, typename T>
68BATCHLAS_INTERNAL_API Event sytrd_sb2st_hh(Queue& ctx,
70 const MatrixView<T, MatrixFormat::Dense>& ab_tri_out,
71 const VectorView<typename base_type<T>::type>& d_out,
72 const VectorView<typename base_type<T>::type>& e_out,
74 const VectorView<T>& tau_out,
75 Uplo uplo,
76 int32_t kd,
77 const Span<std::byte>& ws);
78
79template <Backend B, typename T>
80BATCHLAS_INTERNAL_API size_t sytrd_sb2st_hh_buffer_size(Queue& ctx, int32_t n, int32_t kd, int32_t batch);
81
82// Maximal runs of pairwise-disjoint (commuting) reflectors, run w = [off[w], off[w+1]). They
83// equal the sweeps but are DERIVED from the schedule, so an unsound grouping cannot slip in.
84inline std::vector<int32_t> build_sb2st_hh_wave_offsets(
85 const std::vector<Sb2stHhRefl>& sched, int32_t n) {
86 std::vector<int32_t> off;
87 const int32_t nrefl = static_cast<int32_t>(sched.size());
88 if (nrefl <= 0 || n <= 0) return off;
89
90 std::vector<int32_t> stamp(static_cast<size_t>(n), -1);
91 int32_t run = 0;
92 off.push_back(0);
93 for (int32_t k = 0; k < nrefl; ++k) {
94 const int32_t s = sched[k].start;
95 const int32_t e = s + sched[k].len;
96 bool overlaps = false;
97 for (int32_t r = s; r < e && r < n; ++r) {
98 if (stamp[r] == run) { overlaps = true; break; }
99 }
100 if (overlaps) { off.push_back(k); ++run; }
101 for (int32_t r = s; r < e && r < n; ++r) stamp[r] = run;
102 }
103 off.push_back(nrefl);
104 return off;
105}
106
107// Z := Q2 Z. starts/lens/waves come from the two builders above; every span must outlive the
108// returned Event (nothing is copied).
109template <Backend B, typename T>
110BATCHLAS_INTERNAL_API Event unmqr_hb2st(Queue& ctx,
112 const VectorView<T>& tau_in,
114 int32_t n,
115 int32_t kd,
116 Span<const int32_t> starts,
118 Span<const int32_t> waves);
119
120} // namespace internal
121} // namespace batchlas
Non-owning view of a batch of matrices: the argument type of every entry point.
Definition matrix.hh:485
Non-owning view of a batch of strided vectors: the vector argument type of the entry points.
Definition matrix.hh:1754
Enumerations, scalar traits and scalar concepts shared by every public header.
Uplo
Which triangle of a symmetric, Hermitian or triangular operand is referenced.
Definition enums.hh:287
The batched containers: Matrix (owning), MatrixView (non-owning), KernelMatrixView (device-side),...
std::vector< Sb2stHhRefl > build_sb2st_hh_schedule(int32_t n, int32_t kd)
int32_t sb2st_hh_num_reflectors(int32_t n, int32_t kd)
BATCHLAS_INTERNAL_API Event unmqr_hb2st(Queue &ctx, const MatrixView< T, MatrixFormat::Dense > &v_in, const VectorView< T > &tau_in, const MatrixView< T, MatrixFormat::Dense > &z_io, int32_t n, int32_t kd, Span< const int32_t > starts, Span< const int32_t > lens, Span< const int32_t > waves)
int32_t sb2st_hh_work_bandwidth(int32_t n, int32_t kd)
BATCHLAS_INTERNAL_API size_t sytrd_sb2st_hh_buffer_size(Queue &ctx, int32_t n, int32_t kd, int32_t batch)
std::vector< int32_t > build_sb2st_hh_wave_offsets(const std::vector< Sb2stHhRefl > &sched, int32_t n)
BATCHLAS_INTERNAL_API Event sytrd_sb2st_hh(Queue &ctx, const MatrixView< T, MatrixFormat::Dense > &ab_in, const MatrixView< T, MatrixFormat::Dense > &ab_tri_out, const VectorView< typename base_type< T >::type > &d_out, const VectorView< typename base_type< T >::type > &e_out, const MatrixView< T, MatrixFormat::Dense > &v_out, const VectorView< T > &tau_out, Uplo uplo, int32_t kd, const Span< std::byte > &ws)
Completion handle of enqueued work, returned by every entry point.
Where BatchLAS work runs: a device, a backend, an ordered SYCL queue and a workspace arena.
Non-owning view of size() contiguous elements of type T.
Definition sycl-span.hh:39
T type
The real type.
Definition enums.hh:30
batchlas::Device, batchlas::Event and batchlas::Queue: where work runs and how it is ordered.
batchlas::Span, the non-owning pointer + length every entry point takes for 1-D data.