Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
vision
Commits
e13b8f5c
"...git@developer.sourcefind.cn:OpenDAS/pytorch3d.git" did not exist on "3a063f5976781ed30c1c36b65fe837d63e76b94e"
Unverified
Commit
e13b8f5c
authored
Sep 07, 2023
by
Philip Meier
Committed by
GitHub
Sep 07, 2023
Browse files
port tests for F.pad and transforms.Pad (#7939)
parent
e9f80941
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
171 additions
and
322 deletions
+171
-322
test/test_transforms_v2.py
test/test_transforms_v2.py
+0
-15
test/test_transforms_v2_consistency.py
test/test_transforms_v2_consistency.py
+0
-15
test/test_transforms_v2_functional.py
test/test_transforms_v2_functional.py
+0
-69
test/test_transforms_v2_refactored.py
test/test_transforms_v2_refactored.py
+168
-0
test/transforms_v2_dispatcher_infos.py
test/transforms_v2_dispatcher_infos.py
+1
-15
test/transforms_v2_kernel_infos.py
test/transforms_v2_kernel_infos.py
+2
-208
No files found.
test/test_transforms_v2.py
View file @
e13b8f5c
...
@@ -390,21 +390,6 @@ def test_pure_tensor_heuristic(flat_inputs):
...
@@ -390,21 +390,6 @@ def test_pure_tensor_heuristic(flat_inputs):
assert
transform
.
was_applied
(
output
,
input
)
assert
transform
.
was_applied
(
output
,
input
)
class
TestPad
:
def
test_assertions
(
self
):
with
pytest
.
raises
(
TypeError
,
match
=
"Got inappropriate padding arg"
):
transforms
.
Pad
(
"abc"
)
with
pytest
.
raises
(
ValueError
,
match
=
"Padding must be an int or a 1, 2, or 4"
):
transforms
.
Pad
([
-
0.7
,
0
,
0.7
])
with
pytest
.
raises
(
TypeError
,
match
=
"Got inappropriate fill arg"
):
transforms
.
Pad
(
12
,
fill
=
"abc"
)
with
pytest
.
raises
(
ValueError
,
match
=
"Padding mode should be either"
):
transforms
.
Pad
(
12
,
padding_mode
=
"abc"
)
class
TestRandomZoomOut
:
class
TestRandomZoomOut
:
def
test_assertions
(
self
):
def
test_assertions
(
self
):
with
pytest
.
raises
(
TypeError
,
match
=
"Got inappropriate fill arg"
):
with
pytest
.
raises
(
TypeError
,
match
=
"Got inappropriate fill arg"
):
...
...
test/test_transforms_v2_consistency.py
View file @
e13b8f5c
...
@@ -109,21 +109,6 @@ CONSISTENCY_CONFIGS = [
...
@@ -109,21 +109,6 @@ CONSISTENCY_CONFIGS = [
],
],
make_images_kwargs
=
dict
(
DEFAULT_MAKE_IMAGES_KWARGS
,
sizes
=
[(
20
,
19
)]),
make_images_kwargs
=
dict
(
DEFAULT_MAKE_IMAGES_KWARGS
,
sizes
=
[(
20
,
19
)]),
),
),
ConsistencyConfig
(
v2_transforms
.
Pad
,
legacy_transforms
.
Pad
,
[
NotScriptableArgsKwargs
(
3
),
ArgsKwargs
([
3
]),
ArgsKwargs
([
2
,
3
]),
ArgsKwargs
([
3
,
2
,
1
,
4
]),
NotScriptableArgsKwargs
(
5
,
fill
=
1
,
padding_mode
=
"constant"
),
ArgsKwargs
([
5
],
fill
=
1
,
padding_mode
=
"constant"
),
NotScriptableArgsKwargs
(
5
,
padding_mode
=
"edge"
),
NotScriptableArgsKwargs
(
5
,
padding_mode
=
"reflect"
),
NotScriptableArgsKwargs
(
5
,
padding_mode
=
"symmetric"
),
],
),
*
[
*
[
ConsistencyConfig
(
ConsistencyConfig
(
v2_transforms
.
LinearTransformation
,
v2_transforms
.
LinearTransformation
,
...
...
test/test_transforms_v2_functional.py
View file @
e13b8f5c
...
@@ -524,75 +524,6 @@ class TestClampBoundingBoxes:
...
@@ -524,75 +524,6 @@ class TestClampBoundingBoxes:
# `transforms_v2_kernel_infos.py`
# `transforms_v2_kernel_infos.py`
def
_parse_padding
(
padding
):
if
isinstance
(
padding
,
int
):
return
[
padding
]
*
4
if
isinstance
(
padding
,
list
):
if
len
(
padding
)
==
1
:
return
padding
*
4
if
len
(
padding
)
==
2
:
return
padding
*
2
# [left, up, right, down]
return
padding
@
pytest
.
mark
.
parametrize
(
"device"
,
cpu_and_cuda
())
@
pytest
.
mark
.
parametrize
(
"padding"
,
[[
1
],
[
1
,
1
],
[
1
,
1
,
2
,
2
]])
def
test_correctness_pad_bounding_boxes
(
device
,
padding
):
def
_compute_expected_bbox
(
bbox
,
format
,
padding_
):
pad_left
,
pad_up
,
_
,
_
=
_parse_padding
(
padding_
)
dtype
=
bbox
.
dtype
bbox
=
(
bbox
.
clone
()
if
format
==
tv_tensors
.
BoundingBoxFormat
.
XYXY
else
convert_bounding_box_format
(
bbox
,
old_format
=
format
,
new_format
=
tv_tensors
.
BoundingBoxFormat
.
XYXY
)
)
bbox
[
0
::
2
]
+=
pad_left
bbox
[
1
::
2
]
+=
pad_up
bbox
=
convert_bounding_box_format
(
bbox
,
old_format
=
tv_tensors
.
BoundingBoxFormat
.
XYXY
,
new_format
=
format
)
if
bbox
.
dtype
!=
dtype
:
# Temporary cast to original dtype
# e.g. float32 -> int
bbox
=
bbox
.
to
(
dtype
)
return
bbox
def
_compute_expected_canvas_size
(
bbox
,
padding_
):
pad_left
,
pad_up
,
pad_right
,
pad_down
=
_parse_padding
(
padding_
)
height
,
width
=
bbox
.
canvas_size
return
height
+
pad_up
+
pad_down
,
width
+
pad_left
+
pad_right
for
bboxes
in
make_multiple_bounding_boxes
(
extra_dims
=
((
4
,),)):
bboxes
=
bboxes
.
to
(
device
)
bboxes_format
=
bboxes
.
format
bboxes_canvas_size
=
bboxes
.
canvas_size
output_boxes
,
output_canvas_size
=
F
.
pad_bounding_boxes
(
bboxes
,
format
=
bboxes_format
,
canvas_size
=
bboxes_canvas_size
,
padding
=
padding
)
torch
.
testing
.
assert_close
(
output_canvas_size
,
_compute_expected_canvas_size
(
bboxes
,
padding
))
expected_bboxes
=
torch
.
stack
(
[
_compute_expected_bbox
(
b
,
bboxes_format
,
padding
)
for
b
in
bboxes
.
reshape
(
-
1
,
4
).
unbind
()]
).
reshape
(
bboxes
.
shape
)
torch
.
testing
.
assert_close
(
output_boxes
,
expected_bboxes
,
atol
=
1
,
rtol
=
0
)
@
pytest
.
mark
.
parametrize
(
"device"
,
cpu_and_cuda
())
def
test_correctness_pad_segmentation_mask_on_fixed_input
(
device
):
mask
=
torch
.
ones
((
1
,
3
,
3
),
dtype
=
torch
.
long
,
device
=
device
)
out_mask
=
F
.
pad_mask
(
mask
,
padding
=
[
1
,
1
,
1
,
1
])
expected_mask
=
torch
.
zeros
((
1
,
5
,
5
),
dtype
=
torch
.
long
,
device
=
device
)
expected_mask
[:,
1
:
-
1
,
1
:
-
1
]
=
1
torch
.
testing
.
assert_close
(
out_mask
,
expected_mask
)
@
pytest
.
mark
.
parametrize
(
"device"
,
cpu_and_cuda
())
@
pytest
.
mark
.
parametrize
(
"device"
,
cpu_and_cuda
())
@
pytest
.
mark
.
parametrize
(
@
pytest
.
mark
.
parametrize
(
"startpoints, endpoints"
,
"startpoints, endpoints"
,
...
...
test/test_transforms_v2_refactored.py
View file @
e13b8f5c
...
@@ -3346,3 +3346,171 @@ class TestResizedCrop:
...
@@ -3346,3 +3346,171 @@ class TestResizedCrop:
for
param
in
[
"scale"
,
"ratio"
]:
for
param
in
[
"scale"
,
"ratio"
]:
with
pytest
.
warns
(
match
=
"Scale and ratio should be of kind"
):
with
pytest
.
warns
(
match
=
"Scale and ratio should be of kind"
):
transforms
.
RandomResizedCrop
(
size
=
self
.
INPUT_SIZE
,
**
{
param
:
[
1
,
0
]})
transforms
.
RandomResizedCrop
(
size
=
self
.
INPUT_SIZE
,
**
{
param
:
[
1
,
0
]})
class
TestPad
:
EXHAUSTIVE_TYPE_PADDINGS
=
[
1
,
(
1
,),
(
1
,
2
),
(
1
,
2
,
3
,
4
),
[
1
],
[
1
,
2
],
[
1
,
2
,
3
,
4
]]
CORRECTNESS_PADDINGS
=
[
padding
for
padding
in
EXHAUSTIVE_TYPE_PADDINGS
if
isinstance
(
padding
,
int
)
or
isinstance
(
padding
,
list
)
and
len
(
padding
)
>
1
]
PADDING_MODES
=
[
"constant"
,
"symmetric"
,
"edge"
,
"reflect"
]
@
param_value_parametrization
(
padding
=
EXHAUSTIVE_TYPE_PADDINGS
,
fill
=
EXHAUSTIVE_TYPE_FILLS
,
padding_mode
=
PADDING_MODES
,
)
@
pytest
.
mark
.
parametrize
(
"dtype"
,
[
torch
.
uint8
,
torch
.
float32
])
@
pytest
.
mark
.
parametrize
(
"device"
,
cpu_and_cuda
())
def
test_kernel_image
(
self
,
param
,
value
,
dtype
,
device
):
if
param
==
"fill"
:
value
=
adapt_fill
(
value
,
dtype
=
dtype
)
kwargs
=
{
param
:
value
}
if
param
!=
"padding"
:
kwargs
[
"padding"
]
=
[
1
]
image
=
make_image
(
dtype
=
dtype
,
device
=
device
)
check_kernel
(
F
.
pad_image
,
image
,
**
kwargs
,
check_scripted_vs_eager
=
not
(
(
param
==
"padding"
and
isinstance
(
value
,
int
))
# See https://github.com/pytorch/vision/pull/7252#issue-1585585521 for details
or
(
param
==
"fill"
and
(
isinstance
(
value
,
tuple
)
or
(
isinstance
(
value
,
list
)
and
any
(
isinstance
(
v
,
int
)
for
v
in
value
))
)
)
),
)
@
pytest
.
mark
.
parametrize
(
"format"
,
list
(
tv_tensors
.
BoundingBoxFormat
))
def
test_kernel_bounding_boxes
(
self
,
format
):
bounding_boxes
=
make_bounding_boxes
(
format
=
format
)
check_kernel
(
F
.
pad_bounding_boxes
,
bounding_boxes
,
format
=
bounding_boxes
.
format
,
canvas_size
=
bounding_boxes
.
canvas_size
,
padding
=
[
1
],
)
@
pytest
.
mark
.
parametrize
(
"padding_mode"
,
[
"symmetric"
,
"edge"
,
"reflect"
])
def
test_kernel_bounding_boxes_errors
(
self
,
padding_mode
):
bounding_boxes
=
make_bounding_boxes
()
with
pytest
.
raises
(
ValueError
,
match
=
f
"'
{
padding_mode
}
' is not supported"
):
F
.
pad_bounding_boxes
(
bounding_boxes
,
format
=
bounding_boxes
.
format
,
canvas_size
=
bounding_boxes
.
canvas_size
,
padding
=
[
1
],
padding_mode
=
padding_mode
,
)
@
pytest
.
mark
.
parametrize
(
"make_mask"
,
[
make_segmentation_mask
,
make_detection_mask
])
def
test_kernel_mask
(
self
,
make_mask
):
check_kernel
(
F
.
pad_mask
,
make_mask
(),
padding
=
[
1
])
@
pytest
.
mark
.
parametrize
(
"fill"
,
[[
1
],
(
0
,),
[
1
,
0
,
1
],
(
0
,
1
,
0
)])
def
test_kernel_mask_errors
(
self
,
fill
):
with
pytest
.
raises
(
ValueError
,
match
=
"Non-scalar fill value is not supported"
):
check_kernel
(
F
.
pad_mask
,
make_segmentation_mask
(),
padding
=
[
1
],
fill
=
fill
)
@
pytest
.
mark
.
parametrize
(
"make_input"
,
[
make_image_tensor
,
make_image_pil
,
make_image
,
make_bounding_boxes
,
make_segmentation_mask
,
make_video
],
)
def
test_functional
(
self
,
make_input
):
check_functional
(
F
.
pad
,
make_input
(),
padding
=
[
1
])
@
pytest
.
mark
.
parametrize
(
(
"kernel"
,
"input_type"
),
[
(
F
.
pad_image
,
torch
.
Tensor
),
# The PIL kernel uses fill=0 as default rather than fill=None as all others.
# Since the whole fill story is already really inconsistent, we won't introduce yet another case to allow
# for this test to pass.
# See https://github.com/pytorch/vision/issues/6623 for a discussion.
# (F._pad_image_pil, PIL.Image.Image),
(
F
.
pad_image
,
tv_tensors
.
Image
),
(
F
.
pad_bounding_boxes
,
tv_tensors
.
BoundingBoxes
),
(
F
.
pad_mask
,
tv_tensors
.
Mask
),
(
F
.
pad_video
,
tv_tensors
.
Video
),
],
)
def
test_functional_signature
(
self
,
kernel
,
input_type
):
check_functional_kernel_signature_match
(
F
.
pad
,
kernel
=
kernel
,
input_type
=
input_type
)
@
pytest
.
mark
.
parametrize
(
"make_input"
,
[
make_image_tensor
,
make_image_pil
,
make_image
,
make_bounding_boxes
,
make_segmentation_mask
,
make_video
],
)
def
test_transform
(
self
,
make_input
):
check_transform
(
transforms
.
Pad
(
padding
=
[
1
]),
make_input
())
def
test_transform_errors
(
self
):
with
pytest
.
raises
(
TypeError
,
match
=
"Got inappropriate padding arg"
):
transforms
.
Pad
(
"abc"
)
with
pytest
.
raises
(
ValueError
,
match
=
"Padding must be an int or a 1, 2, or 4"
):
transforms
.
Pad
([
-
0.7
,
0
,
0.7
])
with
pytest
.
raises
(
TypeError
,
match
=
"Got inappropriate fill arg"
):
transforms
.
Pad
(
12
,
fill
=
"abc"
)
with
pytest
.
raises
(
ValueError
,
match
=
"Padding mode should be either"
):
transforms
.
Pad
(
12
,
padding_mode
=
"abc"
)
@
pytest
.
mark
.
parametrize
(
"padding"
,
CORRECTNESS_PADDINGS
)
@
pytest
.
mark
.
parametrize
(
(
"padding_mode"
,
"fill"
),
[
*
[(
"constant"
,
fill
)
for
fill
in
CORRECTNESS_FILLS
],
*
[(
padding_mode
,
None
)
for
padding_mode
in
[
"symmetric"
,
"edge"
,
"reflect"
]],
],
)
@
pytest
.
mark
.
parametrize
(
"fn"
,
[
F
.
pad
,
transform_cls_to_functional
(
transforms
.
Pad
)])
def
test_image_correctness
(
self
,
padding
,
padding_mode
,
fill
,
fn
):
image
=
make_image
(
dtype
=
torch
.
uint8
,
device
=
"cpu"
)
actual
=
fn
(
image
,
padding
=
padding
,
padding_mode
=
padding_mode
,
fill
=
fill
)
expected
=
F
.
to_image
(
F
.
pad
(
F
.
to_pil_image
(
image
),
padding
=
padding
,
padding_mode
=
padding_mode
,
fill
=
fill
))
assert_equal
(
actual
,
expected
)
def
_reference_pad_bounding_boxes
(
self
,
bounding_boxes
,
*
,
padding
):
if
isinstance
(
padding
,
int
):
padding
=
[
padding
]
left
,
top
,
right
,
bottom
=
padding
*
(
4
//
len
(
padding
))
affine_matrix
=
np
.
array
(
[
[
1
,
0
,
left
],
[
0
,
1
,
top
],
],
)
height
=
bounding_boxes
.
canvas_size
[
0
]
+
top
+
bottom
width
=
bounding_boxes
.
canvas_size
[
1
]
+
left
+
right
return
reference_affine_bounding_boxes_helper
(
bounding_boxes
,
affine_matrix
=
affine_matrix
,
new_canvas_size
=
(
height
,
width
)
)
@
pytest
.
mark
.
parametrize
(
"padding"
,
CORRECTNESS_PADDINGS
)
@
pytest
.
mark
.
parametrize
(
"format"
,
list
(
tv_tensors
.
BoundingBoxFormat
))
@
pytest
.
mark
.
parametrize
(
"dtype"
,
[
torch
.
int64
,
torch
.
float32
])
@
pytest
.
mark
.
parametrize
(
"device"
,
cpu_and_cuda
())
@
pytest
.
mark
.
parametrize
(
"fn"
,
[
F
.
pad
,
transform_cls_to_functional
(
transforms
.
Pad
)])
def
test_bounding_boxes_correctness
(
self
,
padding
,
format
,
dtype
,
device
,
fn
):
bounding_boxes
=
make_bounding_boxes
(
format
=
format
,
dtype
=
dtype
,
device
=
device
)
actual
=
fn
(
bounding_boxes
,
padding
=
padding
)
expected
=
self
.
_reference_pad_bounding_boxes
(
bounding_boxes
,
padding
=
padding
)
assert_equal
(
actual
,
expected
)
test/transforms_v2_dispatcher_infos.py
View file @
e13b8f5c
import
pytest
import
pytest
import
torchvision.transforms.v2.functional
as
F
import
torchvision.transforms.v2.functional
as
F
from
torchvision
import
tv_tensors
from
torchvision
import
tv_tensors
from
transforms_v2_kernel_infos
import
KERNEL_INFOS
,
pad_xfail_jit_fill_condition
from
transforms_v2_kernel_infos
import
KERNEL_INFOS
from
transforms_v2_legacy_utils
import
InfoBase
,
TestMark
from
transforms_v2_legacy_utils
import
InfoBase
,
TestMark
__all__
=
[
"DispatcherInfo"
,
"DISPATCHER_INFOS"
]
__all__
=
[
"DispatcherInfo"
,
"DISPATCHER_INFOS"
]
...
@@ -111,20 +111,6 @@ multi_crop_skips.append(skip_dispatch_tv_tensor)
...
@@ -111,20 +111,6 @@ multi_crop_skips.append(skip_dispatch_tv_tensor)
DISPATCHER_INFOS
=
[
DISPATCHER_INFOS
=
[
DispatcherInfo
(
F
.
pad
,
kernels
=
{
tv_tensors
.
Image
:
F
.
pad_image
,
tv_tensors
.
Video
:
F
.
pad_video
,
tv_tensors
.
BoundingBoxes
:
F
.
pad_bounding_boxes
,
tv_tensors
.
Mask
:
F
.
pad_mask
,
},
pil_kernel_info
=
PILKernelInfo
(
F
.
_pad_image_pil
,
kernel_name
=
"pad_image_pil"
),
test_marks
=
[
xfail_jit
(
"F.pad only supports vector fills for list of floats"
,
condition
=
pad_xfail_jit_fill_condition
),
xfail_jit_python_scalar_arg
(
"padding"
),
],
),
DispatcherInfo
(
DispatcherInfo
(
F
.
perspective
,
F
.
perspective
,
kernels
=
{
kernels
=
{
...
...
test/transforms_v2_kernel_infos.py
View file @
e13b8f5c
import
functools
import
functools
import
itertools
import
itertools
import
numpy
as
np
import
PIL.Image
import
PIL.Image
import
pytest
import
pytest
import
torch.testing
import
torch.testing
import
torchvision.transforms.v2.functional
as
F
import
torchvision.transforms.v2.functional
as
F
from
torchvision
import
tv_tensors
from
torchvision
import
tv_tensors
from
torchvision.transforms._functional_tensor
import
_max_value
as
get_max_value
,
_parse_pad_padding
from
torchvision.transforms._functional_tensor
import
_max_value
as
get_max_value
from
transforms_v2_legacy_utils
import
(
from
transforms_v2_legacy_utils
import
(
# noqa: F401
ArgsKwargs
,
ArgsKwargs
,
combinations_grid
,
combinations_grid
,
DEFAULT_PORTRAIT_SPATIAL_SIZE
,
DEFAULT_PORTRAIT_SPATIAL_SIZE
,
...
@@ -183,211 +182,6 @@ def float32_vs_uint8_fill_adapter(other_args, kwargs):
...
@@ -183,211 +182,6 @@ def float32_vs_uint8_fill_adapter(other_args, kwargs):
return
other_args
,
dict
(
kwargs
,
fill
=
fill
)
return
other_args
,
dict
(
kwargs
,
fill
=
fill
)
def
reference_affine_bounding_boxes_helper
(
bounding_boxes
,
*
,
format
,
canvas_size
,
affine_matrix
):
def
transform
(
bbox
,
affine_matrix_
,
format_
,
canvas_size_
):
# Go to float before converting to prevent precision loss in case of CXCYWH -> XYXY and W or H is 1
in_dtype
=
bbox
.
dtype
if
not
torch
.
is_floating_point
(
bbox
):
bbox
=
bbox
.
float
()
bbox_xyxy
=
F
.
convert_bounding_box_format
(
bbox
.
as_subclass
(
torch
.
Tensor
),
old_format
=
format_
,
new_format
=
tv_tensors
.
BoundingBoxFormat
.
XYXY
,
inplace
=
True
,
)
points
=
np
.
array
(
[
[
bbox_xyxy
[
0
].
item
(),
bbox_xyxy
[
1
].
item
(),
1.0
],
[
bbox_xyxy
[
2
].
item
(),
bbox_xyxy
[
1
].
item
(),
1.0
],
[
bbox_xyxy
[
0
].
item
(),
bbox_xyxy
[
3
].
item
(),
1.0
],
[
bbox_xyxy
[
2
].
item
(),
bbox_xyxy
[
3
].
item
(),
1.0
],
]
)
transformed_points
=
np
.
matmul
(
points
,
affine_matrix_
.
T
)
out_bbox
=
torch
.
tensor
(
[
np
.
min
(
transformed_points
[:,
0
]).
item
(),
np
.
min
(
transformed_points
[:,
1
]).
item
(),
np
.
max
(
transformed_points
[:,
0
]).
item
(),
np
.
max
(
transformed_points
[:,
1
]).
item
(),
],
dtype
=
bbox_xyxy
.
dtype
,
)
out_bbox
=
F
.
convert_bounding_box_format
(
out_bbox
,
old_format
=
tv_tensors
.
BoundingBoxFormat
.
XYXY
,
new_format
=
format_
,
inplace
=
True
)
# It is important to clamp before casting, especially for CXCYWH format, dtype=int64
out_bbox
=
F
.
clamp_bounding_boxes
(
out_bbox
,
format
=
format_
,
canvas_size
=
canvas_size_
)
out_bbox
=
out_bbox
.
to
(
dtype
=
in_dtype
)
return
out_bbox
return
torch
.
stack
(
[
transform
(
b
,
affine_matrix
,
format
,
canvas_size
)
for
b
in
bounding_boxes
.
reshape
(
-
1
,
4
).
unbind
()]
).
reshape
(
bounding_boxes
.
shape
)
_PAD_PARAMS
=
combinations_grid
(
padding
=
[[
1
],
[
1
,
1
],
[
1
,
1
,
2
,
2
]],
padding_mode
=
[
"constant"
,
"symmetric"
,
"edge"
,
"reflect"
],
)
def
sample_inputs_pad_image_tensor
():
make_pad_image_loaders
=
functools
.
partial
(
make_image_loaders
,
sizes
=
[
DEFAULT_PORTRAIT_SPATIAL_SIZE
],
color_spaces
=
[
"RGB"
],
dtypes
=
[
torch
.
float32
]
)
for
image_loader
,
padding
in
itertools
.
product
(
make_pad_image_loaders
(),
[
1
,
(
1
,),
(
1
,
2
),
(
1
,
2
,
3
,
4
),
[
1
],
[
1
,
2
],
[
1
,
2
,
3
,
4
]],
):
yield
ArgsKwargs
(
image_loader
,
padding
=
padding
)
for
image_loader
in
make_pad_image_loaders
():
for
fill
in
get_fills
(
num_channels
=
image_loader
.
num_channels
,
dtype
=
image_loader
.
dtype
):
yield
ArgsKwargs
(
image_loader
,
padding
=
[
1
],
fill
=
fill
)
for
image_loader
,
padding_mode
in
itertools
.
product
(
# We branch for non-constant padding and integer inputs
make_pad_image_loaders
(
dtypes
=
[
torch
.
uint8
]),
[
"constant"
,
"symmetric"
,
"edge"
,
"reflect"
],
):
yield
ArgsKwargs
(
image_loader
,
padding
=
[
1
],
padding_mode
=
padding_mode
)
# `torch.nn.functional.pad` does not support symmetric padding, and thus we have a custom implementation. Besides
# negative padding, this is already handled by the inputs above.
for
image_loader
in
make_pad_image_loaders
():
yield
ArgsKwargs
(
image_loader
,
padding
=
[
-
1
],
padding_mode
=
"symmetric"
)
def
reference_inputs_pad_image_tensor
():
for
image_loader
,
params
in
itertools
.
product
(
make_image_loaders
(
extra_dims
=
[()],
dtypes
=
[
torch
.
uint8
]),
_PAD_PARAMS
):
for
fill
in
get_fills
(
num_channels
=
image_loader
.
num_channels
,
dtype
=
image_loader
.
dtype
,
):
# FIXME: PIL kernel doesn't support sequences of length 1 if the number of channels is larger. Shouldn't it?
if
isinstance
(
fill
,
(
list
,
tuple
)):
continue
yield
ArgsKwargs
(
image_loader
,
fill
=
fill
,
**
params
)
def
sample_inputs_pad_bounding_boxes
():
for
bounding_boxes_loader
,
padding
in
itertools
.
product
(
make_bounding_box_loaders
(),
[
1
,
(
1
,),
(
1
,
2
),
(
1
,
2
,
3
,
4
),
[
1
],
[
1
,
2
],
[
1
,
2
,
3
,
4
]]
):
yield
ArgsKwargs
(
bounding_boxes_loader
,
format
=
bounding_boxes_loader
.
format
,
canvas_size
=
bounding_boxes_loader
.
canvas_size
,
padding
=
padding
,
padding_mode
=
"constant"
,
)
def
sample_inputs_pad_mask
():
for
mask_loader
in
make_mask_loaders
(
sizes
=
[
DEFAULT_PORTRAIT_SPATIAL_SIZE
],
num_categories
=
[
10
],
num_objects
=
[
5
]):
yield
ArgsKwargs
(
mask_loader
,
padding
=
[
1
])
def
reference_inputs_pad_mask
():
for
mask_loader
,
fill
,
params
in
itertools
.
product
(
make_mask_loaders
(
num_objects
=
[
1
],
extra_dims
=
[()]),
[
None
,
127
],
_PAD_PARAMS
):
yield
ArgsKwargs
(
mask_loader
,
fill
=
fill
,
**
params
)
def
sample_inputs_pad_video
():
for
video_loader
in
make_video_loaders
(
sizes
=
[
DEFAULT_PORTRAIT_SPATIAL_SIZE
],
num_frames
=
[
3
]):
yield
ArgsKwargs
(
video_loader
,
padding
=
[
1
])
def
reference_pad_bounding_boxes
(
bounding_boxes
,
*
,
format
,
canvas_size
,
padding
,
padding_mode
):
left
,
right
,
top
,
bottom
=
_parse_pad_padding
(
padding
)
affine_matrix
=
np
.
array
(
[
[
1
,
0
,
left
],
[
0
,
1
,
top
],
],
dtype
=
"float64"
if
bounding_boxes
.
dtype
==
torch
.
float64
else
"float32"
,
)
height
=
canvas_size
[
0
]
+
top
+
bottom
width
=
canvas_size
[
1
]
+
left
+
right
expected_bboxes
=
reference_affine_bounding_boxes_helper
(
bounding_boxes
,
format
=
format
,
canvas_size
=
(
height
,
width
),
affine_matrix
=
affine_matrix
)
return
expected_bboxes
,
(
height
,
width
)
def
reference_inputs_pad_bounding_boxes
():
for
bounding_boxes_loader
,
padding
in
itertools
.
product
(
make_bounding_box_loaders
(
extra_dims
=
((),
(
4
,))),
[
1
,
(
1
,),
(
1
,
2
),
(
1
,
2
,
3
,
4
),
[
1
],
[
1
,
2
],
[
1
,
2
,
3
,
4
]]
):
yield
ArgsKwargs
(
bounding_boxes_loader
,
format
=
bounding_boxes_loader
.
format
,
canvas_size
=
bounding_boxes_loader
.
canvas_size
,
padding
=
padding
,
padding_mode
=
"constant"
,
)
def
pad_xfail_jit_fill_condition
(
args_kwargs
):
fill
=
args_kwargs
.
kwargs
.
get
(
"fill"
)
if
not
isinstance
(
fill
,
(
list
,
tuple
)):
return
False
elif
isinstance
(
fill
,
tuple
):
return
True
else
:
# isinstance(fill, list):
return
all
(
isinstance
(
f
,
int
)
for
f
in
fill
)
KERNEL_INFOS
.
extend
(
[
KernelInfo
(
F
.
pad_image
,
sample_inputs_fn
=
sample_inputs_pad_image_tensor
,
reference_fn
=
pil_reference_wrapper
(
F
.
_pad_image_pil
),
reference_inputs_fn
=
reference_inputs_pad_image_tensor
,
float32_vs_uint8
=
float32_vs_uint8_fill_adapter
,
closeness_kwargs
=
float32_vs_uint8_pixel_difference
(),
test_marks
=
[
xfail_jit_python_scalar_arg
(
"padding"
),
xfail_jit
(
"F.pad only supports vector fills for list of floats"
,
condition
=
pad_xfail_jit_fill_condition
),
],
),
KernelInfo
(
F
.
pad_bounding_boxes
,
sample_inputs_fn
=
sample_inputs_pad_bounding_boxes
,
reference_fn
=
reference_pad_bounding_boxes
,
reference_inputs_fn
=
reference_inputs_pad_bounding_boxes
,
test_marks
=
[
xfail_jit_python_scalar_arg
(
"padding"
),
],
),
KernelInfo
(
F
.
pad_mask
,
sample_inputs_fn
=
sample_inputs_pad_mask
,
reference_fn
=
pil_reference_wrapper
(
F
.
_pad_image_pil
),
reference_inputs_fn
=
reference_inputs_pad_mask
,
float32_vs_uint8
=
float32_vs_uint8_fill_adapter
,
),
KernelInfo
(
F
.
pad_video
,
sample_inputs_fn
=
sample_inputs_pad_video
,
),
]
)
_PERSPECTIVE_COEFFS
=
[
_PERSPECTIVE_COEFFS
=
[
[
1.2405
,
0.1772
,
-
6.9113
,
0.0463
,
1.251
,
-
5.235
,
0.00013
,
0.0018
],
[
1.2405
,
0.1772
,
-
6.9113
,
0.0463
,
1.251
,
-
5.235
,
0.00013
,
0.0018
],
[
0.7366
,
-
0.11724
,
1.45775
,
-
0.15012
,
0.73406
,
2.6019
,
-
0.0072
,
-
0.0063
],
[
0.7366
,
-
0.11724
,
1.45775
,
-
0.15012
,
0.73406
,
2.6019
,
-
0.0072
,
-
0.0063
],
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment