Skip to content

Refactor linear algebra module and remove unused code#195

Merged
ulises-jeremias merged 60 commits intomainfrom
feature/new-lapack
Dec 28, 2025
Merged

Refactor linear algebra module and remove unused code#195
ulises-jeremias merged 60 commits intomainfrom
feature/new-lapack

Conversation

@ulises-jeremias
Copy link
Copy Markdown
Member

@ulises-jeremias ulises-jeremias commented Jan 7, 2024

Summary by CodeRabbit

  • Chores

    • Updated CI test steps and platform-specific test selections; adjusted flags for C backends.
    • .gitignore updated to ignore "reference".
    • Added a multi-phase implementation plan for BLAS/LAPACK work.
  • New Features

    • Added LAPACK and BLAS APIs and comprehensive wrappers for common factorizations, solvers, SVD, and eigen routines.
    • Introduced strong enums and conversion helpers for numerical options.
    • Large test suites for BLAS and LAPACK (Level 1–3 + integration) added.
  • Documentation

    • New READMEs describing BLAS/LAPACK backends and installation notes.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 7, 2024

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Added a comprehensive Pure‑V and LAPACKE LAPACK/BLAS implementation and test-suite: new lapack64 and blas64 cores, high‑level V wrappers, many BLAS/LAPACK routines and tests, enum conversion layers, CI adjustments, README and implementation plan, and .gitignore update. Changes span core algorithms, wrappers, tests, and build flags.

Changes

