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

Best practice on properly supporting OffsetArrays #281

Merged
merged 4 commits into from May 22, 2022
Merged

Conversation

johnnychen94
Copy link
Member

@johnnychen94 johnnychen94 commented May 17, 2022

This package is catching the eyes of the entire community, let's write some best practices on this so that people know how to handle it appropriately.

closes #282

cc: @t-bltg

@codecov
Copy link

codecov bot commented May 17, 2022

Codecov Report

Merging #281 (9be698b) into master (d8c8d42) will not change coverage.
The diff coverage is n/a.

❗ Current head 9be698b differs from pull request most recent head e9fd3f0. Consider uploading reports for the commit e9fd3f0 to get more accurate results

@@           Coverage Diff           @@
##           master     #281   +/-   ##
=======================================
  Coverage   95.90%   95.90%           
=======================================
  Files           5        5           
  Lines         464      464           
=======================================
  Hits          445      445           
  Misses         19       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 d8c8d42...e9fd3f0. Read the comment docs.

@johnnychen94 johnnychen94 changed the title Best practice on properly support OffsetArrays Best practice on properly supporting OffsetArrays May 17, 2022
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated
-- use `for i in eachindex(x)` instead.
- For multi-dimensional array, there are also `LinearIndices` and `CartesianIndices`.
- Instead of checking the size `size(A) == size(B)`, check the axes `axes(A) == axes(B)`.
- Use `OffsetArrays.no_offset_view(x)` to put everything back to 1-based indexing. But don't
Copy link
Member

Choose a reason for hiding this comment

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

This seems a bit vague, and I'm not certain that I fully understand the cases where it might not work. Maybe we can suggest OffsetArrays.no_offset_view if one requires 1-indexed arrays in their own code, and Base.require_one_based_indexing if they require users to pass 1-indexed arrays as arguments?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry. I was thinking of the A * B example for offset arrays -- for this we don't have a well-defined behavior on what axes should be used or what axes should be output, in this case, it's better to just use Base.require_one_based_indexing and leave it to users to do the conversion.

@ChrisJefferson
Copy link

ChrisJefferson commented May 18, 2022

(coming in as a julia newbie), maybe something like (this text is probably awful, feel free to edit / ignore)

Only use @inbounds if profiling shows it is worthwhile

@inbounds allows code to turn off bounds checking. It's easy to use incorrectly, particularly when OffsetArrays are used -- even the official example of its use in Julia's documentation was wrong for a while. Avoid @inbounds unless you have benchmarked your code and found it is useful -- as Julia's compiler gets better the cost of bounds checking usually small, or even 0, and using @inbounds changes bugs from throwing an assertion to silently returning invalid values.

@johnnychen94
Copy link
Member Author

johnnychen94 commented May 19, 2022

@ChrisJefferson this is a useful comment from my experience!

The @inbounds macro only becomes useful when it happens in the innermost loop -- it is usually a trick to eliminate the unnecessary boundcheck if-branch and thus enable CPU SIMD and make codes much faster.
For any non-trivial functions, @inbounds can become quite useless speaking of performance improvement. This means that @inbounds checks are often unnecessary for common package users.

But I'm afraid the most appropriate place to put this comment is somewhere in the Julia documentation, I'll try to find out a place to add this and submit a PR to the upstream Julia repo. But let me share this to JuliaLang/julia#45342 first.

@PallHaraldsson
Copy link

PallHaraldsson commented May 22, 2022

Isn't it best to merge this in whole (or in part? at least the pointer on --check-bounds=yes that closes #282).

I read the text and it seems fine by me (I'm not the expert). My proposal #284 (trying to avoid the issue) was closed. I may need to think it more carefully, until then having best (or better) practice is good.

Please do not delay too much merging some "best" practice. Perfect is the enemy of the good. The text can always be improved later.

@johnnychen94 johnnychen94 merged commit 6b431ca into master May 22, 2022
@johnnychen94 johnnychen94 deleted the jc/faq branch May 22, 2022 16:49
@timholy
Copy link
Member

timholy commented May 24, 2022

There's also https://docs.julialang.org/en/v1/devdocs/offset-arrays/ which goes into more detail. Should we link that from here? nvm, I see it is. Thanks!!

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.

Add big scary warning recommending testing compatibility with --check-bounds=yes
5 participants