Skip to content
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

Use Float32 to calculate DE_2000 for low precision colors #494

Merged
merged 1 commit into from
Jul 29, 2021

Conversation

kimikage
Copy link
Collaborator

@kimikage kimikage commented Jun 20, 2021

This speeds up the calculation of DE_2000 while ensuring the accuracy of 5e-5.
This changes not only the type of intermediate variables, but also the return type. (cf. #477)
This also fixes typos in the DE_2000 test data. (separated to #499)

julia> a, b = Lab(50, -1.3802, -84.2814), Lab(50, 0.0000, -82.7485);

julia> colordiff(Lab{BigFloat}(a), Lab{BigFloat}(b)) |> Float64
0.9999988647524654

julia> colordiff(Lab{Float64}(a), Lab{Float64}(b))
0.9999988647524661

julia> colordiff(Lab{Float32}(a), Lab{Float32}(b))
1.0000001f0

julia> colordiff(Lab{BigFloat}.(Lab{Float32}.((a, b)))...) |> Float32
0.99999994f0

Benchmark

julia> a = Lab{Float32}.(rand(RGB{Float32}, 1000, 1000));

julia> b = Lab{Float32}.(rand(RGB{Float32}, 1000, 1000));

julia> @btime colordiff.($a, $b);
  174.563 ms (2 allocations: 7.63 MiB) # v0.12.8 (`Float64`)
   69.342 ms (2 allocations: 3.81 MiB) # this PR (`Float32`)

julia> a64, b64 = Lab{Float64}.(a), Lab{Float64}.(b);

julia> @btime colordiff.($a64, $b64);
  107.792 ms (2 allocations: 7.63 MiB) # this PR

julia> versioninfo()
Julia Version 1.6.2
Commit 1b93d53fc4 (2021-07-14 15:36 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-11.0.1 (ORCJIT, tigerlake)

@codecov
Copy link

codecov bot commented Jun 20, 2021

Codecov Report

Merging #494 (ba054ea) into master (2a0b92d) will increase coverage by 0.15%.
The diff coverage is 98.14%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #494      +/-   ##
==========================================
+ Coverage   93.64%   93.80%   +0.15%     
==========================================
  Files           9        9              
  Lines        1118     1146      +28     
==========================================
+ Hits         1047     1075      +28     
  Misses         71       71              
Impacted Files Coverage Δ
src/utilities.jl 98.68% <87.50%> (ø)
src/differences.jl 99.25% <100.00%> (+0.19%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2a0b92d...ba054ea. Read the comment docs.

@kimikage
Copy link
Collaborator Author

kimikage commented Jun 21, 2021

At the moment, this uses Float32 entirely, in order to identify the effect of precompilation. However, in practice, using Float32 instead of Float64 outside of bottlenecks should not result in significant speed improvements.

Probably, atands and cosds are the bottlenecks.
Edit: atand has been improved in PR #495. cosd was replaced by cos in PR #498, and _de2000_t(::Float32) will be specialized.
Edit2: _de2000_t(::Float32) and _de2000_rot(::Float32) were specialized.

@kimikage
Copy link
Collaborator Author

kimikage commented Jul 8, 2021

I would like to determine if it is worth calculating delta_h in DE_2000 with Float32, after improving the accuracy of delta_h.
cf. #477 (comment) (Edit: cf. PR #501)

@johnnychen94
Copy link
Member

FWIW, I doubt that anyone is really using it for DE_2000, but CUDA devices are partialcularily optimized for Float32 operations and not for Float64.

@kimikage kimikage force-pushed the de2000_float32 branch 2 times, most recently from 5ee4a90 to 99e5bb5 Compare July 24, 2021 02:04
@kimikage kimikage marked this pull request as ready for review July 24, 2021 04:16
@kimikage kimikage changed the title [WIP] Use Float32 to calculate DE_2000 for low precision colors Use Float32 to calculate DE_2000 for low precision colors Jul 24, 2021
@kimikage kimikage force-pushed the de2000_float32 branch 2 times, most recently from 39590c8 to 793b7d9 Compare July 24, 2021 14:15
This speeds up the calculation of `DE_2000` while ensuring the accuracy of `5e-5`.
This changes not only the type of intermediate variables,
but also the return type.
@kimikage
Copy link
Collaborator Author

kimikage commented Jul 25, 2021

Probably the last bottleneck is mean_hue. As we learned in high school, a vector bisecting the angle of two direction vectors can be represented by the composition of their unit vectors. This method reduces the costly atan to a single call, but causes a loss of significance when the mean hue is near 0°, 90°, 180°, or 270°. Perhaps rotating the entire field will work around the problem.
Edit: By rotating each hue by 90° inward when the hue difference is greater than 90°, the updated hue difference will be less than 90°, which will avoid the loss of digits in one of the a* or b*.
Edit2: cf. PR #505

I've spent too much time improving delta_h, so I'd like to merge this PR first, with mean_hue being a future task.

@kimikage
Copy link
Collaborator Author

Since this change is related to issue #496 as well as speed, I would like to merge this.

@kimikage kimikage merged commit 15466d6 into JuliaGraphics:master Jul 29, 2021
@kimikage kimikage deleted the de2000_float32 branch July 29, 2021 03:32
@jonathanBieler jonathanBieler mentioned this pull request Sep 15, 2022
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants