Skip to content

Remove SparseArrays dependency #56

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

Merged
merged 14 commits into from
Oct 12, 2023

Conversation

devmotion
Copy link
Collaborator

This PR removes the SparseArrays dependency completely.

Only the implementation of == and +/- required a bit more code, otherwise not too many changes were needed.

Fixes #53.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 10, 2023

Benchmark Results

main 0bcc134... t[main]/t[0bcc134...]
Quantity/creation/Quantity(x) 4 ± 0.2 ns 3 ± 0.1 ns 1.33
Quantity/creation/Quantity(x, length=y) 4.2 ± 0.2 ns 3.9 ± 0.4 ns 1.08
Quantity/with_numbers/*real 3.6 ± 0.5 ns 3.8 ± 0.3 ns 0.947
Quantity/with_numbers/^int 12.3 ± 3.9 ns 11.9 ± 2.7 ns 1.03
Quantity/with_numbers/^int * real 13.3 ± 4 ns 12.5 ± 4.3 ns 1.06
Quantity/with_quantity/+y 6.3 ± 0.3 ns 6 ± 0.6 ns 1.05
Quantity/with_quantity//y 4.7 ± 0.2 ns 4.2 ± 0.4 ns 1.12
Quantity/with_self/dimension 1.8 ± 0.1 ns 1.9 ± 0.3 ns 0.947
Quantity/with_self/inv 4.5 ± 0.2 ns 3.9 ± 0.3 ns 1.15
Quantity/with_self/ustrip 1.9 ± 0.1 ns 1.9 ± 0.1 ns 1
QuantityArray/broadcasting/multi_array_of_quantities 0.351 ± 0.17 ms 0.348 ± 0.16 ms 1.01
QuantityArray/broadcasting/multi_normal_array 0.105 ± 0.022 ms 0.103 ± 0.029 ms 1.02
QuantityArray/broadcasting/multi_quantity_array 0.349 ± 0.041 ms 0.349 ± 0.043 ms 1
QuantityArray/broadcasting/x^2_array_of_quantities 0.0719 ± 0.014 ms 0.0713 ± 0.017 ms 1.01
QuantityArray/broadcasting/x^2_normal_array 12.7 ± 1.2 μs 12.2 ± 1.5 μs 1.04
QuantityArray/broadcasting/x^2_quantity_array 13 ± 1.2 μs 13 ± 10 μs 1
QuantityArray/broadcasting/x^4_array_of_quantities 0.184 ± 0.048 ms 0.185 ± 0.048 ms 0.995
QuantityArray/broadcasting/x^4_normal_array 0.0953 ± 0.018 ms 0.097 ± 0.025 ms 0.982
QuantityArray/broadcasting/x^4_quantity_array 0.119 ± 0.021 ms 0.116 ± 0.026 ms 1.03
time_to_load 0.226 ± 0.0087 s 0.29 ± 0.066 s 0.778

Benchmark Plots

A plot of the benchmark results have been uploaded as an artifact to the workflow run for this PR.
Go to "Actions"->"Benchmark a pull request"->[the most recent run]->"Artifacts" (at the bottom).

@MilesCranmer
Copy link
Member

Nice work!! Really appreciate your effort on this.

It will take me a bit longer to read through this one but I'll try to get to it soon.

@MilesCranmer
Copy link
Member

MilesCranmer commented Oct 10, 2023

I'm wondering (maybe I missed it) if there could be some filter! or deleteat! somewhere? Otherwise it seems like the vector of dimensions could keep growing.

e.g., each operation on SymbolicDimensions could end with something like

remove_zeros(v) = filter!(e->!iszero(e), v)

(but adapted to the two vector version).

I'm not sure where in the operations SparseArrays performs this.

Edit: wait, it seems like you do this at the stage of creating a new vector (by simply not pushing zeros), so its fine?

@devmotion
Copy link
Collaborator Author

wait, it seems like you do this at the stage of creating a new vector (by simply not pushing zeros), so its fine?

When performing multiplications and divisions (i.e., addition and subtraction of dimensions) only non-zero dimensions of the result are stored. Similarly, when constructing SymbolicDimensions and when converting from Dimension only non-zero dimensions are stored.

Copy link
Member

@MilesCranmer MilesCranmer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial suggestions to change UInt8 to UInt16, and also make that type a global constant for ensuring consistency.

Copy link
Member

@MilesCranmer MilesCranmer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think everything is looking good. The one thing remaining is adding some unittests to ensure coverage over all the modifications. In particular it looks like all the branches of == do not get tested by the current tests (green/red column to the left of code):

Screenshot 2023-10-12 at 13 36 08

which would be good to ensure we test extensively enough, since it is a custom sparse array type. Also, some of the utility functions are not currently tested:

Screenshot 2023-10-12 at 13 36 59

which would be good to add as well.

@devmotion
Copy link
Collaborator Author

I added more tests that should improve coverage.

@MilesCranmer
Copy link
Member

MilesCranmer commented Oct 12, 2023

One more TODO item (I think the last one, we're almost done) is to benchmark QuantityArray broadcasting for SymbolicDimensions. I am curious to see if the compiler inlining on the == changes at all with the custom sparse array implementation. [I will try to do this soon]

@MilesCranmer
Copy link
Member

MilesCranmer commented Oct 12, 2023

Awesome. I have no idea how, but this PR makes the broadcasting on SymbolicDimensions ~18x as fast as it was before!

Before:

julia> f(v) = v^2 * 1.5;

julia> @btime $f.(qa) setup=(xa = randn(10000) .* us"km/s"; qa = QuantityArray(xa));
  17.795 ms (160019 allocations: 13.05 MiB)

after:

julia> @btime $f.(qa) setup=(xa = randn(10000) .* us"km/s"; qa = QuantityArray(xa));
  1.053 ms (40007 allocations: 2.06 MiB)

(Still several orders of magnitude slower than with normal Dimensions, which has an advantage by being immutable, but I think this is pretty good)


Also, I went ahead and fixed the bug I noted here.

@MilesCranmer
Copy link
Member

Hm, I found another bug:

> convert(Quantity{Float64,SymbolicDimensions}, u"kg")
1.0 

not sure why this happens.

Copy link
Member

@MilesCranmer MilesCranmer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cheers for the awesome contribution @devmotion!! 🎉🎉

@MilesCranmer MilesCranmer merged commit d08e6f1 into SymbolicML:main Oct 12, 2023
@devmotion devmotion deleted the dw/sparsearrays branch October 13, 2023 08:01
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.

Make SparseArrays a weak dependency?
2 participants