Skip to content

Testing, benchmarking, performance improvements - #73

Merged
alphaville merged 23 commits into
mainfrom
f/improvements
Nov 4, 2026
Merged

alphaville merged 23 commits into
mainfrom
f/improvements

Conversation

@alphaville

@alphaville alphaville commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

Main Changes

Target version: v2.0.0

Added

  • scripts/run_python_tests.sh runs the Python pytest suite with configurable interpreter/build paths and optional C++ exchange tests.
  • File-I/O tests cover shapes, precision, binary layout, non-contiguous inputs, malformed files, filesystem errors, and actual C++/Python exchanges using temporary fixtures.
  • LeastSquaresBatchedWorkspace<T> preallocates reusable status storage and one-entry matrix-pointer arrays only for batches of one.
  • Svd::rankRelative(rtol, atol = 0) adds GPU rank calculation using per-matrix thresholds max(atol, rtol * sigmaMax) and validated tolerances.
  • Build/test and CUDA memory-check scripts run C++/Python tests, repeated leak checks, and save sanitizer logs.
  • Size-safe Session::recordAllocation(size_t), recordDeallocation(size_t), and counted cudaRelease methods.
  • DTensor::getRowsInto(destination, rowsFrom, rowsTo, matIdx) validates and copies rows into preallocated storage on the source stream.
  • DTensor::leastSquaresBatched(b, infoArray) supports reusable device status storage without per-call allocation.
  • Session::numStreams() exposes the initialized stream count.
  • Configurable GPU benchmarks compare batched GEMM and row-extraction methods, with correctness checks, host/GPU timings, and CSV results.
  • Regression tests cover validation, files, GEMM coefficients, stream ordering, ownership, rank tolerances, and reusable buffers.

Changed

  • Breaking: replace incrementAllocatedBytes(int) with separate size-safe allocation/deallocation methods.
  • Breaking: copy assignment deep-copies; move assignment transfers storage and empties the source. Use slices for aliases and deviceCopyTo for preallocated copies.
  • Reshape retains and reuses owned matrix-pointer capacity where possible.
  • Column-major uploads use the supplied host vector directly; only row-major uploads allocate a conversion buffer.
  • setStreamIdx returns a reference for lvalues and moves rvalues, avoiding implicit allocation and deep copying.
  • getRows uses one asynchronous 2D copy and inherits the source stream; getRowsInto preserves the destination's stream index.
  • Tensor constructors validate dimensions, allocation overflow, vector length, and storage mode before allocating.
  • Validate reshape sizes, slices, random bounds, row extraction, debug access, empty factoriser inputs, and QR output shapes.
  • Reject zero streams and reconfiguration after initialization; validate stream indices against the initialized count.
  • Document numerical preconditions, buffer lifetimes, stream dependencies, reusable workspaces, and binary-format assumptions.
  • Ignore generated build files, dependencies, binaries, and temporary test artifacts, including in-source builds.

Fixed

  • Nullspace projection uses constructor-allocated scratch and stream-ordered copy-back to avoid GEMM aliasing; tests cover dense batches, repeated calls, streams, and allocation reuse.
  • Givens annihilation uses the identity rotation for an already-zero pair, avoiding NaNs and preserving both rows; covered for float and double.
  • Python file I/O rejects incomplete headers, payload-size mismatches, zero dimensions, empty/scalar arrays, and object/zero-size dtypes before loading or overwriting data.
  • Python binary loading preserves column-major element order for single matrices, with a rectangular round-trip regression test.
  • Batched Cholesky and least-squares support single matrices using constructor-allocated pointer storage without allocations during reusable solves.
  • Size QR workspace for the largest requirement across factorisation, least-squares, and Q extraction; add large square/tall regressions for both precisions.
  • Share stream configuration across translation units using an inline static Session member, with a two-file regression test.
  • Prevent SVD constructor exception leaks using a unique_ptr owner and raw observer; verify cleanup with allocation-failure tests.
  • Tensor constructors release GPU storage on subsequent host-allocation failures; fault-injection tests verify cleanup for float, double, and int.
  • Session shutdown completes pending work, releases library handles, and destroys owned CUDA streams.
  • Single and batched Cholesky queries, factorisations, solves, and status tensors use the matrix-selected stream.
  • Host transfers, scalar reads, initialization, and pointer uploads complete on their selected stream; transpose results inherit the source stream.
  • Device copies wait for prior destination work and complete on the source stream before returning.
  • QR debugging-helper uploads complete on the selected solver stream before returning, fixing intermittent stream-ordering failures.
  • Track owned bytes and pointer capacity independently of shape, count successful allocations/frees, and preserve accounting across reshape, views, and moves.
  • Reset Svd::rank() counters on each call; SVD factorisation, rank kernels, and results use the input stream.
  • Assignment releases previous storage and safely handles metadata, self-assignment, and empty tensors; deep copies complete on the source stream.
  • Enable testing at the project root so ctest --test-dir build discovers the test suite.
  • Make the Python-format binary-reader test independent of generated Python files and the working directory.
  • Reject malformed text and incomplete or incorrectly sized binary files; report write failures and handle short filenames and empty data safely.
  • Avoid null-pointer arithmetic when slicing a single-matrix tensor along the matrix axis.
  • QR operations use the matrix-selected cuSolver/cuBLAS stream; getQR synchronizes before reading R on the host.
  • Givens coefficient kernels use the selected cuBLAS stream, check launch errors, and restore the previous pointer mode.
  • Make test-stream setup independent of execution order and add nonblocking-stream regressions for QR, Givens, and row extraction.
  • Correct the row-slicing test to select a column before slicing its rows.

Associated Issues

  • None for now

@alphaville alphaville added bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request labels Nov 4, 2026
@alphaville alphaville self-assigned this Nov 4, 2026
@alphaville
alphaville marked this pull request as ready for review November 4, 2026 16:33
@alphaville
alphaville merged commit 068b43b into main Nov 4, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant