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
No-cache fast painting #6607
No-cache fast painting #6607
Conversation
@@ -1501,20 +1513,6 @@ def test_invalidate_cache_when_change_color_mode(): | |||
) | |||
|
|||
|
|||
@pytest.mark.parametrize("dtype", np.sctypes['int'] + np.sctypes['uint']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wtf I only just now noticed np.sctypes exists 😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this! Lots of cache logic removed which is a huge win. 😍
I'm unclear about a lot of parts though so I've made some requests for comments/docstrings.
napari/layers/labels/labels.py
Outdated
def _get_pt_not_disp(self, indices, values): | ||
slice_input = self._slice.slice_input | ||
point = np.round( | ||
self.world_to_data(slice_input.world_slice.point) | ||
).astype(int) | ||
return {dim: point[dim] for dim in slice_input.not_displayed} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is weird... indices and values aren't used? Can you add a docstring to help me understand why the function signature is what it is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I'm sorry. It is an artifact of simplification of code. First version was using it.
napari/utils/indexing.py
Outdated
def visible_items_in_slice( | ||
index: Tuple[npt.NDArray[np.int_], ...], position_in_axes: Dict[int, int] | ||
) -> npt.NDArray[np.bool_]: | ||
queries = [ | ||
index[ax] == position for ax, position in position_in_axes.items() | ||
] | ||
return np.logical_and.reduce(queries, axis=0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a docstring here? I don't understand what this function is supposed to do. (And I'm not sure it should be public...?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added. Should I make it private?
The question is why the whole module is public.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, but given that it is, let's not expand it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved
napari/layers/labels/labels.py
Outdated
displayed_indices = index_in_slice(indices, pt_not_disp) | ||
self._slice.image.raw[displayed_indices] = value | ||
self._slice.image.raw[displayed_indices] = visible_values | ||
# self._slice.image.view[displayed_indices] = self.colormap._map_to_gpu(value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the comment? It might be worth adding a comment mentioning that the view must also be updated but is done below only if contour == 0 (why?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is done only if contour == 0
because in other situation we need to recalculate contours, so use _raw_to_displayed method
@@ -664,6 +664,18 @@ def test_contour_local_updates(): | |||
) | |||
|
|||
|
|||
def test_data_setitem_multi_dim(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you describe the bug you found in a docstring here? I still don't understand it after reading the code...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added. Could you check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's great!
Co-authored-by: Juan Nunez-Iglesias <jni@fastmail.com>
Co-authored-by: Juan Nunez-Iglesias <jni@fastmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is nice and small now! 😍 @Czaki can you (a) check my proposed name change (optional) and (b) add my proposed docstring (not optional 😂), then I will merge. 🚀
Co-authored-by: Juan Nunez-Iglesias <jni@fastmail.com>
for more information, see https://pre-commit.ci
Done. Let's wait on CI |
@Czaki fyi here is my latest script for manual testing of painting fps:
For uint64 I get about 50-55fps both on this PR and on e0c0c8e... And on main. 😂 I'd be curious if you can test on a normal Windows workstation... (I am in the process of setting up my Linux tower again but it's not running yet.) |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #6607 +/- ##
==========================================
- Coverage 92.27% 92.22% -0.05%
==========================================
Files 603 603
Lines 53933 53898 -35
==========================================
- Hits 49767 49708 -59
- Misses 4166 4190 +24 ☔ View full report in Codecov by Sentry. |
@Czaki I've updated the PR description to provide a bit more background. Please check it for accuracy, especially this bit:
I wrote that from memory based on the deleted code, I haven't actually verified that it's true. 😅 I am going to bed now, but please merge if my description is accurate, and if you could then incorporate this into #6542 I would be very grateful! 🙏 @psobolewskiPhD if you could re-review #6542 and approve (😬), we can merge and release rc4! 🚀 Goodnight all, looking forward to the morning! 😊 |
It is true. It still sends only a rectangle containing updated data. |
45-60 fps on windows. |
closes #6579 supersedes #6583 were mapped to texture dtypes/values and sent on to the GPU. In this PR, an alternate strategy is introduced: rather than caching previously-transformed data and then doing a diff with the cache, we paint the data *and* the texture-mapped data directly. The partial update of the on-GPU texture also introduced in #5732 is maintained, as it can dramatically reduce the amount of data needing to be transferred from CPU to GPU memory. This PR is built on top of #6602. --------- Co-authored-by: Juan Nunez-Iglesias <jni@fastmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
…ccount (#6616) # References and relevant issues closes #6615 # Description In #6607, we started painting into both the data and the slice view. (And this was already happening and broken when painting into lazy arrays such as zarr and dask, #6112.) However, when setting the view we need to take into account the axis ordering used when slicing (some axes may be transposed). This manifested as an index error in #6615. In this PR, we add an `indices_order` argument to `index_in_slice` function and the function returns indices in the requested order, which we can then use to set the view.
…ccount (#6616) closes #6615 In #6607, we started painting into both the data and the slice view. (And this was already happening and broken when painting into lazy arrays such as zarr and dask, #6112.) However, when setting the view we need to take into account the axis ordering used when slicing (some axes may be transposed). This manifested as an index error in #6615. In this PR, we add an `indices_order` argument to `index_in_slice` function and the function returns indices in the requested order, which we can then use to set the view.
References and relevant issues
closes #6579
supersedes #6583
Description
#5732 introduced a cache of mapped data so that only changed indices were mapped to texture dtypes/values and sent on to the GPU. In this PR, an alternate strategy is introduced: rather than caching previously-transformed data and then doing a diff with the cache, we paint the data and the texture-mapped data directly.
The partial update of the on-GPU texture also introduced in #5732 is maintained, as it can dramatically reduce the amount of data needing to be transferred from CPU to GPU memory.
This PR is built on top of #6602.