-
Notifications
You must be signed in to change notification settings - Fork 7.2k
AdjustSharpness CV-CUDA Backend #9301
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
Open
justincdavis
wants to merge
15
commits into
pytorch:main
Choose a base branch
from
justincdavis:feat/adjust_sharpness_cvcuda
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
44db71c
implement additional cvcuda infra for all branches to avoid duplicate…
justincdavis e3dd700
update make_image_cvcuda to have default batch dim
justincdavis c035df1
add stanardized setup to main for easier updating of PRs and branches
justincdavis 98d7dfb
update is_cvcuda_tensor
justincdavis ddc116d
add cvcuda to pil compatible to transforms by default
justincdavis e51dc7e
remove cvcuda from transform class
justincdavis e14e210
merge with main
justincdavis 4939355
resolve more formatting naming
justincdavis fbea584
update is cvcuda tensor impl
justincdavis 1054981
adjust_sharpness complete and tested, fully identical. uses zero-copy
justincdavis cef9719
update to main standards
justincdavis bbc0360
fix incorrect split when batch greater than 1
justincdavis eee8862
Merge remote-tracking branch 'upstream/main' into feat/adjust_sharpne…
justincdavis bcedb07
merge with main
justincdavis eee2040
simplify and drop unused cvcuda parts
justincdavis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| from typing import TYPE_CHECKING | ||
|
|
||
| import PIL.Image | ||
| import torch | ||
| from torch.nn.functional import conv2d | ||
|
|
@@ -9,7 +11,13 @@ | |
|
|
||
| from ._misc import _num_value_bits, to_dtype_image | ||
| from ._type_conversion import pil_to_tensor, to_pil_image | ||
| from ._utils import _get_kernel, _register_kernel_internal | ||
| from ._utils import _get_kernel, _import_cvcuda, _is_cvcuda_available, _register_kernel_internal | ||
|
|
||
|
|
||
| CVCUDA_AVAILABLE = _is_cvcuda_available() | ||
|
|
||
| if TYPE_CHECKING: | ||
| import cvcuda # type: ignore[import-not-found] | ||
|
|
||
|
|
||
| def rgb_to_grayscale(inpt: torch.Tensor, num_output_channels: int = 1) -> torch.Tensor: | ||
|
|
@@ -286,6 +294,88 @@ def adjust_sharpness_video(video: torch.Tensor, sharpness_factor: float) -> torc | |
| return adjust_sharpness_image(video, sharpness_factor=sharpness_factor) | ||
|
|
||
|
|
||
| _max_value_map: dict["cvcuda.Type", float | int] = {} | ||
| _dtype_to_format: dict[tuple["cvcuda.Type", int], "cvcuda.Format"] = {} | ||
|
|
||
|
|
||
| def _adjust_sharpness_image_cvcuda( | ||
| image: "cvcuda.Tensor", | ||
| sharpness_factor: float, | ||
| ) -> "cvcuda.Tensor": | ||
| cvcuda = _import_cvcuda() | ||
|
|
||
| if len(_max_value_map) == 0: | ||
| _max_value_map[cvcuda.Type.U8] = 255 | ||
| _max_value_map[cvcuda.Type.F32] = 1.0 | ||
| if len(_dtype_to_format) == 0: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using |
||
| _dtype_to_format[(cvcuda.Type.U8, 1)] = cvcuda.Format.U8 | ||
| _dtype_to_format[(cvcuda.Type.U8, 3)] = cvcuda.Format.RGB8 | ||
| _dtype_to_format[(cvcuda.Type.F32, 1)] = cvcuda.Format.F32 | ||
| _dtype_to_format[(cvcuda.Type.F32, 3)] = cvcuda.Format.RGBf32 | ||
|
|
||
| if sharpness_factor < 0: | ||
| raise ValueError(f"sharpness_factor ({sharpness_factor}) is not non-negative.") | ||
|
|
||
| n, h, w, c = image.shape | ||
| if c not in (1, 3): | ||
| raise TypeError(f"Input image tensor can have 1 or 3 channels, but found {c}") | ||
|
|
||
| if h <= 2 or w <= 2: | ||
| return image | ||
|
|
||
| # grab the constants like in the torchvision | ||
| bound = _max_value_map[image.dtype] | ||
| fp = image.dtype == cvcuda.Type.F32 | ||
| img_format = _dtype_to_format.get((image.dtype, c)) | ||
| if img_format is None: | ||
| raise TypeError(f"Unsupported dtype/channel combination: {image.dtype}, {c} channels") | ||
|
|
||
| # conv2d requires ImageBatchVarShape, so we split the batch into individual images | ||
| # CV-CUDA has no split, so use zero-copy and torch | ||
| batch = cvcuda.ImageBatchVarShape(capacity=n) | ||
| for tensor in torch.as_tensor(image.cuda()).split(1, dim=0): | ||
| cv_image = cvcuda.as_image(tensor, format=img_format) | ||
| batch.pushback(cv_image) | ||
|
|
||
| # create kernel same as adjust_sharpness_image | ||
| a, b = 1.0 / 13.0, 5.0 / 13.0 | ||
| torch_kernel = torch.tensor([[a, a, a], [a, b, a], [a, a, a]], dtype=torch.float32, device="cuda") | ||
| kernel_batch = cvcuda.ImageBatchVarShape(capacity=n) | ||
| for _ in range(n): | ||
| kernel_batch.pushback(cvcuda.as_image(torch_kernel, format=cvcuda.Format.F32)) | ||
|
|
||
| # anchors of kernel for cvcuda, [-1, -1] means center of kernel | ||
| anchor_data = torch.tensor([[-1, -1]] * n, dtype=torch.int32, device="cuda") | ||
| anchor = cvcuda.as_tensor(anchor_data, "NC") | ||
|
|
||
| # run the sharpen operator using cvcuda.conv2d | ||
| sharpened_batch = cvcuda.conv2d(batch, kernel=kernel_batch, kernel_anchor=anchor, border=cvcuda.Border.REPLICATE) | ||
| sharpened_list = [] | ||
| for sharpened_img in sharpened_batch: | ||
| tensor = cvcuda.as_tensor(sharpened_img.cuda(), cvcuda.TensorLayout.HWC) | ||
| sharpened_list.append(tensor) | ||
| sharpened = cvcuda.stack(sharpened_list) | ||
|
|
||
| # handle the final blend operations using zero-copy from the adjust_sharpness_image | ||
| blurred_degenerate = torch.as_tensor(sharpened.cuda()) | ||
| output = torch.as_tensor(image.cuda()).to(dtype=torch.float32, copy=True) | ||
| if not fp: | ||
| blurred_degenerate = blurred_degenerate.round() | ||
| view = output[:, 1:-1, 1:-1, :] | ||
| blurred_inner = blurred_degenerate[:, 1:-1, 1:-1, :] | ||
| view.add_(blurred_inner.sub(view), alpha=(1.0 - sharpness_factor)) | ||
| output = output.clamp_(0, bound) | ||
| if not fp: | ||
| output = output.to(torch.uint8) | ||
|
|
||
| # convert back to cvcuda.Tensor | ||
| return cvcuda.as_tensor(output.contiguous(), cvcuda.TensorLayout.NHWC) | ||
|
|
||
|
|
||
| if CVCUDA_AVAILABLE: | ||
| _register_kernel_internal(adjust_sharpness, _import_cvcuda().Tensor)(_adjust_sharpness_image_cvcuda) | ||
|
|
||
|
|
||
| def adjust_hue(inpt: torch.Tensor, hue_factor: float) -> torch.Tensor: | ||
| """Adjust hue""" | ||
| if torch.jit.is_scripting(): | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Using
if not _max_value_map: