Skip to content

Keep broadcasts over views of dense arrays sparse - #772

Open
ViralBShah wants to merge 1 commit into
mainfrom
broadcast-dense-views
Open

Keep broadcasts over views of dense arrays sparse#772
ViralBShah wants to merge 1 commit into
mainfrom
broadcast-dense-views

Conversation

@ViralBShah

Copy link
Copy Markdown
Member

Fixes #508.

Broadcasting a sparse array against a dense Matrix stays sparse, but doing
the same against a view of that matrix silently produced a dense result:

julia> A = sprand(5, 5, 0.3); B = rand(5, 5);

julia> typeof(A .* B)
SparseMatrixCSC{Float64, Int64}

julia> typeof(A .* view(B, :, :))
Matrix{Float64}

The cause is is_supported_sparse_broadcast, which whitelists Array but
not SubArray. A view therefore answered false, and copy(::Broadcasted{PromoteToSparse})
diverted the whole expression to the generic dense path — losing both the
sparse result type and the structural zeros of A.

This recurses through SubArray to its parent, exactly as Transpose/Adjoint
are already handled one line above, so a view is supported whenever the array
it views is. That covers non-strided views (view(B, [1,3,5], :)) as well as
strided ones, and picks up views of sparse arrays at the same time. Arrays
that were unsupported before still divert to the dense fallback.

Tests cover dense views, adjoints of views, sparse views, broadcast!, and
that a zero-preserving op no longer fills in structural zeros.

🤖 Generated with Claude Code

https://claude.ai/code/session_01L8HenXTVrASo1sBZVGhpDQ

`is_supported_sparse_broadcast` only whitelisted `Array`, so any `SubArray`
of a dense array fell out of the `PromoteToSparse` path and diverted the
whole broadcast to the generic dense code: `A .* B` returned a
`SparseMatrixCSC` but `A .* view(B, :, :)` returned a `Matrix`.

Recurse through `SubArray` to its parent, the same way `Transpose`/`Adjoint`
are already handled. Views of sparse arrays are covered by this too.

Fixes #508.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8HenXTVrASo1sBZVGhpDQ
@codecov

codecov Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.19%. Comparing base (53690b3) to head (5b4df74).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #772   +/-   ##
=======================================
  Coverage   84.19%   84.19%           
=======================================
  Files          13       13           
  Lines        9403     9404    +1     
=======================================
+ Hits         7917     7918    +1     
  Misses       1486     1486           

☔ 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.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Elementwise multiplication by a view of a dense matrix gives a dense matrix

1 participant