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
Rotate per-frame #3820
Rotate per-frame #3820
Conversation
Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
// kernels::vec2shape reverses the extents, store them in that order in parity vector | ||
parity[2 - i] = in_size[dominant_src_axis[i]] % 2; |
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.
What's wrong with storing it naturally and returning vec2shape(parity)
? I think the code would be more readable that way.
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.
Because it has +
operator defined:)
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.
Fair point :) But now that you've mentioned it, it also has a max
. How about switching the order to x, y, z and returning two vectors? You could calculate the size on ivec2/3 and convert to TensorShape at the very end.
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.
Great, thanks for pointing to it.
!build |
CI MESSAGE: [4629623]: BUILD STARTED |
for (int dim_idx = 0; dim_idx < spatial_ndim; dim_idx++) { | ||
bool should_be_odd = 2 * acc_parity[dim_idx] > num_frames; | ||
if (acc_shape[dim_idx] % 2 != should_be_odd) { | ||
acc_shape[dim_idx]++; | ||
} | ||
} |
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.
if acc_shape
was an ivec, you could do:
for (int dim_idx = 0; dim_idx < spatial_ndim; dim_idx++) { | |
bool should_be_odd = 2 * acc_parity[dim_idx] > num_frames; | |
if (acc_shape[dim_idx] % 2 != should_be_odd) { | |
acc_shape[dim_idx]++; | |
} | |
} | |
acc_shape += (acc_shape % 2) ^ (2 * acc_parity > num_frames); |
(it must be ^, because operator != returns a single boolean).
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.
done
assert(len(arrays)) | ||
acc_max = arrays[0] | ||
for array in arrays[1:]: | ||
acc_max = np.maximum(acc_max, array) | ||
return acc_max |
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.
assert(len(arrays)) | |
acc_max = arrays[0] | |
for array in arrays[1:]: | |
acc_max = np.maximum(acc_max, array) | |
return acc_max | |
# find the elementwise maximum of the arrays in the list | |
return np.max(arrays, axis=0) |
It will automatically treat the outer list as an extra dimension.
Perhaps you don't even need a function for that (see below).
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.
done
corrected_shapes = [ | ||
np.array(get_3d_output_size(math.radians(angle), axis, shape, True), dtype=np.int32) | ||
for shape, angle, axis in zip(input_shapes, angles, axes)] | ||
max_shape = maximum_array(no_correction_shapes) |
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.
max_shape = maximum_array(no_correction_shapes) | |
max_shape = np.max(no_correction_shapes, axis=0) # elementwise maximum |
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.
done
parity = sum([np.array([extent % 2 for extent in shape], dtype=np.int32) | ||
for shape in corrected_shapes]) |
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.
parity = sum([np.array([extent % 2 for extent in shape], dtype=np.int32) | |
for shape in corrected_shapes]) | |
parity = np.sum(np.array(corrected_shapes, dtype=np.int32) % 2, 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.
done
CI MESSAGE: [4629623]: BUILD PASSED |
Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
for j in range(3): | ||
if rotation[i, j] > maxv: | ||
maxv = rotation[i, j] | ||
dominant_axis[i] = j |
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.
You're overwriting dominant_axis here, which is still used in the outer loop to get maxv.
Edit: this is not important - these nested loops can be reimplemented as a one-liner, see below.
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.
done
|
||
|
||
def get_3d_output_size(angle, axis, input_size, parity_correction=False): | ||
rotation = np.abs(get_3d_lin_rotation(angle, axis)) |
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.
Nitpick: Some other name would be nice - this is not really a rotation matrix...
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.
done
for i in range(3): | ||
maxv = rotation[i, dominant_axis[i]] | ||
for j in range(3): | ||
if rotation[i, j] > maxv: | ||
maxv = rotation[i, j] | ||
dominant_axis[i] = j |
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.
for i in range(3): | |
maxv = rotation[i, dominant_axis[i]] | |
for j in range(3): | |
if rotation[i, j] > maxv: | |
maxv = rotation[i, j] | |
dominant_axis[i] = j | |
dominant_axis = np.argmax(rotation, axis=1) |
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.
done
if out_size[i] % 2 != in_size[dominant_axis[i]] % 2: | ||
out_size[i] += 1 | ||
|
||
return np.array(list(reversed(out_size)), dtype=np.int32) |
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.
return np.array(list(reversed(out_size)), dtype=np.int32) | |
return out_size[::-1] |
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.
done
@@ -28,6 +28,49 @@ | |||
vid_file = os.path.join(data_root, 'db', 'video', | |||
'sintel', 'sintel_trailer-720p.mp4') | |||
|
|||
class ParamsProvider: | |||
def __init__(self, input_params): |
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.
How about:
def __init__(self, input_params): | |
def __init__(self, **input_params : ParamDesc): |
?
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 wanted to leave existing tests as they are. I split the ParamsProvider into a base class and actual class, the first is just about providing input data to the provider instance while the actual one take input arguments description (added docs there with some type annotation) and computes parameters. This way derived classes can easily control format of tensor arguments description.
Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
!build |
CI MESSAGE: [4667693]: BUILD STARTED |
CI MESSAGE: [4667693]: BUILD FAILED |
CI MESSAGE: [4667693]: BUILD PASSED |
* Add support for FHWC and FDHWC layouts * Add support for per-frame tensor input to angle and axis parameters Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
* Add support for FHWC and FDHWC layouts * Add support for per-frame tensor input to angle and axis parameters Signed-off-by: Kamil Tokarski <ktokarski@nvidia.com>
Signed-off-by: Kamil Tokarski ktokarski@nvidia.com
Category:
New feature (non-breaking change which adds functionality)
Description:
angle
andaxis
parameters.Additional information:
Affected modules and functionalities:
Key points relevant for the review:
Checklist
Tests
Documentation
DALI team only
Requirements
REQ IDs: ROTATE.10
JIRA TASK: DALI-2508