Skip to content

Commit

Permalink
api,cpu,tests: introduce resampling primitive
Browse files Browse the repository at this point in the history
  • Loading branch information
irinasok committed Dec 6, 2019
1 parent bbf635f commit 16b9a5d
Show file tree
Hide file tree
Showing 40 changed files with 3,193 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc/mainpage.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Memory bandwidth limited operations:
* [Local Response Normalization](@ref dev_guide_lrn)
* [LogSoftmax](@ref dev_guide_logsoftmax)
* [Pooling](@ref dev_guide_pooling)
* [Resampling](@ref dev_guide_resampling)
* [Shuffle](@ref dev_guide_shuffle)
* [Softmax](@ref dev_guide_softmax)
* [Sum](@ref dev_guide_sum)
Expand Down
123 changes: 123 additions & 0 deletions doc/primitives/resampling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
Resampling {#dev_guide_resampling}
=====================================

>
> [API reference](@ref dnnl_api_resampling)
>
The resampling primitive computes forward or backward resampling operation on
1D, 2D, or 3D spatial data. Resampling performs spatial scaling of original
tensor using one of the supported interpolation algorithms:
- Nearest Neighbor
- Linear (or Bilinear for 2D spatial tensor, Trilinear for 3D spatial tensor).

Resampling operation is defined by the source tensor and scaling factors in
each spatial dimension. Upsampling and downsampling are the alternative terms
for resampling that are used when all scaling factors are greater (upsampling)
or less (downsampling) than one.

The resampling operation is defined by the following formulas. We show formulas
only for 2D spatial data which are straightforward to generalize to cases of
higher and lower dimensions. Variable names follow the standard
@ref dev_guide_conventions.

Let \f$src\f$ and \f$dst\f$ be \f$N \times C \times IH \times IW\f$ and \f$N
\times C \times OH \times OW\f$ tensors respectively. Let
\f$ F_h = \frac{OH}{IH} \f$ and \f$ F_w = \frac{OW}{IW} \f$ define scaling
factors in each spatial dimension.

The following formulas show how DNNL computes resampling for nearest neighbor
and bilinear interpolation methods.
To further simplify the formulas, we assume the following:
- \f$src(n, ic, ih, iw) = 0\f$ if \f$ih < 0\f$ or \f$iw < 0\f$,
- \f$src(n, ic, ih, iw) = src(n, ic, IH - 1, iw)\f$ if \f$ih \geq IH\f$,
- \f$src(n, ic, ih, iw) = src(n, ic, ih, IW - 1)\f$ if \f$iw \geq IW\f$.

### Forward

#### Nearest Neighbor Resampling

\f[dst(n, c, oh, ow) = src(n, c, ih, iw)\f]

where

- \f$ih = [\frac{oh + 0.5} {F_h} - 0.5]\f$,
- \f$iw = [\frac{ow + 0.5} {F_w} - 0.5]\f$.

#### Bilinear Resampling

\f[
dst(n, c, oh, ow) =
src(n, c, ih_0, iw_0) \cdot W_{ih} \cdot W_{iw} + \\
src(n, c, ih_1, iw_0) \cdot (1 - W_{ih}) \cdot W_{iw} + \\
src(n, c, ih_0, iw_1) \cdot W_{ih} \cdot (1 - W_{iw}) + \\
src(n, c, ih_1, iw_1) \cdot (1 - W_{ih}) \cdot (1 - W_{iw}) \\
\f]

where
- \f$ih_0 = \left\lfloor{\frac {oh + 0.5} {F_h} - 0.5}\right\rfloor\f$,
- \f$ih_1 = \left\lceil {\frac {oh + 0.5} {F_h} - 0.5}\right\rceil\f$,
- \f$iw_0 = \left\lfloor{\frac {ow + 0.5} {F_w} - 0.5}\right\rfloor\f$,
- \f$iw_1 = \left\lceil {\frac {ow + 0.5} {F_w} - 0.5}\right\rceil\f$,
- \f$W_{ih} = \frac{oh + 0.5}{F_h} - 0.5 - ih_0\f$,
- \f$W_{iw} = \frac{ow + 0.5}{F_w} - 0.5 - iw_0\f$.


#### Difference Between Forward Training and Forward Inference

There is no difference between the #dnnl_forward_training
and #dnnl_forward_inference propagation kinds.

### Backward

The backward propagation computes \f$diff\_src\f$
based on \f$diff\_dst\f$.

## Implementation Details

### General Notes
1. Resampling implementation supports data with arbitrary data tag (nchw, nhwc,
nChw16c, etc.) but memory tags for `src` and `dst` are expected to be the
same. Resampling primitive supports `dst` and `diff_src` memory tag
#dnnl::memory::format_tag::any and can define destination format based on
source format.
2. Resampling descriptor can be created by specifying the source and
destination memory descriptors, only the source descriptor and floating
point factors, or the source and destination memory descriptors and factors.
In case when user does not provide the destination descriptor, the
destination dimensions are deduced using the factors:
\f$
output\_spatial\_size = \left\lfloor{
\frac{input\_spatial\_size} {F}
}\right\rfloor
\f$.

@note
Implementation of resampling algorithm uses factors as defined by the
relation \f$F = \frac{output\_spatial\_ size} {
input\_spatial\_size}\f$ that do not necessarily equal to the ones passed
by the user.


### Data Types

Resampling primitive supports the following combination of data types for
source and destination memory objects:

| Propagation | Source | Destination |
| :-- | :-- | :-- |
| forward / backward | f32 | f32 |
| forward / backward | bf16 | bf16 |

### Post-ops and Attributes

The resampling primitive doesn't support any post-ops or attributes.

## Implementation Limitations

1. No primitive specific limitations. Refer to @ref dev_guide_data_types for
limitations related to data types support.

## Performance Tips

N/A
55 changes: 55 additions & 0 deletions include/dnnl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2727,6 +2727,61 @@ dnnl_status_t DNNL_API dnnl_matmul_desc_init(dnnl_matmul_desc_t *matmul_desc,

/// @} dnnl_api_matmul

/// @addtogroup dnnl_api_resampling Resampling
/// @{

/// Initializes a descriptor for a resampling forward propagation primitive.
///
/// @note
/// Destination memory descriptor is allowed to be initialized with
/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any.
///
/// Inputs:
/// - src (#dnnl_query_src_md, 0)
///
/// Outputs:
/// - dst (#dnnl_query_dst_md, 0)
///
///
/// @param resampling_desc Output descriptor for a resamplinging primitive.
/// @param prop_kind Propagation kind. Possible values are
/// #dnnl_forward_training and #dnnl_forward_inference.
/// @param alg_kind resampling algorithm kind: either #dnnl_resampling_nearest,
/// or #dnnl_resampling_linear.
/// @param factors Array of scaling factors for spatial dimension.
/// @param src_desc Source memory descriptor.
/// @param dst_desc Destination memory descriptor.
/// @returns #dnnl_success on success and a status describing the error
/// otherwise.
dnnl_status_t DNNL_API dnnl_resampling_forward_desc_init(
dnnl_resampling_desc_t *resampling_desc, dnnl_prop_kind_t prop_kind,
dnnl_alg_kind_t alg_kind, const float *factors,
const dnnl_memory_desc_t *src_desc, const dnnl_memory_desc_t *dst_desc);

/// Initializes a descriptor for resampling backward propagation primitive.
///
/// Inputs:
/// - diff_dst (#dnnl_query_diff_dst_md, 0)
///
/// Outputs:
/// - diff_src (#dnnl_query_diff_src_md, 0)
///
/// @param resampling_desc Output descriptor for a resampling primitive.
/// @param alg_kind resamplinging algorithm kind: either
/// #dnnl_resampling_nearest, or #dnnl_resampling_linear.
/// @param diff_src_desc Diff source memory descriptor.
/// @param diff_dst_desc Diff destination memory descriptor.
/// @param factors Array of scaling factors for spatial dimension.
/// @returns #dnnl_success on success and a status describing the error
/// otherwise.
///
dnnl_status_t DNNL_API dnnl_resampling_backward_desc_init(
dnnl_resampling_desc_t *resampling_desc, dnnl_alg_kind_t alg_kind,
const float *factors, const dnnl_memory_desc_t *diff_src_desc,
const dnnl_memory_desc_t *diff_dst_desc);

/// @} dnnl_api_resampling

/// @} dnnl_api_primitives

/// @addtogroup dnnl_api_engine
Expand Down
Loading

0 comments on commit 16b9a5d

Please sign in to comment.