From 61813ca376efa9e1fd796c6d9856cc1cbc486500 Mon Sep 17 00:00:00 2001 From: Michel Pelletier Date: Tue, 7 Apr 2026 13:55:23 -0700 Subject: [PATCH 1/5] Complete element setter/getter functional API for all GraphBLAS types Previously matrix.py, vector.py, and scalar.py only exposed `set_bool` and `bool` functions for accessing elements, even though SuiteSparse:GraphBLAS supports many more types. This fills out the functional API to cover every type the C library supports, following the existing `set_bool` / `bool` pattern exactly. Adds setter/getter pairs for: int8, int16, int32, int64, uint8, uint16, uint32, uint64, fp32, fp64, fc32, fc64. The complex types (fc32, fc64) are gated on `supports_complex()` so the functions are only defined on builds compiled with SuiteSparse complex support enabled (fc32/fc64 are GxB extensions, and the standard suitesparse.sh build disables them via GxB_NO_FC32 / GxB_NO_FC64). Each new function carries a doctest that round-trips a value through its setter and getter. Doctest counts after this change: matrix: 97 attempted, 0 failed vector: 90 attempted, 0 failed scalar: 81 attempted, 0 failed total: 268 attempted, 0 failed --- suitesparse_graphblas/matrix.py | 313 ++++++++++++++++++++++++++++- suitesparse_graphblas/scalar.py | 337 +++++++++++++++++++++++++++++++- suitesparse_graphblas/vector.py | 313 ++++++++++++++++++++++++++++- 3 files changed, 960 insertions(+), 3 deletions(-) diff --git a/suitesparse_graphblas/matrix.py b/suitesparse_graphblas/matrix.py index 5efa15d..9f8d10a 100644 --- a/suitesparse_graphblas/matrix.py +++ b/suitesparse_graphblas/matrix.py @@ -1,4 +1,4 @@ -from suitesparse_graphblas import check_status, ffi, lib +from suitesparse_graphblas import check_status, ffi, lib, supports_complex from .io.serialize import deserialize_matrix as deserialize # noqa: F401 from .io.serialize import serialize_matrix as serialize # noqa: F401 @@ -200,3 +200,314 @@ def bool(A, i, j): value = ffi.new("bool*") check_status(A, lib.GrB_Matrix_extractElement_BOOL(value, A[0], i, j)) return value[0] + + +def set_int8(A, value, i, j): + """Set an int8 value to the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_INT8, 3, 3) + >>> set_int8(A, 7, 2, 2) + >>> int8(A, 2, 2) == 7 + True + + """ + check_status(A, lib.GrB_Matrix_setElement_INT8(A[0], value, i, j)) + + +def int8(A, i, j): + """Get an int8 value from the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_INT8, 3, 3) + >>> set_int8(A, 7, 2, 2) + >>> int8(A, 2, 2) == 7 + True + + """ + value = ffi.new("int8_t*") + check_status(A, lib.GrB_Matrix_extractElement_INT8(value, A[0], i, j)) + return value[0] + + +def set_int16(A, value, i, j): + """Set an int16 value to the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_INT16, 3, 3) + >>> set_int16(A, 7, 2, 2) + >>> int16(A, 2, 2) == 7 + True + + """ + check_status(A, lib.GrB_Matrix_setElement_INT16(A[0], value, i, j)) + + +def int16(A, i, j): + """Get an int16 value from the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_INT16, 3, 3) + >>> set_int16(A, 7, 2, 2) + >>> int16(A, 2, 2) == 7 + True + + """ + value = ffi.new("int16_t*") + check_status(A, lib.GrB_Matrix_extractElement_INT16(value, A[0], i, j)) + return value[0] + + +def set_int32(A, value, i, j): + """Set an int32 value to the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_INT32, 3, 3) + >>> set_int32(A, 7, 2, 2) + >>> int32(A, 2, 2) == 7 + True + + """ + check_status(A, lib.GrB_Matrix_setElement_INT32(A[0], value, i, j)) + + +def int32(A, i, j): + """Get an int32 value from the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_INT32, 3, 3) + >>> set_int32(A, 7, 2, 2) + >>> int32(A, 2, 2) == 7 + True + + """ + value = ffi.new("int32_t*") + check_status(A, lib.GrB_Matrix_extractElement_INT32(value, A[0], i, j)) + return value[0] + + +def set_int64(A, value, i, j): + """Set an int64 value to the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_INT64, 3, 3) + >>> set_int64(A, 7, 2, 2) + >>> int64(A, 2, 2) == 7 + True + + """ + check_status(A, lib.GrB_Matrix_setElement_INT64(A[0], value, i, j)) + + +def int64(A, i, j): + """Get an int64 value from the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_INT64, 3, 3) + >>> set_int64(A, 7, 2, 2) + >>> int64(A, 2, 2) == 7 + True + + """ + value = ffi.new("int64_t*") + check_status(A, lib.GrB_Matrix_extractElement_INT64(value, A[0], i, j)) + return value[0] + + +def set_uint8(A, value, i, j): + """Set a uint8 value to the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_UINT8, 3, 3) + >>> set_uint8(A, 7, 2, 2) + >>> uint8(A, 2, 2) == 7 + True + + """ + check_status(A, lib.GrB_Matrix_setElement_UINT8(A[0], value, i, j)) + + +def uint8(A, i, j): + """Get a uint8 value from the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_UINT8, 3, 3) + >>> set_uint8(A, 7, 2, 2) + >>> uint8(A, 2, 2) == 7 + True + + """ + value = ffi.new("uint8_t*") + check_status(A, lib.GrB_Matrix_extractElement_UINT8(value, A[0], i, j)) + return value[0] + + +def set_uint16(A, value, i, j): + """Set a uint16 value to the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_UINT16, 3, 3) + >>> set_uint16(A, 7, 2, 2) + >>> uint16(A, 2, 2) == 7 + True + + """ + check_status(A, lib.GrB_Matrix_setElement_UINT16(A[0], value, i, j)) + + +def uint16(A, i, j): + """Get a uint16 value from the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_UINT16, 3, 3) + >>> set_uint16(A, 7, 2, 2) + >>> uint16(A, 2, 2) == 7 + True + + """ + value = ffi.new("uint16_t*") + check_status(A, lib.GrB_Matrix_extractElement_UINT16(value, A[0], i, j)) + return value[0] + + +def set_uint32(A, value, i, j): + """Set a uint32 value to the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_UINT32, 3, 3) + >>> set_uint32(A, 7, 2, 2) + >>> uint32(A, 2, 2) == 7 + True + + """ + check_status(A, lib.GrB_Matrix_setElement_UINT32(A[0], value, i, j)) + + +def uint32(A, i, j): + """Get a uint32 value from the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_UINT32, 3, 3) + >>> set_uint32(A, 7, 2, 2) + >>> uint32(A, 2, 2) == 7 + True + + """ + value = ffi.new("uint32_t*") + check_status(A, lib.GrB_Matrix_extractElement_UINT32(value, A[0], i, j)) + return value[0] + + +def set_uint64(A, value, i, j): + """Set a uint64 value to the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_UINT64, 3, 3) + >>> set_uint64(A, 7, 2, 2) + >>> uint64(A, 2, 2) == 7 + True + + """ + check_status(A, lib.GrB_Matrix_setElement_UINT64(A[0], value, i, j)) + + +def uint64(A, i, j): + """Get a uint64 value from the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_UINT64, 3, 3) + >>> set_uint64(A, 7, 2, 2) + >>> uint64(A, 2, 2) == 7 + True + + """ + value = ffi.new("uint64_t*") + check_status(A, lib.GrB_Matrix_extractElement_UINT64(value, A[0], i, j)) + return value[0] + + +def set_fp32(A, value, i, j): + """Set an fp32 value to the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_FP32, 3, 3) + >>> set_fp32(A, 1.5, 2, 2) + >>> fp32(A, 2, 2) == 1.5 + True + + """ + check_status(A, lib.GrB_Matrix_setElement_FP32(A[0], value, i, j)) + + +def fp32(A, i, j): + """Get an fp32 value from the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_FP32, 3, 3) + >>> set_fp32(A, 1.5, 2, 2) + >>> fp32(A, 2, 2) == 1.5 + True + + """ + value = ffi.new("float*") + check_status(A, lib.GrB_Matrix_extractElement_FP32(value, A[0], i, j)) + return value[0] + + +def set_fp64(A, value, i, j): + """Set an fp64 value to the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_FP64, 3, 3) + >>> set_fp64(A, 1.5, 2, 2) + >>> fp64(A, 2, 2) == 1.5 + True + + """ + check_status(A, lib.GrB_Matrix_setElement_FP64(A[0], value, i, j)) + + +def fp64(A, i, j): + """Get an fp64 value from the matrix at row `i` column `j`. + + >>> A = new(lib.GrB_FP64, 3, 3) + >>> set_fp64(A, 1.5, 2, 2) + >>> fp64(A, 2, 2) == 1.5 + True + + """ + value = ffi.new("double*") + check_status(A, lib.GrB_Matrix_extractElement_FP64(value, A[0], i, j)) + return value[0] + + +if supports_complex(): + + def set_fc32(A, value, i, j): + """Set an fc32 value to the matrix at row `i` column `j`. + + >>> A = new(lib.GxB_FC32, 3, 3) + >>> set_fc32(A, 2+3j, 2, 2) + >>> fc32(A, 2, 2) == 2+3j + True + + """ + check_status(A, lib.GxB_Matrix_setElement_FC32(A[0], value, i, j)) + + def fc32(A, i, j): + """Get an fc32 value from the matrix at row `i` column `j`. + + >>> A = new(lib.GxB_FC32, 3, 3) + >>> set_fc32(A, 2+3j, 2, 2) + >>> fc32(A, 2, 2) == 2+3j + True + + """ + value = ffi.new("GxB_FC32_t*") + check_status(A, lib.GxB_Matrix_extractElement_FC32(value, A[0], i, j)) + return value[0] + + def set_fc64(A, value, i, j): + """Set an fc64 value to the matrix at row `i` column `j`. + + >>> A = new(lib.GxB_FC64, 3, 3) + >>> set_fc64(A, 2+3j, 2, 2) + >>> fc64(A, 2, 2) == 2+3j + True + + """ + check_status(A, lib.GxB_Matrix_setElement_FC64(A[0], value, i, j)) + + def fc64(A, i, j): + """Get an fc64 value from the matrix at row `i` column `j`. + + >>> A = new(lib.GxB_FC64, 3, 3) + >>> set_fc64(A, 2+3j, 2, 2) + >>> fc64(A, 2, 2) == 2+3j + True + + """ + value = ffi.new("GxB_FC64_t*") + check_status(A, lib.GxB_Matrix_extractElement_FC64(value, A[0], i, j)) + return value[0] diff --git a/suitesparse_graphblas/scalar.py b/suitesparse_graphblas/scalar.py index c0d5747..e072a8f 100644 --- a/suitesparse_graphblas/scalar.py +++ b/suitesparse_graphblas/scalar.py @@ -1,4 +1,4 @@ -from suitesparse_graphblas import check_status, exceptions, ffi, lib +from suitesparse_graphblas import check_status, exceptions, ffi, lib, supports_complex def free(v): @@ -63,3 +63,338 @@ def bool(s): if res == exceptions.NoValue: return None return value[0] + + +def set_int8(s, value): + """Set an int8 value to the scalar. + + >>> s = new(lib.GrB_INT8) + >>> set_int8(s, 7) + >>> int8(s) == 7 + True + + """ + check_status(s, lib.GxB_Scalar_setElement_INT8(s[0], value)) + + +def int8(s): + """Get an int8 value from the scalar. + + >>> s = new(lib.GrB_INT8) + >>> set_int8(s, 7) + >>> int8(s) == 7 + True + + """ + value = ffi.new("int8_t*") + res = check_status(s, lib.GxB_Scalar_extractElement_INT8(value, s[0])) + if res == exceptions.NoValue: + return None + return value[0] + + +def set_int16(s, value): + """Set an int16 value to the scalar. + + >>> s = new(lib.GrB_INT16) + >>> set_int16(s, 7) + >>> int16(s) == 7 + True + + """ + check_status(s, lib.GxB_Scalar_setElement_INT16(s[0], value)) + + +def int16(s): + """Get an int16 value from the scalar. + + >>> s = new(lib.GrB_INT16) + >>> set_int16(s, 7) + >>> int16(s) == 7 + True + + """ + value = ffi.new("int16_t*") + res = check_status(s, lib.GxB_Scalar_extractElement_INT16(value, s[0])) + if res == exceptions.NoValue: + return None + return value[0] + + +def set_int32(s, value): + """Set an int32 value to the scalar. + + >>> s = new(lib.GrB_INT32) + >>> set_int32(s, 7) + >>> int32(s) == 7 + True + + """ + check_status(s, lib.GxB_Scalar_setElement_INT32(s[0], value)) + + +def int32(s): + """Get an int32 value from the scalar. + + >>> s = new(lib.GrB_INT32) + >>> set_int32(s, 7) + >>> int32(s) == 7 + True + + """ + value = ffi.new("int32_t*") + res = check_status(s, lib.GxB_Scalar_extractElement_INT32(value, s[0])) + if res == exceptions.NoValue: + return None + return value[0] + + +def set_int64(s, value): + """Set an int64 value to the scalar. + + >>> s = new(lib.GrB_INT64) + >>> set_int64(s, 7) + >>> int64(s) == 7 + True + + """ + check_status(s, lib.GxB_Scalar_setElement_INT64(s[0], value)) + + +def int64(s): + """Get an int64 value from the scalar. + + >>> s = new(lib.GrB_INT64) + >>> set_int64(s, 7) + >>> int64(s) == 7 + True + + """ + value = ffi.new("int64_t*") + res = check_status(s, lib.GxB_Scalar_extractElement_INT64(value, s[0])) + if res == exceptions.NoValue: + return None + return value[0] + + +def set_uint8(s, value): + """Set a uint8 value to the scalar. + + >>> s = new(lib.GrB_UINT8) + >>> set_uint8(s, 7) + >>> uint8(s) == 7 + True + + """ + check_status(s, lib.GxB_Scalar_setElement_UINT8(s[0], value)) + + +def uint8(s): + """Get a uint8 value from the scalar. + + >>> s = new(lib.GrB_UINT8) + >>> set_uint8(s, 7) + >>> uint8(s) == 7 + True + + """ + value = ffi.new("uint8_t*") + res = check_status(s, lib.GxB_Scalar_extractElement_UINT8(value, s[0])) + if res == exceptions.NoValue: + return None + return value[0] + + +def set_uint16(s, value): + """Set a uint16 value to the scalar. + + >>> s = new(lib.GrB_UINT16) + >>> set_uint16(s, 7) + >>> uint16(s) == 7 + True + + """ + check_status(s, lib.GxB_Scalar_setElement_UINT16(s[0], value)) + + +def uint16(s): + """Get a uint16 value from the scalar. + + >>> s = new(lib.GrB_UINT16) + >>> set_uint16(s, 7) + >>> uint16(s) == 7 + True + + """ + value = ffi.new("uint16_t*") + res = check_status(s, lib.GxB_Scalar_extractElement_UINT16(value, s[0])) + if res == exceptions.NoValue: + return None + return value[0] + + +def set_uint32(s, value): + """Set a uint32 value to the scalar. + + >>> s = new(lib.GrB_UINT32) + >>> set_uint32(s, 7) + >>> uint32(s) == 7 + True + + """ + check_status(s, lib.GxB_Scalar_setElement_UINT32(s[0], value)) + + +def uint32(s): + """Get a uint32 value from the scalar. + + >>> s = new(lib.GrB_UINT32) + >>> set_uint32(s, 7) + >>> uint32(s) == 7 + True + + """ + value = ffi.new("uint32_t*") + res = check_status(s, lib.GxB_Scalar_extractElement_UINT32(value, s[0])) + if res == exceptions.NoValue: + return None + return value[0] + + +def set_uint64(s, value): + """Set a uint64 value to the scalar. + + >>> s = new(lib.GrB_UINT64) + >>> set_uint64(s, 7) + >>> uint64(s) == 7 + True + + """ + check_status(s, lib.GxB_Scalar_setElement_UINT64(s[0], value)) + + +def uint64(s): + """Get a uint64 value from the scalar. + + >>> s = new(lib.GrB_UINT64) + >>> set_uint64(s, 7) + >>> uint64(s) == 7 + True + + """ + value = ffi.new("uint64_t*") + res = check_status(s, lib.GxB_Scalar_extractElement_UINT64(value, s[0])) + if res == exceptions.NoValue: + return None + return value[0] + + +def set_fp32(s, value): + """Set an fp32 value to the scalar. + + >>> s = new(lib.GrB_FP32) + >>> set_fp32(s, 1.5) + >>> fp32(s) == 1.5 + True + + """ + check_status(s, lib.GxB_Scalar_setElement_FP32(s[0], value)) + + +def fp32(s): + """Get an fp32 value from the scalar. + + >>> s = new(lib.GrB_FP32) + >>> set_fp32(s, 1.5) + >>> fp32(s) == 1.5 + True + + """ + value = ffi.new("float*") + res = check_status(s, lib.GxB_Scalar_extractElement_FP32(value, s[0])) + if res == exceptions.NoValue: + return None + return value[0] + + +def set_fp64(s, value): + """Set an fp64 value to the scalar. + + >>> s = new(lib.GrB_FP64) + >>> set_fp64(s, 1.5) + >>> fp64(s) == 1.5 + True + + """ + check_status(s, lib.GxB_Scalar_setElement_FP64(s[0], value)) + + +def fp64(s): + """Get an fp64 value from the scalar. + + >>> s = new(lib.GrB_FP64) + >>> set_fp64(s, 1.5) + >>> fp64(s) == 1.5 + True + + """ + value = ffi.new("double*") + res = check_status(s, lib.GxB_Scalar_extractElement_FP64(value, s[0])) + if res == exceptions.NoValue: + return None + return value[0] + + +if supports_complex(): + + def set_fc32(s, value): + """Set an fc32 value to the scalar. + + >>> s = new(lib.GxB_FC32) + >>> set_fc32(s, 2+3j) + >>> fc32(s) == 2+3j + True + + """ + check_status(s, lib.GxB_Scalar_setElement_FC32(s[0], value)) + + def fc32(s): + """Get an fc32 value from the scalar. + + >>> s = new(lib.GxB_FC32) + >>> set_fc32(s, 2+3j) + >>> fc32(s) == 2+3j + True + + """ + value = ffi.new("GxB_FC32_t*") + res = check_status(s, lib.GxB_Scalar_extractElement_FC32(value, s[0])) + if res == exceptions.NoValue: + return None + return value[0] + + def set_fc64(s, value): + """Set an fc64 value to the scalar. + + >>> s = new(lib.GxB_FC64) + >>> set_fc64(s, 2+3j) + >>> fc64(s) == 2+3j + True + + """ + check_status(s, lib.GxB_Scalar_setElement_FC64(s[0], value)) + + def fc64(s): + """Get an fc64 value from the scalar. + + >>> s = new(lib.GxB_FC64) + >>> set_fc64(s, 2+3j) + >>> fc64(s) == 2+3j + True + + """ + value = ffi.new("GxB_FC64_t*") + res = check_status(s, lib.GxB_Scalar_extractElement_FC64(value, s[0])) + if res == exceptions.NoValue: + return None + return value[0] diff --git a/suitesparse_graphblas/vector.py b/suitesparse_graphblas/vector.py index a6a15c6..412b9da 100644 --- a/suitesparse_graphblas/vector.py +++ b/suitesparse_graphblas/vector.py @@ -1,4 +1,4 @@ -from suitesparse_graphblas import check_status, ffi, lib +from suitesparse_graphblas import check_status, ffi, lib, supports_complex from .io.serialize import deserialize_vector as deserialize # noqa: F401 from .io.serialize import serialize_vector as serialize # noqa: F401 @@ -101,3 +101,314 @@ def bool(v, i): value = ffi.new("bool*") check_status(v, lib.GrB_Vector_extractElement_BOOL(value, v[0], i)) return value[0] + + +def set_int8(v, value, i): + """Set an int8 value to the vector at position `i`. + + >>> v = new(lib.GrB_INT8, 3) + >>> set_int8(v, 7, 2) + >>> int8(v, 2) == 7 + True + + """ + check_status(v, lib.GrB_Vector_setElement_INT8(v[0], value, i)) + + +def int8(v, i): + """Get an int8 value from the vector at position `i`. + + >>> v = new(lib.GrB_INT8, 3) + >>> set_int8(v, 7, 2) + >>> int8(v, 2) == 7 + True + + """ + value = ffi.new("int8_t*") + check_status(v, lib.GrB_Vector_extractElement_INT8(value, v[0], i)) + return value[0] + + +def set_int16(v, value, i): + """Set an int16 value to the vector at position `i`. + + >>> v = new(lib.GrB_INT16, 3) + >>> set_int16(v, 7, 2) + >>> int16(v, 2) == 7 + True + + """ + check_status(v, lib.GrB_Vector_setElement_INT16(v[0], value, i)) + + +def int16(v, i): + """Get an int16 value from the vector at position `i`. + + >>> v = new(lib.GrB_INT16, 3) + >>> set_int16(v, 7, 2) + >>> int16(v, 2) == 7 + True + + """ + value = ffi.new("int16_t*") + check_status(v, lib.GrB_Vector_extractElement_INT16(value, v[0], i)) + return value[0] + + +def set_int32(v, value, i): + """Set an int32 value to the vector at position `i`. + + >>> v = new(lib.GrB_INT32, 3) + >>> set_int32(v, 7, 2) + >>> int32(v, 2) == 7 + True + + """ + check_status(v, lib.GrB_Vector_setElement_INT32(v[0], value, i)) + + +def int32(v, i): + """Get an int32 value from the vector at position `i`. + + >>> v = new(lib.GrB_INT32, 3) + >>> set_int32(v, 7, 2) + >>> int32(v, 2) == 7 + True + + """ + value = ffi.new("int32_t*") + check_status(v, lib.GrB_Vector_extractElement_INT32(value, v[0], i)) + return value[0] + + +def set_int64(v, value, i): + """Set an int64 value to the vector at position `i`. + + >>> v = new(lib.GrB_INT64, 3) + >>> set_int64(v, 7, 2) + >>> int64(v, 2) == 7 + True + + """ + check_status(v, lib.GrB_Vector_setElement_INT64(v[0], value, i)) + + +def int64(v, i): + """Get an int64 value from the vector at position `i`. + + >>> v = new(lib.GrB_INT64, 3) + >>> set_int64(v, 7, 2) + >>> int64(v, 2) == 7 + True + + """ + value = ffi.new("int64_t*") + check_status(v, lib.GrB_Vector_extractElement_INT64(value, v[0], i)) + return value[0] + + +def set_uint8(v, value, i): + """Set a uint8 value to the vector at position `i`. + + >>> v = new(lib.GrB_UINT8, 3) + >>> set_uint8(v, 7, 2) + >>> uint8(v, 2) == 7 + True + + """ + check_status(v, lib.GrB_Vector_setElement_UINT8(v[0], value, i)) + + +def uint8(v, i): + """Get a uint8 value from the vector at position `i`. + + >>> v = new(lib.GrB_UINT8, 3) + >>> set_uint8(v, 7, 2) + >>> uint8(v, 2) == 7 + True + + """ + value = ffi.new("uint8_t*") + check_status(v, lib.GrB_Vector_extractElement_UINT8(value, v[0], i)) + return value[0] + + +def set_uint16(v, value, i): + """Set a uint16 value to the vector at position `i`. + + >>> v = new(lib.GrB_UINT16, 3) + >>> set_uint16(v, 7, 2) + >>> uint16(v, 2) == 7 + True + + """ + check_status(v, lib.GrB_Vector_setElement_UINT16(v[0], value, i)) + + +def uint16(v, i): + """Get a uint16 value from the vector at position `i`. + + >>> v = new(lib.GrB_UINT16, 3) + >>> set_uint16(v, 7, 2) + >>> uint16(v, 2) == 7 + True + + """ + value = ffi.new("uint16_t*") + check_status(v, lib.GrB_Vector_extractElement_UINT16(value, v[0], i)) + return value[0] + + +def set_uint32(v, value, i): + """Set a uint32 value to the vector at position `i`. + + >>> v = new(lib.GrB_UINT32, 3) + >>> set_uint32(v, 7, 2) + >>> uint32(v, 2) == 7 + True + + """ + check_status(v, lib.GrB_Vector_setElement_UINT32(v[0], value, i)) + + +def uint32(v, i): + """Get a uint32 value from the vector at position `i`. + + >>> v = new(lib.GrB_UINT32, 3) + >>> set_uint32(v, 7, 2) + >>> uint32(v, 2) == 7 + True + + """ + value = ffi.new("uint32_t*") + check_status(v, lib.GrB_Vector_extractElement_UINT32(value, v[0], i)) + return value[0] + + +def set_uint64(v, value, i): + """Set a uint64 value to the vector at position `i`. + + >>> v = new(lib.GrB_UINT64, 3) + >>> set_uint64(v, 7, 2) + >>> uint64(v, 2) == 7 + True + + """ + check_status(v, lib.GrB_Vector_setElement_UINT64(v[0], value, i)) + + +def uint64(v, i): + """Get a uint64 value from the vector at position `i`. + + >>> v = new(lib.GrB_UINT64, 3) + >>> set_uint64(v, 7, 2) + >>> uint64(v, 2) == 7 + True + + """ + value = ffi.new("uint64_t*") + check_status(v, lib.GrB_Vector_extractElement_UINT64(value, v[0], i)) + return value[0] + + +def set_fp32(v, value, i): + """Set an fp32 value to the vector at position `i`. + + >>> v = new(lib.GrB_FP32, 3) + >>> set_fp32(v, 1.5, 2) + >>> fp32(v, 2) == 1.5 + True + + """ + check_status(v, lib.GrB_Vector_setElement_FP32(v[0], value, i)) + + +def fp32(v, i): + """Get an fp32 value from the vector at position `i`. + + >>> v = new(lib.GrB_FP32, 3) + >>> set_fp32(v, 1.5, 2) + >>> fp32(v, 2) == 1.5 + True + + """ + value = ffi.new("float*") + check_status(v, lib.GrB_Vector_extractElement_FP32(value, v[0], i)) + return value[0] + + +def set_fp64(v, value, i): + """Set an fp64 value to the vector at position `i`. + + >>> v = new(lib.GrB_FP64, 3) + >>> set_fp64(v, 1.5, 2) + >>> fp64(v, 2) == 1.5 + True + + """ + check_status(v, lib.GrB_Vector_setElement_FP64(v[0], value, i)) + + +def fp64(v, i): + """Get an fp64 value from the vector at position `i`. + + >>> v = new(lib.GrB_FP64, 3) + >>> set_fp64(v, 1.5, 2) + >>> fp64(v, 2) == 1.5 + True + + """ + value = ffi.new("double*") + check_status(v, lib.GrB_Vector_extractElement_FP64(value, v[0], i)) + return value[0] + + +if supports_complex(): + + def set_fc32(v, value, i): + """Set an fc32 value to the vector at position `i`. + + >>> v = new(lib.GxB_FC32, 3) + >>> set_fc32(v, 2+3j, 2) + >>> fc32(v, 2) == 2+3j + True + + """ + check_status(v, lib.GxB_Vector_setElement_FC32(v[0], value, i)) + + def fc32(v, i): + """Get an fc32 value from the vector at position `i`. + + >>> v = new(lib.GxB_FC32, 3) + >>> set_fc32(v, 2+3j, 2) + >>> fc32(v, 2) == 2+3j + True + + """ + value = ffi.new("GxB_FC32_t*") + check_status(v, lib.GxB_Vector_extractElement_FC32(value, v[0], i)) + return value[0] + + def set_fc64(v, value, i): + """Set an fc64 value to the vector at position `i`. + + >>> v = new(lib.GxB_FC64, 3) + >>> set_fc64(v, 2+3j, 2) + >>> fc64(v, 2) == 2+3j + True + + """ + check_status(v, lib.GxB_Vector_setElement_FC64(v[0], value, i)) + + def fc64(v, i): + """Get an fc64 value from the vector at position `i`. + + >>> v = new(lib.GxB_FC64, 3) + >>> set_fc64(v, 2+3j, 2) + >>> fc64(v, 2) == 2+3j + True + + """ + value = ffi.new("GxB_FC64_t*") + check_status(v, lib.GxB_Vector_extractElement_FC64(value, v[0], i)) + return value[0] From a85dc40e75141d4e6d66ee0e1795e2418a74ef32 Mon Sep 17 00:00:00 2001 From: Michel Pelletier Date: Tue, 7 Apr 2026 13:55:53 -0700 Subject: [PATCH 2/5] Modernize Dockerfile to build against current Python and GraphBLAS The Dockerfile had bit-rotted: the python:3.10-slim-buster base image no longer builds (Debian buster apt repos are gone), and the most recent commit simultaneously dropped Python <=3.10 support in pyproject.toml while leaving the Dockerfile pinned to Python 3.10. Several install paths and cmake flags were also out of date for SuiteSparse:GraphBLAS 10.x. Changes: - Bump base image from python:3.10-slim-buster (EOL) to python:3.12-slim-bookworm. Update hardcoded python3.10 site-packages paths to python3.12 in three places. - Update GraphBLAS header copy: 10.x installs the header at /usr/include/suitesparse/GraphBLAS.h, not /usr/include/GraphBLAS.h, and create_headers.py looks for it at ${sys.prefix}/include/suitesparse/GraphBLAS.h. - Replace deprecated `python3 setup.py install` with `pip install --no-build-isolation --no-deps .`. The pip-driven path is required by modern setuptools, and pip is added to the build-time install list along with pycparser/setuptools/wheel/setuptools-git-versioning which the build now needs explicitly. - Add cmake flags matching CI in suitesparse.sh: -DCMAKE_BUILD_TYPE=Release, -DJITINIT=2, -DGRAPHBLAS_USE_JIT=OFF. The JIT flags avoid segfaults in tests; without them GraphBLAS may attempt JIT compilation at runtime. - Replace stale -DGBCOMPACT cmake flag with the current name -DCOMPACT, and give ARG COMPACT a default of 0 so the substitution is non-empty when the build-arg is omitted. - Make `git tag ${VERSION}` idempotent: wrap with `(... || true)` so the build does not fail when ${VERSION} matches an existing tag in the source tree (which is now the case for the current 10.3.1.0 release tag). - Fix Docker COPY collapsing the libgraphblas symlink chain (libgraphblas.so -> .so.10 -> .so.10.3.1) into three identical 67MB regular files. Copy only the real versioned library (libgraphblas.so.*.*.*) and recreate symlinks via `ln -sf` in a RUN step. Apply the same fix to libgomp in the final stage. This removes the `ldconfig: ... is not a symbolic link` warnings and saves ~130MB. - Cleanup: remove unused `ARG SUITESPARSE` redeclaration in the psg stage, fix the lowercase `as` -> `AS` for FromAsCasing warnings, and switch `ENV PYTHONUNBUFFERED 1` to the modern `ENV key=value` form. - Drop the bizarre `WORKDIR /build/GraphBLAS/build` that was set *before* the GraphBLAS git clone, producing the path /build/GraphBLAS/build/GraphBLAS/build. The clone now happens directly under /build. Built and verified by running the doctests inside the produced image: $ docker build --build-arg SUITESPARSE=v10.3.1 \\ --build-arg VERSION=10.3.1.0 \\ -t psg-test:latest . $ docker run --rm psg-test:latest python3 -c " import suitesparse_graphblas; suitesparse_graphblas.initialize() from suitesparse_graphblas.tests.test_doctest import test_run_doctests test_run_doctests()" -> 268 doctests pass, supports_complex=True --- Dockerfile | 58 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/Dockerfile b/Dockerfile index f20e91f..e20d1b6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,47 +1,71 @@ -ARG BASE_CONTAINER=python:3.10-slim-buster -FROM ${BASE_CONTAINER} as suitesparse +ARG BASE_CONTAINER=python:3.12-slim-bookworm +FROM ${BASE_CONTAINER} AS suitesparse ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -yq build-essential cmake git ARG SUITESPARSE -ARG COMPACT +ARG COMPACT=0 WORKDIR /build RUN git clone https://github.com/eliben/pycparser.git --depth 1 -WORKDIR /build/GraphBLAS/build +# Use `-DJITINIT=2` so that the JIT functionality is available, but disabled by default. +# Level 2, "run", means that pre-JIT kernels may be used, which does not require a compiler at runtime. +# Disable JIT entirely to avoid segfaulting in tests (matches CI in suitesparse.sh). RUN git clone https://github.com/DrTimothyAldenDavis/GraphBLAS.git --depth 1 --branch ${SUITESPARSE} \ && cd GraphBLAS/build \ - && cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DGBCOMPACT=${COMPACT} \ + && cmake .. \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DCOMPACT=${COMPACT} \ + -DJITINIT=2 \ + -DGRAPHBLAS_USE_JIT=OFF \ && make -j$(nproc) \ && make install -FROM ${BASE_CONTAINER} as psg -ARG SUITESPARSE +FROM ${BASE_CONTAINER} AS psg ARG VERSION -ENV PYTHONUNBUFFERED 1 +ENV PYTHONUNBUFFERED=1 -COPY --from=suitesparse /usr/include/GraphBLAS.h /usr/local/include/ -COPY --from=suitesparse /usr/lib/x86_64-linux-gnu/libgraphblas* /usr/lib/x86_64-linux-gnu/ -COPY --from=suitesparse /build/pycparser/utils/fake_libc_include/* /usr/local/lib/python3.10/site-packages/pycparser/utils/fake_libc_include/ +COPY --from=suitesparse /usr/include/suitesparse/GraphBLAS.h /usr/local/include/suitesparse/GraphBLAS.h +# Copy only the real versioned library; recreate symlinks (Docker COPY collapses cross-stage symlinks). +COPY --from=suitesparse /usr/lib/x86_64-linux-gnu/libgraphblas.so.*.*.* /usr/lib/x86_64-linux-gnu/ +RUN cd /usr/lib/x86_64-linux-gnu \ + && REAL=$(ls libgraphblas.so.*.*.*) \ + && SOMAJOR=libgraphblas.so.$(echo "$REAL" | sed -E 's/libgraphblas\.so\.([0-9]+).*/\1/') \ + && ln -sf "$REAL" "$SOMAJOR" \ + && ln -sf "$SOMAJOR" libgraphblas.so \ + && ldconfig RUN apt-get update && apt-get install -yq build-essential git -RUN pip3 install numpy cffi pytest cython +RUN pip3 install --break-system-packages numpy cffi pytest cython pycparser setuptools wheel setuptools-git-versioning + +COPY --from=suitesparse /build/pycparser/utils/fake_libc_include/* /usr/local/lib/python3.12/site-packages/pycparser/utils/fake_libc_include/ RUN mkdir -p /psg ADD . /psg WORKDIR /psg -RUN git tag ${VERSION} && \ +# `git tag || true` so the build is idempotent when ${VERSION} already matches an existing tag in the source tree. +RUN (git tag ${VERSION} || true) && \ python3 suitesparse_graphblas/create_headers.py && \ - python3 setup.py install && \ + pip3 install --break-system-packages --no-build-isolation --no-deps . && \ ldconfig #RUN pytest --pyargs suitesparse_graphblas.tests RUN apt-get -y --purge remove git python3-pip && apt-get clean FROM ${BASE_CONTAINER} -COPY --from=suitesparse /usr/lib/x86_64-linux-gnu/libgraphblas* /usr/lib/x86_64-linux-gnu/ -COPY --from=suitesparse /usr/lib/x86_64-linux-gnu/libgomp* /usr/lib/x86_64-linux-gnu/ -COPY --from=psg /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages +COPY --from=suitesparse /usr/lib/x86_64-linux-gnu/libgraphblas.so.*.*.* /usr/lib/x86_64-linux-gnu/ +COPY --from=suitesparse /usr/lib/x86_64-linux-gnu/libgomp.so.*.*.* /usr/lib/x86_64-linux-gnu/ +COPY --from=psg /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages +RUN cd /usr/lib/x86_64-linux-gnu \ + && GBREAL=$(ls libgraphblas.so.*.*.*) \ + && GBSOMAJOR=libgraphblas.so.$(echo "$GBREAL" | sed -E 's/libgraphblas\.so\.([0-9]+).*/\1/') \ + && ln -sf "$GBREAL" "$GBSOMAJOR" \ + && ln -sf "$GBSOMAJOR" libgraphblas.so \ + && GMREAL=$(ls libgomp.so.*.*.*) \ + && GMSOMAJOR=libgomp.so.$(echo "$GMREAL" | sed -E 's/libgomp\.so\.([0-9]+).*/\1/') \ + && ln -sf "$GMREAL" "$GMSOMAJOR" \ + && ldconfig From a0624345d7e3847479ed51ab77d7a646c70dbf41 Mon Sep 17 00:00:00 2001 From: Michel Pelletier Date: Tue, 7 Apr 2026 16:30:24 -0700 Subject: [PATCH 3/5] Rename element getters to `get_*` in functional API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The element getter functions in matrix.py, vector.py, and scalar.py were named after their GraphBLAS type suffix — `bool`, `int8`, `fp32`, `fc64`, etc. — which can be confused with concrete type objects (e.g. NumPy's `int8` dtype). Prefix every getter with `get_`, mirroring the existing `set_` prefix on the corresponding setters: `bool` -> `get_bool`, `int32` -> `get_int32`, `fc64` -> `get_fc64`, etc. The setters (`set_bool`, `set_int8`, ...) are NOT renamed. This is a pure rename, not an API redesign. Implementations and doctests are otherwise unchanged. Each setter's doctest already referenced its corresponding getter for round-trip verification, so both setter and getter docstrings were updated. Affected: - 13 getter `def` lines per file (one per element type) - 26 doctest references per file (one in each setter doctest, one in each getter doctest) - 3 files * (13 + 26) = 117 line replacements total Verified by rebuilding the Docker test image and rerunning the full doctest suite inside the container: matrix: 97 attempted, 0 failed vector: 90 attempted, 0 failed scalar: 81 attempted, 0 failed TOTAL: 268 attempted, 0 failed test_run_doctests: OK Both the direct `doctest.testmod` invocation and the official `tests/test_doctest.py::test_run_doctests` entry point pass, including the complex `get_fc32` / `get_fc64` doctests that depend on `supports_complex()`. --- suitesparse_graphblas/matrix.py | 78 ++++++++++++++++----------------- suitesparse_graphblas/scalar.py | 78 ++++++++++++++++----------------- suitesparse_graphblas/vector.py | 78 ++++++++++++++++----------------- 3 files changed, 117 insertions(+), 117 deletions(-) diff --git a/suitesparse_graphblas/matrix.py b/suitesparse_graphblas/matrix.py index 9f8d10a..192085b 100644 --- a/suitesparse_graphblas/matrix.py +++ b/suitesparse_graphblas/matrix.py @@ -181,19 +181,19 @@ def set_bool(A, value, i, j): >>> A = new(lib.GrB_BOOL, 3, 3) >>> set_bool(A, True, 2, 2) - >>> bool(A, 2, 2) == True + >>> get_bool(A, 2, 2) == True True """ check_status(A, lib.GrB_Matrix_setElement_BOOL(A[0], value, i, j)) -def bool(A, i, j): +def get_bool(A, i, j): """Get a boolean value from the matrix at row `i` column `j`. >>> A = new(lib.GrB_BOOL, 3, 3) >>> set_bool(A, True, 2, 2) - >>> bool(A, 2, 2) == True + >>> get_bool(A, 2, 2) == True True """ @@ -207,19 +207,19 @@ def set_int8(A, value, i, j): >>> A = new(lib.GrB_INT8, 3, 3) >>> set_int8(A, 7, 2, 2) - >>> int8(A, 2, 2) == 7 + >>> get_int8(A, 2, 2) == 7 True """ check_status(A, lib.GrB_Matrix_setElement_INT8(A[0], value, i, j)) -def int8(A, i, j): +def get_int8(A, i, j): """Get an int8 value from the matrix at row `i` column `j`. >>> A = new(lib.GrB_INT8, 3, 3) >>> set_int8(A, 7, 2, 2) - >>> int8(A, 2, 2) == 7 + >>> get_int8(A, 2, 2) == 7 True """ @@ -233,19 +233,19 @@ def set_int16(A, value, i, j): >>> A = new(lib.GrB_INT16, 3, 3) >>> set_int16(A, 7, 2, 2) - >>> int16(A, 2, 2) == 7 + >>> get_int16(A, 2, 2) == 7 True """ check_status(A, lib.GrB_Matrix_setElement_INT16(A[0], value, i, j)) -def int16(A, i, j): +def get_int16(A, i, j): """Get an int16 value from the matrix at row `i` column `j`. >>> A = new(lib.GrB_INT16, 3, 3) >>> set_int16(A, 7, 2, 2) - >>> int16(A, 2, 2) == 7 + >>> get_int16(A, 2, 2) == 7 True """ @@ -259,19 +259,19 @@ def set_int32(A, value, i, j): >>> A = new(lib.GrB_INT32, 3, 3) >>> set_int32(A, 7, 2, 2) - >>> int32(A, 2, 2) == 7 + >>> get_int32(A, 2, 2) == 7 True """ check_status(A, lib.GrB_Matrix_setElement_INT32(A[0], value, i, j)) -def int32(A, i, j): +def get_int32(A, i, j): """Get an int32 value from the matrix at row `i` column `j`. >>> A = new(lib.GrB_INT32, 3, 3) >>> set_int32(A, 7, 2, 2) - >>> int32(A, 2, 2) == 7 + >>> get_int32(A, 2, 2) == 7 True """ @@ -285,19 +285,19 @@ def set_int64(A, value, i, j): >>> A = new(lib.GrB_INT64, 3, 3) >>> set_int64(A, 7, 2, 2) - >>> int64(A, 2, 2) == 7 + >>> get_int64(A, 2, 2) == 7 True """ check_status(A, lib.GrB_Matrix_setElement_INT64(A[0], value, i, j)) -def int64(A, i, j): +def get_int64(A, i, j): """Get an int64 value from the matrix at row `i` column `j`. >>> A = new(lib.GrB_INT64, 3, 3) >>> set_int64(A, 7, 2, 2) - >>> int64(A, 2, 2) == 7 + >>> get_int64(A, 2, 2) == 7 True """ @@ -311,19 +311,19 @@ def set_uint8(A, value, i, j): >>> A = new(lib.GrB_UINT8, 3, 3) >>> set_uint8(A, 7, 2, 2) - >>> uint8(A, 2, 2) == 7 + >>> get_uint8(A, 2, 2) == 7 True """ check_status(A, lib.GrB_Matrix_setElement_UINT8(A[0], value, i, j)) -def uint8(A, i, j): +def get_uint8(A, i, j): """Get a uint8 value from the matrix at row `i` column `j`. >>> A = new(lib.GrB_UINT8, 3, 3) >>> set_uint8(A, 7, 2, 2) - >>> uint8(A, 2, 2) == 7 + >>> get_uint8(A, 2, 2) == 7 True """ @@ -337,19 +337,19 @@ def set_uint16(A, value, i, j): >>> A = new(lib.GrB_UINT16, 3, 3) >>> set_uint16(A, 7, 2, 2) - >>> uint16(A, 2, 2) == 7 + >>> get_uint16(A, 2, 2) == 7 True """ check_status(A, lib.GrB_Matrix_setElement_UINT16(A[0], value, i, j)) -def uint16(A, i, j): +def get_uint16(A, i, j): """Get a uint16 value from the matrix at row `i` column `j`. >>> A = new(lib.GrB_UINT16, 3, 3) >>> set_uint16(A, 7, 2, 2) - >>> uint16(A, 2, 2) == 7 + >>> get_uint16(A, 2, 2) == 7 True """ @@ -363,19 +363,19 @@ def set_uint32(A, value, i, j): >>> A = new(lib.GrB_UINT32, 3, 3) >>> set_uint32(A, 7, 2, 2) - >>> uint32(A, 2, 2) == 7 + >>> get_uint32(A, 2, 2) == 7 True """ check_status(A, lib.GrB_Matrix_setElement_UINT32(A[0], value, i, j)) -def uint32(A, i, j): +def get_uint32(A, i, j): """Get a uint32 value from the matrix at row `i` column `j`. >>> A = new(lib.GrB_UINT32, 3, 3) >>> set_uint32(A, 7, 2, 2) - >>> uint32(A, 2, 2) == 7 + >>> get_uint32(A, 2, 2) == 7 True """ @@ -389,19 +389,19 @@ def set_uint64(A, value, i, j): >>> A = new(lib.GrB_UINT64, 3, 3) >>> set_uint64(A, 7, 2, 2) - >>> uint64(A, 2, 2) == 7 + >>> get_uint64(A, 2, 2) == 7 True """ check_status(A, lib.GrB_Matrix_setElement_UINT64(A[0], value, i, j)) -def uint64(A, i, j): +def get_uint64(A, i, j): """Get a uint64 value from the matrix at row `i` column `j`. >>> A = new(lib.GrB_UINT64, 3, 3) >>> set_uint64(A, 7, 2, 2) - >>> uint64(A, 2, 2) == 7 + >>> get_uint64(A, 2, 2) == 7 True """ @@ -415,19 +415,19 @@ def set_fp32(A, value, i, j): >>> A = new(lib.GrB_FP32, 3, 3) >>> set_fp32(A, 1.5, 2, 2) - >>> fp32(A, 2, 2) == 1.5 + >>> get_fp32(A, 2, 2) == 1.5 True """ check_status(A, lib.GrB_Matrix_setElement_FP32(A[0], value, i, j)) -def fp32(A, i, j): +def get_fp32(A, i, j): """Get an fp32 value from the matrix at row `i` column `j`. >>> A = new(lib.GrB_FP32, 3, 3) >>> set_fp32(A, 1.5, 2, 2) - >>> fp32(A, 2, 2) == 1.5 + >>> get_fp32(A, 2, 2) == 1.5 True """ @@ -441,19 +441,19 @@ def set_fp64(A, value, i, j): >>> A = new(lib.GrB_FP64, 3, 3) >>> set_fp64(A, 1.5, 2, 2) - >>> fp64(A, 2, 2) == 1.5 + >>> get_fp64(A, 2, 2) == 1.5 True """ check_status(A, lib.GrB_Matrix_setElement_FP64(A[0], value, i, j)) -def fp64(A, i, j): +def get_fp64(A, i, j): """Get an fp64 value from the matrix at row `i` column `j`. >>> A = new(lib.GrB_FP64, 3, 3) >>> set_fp64(A, 1.5, 2, 2) - >>> fp64(A, 2, 2) == 1.5 + >>> get_fp64(A, 2, 2) == 1.5 True """ @@ -469,18 +469,18 @@ def set_fc32(A, value, i, j): >>> A = new(lib.GxB_FC32, 3, 3) >>> set_fc32(A, 2+3j, 2, 2) - >>> fc32(A, 2, 2) == 2+3j + >>> get_fc32(A, 2, 2) == 2+3j True """ check_status(A, lib.GxB_Matrix_setElement_FC32(A[0], value, i, j)) - def fc32(A, i, j): + def get_fc32(A, i, j): """Get an fc32 value from the matrix at row `i` column `j`. >>> A = new(lib.GxB_FC32, 3, 3) >>> set_fc32(A, 2+3j, 2, 2) - >>> fc32(A, 2, 2) == 2+3j + >>> get_fc32(A, 2, 2) == 2+3j True """ @@ -493,18 +493,18 @@ def set_fc64(A, value, i, j): >>> A = new(lib.GxB_FC64, 3, 3) >>> set_fc64(A, 2+3j, 2, 2) - >>> fc64(A, 2, 2) == 2+3j + >>> get_fc64(A, 2, 2) == 2+3j True """ check_status(A, lib.GxB_Matrix_setElement_FC64(A[0], value, i, j)) - def fc64(A, i, j): + def get_fc64(A, i, j): """Get an fc64 value from the matrix at row `i` column `j`. >>> A = new(lib.GxB_FC64, 3, 3) >>> set_fc64(A, 2+3j, 2, 2) - >>> fc64(A, 2, 2) == 2+3j + >>> get_fc64(A, 2, 2) == 2+3j True """ diff --git a/suitesparse_graphblas/scalar.py b/suitesparse_graphblas/scalar.py index e072a8f..4be4816 100644 --- a/suitesparse_graphblas/scalar.py +++ b/suitesparse_graphblas/scalar.py @@ -42,19 +42,19 @@ def set_bool(s, value): >>> s = new(lib.GrB_BOOL) >>> set_bool(s, True) - >>> bool(s) == True + >>> get_bool(s) == True True """ check_status(s, lib.GxB_Scalar_setElement_BOOL(s[0], value)) -def bool(s): +def get_bool(s): """Get a boolean value from the scalar. >>> s = new(lib.GrB_BOOL) >>> set_bool(s, True) - >>> bool(s) == True + >>> get_bool(s) == True True """ @@ -70,19 +70,19 @@ def set_int8(s, value): >>> s = new(lib.GrB_INT8) >>> set_int8(s, 7) - >>> int8(s) == 7 + >>> get_int8(s) == 7 True """ check_status(s, lib.GxB_Scalar_setElement_INT8(s[0], value)) -def int8(s): +def get_int8(s): """Get an int8 value from the scalar. >>> s = new(lib.GrB_INT8) >>> set_int8(s, 7) - >>> int8(s) == 7 + >>> get_int8(s) == 7 True """ @@ -98,19 +98,19 @@ def set_int16(s, value): >>> s = new(lib.GrB_INT16) >>> set_int16(s, 7) - >>> int16(s) == 7 + >>> get_int16(s) == 7 True """ check_status(s, lib.GxB_Scalar_setElement_INT16(s[0], value)) -def int16(s): +def get_int16(s): """Get an int16 value from the scalar. >>> s = new(lib.GrB_INT16) >>> set_int16(s, 7) - >>> int16(s) == 7 + >>> get_int16(s) == 7 True """ @@ -126,19 +126,19 @@ def set_int32(s, value): >>> s = new(lib.GrB_INT32) >>> set_int32(s, 7) - >>> int32(s) == 7 + >>> get_int32(s) == 7 True """ check_status(s, lib.GxB_Scalar_setElement_INT32(s[0], value)) -def int32(s): +def get_int32(s): """Get an int32 value from the scalar. >>> s = new(lib.GrB_INT32) >>> set_int32(s, 7) - >>> int32(s) == 7 + >>> get_int32(s) == 7 True """ @@ -154,19 +154,19 @@ def set_int64(s, value): >>> s = new(lib.GrB_INT64) >>> set_int64(s, 7) - >>> int64(s) == 7 + >>> get_int64(s) == 7 True """ check_status(s, lib.GxB_Scalar_setElement_INT64(s[0], value)) -def int64(s): +def get_int64(s): """Get an int64 value from the scalar. >>> s = new(lib.GrB_INT64) >>> set_int64(s, 7) - >>> int64(s) == 7 + >>> get_int64(s) == 7 True """ @@ -182,19 +182,19 @@ def set_uint8(s, value): >>> s = new(lib.GrB_UINT8) >>> set_uint8(s, 7) - >>> uint8(s) == 7 + >>> get_uint8(s) == 7 True """ check_status(s, lib.GxB_Scalar_setElement_UINT8(s[0], value)) -def uint8(s): +def get_uint8(s): """Get a uint8 value from the scalar. >>> s = new(lib.GrB_UINT8) >>> set_uint8(s, 7) - >>> uint8(s) == 7 + >>> get_uint8(s) == 7 True """ @@ -210,19 +210,19 @@ def set_uint16(s, value): >>> s = new(lib.GrB_UINT16) >>> set_uint16(s, 7) - >>> uint16(s) == 7 + >>> get_uint16(s) == 7 True """ check_status(s, lib.GxB_Scalar_setElement_UINT16(s[0], value)) -def uint16(s): +def get_uint16(s): """Get a uint16 value from the scalar. >>> s = new(lib.GrB_UINT16) >>> set_uint16(s, 7) - >>> uint16(s) == 7 + >>> get_uint16(s) == 7 True """ @@ -238,19 +238,19 @@ def set_uint32(s, value): >>> s = new(lib.GrB_UINT32) >>> set_uint32(s, 7) - >>> uint32(s) == 7 + >>> get_uint32(s) == 7 True """ check_status(s, lib.GxB_Scalar_setElement_UINT32(s[0], value)) -def uint32(s): +def get_uint32(s): """Get a uint32 value from the scalar. >>> s = new(lib.GrB_UINT32) >>> set_uint32(s, 7) - >>> uint32(s) == 7 + >>> get_uint32(s) == 7 True """ @@ -266,19 +266,19 @@ def set_uint64(s, value): >>> s = new(lib.GrB_UINT64) >>> set_uint64(s, 7) - >>> uint64(s) == 7 + >>> get_uint64(s) == 7 True """ check_status(s, lib.GxB_Scalar_setElement_UINT64(s[0], value)) -def uint64(s): +def get_uint64(s): """Get a uint64 value from the scalar. >>> s = new(lib.GrB_UINT64) >>> set_uint64(s, 7) - >>> uint64(s) == 7 + >>> get_uint64(s) == 7 True """ @@ -294,19 +294,19 @@ def set_fp32(s, value): >>> s = new(lib.GrB_FP32) >>> set_fp32(s, 1.5) - >>> fp32(s) == 1.5 + >>> get_fp32(s) == 1.5 True """ check_status(s, lib.GxB_Scalar_setElement_FP32(s[0], value)) -def fp32(s): +def get_fp32(s): """Get an fp32 value from the scalar. >>> s = new(lib.GrB_FP32) >>> set_fp32(s, 1.5) - >>> fp32(s) == 1.5 + >>> get_fp32(s) == 1.5 True """ @@ -322,19 +322,19 @@ def set_fp64(s, value): >>> s = new(lib.GrB_FP64) >>> set_fp64(s, 1.5) - >>> fp64(s) == 1.5 + >>> get_fp64(s) == 1.5 True """ check_status(s, lib.GxB_Scalar_setElement_FP64(s[0], value)) -def fp64(s): +def get_fp64(s): """Get an fp64 value from the scalar. >>> s = new(lib.GrB_FP64) >>> set_fp64(s, 1.5) - >>> fp64(s) == 1.5 + >>> get_fp64(s) == 1.5 True """ @@ -352,18 +352,18 @@ def set_fc32(s, value): >>> s = new(lib.GxB_FC32) >>> set_fc32(s, 2+3j) - >>> fc32(s) == 2+3j + >>> get_fc32(s) == 2+3j True """ check_status(s, lib.GxB_Scalar_setElement_FC32(s[0], value)) - def fc32(s): + def get_fc32(s): """Get an fc32 value from the scalar. >>> s = new(lib.GxB_FC32) >>> set_fc32(s, 2+3j) - >>> fc32(s) == 2+3j + >>> get_fc32(s) == 2+3j True """ @@ -378,18 +378,18 @@ def set_fc64(s, value): >>> s = new(lib.GxB_FC64) >>> set_fc64(s, 2+3j) - >>> fc64(s) == 2+3j + >>> get_fc64(s) == 2+3j True """ check_status(s, lib.GxB_Scalar_setElement_FC64(s[0], value)) - def fc64(s): + def get_fc64(s): """Get an fc64 value from the scalar. >>> s = new(lib.GxB_FC64) >>> set_fc64(s, 2+3j) - >>> fc64(s) == 2+3j + >>> get_fc64(s) == 2+3j True """ diff --git a/suitesparse_graphblas/vector.py b/suitesparse_graphblas/vector.py index 412b9da..bd7b73c 100644 --- a/suitesparse_graphblas/vector.py +++ b/suitesparse_graphblas/vector.py @@ -82,19 +82,19 @@ def set_bool(v, value, i): >>> v = new(lib.GrB_BOOL, 3) >>> set_bool(v, True, 2) - >>> bool(v, 2) == True + >>> get_bool(v, 2) == True True """ check_status(v, lib.GrB_Vector_setElement_BOOL(v[0], value, i)) -def bool(v, i): +def get_bool(v, i): """Get a boolean value from the vector at position `i`. >>> v = new(lib.GrB_BOOL, 3) >>> set_bool(v, True, 2) - >>> bool(v, 2) == True + >>> get_bool(v, 2) == True True """ @@ -108,19 +108,19 @@ def set_int8(v, value, i): >>> v = new(lib.GrB_INT8, 3) >>> set_int8(v, 7, 2) - >>> int8(v, 2) == 7 + >>> get_int8(v, 2) == 7 True """ check_status(v, lib.GrB_Vector_setElement_INT8(v[0], value, i)) -def int8(v, i): +def get_int8(v, i): """Get an int8 value from the vector at position `i`. >>> v = new(lib.GrB_INT8, 3) >>> set_int8(v, 7, 2) - >>> int8(v, 2) == 7 + >>> get_int8(v, 2) == 7 True """ @@ -134,19 +134,19 @@ def set_int16(v, value, i): >>> v = new(lib.GrB_INT16, 3) >>> set_int16(v, 7, 2) - >>> int16(v, 2) == 7 + >>> get_int16(v, 2) == 7 True """ check_status(v, lib.GrB_Vector_setElement_INT16(v[0], value, i)) -def int16(v, i): +def get_int16(v, i): """Get an int16 value from the vector at position `i`. >>> v = new(lib.GrB_INT16, 3) >>> set_int16(v, 7, 2) - >>> int16(v, 2) == 7 + >>> get_int16(v, 2) == 7 True """ @@ -160,19 +160,19 @@ def set_int32(v, value, i): >>> v = new(lib.GrB_INT32, 3) >>> set_int32(v, 7, 2) - >>> int32(v, 2) == 7 + >>> get_int32(v, 2) == 7 True """ check_status(v, lib.GrB_Vector_setElement_INT32(v[0], value, i)) -def int32(v, i): +def get_int32(v, i): """Get an int32 value from the vector at position `i`. >>> v = new(lib.GrB_INT32, 3) >>> set_int32(v, 7, 2) - >>> int32(v, 2) == 7 + >>> get_int32(v, 2) == 7 True """ @@ -186,19 +186,19 @@ def set_int64(v, value, i): >>> v = new(lib.GrB_INT64, 3) >>> set_int64(v, 7, 2) - >>> int64(v, 2) == 7 + >>> get_int64(v, 2) == 7 True """ check_status(v, lib.GrB_Vector_setElement_INT64(v[0], value, i)) -def int64(v, i): +def get_int64(v, i): """Get an int64 value from the vector at position `i`. >>> v = new(lib.GrB_INT64, 3) >>> set_int64(v, 7, 2) - >>> int64(v, 2) == 7 + >>> get_int64(v, 2) == 7 True """ @@ -212,19 +212,19 @@ def set_uint8(v, value, i): >>> v = new(lib.GrB_UINT8, 3) >>> set_uint8(v, 7, 2) - >>> uint8(v, 2) == 7 + >>> get_uint8(v, 2) == 7 True """ check_status(v, lib.GrB_Vector_setElement_UINT8(v[0], value, i)) -def uint8(v, i): +def get_uint8(v, i): """Get a uint8 value from the vector at position `i`. >>> v = new(lib.GrB_UINT8, 3) >>> set_uint8(v, 7, 2) - >>> uint8(v, 2) == 7 + >>> get_uint8(v, 2) == 7 True """ @@ -238,19 +238,19 @@ def set_uint16(v, value, i): >>> v = new(lib.GrB_UINT16, 3) >>> set_uint16(v, 7, 2) - >>> uint16(v, 2) == 7 + >>> get_uint16(v, 2) == 7 True """ check_status(v, lib.GrB_Vector_setElement_UINT16(v[0], value, i)) -def uint16(v, i): +def get_uint16(v, i): """Get a uint16 value from the vector at position `i`. >>> v = new(lib.GrB_UINT16, 3) >>> set_uint16(v, 7, 2) - >>> uint16(v, 2) == 7 + >>> get_uint16(v, 2) == 7 True """ @@ -264,19 +264,19 @@ def set_uint32(v, value, i): >>> v = new(lib.GrB_UINT32, 3) >>> set_uint32(v, 7, 2) - >>> uint32(v, 2) == 7 + >>> get_uint32(v, 2) == 7 True """ check_status(v, lib.GrB_Vector_setElement_UINT32(v[0], value, i)) -def uint32(v, i): +def get_uint32(v, i): """Get a uint32 value from the vector at position `i`. >>> v = new(lib.GrB_UINT32, 3) >>> set_uint32(v, 7, 2) - >>> uint32(v, 2) == 7 + >>> get_uint32(v, 2) == 7 True """ @@ -290,19 +290,19 @@ def set_uint64(v, value, i): >>> v = new(lib.GrB_UINT64, 3) >>> set_uint64(v, 7, 2) - >>> uint64(v, 2) == 7 + >>> get_uint64(v, 2) == 7 True """ check_status(v, lib.GrB_Vector_setElement_UINT64(v[0], value, i)) -def uint64(v, i): +def get_uint64(v, i): """Get a uint64 value from the vector at position `i`. >>> v = new(lib.GrB_UINT64, 3) >>> set_uint64(v, 7, 2) - >>> uint64(v, 2) == 7 + >>> get_uint64(v, 2) == 7 True """ @@ -316,19 +316,19 @@ def set_fp32(v, value, i): >>> v = new(lib.GrB_FP32, 3) >>> set_fp32(v, 1.5, 2) - >>> fp32(v, 2) == 1.5 + >>> get_fp32(v, 2) == 1.5 True """ check_status(v, lib.GrB_Vector_setElement_FP32(v[0], value, i)) -def fp32(v, i): +def get_fp32(v, i): """Get an fp32 value from the vector at position `i`. >>> v = new(lib.GrB_FP32, 3) >>> set_fp32(v, 1.5, 2) - >>> fp32(v, 2) == 1.5 + >>> get_fp32(v, 2) == 1.5 True """ @@ -342,19 +342,19 @@ def set_fp64(v, value, i): >>> v = new(lib.GrB_FP64, 3) >>> set_fp64(v, 1.5, 2) - >>> fp64(v, 2) == 1.5 + >>> get_fp64(v, 2) == 1.5 True """ check_status(v, lib.GrB_Vector_setElement_FP64(v[0], value, i)) -def fp64(v, i): +def get_fp64(v, i): """Get an fp64 value from the vector at position `i`. >>> v = new(lib.GrB_FP64, 3) >>> set_fp64(v, 1.5, 2) - >>> fp64(v, 2) == 1.5 + >>> get_fp64(v, 2) == 1.5 True """ @@ -370,18 +370,18 @@ def set_fc32(v, value, i): >>> v = new(lib.GxB_FC32, 3) >>> set_fc32(v, 2+3j, 2) - >>> fc32(v, 2) == 2+3j + >>> get_fc32(v, 2) == 2+3j True """ check_status(v, lib.GxB_Vector_setElement_FC32(v[0], value, i)) - def fc32(v, i): + def get_fc32(v, i): """Get an fc32 value from the vector at position `i`. >>> v = new(lib.GxB_FC32, 3) >>> set_fc32(v, 2+3j, 2) - >>> fc32(v, 2) == 2+3j + >>> get_fc32(v, 2) == 2+3j True """ @@ -394,18 +394,18 @@ def set_fc64(v, value, i): >>> v = new(lib.GxB_FC64, 3) >>> set_fc64(v, 2+3j, 2) - >>> fc64(v, 2) == 2+3j + >>> get_fc64(v, 2) == 2+3j True """ check_status(v, lib.GxB_Vector_setElement_FC64(v[0], value, i)) - def fc64(v, i): + def get_fc64(v, i): """Get an fc64 value from the vector at position `i`. >>> v = new(lib.GxB_FC64, 3) >>> set_fc64(v, 2+3j, 2) - >>> fc64(v, 2) == 2+3j + >>> get_fc64(v, 2) == 2+3j True """ From 927e430c96698178da10c794b5caf5555e282867 Mon Sep 17 00:00:00 2001 From: Michel Pelletier Date: Wed, 8 Apr 2026 16:08:03 -0700 Subject: [PATCH 4/5] Prefix matrix/vector/scalar helper functions with module name The metadata/utility helpers in matrix.py, vector.py, and scalar.py were named after generic concepts (`new`, `free`, `type`, `format`, `shape`, `size`, etc.). Several of those names shadow Python builtins (`type`, `format`) or collide with common variables, making bare imports awkward (`from suitesparse_graphblas.matrix import type` is asking for trouble). Prefix every helper with its module name so each function is unambiguous on import: matrix.py (16 helpers): free / new / type / nrows / ncols / nvals / shape / format / set_format / sparsity_status / sparsity_control / set_sparsity_control / hyper_switch / set_hyper_switch / bitmap_switch / set_bitmap_switch -> matrix_free, matrix_new, matrix_type, ..., matrix_set_bitmap_switch vector.py (5 helpers): free / new / type / size / nvals -> vector_free, vector_new, vector_type, vector_size, vector_nvals scalar.py (3 helpers): free / new / type -> scalar_free, scalar_new, scalar_type The element setters/getters (set_bool, get_bool, set_int8, get_int8, ..., set_fc64, get_fc64) are NOT renamed -- they already have a clear set_*/get_* naming convention. Internal cross-references updated: - `def matrix_new(T, ..., *, free=matrix_free)` -- the default value of the `free` keyword argument now references the renamed module-level function. The kwarg parameter name itself stays as `free` so existing callers passing `free=None` or `free=my_func` still work. - `matrix_shape()` body now calls `matrix_nrows(A)` and `matrix_ncols(A)`. - All in-module doctests updated: `>>> A = new(...)` -> `>>> A = matrix_new(...)`, `>>> nrows(A)` -> `>>> matrix_nrows(A)`, etc. Element setter/getter doctests that call `new(...)` to construct test instances are also updated to use the prefixed name. - Local variable shadows (e.g. `format = ffi.new(...)` inside `matrix_format()`) and kwarg parameter names (e.g. `format` in `matrix_set_format(A, format)`) are intentionally left alone -- they are local and don't reference the renamed functions. - `ffi.new(...)` (cffi calls) is preserved -- distinguished from the renamed `new(...)` via a negative lookbehind in the rename pattern. External call sites updated: - `suitesparse_graphblas/__init__.py`: `burble` class doctest references `matrix.matrix_new(...)` and `matrix.matrix_nvals(...)`. - `suitesparse_graphblas/io/binary.py`: 13 `matrix.X(...)` call sites in the binread/binwrite serialization paths now call `matrix.matrix_X(...)`. - `suitesparse_graphblas/io/serialize.py`: 2 docstring prose mentions plus 2 attribute references (`matrix.free` -> `matrix.matrix_free`, `vector.free` -> `vector.vector_free`) used as the default GC callback in `deserialize_matrix` / `deserialize_vector`. - `suitesparse_graphblas/tests/test_io.py`: 17 external call sites updated to the prefixed names. Verified by rebuilding the Docker test image and running both the full doctest suite and the pytest suite inside the container: matrix: 97 attempted, 0 failed vector: 90 attempted, 0 failed scalar: 81 attempted, 0 failed TOTAL doctest: 268 attempted, 0 failed pytest: 9 passed test_doctest, test_exceptions, test_io (matrix and vector serialization round-trip), test_jit, test_package, test_scalar --- suitesparse_graphblas/__init__.py | 6 +- suitesparse_graphblas/io/binary.py | 26 ++--- suitesparse_graphblas/io/serialize.py | 8 +- suitesparse_graphblas/matrix.py | 126 ++++++++++++------------- suitesparse_graphblas/scalar.py | 66 ++++++------- suitesparse_graphblas/tests/test_io.py | 34 +++---- suitesparse_graphblas/vector.py | 86 ++++++++--------- 7 files changed, 176 insertions(+), 176 deletions(-) diff --git a/suitesparse_graphblas/__init__.py b/suitesparse_graphblas/__init__.py index 72838b0..e57ca27 100644 --- a/suitesparse_graphblas/__init__.py +++ b/suitesparse_graphblas/__init__.py @@ -228,7 +228,7 @@ class burble: >>> from suitesparse_graphblas import burble, lib, matrix >>> - >>> A = matrix.new(lib.GrB_BOOL, 3, 3) + >>> A = matrix.matrix_new(lib.GrB_BOOL, 3, 3) >>> burble.is_enabled False >>> burble.enable() @@ -239,7 +239,7 @@ class burble: Example with explicit enable and disable: >>> burble.enable() - >>> n = matrix.nvals(A) + >>> n = matrix.matrix_nvals(A) [ GrB_Matrix_nvals 1.91e-06 sec ] >>> burble.disable() @@ -247,7 +247,7 @@ class burble: Example as a context manager: >>> with burble(): - >>> n = matrix.nvals(A) + >>> n = matrix.matrix_nvals(A) [ GrB_Matrix_nvals 1.91e-06 sec ] diff --git a/suitesparse_graphblas/io/binary.py b/suitesparse_graphblas/io/binary.py index 4e95931..190cc28 100644 --- a/suitesparse_graphblas/io/binary.py +++ b/suitesparse_graphblas/io/binary.py @@ -123,19 +123,19 @@ def binwrite(A, filename, comments=None, opener=Path.open): typecode = ffinew("int32_t*") matrix_type = ffi.new("GrB_Type*") - nrows[0] = matrix.nrows(A) - ncols[0] = matrix.ncols(A) - nvals[0] = matrix.nvals(A) - matrix_type[0] = matrix.type(A) + nrows[0] = matrix.matrix_nrows(A) + ncols[0] = matrix.matrix_ncols(A) + nvals[0] = matrix.matrix_nvals(A) + matrix_type[0] = matrix.matrix_type(A) check_status(A, lib.GxB_Type_size(typesize, matrix_type[0])) typecode[0] = _ss_typecodes[matrix_type[0]] - format[0] = matrix.format(A) - hyper_switch[0] = matrix.hyper_switch(A) - bitmap_switch[0] = matrix.bitmap_switch(A) - sparsity_status[0] = matrix.sparsity_status(A) - sparsity_control[0] = matrix.sparsity_control(A) + format[0] = matrix.matrix_format(A) + hyper_switch[0] = matrix.matrix_hyper_switch(A) + bitmap_switch[0] = matrix.matrix_bitmap_switch(A) + sparsity_status[0] = matrix.matrix_sparsity_status(A) + sparsity_control[0] = matrix.matrix_sparsity_control(A) by_row = format[0] == lib.GxB_BY_ROW by_col = format[0] == lib.GxB_BY_COL @@ -446,7 +446,7 @@ def binread(filename, opener=Path.open): Ax[0] = readinto_new_buffer(f, "uint8_t*", typesize[0] if is_iso[0] else Ax_size[0]) - A = matrix.new(atype, nrows[0], ncols[0]) + A = matrix.matrix_new(atype, nrows[0], ncols[0]) if by_col and is_hyper: check_status( @@ -546,7 +546,7 @@ def binread(filename, opener=Path.open): else: raise TypeError("Unknown format {format[0]}") - matrix.set_sparsity_control(A, sparsity_control[0]) - matrix.set_hyper_switch(A, hyper_switch[0]) - matrix.set_bitmap_switch(A, bitmap_switch[0]) + matrix.matrix_set_sparsity_control(A, sparsity_control[0]) + matrix.matrix_set_hyper_switch(A, hyper_switch[0]) + matrix.matrix_set_bitmap_switch(A, bitmap_switch[0]) return A diff --git a/suitesparse_graphblas/io/serialize.py b/suitesparse_graphblas/io/serialize.py index fcc7804..63e2e3d 100644 --- a/suitesparse_graphblas/io/serialize.py +++ b/suitesparse_graphblas/io/serialize.py @@ -88,7 +88,7 @@ def deserialize_matrix(data, *, free=True, nthreads=None): """Deserialize a Matrix from bytes. The `free` argument is called when the object is garbage - collected, the default is `matrix.free()`. If `free` is None then + collected, the default is `matrix.matrix_free()`. If `free` is None then there is no automatic garbage collection and it is up to the user to free the matrix. """ @@ -108,7 +108,7 @@ def deserialize_matrix(data, *, free=True, nthreads=None): if free: if callable(free): return ffi.gc(A, free) - return ffi.gc(A, matrix.free) + return ffi.gc(A, matrix.matrix_free) return A @@ -116,7 +116,7 @@ def deserialize_vector(data, *, free=True, nthreads=None): """Deserialize a Vector from bytes. The `free` argument is called when the object is garbage - collected, the default is `vector.free()`. If `free` is None then + collected, the default is `vector.vector_free()`. If `free` is None then there is no automatic garbage collection and it is up to the user to free the vector. """ @@ -136,7 +136,7 @@ def deserialize_vector(data, *, free=True, nthreads=None): if free: if callable(free): return ffi.gc(v, free) - return ffi.gc(v, vector.free) + return ffi.gc(v, vector.vector_free) return v diff --git a/suitesparse_graphblas/matrix.py b/suitesparse_graphblas/matrix.py index 192085b..7646090 100644 --- a/suitesparse_graphblas/matrix.py +++ b/suitesparse_graphblas/matrix.py @@ -4,28 +4,28 @@ from .io.serialize import serialize_matrix as serialize # noqa: F401 -def free(A): +def matrix_free(A): """Free a matrix.""" check_status(A, lib.GrB_Matrix_free(A)) -def new(T, nrows=lib.GxB_INDEX_MAX, ncols=lib.GxB_INDEX_MAX, *, free=free): +def matrix_new(T, nrows=lib.GxB_INDEX_MAX, ncols=lib.GxB_INDEX_MAX, *, free=matrix_free): """Create a new `GrB_Matrix` of type `T` and initialize it. The following example creates an eight bit unsigned 2x2 matrix: - >>> A = new(lib.GrB_UINT8, 2, 2) - >>> shape(A) + >>> A = matrix_new(lib.GrB_UINT8, 2, 2) + >>> matrix_shape(A) (2, 2) The default value for `nrows` and `ncols` is `lib.GxB_INDEX_MAX` which creates a Matrix with maximal bounds: - >>> A = new(lib.GrB_UINT8) - >>> shape(A) == (lib.GxB_INDEX_MAX, lib.GxB_INDEX_MAX) + >>> A = matrix_new(lib.GrB_UINT8) + >>> matrix_shape(A) == (lib.GxB_INDEX_MAX, lib.GxB_INDEX_MAX) True The `free` argument is called when the object is garbage - collected, the default is `matrix.free()`. If `free` is None then + collected, the default is `matrix.matrix_free()`. If `free` is None then there is no automatic garbage collection and it is up to the user to free the matrix. @@ -37,11 +37,11 @@ def new(T, nrows=lib.GxB_INDEX_MAX, ncols=lib.GxB_INDEX_MAX, *, free=free): return A -def type(A): +def matrix_type(A): """Return the GraphBLAS type of the vector. - >>> A = new(lib.GrB_UINT8) - >>> type(A) == lib.GrB_UINT8 + >>> A = matrix_new(lib.GrB_UINT8) + >>> matrix_type(A) == lib.GrB_UINT8 True """ @@ -50,11 +50,11 @@ def type(A): return T[0] -def nrows(A): +def matrix_nrows(A): """Return the number of rows in the matrix. - >>> A = new(lib.GrB_UINT8, 2, 3) - >>> nrows(A) + >>> A = matrix_new(lib.GrB_UINT8, 2, 3) + >>> matrix_nrows(A) 2 """ @@ -63,11 +63,11 @@ def nrows(A): return n[0] -def ncols(A): +def matrix_ncols(A): """Return the number of columns in the matrix. - >>> A = new(lib.GrB_UINT8, 2, 3) - >>> ncols(A) + >>> A = matrix_new(lib.GrB_UINT8, 2, 3) + >>> matrix_ncols(A) 3 """ @@ -76,11 +76,11 @@ def ncols(A): return n[0] -def nvals(A): +def matrix_nvals(A): """Return the number of stored elements in the matrix. - >>> A = new(lib.GrB_UINT8, 2, 3) - >>> nvals(A) + >>> A = matrix_new(lib.GrB_UINT8, 2, 3) + >>> matrix_nvals(A) 0 """ @@ -89,22 +89,22 @@ def nvals(A): return n[0] -def shape(A): +def matrix_shape(A): """Return the shape of the matrix as a two tuple `(nrows, ncols)` - >>> A = new(lib.GrB_UINT8, 2, 2) - >>> shape(A) + >>> A = matrix_new(lib.GrB_UINT8, 2, 2) + >>> matrix_shape(A) (2, 2) """ - return (nrows(A), ncols(A)) + return (matrix_nrows(A), matrix_ncols(A)) -def format(A): +def matrix_format(A): """Return the format of the matrix. - >>> A = new(lib.GrB_UINT8, 2, 2) - >>> format(A) == lib.GxB_BY_ROW + >>> A = matrix_new(lib.GrB_UINT8, 2, 2) + >>> matrix_format(A) == lib.GxB_BY_ROW True """ @@ -113,12 +113,12 @@ def format(A): return format[0] -def set_format(A, format): +def matrix_set_format(A, format): """Set the format of the matrix. - >>> A = new(lib.GrB_UINT8, 2, 2) - >>> set_format(A, lib.GxB_BY_COL) - >>> format(A) == lib.GxB_BY_COL + >>> A = matrix_new(lib.GrB_UINT8, 2, 2) + >>> matrix_set_format(A, lib.GxB_BY_COL) + >>> matrix_format(A) == lib.GxB_BY_COL True """ @@ -126,14 +126,14 @@ def set_format(A, format): check_status(A, lib.GxB_Matrix_Option_set_INT32(A[0], lib.GxB_FORMAT, format_val)) -def sparsity_status(A): +def matrix_sparsity_status(A): """Get the sparsity status of the matrix.""" sparsity_status = ffi.new("int32_t*") check_status(A, lib.GxB_Matrix_Option_get_INT32(A[0], lib.GxB_SPARSITY_STATUS, sparsity_status)) return sparsity_status[0] -def sparsity_control(A): +def matrix_sparsity_control(A): """Get the sparsity control of the matrix.""" sparsity_control = ffi.new("int32_t*") check_status( @@ -142,7 +142,7 @@ def sparsity_control(A): return sparsity_control[0] -def set_sparsity_control(A, sparsity): +def matrix_set_sparsity_control(A, sparsity): """Set the sparsity control of the matrix.""" sparsity_control = ffi.cast("int32_t", sparsity) check_status( @@ -150,27 +150,27 @@ def set_sparsity_control(A, sparsity): ) -def hyper_switch(A): +def matrix_hyper_switch(A): """Get the hyper switch of the matrix.""" hyper_switch = ffi.new("double*") check_status(A, lib.GxB_Matrix_Option_get_FP64(A[0], lib.GxB_HYPER_SWITCH, hyper_switch)) return hyper_switch[0] -def set_hyper_switch(A, hyper_switch): +def matrix_set_hyper_switch(A, hyper_switch): """Set the hyper switch of the matrix.""" hyper_switch = ffi.cast("double", hyper_switch) check_status(A, lib.GxB_Matrix_Option_set_FP64(A[0], lib.GxB_HYPER_SWITCH, hyper_switch)) -def bitmap_switch(A): +def matrix_bitmap_switch(A): """Get the bitmap switch of the matrix.""" bitmap_switch = ffi.new("double*") check_status(A, lib.GxB_Matrix_Option_get_FP64(A[0], lib.GxB_BITMAP_SWITCH, bitmap_switch)) return bitmap_switch[0] -def set_bitmap_switch(A, bitmap_switch): +def matrix_set_bitmap_switch(A, bitmap_switch): """Set the bitmap switch of the matrix.""" bitmap_switch = ffi.cast("double", bitmap_switch) check_status(A, lib.GxB_Matrix_Option_set_FP64(A[0], lib.GxB_BITMAP_SWITCH, bitmap_switch)) @@ -179,7 +179,7 @@ def set_bitmap_switch(A, bitmap_switch): def set_bool(A, value, i, j): """Set a boolean value to the matrix at row `i` column `j`. - >>> A = new(lib.GrB_BOOL, 3, 3) + >>> A = matrix_new(lib.GrB_BOOL, 3, 3) >>> set_bool(A, True, 2, 2) >>> get_bool(A, 2, 2) == True True @@ -191,7 +191,7 @@ def set_bool(A, value, i, j): def get_bool(A, i, j): """Get a boolean value from the matrix at row `i` column `j`. - >>> A = new(lib.GrB_BOOL, 3, 3) + >>> A = matrix_new(lib.GrB_BOOL, 3, 3) >>> set_bool(A, True, 2, 2) >>> get_bool(A, 2, 2) == True True @@ -205,7 +205,7 @@ def get_bool(A, i, j): def set_int8(A, value, i, j): """Set an int8 value to the matrix at row `i` column `j`. - >>> A = new(lib.GrB_INT8, 3, 3) + >>> A = matrix_new(lib.GrB_INT8, 3, 3) >>> set_int8(A, 7, 2, 2) >>> get_int8(A, 2, 2) == 7 True @@ -217,7 +217,7 @@ def set_int8(A, value, i, j): def get_int8(A, i, j): """Get an int8 value from the matrix at row `i` column `j`. - >>> A = new(lib.GrB_INT8, 3, 3) + >>> A = matrix_new(lib.GrB_INT8, 3, 3) >>> set_int8(A, 7, 2, 2) >>> get_int8(A, 2, 2) == 7 True @@ -231,7 +231,7 @@ def get_int8(A, i, j): def set_int16(A, value, i, j): """Set an int16 value to the matrix at row `i` column `j`. - >>> A = new(lib.GrB_INT16, 3, 3) + >>> A = matrix_new(lib.GrB_INT16, 3, 3) >>> set_int16(A, 7, 2, 2) >>> get_int16(A, 2, 2) == 7 True @@ -243,7 +243,7 @@ def set_int16(A, value, i, j): def get_int16(A, i, j): """Get an int16 value from the matrix at row `i` column `j`. - >>> A = new(lib.GrB_INT16, 3, 3) + >>> A = matrix_new(lib.GrB_INT16, 3, 3) >>> set_int16(A, 7, 2, 2) >>> get_int16(A, 2, 2) == 7 True @@ -257,7 +257,7 @@ def get_int16(A, i, j): def set_int32(A, value, i, j): """Set an int32 value to the matrix at row `i` column `j`. - >>> A = new(lib.GrB_INT32, 3, 3) + >>> A = matrix_new(lib.GrB_INT32, 3, 3) >>> set_int32(A, 7, 2, 2) >>> get_int32(A, 2, 2) == 7 True @@ -269,7 +269,7 @@ def set_int32(A, value, i, j): def get_int32(A, i, j): """Get an int32 value from the matrix at row `i` column `j`. - >>> A = new(lib.GrB_INT32, 3, 3) + >>> A = matrix_new(lib.GrB_INT32, 3, 3) >>> set_int32(A, 7, 2, 2) >>> get_int32(A, 2, 2) == 7 True @@ -283,7 +283,7 @@ def get_int32(A, i, j): def set_int64(A, value, i, j): """Set an int64 value to the matrix at row `i` column `j`. - >>> A = new(lib.GrB_INT64, 3, 3) + >>> A = matrix_new(lib.GrB_INT64, 3, 3) >>> set_int64(A, 7, 2, 2) >>> get_int64(A, 2, 2) == 7 True @@ -295,7 +295,7 @@ def set_int64(A, value, i, j): def get_int64(A, i, j): """Get an int64 value from the matrix at row `i` column `j`. - >>> A = new(lib.GrB_INT64, 3, 3) + >>> A = matrix_new(lib.GrB_INT64, 3, 3) >>> set_int64(A, 7, 2, 2) >>> get_int64(A, 2, 2) == 7 True @@ -309,7 +309,7 @@ def get_int64(A, i, j): def set_uint8(A, value, i, j): """Set a uint8 value to the matrix at row `i` column `j`. - >>> A = new(lib.GrB_UINT8, 3, 3) + >>> A = matrix_new(lib.GrB_UINT8, 3, 3) >>> set_uint8(A, 7, 2, 2) >>> get_uint8(A, 2, 2) == 7 True @@ -321,7 +321,7 @@ def set_uint8(A, value, i, j): def get_uint8(A, i, j): """Get a uint8 value from the matrix at row `i` column `j`. - >>> A = new(lib.GrB_UINT8, 3, 3) + >>> A = matrix_new(lib.GrB_UINT8, 3, 3) >>> set_uint8(A, 7, 2, 2) >>> get_uint8(A, 2, 2) == 7 True @@ -335,7 +335,7 @@ def get_uint8(A, i, j): def set_uint16(A, value, i, j): """Set a uint16 value to the matrix at row `i` column `j`. - >>> A = new(lib.GrB_UINT16, 3, 3) + >>> A = matrix_new(lib.GrB_UINT16, 3, 3) >>> set_uint16(A, 7, 2, 2) >>> get_uint16(A, 2, 2) == 7 True @@ -347,7 +347,7 @@ def set_uint16(A, value, i, j): def get_uint16(A, i, j): """Get a uint16 value from the matrix at row `i` column `j`. - >>> A = new(lib.GrB_UINT16, 3, 3) + >>> A = matrix_new(lib.GrB_UINT16, 3, 3) >>> set_uint16(A, 7, 2, 2) >>> get_uint16(A, 2, 2) == 7 True @@ -361,7 +361,7 @@ def get_uint16(A, i, j): def set_uint32(A, value, i, j): """Set a uint32 value to the matrix at row `i` column `j`. - >>> A = new(lib.GrB_UINT32, 3, 3) + >>> A = matrix_new(lib.GrB_UINT32, 3, 3) >>> set_uint32(A, 7, 2, 2) >>> get_uint32(A, 2, 2) == 7 True @@ -373,7 +373,7 @@ def set_uint32(A, value, i, j): def get_uint32(A, i, j): """Get a uint32 value from the matrix at row `i` column `j`. - >>> A = new(lib.GrB_UINT32, 3, 3) + >>> A = matrix_new(lib.GrB_UINT32, 3, 3) >>> set_uint32(A, 7, 2, 2) >>> get_uint32(A, 2, 2) == 7 True @@ -387,7 +387,7 @@ def get_uint32(A, i, j): def set_uint64(A, value, i, j): """Set a uint64 value to the matrix at row `i` column `j`. - >>> A = new(lib.GrB_UINT64, 3, 3) + >>> A = matrix_new(lib.GrB_UINT64, 3, 3) >>> set_uint64(A, 7, 2, 2) >>> get_uint64(A, 2, 2) == 7 True @@ -399,7 +399,7 @@ def set_uint64(A, value, i, j): def get_uint64(A, i, j): """Get a uint64 value from the matrix at row `i` column `j`. - >>> A = new(lib.GrB_UINT64, 3, 3) + >>> A = matrix_new(lib.GrB_UINT64, 3, 3) >>> set_uint64(A, 7, 2, 2) >>> get_uint64(A, 2, 2) == 7 True @@ -413,7 +413,7 @@ def get_uint64(A, i, j): def set_fp32(A, value, i, j): """Set an fp32 value to the matrix at row `i` column `j`. - >>> A = new(lib.GrB_FP32, 3, 3) + >>> A = matrix_new(lib.GrB_FP32, 3, 3) >>> set_fp32(A, 1.5, 2, 2) >>> get_fp32(A, 2, 2) == 1.5 True @@ -425,7 +425,7 @@ def set_fp32(A, value, i, j): def get_fp32(A, i, j): """Get an fp32 value from the matrix at row `i` column `j`. - >>> A = new(lib.GrB_FP32, 3, 3) + >>> A = matrix_new(lib.GrB_FP32, 3, 3) >>> set_fp32(A, 1.5, 2, 2) >>> get_fp32(A, 2, 2) == 1.5 True @@ -439,7 +439,7 @@ def get_fp32(A, i, j): def set_fp64(A, value, i, j): """Set an fp64 value to the matrix at row `i` column `j`. - >>> A = new(lib.GrB_FP64, 3, 3) + >>> A = matrix_new(lib.GrB_FP64, 3, 3) >>> set_fp64(A, 1.5, 2, 2) >>> get_fp64(A, 2, 2) == 1.5 True @@ -451,7 +451,7 @@ def set_fp64(A, value, i, j): def get_fp64(A, i, j): """Get an fp64 value from the matrix at row `i` column `j`. - >>> A = new(lib.GrB_FP64, 3, 3) + >>> A = matrix_new(lib.GrB_FP64, 3, 3) >>> set_fp64(A, 1.5, 2, 2) >>> get_fp64(A, 2, 2) == 1.5 True @@ -467,7 +467,7 @@ def get_fp64(A, i, j): def set_fc32(A, value, i, j): """Set an fc32 value to the matrix at row `i` column `j`. - >>> A = new(lib.GxB_FC32, 3, 3) + >>> A = matrix_new(lib.GxB_FC32, 3, 3) >>> set_fc32(A, 2+3j, 2, 2) >>> get_fc32(A, 2, 2) == 2+3j True @@ -478,7 +478,7 @@ def set_fc32(A, value, i, j): def get_fc32(A, i, j): """Get an fc32 value from the matrix at row `i` column `j`. - >>> A = new(lib.GxB_FC32, 3, 3) + >>> A = matrix_new(lib.GxB_FC32, 3, 3) >>> set_fc32(A, 2+3j, 2, 2) >>> get_fc32(A, 2, 2) == 2+3j True @@ -491,7 +491,7 @@ def get_fc32(A, i, j): def set_fc64(A, value, i, j): """Set an fc64 value to the matrix at row `i` column `j`. - >>> A = new(lib.GxB_FC64, 3, 3) + >>> A = matrix_new(lib.GxB_FC64, 3, 3) >>> set_fc64(A, 2+3j, 2, 2) >>> get_fc64(A, 2, 2) == 2+3j True @@ -502,7 +502,7 @@ def set_fc64(A, value, i, j): def get_fc64(A, i, j): """Get an fc64 value from the matrix at row `i` column `j`. - >>> A = new(lib.GxB_FC64, 3, 3) + >>> A = matrix_new(lib.GxB_FC64, 3, 3) >>> set_fc64(A, 2+3j, 2, 2) >>> get_fc64(A, 2, 2) == 2+3j True diff --git a/suitesparse_graphblas/scalar.py b/suitesparse_graphblas/scalar.py index 4be4816..289ca51 100644 --- a/suitesparse_graphblas/scalar.py +++ b/suitesparse_graphblas/scalar.py @@ -1,20 +1,20 @@ from suitesparse_graphblas import check_status, exceptions, ffi, lib, supports_complex -def free(v): +def scalar_free(v): """Free a scalar.""" check_status(v, lib.GxB_Scalar_free(v)) -def new(T, *, free=free): +def scalar_new(T, *, free=scalar_free): """Create a new `GxB_Scalar` of type `T` and initialize it. The `free` argument is called when the object is garbage - collected, the default is `scalar.free()`. If `free` is None then + collected, the default is `scalar.scalar_free()`. If `free` is None then there is no automatic garbage collection and it is up to the user to free the scalar. - >>> S = new(lib.GrB_UINT8) + >>> S = scalar_new(lib.GrB_UINT8) """ s = ffi.new("GxB_Scalar*") @@ -24,11 +24,11 @@ def new(T, *, free=free): return s -def type(s): +def scalar_type(s): """Return the GraphBLAS type of the scalar. - >>> S = new(lib.GrB_UINT8) - >>> type(S) == lib.GrB_UINT8 + >>> S = scalar_new(lib.GrB_UINT8) + >>> scalar_type(S) == lib.GrB_UINT8 True """ @@ -40,7 +40,7 @@ def type(s): def set_bool(s, value): """Set a boolean value to the scalar. - >>> s = new(lib.GrB_BOOL) + >>> s = scalar_new(lib.GrB_BOOL) >>> set_bool(s, True) >>> get_bool(s) == True True @@ -52,7 +52,7 @@ def set_bool(s, value): def get_bool(s): """Get a boolean value from the scalar. - >>> s = new(lib.GrB_BOOL) + >>> s = scalar_new(lib.GrB_BOOL) >>> set_bool(s, True) >>> get_bool(s) == True True @@ -68,7 +68,7 @@ def get_bool(s): def set_int8(s, value): """Set an int8 value to the scalar. - >>> s = new(lib.GrB_INT8) + >>> s = scalar_new(lib.GrB_INT8) >>> set_int8(s, 7) >>> get_int8(s) == 7 True @@ -80,7 +80,7 @@ def set_int8(s, value): def get_int8(s): """Get an int8 value from the scalar. - >>> s = new(lib.GrB_INT8) + >>> s = scalar_new(lib.GrB_INT8) >>> set_int8(s, 7) >>> get_int8(s) == 7 True @@ -96,7 +96,7 @@ def get_int8(s): def set_int16(s, value): """Set an int16 value to the scalar. - >>> s = new(lib.GrB_INT16) + >>> s = scalar_new(lib.GrB_INT16) >>> set_int16(s, 7) >>> get_int16(s) == 7 True @@ -108,7 +108,7 @@ def set_int16(s, value): def get_int16(s): """Get an int16 value from the scalar. - >>> s = new(lib.GrB_INT16) + >>> s = scalar_new(lib.GrB_INT16) >>> set_int16(s, 7) >>> get_int16(s) == 7 True @@ -124,7 +124,7 @@ def get_int16(s): def set_int32(s, value): """Set an int32 value to the scalar. - >>> s = new(lib.GrB_INT32) + >>> s = scalar_new(lib.GrB_INT32) >>> set_int32(s, 7) >>> get_int32(s) == 7 True @@ -136,7 +136,7 @@ def set_int32(s, value): def get_int32(s): """Get an int32 value from the scalar. - >>> s = new(lib.GrB_INT32) + >>> s = scalar_new(lib.GrB_INT32) >>> set_int32(s, 7) >>> get_int32(s) == 7 True @@ -152,7 +152,7 @@ def get_int32(s): def set_int64(s, value): """Set an int64 value to the scalar. - >>> s = new(lib.GrB_INT64) + >>> s = scalar_new(lib.GrB_INT64) >>> set_int64(s, 7) >>> get_int64(s) == 7 True @@ -164,7 +164,7 @@ def set_int64(s, value): def get_int64(s): """Get an int64 value from the scalar. - >>> s = new(lib.GrB_INT64) + >>> s = scalar_new(lib.GrB_INT64) >>> set_int64(s, 7) >>> get_int64(s) == 7 True @@ -180,7 +180,7 @@ def get_int64(s): def set_uint8(s, value): """Set a uint8 value to the scalar. - >>> s = new(lib.GrB_UINT8) + >>> s = scalar_new(lib.GrB_UINT8) >>> set_uint8(s, 7) >>> get_uint8(s) == 7 True @@ -192,7 +192,7 @@ def set_uint8(s, value): def get_uint8(s): """Get a uint8 value from the scalar. - >>> s = new(lib.GrB_UINT8) + >>> s = scalar_new(lib.GrB_UINT8) >>> set_uint8(s, 7) >>> get_uint8(s) == 7 True @@ -208,7 +208,7 @@ def get_uint8(s): def set_uint16(s, value): """Set a uint16 value to the scalar. - >>> s = new(lib.GrB_UINT16) + >>> s = scalar_new(lib.GrB_UINT16) >>> set_uint16(s, 7) >>> get_uint16(s) == 7 True @@ -220,7 +220,7 @@ def set_uint16(s, value): def get_uint16(s): """Get a uint16 value from the scalar. - >>> s = new(lib.GrB_UINT16) + >>> s = scalar_new(lib.GrB_UINT16) >>> set_uint16(s, 7) >>> get_uint16(s) == 7 True @@ -236,7 +236,7 @@ def get_uint16(s): def set_uint32(s, value): """Set a uint32 value to the scalar. - >>> s = new(lib.GrB_UINT32) + >>> s = scalar_new(lib.GrB_UINT32) >>> set_uint32(s, 7) >>> get_uint32(s) == 7 True @@ -248,7 +248,7 @@ def set_uint32(s, value): def get_uint32(s): """Get a uint32 value from the scalar. - >>> s = new(lib.GrB_UINT32) + >>> s = scalar_new(lib.GrB_UINT32) >>> set_uint32(s, 7) >>> get_uint32(s) == 7 True @@ -264,7 +264,7 @@ def get_uint32(s): def set_uint64(s, value): """Set a uint64 value to the scalar. - >>> s = new(lib.GrB_UINT64) + >>> s = scalar_new(lib.GrB_UINT64) >>> set_uint64(s, 7) >>> get_uint64(s) == 7 True @@ -276,7 +276,7 @@ def set_uint64(s, value): def get_uint64(s): """Get a uint64 value from the scalar. - >>> s = new(lib.GrB_UINT64) + >>> s = scalar_new(lib.GrB_UINT64) >>> set_uint64(s, 7) >>> get_uint64(s) == 7 True @@ -292,7 +292,7 @@ def get_uint64(s): def set_fp32(s, value): """Set an fp32 value to the scalar. - >>> s = new(lib.GrB_FP32) + >>> s = scalar_new(lib.GrB_FP32) >>> set_fp32(s, 1.5) >>> get_fp32(s) == 1.5 True @@ -304,7 +304,7 @@ def set_fp32(s, value): def get_fp32(s): """Get an fp32 value from the scalar. - >>> s = new(lib.GrB_FP32) + >>> s = scalar_new(lib.GrB_FP32) >>> set_fp32(s, 1.5) >>> get_fp32(s) == 1.5 True @@ -320,7 +320,7 @@ def get_fp32(s): def set_fp64(s, value): """Set an fp64 value to the scalar. - >>> s = new(lib.GrB_FP64) + >>> s = scalar_new(lib.GrB_FP64) >>> set_fp64(s, 1.5) >>> get_fp64(s) == 1.5 True @@ -332,7 +332,7 @@ def set_fp64(s, value): def get_fp64(s): """Get an fp64 value from the scalar. - >>> s = new(lib.GrB_FP64) + >>> s = scalar_new(lib.GrB_FP64) >>> set_fp64(s, 1.5) >>> get_fp64(s) == 1.5 True @@ -350,7 +350,7 @@ def get_fp64(s): def set_fc32(s, value): """Set an fc32 value to the scalar. - >>> s = new(lib.GxB_FC32) + >>> s = scalar_new(lib.GxB_FC32) >>> set_fc32(s, 2+3j) >>> get_fc32(s) == 2+3j True @@ -361,7 +361,7 @@ def set_fc32(s, value): def get_fc32(s): """Get an fc32 value from the scalar. - >>> s = new(lib.GxB_FC32) + >>> s = scalar_new(lib.GxB_FC32) >>> set_fc32(s, 2+3j) >>> get_fc32(s) == 2+3j True @@ -376,7 +376,7 @@ def get_fc32(s): def set_fc64(s, value): """Set an fc64 value to the scalar. - >>> s = new(lib.GxB_FC64) + >>> s = scalar_new(lib.GxB_FC64) >>> set_fc64(s, 2+3j) >>> get_fc64(s) == 2+3j True @@ -387,7 +387,7 @@ def set_fc64(s, value): def get_fc64(s): """Get an fc64 value from the scalar. - >>> s = new(lib.GxB_FC64) + >>> s = scalar_new(lib.GxB_FC64) >>> set_fc64(s, 2+3j) >>> get_fc64(s) == 2+3j True diff --git a/suitesparse_graphblas/tests/test_io.py b/suitesparse_graphblas/tests/test_io.py index dcdf857..7b4c899 100644 --- a/suitesparse_graphblas/tests/test_io.py +++ b/suitesparse_graphblas/tests/test_io.py @@ -90,7 +90,7 @@ def _test_elements(T): def test_serialize_matrix(): T = lib.GrB_INT64 - A = matrix.new(T, 2, 2) + A = matrix.matrix_new(T, 2, 2) for args in zip(*_test_elements(T)): f = _element_setters[T] check_status(A, f(A[0], *args)) @@ -98,12 +98,12 @@ def test_serialize_matrix(): B = matrix.deserialize(data) # Test equal - C = matrix.new(lib.GrB_BOOL, 2, 2) + C = matrix.matrix_new(lib.GrB_BOOL, 2, 2) check_status( C, lib.GrB_Matrix_eWiseAdd_BinaryOp(C[0], NULL, NULL, _eq_ops[T], A[0], B[0], NULL), ) - assert matrix.nvals(A) == matrix.nvals(B) == matrix.nvals(C) + assert matrix.matrix_nvals(A) == matrix.matrix_nvals(B) == matrix.matrix_nvals(C) is_eq = ffi.new("bool*") check_status( C, @@ -114,19 +114,19 @@ def test_serialize_matrix(): def test_serialize_vector(): T = lib.GrB_INT64 - v = vector.new(T, 3) + v = vector.vector_new(T, 3) check_status(v, lib.GrB_Vector_setElement_INT64(v[0], 2, 0)) check_status(v, lib.GrB_Vector_setElement_INT64(v[0], 10, 1)) data = vector.serialize(v, lib.GxB_COMPRESSION_LZ4HC, level=7) w = vector.deserialize(data) # Test equal - x = vector.new(lib.GrB_BOOL, 3) + x = vector.vector_new(lib.GrB_BOOL, 3) check_status( x, lib.GrB_Vector_eWiseAdd_BinaryOp(x[0], NULL, NULL, _eq_ops[T], v[0], w[0], NULL), ) - assert vector.nvals(v) == vector.nvals(w) == vector.nvals(x) + assert vector.vector_nvals(v) == vector.vector_nvals(w) == vector.vector_nvals(x) is_eq = ffi.new("bool*") check_status( x, @@ -140,7 +140,7 @@ def test_matrix_binfile_read_write(tmp_path): for format in (lib.GxB_BY_ROW, lib.GxB_BY_COL): for T in grb_types: for sparsity in (lib.GxB_HYPERSPARSE, lib.GxB_SPARSE, lib.GxB_BITMAP, lib.GxB_FULL): - A = matrix.new(T, 2, 2) + A = matrix.matrix_new(T, 2, 2) if T is not lib.GxB_FULL: for args in zip(*_test_elements(T)): @@ -162,21 +162,21 @@ def test_matrix_binfile_read_write(tmp_path): NULL, ), ) - matrix.set_sparsity_control(A, sparsity) - matrix.set_format(A, format) + matrix.matrix_set_sparsity_control(A, sparsity) + matrix.matrix_set_format(A, format) binfilef = tmp_path / "binfilewrite_test.binfile" binary.binwrite(A, binfilef, opener=opener) B = binary.binread(binfilef, opener=opener) - assert matrix.type(A) == matrix.type(B) - assert matrix.nrows(A) == matrix.nrows(B) - assert matrix.ncols(A) == matrix.ncols(B) - assert matrix.hyper_switch(A) == matrix.hyper_switch(B) - assert matrix.bitmap_switch(A) == matrix.bitmap_switch(B) - # assert matrix.sparsity_control(A) == matrix.sparsity_control(B) + assert matrix.matrix_type(A) == matrix.matrix_type(B) + assert matrix.matrix_nrows(A) == matrix.matrix_nrows(B) + assert matrix.matrix_ncols(A) == matrix.matrix_ncols(B) + assert matrix.matrix_hyper_switch(A) == matrix.matrix_hyper_switch(B) + assert matrix.matrix_bitmap_switch(A) == matrix.matrix_bitmap_switch(B) + # assert matrix.matrix_sparsity_control(A) == matrix.matrix_sparsity_control(B) - C = matrix.new(lib.GrB_BOOL, 2, 2) + C = matrix.matrix_new(lib.GrB_BOOL, 2, 2) check_status( C, @@ -185,7 +185,7 @@ def test_matrix_binfile_read_write(tmp_path): ), ) - assert matrix.nvals(A) == matrix.nvals(B) == matrix.nvals(C) + assert matrix.matrix_nvals(A) == matrix.matrix_nvals(B) == matrix.matrix_nvals(C) is_eq = ffi.new("bool*") check_status( diff --git a/suitesparse_graphblas/vector.py b/suitesparse_graphblas/vector.py index bd7b73c..66f9a5e 100644 --- a/suitesparse_graphblas/vector.py +++ b/suitesparse_graphblas/vector.py @@ -4,26 +4,26 @@ from .io.serialize import serialize_vector as serialize # noqa: F401 -def free(v): +def vector_free(v): """Free a vector.""" check_status(v, lib.GrB_Vector_free(v)) -def new(T, size=lib.GxB_INDEX_MAX, *, free=free): +def vector_new(T, size=lib.GxB_INDEX_MAX, *, free=vector_free): """Create a new `GrB_Vector` of type `T` and initialize it. - >>> A = new(lib.GrB_UINT8, 2) - >>> size(A) + >>> A = vector_new(lib.GrB_UINT8, 2) + >>> vector_size(A) 2 The default `size` is `lib.GxB_INDEX_MAX`. - >>> A = new(lib.GrB_UINT8) - >>> size(A) == lib.GxB_INDEX_MAX + >>> A = vector_new(lib.GrB_UINT8) + >>> vector_size(A) == lib.GxB_INDEX_MAX True The `free` argument is called when the object is garbage - collected, the default is `vector.free()`. If `free` is None then + collected, the default is `vector.vector_free()`. If `free` is None then there is no automatic garbage collection and it is up to the user to free the vector. """ @@ -34,11 +34,11 @@ def new(T, size=lib.GxB_INDEX_MAX, *, free=free): return v -def type(v): +def vector_type(v): """Return the GraphBLAS type of the vector. - >>> v = new(lib.GrB_UINT8, 2) - >>> type(v) == lib.GrB_UINT8 + >>> v = vector_new(lib.GrB_UINT8, 2) + >>> vector_type(v) == lib.GrB_UINT8 True @@ -48,11 +48,11 @@ def type(v): return T[0] -def size(v): +def vector_size(v): """Return the size of the vector. - >>> v = new(lib.GrB_UINT8, 2) - >>> size(v) == 2 + >>> v = vector_new(lib.GrB_UINT8, 2) + >>> vector_size(v) == 2 True """ @@ -61,14 +61,14 @@ def size(v): return n[0] -def nvals(v): +def vector_nvals(v): """Return the number of stored elements in the vector. - >>> v = new(lib.GrB_BOOL, 2) - >>> nvals(v) + >>> v = vector_new(lib.GrB_BOOL, 2) + >>> vector_nvals(v) 0 >>> set_bool(v, True, 1) - >>> nvals(v) + >>> vector_nvals(v) 1 """ @@ -80,7 +80,7 @@ def nvals(v): def set_bool(v, value, i): """Set a boolean value to the vector at position `i`. - >>> v = new(lib.GrB_BOOL, 3) + >>> v = vector_new(lib.GrB_BOOL, 3) >>> set_bool(v, True, 2) >>> get_bool(v, 2) == True True @@ -92,7 +92,7 @@ def set_bool(v, value, i): def get_bool(v, i): """Get a boolean value from the vector at position `i`. - >>> v = new(lib.GrB_BOOL, 3) + >>> v = vector_new(lib.GrB_BOOL, 3) >>> set_bool(v, True, 2) >>> get_bool(v, 2) == True True @@ -106,7 +106,7 @@ def get_bool(v, i): def set_int8(v, value, i): """Set an int8 value to the vector at position `i`. - >>> v = new(lib.GrB_INT8, 3) + >>> v = vector_new(lib.GrB_INT8, 3) >>> set_int8(v, 7, 2) >>> get_int8(v, 2) == 7 True @@ -118,7 +118,7 @@ def set_int8(v, value, i): def get_int8(v, i): """Get an int8 value from the vector at position `i`. - >>> v = new(lib.GrB_INT8, 3) + >>> v = vector_new(lib.GrB_INT8, 3) >>> set_int8(v, 7, 2) >>> get_int8(v, 2) == 7 True @@ -132,7 +132,7 @@ def get_int8(v, i): def set_int16(v, value, i): """Set an int16 value to the vector at position `i`. - >>> v = new(lib.GrB_INT16, 3) + >>> v = vector_new(lib.GrB_INT16, 3) >>> set_int16(v, 7, 2) >>> get_int16(v, 2) == 7 True @@ -144,7 +144,7 @@ def set_int16(v, value, i): def get_int16(v, i): """Get an int16 value from the vector at position `i`. - >>> v = new(lib.GrB_INT16, 3) + >>> v = vector_new(lib.GrB_INT16, 3) >>> set_int16(v, 7, 2) >>> get_int16(v, 2) == 7 True @@ -158,7 +158,7 @@ def get_int16(v, i): def set_int32(v, value, i): """Set an int32 value to the vector at position `i`. - >>> v = new(lib.GrB_INT32, 3) + >>> v = vector_new(lib.GrB_INT32, 3) >>> set_int32(v, 7, 2) >>> get_int32(v, 2) == 7 True @@ -170,7 +170,7 @@ def set_int32(v, value, i): def get_int32(v, i): """Get an int32 value from the vector at position `i`. - >>> v = new(lib.GrB_INT32, 3) + >>> v = vector_new(lib.GrB_INT32, 3) >>> set_int32(v, 7, 2) >>> get_int32(v, 2) == 7 True @@ -184,7 +184,7 @@ def get_int32(v, i): def set_int64(v, value, i): """Set an int64 value to the vector at position `i`. - >>> v = new(lib.GrB_INT64, 3) + >>> v = vector_new(lib.GrB_INT64, 3) >>> set_int64(v, 7, 2) >>> get_int64(v, 2) == 7 True @@ -196,7 +196,7 @@ def set_int64(v, value, i): def get_int64(v, i): """Get an int64 value from the vector at position `i`. - >>> v = new(lib.GrB_INT64, 3) + >>> v = vector_new(lib.GrB_INT64, 3) >>> set_int64(v, 7, 2) >>> get_int64(v, 2) == 7 True @@ -210,7 +210,7 @@ def get_int64(v, i): def set_uint8(v, value, i): """Set a uint8 value to the vector at position `i`. - >>> v = new(lib.GrB_UINT8, 3) + >>> v = vector_new(lib.GrB_UINT8, 3) >>> set_uint8(v, 7, 2) >>> get_uint8(v, 2) == 7 True @@ -222,7 +222,7 @@ def set_uint8(v, value, i): def get_uint8(v, i): """Get a uint8 value from the vector at position `i`. - >>> v = new(lib.GrB_UINT8, 3) + >>> v = vector_new(lib.GrB_UINT8, 3) >>> set_uint8(v, 7, 2) >>> get_uint8(v, 2) == 7 True @@ -236,7 +236,7 @@ def get_uint8(v, i): def set_uint16(v, value, i): """Set a uint16 value to the vector at position `i`. - >>> v = new(lib.GrB_UINT16, 3) + >>> v = vector_new(lib.GrB_UINT16, 3) >>> set_uint16(v, 7, 2) >>> get_uint16(v, 2) == 7 True @@ -248,7 +248,7 @@ def set_uint16(v, value, i): def get_uint16(v, i): """Get a uint16 value from the vector at position `i`. - >>> v = new(lib.GrB_UINT16, 3) + >>> v = vector_new(lib.GrB_UINT16, 3) >>> set_uint16(v, 7, 2) >>> get_uint16(v, 2) == 7 True @@ -262,7 +262,7 @@ def get_uint16(v, i): def set_uint32(v, value, i): """Set a uint32 value to the vector at position `i`. - >>> v = new(lib.GrB_UINT32, 3) + >>> v = vector_new(lib.GrB_UINT32, 3) >>> set_uint32(v, 7, 2) >>> get_uint32(v, 2) == 7 True @@ -274,7 +274,7 @@ def set_uint32(v, value, i): def get_uint32(v, i): """Get a uint32 value from the vector at position `i`. - >>> v = new(lib.GrB_UINT32, 3) + >>> v = vector_new(lib.GrB_UINT32, 3) >>> set_uint32(v, 7, 2) >>> get_uint32(v, 2) == 7 True @@ -288,7 +288,7 @@ def get_uint32(v, i): def set_uint64(v, value, i): """Set a uint64 value to the vector at position `i`. - >>> v = new(lib.GrB_UINT64, 3) + >>> v = vector_new(lib.GrB_UINT64, 3) >>> set_uint64(v, 7, 2) >>> get_uint64(v, 2) == 7 True @@ -300,7 +300,7 @@ def set_uint64(v, value, i): def get_uint64(v, i): """Get a uint64 value from the vector at position `i`. - >>> v = new(lib.GrB_UINT64, 3) + >>> v = vector_new(lib.GrB_UINT64, 3) >>> set_uint64(v, 7, 2) >>> get_uint64(v, 2) == 7 True @@ -314,7 +314,7 @@ def get_uint64(v, i): def set_fp32(v, value, i): """Set an fp32 value to the vector at position `i`. - >>> v = new(lib.GrB_FP32, 3) + >>> v = vector_new(lib.GrB_FP32, 3) >>> set_fp32(v, 1.5, 2) >>> get_fp32(v, 2) == 1.5 True @@ -326,7 +326,7 @@ def set_fp32(v, value, i): def get_fp32(v, i): """Get an fp32 value from the vector at position `i`. - >>> v = new(lib.GrB_FP32, 3) + >>> v = vector_new(lib.GrB_FP32, 3) >>> set_fp32(v, 1.5, 2) >>> get_fp32(v, 2) == 1.5 True @@ -340,7 +340,7 @@ def get_fp32(v, i): def set_fp64(v, value, i): """Set an fp64 value to the vector at position `i`. - >>> v = new(lib.GrB_FP64, 3) + >>> v = vector_new(lib.GrB_FP64, 3) >>> set_fp64(v, 1.5, 2) >>> get_fp64(v, 2) == 1.5 True @@ -352,7 +352,7 @@ def set_fp64(v, value, i): def get_fp64(v, i): """Get an fp64 value from the vector at position `i`. - >>> v = new(lib.GrB_FP64, 3) + >>> v = vector_new(lib.GrB_FP64, 3) >>> set_fp64(v, 1.5, 2) >>> get_fp64(v, 2) == 1.5 True @@ -368,7 +368,7 @@ def get_fp64(v, i): def set_fc32(v, value, i): """Set an fc32 value to the vector at position `i`. - >>> v = new(lib.GxB_FC32, 3) + >>> v = vector_new(lib.GxB_FC32, 3) >>> set_fc32(v, 2+3j, 2) >>> get_fc32(v, 2) == 2+3j True @@ -379,7 +379,7 @@ def set_fc32(v, value, i): def get_fc32(v, i): """Get an fc32 value from the vector at position `i`. - >>> v = new(lib.GxB_FC32, 3) + >>> v = vector_new(lib.GxB_FC32, 3) >>> set_fc32(v, 2+3j, 2) >>> get_fc32(v, 2) == 2+3j True @@ -392,7 +392,7 @@ def get_fc32(v, i): def set_fc64(v, value, i): """Set an fc64 value to the vector at position `i`. - >>> v = new(lib.GxB_FC64, 3) + >>> v = vector_new(lib.GxB_FC64, 3) >>> set_fc64(v, 2+3j, 2) >>> get_fc64(v, 2) == 2+3j True @@ -403,7 +403,7 @@ def set_fc64(v, value, i): def get_fc64(v, i): """Get an fc64 value from the vector at position `i`. - >>> v = new(lib.GxB_FC64, 3) + >>> v = vector_new(lib.GxB_FC64, 3) >>> set_fc64(v, 2+3j, 2) >>> get_fc64(v, 2) == 2+3j True From 8d4c1dae88ea5af07aa0163bd958425aafaff07d Mon Sep 17 00:00:00 2001 From: Michel Pelletier Date: Thu, 9 Apr 2026 07:13:10 -0700 Subject: [PATCH 5/5] Wrap long assert line in test_io.py for Black The `matrix.nvals` -> `matrix.matrix_nvals` rename pushed the triple equality in `test_matrix_binfile_read_write` to 101 characters, exceeding the project's 100-char line length. Apply Black's suggested parenthesized wrap to bring it back under the limit. --- suitesparse_graphblas/tests/test_io.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/suitesparse_graphblas/tests/test_io.py b/suitesparse_graphblas/tests/test_io.py index 7b4c899..a06afb9 100644 --- a/suitesparse_graphblas/tests/test_io.py +++ b/suitesparse_graphblas/tests/test_io.py @@ -185,7 +185,9 @@ def test_matrix_binfile_read_write(tmp_path): ), ) - assert matrix.matrix_nvals(A) == matrix.matrix_nvals(B) == matrix.matrix_nvals(C) + assert ( + matrix.matrix_nvals(A) == matrix.matrix_nvals(B) == matrix.matrix_nvals(C) + ) is_eq = ffi.new("bool*") check_status(