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

Erase CPU operator #1609

Merged
merged 19 commits into from
Jan 9, 2020
Merged

Erase CPU operator #1609

merged 19 commits into from
Jan 9, 2020

Conversation

jantonguirao
Copy link
Contributor

@jantonguirao jantonguirao commented Dec 24, 2019

Why we need this PR?

Pick one, remove the rest

  • It adds a new feature: Erase CPU operator, allowing to erase regions of the input, assigning a constant value

What happened in this PR?

Fill relevant points, put NA otherwise. Replace anything inside []

  • What solution was applied:
    Created an Erase CPU kernel
    Created an Erase CPU operator
    The Erase operator API allows the user to specify one or more regions with an anchor and a shape. The coordinates in both anchor and shape are typically a subset of the input dimensions. The user can specify the dimensions to be used.
    Example:
    layout="HWC" axis_names="WH" anchor=(10, 20) shape=(20, 30)
    specifies a region going from x=10 to x=30 and from y=20 to y=50
  • Affected modules and functionalities:
    Erase CPU kernel and operator
  • Key points relevant for the review:
    The kernel and operator implementation
  • Validation and testing:
    Python tests for the operator and C++ tests for the kernel
  • Documentation (including examples):
    Doc string contains detailed usage description, including example
    Jupyter notebook example

JIRA TASK: [DALI-1206]

Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
@jantonguirao jantonguirao changed the title [WIP] Erase CPU operator Erase CPU operator Dec 30, 2019
@jantonguirao jantonguirao requested a review from a team December 30, 2019 12:42
Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
@klecki
Copy link
Contributor

klecki commented Jan 2, 2020

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [1054794]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [1054794]: BUILD FAILED

Copy link
Contributor

@klecki klecki left a comment

Choose a reason for hiding this comment

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

The kernel and operator look ok, small problem in argument handling, most issues with docs and argument handling - I'm ok with merging this and later reworking.

As for the example it would be good to repeat and explain the layout of multiple ROIs and maybe show how they are treated when they are out of bounds.

There seem to be empty cells at the end as well.

@@ -0,0 +1,18 @@
# Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
Copy link
Contributor

Choose a reason for hiding this comment

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

Soon to be 2020.

Suggested change
# Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

will fix

The erase region covers the range from 10 to 200 in the vertical dimension (heigth) and goes from
20 to 220 in the horizontal dimension (width). The range for the channel dimension goes from 0 to 3, as it
was not specified. That is
output[y, x, c] = 0 if 20 <= x < 220 and 10 <= y < 200
Copy link
Contributor

Choose a reason for hiding this comment

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

That formatting probably is going to be off, maybe use the :: for preformatted block?
Also below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

will do

