71 int* piv_item,
int piv_base, int32_t* info_item,
72 ValAcc rval, IdxAcc ridx) {
75 const auto g = it.get_group();
76 const auto sg = it.get_sub_group();
77 const int lane =
static_cast<int>(sg.get_local_linear_id());
78 const int nlanes =
static_cast<int>(sg.get_local_linear_range());
79 const int team =
static_cast<int>(sg.get_group_linear_id());
80 const int nteams =
static_cast<int>(sg.get_group_linear_range());
86 :
static_cast<int>(it.get_local_range(0));
88 :
static_cast<int>(it.get_local_linear_id());
91 const auto phase_barrier = [&]() {
93 sycl::group_barrier(sg);
95 sycl::group_barrier(g);
99 int32_t info_local = (tid == 0) ? *info_item : 0;
101 for (
int k = 0; k < kmax; ++k) {
104 for (
int i = k + tid; i < m; i += wg) {
106 if (v > bv) { bv = v; bi = i; }
109 for (uint32_t off =
static_cast<uint32_t
>(nlanes) / 2; off > 0; off >>= 1) {
110 const R ov = sycl::permute_group_by_xor(sg, bv, off);
111 const int oi = sycl::permute_group_by_xor(sg, bi, off);
112 if (ov > bv || (ov == bv && oi < bi)) { bv = ov; bi = oi; }
122 static_cast<void>(rval);
123 static_cast<void>(ridx);
126 rval[
static_cast<std::size_t
>(team)] = bv;
127 ridx[
static_cast<std::size_t
>(team)] = bi;
129 sycl::group_barrier(g);
133 for (
int t = 0; t < nteams; ++t) {
134 const R v = rval[
static_cast<std::size_t
>(t)];
135 const int ii = ridx[
static_cast<std::size_t
>(t)];
136 if (v > fv || (v == fv && ii < p)) { fv = v; p = ii; }
139 static_cast<void>(fv);
143 piv_item[k] = piv_base + p + 1;
149 for (
int c = tid; c < n; c += wg) {
159 const D d = A.at(k, k);
160 if (batchlas::sycl_device::dev_is_zero(d)) {
162 if (tid == 0 && info_local == 0) {
163 info_local =
static_cast<int32_t
>(piv_base + k + 1);
166 const D r = batchlas::sycl_device::dev_recip(d);
167 const bool use_mul = batchlas::sycl_device::dev_isfinite(r) &&
168 !batchlas::sycl_device::dev_is_zero(r);
170 for (
int i = k + 1 + tid; i < m; i += wg) {
171 A.at(i, k) = batchlas::sycl_device::dev_mul(A.at(i, k), r);
175 for (
int i = k + 1 + tid; i < m; i += wg) {
176 A.at(i, k) = batchlas::sycl_device::dev_div(A.at(i, k), d);
184 const int mm = m - k - 1;
185 const int nn = n - k - 1;
186 if (mm > 0 && nn > 0) {
187 const int total = mm * nn;
188 for (
int e = tid; e < total; e += wg) {
189 const int i = k + 1 + (e % mm);
190 const int j = k + 1 + (e / mm);
191 A.at(i, j) = batchlas::sycl_device::dev_sub(
193 batchlas::sycl_device::dev_mul(A.at(i, k), A.at(k, j)));
200 *info_item = info_local;