Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
33c4018
Adding the diagnostic benchmark
mmelnich Mar 26, 2026
ab71121
Support for composite FEM operator
mmelnich Apr 2, 2026
383acd1
Adding a new benchmark
mmelnich Apr 3, 2026
8bcb860
Install script update
mmelnich Apr 4, 2026
7eaa6ec
Removing inefficiency
mmelnich Apr 4, 2026
d641656
Optimizing the benchmark
mmelnich Apr 6, 2026
8d9cc77
Minor updates
mmelnich Apr 6, 2026
3a5e801
CQRRT benchmarks redesigned
mmelnich Apr 7, 2026
4185e71
Small optimizations
mmelnich Apr 7, 2026
7a27780
Script name update
mmelnich Apr 7, 2026
cb1af26
Benchmark fix
mmelnich Apr 8, 2026
0ceeb73
Added BQRRP option to CQRRT
mmelnich Apr 9, 2026
118545d
CQRRT_stb analytical est
mmelnich Apr 24, 2026
a4f1c39
New benchmark for Oleg
mmelnich May 7, 2026
d92e012
Comments update
mmelnich May 7, 2026
ad00419
Fix TRSM direction when forming R_sk^{-1} from identity
mmelnich May 15, 2026
8acd6b3
IR-LSQ refactor: sparse-input benchmark, fix breakdown + analytical_k…
mmelnich May 22, 2026
e9e9ee1
GSVD benchmark: rewrite FEM mode for J = L^{-1} * K * V composite
mmelnich May 28, 2026
9c7b19f
Merge IR-LSQ into CQRRT_linop_applications; add Higham residual metric
mmelnich Jun 1, 2026
527a0b5
Refactor CholQR family around shared PCholQR primitive (collaborator'…
mmelnich Jun 1, 2026
5c50255
Add PowerOp linop and sparse_axpby helper
mmelnich Jun 1, 2026
8dc80b2
Add SparseLUSolverLinOp for sparse A^{-1} on indefinite matrices
mmelnich Jun 1, 2026
424e369
Add TransposedOp generic linop wrapper
mmelnich Jun 1, 2026
252b303
Add rspec mode (reduced spectral approximation) to applications bench…
mmelnich Jun 2, 2026
2ab53b5
Drop SVD/upcast paths from applications benchmark; remove obsolete test
mmelnich Jun 2, 2026
48488a0
Use canonical condition-number and orth-error helpers in diagnostic.cc
mmelnich Jun 2, 2026
94cf3ac
Style fixes in CQRRT benchmarks: lacpy, syrk+symmetrize, drop wrappers
mmelnich Jun 2, 2026
6e05d80
SparseLU: reuse solve scratch across calls; simplify tests
mmelnich Jun 2, 2026
132ca46
cholqr_primitive: internalize scratch allocation
mmelnich Jun 2, 2026
fd08005
Replace std::vector workspaces with raw T* (IR-LSQ + applications bench)
mmelnich Jun 2, 2026
5ecbe1f
Replace std::vector workspaces with raw T* in CQRRT_linop_basic
mmelnich Jun 2, 2026
3a93498
Extract small benchmark I/O helpers into cqrrt_bench_common.hh
mmelnich Jun 2, 2026
34365ec
orth_error: revert to explicit Q materialization; cholqr diagnostics
mmelnich Jun 5, 2026
98627b5
CholQR family rework: adaptive shift, CholQR2, sCholQR3_basic on prim…
mmelnich Jun 5, 2026
07e1c80
analytical_kb: account for primitive transients + adaptive-shift G_ba…
mmelnich Jun 8, 2026
36cf3c2
Change of shift policies in QR
mmelnich Jun 9, 2026
0b42c89
test: guard CQRRT_linops BQRRP precond test on macOS (Apple Accelerat…
mmelnich Jun 9, 2026
2391941
rspec: replace SparseLU linop with sparse Cholesky for X = K - omega*M
mmelnich Jun 10, 2026
4bcb98b
cholqr: unify cholqr/pcholqr into one primitive (optional preconditio…
mmelnich Jun 10, 2026
2a2577e
cholqr: shared cholqr_iterate engine; CholQR/CholQR2/sCholQR3 as thin…
mmelnich Jun 10, 2026
53ea706
rspec: record runtime breakdown CSV (QR + Rayleigh-Ritz phases)
mmelnich Jun 10, 2026
2c2adde
Add regularized augmented-operator IR-LSQ benchmark (irlsq_reg)
mmelnich Jun 12, 2026
e2eb9fb
irlsq_reg: scale mu like the shifted-CholeskyQR shift (Fukaya)
mmelnich Jun 16, 2026
dfaa2b3
irlsq_reg: revert mu to the collaborator's spec (mu = mu_factor * u)
mmelnich Jun 17, 2026
4e5089a
sCHolQR3 fix
mmelnich Jun 22, 2026
480e3cc
macos fix
mmelnich Jun 22, 2026
d0ec977
CQRRT_linops: adaptive-shift safety net in the preconditioned-Gram Ch…
mmelnich Jul 3, 2026
578c18d
Add Blendenpik (LSQR + sketch-QR preconditioner) + Cholesky retry-cou…
mmelnich Jul 10, 2026
25ec6a6
Add matrix-free Toeplitz LS benchmark (Oleg's autoregression experiment)
mmelnich Jul 14, 2026
d2e5677
Toeplitz LS: record full Oleg metric set (solver/normal relres, cond …
mmelnich Jul 15, 2026
bd88dba
IR-LSQ inner-CG diagnosis, Blendenpik warm start, and correctness fixes
mmelnich Jul 27, 2026
764a082
rl_gen: fix gen_bad_cholqr_singvals, which returned an all-ones spectrum
mmelnich Jul 28, 2026
8cf1033
Add dense (non-LinOp) entry points for the CholQR family
mmelnich Jul 28, 2026
340f85d
benchmark: emit LSQR solve breakdown (fwd/adj/trsm) in toeplitz_ls
mmelnich Jul 30, 2026
250e3e9
IterRefineLSQ: exit inner CG on stagnation and return the best iterate
mmelnich Jul 30, 2026
f116918
...
mmelnich Jul 30, 2026
47b32c0
irlsq_reg: record warm-start x0 build time as ir_setup_us CSV column
mmelnich Jul 30, 2026
e9c3547
toeplitz_ls: warm-start ablation knobs + setup_us column
mmelnich Jul 31, 2026
135ee7c
IterRefineLSQ: single inner-CG restart from the returned iterate (inn…
mmelnich Aug 5, 2026
7361022
PeakRSSTracker: malloc_trim(0) at start() so per-method RSS deltas ar…
mmelnich Aug 5, 2026
3ddfa47
benchmarks: Blendenpik-only warm start (warm+cold rows), CPU warmups,…
mmelnich Aug 5, 2026
17a60e2
Port restarted_pcg_ne and unify the two LS benchmark solver structures
mmelnich Aug 6, 2026
3b2ee61
pcg_ne: stable round residual (Epperly Alg. 1 line 5) + regression tests
mmelnich Aug 6, 2026
39b9808
CQRRT_diagnostic: add the correctly-ordered TRSM-with-identity path
mmelnich Aug 7, 2026
4c32aae
Unify LS solvers on restarted_pcg_ne with per-round restart pacing
mmelnich Aug 7, 2026
60f366a
Cap BLAS threads around the preconditioner triangular solves
mmelnich Aug 8, 2026
d148e73
Calibrate the level-2 thread cap on the benchmark hardware
mmelnich Aug 8, 2026
b5a2886
Cap threads for the FFT applies in ToeplitzLinOp
mmelnich Aug 10, 2026
6d026d5
Add refined Blendenpik rows: warm and cold, through our own solver
mmelnich Aug 10, 2026
a73d03d
Add the refined Blendenpik rows to the irlsq_reg path too
mmelnich Aug 11, 2026
3b08493
Env knobs for the 0812_d2 accuracy era: RANDLAPACK_GRAM_LEFT=gemm (pe…
mmelnich Aug 17, 2026
868477b
Solver stack: complete timing attribution, named exit statuses, LS-fl…
mmelnich Aug 27, 2026
c9c837e
Benchmarks: shared refined-Blendenpik dispatch, complete per-row acco…
mmelnich Aug 27, 2026
db21de0
PR #129 audit fixes + paper-consistency pass
mmelnich Aug 29, 2026
92061e2
Benchmarks: RANDLAPACK_CHOL_MAX_RETRIES knob pins published Q-less ro…
mmelnich Sep 1, 2026
dabde67
CholQR: RANDLAPACK_CHOL_SYMMETRIZE knob makes the Gram symmetrization…
mmelnich Sep 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,6 @@ benchmark/build/**
test/test_runner

z_ignore_riley/**
benchmark-build-audit/
build-audit/
install-audit/
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR})
include(compiler_flags)

# Configure the build
enable_testing()

include(rl_build_options)
include(rl_version)

Expand All @@ -60,6 +58,7 @@ add_subdirectory(RandBLAS)
# Compile sources
add_subdirectory(RandLAPACK)
if (RandLAPACK_BUILD_TESTS)
enable_testing()
add_subdirectory(test)
endif()

Expand Down
11 changes: 9 additions & 2 deletions RandLAPACK.hh
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,19 @@
#include "RandLAPACK/comps/rl_syrf.hh"
#include "RandLAPACK/comps/rl_orth.hh"
#include "RandLAPACK/comps/rl_rpchol.hh"
#include "RandLAPACK/comps/rl_cholqr.hh"

// Drivers
#include "RandLAPACK/drivers/rl_rsvd.hh"
#include "RandLAPACK/drivers/rl_cqrrt.hh"
#include "RandLAPACK/drivers/rl_cqrrt.hh" // holds both dense CQRRT and CQRRT_linops
#include "RandLAPACK/drivers/rl_cholqr_linops.hh"
#include "RandLAPACK/drivers/rl_cqrrt_linops.hh"
#include "RandLAPACK/drivers/rl_cholqr_dense.hh"
#include "RandLAPACK/drivers/rl_iter_refine_lsq.hh"
// Both of these declare themselves "Public API" in their headers but were reachable
// only by including them directly, which is part of why neither had any test coverage.
#include "RandLAPACK/drivers/rl_lsqr.hh"
#include "RandLAPACK/drivers/rl_restarted_pcg_ne.hh"
#include "RandLAPACK/drivers/rl_blendenpik.hh"
#include "RandLAPACK/drivers/rl_scholqr3_linops.hh"
#include "RandLAPACK/drivers/rl_cqrrpt.hh"
#include "RandLAPACK/drivers/rl_bqrrp.hh"
Expand Down
747 changes: 747 additions & 0 deletions RandLAPACK/comps/rl_cholqr.hh

Large diffs are not rendered by default.

302 changes: 302 additions & 0 deletions RandLAPACK/drivers/rl_blendenpik.hh

Large diffs are not rendered by default.

353 changes: 353 additions & 0 deletions RandLAPACK/drivers/rl_cholqr_dense.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,353 @@
#pragma once

#include "rl_util.hh"
#include "rl_blaspp.hh"
#include "rl_lapackpp.hh"
#include "rl_linops.hh"
#include "rl_exceptions.hh"
#include "../comps/rl_cholqr.hh"

#include <cstdint>
#include <vector>
#include <chrono>
#include <limits>

namespace RandLAPACK {

/// Dense (non-LinOp) entry points for the CholQR family.
///
/// These drivers take a raw column-major buffer instead of a LinearOperator, for
/// callers that work through the regular BLAS API and do not want to build an
/// operator first. They run the SAME numerics as their LinOp counterparts in
/// `rl_cholqr_linops.hh` and `rl_scholqr3_linops.hh`: each wraps its input in a
/// `linops::DenseLinOp` and delegates to the shared `cholqr_iterate` engine, so
/// the pass count, the shift policy, and the adaptive-shift retry are inherited
/// rather than reimplemented. The only thing that differs is the interface.
///
/// The three members of the family are distinguished exactly as in the engine:
/// CholQR_dense num_iters = 1, both shifts 0 (unshifted first attempt)
/// CholQR2_dense num_iters = 2, both shifts 0
/// sCholQR3_dense num_iters = 3, iter 1 shifted by eps, iters 2-3 unshifted
///
/// A is not modified. R is the (upper-triangular) output factor. When a Q buffer
/// is supplied, Q = A * R^{-1} is materialized after the factorization and is
/// excluded from the reported timing total, matching the LinOp drivers' test mode.

namespace detail {

/// Shared body for the three dense drivers. Wraps A in a DenseLinOp and runs
/// `num_iters` passes of the CholQR engine.
///
/// @param[in] m Rows of A. Must be >= 0.
/// @param[in] n Columns of A. Must be >= 0 and <= m.
/// @param[in] A Column-major input buffer, not modified.
/// @param[in] lda Leading dimension of A, must be >= m.
/// @param[out] R Output factor, n by n, column-major.
/// @param[in] ldr Leading dimension of R, must be >= n.
/// @param[out] Q Optional. If non-null, receives Q = A * R^{-1} (m by n).
/// @param[in] ldq Leading dimension of Q. Must be >= m. Ignored when Q is null.
/// @param[out] applied_shifts Optional, length num_iters: per-pass absolute shift
/// the successful potrf carried (0 = unshifted).
/// @param[out] gram_traces Optional, length num_iters: per-pass Gram trace.
/// @param[out] q_mat_us Optional. When Q is materialized and timing is on, receives
/// the wall-clock (us) spent materializing Q, so the caller can
/// exclude it from the reported total exactly as the LinOp
/// drivers do. Set to 0 when Q is null or timing is off.
/// @return 0 on success, or the 1-based index of the pass whose Cholesky failed.
template <typename T>
int cholqr_dense_body(
int64_t m,
int64_t n,
const T* A,
int64_t lda,
T* R,
int64_t ldr,
T* Q,
int64_t ldq,
int64_t block_size,
int num_iters,
T shift_iter1,
T shift_iter_rest,
int max_retries,
T shift_growth,
bool timing,
long* iter_times,
int* n_retries_total,
T* applied_shifts,
T* gram_traces,
long* q_mat_us
) {
randlapack_require(m >= 0) << "m=" << m << " must be >= 0";
randlapack_require(n >= 0) << "n=" << n << " must be >= 0";
randlapack_require(n <= m) << "n=" << n << " must be <= m=" << m << " (CholQR needs a tall or square input)";
randlapack_require(lda >= m) << "lda=" << lda << " < m=" << m << " (column-major input)";
randlapack_require(ldr >= n) << "ldr=" << ldr << " < n=" << n;
randlapack_require(!(A == nullptr && m > 0 && n > 0)) << "A buffer is null but m=" << m << " and n=" << n << " imply a nonempty matrix";
randlapack_require(!(Q != nullptr && ldq < m)) << "ldq=" << ldq << " < m=" << m << " (column-major Q output)";

if (q_mat_us) *q_mat_us = 0;

linops::DenseLinOp<T> A_op(m, n, A, lda, Layout::ColMajor);

int info = cholqr_iterate<T, linops::DenseLinOp<T>>(
A_op, R, ldr, block_size, num_iters,
shift_iter1, shift_iter_rest,
max_retries, shift_growth, timing,
iter_times, n_retries_total, applied_shifts, gram_traces);
if (info != 0)
return info;

if (Q != nullptr) {
int64_t b_eff = (block_size > 0 && block_size < n) ? block_size : n;
if (timing && q_mat_us) {
std::chrono::steady_clock::time_point qt0 = std::chrono::steady_clock::now();
RandLAPACK::materialize_Q_from_R(A_op, R, ldr, m, n, b_eff, Q, ldq);
std::chrono::steady_clock::time_point qt1 = std::chrono::steady_clock::now();
*q_mat_us = std::chrono::duration_cast<std::chrono::microseconds>(qt1 - qt0).count();
} else {
RandLAPACK::materialize_Q_from_R(A_op, R, ldr, m, n, b_eff, Q, ldq);
}
}
return 0;
}

} // end namespace detail


/// Plain CholeskyQR on a dense column-major buffer.
/// One unpreconditioned pass, unshifted first attempt.
template <typename T>
class CholQR_dense {
public:

bool timing;
int64_t block_size;

// Adaptive-shift safety net: the first attempt is unshifted, and only on
// potrf breakdown does the primitive seed the shift and grow it. A negative
// max_retries means unbounded, matching the LinOp drivers.
int max_retries;
T shift_growth;
int n_chol_retries = 0; ///< shift retries used on the last call (0 = clean)
/// Per-pass shift record from the last call: the absolute diagonal shift the
/// successful potrf carried (0 = unshifted) and that pass's Gram trace.
T chol_applied_shifts[1] = {T(0)};
T chol_gram_traces[1] = {T(0)};

// 6 entries: alloc, fwd, adj, chol, rest, total
std::vector<long> times;
long total_us() const { return times.empty() ? -1L : times.back(); }

CholQR_dense(
bool time_subroutines
) {
timing = time_subroutines;
block_size = kDefaultGramBlockSize;
max_retries = -1;
shift_growth = T(10);
}

int call(
int64_t m,
int64_t n,
const T* A,
int64_t lda,
T* R,
int64_t ldr,
T* Q = nullptr,
int64_t ldq = 0
) {
std::chrono::steady_clock::time_point total_t_start, total_t_stop;
if (this->timing) total_t_start = std::chrono::steady_clock::now();

long it[5] = {0};
long q_mat_us = 0;
int info = detail::cholqr_dense_body<T>(
m, n, A, lda, R, ldr, Q, ldq,
this->block_size, /*num_iters=*/1,
/*shift_iter1=*/T(0), /*shift_iter_rest=*/T(0),
this->max_retries, this->shift_growth, this->timing,
this->timing ? it : nullptr, &this->n_chol_retries,
this->chol_applied_shifts, this->chol_gram_traces,
this->timing ? &q_mat_us : nullptr);
if (info != 0) return info;

if (this->timing) {
total_t_stop = std::chrono::steady_clock::now();
long total_dur = std::chrono::duration_cast<std::chrono::microseconds>(total_t_stop - total_t_start).count() - q_mat_us;
long fwd = it[0], adj = it[1], chol = it[3];
long rest_dur = total_dur - (fwd + adj + chol);
this->times = {0L, fwd, adj, chol, rest_dur, total_dur};
}
return 0;
}
};


/// CholeskyQR2 on a dense column-major buffer.
/// Two passes, both starting unshifted; the retry rescues a non-PD Gram.
template <typename T>
class CholQR2_dense {
public:

bool timing;
int64_t block_size;

int max_retries;
T shift_growth;
int n_chol_retries = 0;
/// Per-pass shift record from the last call (pass 1, pass 2): absolute shift
/// the successful potrf carried (0 = unshifted) and that pass's Gram trace.
T chol_applied_shifts[2] = {T(0), T(0)};
T chol_gram_traces[2] = {T(0), T(0)};

// 11 entries: alloc, fwd1, adj1, chol1, upd1, fwd2, adj2, gemm2, chol2, upd2, total
// upd1 is 0 by convention (iter 1 has no R-update step). Matches
// CholQR2_linops's layout exactly (the always-zero iter-1 gemm slot is
// dropped, not carried as a 12th entry).
std::vector<long> times;
long total_us() const { return times.empty() ? -1L : times.back(); }

CholQR2_dense(
bool time_subroutines
) {
timing = time_subroutines;
block_size = kDefaultGramBlockSize;
max_retries = -1;
shift_growth = T(10);
}

int call(
int64_t m,
int64_t n,
const T* A,
int64_t lda,
T* R,
int64_t ldr,
T* Q = nullptr,
int64_t ldq = 0
) {
std::chrono::steady_clock::time_point total_t_start, total_t_stop;
if (this->timing) total_t_start = std::chrono::steady_clock::now();

long it[10] = {0};
long q_mat_us = 0;
int info = detail::cholqr_dense_body<T>(
m, n, A, lda, R, ldr, Q, ldq,
this->block_size, /*num_iters=*/2,
/*shift_iter1=*/T(0), /*shift_iter_rest=*/T(0),
this->max_retries, this->shift_growth, this->timing,
this->timing ? it : nullptr, &this->n_chol_retries,
this->chol_applied_shifts, this->chol_gram_traces,
this->timing ? &q_mat_us : nullptr);
if (info != 0) return info;

if (this->timing) {
total_t_stop = std::chrono::steady_clock::now();
long total_dur = std::chrono::duration_cast<std::chrono::microseconds>(total_t_stop - total_t_start).count() - q_mat_us;
// it = [fwd1,adj1,gemm1=0,chol1,upd1, fwd2,adj2,gemm2,chol2,upd2].
// Drop the always-zero gemm1 slot (it[2]) to match CholQR2_linops.
this->times = {0L, it[0], it[1], it[3], it[4],
it[5], it[6], it[7], it[8], it[9],
total_dur};
}
return 0;
}
};


/// Shifted CholeskyQR3 on a dense column-major buffer.
/// Three passes; iter 1 carries the shift (default: the paper's 11*n*eps, or
/// eps via RANDLAPACK_SCHOLQR3_SHIFT=eps), iters 2 and 3 are unshifted
/// (Fukaya's prescription). This mirrors sCholQR3_linops exactly, including its
/// RANDLAPACK_SCHOLQR3_SHIFT env knob (shared via scholqr3_eps_shift() in
/// comps/rl_cholqr.hh).
template <typename T>
class sCholQR3_dense {
public:

bool timing;
int64_t block_size;

T shift_factor_iter1;
T shift_factor_iter23;

int max_retries;
T shift_growth;
int n_chol_retries = 0;
/// Per-pass shift record from the last call (passes 1-3): absolute shift the
/// successful potrf carried (0 = unshifted) and that pass's Gram trace.
T chol_applied_shifts[3] = {T(0), T(0), T(0)};
T chol_gram_traces[3] = {T(0), T(0), T(0)};

// Timing breakdown (18 entries; matches sCholQR3_linops exactly):
// [0] alloc
// [1] fwd1 [2] adj1 [3] chol1 [4] upd1
// [5] fwd2 [6] adj2 [7] gemm2 [8] chol2 [9] upd2
// [10] fwd3 [11] adj3 [12] gemm3 [13] chol3 [14] upd3
// [15] q_mat [16] rest [17] total
std::vector<long> times;
long total_us() const { return times.empty() ? -1L : times.back(); }

sCholQR3_dense(
bool time_subroutines
) {
timing = time_subroutines;
block_size = kDefaultGramBlockSize;
shift_factor_iter1 = T(-1); // < 0: resolve default (11*n*eps, or eps via env) at call time
shift_factor_iter23 = T(0);
max_retries = -1;
shift_growth = T(10);
}

int call(
int64_t m,
int64_t n,
const T* A,
int64_t lda,
T* R,
int64_t ldr,
T* Q = nullptr,
int64_t ldq = 0
) {
std::chrono::steady_clock::time_point total_t_start, total_t_stop;
if (this->timing) total_t_start = std::chrono::steady_clock::now();

// First-pass shift defaults to the paper's s = 11*eps*n*trace(G)
// (FukayaEtAl2020, c = 11); RANDLAPACK_SCHOLQR3_SHIFT=eps selects the
// legacy eps*trace(G). A caller-set shift_factor_iter1 >= 0 wins.
// Same knob resolution as sCholQR3_linops.
const T eps_T = std::numeric_limits<T>::epsilon();
const T sf1 = (this->shift_factor_iter1 >= T(0))
? this->shift_factor_iter1
: (scholqr3_eps_shift() ? eps_T : T(11) * T(n) * eps_T);

long it[15] = {0};
long q_mat_us = 0;
int info = detail::cholqr_dense_body<T>(
m, n, A, lda, R, ldr, Q, ldq,
this->block_size, /*num_iters=*/3,
sf1, this->shift_factor_iter23,
this->max_retries, this->shift_growth, this->timing,
this->timing ? it : nullptr, &this->n_chol_retries,
this->chol_applied_shifts, this->chol_gram_traces,
this->timing ? &q_mat_us : nullptr);
if (info != 0) return info; // 1/2/3 = the pass that failed

if (this->timing) {
total_t_stop = std::chrono::steady_clock::now();
long total_dur = std::chrono::duration_cast<std::chrono::microseconds>(total_t_stop - total_t_start).count() - q_mat_us;
long iters_sum = 0;
for (int i = 0; i < 15; ++i) iters_sum += it[i];
long rest_dur = total_dur - iters_sum;
this->times = {0L,
it[0], it[1], it[3], it[4], // fwd1, adj1, chol1, upd1
it[5], it[6], it[7], it[8], it[9], // fwd2, adj2, gemm2, chol2, upd2
it[10], it[11], it[12], it[13], it[14], // fwd3, adj3, gemm3, chol3, upd3
q_mat_us, rest_dur, total_dur};
}
return 0;
}
};

} // end namespace RandLAPACK
Loading
Loading