if (spec.HasArgument("axis_names")) {
for (auto axis_name : spec.GetArgument<TensorLayout>("axis_names")) {
int d = layout.find(axis_name);
DALI_ENFORCE(d >= 0);
Copy link
Contributor

Choose a reason for hiding this comment

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

I would put a verbose message here, like:

Suggested change
DALI_ENFORCE(d >= 0);
DALI_ENFORCE(d >= 0, make_string("Axis ', axis_name, "' is not present in the input layout.");

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do


namespace detail {

SmallVector<int, 3> GetAxes(const OpSpec &spec, TensorLayout layout) {
Copy link
Contributor

Choose a reason for hiding this comment

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

BTW, I think at this point it would be good to factor out the handling of axes, axis_names, anchor and shape as they are shared with Slice (and related Operators) and the code should probably be reused - we will have unified behaviour for that instead of reimplementing it every time.

This one here gets a slightly different behaviour as you can specify multiple anchors, but that probably is doable with limiting it to 1 anchor for slice.

I'm fine with doing this as a follow-up.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree, let's do that in a follow-up PR

} else if (spec.HasArgument("axes")) {
axes = spec.GetRepeatedArgument<int>("axes");
} else {
// no axes info, expecting all dimensions except 'C'
Copy link
Contributor

Choose a reason for hiding this comment

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

Either I missed it or there is no description of this behaviour in the docstring.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's there in the description of "fill_value":

  .AddOptionalArg("fill_value",
    R"code(Value to fill the erased region. Might be specified as a single value (e.g. 0) or a multi-channel value
(e.g. (200, 210, 220)). If a multi-channel fill value is provided, the input layout should contain a channel dimension `C`)code",
    std::vector<float>{0, })

Copy link
Contributor

Choose a reason for hiding this comment

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

But still it doesn't say that the axes can be left unspecified and than you expect shapes for everything except 'C'

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right, I'll fix that

auto norm_anchor = spec.template GetArgument<bool>("normalized_anchor");

std::vector<float> roi_shape;
bool has_tensor_roi_shape = spec.HasTensorArgument("anchor");
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy-paste mistake?

Suggested change
bool has_tensor_roi_shape = spec.HasTensorArgument("anchor");
bool has_tensor_roi_shape = spec.HasTensorArgument("shape");

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch

Signed-off-by: Joaquin Anton <janton@nvidia.com>
@jantonguirao
Copy link
Contributor Author

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [1054835]: BUILD STARTED

@@ -70,7 +73,7 @@ Example 3:
vector<float>(), true)
.AddOptionalArg("axes",
R"code(Order of dimensions used for anchor and shape arguments, as dimension indexes. For instance, `axes=(1, 0)`
means the coordinates in `anchor` and `shape` refer to axes 1 and 0, in that particular order)code",
means the coordinates in `anchor` and `shape` refer to axes 1 and 0,1054794 in that particular order)code",
Copy link
Contributor

@klecki klecki Jan 2, 2020

Choose a reason for hiding this comment

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

??

Suggested change
means the coordinates in `anchor` and `shape` refer to axes 1 and 0,1054794 in that particular order)code",
means the coordinates in `anchor` and `shape` refer to axes 1 and 0, in that particular order)code",

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [1054835]: BUILD PASSED

Signed-off-by: Joaquin Anton <janton@nvidia.com>
@jantonguirao
Copy link
Contributor Author

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [1056239]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [1056239]: BUILD PASSED

@jantonguirao jantonguirao requested a review from a team January 7, 2020 14:32
Copy link
Contributor

@JanuszL JanuszL left a comment

Choose a reason for hiding this comment

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

erase.ipynb is not included in the docs.

}

INSTANTIATE_TEST_SUITE_P(EraseCpuTest, EraseCpuTest, testing::Combine(
testing::Values(std::array<int64_t, 3>{32, 15, 3}), // data shape
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add a test case of 1C image as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do


Example 3:

anchor=(0.15, 0.15), shape=(0.3, 0.3), axis_names="HW", fill_value=(100,), normalized_anchor=True, normalized_shape=True
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
anchor=(0.15, 0.15), shape=(0.3, 0.3), axis_names="HW", fill_value=(100,), normalized_anchor=True, normalized_shape=True
anchor=(0.15, 0.15), shape=(0.3, 0.3), axis_names="HW", fill_value=100, normalized_anchor=True, normalized_shape=True

For consistence?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

will do

Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
Signed-off-by: Joaquin Anton <janton@nvidia.com>
@jantonguirao
Copy link
Contributor Author

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [1062421]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [1062421]: BUILD FAILED

Signed-off-by: Joaquin Anton <janton@nvidia.com>
@jantonguirao
Copy link
Contributor Author

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [1062437]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [1062437]: BUILD FAILED

Signed-off-by: Joaquin Anton <janton@nvidia.com>
@jantonguirao
Copy link
Contributor Author

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [1062776]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [1062776]: BUILD PASSED

@jantonguirao jantonguirao merged commit a524dd9 into NVIDIA:master Jan 9, 2020
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.

4 participants