-
Notifications
You must be signed in to change notification settings - Fork 1
Sparse mapping refactor #63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #63 +/- ##
==========================================
- Coverage 76.70% 74.38% -2.33%
==========================================
Files 8 9 +1
Lines 601 648 +47
==========================================
+ Hits 461 482 +21
- Misses 140 166 +26
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Can you bump the version? |
I'm not entirely sure how I managed to locally get the BlockSparseArray tests to pass, as it seems like the downstream tests here are failing. Having a closer look here, it does seem to be the case that this is a bit of a breaking change, and I'm not sure if it is worth it to try to make it non-breaking. Let me know if you disagree though, I don't think it is impossible, but it is definitely cleaner to depend on |
So is the idea that this PR now expects |
The problem is actually the other way around: the downstream packages define |
Got it. So in this design, if an array type |
Yes, this is part of the changes I have here. I've implemented |
I think the part that is confusing me is that I don't see the logic where if only |
Looks good to me, ready to merge? |
Good to go for me! |
This PR is a slightly more careful implementation of the sparse mapping functionality.
The core logic consists of using a trait
ZeroPreserving
for determining whether or not a function preserves zeros.There are 3 modes:
NonPreserving
: map overeachindex
WeakPreserving
: map over each index where not all input values are 0.StrongPreserving
: map over each index where not any of the input values are 0.The logic seems to work as intended, and is decently flexible, but there are some questions left to tackle.
Currently, I still didn't handle dealing with cases where
zero(eltype(T))
does not exist. In principle I am okay with getting rid of this fallback definition, but that leads to a bunch of required specializations on top of the simple+
-
and*
due to these functions appearing in a wrapped form from the way broadcasting is passed tomap
.Also, there is a very interesting problem associated to
map!(f, C, As...)
where any or all of theAs
have overlapping memory withC
. Since we have to zero out the memory in general cases, as we might not be mapping over all indices, we also have to make a copy.This is handled by
unalias
, but might give unwanted copies:For example:
map!(identity, C1, C2)
withC1 = C2
would now lead to first copyingC2
, than zeroing outC1
, and finally moving the copiedC2
intoC1
. This happens for example with scalar multiplications of the formC .*= beta
, insparse_mul
.I can manually correct this behavior there, but just wanted to mention this.
I'll finish with the cleanup of the other functions etc after a first round of review?