@@ -308,7 +308,7 @@ function Base.similar(mat::CuSparseMatrixCOO, ::Type{T}, dims::Dims{2}) where {T
308308 new_rowInd = similar (mat. rowInd)
309309 new_colInd = similar (mat. colInd)
310310 new_nzVal = similar (mat. nzVal, T)
311- return CuSparseMatrixCOO (new_rowInd, new_colInd, new_nzVal, dims)
311+ return CuSparseMatrixCOO {T, Ti} (new_rowInd, new_colInd, new_nzVal, dims)
312312end
313313
314314function Base. similar (mat:: CuSparseMatrixBSR{Tv, Ti} , :: Type{T} , dims:: Dims{2} ) where {Tv, Ti, T}
@@ -478,57 +478,39 @@ Base.getindex(A::CuSparseMatrixCSR, ::Colon, j::Integer) = CuSparseVector(sparse
478478
479479function Base. getindex (A:: CuSparseVector{Tv, Ti} , i:: Integer ) where {Tv, Ti}
480480 @boundscheck checkbounds (A, i)
481- result = zero (Tv)
482- for k in 1 : nnz (A)
483- A. iPtr[k] == i && (result = sum_duplicate (result, A. nzVal[k]))
484- end
485- return result
481+ ii = searchsortedfirst (A. iPtr, convert (Ti, i))
482+ (ii > nnz (A) || A. iPtr[ii] != i) && return zero (Tv)
483+ A. nzVal[ii]
486484end
487485
488- # Scalar getindex methods linear-scan the minor axis rather than binary-searching
489- # and sum across matching entries. cuSPARSE formats don't guarantee sorted indices
490- # within a major-axis slice (e.g. SpGEMM output may leave CSR columns unsorted
491- # within a row, and COO is only guaranteed row-sorted), nor uniqueness — duplicate
492- # (i, j) entries are permitted and their values sum, matching the convention of
493- # Julia's `sparse()` constructor and SciPy/CuPy. For Bool we OR instead of sum,
494- # also matching `sparse()`, since Bool + Bool doesn't stay Bool.
495- sum_duplicate (a, b) = a + b
496- sum_duplicate (a:: Bool , b:: Bool ) = a | b
497-
498486function Base. getindex (A:: CuSparseMatrixCSC{T} , i0:: Integer , i1:: Integer ) where T
499487 @boundscheck checkbounds (A, i0, i1)
500488 r1 = Int (A. colPtr[i1])
501489 r2 = Int (A. colPtr[i1+ 1 ]- 1 )
502- result = zero (T)
503- for k in r1: r2
504- rowvals (A)[k] == i0 && (result = sum_duplicate (result, nonzeros (A)[k]))
505- end
506- return result
490+ (r1 > r2) && return zero (T)
491+ r1 = searchsortedfirst (rowvals (A), i0, r1, r2, Base. Order. Forward)
492+ (r1 > r2 || rowvals (A)[r1] != i0) && return zero (T)
493+ nonzeros (A)[r1]
507494end
508495
509496function Base. getindex (A:: CuSparseMatrixCSR{T} , i0:: Integer , i1:: Integer ) where T
510497 @boundscheck checkbounds (A, i0, i1)
511498 c1 = Int (A. rowPtr[i0])
512499 c2 = Int (A. rowPtr[i0+ 1 ]- 1 )
513- result = zero (T)
514- for k in c1: c2
515- A. colVal[k] == i1 && (result = sum_duplicate (result, nonzeros (A)[k]))
516- end
517- return result
500+ (c1 > c2) && return zero (T)
501+ c1 = searchsortedfirst (A. colVal, i1, c1, c2, Base. Order. Forward)
502+ (c1 > c2 || A. colVal[c1] != i1) && return zero (T)
503+ nonzeros (A)[c1]
518504end
519505
520506function Base. getindex (A:: CuSparseMatrixCOO{T} , i0:: Integer , i1:: Integer ) where T
521507 @boundscheck checkbounds (A, i0, i1)
522- # cuSPARSE only guarantees COO is sorted by row, so binary-search the row
523- # range but linear-scan for the column.
524508 r1 = searchsortedfirst (A. rowInd, i0, Base. Order. Forward)
525509 (r1 > length (A. rowInd) || A. rowInd[r1] > i0) && return zero (T)
526- r2 = searchsortedlast (A. rowInd, i0, Base. Order. Forward)
527- result = zero (T)
528- for k in r1: r2
529- A. colInd[k] == i1 && (result = sum_duplicate (result, nonzeros (A)[k]))
530- end
531- return result
510+ r2 = min (searchsortedfirst (A. rowInd, i0+ 1 , Base. Order. Forward), length (A. rowInd))
511+ c1 = searchsortedfirst (A. colInd, i1, r1, r2, Base. Order. Forward)
512+ (c1 > r2 || c1 == length (A. colInd) + 1 || A. colInd[c1] > i1) && return zero (T)
513+ nonzeros (A)[c1]
532514end
533515
534516function Base. getindex (A:: CuSparseMatrixBSR{T} , i0:: Integer , i1:: Integer ) where T
@@ -538,11 +520,10 @@ function Base.getindex(A::CuSparseMatrixBSR{T}, i0::Integer, i1::Integer) where
538520 block_idx = (i0_idx - 1 ) * A. blockDim + i1_idx - 1
539521 c1 = Int (A. rowPtr[i0_block])
540522 c2 = Int (A. rowPtr[i0_block+ 1 ]- 1 )
541- result = zero (T)
542- for k in c1: c2
543- A. colVal[k] == i1_block && (result = sum_duplicate (result, nonzeros (A)[k+ block_idx]))
544- end
545- return result
523+ (c1 > c2) && return zero (T)
524+ c1 = searchsortedfirst (A. colVal, i1_block, c1, c2, Base. Order. Forward)
525+ (c1 > c2 || A. colVal[c1] != i1_block) && return zero (T)
526+ nonzeros (A)[c1+ block_idx]
546527end
547528
548529# matrix slices
0 commit comments