Cohort / File(s) Change Summary
CI & repo
.github/workflows/ci.yml, .gitignore, README.md
CI test step replaced with "Pure V Backend with Pure C Backend" (adds --use-lapacke alongside --use-cblas), macOS Pure‑V step commented out; .gitignore adds reference; README note about QR path/tests.
Project plan & docs
IMPLEMENTATION_PLAN.md, lapack/README.md, blas/README.md
New implementation plan and package READMEs describing backends, installation, roadmap, and timelines.
Top-level LAPACK wrappers & API
lapack/lapack_wrappers.v, lapack/lapack_notd_vsl_lapack_lapacke.v, lapack/lapack_d_vsl_lapack_lapacke.v
Added high-level V wrappers and LAPACKE C bindings; refactored LAPACK surface to call lapack64 backend, added many idiomatic 2D matrix APIs and flat-array wrappers.
lapack <-> lapack64 conversions
lapack/conversions.v, lapack/lapack64/conversions.v, lapack/lapack64/cflags_d_vsl_lapack_lapacke.v, lapack/cflags_d_vsl_lapack_lapacke.v
Introduced strongly typed LAPACK enums and exhaustive conversion functions; updated module names and platform cflags/link flags.
lapack64 core algorithms & utilities
lapack/lapack64/*.v (e.g. dgesv.v, dgeev.v, dgetf2.v, dgetrf.v, dgetrs.v, dgetri.v, dgetri_test.v, dgetrf_test.v, dpotrf.v, dpotf2.v, dtrtri.v, dtrti2.v, dgebal.v, dgeqrf.v, dorgqr.v, dlange.v, dlacpy.v, dlaswp.v)
Large set of new LAPACK64 implementations: LU, QR, Cholesky, inverse, eigen, balancing, norms, copy/swap, workspace/query handling, blocked/unblocked variants, and corresponding unit tests.
High-level lapack tests & utilities
lapack/lapack_test.v
Added extensive LAPACK test suite and matrix utilities (norms, SPD generators, orthogonality checks) exercising many routines and integration scenarios.
BLAS enums, wrappers & backends
blas/conversions.v, blas/oblas_notd_vsl_blas_cblas.v, blas/oblas_d_vsl_blas_cblas.v, blas/oblas_notd_vsl_blas_cblas.v, blas/colmajor.v, blas/oblas_d_vsl_blas_cblas.v
Introduced strongly typed BLAS enums, conversion helpers, OpenBLAS/CBLAS bindings, and pure‑V wrappers delegating to blas64 with explicit enum conversions and data‑layout handling.
blas64 core algorithms
blas/blas64/*.v (e.g. colmajor.v, level1f64_test.v, level2f64_test.v, level3f64_test.v, level3f64_dsyr2k.v, level3f64_dtrmm.v, level3f64_dtrsm.v, util.v)
Added column‑major BLAS64 implementations for core Level‑1/2/3 routines (cm_*), specialized dtrmm/dtrsm/dsyr2k, test tolerance constant and comprehensive tests for Level‑1/2/3.
High-level BLAS tests
blas/blas_test.v
Added BLAS test suite exercising many BLAS interfaces in row‑major wrappers and larger correctness/performance checks.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Poem

🐇 I hopped through enums, matrices in tow,
I pivoted, factored, and made tests glow.
From dgetrf to dgesvd I bounced with delight,
CI flags flipped and the builds took flight.
Tiny paws, big math — the rabbit says "Let's code!"

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/new-lapack

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d790038 and f03e248.

📒 Files selected for processing (31)
  • README.md
  • blas/blas64/colmajor.v
  • blas/blas_test.v
  • blas/colmajor.v
  • blas/oblas_d_vsl_blas_cblas.v
  • blas/oblas_notd_vsl_blas_cblas.v
  • lapack/cflags_d_vsl_lapack_lapacke.v
  • lapack/lapack64/cflags_d_vsl_lapack_lapacke.v
  • lapack/lapack64/dgebal.v
  • lapack/lapack64/dgeev.v
  • lapack/lapack64/dgeqr2.v
  • lapack/lapack64/dgeqrf.v
  • lapack/lapack64/dgesv.v
  • lapack/lapack64/dgetf2.v
  • lapack/lapack64/dgetrf.v
  • lapack/lapack64/dgetrf_test.v
  • lapack/lapack64/dgetri.v
  • lapack/lapack64/dgetri_test.v
  • lapack/lapack64/dgetrs.v
  • lapack/lapack64/dlacpy.v
  • lapack/lapack64/dlange.v
  • lapack/lapack64/dlaswp.v
  • lapack/lapack64/dorgqr.v
  • lapack/lapack64/dpotf2.v
  • lapack/lapack64/dpotrf.v
  • lapack/lapack64/dpotrf_test.v
  • lapack/lapack64/dtrti2.v
  • lapack/lapack64/dtrtri.v
  • lapack/lapack_notd_vsl_lapack_lapacke.v
  • lapack/lapack_test.v
  • lapack/lapack_wrappers.v

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 57dc598 and 6f4fe35.
Files ignored due to filter (2)
  • blas/v.mod
  • lapack/v.mod
Files selected for processing (28)
  • bin/test (1 hunks)
  • blas/README.md (1 hunks)
  • blas/blas64/conversions.v (1 hunks)
  • blas/blas64/dgemm.v (1 hunks)
  • blas/blas64/dgemv.v (1 hunks)
  • blas/blas64/dgemv_test.v (1 hunks)
  • blas/blas64/error.v (1 hunks)
  • blas/blas64/level1f64.v (1 hunks)
  • blas/blas64/level1f64_ddot.v (1 hunks)
  • blas/blas64/level2f64.v (1 hunks)
  • blas/blas64/level3f64.v (1 hunks)
  • blas/blas64/util.v (1 hunks)
  • blas/cflags_d_vsl_blas_cblas.v (2 hunks)
  • blas/conversions.v (1 hunks)
  • blas/oblas_d_vsl_blas_cblas.v (1 hunks)
  • blas/oblas_notd_vsl_blas_cblas.v (1 hunks)
  • la/blas.v (16 hunks)
  • la/densesol.v (2 hunks)
  • la/matrix_ops.v (5 hunks)
  • lapack/README.md (1 hunks)
  • lapack/cflags_d_vsl_lapack_lapacke copy.v (1 hunks)
  • lapack/cflags_notd_vsl_lapack_lapacke.v (1 hunks)
  • lapack/lapack64/dgesv.v (1 hunks)
  • lapack/lapack64/dgetrf.v (1 hunks)
  • lapack/lapack64/errors.v (1 hunks)
  • lapack/lapack_common.v (3 hunks)
  • lapack/lapack_default.c.v (1 hunks)
  • lapack/lapack_macos.c.v (1 hunks)
Files skipped from review due to trivial changes (8)
  • blas/blas64/conversions.v
  • blas/blas64/dgemm.v
  • blas/blas64/dgemv.v
  • blas/blas64/error.v
  • blas/blas64/level1f64.v
  • blas/blas64/level2f64.v
  • blas/blas64/level3f64.v
  • blas/blas64/util.v
Additional comments: 43
lapack/lapack_macos.c.v (1)
  • 1-4: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [1-7]

The module name change and the function implementation look good.

lapack/lapack_default.c.v (2)
  • 1-5: The module name change and the updated import statement are correct.

  • 1-8: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [5-9]

The update to the C.LAPACKE_dlange function signature and the public function dlange wrapper are consistent with the refactoring to use blas64.

lapack/cflags_d_vsl_lapack_lapacke copy.v (1)
  • 1-10: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [1-13]

The module name change, compiler flags, and conditional inclusion of "lapacke.h" for macOS are correct.

la/densesol.v (1)
  • 1-8: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [3-19]

The update to the import statement and the den_solve function to use lapack.dgesv is correct.

blas/cflags_d_vsl_blas_cblas.v (1)
  • 7-15: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [1-11]

The module name change, compiler flags, and conditional inclusion of "cblas.h" for macOS are correct.

blas/blas64/level1f64_ddot.v (1)
  • 1-4: > Note: This review was outside the patches, so it was mapped to the patch with the greatest overlap. Original lines [1-34]

The module name change to "blas64" and the import statement update are correct. The ddot function logic and error handling are appropriate.

lapack/lapack64/dgetrf.v (1)
  • 1-51: The import statements and the dgetrf function logic and error handling are correct.
lapack/lapack64/dgesv.v (1)
  • 1-56: The import statements and the dgesv function logic and error handling are correct.
bin/test (1)
  • 31-31: The flag change from -d vsl_vlas_cblas to -d vsl_blas_cblas is correct and consistent with the module refactoring.
lapack/README.md (1)
  • 1-58: The documentation updates in the README.md file are correct, reflecting the new compilation flag and providing clear installation instructions for dependencies.
blas/README.md (1)
  • 1-66: The documentation updates in the README.md file are correct, reflecting the new compilation flag and providing clear installation instructions for dependencies.
blas/oblas_notd_vsl_blas_cblas.v (1)
  • 1-81: The module name change to "blas" and the updated import statement are correct. The inline functions are appropriate wrappers for the blas64 functions.
blas/blas64/dgemv_test.v (2)
  • 1-1: The module name change to "blas64" is correct.

  • 2-2: The test functions for dgemv are correctly implemented.

la/matrix_ops.v (2)
  • 4-4: The update to the import statement from vsl.vlas to vsl.lapack is correct.

  • 5-5: The updates to the functions matrix_det, matrix_inv_small, matrix_svd, and matrix_inv to use the lapack module are correct.

lapack/lapack_common.v (2)
  • 1-5: The module name change to "lapack" and the updated import statements are correct.

  • 7-23: The updates to the C function declarations to use blas64.MemoryLayout are correct and consistent with the refactoring.

lapack/lapack64/errors.v (1)
  • 1-178: The constants for error messages in lapack/lapack64/errors.v are consistent and clear.
blas/conversions.v (3)
  • 1-7: The module name and import path have been updated correctly from vlas to blas.

  • 9-13: The function signatures have been updated to use the new blas64 types, which is consistent with the module changes.

  • 1-16: > Note: This review was outside the patches, and no patch overlapping with it was found. Original lines [17-178]

The utility functions for matrix and vector operations remain unchanged and are consistent and clear.

la/blas.v (16)
  • 3-3: The import statement has been updated correctly from vsl.vlas to vsl.blas.

  • 50-50: The reference to vlas.ddot has been correctly replaced with blas.ddot.

  • 69-69: The reference to vlas.daxpy has been correctly replaced with blas.daxpy.

  • 139-139: The reference to vlas.dgemv has been correctly replaced with blas.dgemv.

  • 170-170: The reference to vlas.dgemv for the transpose operation has been correctly replaced with blas.dgemv.

  • 202-202: The reference to vlas.dger has been correctly replaced with blas.dger.

  • 223-223: The reference to vlas.dgemv in matrix_vector_mul_add has been correctly replaced with blas.dgemv.

  • 243-243: The reference to vlas.dgemm in matrix_matrix_mul has been correctly replaced with blas.dgemm.

  • 263-263: The reference to vlas.dgemm in matrix_tr_matrix_mul has been correctly replaced with blas.dgemm.

  • 272-272: The reference to vlas.dgemm in matrix_matrix_tr_mul has been correctly replaced with blas.dgemm.

  • 281-281: The reference to vlas.dgemm in matrix_tr_matrix_tr_mul has been correctly replaced with blas.dgemm.

  • 290-290: The reference to vlas.dgemm in matrix_matrix_muladd has been correctly replaced with blas.dgemm.

  • 299-299: The reference to vlas.dgemm in matrix_tr_matrix_muladd has been correctly replaced with blas.dgemm.

  • 308-308: The reference to vlas.dgemm in matrix_matrix_tr_muladd has been correctly replaced with blas.dgemm.

  • 317-317: The reference to vlas.dgemm in matrix_tr_matrix_tr_mul_add has been correctly replaced with blas.dgemm.

  • 328-328: The reference to vlas.daxpy in matrix_add has been correctly replaced with blas.daxpy.

blas/oblas_d_vsl_blas_cblas.v (4)
  • 1-3: The module has been renamed to blas and now imports vsl.blas64.blas64. This change aligns with the PR's objective to refactor the linear algebra module.

  • 5-172: The C function declarations appear to be correctly defined with appropriate parameter types and return types matching the BLAS library's API.

  • 191-448: The V public functions use unsafe to pass array pointers to the C functions. This is necessary for performance reasons but requires careful handling to ensure safety. The functions are marked as inline, which is appropriate for small wrapper functions to avoid function call overhead.

  • 191-448: The use of unsafe is justified in this context as it is required for performance-critical numerical computations where direct memory access is necessary. Ensure that the arrays passed to these functions are always valid and that their lifetimes are managed correctly to prevent undefined behavior.

Comment on lines +191 to +448
// set_num_threads sets the number of threads in OpenBLAS
pub fn set_num_threads(n int) {
C.openblas_set_num_threads(n)
}

@[inline]
pub fn sdsdot(n int, alpha f32, x []f32, incx int, y []f32, incy int) f32 {
return C.cblas_sdsdot(n, alpha, unsafe { &x[0] }, incx, unsafe { &y[0] }, incy)
}

@[inline]
pub fn dsdot(n int, x []f32, incx int, y []f32, incy int) f64 {
return C.cblas_dsdot(n, unsafe { &x[0] }, incx, unsafe { &y[0] }, incy)
}

@[inline]
pub fn sdot(n int, x []f32, incx int, y []f32, incy int) f32 {
return C.cblas_sdot(n, unsafe { &x[0] }, incx, unsafe { &y[0] }, incy)
}

@[inline]
pub fn ddot(n int, x []f64, incx int, y []f64, incy int) f64 {
return C.cblas_ddot(n, unsafe { &x[0] }, incx, unsafe { &y[0] }, incy)
}

@[inline]
pub fn sasum(n int, x []f32, incx int) f32 {
return C.cblas_sasum(n, unsafe { &x[0] }, incx)
}

@[inline]
pub fn dasum(n int, x []f64, incx int) f64 {
return C.cblas_dasum(n, unsafe { &x[0] }, incx)
}

@[inline]
pub fn ssum(n int, x []f32, incx int) f32 {
return C.cblas_ssum(n, unsafe { &x[0] }, incx)
}

@[inline]
pub fn dsum(n int, x []f64, incx int) f64 {
return C.cblas_dsum(n, unsafe { &x[0] }, incx)
}

@[inline]
pub fn snrm2(n int, x []f32, incx int) f32 {
return C.cblas_snrm2(n, unsafe { &x[0] }, incx)
}

@[inline]
pub fn dnrm2(n int, x []f64, incx int) f64 {
return C.cblas_dnrm2(n, unsafe { &x[0] }, incx)
}

@[inline]
pub fn isamax(n int, x []f32, incx int) int {
return C.cblas_isamax(n, unsafe { &x[0] }, incx)
}

@[inline]
pub fn idamax(n int, x []f64, incx int) int {
return C.cblas_idamax(n, unsafe { &x[0] }, incx)
}

@[inline]
pub fn isamin(n int, x []f32, incx int) int {
return C.cblas_isamin(n, unsafe { &x[0] }, incx)
}

@[inline]
pub fn idamin(n int, x &f64, incx int) int {
return C.cblas_idamin(n, unsafe { &x[0] }, incx)
}

@[inline]
pub fn ismax(n int, x []f32, incx int) int {
return C.cblas_ismax(n, unsafe { &x[0] }, incx)
}

@[inline]
pub fn idmax(n int, x []f64, incx int) int {
return C.cblas_idmax(n, unsafe { &x[0] }, incx)
}

@[inline]
pub fn ismin(n int, x []f32, incx int) int {
return C.cblas_ismin(n, unsafe { &x[0] }, incx)
}

@[inline]
pub fn idmin(n int, x []f64, incx int) int {
return C.cblas_idmin(n, unsafe { &x[0] }, incx)
}

@[inline]
pub fn saxpy(n int, alpha f32, x []f32, incx int, mut y []f32, incy int) {
C.cblas_saxpy(n, alpha, unsafe { &x[0] }, incx, unsafe { &y[0] }, incy)
}

@[inline]
pub fn daxpy(n int, alpha f64, x []f64, incx int, mut y []f64, incy int) {
C.cblas_daxpy(n, alpha, unsafe { &x[0] }, incx, unsafe { &y[0] }, incy)
}

@[inline]
pub fn scopy(n int, mut x []f32, incx int, mut y []f32, incy int) {
C.cblas_scopy(n, unsafe { &x[0] }, incx, unsafe { &y[0] }, incy)
}

@[inline]
pub fn dcopy(n int, mut x []f64, incx int, mut y []f64, incy int) {
C.cblas_dcopy(n, unsafe { &x[0] }, incx, unsafe { &y[0] }, incy)
}

@[inline]
pub fn sswap(n int, mut x []f32, incx int, mut y []f32, incy int) {
C.cblas_sswap(n, unsafe { &x[0] }, incx, unsafe { &y[0] }, incy)
}

@[inline]
pub fn dswap(n int, mut x []f64, incx int, mut y []f64, incy int) {
C.cblas_dswap(n, unsafe { &x[0] }, incx, unsafe { &y[0] }, incy)
}

@[inline]
pub fn srot(n int, mut x []f32, incx int, mut y []f32, incy int, c f32, s f32) {
C.cblas_srot(n, unsafe { &x[0] }, incx, unsafe { &y[0] }, incy, c, s)
}

@[inline]
pub fn drot(n int, mut x []f64, incx int, mut y []f64, incy int, c f64, s f64) {
C.cblas_drot(n, unsafe { &x[0] }, incx, unsafe { &y[0] }, incy, c, s)
}

@[inline]
pub fn srotg(a f32, b f32, c f32, s f32) {
C.cblas_srotg(&a, &b, &c, &s)
}

@[inline]
pub fn drotg(a f64, b f64, c f64, s f64) {
C.cblas_drotg(&a, &b, &c, &s)
}

@[inline]
pub fn srotm(n int, x []f32, incx int, y []f32, incy int, p []f32) {
C.cblas_srotm(n, unsafe { &x[0] }, incx, unsafe { &y[0] }, incy, unsafe { &p[0] })
}

@[inline]
pub fn drotm(n int, x []f64, incx int, y []f64, incy int, p []f64) {
C.cblas_drotm(n, unsafe { &x[0] }, incx, unsafe { &y[0] }, incy, unsafe { &p[0] })
}

@[inline]
pub fn srotmg(d1 f32, d2 f32, b1 f32, b2 f32, p []f32) {
C.cblas_srotmg(&d1, &d2, &b1, b2, unsafe { &p[0] })
}

@[inline]
pub fn drotmg(d1 f64, d2 f64, b1 f64, b2 f32, p []f64) {
C.cblas_drotmg(&d1, &d2, &b1, b2, unsafe { &p[0] })
}

@[inline]
pub fn sscal(n int, alpha f32, mut x []f32, incx int) {
C.cblas_sscal(n, alpha, unsafe { &x[0] }, incx)
}

@[inline]
pub fn dscal(n int, alpha f64, mut x []f64, incx int) {
C.cblas_dscal(n, alpha, unsafe { &x[0] }, incx)
}

@[inline]
pub fn sgemv(trans bool, m int, n int, alpha f32, a []f32, lda int, x []f32, incx int, beta f32, mut y []f32, incy int) {
C.cblas_sgemv(.row_major, c_trans(trans), m, n, alpha, unsafe { &a[0] }, lda, unsafe { &x[0] },
incx, beta, unsafe { &y[0] }, incy)
}

@[inline]
pub fn dgemv(trans bool, m int, n int, alpha f64, a []f64, lda int, x []f64, incx int, beta f64, mut y []f64, incy int) {
C.cblas_dgemv(.row_major, c_trans(trans), m, n, alpha, unsafe { &a[0] }, lda, unsafe { &x[0] },
incx, beta, unsafe { &y[0] }, incy)
}

@[inline]
pub fn sger(m int, n int, alpha f32, x []f32, incx int, y []f32, incy int, mut a []f32, lda int) {
C.cblas_sger(.row_major, m, n, alpha, unsafe { &x[0] }, incx, unsafe { &y[0] }, incy,
unsafe { &a[0] }, lda)
}

@[inline]
pub fn dger(m int, n int, alpha f64, x []f64, incx int, y []f64, incy int, mut a []f64, lda int) {
C.cblas_dger(.row_major, m, n, alpha, unsafe { &x[0] }, incx, unsafe { &y[0] }, incy,
unsafe { &a[0] }, lda)
}

@[inline]
pub fn strsv(uplo bool, trans_a bool, diag blas64.Diagonal, n int, a []f32, lda int, mut x []f32, incx int) {
C.cblas_strsv(.row_major, c_uplo(uplo), c_trans(trans_a), diag, n, unsafe { &a[0] },
lda, unsafe { &x[0] }, incx)
}

@[inline]
pub fn dtrsv(uplo bool, trans_a bool, diag blas64.Diagonal, n int, a []f64, lda int, mut x []f64, incx int) {
C.cblas_dtrsv(.row_major, c_uplo(uplo), c_trans(trans_a), diag, n, unsafe { &a[0] },
lda, unsafe { &x[0] }, incx)
}

@[inline]
pub fn strmv(uplo bool, trans_a bool, diag blas64.Diagonal, n int, a []f32, lda int, mut x []f32, incx int) {
C.cblas_strmv(.row_major, c_uplo(uplo), c_trans(trans_a), diag, n, unsafe { &a[0] },
lda, unsafe { &x[0] }, incx)
}

@[inline]
pub fn dtrmv(uplo bool, trans_a bool, diag blas64.Diagonal, n int, a []f64, lda int, mut x []f64, incx int) {
C.cblas_dtrmv(.row_major, c_uplo(uplo), c_trans(trans_a), diag, n, unsafe { &a[0] },
lda, unsafe { &x[0] }, incx)
}

@[inline]
pub fn ssyr(uplo bool, n int, alpha f32, x []f32, incx int, mut a []f32, lda int) {
C.cblas_ssyr(.row_major, c_uplo(uplo), n, alpha, unsafe { &x[0] }, incx, unsafe { &a[0] },
lda)
}

@[inline]
pub fn dsyr(uplo bool, n int, alpha f64, x []f64, incx int, mut a []f64, lda int) {
C.cblas_dsyr(.row_major, c_uplo(uplo), n, alpha, unsafe { &x[0] }, incx, unsafe { &a[0] },
lda)
}

@[inline]
pub fn ssyr2(uplo bool, n int, alpha f32, x []f32, incx int, y []f32, incy int, mut a []f32, lda int) {
C.cblas_ssyr2(.row_major, c_uplo(uplo), n, alpha, unsafe { &x[0] }, incx, unsafe { &y[0] },
incy, unsafe { &a[0] }, lda)
}

@[inline]
pub fn dsyr2(uplo bool, n int, alpha f64, x []f64, incx int, y []f64, incy int, mut a []f64, lda int) {
C.cblas_dsyr2(.row_major, c_uplo(uplo), n, alpha, unsafe { &x[0] }, incx, unsafe { &y[0] },
incy, unsafe { &a[0] }, lda)
}

@[inline]
pub fn sgemm(trans_a bool, trans_b bool, m int, n int, k int, alpha f32, a []f32, lda int, b []f32, ldb int, beta f32, mut cc []f32, ldc int) {
C.cblas_sgemm(.row_major, c_trans(trans_a), c_trans(trans_b), m, n, k, alpha, unsafe { &a[0] },
lda, unsafe { &b[0] }, ldb, beta, unsafe { &cc[0] }, ldc)
}

@[inline]
pub fn dgemm(trans_a bool, trans_b bool, m int, n int, k int, alpha f64, a []f64, lda int, b []f64, ldb int, beta f64, mut cc []f64, ldc int) {
C.cblas_dgemm(.row_major, c_trans(trans_a), c_trans(trans_b), m, n, k, alpha, unsafe { &a[0] },
lda, unsafe { &b[0] }, ldb, beta, unsafe { &cc[0] }, ldc)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding tests for the new wrapper functions to ensure they correctly interface with the C BLAS library and handle edge cases appropriately.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 6f4fe35 and d667c95.
Files selected for processing (1)
  • blas/README.md (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • blas/README.md

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between d667c95 and 10eea19.
Files selected for processing (6)
  • blas/blas64/conversions.v (1 hunks)
  • blas/conversions.v (1 hunks)
  • blas/oblas_d_vsl_blas_cblas.v (1 hunks)
  • blas/oblas_notd_vsl_blas_cblas.v (1 hunks)
  • lapack/lapack_common.v (3 hunks)
  • lapack/lapack_default.c.v (1 hunks)
Files skipped from review as they are similar to previous changes (5)
  • blas/conversions.v
  • blas/oblas_d_vsl_blas_cblas.v
  • blas/oblas_notd_vsl_blas_cblas.v
  • lapack/lapack_common.v
  • lapack/lapack_default.c.v
Additional comments: 1
blas/blas64/conversions.v (1)
  • 1-33: The enums MemoryLayout, Transpose, Uplo, Diagonal, and Side are well-defined and appropriately documented. The naming convention is consistent, and the values seem to be aligned with the typical BLAS library constants. This should make the usage of the enums intuitive for those familiar with BLAS.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 10eea19 and 5bd805c.
Files selected for processing (3)
  • lapack/lapack64/dgesv.v (1 hunks)
  • lapack/lapack64/dgetrf.v (1 hunks)
  • lapack/lapack64/dgetrs.v (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • lapack/lapack64/dgesv.v
  • lapack/lapack64/dgetrf.v
Additional comments: 8
lapack/lapack64/dgetrs.v (8)
  • 19-19: The function signature for dgetrs is clear and matches the documentation provided. It accepts parameters for the transpose type, matrix dimensions, matrix data, leading dimensions, pivot indices, and right-hand side matrix.

  • 20-34: The input validation checks for trans, n, nrhs, lda, and ldb are thorough and follow good practices by checking for invalid values and throwing appropriate panic messages.

  • 37-38: The quick return check for n == 0 || nrhs == 0 is a good performance optimization to avoid unnecessary computation when there are no equations to solve or no right-hand sides.

  • 41-49: The length checks for the arrays a, b, and ipiv are correct and ensure that the arrays are of sufficient size to hold the necessary data for the matrix operations.

  • 51-58: The logic for solving the system of equations when trans != .no_trans is correct. It uses the LAPACK utility dlaswp and BLAS functions dtrsm to perform the necessary matrix operations.

  • 61-66: The logic for solving the transposed system of equations is correct. It uses the BLAS function dtrsm for both the upper and lower triangular matrix solutions and applies the LAPACK utility dlaswp to adjust the right-hand side matrix b.

  • 19-66: Ensure that the constants used for transpose types and matrix sides (e.g., .no_trans, .trans, .conj_trans, .left, .upper, .lower, .unit, .non_unit) are consistent with the blas module's definitions and that they are correctly implemented in the blas module.

  • 20-34: Verify that the panic messages (e.g., bad_trans, n_lt0, nrhs_lt0, bad_ld_a, bad_ld_b, short_ab, short_b, bad_len_ipiv) are defined elsewhere in the codebase and provide meaningful error messages to the user.

Verification successful

The panic messages such as bad_trans, n_lt0, nrhs_lt0, bad_ld_a, bad_ld_b, short_ab, short_b, and bad_len_ipiv are defined in the lapack/lapack64/errors.v file and are used throughout the lapack64 and blas64 modules to provide meaningful error messages.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify the panic messages in the codebase.
rg --type v 'bad_trans|n_lt0|nrhs_lt0|bad_ld_a|bad_ld_b|short_ab|short_b|bad_len_ipiv'

Length of output: 114



Script:

#!/bin/bash
# Search for the panic message definitions without specifying the file type.
rg 'bad_trans|n_lt0|nrhs_lt0|bad_ld_a|bad_ld_b|short_ab|short_b|bad_len_ipiv'

Length of output: 2432

* 'main' of github.com:vlang/vsl:
  Finished #197
  update include and lib paths for openmpi on FreeBSD (#196)
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 5bd805c and ea376ac.
Files selected for processing (4)
  • blas/README.md (1 hunks)
  • blas/conversions.v (1 hunks)
  • la/blas.v (16 hunks)
  • lapack/README.md (1 hunks)
Additional comments: 28
blas/README.md (4)
  • 1-3: The introduction clearly states the purpose of the package. Ensure the implementation details mentioned align with the actual code changes.
  • 5-8: The table provides a clear overview of the backends available. Verify that the compilation flags and status descriptions are up-to-date with the latest codebase changes.
Verification successful

The grep results confirm the documentation accuracy for the OpenBLAS backend's compilation flag -d vsl_blas_cblas as mentioned in the blas/README.md and its usage within the repository, specifically in a bin/test script. This suggests that the documentation for the OpenBLAS backend is up-to-date regarding the compilation flag.

However, the review comment's request to verify the compilation flags and status descriptions for all backends, including the "Pure V implementation," was only partially addressed. The verification focused on the OpenBLAS backend, and there was no specific flag to verify for the "Pure V implementation" backend based on the provided context. Therefore, while the OpenBLAS backend documentation is verified to be accurate, the review did not fully cover the "Pure V implementation" backend's status or compilation flags.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify the compilation flags for BLAS backends are correctly documented.
grep -r "vsl_blas_cblas" .

Length of output: 432

* 12-20: The OpenBLAS backend section is informative. Confirm that the installation instructions for OpenBLAS are still valid and that the compilation flag `-d vsl_blas_cblas` is correctly implemented in the build process. * 27-59: Installation instructions for macOS, Debian/Ubuntu, and Arch Linux/Manjaro are provided. Ensure these instructions are current and correct for installing OpenBLAS on these platforms.
lapack/README.md (4)
  • 1-3: The introduction succinctly explains the purpose of the LAPACK package. Confirm that the implementation details are consistent with the code changes.
  • 5-9: The backend table lists BLAS and LAPACKE with their statuses and compilation flags. Verify that these details accurately reflect the current state of the codebase and documentation.
  • 13-21: The LAPACKE backend section provides useful information. Ensure the installation instructions for LAPACKE are accurate and that the compilation flag -d vsl_lapack_lapacke is correctly implemented.
  • 28-58: Installation instructions for macOS, Debian/Ubuntu, and Arch Linux/Manjaro are detailed. Confirm these instructions are up-to-date for installing LAPACKE on these platforms.
la/blas.v (16)
  • 3-3: The import statement correctly references the updated blas module. Confirm that all necessary functions and types from blas are available and used correctly throughout the file.
  • 41-41: The use of blas.ddot for the dot product operation is appropriate. Ensure that the parameters passed match the expected signature of ddot in the blas module.
  • 60-60: The call to blas.daxpy for vector addition is correctly implemented. Verify that the performance implications of using daxpy over manual looping for smaller vectors are considered.
  • 130-130: The use of blas.dgemv for matrix-vector multiplication is correct. Check that the parameters and the decision to use dgemv based on matrix dimensions are optimal.
  • 160-160: The implementation of blas.dgemv for the transpose(matrix)-vector multiplication is appropriate. Confirm that the boolean flag for transposition is correctly passed.
  • 191-191: The call to blas.dger for vector-vector transpose multiplication is correctly used. Ensure that the dimensions and scaling factor are correctly applied.
  • 211-211: The use of blas.dgemv with an addition operation is correctly implemented. Verify that the addition flag (1.0 for beta) is correctly utilized for the operation.
  • 231-231: The call to blas.dgemm for matrix multiplication is correct. Ensure that the parameters, including the no-transpose flags and scaling factors, are accurately passed.
  • 251-251: The implementation of blas.dgemm for transposed matrix multiplication is appropriate. Confirm that the transposition flag for matrix a is correctly set.
  • 260-260: The use of blas.dgemm for matrix multiplication with transposed b is correctly implemented. Verify that the transposition flag for matrix b is accurately set.
  • 269-269: The call to blas.dgemm for multiplication with both matrices transposed is correct. Ensure that both transposition flags are accurately set.
  • 278-278: The implementation of blas.dgemm for matrix multiplication with addition is correctly used. Confirm that the addition flag (1.0 for beta) is correctly utilized.
  • 287-287: The use of blas.dgemm for transposed matrix multiplication with addition is appropriate. Verify that the transposition flag for matrix a and the addition flag are correctly set.
  • 296-296: The call to blas.dgemm for matrix multiplication with transposed b and addition is correctly implemented. Ensure that the transposition flag for matrix b and the addition flag are accurately set.
  • 305-305: The implementation of blas.dgemm for multiplication with both matrices transposed and addition is correct. Confirm that both transposition flags and the addition flag are accurately set.
  • 316-316: The use of blas.daxpy for matrix addition is correctly implemented. Verify that the performance implications of using daxpy over manual looping for smaller matrices are considered.
blas/conversions.v (4)
  • 1-1: The module declaration correctly reflects the updated module name. Confirm that this change is consistent throughout the entire codebase.
  • 7-7: The import statement correctly references the updated blas64 module. Ensure that all necessary functions and types from blas64 are available and used correctly throughout the file.
  • 9-22: The addition of new types (MemoryLayout, Transpose, Uplo, Diagonal, Side) is appropriate. Confirm that these types are correctly used in the context of the BLAS operations.
  • 24-40: The refactoring of helper functions (c_trans, c_uplo, l_uplo, job_vlr) to work with the new types is correctly implemented. Verify that these functions are used appropriately wherever necessary.

* 'main' of github.com:vlang/vsl:
  fix kmeans.v (#199)
  Update maximum dimension checks in HDF5 file functions
* 'main' of github.com:vlang/vsl:
  Refactor print statement to display vector data
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between ea376ac and ae0628b.
Files selected for processing (2)
  • lapack/lapack64/dgetrf.v (1 hunks)
  • lapack/lapack64/ilaenv.v (1 hunks)
Additional comments: 9
lapack/lapack64/dgetrf.v (6)
  • 27-27: The function signature for dgetrf is clear and well-documented, indicating good maintainability and readability.
  • 30-38: Ensure that the error messages for panic are descriptive enough to help users understand the cause of the error. It's recommended to include more context in the error messages.
  • 52-52: The use of ilaenv to determine the block size (nb) is a good practice as it allows for algorithm tuning based on the specific characteristics of the computation.
  • 54-57: The conditional logic to choose between the blocked and unblocked algorithm based on nb is clear and follows best practices for performance optimization.
  • 59-78: The loop to process matrix blocks is logically sound. However, consider adding comments within the loop to explain the purpose of each major step for better readability and maintainability.
  • 74-75: Using unsafe to create a slice may lead to potential issues if not handled carefully. Ensure that the bounds are correctly calculated to prevent out-of-bounds access.
lapack/lapack64/ilaenv.v (3)
  • 22-22: The function signature for ilaenv is clear and well-documented, indicating good maintainability and readability.
  • 24-28: The initial checks for sname and cname based on the first character of name are a good practice for early validation of input parameters.
  • 245-245: Ensure that the min function is defined and correctly calculates the minimum of n1 and n2. This line assumes the existence of such a function, which is crucial for the correct operation of ilaenv.

Comment on lines +34 to +271
match ispec {
1 {
match c2 {
'GE' {
match c3 {
'TRF', 'TRI' {
return 64
}
'QRF', 'RQF', 'LQF', 'QLF', 'HRD', 'BRD' {
return 32
}
else {
panic(bad_name)
}
}
}
'PO' {
match c3 {
'TRF' {
return 64
}
else {
panic(bad_name)
}
}
}
'SY', 'HE' {
match c3 {
'TRF' {
return 64
}
'TRD', 'GST' {
return 32
}
else {
panic(bad_name)
}
}
}
'OR', 'UN' {
match c3[0] {
'G', 'M' {
match c3[1..] {
'QR', 'RQ', 'LQ', 'QL', 'HR', 'TR', 'BR' {
return 32
}
else {
panic(bad_name)
}
}
}
else {
panic(bad_name)
}
}
}
'GB', 'PB' {
// Assuming n4 and n2 are defined elsewhere in your code
match c3 {
'TRF' {
// Replace `n4` and `n2` with actual variables
if sname {
// if n4 <= 64 {
// return 1
// }
return 32
}
// if n4 <= 64 {
// return 1
// }
return 32
}
else {
panic(bad_name)
}
}
}
'PT', 'TR', 'LA' {
// Additional cases as per your original logic
}
'ST' {
if sname && c3 == 'EBZ' {
return 1
}
panic(bad_name)
}
else {
panic(bad_name)
}
}
}
2 {
match c2 {
'GE' {
match c3 {
'QRF', 'RQF', 'LQF', 'QLF', 'HRD', 'BRD', 'TRI' {
if sname {
return 2
}
return 2
}
else {
panic(bad_name)
}
}
}
'SY' {
match c3 {
'TRF' {
if sname {
return 8
}
return 8
}
'TRD' {
if sname {
return 2
}
panic(bad_name)
}
else {
panic(bad_name)
}
}
}
'HE' {
if c3 == 'TRD' {
return 2
}
panic(bad_name)
}
'OR', 'UN' {
if !sname {
panic(bad_name)
}
match c3[0] {
'G', 'M' {
match c4 {
'QR', 'RQ', 'LQ', 'QL', 'HR', 'TR', 'BR' {
return 2
}
else {
panic(bad_name)
}
}
}
else {
panic(bad_name)
}
}
}
else {
panic(bad_name)
}
}
}
3 {
match c2 {
'GE' {
match c3 {
'QRF', 'RQF', 'LQF', 'QLF', 'HRD', 'BRD' {
if sname {
return 128
}
return 128
}
else {
panic(bad_name)
}
}
}
'SY', 'HE' {
if c3 == 'TRD' {
return 32
}
panic(bad_name)
}
'OR', 'UN' {
match c3[0] {
'G' {
match c4 {
'QR', 'RQ', 'LQ', 'QL', 'HR', 'TR', 'BR' {
return 128
}
else {
panic(bad_name)
}
}
}
else {
panic(bad_name)
}
}
}
else {
panic(bad_name)
}
}
}
4 {
// Used by xHSEQR
return 6
}
5 {
// Not used
return 2
}
6 {
// Used by xGELSS and xGESVD
// Assuming n1 and n2 are defined elsewhere in your code
// Replace `min(n1, n2)` with actual min calculation or function
return int(f64(min(n1, n2)) * 1.6)
}
7 {
// Not used
return 1
}
8 {
// Used by xHSEQR
return 50
}
9 {
// Used by xGELSD and xGESDD
return 25
}
10, 11 {
// Go guarantees ieee
return 1
}
12, 13, 14, 15, 16 {
// dhseqr and related functions for eigenvalue problems.
return iparmq(ispec, name, opts, n1, n2, n3, n4)
}
else {
panic(bad_ispec)
}
}
return 0
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The extensive use of match statements for algorithm tuning parameter selection is logically sound. However, consider refactoring to reduce the complexity and improve maintainability. Extracting repeated logic into separate functions or using a data-driven approach could be beneficial.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Comment on lines +69 to +73
info := C.LAPACKE_dgesvd(.row_major, jobu, jobvt, m, n, &a[0], lda, &s[0], &u[0],
ldu, &vt[0], ldvt, &superb[0])
if info != 0 {
errors.vsl_panic('lapack failed', .efailed)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider improving error handling in dgesvd. Instead of panicking, it might be better to return an error to the caller, allowing them to decide how to handle it.

Comment on lines +93 to +94
lapack64.dgetrf(m, n, mut a, lda, ipiv)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider improving error handling in dgetrf to return errors instead of panicking, providing more flexibility to the caller.

Comment on lines +131 to +135
unsafe {
info := C.LAPACKE_dpotrf(.row_major, blas.l_uplo(up), n, &a[0], lda)
if info != 0 {
errors.vsl_panic('lapack failed', .efailed)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider improving error handling in dpotrf to return errors instead of panicking, providing more flexibility to the caller.

Comment on lines +178 to +182
info := C.LAPACKE_dgeev(.row_major, &char(blas.job_vlr(calc_vl).str().str), &char(blas.job_vlr(calc_vr).str().str),
n, &a[0], lda, &wr[0], &wi[0], &vvl, ldvl, &vvr, ldvr)
if info != 0 {
errors.vsl_panic('lapack failed', .efailed)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider improving error handling in dgeev to return errors instead of panicking, providing more flexibility to the caller.

* 'main' of github.com:vlang/vsl:
  refactor: Update create_image_2d function to use local variable for format
  Update lint.yml
  Update lint.yml
  refactor: update README.md to include link to examples folder
  refactor: update README.md to include link to examples folder
  fix error in examples/vcl_opencl_fractals_one_argument/main.v (fix main V CI)
  refactor: Update image creation functions to use generic 'image' instead of 'image_2d'
  refactor: Update image creation functions to use generic 'image' instead of 'image_2d'
  refactor: Update create_image_2d function to use local variable for format
  chore: Add output image to README
  chore: Remove unused plot examples using script mode
  refactor: Update AC signal calculation to include amplitude parameter
  chore: Update plot examples with axis titles and script mode
  1 basic plotting example with axis titles and 3 more ones using script mode (#205)
  remove unused `math` import, run `v fmt -w .`
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between ab34e62 and b2f481c.

Files selected for processing (5)
  • lapack/lapack64/dgesv.v (1 hunks)
  • lapack/lapack64/dgetrf.v (1 hunks)
  • lapack/lapack64/dgetrs.v (1 hunks)
  • lapack/lapack64/errors.v (1 hunks)
  • lapack/lapack64/ilaenv.v (1 hunks)
Files skipped from review due to trivial changes (1)
  • lapack/lapack64/errors.v
Additional comments not posted (3)
lapack/lapack64/dgesv.v (1)

1-56: The implementation of dgesv function is robust and well-documented, providing clear error handling and utilizing efficient linear algebra routines.

lapack/lapack64/dgetrs.v (1)

1-67: The dgetrs function is correctly implemented with comprehensive error handling and efficient use of BLAS routines for solving linear equations.

lapack/lapack64/dgetrf.v (1)

1-88: The dgetrf function is well-implemented with robust error handling and efficient use of blocked and unblocked algorithms for LU decomposition.

Comment on lines +1 to +272
module lapack64

// ilaenv returns algorithm tuning parameters for the algorithm given by the
// input string. ispec specifies the parameter to return:
//
// 1: The optimal block size for a blocked algorithm.
// 2: The minimum block size for a blocked algorithm.
// 3: The block size of unprocessed data at which a blocked algorithm should
// crossover to an unblocked version.
// 4: The number of shifts.
// 5: The minimum column dimension for blocking to be used.
// 6: The crossover point for SVD (to use QR factorization or not).
// 7: The number of processors.
// 8: The crossover point for multi-shift in QR and QZ methods for non-symmetric eigenvalue problems.
// 9: Maximum size of the subproblems in divide-and-conquer algorithms.
// 10: ieee infinity and NaN arithmetic can be trusted not to trap.
// 11: ieee infinity arithmetic can be trusted not to trap.
// 12...16: parameters for Dhseqr and related functions. See Iparmq for more
// information.
//
// ilaenv is an internal routine. It is exported for testing purposes.
fn ilaenv(ispec int, name string, opts string, n1 int, n2 int, n3 int, n4 int) int {
// TODO(btracey): Replace this with a constant lookup? A list of constants?
sname := name[0] == `S` || name[0] == `D`
cname := name[0] == `C` || name[0] == `Z`
if !sname && !cname {
panic(bad_name)
}

c2 := name[1..3]
c3 := name[3..6]
c4 := c3[1..3]

match ispec {
1 {
match c2 {
'GE' {
match c3 {
'TRF', 'TRI' {
return 64
}
'QRF', 'RQF', 'LQF', 'QLF', 'HRD', 'BRD' {
return 32
}
else {
panic(bad_name)
}
}
}
'PO' {
match c3 {
'TRF' {
return 64
}
else {
panic(bad_name)
}
}
}
'SY', 'HE' {
match c3 {
'TRF' {
return 64
}
'TRD', 'GST' {
return 32
}
else {
panic(bad_name)
}
}
}
'OR', 'UN' {
match c3[0] {
`G`, `M` {
match c3[1..] {
'QR', 'RQ', 'LQ', 'QL', 'HR', 'TR', 'BR' {
return 32
}
else {
panic(bad_name)
}
}
}
else {
panic(bad_name)
}
}
}
'GB', 'PB' {
// Assuming n4 and n2 are defined elsewhere in your code
match c3 {
'TRF' {
// Replace `n4` and `n2` with actual variables
if sname {
// if n4 <= 64 {
// return 1
// }
return 32
}
// if n4 <= 64 {
// return 1
// }
return 32
}
else {
panic(bad_name)
}
}
}
'PT', 'TR', 'LA' {
// Additional cases as per your original logic
}
'ST' {
if sname && c3 == 'EBZ' {
return 1
}
panic(bad_name)
}
else {
panic(bad_name)
}
}
}
2 {
match c2 {
'GE' {
match c3 {
'QRF', 'RQF', 'LQF', 'QLF', 'HRD', 'BRD', 'TRI' {
if sname {
return 2
}
return 2
}
else {
panic(bad_name)
}
}
}
'SY' {
match c3 {
'TRF' {
if sname {
return 8
}
return 8
}
'TRD' {
if sname {
return 2
}
panic(bad_name)
}
else {
panic(bad_name)
}
}
}
'HE' {
if c3 == 'TRD' {
return 2
}
panic(bad_name)
}
'OR', 'UN' {
if !sname {
panic(bad_name)
}
match c3[0] {
`G`, `M` {
match c4 {
'QR', 'RQ', 'LQ', 'QL', 'HR', 'TR', 'BR' {
return 2
}
else {
panic(bad_name)
}
}
}
else {
panic(bad_name)
}
}
}
else {
panic(bad_name)
}
}
}
3 {
match c2 {
'GE' {
match c3 {
'QRF', 'RQF', 'LQF', 'QLF', 'HRD', 'BRD' {
if sname {
return 128
}
return 128
}
else {
panic(bad_name)
}
}
}
'SY', 'HE' {
if c3 == 'TRD' {
return 32
}
panic(bad_name)
}
'OR', 'UN' {
match c3[0] {
`G` {
match c4 {
'QR', 'RQ', 'LQ', 'QL', 'HR', 'TR', 'BR' {
return 128
}
else {
panic(bad_name)
}
}
}
else {
panic(bad_name)
}
}
}
else {
panic(bad_name)
}
}
}
4 {
// Used by xHSEQR
return 6
}
5 {
// Not used
return 2
}
6 {
// Used by xGELSS and xGESVD
// Assuming n1 and n2 are defined elsewhere in your code
// Replace `min(n1, n2)` with actual min calculation or function
return int(f64(min(n1, n2)) * 1.6)
}
7 {
// Not used
return 1
}
8 {
// Used by xHSEQR
return 50
}
9 {
// Used by xGELSD and xGESDD
return 25
}
10, 11 {
// Go guarantees ieee
return 1
}
12, 13, 14, 15, 16 {
// dhseqr and related functions for eigenvalue problems.
return iparmq(ispec, name, opts, n1, n2, n3, n4)
}
else {
panic(bad_ispec)
}
}
return 0
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider refactoring the ilaenv function to reduce complexity and improve maintainability. Extracting repeated logic into separate functions or using a data-driven approach could be beneficial.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
IMPLEMENTATION_PLAN.md (2)

25-26: Use the official “macOS” spelling for the platform name

Tiny style fix to keep documentation professional and consistent.

-  - Platform-specific: `lapack_macos.c.v`, `lapack_default.c.v`
+  - Platform-specific: `lapack_macos.c.v`, `lapack_default.c.v`  <!-- macOS is the official branding -->

572-580: Clarify doc-string guideline reference

Mentioning “Docstrings for all public functions” is great; add a link to the project’s CONTRIBUTING or V style guide so new contributors know the exact expectations.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 943aa1d and df84062.

📒 Files selected for processing (2)
  • .gitignore (1 hunks)
  • IMPLEMENTATION_PLAN.md (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .gitignore
🧰 Additional context used
🪛 LanguageTool
IMPLEMENTATION_PLAN.md

[style] ~3-~3: Some style guides suggest that commas should set off the year in a month-day-year date.
Context: ...lementation Plan Date: January 27, 2025 Purpose: Comprehensive plan to im...

(MISSING_COMMA_AFTER_YEAR)


[grammar] ~25-~25: The operating system from Apple is written “macOS”.
Context: ...ackend disabled) - Platform-specific: lapack_macos.c.v, lapack_default.c.v ### Referen...

(MAC_OS)


[style] ~374-~374: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...EMM - [ ] Recursive algorithms: For very large matrices - [ ] **Memory hierarchy aware...

(EN_WEAK_ADJECTIVE)


[grammar] ~506-~506: A determiner may be missing.
Context: ...ance - [ ] Optimization techniques: Getting best performance - [ ] Memory management...

(THE_SUPERLATIVE)


[misspelling] ~561-~561: This word is normally spelled as one.
Context: ...sage - [ ] Good parallel performance on multi-core systems ### Quality Requirements - [ ...

(EN_COMPOUNDS_MULTI_CORE)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: docs
  • GitHub Check: run-tests-on-linux (ubuntu-22.04)
  • GitHub Check: MegaLinter
  • GitHub Check: run-tests-on-linux (ubuntu-22.04, --prod)
  • GitHub Check: run-tests-on-macos (macos-latest, --prod)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04, --prod)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04)
  • GitHub Check: run-tests-on-macos (macos-latest)
  • GitHub Check: MegaLinter

Comment on lines +33 to +35
- **Command**: `cd /home/ulisesjcf/.vmodules && v -d vsl_lapack_lapacke -d vsl_blas_cblas test ./vsl`
- **Current Status**: All 56 tests passing ✅
- **Coverage**: Basic functionality tested, but many functions missing comprehensive tests
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid hard-coded absolute paths that leak developer machines

/home/ulisesjcf/.vmodules is user-specific and will break for every other contributor or CI runner. Switch to a project-relative path or rely on $VPATH / environment variables.

- - **Command**: `cd /home/ulisesjcf/.vmodules && v -d vsl_lapack_lapacke -d vsl_blas_cblas test ./vsl`
+ - **Command**: `v -d vsl_lapack_lapacke -d vsl_blas_cblas test ./vsl`

[security/PII]

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- **Command**: `cd /home/ulisesjcf/.vmodules && v -d vsl_lapack_lapacke -d vsl_blas_cblas test ./vsl`
- **Current Status**: All 56 tests passing ✅
- **Coverage**: Basic functionality tested, but many functions missing comprehensive tests
- **Command**: `v -d vsl_lapack_lapacke -d vsl_blas_cblas test ./vsl`
- **Current Status**: All 56 tests passing ✅
- **Coverage**: Basic functionality tested, but many functions missing comprehensive tests
🤖 Prompt for AI Agents
In IMPLEMENTATION_PLAN.md around lines 33 to 35, the command uses a hard-coded
absolute path '/home/ulisesjcf/.vmodules' which is user-specific and not
portable. Replace this absolute path with a project-relative path or use
environment variables like $VPATH to make the command work across different
developer machines and CI environments without leaking personal information.

- Updated LAPACKE_dsyev function signature to remove unnecessary parameters.
- Added QR, LQ, and LU factorization functions for both single and double precision.
- Introduced wrappers for LAPACK functions to handle flat array interfaces for dgesv, dgesvd, dgetrf, dgetri, geev, syev, geqrf, and orgqr.
- Improved error handling for LAPACK function calls.
- Enhanced matrix operations by adding support for symmetric eigenvalue problems and singular value decomposition.
- Ensured proper memory management and data copying between flat and 2D array representations.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (1)
lapack/lapack_d_vsl_lapack_lapacke.v (1)

240-240: Centralize error handling to improve maintainability.

The error handling pattern is repeated across all wrapper functions. Consider implementing the centralized error handler suggested in the previous review.

Add this helper function at the beginning of the wrapper functions section:

+// handle_lapack_error centralizes LAPACK error handling
+fn handle_lapack_error(info int, operation string) ! {
+    if info != 0 {
+        return errors.error('LAPACK ${operation} failed with info=${info}', .efailed)
+    }
+}

Then update all error handling calls:

-if info != 0 {
-    return errors.error('LAPACK dgesv failed with info=${info}', .efailed)
-}
+handle_lapack_error(info, 'dgesv')!

Also applies to: 285-285, 335-335, 381-381, 414-414, 451-451, 491-491, 528-528, 562-562

🧹 Nitpick comments (1)
lapack/lapack_d_vsl_lapack_lapacke.v (1)

208-250: Consider adding in-place variants for performance-critical applications.

The current wrappers allocate new arrays and perform copying, which could impact performance for large matrices. Consider offering in-place variants that modify the input arrays directly.

For performance-critical applications, consider:

  1. Adding _inplace variants that modify input arrays directly
  2. Documenting the performance characteristics
  3. Providing benchmarks to help users choose between safety and performance

Example for gesv_inplace:

// gesv_inplace - Solves AX=B in-place, modifying both a and b
pub fn gesv_inplace(mut a [][]f64, mut b [][]f64) ! {
    // Validate dimensions...
    // Use existing arrays without allocation
    // Document that a is destroyed and b contains solution
}

Also applies to: 263-305

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between df84062 and 455566c.

📒 Files selected for processing (1)
  • lapack/lapack_d_vsl_lapack_lapacke.v (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: run-tests-on-linux (ubuntu-22.04, --prod)
  • GitHub Check: run-tests-on-macos (macos-latest)
  • GitHub Check: run-tests-on-macos (macos-latest, --prod)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04, --prod)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04)
  • GitHub Check: run-tests-on-linux (ubuntu-22.04)
  • GitHub Check: MegaLinter
  • GitHub Check: docs
  • GitHub Check: MegaLinter
🔇 Additional comments (2)
lapack/lapack_d_vsl_lapack_lapacke.v (2)

8-8: All job type enums are properly defined

We’ve verified that SVDJob, LeftEigenVectorsJob, RightEigenVectorsJob, EigenVectorsJob, and BalanceJob are all declared as type aliases in lapack/conversions.v, pointing to the corresponding lapack64 definitions. No missing enum definitions remain.


126-126: Fix output parameter types in sgebal declaration.

The ilo and ihi parameters are output parameters and should be pointers.

-fn C.LAPACKE_sgebal(matrix_layout blas.MemoryLayout, job BalanceJob, n int, a &f32, lda int, ilo &int, ihi &int, scale &f32) int
+fn C.LAPACKE_sgebal(matrix_layout blas.MemoryLayout, job BalanceJob, n int, a &f32, lda int, ilo &int, ihi &int, scale &f32) int

Likely an incorrect or invalid review comment.


fn C.LAPACKE_dsyev(matrix_layout blas.MemoryLayout, jobz EigenVectorsJob, uplo blas.Uplo, n int, a &f64, lda int, w &f64) int

fn C.LAPACKE_dgebal(matrix_layout blas.MemoryLayout, job BalanceJob, n int, a &f64, lda int, ilo int, ihi int, scale &f64) int
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix output parameter types in dgebal declaration.

The ilo and ihi parameters are output parameters and should be pointers.

-fn C.LAPACKE_dgebal(matrix_layout blas.MemoryLayout, job BalanceJob, n int, a &f64, lda int, ilo int, ihi int, scale &f64) int
+fn C.LAPACKE_dgebal(matrix_layout blas.MemoryLayout, job BalanceJob, n int, a &f64, lda int, ilo &int, ihi &int, scale &f64) int
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fn C.LAPACKE_dgebal(matrix_layout blas.MemoryLayout, job BalanceJob, n int, a &f64, lda int, ilo int, ihi int, scale &f64) int
fn C.LAPACKE_dgebal(matrix_layout blas.MemoryLayout, job BalanceJob, n int, a &f64, lda int, ilo &int, ihi &int, scale &f64) int
🤖 Prompt for AI Agents
In lapack/lapack_d_vsl_lapack_lapacke.v at line 20, the function declaration for
C.LAPACKE_dgebal incorrectly defines the output parameters ilo and ihi as
integers instead of pointers. Change the types of ilo and ihi to pointers to int
to correctly represent them as output parameters.


// geev - Computes eigenvalues and eigenvectors of a general matrix
@[inline]
pub fn geev(a [][]f64, calc_vl LeftEigenVectorsJob, calc_vr LeftEigenVectorsJob) !([]f64, []f64, [][]f64, [][]f64) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix the parameter type for right eigenvectors.

The second parameter should be RightEigenVectorsJob instead of LeftEigenVectorsJob.

-pub fn geev(a [][]f64, calc_vl LeftEigenVectorsJob, calc_vr LeftEigenVectorsJob) !([]f64, []f64, [][]f64, [][]f64) {
+pub fn geev(a [][]f64, calc_vl LeftEigenVectorsJob, calc_vr RightEigenVectorsJob) !([]f64, []f64, [][]f64, [][]f64) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub fn geev(a [][]f64, calc_vl LeftEigenVectorsJob, calc_vr LeftEigenVectorsJob) !([]f64, []f64, [][]f64, [][]f64) {
pub fn geev(a [][]f64, calc_vl LeftEigenVectorsJob, calc_vr RightEigenVectorsJob) !([]f64, []f64, [][]f64, [][]f64) {
🤖 Prompt for AI Agents
In lapack/lapack_d_vsl_lapack_lapacke.v at line 428, the second parameter of the
geev function is incorrectly typed as LeftEigenVectorsJob. Change this
parameter's type to RightEigenVectorsJob to correctly represent the right
eigenvectors job.

fn C.LAPACKE_zheevr(matrix_layout blas.MemoryLayout, jobz EigenVectorsJob, range byte, uplo blas.Uplo, n int, a voidptr, lda int, vl f64, vu f64, il int, iu int, abstol f64, m &int, w &f64, z voidptr, ldz int, isuppz &int) int

// General eigenvalue problems
fn C.LAPACKE_sgeev(matrix_layout blas.MemoryLayout, calc_vl LeftEigenVectorsJob, calc_vr LeftEigenVectorsJob, n int, a &f32, lda int, wr &f32, wi &f32, vl &f32, ldvl int, vr &f32, ldvr int) int
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix the parameter type name for right eigenvectors.

The second parameter type should be RightEigenVectorsJob instead of LeftEigenVectorsJob.

-fn C.LAPACKE_sgeev(matrix_layout blas.MemoryLayout, calc_vl LeftEigenVectorsJob, calc_vr LeftEigenVectorsJob, n int, a &f32, lda int, wr &f32, wi &f32, vl &f32, ldvl int, vr &f32, ldvr int) int
+fn C.LAPACKE_sgeev(matrix_layout blas.MemoryLayout, calc_vl LeftEigenVectorsJob, calc_vr RightEigenVectorsJob, n int, a &f32, lda int, wr &f32, wi &f32, vl &f32, ldvl int, vr &f32, ldvr int) int
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fn C.LAPACKE_sgeev(matrix_layout blas.MemoryLayout, calc_vl LeftEigenVectorsJob, calc_vr LeftEigenVectorsJob, n int, a &f32, lda int, wr &f32, wi &f32, vl &f32, ldvl int, vr &f32, ldvr int) int
fn C.LAPACKE_sgeev(matrix_layout blas.MemoryLayout, calc_vl LeftEigenVectorsJob, calc_vr RightEigenVectorsJob, n int, a &f32, lda int, wr &f32, wi &f32, vl &f32, ldvl int, vr &f32, ldvr int) int
🤖 Prompt for AI Agents
In lapack/lapack_d_vsl_lapack_lapacke.v at line 111, the second parameter type
is incorrectly set as LeftEigenVectorsJob for the right eigenvectors argument.
Change the type of the second parameter from LeftEigenVectorsJob to
RightEigenVectorsJob to correctly represent the right eigenvectors job.


fn C.LAPACKE_dpotrf(matrix_layout blas.MemoryLayout, uplo blas.Uplo, n int, a &f64, lda int) int

fn C.LAPACKE_dgeev(matrix_layout blas.MemoryLayout, calc_vl LeftEigenVectorsJob, calc_vr LeftEigenVectorsJob, n int, a &f64, lda int, wr &f64, wi &f64, vl &f64, ldvl_ int, vr &f64, ldvr_ int) int
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix the parameter type name for right eigenvectors.

The second parameter type should be RightEigenVectorsJob instead of LeftEigenVectorsJob.

-fn C.LAPACKE_dgeev(matrix_layout blas.MemoryLayout, calc_vl LeftEigenVectorsJob, calc_vr LeftEigenVectorsJob, n int, a &f64, lda int, wr &f64, wi &f64, vl &f64, ldvl_ int, vr &f64, ldvr_ int) int
+fn C.LAPACKE_dgeev(matrix_layout blas.MemoryLayout, calc_vl LeftEigenVectorsJob, calc_vr RightEigenVectorsJob, n int, a &f64, lda int, wr &f64, wi &f64, vl &f64, ldvl_ int, vr &f64, ldvr_ int) int
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fn C.LAPACKE_dgeev(matrix_layout blas.MemoryLayout, calc_vl LeftEigenVectorsJob, calc_vr LeftEigenVectorsJob, n int, a &f64, lda int, wr &f64, wi &f64, vl &f64, ldvl_ int, vr &f64, ldvr_ int) int
fn C.LAPACKE_dgeev(matrix_layout blas.MemoryLayout, calc_vl LeftEigenVectorsJob, calc_vr RightEigenVectorsJob, n int, a &f64, lda int, wr &f64, wi &f64, vl &f64, ldvl_ int, vr &f64, ldvr_ int) int
🤖 Prompt for AI Agents
In lapack/lapack_d_vsl_lapack_lapacke.v at line 16, the parameter type for the
second argument is incorrectly set as LeftEigenVectorsJob but it should be
RightEigenVectorsJob. Update the type of the second parameter from
LeftEigenVectorsJob to RightEigenVectorsJob to correctly represent the
calculation of right eigenvectors.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (6)
lapack/lapack_d_vsl_lapack_lapacke.v (6)

16-16: Fix the parameter type for right eigenvectors.

The calc_vr parameter should be RightEigenVectorsJob instead of LeftEigenVectorsJob.


20-20: Fix output parameter types in dgebal declaration.

The ilo and ihi parameters are output parameters and should be pointers.


111-113: Fix parameter types for right eigenvectors in geev function declarations.

The calc_vr parameter should be RightEigenVectorsJob instead of LeftEigenVectorsJob for all three geev function declarations.


428-428: Fix the parameter type for right eigenvectors.

The second parameter should be RightEigenVectorsJob instead of LeftEigenVectorsJob.


240-241: Consider centralizing error handling to reduce code duplication.

The error handling pattern is repeated throughout the module. Consider creating a centralized error handling function.

Also applies to: 285-286, 335-336, 381-382, 414-415, 451-452, 491-492, 528-529, 562-563


125-129: Inconsistent parameter types in gebal function declarations.

The dgebal function at line 20 has ilo and ihi as int parameters, but the other precision variants correctly use &int. This inconsistency should be resolved.

Apply this diff to fix the inconsistency:

-fn C.LAPACKE_dgebal(matrix_layout blas.MemoryLayout, job BalanceJob, n int, a &f64, lda int, ilo int, ihi int, scale &f64) int
+fn C.LAPACKE_dgebal(matrix_layout blas.MemoryLayout, job BalanceJob, n int, a &f64, lda int, ilo &int, ihi &int, scale &f64) int
🧹 Nitpick comments (1)
lapack/lapack_d_vsl_lapack_lapacke.v (1)

208-250: Implement robust input validation and error handling.

The gesv function handles matrix layout conversion and error checking well, but consider adding validation for empty matrices.

Add validation for empty matrices:

 pub fn gesv(mut a [][]f64, mut b [][]f64) ! {
 	m := a.len
+	if m == 0 {
+		return errors.error('Matrix a cannot be empty', .efailed)
+	}
 	n := a[0].len
+	if n == 0 {
+		return errors.error('Matrix a cannot have zero columns', .efailed)
+	}
 	nrhs := b[0].len
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 455566c and 7afdffc.

📒 Files selected for processing (1)
  • lapack/lapack_d_vsl_lapack_lapacke.v (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: run-tests-on-linux (ubuntu-22.04)
  • GitHub Check: run-tests-on-linux (ubuntu-22.04, --prod)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04, --prod)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04)
  • GitHub Check: run-tests-on-macos (macos-latest, --prod)
  • GitHub Check: run-tests-on-macos (macos-latest)
  • GitHub Check: docs
  • GitHub Check: MegaLinter
  • GitHub Check: MegaLinter
🔇 Additional comments (5)
lapack/lapack_d_vsl_lapack_lapacke.v (5)

1-5: Module structure looks good.

The module declaration and imports are properly structured and include the necessary dependencies.


197-203: Direct wrapper function implementation is correct.

The dgesv function properly handles the direct LAPACKE call with appropriate unsafe block usage.


263-305: SVD function implementation is comprehensive.

The gesvd function properly handles the complex SVD operation with appropriate memory management and matrix conversions.


317-347: LU factorization wrapper handles memory correctly.

The getrf function properly manages the conversion between 2D arrays and flat arrays, with appropriate error handling.


509-572: QR factorization functions are well-implemented.

The geqrf and orgqr functions properly handle the QR factorization workflow with appropriate memory management and error handling.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
blas/blas_test.v (2)

565-565: Clarify the reason for reducing vector size.

The comment mentions reducing from 10000 to 1000 to "avoid numerical precision issues" but doesn't explain what specific issues were encountered. Please provide more context.


589-593: Consider verifying more elements or using sampling.

Currently only verifying the first 10 elements out of 1000. Consider either:

  • Verifying all elements (might impact test performance)
  • Using a sampling approach to check elements throughout the array
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7afdffc and b9ed96e.

📒 Files selected for processing (3)
  • blas/blas_test.v (1 hunks)
  • lapack/lapack64/conversions.v (1 hunks)
  • lapack/lapack_d_vsl_lapack_lapacke.v (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • lapack/lapack64/conversions.v
🚧 Files skipped from review as they are similar to previous changes (1)
  • lapack/lapack_d_vsl_lapack_lapacke.v
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04, --prod)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04)
  • GitHub Check: run-tests-on-linux (ubuntu-22.04)
  • GitHub Check: run-tests-on-macos (macos-latest)
  • GitHub Check: run-tests-on-macos (macos-latest, --prod)
  • GitHub Check: run-tests-on-linux (ubuntu-22.04, --prod)
  • GitHub Check: MegaLinter
  • GitHub Check: docs
  • GitHub Check: MegaLinter
🔇 Additional comments (5)
blas/blas_test.v (5)

20-66: Well-implemented floating-point comparison utilities.

The helper functions demonstrate good practices:

  • Proper NaN handling
  • Relative error comparison for large values
  • Correct negative stride handling in strided comparisons

68-317: Comprehensive and well-structured test data.

The test cases provide excellent coverage:

  • Level 1: Various vector operations with different strides and values
  • Level 2: Matrix-vector operations with transpose options
  • Level 3: Matrix-matrix multiplication scenarios including identity matrices

323-433: Thorough Level 1 BLAS test implementations.

Excellent testing practices:

  • Consistent CBLAS availability checks
  • Proper array cloning before mutation operations
  • Comprehensive coverage of all Level 1 operations
  • Clear assertion messages

439-490: Well-implemented Level 2 BLAS tests.

Good implementation details:

  • Correct matrix flattening for BLAS API compatibility
  • Proper handling of transpose operations
  • Clear test structure with expected results

496-539: Correct Level 3 BLAS test implementation.

The matrix-matrix multiplication tests are properly implemented with correct matrix flattening and comprehensive test cases.

Comment on lines +545 to +552
fn test_invalid_inputs() {
// Test that invalid inputs cause panics or proper error handling
x := [1.0, 2.0, 3.0]

// Test zero incx - should cause panic
// Note: We can't easily test panics in V, so we'll skip these for now
// In a real implementation, these would be checked
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove or implement the invalid input tests.

This function is currently a no-op. Since the comment indicates that panic testing isn't possible in V, consider either:

  1. Removing this function entirely
  2. Implementing tests for error conditions that can be verified (if the BLAS functions return error codes)
🤖 Prompt for AI Agents
In blas/blas_test.v around lines 545 to 552, the test_invalid_inputs function is
currently empty and does not test any invalid input scenarios. Since panic
testing is not feasible in V, either remove this function entirely to avoid dead
code or implement tests that verify error conditions through return codes or
other means supported by the BLAS functions. Choose the approach that best fits
the current error handling capabilities of the BLAS implementation.

blas/blas_test.v Outdated
expected := 11.0 // 1*3 + 2*4 = 11

// If result is wildly incorrect, CBLAS is not working
return math.abs(result - expected) < 1.0
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Use consistent tolerance for CBLAS detection.

The tolerance of 1.0 is too loose for verifying CBLAS functionality. For such a simple calculation, the result should be much more precise.

Apply this diff to use the defined test tolerance:

-	return math.abs(result - expected) < 1.0
+	return math.abs(result - expected) < test_tol
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return math.abs(result - expected) < 1.0
return math.abs(result - expected) < test_tol
🤖 Prompt for AI Agents
In blas/blas_test.v at line 17, the tolerance used for comparing the result and
expected value is too large (1.0), which is inconsistent with the precision
needed for CBLAS detection. Replace the hardcoded tolerance 1.0 with the
predefined test tolerance constant used elsewhere in the tests to ensure
consistent and stricter precision checks.

- Updated LAPACK function wrappers to convert job parameters for SVD, LU, and eigenvalue computations to their LAPACK64 equivalents.
- Introduced a new test file for LAPACK functionality, covering various linear algebra operations including:
  - General linear system solving (GESV)
  - LU factorization and matrix inversion (GETRF/GETRI)
  - Cholesky factorization (POTRF)
  - Eigenvalue problems (GEEV/SYEV)
  - QR factorization (GEQRF/ORGQR)
  - Singular value decomposition (GESVD)
- Added utility functions for matrix operations, random matrix generation, and orthogonality checks.
- Ensured tests validate correctness and performance against expected results with appropriate tolerances.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🔭 Outside diff range comments (2)
blas/conversions.v (2)

223-223: Fix typo in function name.

The function name has a typo - missing 'c' in 'complex'.

-pub fn print_col_major_omplex_py(m int, n int, data []complex.Complex, nfmt_r_ string, nfmt_i_ string) string {
+pub fn print_col_major_complex_py(m int, n int, data []complex.Complex, nfmt_r_ string, nfmt_i_ string) string {

221-221: Fix typo in function name.

There's a typo in the function name that should be corrected.

-pub fn print_col_major_omplex_py(m int, n int, data []complex.Complex, nfmt_r_ string, nfmt_i_ string) string {
+pub fn print_col_major_complex_py(m int, n int, data []complex.Complex, nfmt_r_ string, nfmt_i_ string) string {
♻️ Duplicate comments (2)
blas/conversions.v (2)

42-412: Add unit tests for utility functions.

Utility functions for matrix operations should be covered by unit tests to verify their correctness, especially with edge cases like zero-sized matrices.


42-412: Verify unit test coverage for utility functions.

The utility functions for matrix operations appear well-implemented, but based on past review feedback, unit tests are missing. These functions handle critical operations like matrix conversions, printing, and eigenvector building.

Please run the following script to verify if unit tests have been added for the utility functions:

#!/bin/bash
# Description: Check for unit tests covering utility functions in blas/conversions.v

# Search for test functions that might test the utility functions
rg -A 5 'fn test_.*(?:slice_to_col_major|print_col_major|extract_row|extract_col|eigenvecs_build|join_complex|split_complex)' --type v

# Also search for any test files that might import this module
rg -l 'import.*blas' --type v | xargs rg 'fn test_' -A 2
🧹 Nitpick comments (2)
lapack/lapack_notd_vsl_lapack_lapacke.v (1)

145-162: Clarify the eigenvector parameter handling logic.

The logic for handling vvl/vvr variables is unclear. Why are we saving and restoring the first elements of the vl/vr arrays? This needs documentation or simplification.

Consider adding a comment explaining this logic or simplifying it if it's not necessary for correct LAPACK operation.

blas/oblas_notd_vsl_blas_cblas.v (1)

5-7: Document why set_num_threads is a no-op.

The empty implementation could be confusing. Add a comment explaining why this function doesn't set thread count.

 // set_num_threads sets the number of threads in BLAS
+// Note: This is a no-op in the current implementation as thread configuration
+// is handled by the underlying BLAS library or not supported.
 @[inline]
 pub fn set_num_threads(n int) {}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b9ed96e and ca12b20.

📒 Files selected for processing (5)
  • blas/conversions.v (2 hunks)
  • blas/oblas_notd_vsl_blas_cblas.v (1 hunks)
  • lapack/conversions.v (1 hunks)
  • lapack/lapack_notd_vsl_lapack_lapacke.v (7 hunks)
  • lapack/lapack_test.v (1 hunks)
🧰 Additional context used
🪛 GitHub Check: run-tests-on-linux (ubuntu-22.04)
lapack/lapack_notd_vsl_lapack_lapacke.v

[failure] 116-116:
infix expr: cannot use int literal (right expression) as bool


[failure] 115-115:
cannot use blas64.Uplo as blas.Uplo in argument 1 to vsl.lapack.lapack64.dpotrf


[failure] 116-116:
infix expr: cannot use int literal (right expression) as bool


[failure] 115-115:
cannot use blas64.Uplo as blas.Uplo in argument 1 to vsl.lapack.lapack64.dpotrf


[failure] 116-116:
infix expr: cannot use int literal (right expression) as bool


[failure] 115-115:
cannot use blas64.Uplo as blas.Uplo in argument 1 to vsl.lapack.lapack64.dpotrf


[failure] 116-116:
infix expr: cannot use int literal (right expression) as bool


[failure] 115-115:
cannot use blas64.Uplo as blas.Uplo in argument 1 to vsl.lapack.lapack64.dpotrf


[failure] 116-116:
infix expr: cannot use int literal (right expression) as bool


[failure] 115-115:
cannot use blas64.Uplo as blas.Uplo in argument 1 to vsl.lapack.lapack64.dpotrf

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04)
  • GitHub Check: run-tests-on-linux (ubuntu-22.04, --prod)
  • GitHub Check: run-tests-on-macos (macos-latest)
  • GitHub Check: run-tests-on-macos (macos-latest, --prod)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04, --prod)
  • GitHub Check: MegaLinter
  • GitHub Check: MegaLinter
🔇 Additional comments (8)
blas/conversions.v (4)

414-505: Well-structured enum conversion implementation.

The explicit conversion functions properly address V's enum type system limitations and provide clean interoperability with the blas64 module. The bidirectional conversions are complete and follow a consistent pattern.


1-7: Module refactoring looks good.

The module name change from vlas to blas and the addition of the blas64 import align well with the refactoring objectives. The imports are appropriate for the functionality provided.


9-40: Well-structured enum definitions with explicit values.

The enum definitions are comprehensive and follow BLAS conventions with explicit integer values. The documentation comments clearly explain the purpose of each enum. This approach provides better type safety compared to implicit conversions.


413-506: Excellent implementation of type-safe enum conversions.

The conversion functions are well-implemented with complete bidirectional mappings for all enum types. The use of match expressions ensures type safety and the documentation clearly explains the necessity of these functions due to V's enum type alias limitations.

Key strengths:

  • Complete coverage of all enum types (MemoryLayout, Transpose, Uplo, Diagonal, Side)
  • Symmetric to/from conversions for each type
  • Clear, descriptive function names
  • Proper error handling through match expressions
lapack/lapack_notd_vsl_lapack_lapacke.v (1)

114-119: Fix multiple issues in dpotrf function.

The function has several issues that need to be addressed:

  1. Incorrect error message references dgesvd instead of dpotrf
  2. Missing enum conversion for the uplo parameter
  3. Type error in the condition (comparing int with bool)
 pub fn dpotrf(uplo blas.Uplo, n int, mut a []f64, lda int) {
-	info := lapack64.dpotrf(blas.to_blas64_uplo(uplo), n, mut a, lda)
-	if info != 0 {
-		errors.vsl_panic('LAPACK dgesvd failed with error code: ${info}', .efailed)
+	info := lapack64.dpotrf(blas.to_blas64_uplo(uplo), n, mut a, lda)
+	if info != 0 {
+		errors.vsl_panic('LAPACK dpotrf failed with error code: ${info}', .efailed)
 	}
 }

Likely an incorrect or invalid review comment.

lapack/lapack_test.v (1)

1-705: Excellent comprehensive test suite.

The test suite is well-structured with:

  • Clear utility functions for matrix operations
  • Appropriate tolerance constants
  • Thorough coverage of LAPACK functionality
  • Good integration tests comparing different solution methods
  • Proper handling of backend availability

The tests follow best practices with deterministic inputs and clear assertions.

lapack/conversions.v (1)

1-600: Well-designed LAPACK enum definitions and conversions.

The module provides comprehensive strongly-typed enums for LAPACK parameters with complete bidirectional conversion functions. The implementation follows a consistent pattern and includes clear documentation explaining the necessity of these conversions due to V's enum type system.

blas/oblas_notd_vsl_blas_cblas.v (1)

9-179: Clean and consistent BLAS wrapper implementation.

All wrapper functions properly delegate to blas64 with appropriate enum conversions. The inline attribute ensures minimal overhead, and the implementation follows a consistent pattern throughout.

Comment on lines +23 to +24
// Uplo is used to specify whether the upper or lower triangle of a matrix is
pub enum Uplo {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Complete the documentation for Uplo enum.

The comment is incomplete and should explain what the enum represents.

-// Uplo is used to specify whether the upper or lower triangle of a matrix is
+// Uplo is used to specify whether the upper or lower triangle of a matrix is being referenced or operated on.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Uplo is used to specify whether the upper or lower triangle of a matrix is
pub enum Uplo {
// Uplo is used to specify whether the upper or lower triangle of a matrix is being referenced or operated on.
pub enum Uplo {
🤖 Prompt for AI Agents
In blas/conversions.v around lines 23 to 24, the documentation comment for the
Uplo enum is incomplete. Expand the comment to fully explain that the Uplo enum
specifies whether the upper or lower triangle of a matrix is being referenced or
used, providing clear context on its purpose in matrix operations.

Comment on lines 165 to 167
if info != 0 {
errors.vsl_panic('LAPACK dgesvd failed with error code: ${info}', .efailed)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix incorrect error message in dgeev.

The error message incorrectly references dgesvd instead of dgeev.

-		errors.vsl_panic('LAPACK dgesvd failed with error code: ${info}', .efailed)
+		errors.vsl_panic('LAPACK dgeev failed with error code: ${info}', .efailed)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if info != 0 {
errors.vsl_panic('LAPACK dgesvd failed with error code: ${info}', .efailed)
}
if info != 0 {
errors.vsl_panic('LAPACK dgeev failed with error code: ${info}', .efailed)
}
🤖 Prompt for AI Agents
In lapack/lapack_notd_vsl_lapack_lapacke.v around lines 165 to 167, the error
message incorrectly mentions "dgesvd" instead of "dgeev". Update the error
message string to correctly reference "dgeev" to accurately reflect the function
where the error occurred.

Comment on lines 92 to 94
if info != 0 {
errors.vsl_panic('LAPACK dgesvd failed with error code: ${info}', .efailed)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix incorrect error message in dgetri.

The error message incorrectly references dgesvd instead of dgetri.

-		errors.vsl_panic('LAPACK dgesvd failed with error code: ${info}', .efailed)
+		errors.vsl_panic('LAPACK dgetri failed with error code: ${info}', .efailed)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if info != 0 {
errors.vsl_panic('LAPACK dgesvd failed with error code: ${info}', .efailed)
}
if info != 0 {
errors.vsl_panic('LAPACK dgetri failed with error code: ${info}', .efailed)
}
🤖 Prompt for AI Agents
In lapack/lapack_notd_vsl_lapack_lapacke.v around lines 92 to 94, the error
message incorrectly mentions "dgesvd" when it should refer to "dgetri". Update
the string in the errors.vsl_panic call to correctly state "LAPACK dgetri failed
with error code" to accurately reflect the function that failed.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (3)
blas/blas64/level1f64_test.v (1)

1-216: Define the missing test_tol constant.

The test_tol variable is used extensively throughout the test file but is never defined. This will cause compilation errors.

Add the missing tolerance constant at the top of the file:

+const test_tol = 1e-14
+
 fn test_ddot() {
blas/blas64/level3f64_test.v (1)

1-78: Define the missing test_tol constant.

Same issue as in level1 tests - the test_tol variable is used but not defined.

Add the missing tolerance constant:

+const test_tol = 1e-14
+
 fn test_dgemm() {
blas/blas64/level2f64_test.v (1)

1-206: Define missing constants and helper functions.

The file uses test_tol and flatten function which are not defined, causing compilation errors.

Add the missing definitions:

+const test_tol = 1e-14
+
+// Helper function to flatten 2D array to 1D for BLAS routines
+fn flatten(a [][]f64) []f64 {
+	mut result := []f64{}
+	for row in a {
+		result << row
+	}
+	return result
+}
+
 fn test_dgemv() {
🧹 Nitpick comments (1)
blas/blas64/level3f64_test.v (1)

68-77: Remove unused helper function.

The unflatten function is defined but never used in the tests. Consider removing it to reduce code clutter.

-// Helper function to unflatten back to 2D array (for verification)
-fn unflatten(s []f64, m int, n int) [][]f64 {
-	mut a := [][]f64{len: m, init: []f64{len: n}}
-	for i in 0 .. m {
-		for j in 0 .. n {
-			a[i][j] = s[i * n + j]
-		}
-	}
-	return a
-}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ca12b20 and 3278a73.

📒 Files selected for processing (4)
  • blas/blas64/level1f64_test.v (1 hunks)
  • blas/blas64/level2f64_test.v (1 hunks)
  • blas/blas64/level3f64_test.v (1 hunks)
  • blas/blas64/util.v (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • blas/blas64/util.v
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04)
  • GitHub Check: run-tests-on-linux (ubuntu-22.04)
  • GitHub Check: run-tests-on-linux (ubuntu-22.04, --prod)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04, --prod)
  • GitHub Check: MegaLinter
  • GitHub Check: run-tests-on-macos (macos-latest)
  • GitHub Check: run-tests-on-macos (macos-latest, --prod)
  • GitHub Check: fmt
  • GitHub Check: docs
  • GitHub Check: MegaLinter
🔇 Additional comments (6)
blas/blas64/level1f64_test.v (2)

10-31: Excellent test coverage for ddot function.

The test cases comprehensively cover basic dot product operations, zero vectors, and stride-based operations. The mathematical calculations are correct and the test structure is well-designed.


73-91: No action required: idamax uses 0-based indexing

The pure V implementation in blas/blas64/level1f64.v initializes its max index at 0 (returning –1 when n == 0) and the CBLAS wrapper likewise returns a 0-based index. The tests’ expected indices (1, 3, 1) are correct.

blas/blas64/level3f64_test.v (1)

10-41: Excellent DGEMM test coverage.

The test cases thoroughly cover matrix multiplication with different transpose options and scaling factors. The mathematical calculations are correct and demonstrate proper understanding of BLAS DGEMM semantics.

blas/blas64/level2f64_test.v (3)

9-43: Comprehensive DGEMV test coverage.

The test cases excellently cover matrix-vector multiplication with different transpose options and scaling factors. The mathematical calculations are correct and demonstrate proper BLAS semantics.


130-158: Verify symmetric matrix handling in DSYMV tests.

The test logic correctly handles symmetric matrices by using only the specified triangle (upper or lower) and applying symmetry. The mathematical calculations and expected results are accurate.


160-174: Band matrix storage format verified.

The test’s a1 array correctly encodes the 2×2 matrix [2 1; 1 2] in band-storage for kl=1, ku=1, lda=3:

  • Column 0 of the 3×2 band matrix is [0, 2, 1] → A(0,0)=B(1,0)=2, A(1,0)=B(2,0)=1
  • Column 1 is [1, 2, 0] → A(0,1)=B(0,1)=1, A(1,1)=B(1,1)=2

This matches the BLAS reference formula A(i,j)=B(ku+i−j,j), so no changes are needed.

… library tolerance functions in BLAS and LAPACK tests
- Implemented dtrmm (triangular matrix-matrix multiplication) and dtrsm (triangular system solve) in the blas64 module.
- Added comprehensive test cases for dtrmm and dtrsm to validate functionality against expected results.
- Included a new symmetric rank-2k update function dsyr2k in the BLAS interface.
- Updated the oblas and lapack interfaces to include the new BLAS functions.
- Enhanced existing tests to cover various scenarios for the new and modified functions.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
blas/blas64/level3f64_test.v (1)

166-174: Remove unused helper function.

The unflatten function is defined but never used in this test file. Consider removing it to avoid dead code.

-// Helper function to unflatten back to 2D array (for verification)
-fn unflatten(s []f64, m int, n int) [][]f64 {
-	mut a := [][]f64{len: m, init: []f64{len: n}}
-	for i in 0 .. m {
-		for j in 0 .. n {
-			a[i][j] = s[i * n + j]
-		}
-	}
-	return a
-}
blas/oblas_notd_vsl_blas_cblas.v (1)

5-7: Document the no-op set_num_threads function.

The function is currently a no-op which might be intentional for interface compatibility, but this should be documented to avoid confusion.

-// set_num_threads sets the number of threads in BLAS
+// set_num_threads sets the number of threads in BLAS
+// Note: This is currently a no-op as thread control is handled by the underlying blas64 implementation
 @[inline]
 pub fn set_num_threads(n int) {}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 292c7eb and 88e553d.

📒 Files selected for processing (7)
  • blas/blas64/level3f64_dsyr2k.v (1 hunks)
  • blas/blas64/level3f64_dtrmm.v (1 hunks)
  • blas/blas64/level3f64_dtrsm.v (1 hunks)
  • blas/blas64/level3f64_test.v (1 hunks)
  • blas/blas_test.v (1 hunks)
  • blas/oblas_notd_vsl_blas_cblas.v (1 hunks)
  • lapack/lapack_notd_vsl_lapack_lapacke.v (7 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • lapack/lapack_notd_vsl_lapack_lapacke.v
🧰 Additional context used
🪛 GitHub Check: run-tests-on-linux (ubuntu-24.04)
blas/blas64/level3f64_dtrsm.v

[warning] 3-3:
module 'float64 (vsl.float.float64)' is imported but never used

🪛 GitHub Check: run-tests-on-linux (ubuntu-22.04)
blas/blas64/level3f64_dtrsm.v

[warning] 3-3:
module 'float64 (vsl.float.float64)' is imported but never used

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: run-tests-on-macos (macos-latest)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04, --prod)
  • GitHub Check: run-tests-on-macos (macos-latest, --prod)
  • GitHub Check: run-tests-on-linux (ubuntu-22.04, --prod)
  • GitHub Check: MegaLinter
  • GitHub Check: MegaLinter
🔇 Additional comments (10)
blas/blas64/level3f64_dtrmm.v (1)

1-217: Well-implemented triangular matrix-matrix multiplication!

The implementation is comprehensive and correctly handles all combinations of parameters (side, uplo, transpose, diagonal). The column-major storage indexing is consistent throughout, and the use of float64.scal_unitary and float64.axpy_unitary for vector operations is appropriate.

blas/blas64/level3f64_dsyr2k.v (1)

1-218: Excellent implementation of symmetric rank 2k update!

The implementation correctly handles all cases for transpose and triangular storage. The optimization for alpha=0 case is well done, and the symmetric matrix property is properly maintained by only updating the specified triangular part.

blas/blas64/level3f64_test.v (1)

10-163: Comprehensive test coverage for Level 3 BLAS functions!

The tests are well-structured with good coverage of different parameter combinations, edge cases, and proper use of column-major storage. The expected values appear to be correctly calculated.

blas/blas64/level3f64_dtrsm.v (1)

6-260: Well-implemented triangular solve function!

The implementation correctly handles all parameter combinations and edge cases. The column-major indexing is consistent, and the logic for solving triangular systems is properly implemented for both left and right side cases.

blas/blas_test.v (2)

21-610: Excellent comprehensive test suite for BLAS operations!

The test structure is well-organized with clear test cases and expected values. The tests properly handle column-major storage and cover a wide range of scenarios for Level 1, 2, and 3 BLAS operations.


629-665: Good performance test implementation!

The test appropriately uses moderately sized vectors (n=1000) to verify both correctness and reasonable performance. The manual verification of results ensures the operations are working correctly even with larger data.

blas/oblas_notd_vsl_blas_cblas.v (4)

9-61: LGTM: Level 1 BLAS functions are correctly implemented.

The Level 1 BLAS functions (vector operations) are properly implemented as direct wrappers to the blas64 functions. The function signatures, parameter types, and delegation are all correct.


63-172: LGTM: Level 2 BLAS functions with proper enum conversions.

The Level 2 BLAS functions (matrix-vector operations) correctly use conversion functions to map enum parameters to the blas64 equivalents. The implementations follow BLAS conventions properly.


174-200: LGTM: Level 3 BLAS functions are well-structured.

The Level 3 BLAS functions (matrix-matrix operations) are correctly implemented with proper enum conversions and parameter delegation. The use of @[inline] attribute is appropriate for performance-critical BLAS operations.


1-3: Conversion utilities and enums are already available in this module

The Transpose, Uplo, Diagonal, and Side enums, along with the to_blas64_* conversion functions, are defined in blas/conversions.v under module blas. Since your wrapper file is also declared as module blas, it can reference those symbols directly without any extra imports.

No change needed.

@@ -0,0 +1,260 @@
module blas64

import vsl.float.float64
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove unused import.

The vsl.float.float64 module is imported but never used in this file.

-import vsl.float.float64
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import vsl.float.float64
🧰 Tools
🪛 GitHub Check: run-tests-on-linux (ubuntu-24.04)

[warning] 3-3:
module 'float64 (vsl.float.float64)' is imported but never used

🪛 GitHub Check: run-tests-on-linux (ubuntu-22.04)

[warning] 3-3:
module 'float64 (vsl.float.float64)' is imported but never used

🤖 Prompt for AI Agents
In blas/blas64/level3f64_dtrsm.v at line 3, the import statement for
vsl.float.float64 is unused. Remove this import line to clean up the code and
avoid unnecessary dependencies.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (3)
blas/README.md (2)

14-17: Add a comma before “but” to fix the compound sentence
Minor grammar improvement—helps readability.

-This backend is probably the fastest one for all platforms but it requires the installation of the OpenBLAS library.
+This backend is probably the fastest one for all platforms, but it requires the installation of the OpenBLAS library.

33-42: Clarify Debian/Ubuntu note wording
“GNU Linux” is uncommon phrasing; “GNU/Linux” or simply “Linux” is clearer. Also, consider moving the “libopenblas-dev is not needed …” sentence below the command to keep the flow (description → command) consistent with the Homebrew and Arch sections.

lapack/README.md (1)

16-17: Add missing comma for correct punctuation

The sentence is a compound clause and needs a comma before “but”:

-the fastest one for all platforms
-but it requires the installation of the LAPACKE library.
+the fastest one for all platforms, but it requires the installation of the LAPACKE library.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 88e553d and 1c8252e.

📒 Files selected for processing (2)
  • blas/README.md (1 hunks)
  • lapack/README.md (1 hunks)
🧰 Additional context used
🪛 LanguageTool
blas/README.md

[uncategorized] ~15-~15: Use a comma before ‘but’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...obably the fastest one for all platforms but it requires the installation of the Ope...

(COMMA_COMPOUND_SENTENCE)

lapack/README.md

[uncategorized] ~16-~16: Use a comma before ‘but’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...obably the fastest one for all platforms but it requires the installation of the LAP...

(COMMA_COMPOUND_SENTENCE)

🪛 markdownlint-cli2 (0.17.2)
lapack/README.md

8-8: Table column count
Expected: 4; Actual: 2; Too few cells, row will be missing data

(MD056, table-column-count)


9-9: Table column count
Expected: 4; Actual: 3; Too few cells, row will be missing data

(MD056, table-column-count)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: run-tests-on-linux (ubuntu-22.04, --prod)
  • GitHub Check: MegaLinter
  • GitHub Check: run-tests-on-linux (ubuntu-22.04)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04, --prod)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04)
  • GitHub Check: run-tests-on-macos (macos-latest, --prod)
  • GitHub Check: run-tests-on-macos (macos-latest)
  • GitHub Check: docs
  • GitHub Check: MegaLinter

Comment on lines +1 to +3
# The V Basic Linear Algebra System

This package implements Basic Linear Algebra System (BLAS) routines in V.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use the canonical BLAS expansion (“Basic Linear Algebra Subprograms”)
The abbreviation BLAS traditionally stands for Subprograms, not System. Using the canonical term avoids confusion for users already familiar with the library.

-# The V Basic Linear Algebra System
+# The V Basic Linear Algebra Subprograms (BLAS)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# The V Basic Linear Algebra System
This package implements Basic Linear Algebra System (BLAS) routines in V.
# The V Basic Linear Algebra Subprograms (BLAS)
This package implements Basic Linear Algebra System (BLAS) routines in V.
🤖 Prompt for AI Agents
In blas/README.md at lines 1 to 3, the abbreviation BLAS is incorrectly expanded
as "Basic Linear Algebra System." Change this to the canonical expansion "Basic
Linear Algebra Subprograms" to align with the standard terminology and avoid
confusion for users familiar with BLAS.

Comment on lines +5 to +9
| Backend | Description | Status | Compilation Flags |
| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ----------------------- | ----------------- |
| BLAS | Pure V implementation | WIP | `NONE` |
| LAPACKE | LAPACKE is a C interface to LAPACK. It is a standard part of the LAPACK distribution. |
| Check the section [LAPACKE Backend](#lapacke-backend) for more information. | Stable | `-d vsl_lapack_lapacke` |
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix broken Markdown table rendering

Rows 8-9 have fewer columns than the header row, so the table collapses when rendered (see MD056 warnings). Merge the two LAPACKE lines into a single row with four cells:

-| LAPACKE                                                                     | LAPACKE is a C interface to LAPACK. It is a standard part of the LAPACK distribution. |
-| Check the section [LAPACKE Backend](#lapacke-backend) for more information. | Stable                                                                                | `-d vsl_lapack_lapacke` |
+| LAPACKE                                                                     | LAPACKE is a C interface to LAPACK. Check the section [LAPACKE Backend](#lapacke-backend) for more information. | Stable | `-d vsl_lapack_lapacke` |

This restores a valid 4-column layout and eliminates the linter errors.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
| Backend | Description | Status | Compilation Flags |
| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ----------------------- | ----------------- |
| BLAS | Pure V implementation | WIP | `NONE` |
| LAPACKE | LAPACKE is a C interface to LAPACK. It is a standard part of the LAPACK distribution. |
| Check the section [LAPACKE Backend](#lapacke-backend) for more information. | Stable | `-d vsl_lapack_lapacke` |
| Backend | Description | Status | Compilation Flags |
| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ----------------------- | ----------------- |
| BLAS | Pure V implementation | WIP | `NONE` |
| LAPACKE | LAPACKE is a C interface to LAPACK. Check the section [LAPACKE Backend](#lapacke-backend) for more information. | Stable | `-d vsl_lapack_lapacke` |
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

8-8: Table column count
Expected: 4; Actual: 2; Too few cells, row will be missing data

(MD056, table-column-count)


9-9: Table column count
Expected: 4; Actual: 3; Too few cells, row will be missing data

(MD056, table-column-count)

🤖 Prompt for AI Agents
In lapack/README.md around lines 5 to 9, the Markdown table rows for LAPACKE
have fewer columns than the header, causing rendering issues. Merge the two
separate LAPACKE lines into one row with four columns: Backend, Description,
Status, and Compilation Flags. Ensure the description cell includes the full
text from both lines combined, preserving all information while maintaining the
table's column structure.

Comment on lines +45 to +50
The best way of installing OpenBLAS is using
[blas-openblas](https://archlinux.org/packages/extra/x86_64/blas-openblas/).

```sh
sudo pacman -S blas-openblas
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify Arch Linux instructions – package name appears wrong

The Arch section refers to OpenBLAS (blas-openblas) even though the goal is to install LAPACKE headers/libs. On Arch, LAPACKE is shipped by lapack (which itself pulls OpenBLAS). Consider replacing these lines with:

-The best way of installing OpenBLAS is using
-[blas-openblas](https://archlinux.org/packages/extra/x86_64/blas-openblas/).
-
-```sh
-sudo pacman -S blas-openblas
-```
+LAPACKE headers and libraries are provided by the
+[lapack](https://archlinux.org/packages/extra/x86_64/lapack/) package
+(which depends on OpenBLAS):
+
+```sh
+sudo pacman -S lapack
+```

Please double-check the package names to avoid installation errors.


🏁 Script executed:

#!/bin/bash
# Verify Arch package contents and dependencies via the Arch Linux website API

# 1. Check that the 'lapack' package includes the LAPACKE header
echo "Contents of lapack package (looking for lapacke.h):"
curl -s https://archlinux.org/packages/extra/x86_64/lapack/json/ | jq '.files' | grep -F "include/lapacke.h" || echo "→ lapacke.h not found in lapack"

# 2. Check that the 'blas-openblas' package does not include the LAPACKE header
echo
echo "Contents of blas-openblas package (looking for lapacke.h):"
curl -s https://archlinux.org/packages/extra/x86_64/blas-openblas/json/ | jq '.files' | grep -F "lapacke.h" || echo "→ lapacke.h not found in blas-openblas"

# 3. List dependencies of the lapack package to confirm it depends on a BLAS provider (OpenBLAS)
echo
echo "Dependencies of lapack package:"
curl -s https://archlinux.org/packages/extra/x86_64/lapack/json/ | jq '.depends'

Length of output: 820


🏁 Script executed:

#!/bin/bash
# Inspect OpenBLAS package details to determine LAPACKE support

echo "Description of openblas package:"
curl -s https://archlinux.org/packages/extra/x86_64/openblas/json/ | jq '.desc'

echo
echo "Header files in openblas package:"
curl -s https://archlinux.org/packages/extra/x86_64/openblas/json/ | jq -r '.files[]' | grep -E "usr/include/.*\.h" | head -n 20

echo
echo "Library files in openblas package:"
curl -s https://archlinux.org/packages/extra/x86_64/openblas/json/ | jq -r '.files[]' | grep -E "usr/lib/.*\.(so|a)" | head -n 20

Length of output: 710


🏁 Script executed:

#!/bin/bash
# Refined search for LAPACKE headers and libraries in lapack and blas-openblas Arch packages

for pkg in lapack blas-openblas; do
  echo "===== Package: $pkg ====="
  curl -s https://archlinux.org/packages/extra/x86_64/$pkg/json/ | \
    jq -r '.files[]' 2>/dev/null | \
    grep -E 'lapacke\.h|liblapacke'
  echo
done

Length of output: 474


🏁 Script executed:

#!/bin/bash
# Verify file listings via HTML pages on archlinux.org for LAPACKE content

echo "=== lapack package files (checking for lapacke headers/libs) ==="
curl -s https://archlinux.org/packages/extra/x86_64/lapack/files/ | grep -E "/usr/include/lapacke.h|/usr/lib/liblapacke"

echo
echo "=== blas-openblas package files (checking for lapacke headers/libs) ==="
curl -s https://archlinux.org/packages/extra/x86_64/blas-openblas/files/ | grep -E "/usr/include/lapacke.h|/usr/lib/liblapacke"

Length of output: 552


🏁 Script executed:

#!/bin/bash
# Correctly extract file names for lapack and blas-openblas packages to check LAPACKE content
for pkg in lapack blas-openblas; do
  echo "===== Package: $pkg ====="
  curl -s https://archlinux.org/packages/extra/x86_64/$pkg/json/ \
    | jq -r '.files[]?.name' 2>/dev/null \
    | grep -E 'lapacke' || echo "→ no lapacke files in $pkg"
  echo
done

Length of output: 602


Update Arch Linux installation instructions for LAPACKE

The Arch package that provides the LAPACKE headers and libraries is lapack (which pulls in OpenBLAS via the virtual blas dependency), not blas-openblas.

Files to update:

  • lapack/README.md (lines 45–50)

Replace the existing snippet with:

-The best way of installing OpenBLAS is using
-[blas-openblas](https://archlinux.org/packages/extra/x86_64/blas-openblas/).
-
-```sh
-sudo pacman -S blas-openblas
-```
+LAPACKE headers and libraries are provided by the
+[lapack](https://archlinux.org/packages/extra/x86_64/lapack/) package
+(which depends on OpenBLAS via the `blas` virtual package):
+
+```sh
+sudo pacman -S lapack
+```
🤖 Prompt for AI Agents
In lapack/README.md around lines 45 to 50, the Arch Linux installation
instructions incorrectly suggest installing the blas-openblas package for
LAPACKE. Update the instructions to indicate that the correct package to install
is lapack, which provides LAPACKE headers and libraries and depends on OpenBLAS
via the blas virtual package. Replace the existing snippet with a description of
the lapack package and the command "sudo pacman -S lapack".

…nvector job parameters

- Removed the `is_cblas_working` function and associated checks from BLAS tests.
- Updated eigenvector job parameters in LAPACK functions to correctly reflect right eigenvector computations.
- Adjusted LAPACK function signatures to use `RightEigenVectorsJob` instead of `LeftEigenVectorsJob` where applicable.
- Enhanced LAPACK function implementations to ensure proper handling of matrix dimensions and conversions between row-major and column-major formats.
- Cleaned up test cases in `lapack_test.v` to eliminate unnecessary LAPACKE backend checks, simplifying the test flow.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (4)
lapack/lapack_notd_vsl_lapack_lapacke.v (2)

92-95: Fix incorrect error message in dgetri.

The error message incorrectly references dgesvd instead of dgetri.

-		errors.vsl_panic('LAPACK dgesvd failed with error code: ${info}', .efailed)
+		errors.vsl_panic('LAPACK dgetri failed with error code: ${info}', .efailed)

165-168: Fix incorrect error message in dgeev.

The error message incorrectly references dgesvd instead of dgeev.

-		errors.vsl_panic('LAPACK dgesvd failed with error code: ${info}', .efailed)
+		errors.vsl_panic('LAPACK dgeev failed with error code: ${info}', .efailed)
lapack/lapack_d_vsl_lapack_lapacke.v (1)

20-20: Fix output parameter types in dgebal declaration.

The ilo and ihi parameters are output parameters and should be pointers.

-fn C.LAPACKE_dgebal(matrix_layout blas.MemoryLayout, job BalanceJob, n int, a &f64, lda int, ilo int, ihi int, scale &f64) int
+fn C.LAPACKE_dgebal(matrix_layout blas.MemoryLayout, job BalanceJob, n int, a &f64, lda int, ilo &int, ihi &int, scale &f64) int
blas/blas_test.v (1)

534-541: Remove or implement the invalid input tests.

This function is currently a no-op. Since the comment indicates that panic testing isn't possible in V, consider either:

  1. Removing this function entirely
  2. Implementing tests for error conditions that can be verified (if the BLAS functions return error codes)
🧹 Nitpick comments (3)
lapack/lapack64/dgeev.v (1)

36-39: Incomplete implementation of dgeev.

The function currently only validates parameters but doesn't compute eigenvalues or eigenvectors. The placeholder comment indicates this needs to be implemented.

Would you like me to help implement the actual LAPACK calls for eigenvalue computation, or open an issue to track this task?

lapack/lapack_notd_vsl_lapack_lapacke.v (1)

337-355: Placeholder implementation needs completion.

The geev function returns zero-initialized arrays instead of computing eigenvalues and eigenvectors. This needs to be implemented once the underlying dgeev in lapack64 is completed.

Would you like me to help implement this function properly once the lapack64.dgeev is complete?

blas/blas_test.v (1)

547-578: Consider expanding performance test coverage.

The performance tests are well-implemented but could benefit from testing more BLAS operations and providing timing information.

Consider adding timing measurements and testing more Level 2/3 operations:

fn test_large_vectors() {
+	import time
	// Test with moderately large vectors to ensure performance is reasonable
	n := 1000 // Reduced from 10000 to avoid numerical precision issues
	mut x := []f64{len: n}
	mut y := []f64{len: n}

	// Fill with test data
	for i in 0 .. n {
		x[i] = f64(i) + 1.0
		y[i] = f64(i) * 2.0
	}

+	// Time DDOT operation
+	start := time.now()
	result := ddot(n, x, 1, y, 1)
+	elapsed := time.since(start)
+	println('DDOT on ${n} elements took: ${elapsed}')
	
	// ... rest of the test
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1c8252e and 35e3fb2.

📒 Files selected for processing (5)
  • blas/blas_test.v (1 hunks)
  • lapack/lapack64/dgeev.v (1 hunks)
  • lapack/lapack_d_vsl_lapack_lapacke.v (1 hunks)
  • lapack/lapack_notd_vsl_lapack_lapacke.v (1 hunks)
  • lapack/lapack_test.v (1 hunks)
🔇 Additional comments (5)
lapack/lapack_notd_vsl_lapack_lapacke.v (1)

146-162: Clarify the vector handling logic in dgeev.

The purpose of saving and restoring vl[0] and vr[0] is unclear. If eigenvectors are not computed, the leading dimensions should be set appropriately without modifying the arrays.

Can you explain why this temporary variable logic is needed? The LAPACK documentation suggests that when eigenvectors are not computed, the corresponding arrays are not referenced.

lapack/lapack_test.v (1)

1-627: Excellent test coverage!

The test suite is comprehensive and well-structured with:

  • Good utility functions for matrix operations
  • Proper verification of mathematical properties
  • Deterministic random seeds for reproducibility
  • Coverage of basic and advanced LAPACK functionality
  • Integration tests comparing different methods
blas/blas_test.v (3)

1-8: LGTM - Well-structured module setup.

The module imports and test tolerance constant are appropriate for double-precision BLAS testing.


260-425: Excellent comprehensive BLAS test coverage.

The test suite provides thorough coverage of Level 1, 2, and 3 BLAS operations with well-structured test cases and proper tolerance checking. The organization by BLAS levels makes the tests easy to understand and maintain.


28-79: All Level 1 expected_dnrm2 values are accurate.

Verified the computed √(6²+5²+4²+2²+6²) matches the hard-coded value within 1×10⁻¹⁴ tolerance. No precision issues found—no changes needed.

Comment on lines +31 to +34
// Quick return if possible
if n == 0 {
return 0
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove unreachable code.

The check for n == 0 is already handled at lines 8-10, making this code unreachable.

-	// Quick return if possible
-	if n == 0 {
-		return 0
-	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Quick return if possible
if n == 0 {
return 0
}
🤖 Prompt for AI Agents
In lapack/lapack64/dgeev.v around lines 31 to 34, the check for n == 0 is
redundant because it is already handled earlier at lines 8 to 10. Remove this
unreachable code block to clean up the function and avoid unnecessary checks.

Comment on lines +116 to +120
info := lapack64.dpotrf(uplo, n, mut a, lda)
if !info {
errors.vsl_panic('LAPACK dgesvd failed with error code: ${info}', .efailed)
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix incorrect error condition in dpotrf.

The condition !info is incorrect - LAPACK returns 0 on success, so this will panic on success instead of failure.

-	if !info {
-		errors.vsl_panic('LAPACK dgesvd failed with error code: ${info}', .efailed)
+	if info != 0 {
+		errors.vsl_panic('LAPACK dpotrf failed with error code: ${info}', .efailed)
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
info := lapack64.dpotrf(uplo, n, mut a, lda)
if !info {
errors.vsl_panic('LAPACK dgesvd failed with error code: ${info}', .efailed)
}
}
info := lapack64.dpotrf(uplo, n, mut a, lda)
if info != 0 {
errors.vsl_panic('LAPACK dpotrf failed with error code: ${info}', .efailed)
}
}
🤖 Prompt for AI Agents
In lapack/lapack_notd_vsl_lapack_lapacke.v around lines 116 to 120, the error
check for the dpotrf call is incorrect because LAPACK returns 0 on success and a
positive integer on failure. Change the condition from `if !info` to `if info !=
0` to correctly detect failure and trigger the panic only when an error occurs.

Comment on lines +494 to +528
fn test_dsyr2k() {
// Test: Symmetric rank-2k update C := alpha*A*B^T + alpha*B*A^T + beta*C
// Using a simple 2x2 case, data stored in column-major order
alpha := 2.0
beta := 0.5

// A is 2x2 matrix (column-major storage)
// Row-major view: [[1, 2], [3, 4]]
// Column-major: [1, 3, 2, 4]
a := [1.0, 3.0, 2.0, 4.0]

// B is 2x2 matrix (column-major storage)
// Row-major view: [[0.5, 1], [1.5, 2]]
// Column-major: [0.5, 1.5, 1, 2]
b := [0.5, 1.5, 1.0, 2.0]

// C is 2x2 symmetric matrix (column-major storage)
// Row-major view: [[1, 2], [2, 4]]
// Column-major: [1, 2, 2, 4]
mut c := [1.0, 2.0, 2.0, 4.0]

// Calculate expected result:
// A*B^T = [[1*0.5+2*1.5, 1*1.0+2*2.0], [3*0.5+4*1.5, 3*1.0+4*2.0]] = [[3.5, 5.0], [7.5, 11.0]]
// B*A^T = [[0.5*1+1.0*3, 0.5*2+1.0*4], [1.5*1+2.0*3, 1.5*2+2.0*4]] = [[3.5, 4.5], [7.5, 11.0]]
// alpha*(A*B^T + B*A^T) = 2.0*([[3.5, 5.0], [7.5, 11.0]] + [[3.5, 4.5], [7.5, 11.0]])
// = 2.0*[[7.0, 9.5], [15.0, 22.0]] = [[14.0, 19.0], [30.0, 44.0]]
// beta*C = 0.5*[[1.0, 2.0], [2.0, 4.0]] = [[0.5, 1.0], [1.0, 2.0]]
// Final: [[14.0+0.5, 19.0+1.0], [30.0+1.0, 44.0+2.0]] = [[14.5, 20.0], [31.0, 46.0]]
// In column-major: [14.5, 31.0, 20.0, 46.0]
expected := [20.5, 29.0, 2.0, 42.0]

dsyr2k(.upper, .no_trans, 2, 2, alpha, a, 2, b, 2, beta, mut c, 2)

assert float64.arrays_tolerance(c, expected, test_tol), 'DSYR2K failed: expected ${expected}, got ${c}'
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix calculation error in dsyr2k test.

There's a discrepancy between the detailed calculation in the comments and the expected result. The comments show the final result should be [14.5, 31.0, 20.0, 46.0] in column-major format, but the expected array is [20.5, 29.0, 2.0, 42.0].

Please verify the calculation and update either the comments or the expected values:

-	expected := [20.5, 29.0, 2.0, 42.0]
+	expected := [14.5, 31.0, 20.0, 46.0]

Or alternatively, verify the calculation is correct and update the comments to match.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fn test_dsyr2k() {
// Test: Symmetric rank-2k update C := alpha*A*B^T + alpha*B*A^T + beta*C
// Using a simple 2x2 case, data stored in column-major order
alpha := 2.0
beta := 0.5
// A is 2x2 matrix (column-major storage)
// Row-major view: [[1, 2], [3, 4]]
// Column-major: [1, 3, 2, 4]
a := [1.0, 3.0, 2.0, 4.0]
// B is 2x2 matrix (column-major storage)
// Row-major view: [[0.5, 1], [1.5, 2]]
// Column-major: [0.5, 1.5, 1, 2]
b := [0.5, 1.5, 1.0, 2.0]
// C is 2x2 symmetric matrix (column-major storage)
// Row-major view: [[1, 2], [2, 4]]
// Column-major: [1, 2, 2, 4]
mut c := [1.0, 2.0, 2.0, 4.0]
// Calculate expected result:
// A*B^T = [[1*0.5+2*1.5, 1*1.0+2*2.0], [3*0.5+4*1.5, 3*1.0+4*2.0]] = [[3.5, 5.0], [7.5, 11.0]]
// B*A^T = [[0.5*1+1.0*3, 0.5*2+1.0*4], [1.5*1+2.0*3, 1.5*2+2.0*4]] = [[3.5, 4.5], [7.5, 11.0]]
// alpha*(A*B^T + B*A^T) = 2.0*([[3.5, 5.0], [7.5, 11.0]] + [[3.5, 4.5], [7.5, 11.0]])
// = 2.0*[[7.0, 9.5], [15.0, 22.0]] = [[14.0, 19.0], [30.0, 44.0]]
// beta*C = 0.5*[[1.0, 2.0], [2.0, 4.0]] = [[0.5, 1.0], [1.0, 2.0]]
// Final: [[14.0+0.5, 19.0+1.0], [30.0+1.0, 44.0+2.0]] = [[14.5, 20.0], [31.0, 46.0]]
// In column-major: [14.5, 31.0, 20.0, 46.0]
expected := [20.5, 29.0, 2.0, 42.0]
dsyr2k(.upper, .no_trans, 2, 2, alpha, a, 2, b, 2, beta, mut c, 2)
assert float64.arrays_tolerance(c, expected, test_tol), 'DSYR2K failed: expected ${expected}, got ${c}'
}
fn test_dsyr2k() {
// Test: Symmetric rank-2k update C := alpha*A*B^T + alpha*B*A^T + beta*C
// Using a simple 2x2 case, data stored in column-major order
alpha := 2.0
beta := 0.5
// A is 2x2 matrix (column-major storage)
// Row-major view: [[1, 2], [3, 4]]
// Column-major: [1, 3, 2, 4]
a := [1.0, 3.0, 2.0, 4.0]
// B is 2x2 matrix (column-major storage)
// Row-major view: [[0.5, 1], [1.5, 2]]
// Column-major: [0.5, 1.5, 1, 2]
b := [0.5, 1.5, 1.0, 2.0]
// C is 2x2 symmetric matrix (column-major storage)
// Row-major view: [[1, 2], [2, 4]]
// Column-major: [1, 2, 2, 4]
mut c := [1.0, 2.0, 2.0, 4.0]
// Calculate expected result:
// A*B^T = [[1*0.5+2*1.5, 1*1.0+2*2.0], [3*0.5+4*1.5, 3*1.0+4*2.0]] = [[3.5, 5.0], [7.5, 11.0]]
// B*A^T = [[0.5*1+1.0*3, 0.5*2+1.0*4], [1.5*1+2.0*3, 1.5*2+2.0*4]] = [[3.5, 4.5], [7.5, 11.0]]
// alpha*(A*B^T + B*A^T) = 2.0*([[3.5, 5.0], [7.5, 11.0]] + [[3.5, 4.5], [7.5, 11.0]])
// = 2.0*[[7.0, 9.5], [15.0, 22.0]] = [[14.0, 19.0], [30.0, 44.0]]
// beta*C = 0.5*[[1.0, 2.0], [2.0, 4.0]] = [[0.5, 1.0], [1.0, 2.0]]
// Final: [[14.0+0.5, 19.0+1.0], [30.0+1.0, 44.0+2.0]] = [[14.5, 20.0], [31.0, 46.0]]
// In column-major: [14.5, 31.0, 20.0, 46.0]
- expected := [20.5, 29.0, 2.0, 42.0]
+ expected := [14.5, 31.0, 20.0, 46.0]
dsyr2k(.upper, .no_trans, 2, 2, alpha, a, 2, b, 2, beta, mut c, 2)
assert float64.arrays_tolerance(c, expected, test_tol), 'DSYR2K failed: expected ${expected}, got ${c}'
}
🤖 Prompt for AI Agents
In blas/blas_test.v around lines 494 to 528, the expected result array for the
dsyr2k test does not match the detailed calculation in the comments. The
comments calculate the final matrix as [14.5, 31.0, 20.0, 46.0] in column-major
order, but the expected array is [20.5, 29.0, 2.0, 42.0]. Review the matrix
multiplication and addition steps to confirm the correct final values, then
update the expected array to match the correct calculation or adjust the
comments to reflect the actual expected result used in the test.

- Updated LAPACK function signatures to return error codes instead of panicking.
- Introduced standardized wrapper functions for LAPACK operations, improving consistency across the API.
- Added detailed error handling in high-level wrapper functions for matrix operations.
- Removed redundant code and improved matrix conversion logic in wrapper functions.
- Cleaned up test files by removing unnecessary whitespace and ensuring consistency in test structure.
- Created a new file for LAPACK wrapper functions to separate concerns and enhance maintainability.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

♻️ Duplicate comments (3)
lapack/lapack_wrappers.v (3)

88-93: Critical: Incorrect matrix storage order in getrf.

The matrix is flattened in row-major order but LAPACK expects column-major.


174-178: Critical: Incorrect matrix storage order in potrf.

The matrix is flattened in row-major order but LAPACK expects column-major.


210-214: Critical: Incorrect matrix storage order in geqrf.

The matrix is flattened in row-major order but LAPACK expects column-major.

🧹 Nitpick comments (3)
lapack/lapack64/dgesv.v (1)

54-63: Consider returning more detailed error information.

The current implementation returns a generic error code of 1 for singularity. LAPACK's dgetrf typically returns the index of the first zero pivot, which would be more informative for debugging.

Consider modifying dgetrf to return the pivot index where singularity was detected, allowing this function to propagate that information to callers.

lapack/lapack64/dgetrf.v (1)

78-82: Remove duplicate comment.

The comment "apply interchanges to columns 1..j-1" is duplicated from line 74.

Apply this diff to fix the comment:

 if j + jb < n {
-    // apply interchanges to columns 1..j-1.
+    // apply interchanges to columns j+jb..n-1.
     mut slice2 := unsafe { a[j + jb..] }
lapack/lapack_notd_vsl_lapack_lapacke.v (1)

155-155: Optimize work array allocation for better performance.

The current implementation allocates work arrays with minimal size calculations. Consider implementing optimal work size queries for better performance, as recommended by LAPACK documentation.

For functions like dsyev, the optimal work size can be determined by calling the function with lwork = -1:

 pub fn dsyev(jobz EigenVectorsJob, uplo blas.Uplo, n int, mut a []f64, lda int, mut w []f64) int {
-	mut work := []f64{len: math.max(1, 3 * n - 1)}
+	// Query optimal work size
+	mut work_query := []f64{len: 1}
+	lapack64.dsyev(to_lapack64_eigen_vectors_job(jobz), uplo, n, mut a, lda, mut w, mut work_query, -1)
+	optimal_lwork := int(work_query[0])
+	mut work := []f64{len: math.max(1, optimal_lwork)}
 	lapack64.dsyev(to_lapack64_eigen_vectors_job(jobz), uplo, n, mut a, lda, mut w, mut
 		work, work.len)
 	return 0
 }

Also applies to: 179-179, 188-188, 205-205

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 35e3fb2 and e3095b8.

📒 Files selected for processing (8)
  • lapack/lapack64/dgesv.v (1 hunks)
  • lapack/lapack64/dgetf2.v (1 hunks)
  • lapack/lapack64/dgetrf.v (1 hunks)
  • lapack/lapack64/dgetrs.v (1 hunks)
  • lapack/lapack_d_vsl_lapack_lapacke.v (1 hunks)
  • lapack/lapack_notd_vsl_lapack_lapacke.v (1 hunks)
  • lapack/lapack_test.v (1 hunks)
  • lapack/lapack_wrappers.v (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • lapack/lapack_test.v
  • lapack/lapack_d_vsl_lapack_lapacke.v
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: MegaLinter
  • GitHub Check: run-tests-on-linux (ubuntu-22.04, --prod)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04, --prod)
  • GitHub Check: run-tests-on-macos (macos-latest)
  • GitHub Check: run-tests-on-macos (macos-latest, --prod)
  • GitHub Check: MegaLinter
🔇 Additional comments (1)
lapack/lapack_notd_vsl_lapack_lapacke.v (1)

163-167: Ignore return value consistency concern in dgeev_standardized

Upon inspection, both the direct dgeev wrapper and the dgeev_standardized wrapper rely on lapack64.dgeev returning an int error code. The explicit check in dgeev_standardized:

info := lapack64.dgeev(...)
return if info == 0 { 0 } else { info }

is functionally identical to returning info directly, so there’s no inconsistency between the two wrappers. No changes are required.

Likely an incorrect or invalid review comment.

Comment on lines +9 to +10
// A * X = B if trans == blas.Trans
// Aᵀ * X = B if trans == blas.NoTrans
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix transpose documentation - the logic appears reversed.

The documentation states that A * X = B if trans == blas.Trans, but typically in BLAS/LAPACK conventions, NoTrans means solve A * X = B and Trans means solve A^T * X = B.

Apply this diff to fix the documentation:

-//	A * X = B  if trans == blas.Trans
-//	Aᵀ * X = B if trans == blas.NoTrans
+//	A * X = B  if trans == blas.NoTrans
+//	Aᵀ * X = B if trans == blas.Trans
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// A * X = B if trans == blas.Trans
// Aᵀ * X = B if trans == blas.NoTrans
// A * X = B if trans == blas.NoTrans
// Aᵀ * X = B if trans == blas.Trans
🤖 Prompt for AI Agents
In lapack/lapack64/dgetrs.v around lines 9 to 10, the transpose documentation is
reversed. Update the comments to correctly state that A * X = B when trans ==
blas.NoTrans, and Aᵀ * X = B when trans == blas.Trans, aligning with standard
BLAS/LAPACK conventions.

Comment on lines +32 to +34
if ldb < math.max(1, nrhs) {
panic(bad_ld_b)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Incorrect validation for leading dimension of B.

The check for ldb should compare against the number of columns in B (nrhs), not rows.

Apply this diff to fix the validation:

-if ldb < math.max(1, nrhs) {
+if ldb < math.max(1, n) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if ldb < math.max(1, nrhs) {
panic(bad_ld_b)
}
if ldb < math.max(1, n) {
panic(bad_ld_b)
}
🤖 Prompt for AI Agents
In lapack/lapack64/dgetrs.v around lines 32 to 34, the validation for the
leading dimension ldb incorrectly compares ldb with the maximum of 1 and nrhs
(number of right-hand sides). The correct check should compare ldb against the
number of rows of B, which is n, not nrhs. Update the condition to panic if ldb
is less than max(1, n) instead of max(1, nrhs).

Comment on lines +12 to +14
} else if lda < math.max(1, n) {
panic(bad_ld_a)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix leading dimension validation.

For column-major storage, lda should be at least m, not n.

Apply this diff to fix the validation:

-} else if lda < math.max(1, n) {
+} else if lda < math.max(1, m) {
🤖 Prompt for AI Agents
In lapack/lapack64/dgetf2.v around lines 12 to 14, the leading dimension
validation incorrectly checks if lda is at least max(1, n), but for column-major
storage lda must be at least max(1, m). Change the condition to compare lda with
max(1, m) instead of max(1, n) to correctly validate the leading dimension.

import math
import vsl.blas

pub fn dgetf2(m int, n int, mut a []f64, lda int, mut ipiv []int) bool {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add function documentation.

The function lacks documentation explaining its purpose and parameters.

Add documentation before the function:

+// dgetf2 computes an LU factorization of a general m×n matrix A using
+// partial pivoting with row interchanges (unblocked algorithm).
+//
+// The factorization has the form
+//   A = P * L * U
+// where P is a permutation matrix, L is lower triangular with unit
+// diagonal elements (lower trapezoidal if m > n), and U is upper
+// triangular (upper trapezoidal if m < n).
+//
+// This is the unblocked version of the algorithm, suitable for small matrices.
 pub fn dgetf2(m int, n int, mut a []f64, lda int, mut ipiv []int) bool {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub fn dgetf2(m int, n int, mut a []f64, lda int, mut ipiv []int) bool {
// dgetf2 computes an LU factorization of a general m×n matrix A using
// partial pivoting with row interchanges (unblocked algorithm).
//
// The factorization has the form
// A = P * L * U
// where P is a permutation matrix, L is lower triangular with unit
// diagonal elements (lower trapezoidal if m > n), and U is upper
// triangular (upper trapezoidal if m < n).
//
// This is the unblocked version of the algorithm, suitable for small matrices.
pub fn dgetf2(m int, n int, mut a []f64, lda int, mut ipiv []int) bool {
🤖 Prompt for AI Agents
In lapack/lapack64/dgetf2.v at line 6, the function dgetf2 lacks documentation.
Add a comment block above the function definition describing its purpose, the
meaning of each parameter (m, n, a, lda, ipiv), and what the function returns.
This will improve code readability and maintainability.

Comment on lines +40 to +52
// Convert A from row-major to flat array
for i in 0 .. n {
for j in 0 .. n {
a_flat[i * n + j] = a[i][j]
}
}

// Convert B from row-major to flat array (row-major storage)
for i in 0 .. n {
for j in 0 .. nrhs {
b_flat[i * nrhs + j] = b[i][j]
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Critical: Incorrect matrix storage order for LAPACK.

The code flattens matrices in row-major order, but LAPACK expects column-major order. This will produce incorrect results.

Apply this diff to fix the storage order:

 // Convert A from row-major to flat array
 for i in 0 .. n {
     for j in 0 .. n {
-        a_flat[i * n + j] = a[i][j]
+        a_flat[j * n + i] = a[i][j]  // Column-major: column j, row i
     }
 }

 // Convert B from row-major to flat array (row-major storage)
 for i in 0 .. n {
     for j in 0 .. nrhs {
-        b_flat[i * nrhs + j] = b[i][j]
+        b_flat[j * n + i] = b[i][j]  // Column-major storage
     }
 }

Also update the reverse conversion:

 // Convert result back to row-major 2D arrays
 for i in 0 .. n {
     for j in 0 .. n {
-        a[i][j] = a_flat[i * n + j]
+        a[i][j] = a_flat[j * n + i]
     }
 }

 for i in 0 .. n {
     for j in 0 .. nrhs {
-        b[i][j] = b_flat[i * nrhs + j]
+        b[i][j] = b_flat[j * n + i]
     }
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In lapack/lapack_wrappers.v around lines 40 to 52, the matrices A and B are
flattened using row-major order, but LAPACK requires column-major order. To fix
this, change the indexing in the loops so that elements are stored column-wise:
for A, assign a_flat[j * n + i] = a[i][j], and for B, assign b_flat[j * nrhs +
i] = b[i][j]. Additionally, update the code that converts the flat arrays back
to 2D matrices to use column-major order indexing accordingly.

Comment on lines +169 to +174
// dgeqrf_standardized - Standardized dgeqrf wrapper (placeholder until implemented)
@[inline]
pub fn dgeqrf_standardized(m int, n int, mut a []f64, lda int, mut tau []f64) int {
// Placeholder - not implemented in lapack64 yet
return -1 // Indicate not implemented
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve placeholder function implementation.

The placeholder functions for dgeqrf return -1 to indicate "not implemented". Consider using a more robust approach such as:

  • Returning a proper LAPACK error code
  • Using a panic with a descriptive message
  • Implementing a feature flag system
-pub fn dgeqrf_standardized(m int, n int, mut a []f64, lda int, mut tau []f64) int {
-	// Placeholder - not implemented in lapack64 yet
-	return -1 // Indicate not implemented
-}
+pub fn dgeqrf_standardized(m int, n int, mut a []f64, lda int, mut tau []f64) int {
+	errors.vsl_panic('dgeqrf is not yet implemented in lapack64 backend', .efailed)
+}
-pub fn dgeqrf(m int, n int, mut a []f64, lda int, mut tau []f64) int {
-	// dgeqrf is not implemented in lapack64 yet
-	return -1 // Indicate not implemented
-}
+pub fn dgeqrf(m int, n int, mut a []f64, lda int, mut tau []f64) int {
+	errors.vsl_panic('dgeqrf is not yet implemented in lapack64 backend', .efailed)
+}

Also applies to: 194-199

🤖 Prompt for AI Agents
In lapack/lapack_notd_vsl_lapack_lapacke.v around lines 169 to 174 and 194 to
199, the placeholder functions for dgeqrf return -1 to indicate "not
implemented," which is not robust. Replace the return value with either a proper
LAPACK error code that clearly signals the function is unimplemented or use a
panic with a descriptive message explaining the function is not yet implemented.
Alternatively, implement a feature flag system to conditionally enable or
disable these placeholders. This will improve error handling and clarity.

Comment on lines +176 to +182
// dorgqr_standardized - Standardized dorgqr wrapper
@[inline]
pub fn dorgqr_standardized(m int, n int, k int, mut a []f64, lda int, tau []f64) int {
mut work := []f64{len: math.max(1, n)}
lapack64.dorgqr(m, n, k, mut a, lda, tau, mut work, work.len)
return 0 // lapack64.dorgqr doesn't return error code
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consolidate duplicate dorgqr implementations.

Both dorgqr_standardized and dorgqr have identical implementations with the same work array management logic. This creates maintenance overhead and potential for inconsistency.

Consider implementing one function that calls the other:

 pub fn dorgqr_standardized(m int, n int, k int, mut a []f64, lda int, tau []f64) int {
-	mut work := []f64{len: math.max(1, n)}
-	lapack64.dorgqr(m, n, k, mut a, lda, tau, mut work, work.len)
-	return 0 // lapack64.dorgqr doesn't return error code
+	return dorgqr(m, n, k, mut a, lda, tau)
 }

Also applies to: 201-208

🤖 Prompt for AI Agents
In lapack/lapack_notd_vsl_lapack_lapacke.v around lines 176 to 182 and also 201
to 208, the functions dorgqr_standardized and dorgqr have duplicate
implementations including the work array setup. To fix this, consolidate by
implementing only one of these functions with the full logic and have the other
function simply call it, passing through all parameters. This reduces
maintenance overhead and ensures consistency.

Comment on lines +152 to +159
// dsyev_standardized - Standardized dsyev wrapper
@[inline]
pub fn dsyev_standardized(jobz EigenVectorsJob, uplo blas.Uplo, n int, mut a []f64, lda int, mut w []f64) int {
mut work := []f64{len: math.max(1, 3 * n - 1)}
lapack64.dsyev(to_lapack64_eigen_vectors_job(jobz), uplo, n, mut a, lda, mut w, mut
work, work.len)
return 0 // lapack64 functions don't return error codes
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consolidate duplicate dsyev implementations.

Both dsyev_standardized and dsyev have identical implementations with the same work array management logic. This creates maintenance overhead and potential for inconsistency.

Consider implementing one function that calls the other:

 pub fn dsyev_standardized(jobz EigenVectorsJob, uplo blas.Uplo, n int, mut a []f64, lda int, mut w []f64) int {
-	mut work := []f64{len: math.max(1, 3 * n - 1)}
-	lapack64.dsyev(to_lapack64_eigen_vectors_job(jobz), uplo, n, mut a, lda, mut w, mut
-		work, work.len)
-	return 0 // lapack64 functions don't return error codes
+	return dsyev(jobz, uplo, n, mut a, lda, mut w)
 }

Also applies to: 184-192

🤖 Prompt for AI Agents
In lapack/lapack_notd_vsl_lapack_lapacke.v around lines 152 to 159 and similarly
at lines 184 to 192, the functions dsyev_standardized and dsyev have duplicate
implementations including identical work array management. To fix this, refactor
by consolidating these two functions into one core implementation and have the
other function call it, eliminating duplicate code and reducing maintenance
overhead.

//
// NOTE: matrix 'a' will be modified
@[inline]
pub fn dgesv(n int, nrhs int, mut a []f64, lda int, mut ipiv []int, mut b []f64, ldb int) int {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add input validation for critical parameters.

The wrapper functions lack input validation for critical parameters like matrix dimensions, leading dimensions, and array lengths. This could lead to undefined behavior or segmentation faults.

Consider adding validation for key parameters:

 pub fn dgesv(n int, nrhs int, mut a []f64, lda int, mut ipiv []int, mut b []f64, ldb int) int {
+	if n < 0 || nrhs < 0 || lda < math.max(1, n) || ldb < math.max(1, n) {
+		errors.vsl_panic('Invalid matrix dimensions in dgesv', .efailed)
+	}
+	if a.len < lda * n || b.len < ldb * nrhs || ipiv.len < n {
+		errors.vsl_panic('Insufficient array lengths in dgesv', .efailed)
+	}
 	return lapack64.dgesv(n, nrhs, mut a, lda, mut ipiv, mut b, ldb)
 }

Also applies to: 76-76, 89-89, 110-110, 137-137

🤖 Prompt for AI Agents
In lapack/lapack_notd_vsl_lapack_lapacke.v at line 31 and similarly at lines 76,
89, 110, and 137, the wrapper functions lack input validation for critical
parameters such as matrix dimensions, leading dimensions, and array lengths. Add
checks at the start of each function to verify that parameters like n, nrhs,
lda, ldb are positive and that the lengths of arrays a, ipiv, and b are
sufficient for the given dimensions. Return an error code or handle invalid
inputs gracefully to prevent undefined behavior or segmentation faults.

Comment on lines +145 to +150
// dpotrf_standardized - Standardized dpotrf wrapper
@[inline]
pub fn dpotrf_standardized(uplo blas.Uplo, n int, mut a []f64, lda int) int {
info := lapack64.dpotrf(uplo, n, mut a, lda)
return if info { 0 } else { 1 }
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove redundant standardized wrapper for dpotrf.

The dpotrf_standardized function is identical to the existing dpotrf function (lines 110-112), creating unnecessary code duplication.

-// dpotrf_standardized - Standardized dpotrf wrapper
-@[inline]
-pub fn dpotrf_standardized(uplo blas.Uplo, n int, mut a []f64, lda int) int {
-	info := lapack64.dpotrf(uplo, n, mut a, lda)
-	return if info { 0 } else { 1 }
-}

Consider using a single implementation or clearly differentiate the purpose of each wrapper.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// dpotrf_standardized - Standardized dpotrf wrapper
@[inline]
pub fn dpotrf_standardized(uplo blas.Uplo, n int, mut a []f64, lda int) int {
info := lapack64.dpotrf(uplo, n, mut a, lda)
return if info { 0 } else { 1 }
}
🤖 Prompt for AI Agents
In lapack/lapack_notd_vsl_lapack_lapacke.v around lines 145 to 150, the
dpotrf_standardized function duplicates the existing dpotrf function (lines
110-112) without any difference. Remove the dpotrf_standardized wrapper entirely
to eliminate redundant code and rely on the existing dpotrf function instead.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (5)
lapack/lapack_notd_vsl_lapack_lapacke.v (5)

149-154: Remove redundant dpotrf_standardized function.

This function is identical to the existing dpotrf function (lines 114-116), creating unnecessary code duplication.

-// dpotrf_standardized - Standardized dpotrf wrapper
-@[inline]
-pub fn dpotrf_standardized(uplo blas.Uplo, n int, mut a []f64, lda int) int {
-	info := lapack64.dpotrf(uplo, n, mut a, lda)
-	return if info { 0 } else { 1 }
-}

156-163: Consolidate duplicate dsyev implementations.

Both dsyev_standardized and dsyev have identical implementations with the same work array management logic. This creates maintenance overhead and potential for inconsistency.

Consider implementing one function that calls the other:

 pub fn dsyev_standardized(jobz EigenVectorsJob, uplo blas.Uplo, n int, mut a []f64, lda int, mut w []f64) int {
-	mut work := []f64{len: math.max(1, 3 * n - 1)}
-	lapack64.dsyev(to_lapack64_eigen_vectors_job(jobz), uplo, n, mut a, lda, mut w, mut
-		work, work.len)
-	return 0 // lapack64 functions don't return error codes
+	return dsyev(jobz, uplo, n, mut a, lda, mut w)
 }

Also applies to: 188-196


180-186: Consolidate duplicate dorgqr implementations.

Both dorgqr_standardized and dorgqr have identical implementations with the same work array management logic. This creates maintenance overhead and potential for inconsistency.

Consider implementing one function that calls the other:

 pub fn dorgqr_standardized(m int, n int, k int, mut a []f64, lda int, tau []f64) int {
-	mut work := []f64{len: math.max(1, n)}
-	lapack64.dorgqr(m, n, k, mut a, lda, tau, mut work, work.len)
-	return 0 // lapack64.dorgqr doesn't return error code
+	return dorgqr(m, n, k, mut a, lda, tau)
 }

Also applies to: 205-212


173-178: Improve placeholder function implementation.

The placeholder functions for dgeqrf return -1 to indicate "not implemented". Consider using a more robust approach such as using a panic with a descriptive message.

-pub fn dgeqrf_standardized(m int, n int, mut a []f64, lda int, mut tau []f64) int {
-	// Placeholder - not implemented in lapack64 yet
-	return -1 // Indicate not implemented
-}
+pub fn dgeqrf_standardized(m int, n int, mut a []f64, lda int, mut tau []f64) int {
+	errors.vsl_panic('dgeqrf is not yet implemented in lapack64 backend', .efailed)
+}
-pub fn dgeqrf(m int, n int, mut a []f64, lda int, mut tau []f64) int {
-	// dgeqrf is not implemented in lapack64 yet
-	return -1 // Indicate not implemented
-}
+pub fn dgeqrf(m int, n int, mut a []f64, lda int, mut tau []f64) int {
+	errors.vsl_panic('dgeqrf is not yet implemented in lapack64 backend', .efailed)
+}

Also applies to: 198-203


31-33: Add input validation for critical parameters.

The wrapper functions lack input validation for critical parameters like matrix dimensions, leading dimensions, and array lengths. This could lead to undefined behavior or segmentation faults.

Consider adding validation for key parameters:

 pub fn dgesv(n int, nrhs int, mut a []f64, lda int, mut ipiv []int, mut b []f64, ldb int) int {
+	if n < 0 || nrhs < 0 || lda < math.max(1, n) || ldb < math.max(1, n) {
+		errors.vsl_panic('Invalid matrix dimensions in dgesv', .efailed)
+	}
+	if a.len < lda * n || b.len < ldb * nrhs || ipiv.len < n {
+		errors.vsl_panic('Insufficient array lengths in dgesv', .efailed)
+	}
 	return lapack64.dgesv(n, nrhs, mut a, lda, mut ipiv, mut b, ldb)
 }

Also applies to: 76-83, 94-95, 114-116, 141-144

🧹 Nitpick comments (2)
lapack/lapack64/dgetri_test.v (1)

70-72: Consider using existing math library functions.

The custom abs function is redundant since V's math module already provides math.abs() function.

-fn abs(x f64) f64 {
-	return if x < 0 { -x } else { x }
-}
+// Use math.abs() instead of custom abs function

And update the usage:

-	assert abs(a[i] - expected[i]) < 1e-10, 'identity inverse should be identity'
+	assert math.abs(a[i] - expected[i]) < 1e-10, 'identity inverse should be identity'
lapack/lapack64/dpotrf_test.v (1)

88-90: Consider using existing math library functions.

The custom abs function is redundant since V's math module already provides math.abs() function.

-fn abs(x f64) f64 {
-	return if x < 0 { -x } else { x }
-}
+// Use math.abs() instead of custom abs function

And update the usage:

-	assert abs(reconstructed[i] - expected[i]) < 1e-8, 'reconstruction error at ${i}: ${diff}'
+	assert math.abs(reconstructed[i] - expected[i]) < 1e-8, 'reconstruction error at ${i}: ${diff}'
-	assert abs(a[i] - expected[i]) < 1e-10, 'identity Cholesky should be identity'
+	assert math.abs(a[i] - expected[i]) < 1e-10, 'identity Cholesky should be identity'
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e3095b8 and d790038.

📒 Files selected for processing (6)
  • lapack/lapack64/dgetf2.v (1 hunks)
  • lapack/lapack64/dgetrf.v (1 hunks)
  • lapack/lapack64/dgetrf_test.v (1 hunks)
  • lapack/lapack64/dgetri_test.v (1 hunks)
  • lapack/lapack64/dpotrf_test.v (1 hunks)
  • lapack/lapack_notd_vsl_lapack_lapacke.v (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • lapack/lapack64/dgetrf.v
  • lapack/lapack64/dgetf2.v
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: run-tests-on-linux (ubuntu-24.04, --prod)
  • GitHub Check: run-tests-on-linux (ubuntu-22.04, --prod)
  • GitHub Check: run-tests-on-macos (macos-latest)
  • GitHub Check: run-tests-on-macos (macos-latest, --prod)
  • GitHub Check: MegaLinter
  • GitHub Check: docs
  • GitHub Check: MegaLinter
🔇 Additional comments (7)
lapack/lapack64/dgetri_test.v (2)

3-45: LGTM! Good test structure with comprehensive validation.

The test correctly follows the two-step process of LU factorization followed by matrix inversion. The debug output and assertions provide good validation of the results.


47-68: LGTM! Excellent edge case testing with identity matrix.

Using the identity matrix as a test case is a smart approach since the inverse of an identity matrix should remain the identity matrix. The numerical tolerance check is appropriate.

lapack/lapack64/dgetrf_test.v (3)

5-44: LGTM! Comprehensive test with good matrix handling.

The test correctly converts from 2D array to flat array format and includes proper validation of pivot indices. The debug output helps with troubleshooting.


46-62: LGTM! Excellent singular matrix edge case testing.

Testing with a singular matrix (where row 2 is 2x row 1) is crucial for validating error handling. The test correctly expects the function to return false without panicking.


64-88: LGTM! Good additional test case for validation.

The test provides another matrix case to ensure the LU factorization works correctly across different inputs. The debug output format is consistent with other tests.

lapack/lapack64/dpotrf_test.v (2)

5-68: LGTM! Excellent test with mathematical verification.

The test not only calls the Cholesky factorization but also reconstructs the original matrix by computing U^T * U to verify correctness. The mathematical approach is sound and the numerical tolerance is appropriate.


70-86: LGTM! Good edge case testing with identity matrix.

Using the identity matrix as a test case is appropriate since the Cholesky factorization of an identity matrix should remain the identity matrix. The test verifies this correctly.

* 'main' of github.com:vlang/vsl:
  noise: respect new wyhash v4.2 (#230)
  prepare for the fix for rand.shuffle in vlang/v#25617
  fix warnings for examples/gm_spatial_binning/main.v
  fix warnings and notices for examples/plot_radar_performance/main.v
  remove unused `import json` in examples/plot_violin_distributions/main.v
  fix plot show test mode (#228)
  add `// vtest retry: 3` to three_d_test.v too, to prevent false positives on the CI of the main V repo
  add `// vtest retry: 3` to readhdf5_test.v to prevent false positives on the CI of the main V repo
- Updated README.md to highlight the temporary skipping of the pure-V QR path tests and recommend using C backends for QR correctness.
- Modified BLAS tests to clarify that input matrices are expected in row-major format, aligning with the API expectations.
- Introduced new column-major BLAS functions to support column-major operations.
- Updated LAPACK wrappers to handle row-major to column-major conversions for various functions, ensuring compatibility with the new BLAS structure.
- Added error handling and validation for LAPACK functions to ensure proper input dimensions and formats.
- Implemented additional LAPACK functions for matrix operations, including dgeqrf and dgetri, with appropriate memory management and error checking.
- Updated README.md to highlight the temporary skipping of the pure-V QR path tests and recommend using C backends for QR correctness.
- Modified BLAS tests to clarify that input matrices are expected in row-major format, aligning with the API expectations.
- Introduced new column-major BLAS functions to support column-major operations.
- Updated LAPACK wrappers to handle row-major to column-major conversions for various functions, ensuring compatibility with the new BLAS structure.
- Added error handling and validation for LAPACK functions to ensure proper input dimensions and formats.
- Implemented additional LAPACK functions for matrix operations, including dgeqrf and dgetri, with appropriate memory management and error checking.
@ulises-jeremias ulises-jeremias merged commit 6654ef4 into main Dec 28, 2025
3 of 10 checks passed
@ulises-jeremias ulises-jeremias deleted the feature/new-lapack branch December 28, 2025 06:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant