Skip to content

Promote the index type over all sparse arguments in mixed sparse and dense cat - #1127

Open
ViralBShah wants to merge 1 commit into
mainfrom
vs/cat-promote-index-type
Open

ViralBShah wants to merge 1 commit into
mainfrom
vs/cat-promote-index-type

Conversation

@ViralBShah

Copy link
Copy Markdown
Member

A sparse/dense hcat, vcat or cat with a matrix result took its index type from the first argument, so the same blocks in another order could throw. The all-sparse methods already promote over every argument.

Before

julia> n = 2; A32 = spzeros(Float64, Int32, 1, n); A64 = spzeros(Float64, Int64, 3_000_000_000, n);

julia> vcat(A32, A64)
3000000001×2 SparseMatrixCSC{Float64, Int64} with 0 stored entries

julia> vcat(A64, A32, ones(1, n))
3000000002×2 SparseMatrixCSC{Float64, Int64} with 2 stored entries

julia> vcat(A32, A64, ones(1, n))
ERROR: ArgumentError: number of rows (m = 3000000002) does not fit in Ti = Int32

julia> hcat(A32', A64', ones(n, 1))
ERROR: ArgumentError: number of columns (n = 3000000002) does not fit in Ti = Int32

julia> cat(A32, A64, ones(1, n); dims=1)
ERROR: ArgumentError: number of rows (m = 3000000002) does not fit in Ti = Int32

After

julia> vcat(A32, A64, ones(1, n))
3000000002×2 SparseMatrixCSC{Float64, Int64} with 2 stored entries

julia> hcat(A32', A64', ones(n, 1))
2×3000000002 SparseMatrixCSC{Float64, Int64} with 2 stored entries

julia> cat(A32, A64, ones(1, n); dims=1)
3000000002×2 SparseMatrixCSC{Float64, Int64} with 2 stored entries

_sparse_cat_t_shaped, which hcat, vcat, cat and sparse_hcat/sparse_vcat share, chose the index type from the arguments after _makesparse. By then a dense array is an Int-indexed sparse matrix, so only the first argument was used. The callers now pass the original arguments, and _sparse_cat_t_shaped converts them itself. The index type keeps its old value, from the first argument or Int for a leading number, and is now promoted with the index type of every argument that is sparse (issparse). A dense argument after the first still adds nothing, so vcat(A32, ones(1, n)) stays Int32. The index type is still worked out from types alone, so the result type is still inferred.

Potential breakage: some calls that worked before now return a wider index type. One case is vcat(A8, A32, D), which gave Int8 and now gives Int32, as vcat(A8, A32) already does. Another is hcat(A32, I), which gave Int32 and now gives Int64. LinearAlgebra turns I into an Int-indexed sparse matrix before the call, and hcat(I, A32) and hvcat already gave Int64.

Left out: hvcat with dense blocks already promotes over all blocks, and it counts a dense block as Int. That behaviour is unchanged. A concatenation whose result is a vector still takes its index type from the first argument, through _catdest.

🤖 Generated with Claude Code

…dense `cat`

A mixed sparse/dense `hcat`, `vcat` or `cat` took the index type of its first argument,
so `vcat(A32, A64, ones(1, n))` threw when the result did not fit in `Int32`, while
`vcat(A64, A32, ones(1, n))` worked. The index type is now promoted over every sparse
argument; a dense argument other than the first still does not widen it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.71429% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 94.72%. Comparing base (48204b2) to head (4c5ac48).
⚠️ Report is 9 commits behind head on main.

Files with missing lines Patch % Lines
src/concatenation.jl 85.71% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1127   +/-   ##
=======================================
  Coverage   94.72%   94.72%           
=======================================
  Files          16       16           
  Lines       10310    10319    +9     
=======================================
+ Hits         9766     9775    +9     
  Misses        544      544           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant