oneAPI Deep Neural Network Library (oneDNN)
Performance library for Deep Learning
1.96.0
memory_format_propagation.cpp

Annotated version: Memory Format Propagation

/*******************************************************************************
* Copyright 2019-2020 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
#include <iostream>
#include <sstream>
#include <string>
#include "example_utils.hpp"
using namespace dnnl;
void memory_format_propagation_tutorial(engine::kind engine_kind) {
// [Initialize engine and stream]
engine eng(engine_kind, 0);
stream s(eng);
// [Initialize engine and stream]
// [Create placeholder memory descriptors]
// Tensor and kernel dimensions. We use the same 3x3 kernel with padding=1
// for both convolution and pooling primitives, which means that the
// activation tensor shapes do not change.
const int N = 1, H = 14, W = 14, IC = 128, OC = 256, KH = 3, KW = 3;
auto conv_src_md = memory::desc({N, IC, H, W}, memory::data_type::f32,
memory::format_tag::any // let convolution choose memory format
);
auto conv_weights_md = memory::desc(
{OC, IC, KH, KW}, memory::data_type::f32,
memory::format_tag::any // let convolution choose memory format
);
auto conv_dst_md = memory::desc({N, OC, H, W}, memory::data_type::f32,
memory::format_tag::any // let convolution choose memory format
);
auto pool_dst_md = conv_dst_md; // shape does not change
// [Create placeholder memory descriptors]
// [Create convolution and pooling primitive descriptors]
conv_src_md, conv_weights_md,
conv_dst_md, // shape information
{1, 1}, // strides
{1, 1}, {1, 1}}, // left and right padding
eng);
conv_pd.dst_desc(), pool_dst_md, // shape information
{1, 1}, {KH, KW}, // strides and kernel
{1, 1}, {1, 1}}, // left and right padding
eng);
// [Create convolution and pooling primitive descriptors]
// [Create source and destination memory objects]
auto src_mem = memory(
eng);
auto weights_mem = memory({{OC, IC, KH, KW}, memory::data_type::f32,
eng);
auto dst_mem = memory(
eng);
// [Create source and destination memory objects]
// [Determine if source needs to be reordered]
bool need_reorder_src = conv_pd.src_desc() != src_mem.get_desc();
// [Determine if source needs to be reordered]
// [Determine if weights and destination need to be reordered]
bool need_reorder_weights
= conv_pd.weights_desc() != weights_mem.get_desc();
bool need_reorder_dst = conv_pd.dst_desc() != dst_mem.get_desc();
// [Determine if weights and destination need to be reordered]
// [Allocate intermediate buffers if necessary]
auto conv_src_mem
= need_reorder_src ? memory(conv_pd.src_desc(), eng) : src_mem;
auto conv_weights_mem = need_reorder_weights
? memory(conv_pd.weights_desc(), eng)
: weights_mem;
auto conv_dst_mem = memory(conv_pd.dst_desc(), eng);
auto pool_dst_mem
= need_reorder_dst ? memory(pool_pd.dst_desc(), eng) : dst_mem;
// [Allocate intermediate buffers if necessary]
// [Perform reorders for source data if necessary]
if (need_reorder_src) {
auto reorder_src = reorder(src_mem, conv_src_mem);
reorder_src.execute(
s, {{DNNL_ARG_FROM, src_mem}, {DNNL_ARG_TO, conv_src_mem}});
s.wait(); // wait for the reorder to complete
}
if (need_reorder_weights) {
auto reorder_weights = reorder(weights_mem, conv_weights_mem);
reorder_weights.execute(s,
{{DNNL_ARG_FROM, weights_mem},
{DNNL_ARG_TO, conv_weights_mem}});
s.wait(); // wait for the reorder to complete
}
// [Perform reorders for source data if necessary]
// [Create and execute convolution and pooling primitives]
auto conv_scratchpad_mem = memory(conv_pd.scratchpad_desc(), eng);
auto conv = convolution_forward(conv_pd);
conv.execute(s,
{{DNNL_ARG_SRC, conv_src_mem}, {DNNL_ARG_WEIGHTS, conv_weights_mem},
{DNNL_ARG_DST, conv_dst_mem}});
auto pool_scratchpad_mem = memory(pool_pd.scratchpad_desc(), eng);
auto pool = pooling_forward(pool_pd);
pool.execute(
s, {{DNNL_ARG_SRC, conv_dst_mem}, {DNNL_ARG_DST, pool_dst_mem}});
s.wait();
// [Create and execute convolution and pooling primitives]
// [Reorder destination data if necessary]
if (need_reorder_dst) {
auto reorder_dst = reorder(pool_dst_mem, dst_mem);
reorder_dst.execute(
s, {{DNNL_ARG_FROM, pool_dst_mem}, {DNNL_ARG_TO, dst_mem}});
s.wait();
}
// [Reorder destination data if necessary]
}
int main(int argc, char **argv) {
return handle_example_errors(
memory_format_propagation_tutorial, parse_engine_kind(argc, argv));
}
dnnl::convolution_forward::primitive_desc::dst_desc
memory::desc dst_desc() const
Returns a destination memory descriptor.
Definition: dnnl.hpp:3824
dnnl.hpp
dnnl::reorder
Reorder primitive.
Definition: dnnl.hpp:3157
dnnl::stream
An execution stream.
Definition: dnnl.hpp:975
dnnl::engine
An execution engine.
Definition: dnnl.hpp:859
DNNL_ARG_TO
#define DNNL_ARG_TO
A special mnemonic for reorder destination argument.
Definition: dnnl_types.h:2022
dnnl::stream::wait
stream & wait()
Waits for all primitives executing in the stream to finish.
Definition: dnnl.hpp:1015
dnnl::memory::data_type::f32
@ f32
32-bit/single-precision floating point.
dnnl::engine::kind
kind
Kinds of engines.
Definition: dnnl.hpp:864
DNNL_ARG_DST
#define DNNL_ARG_DST
A special mnemonic for destination argument for primitives that have a single destination.
Definition: dnnl_types.h:2019
dnnl::memory::format_tag::oihw
@ oihw
4D CNN weights tensor; an alias for dnnl::memory::format_tag::abcd
dnnl::convolution_forward
Convolution forward propagation primitive.
Definition: dnnl.hpp:3571
dnnl::prop_kind::forward_inference
@ forward_inference
Forward data propagation (inference mode).
dnnl::pooling_forward::primitive_desc
Primitive descriptor for a pooling forward propagation primitive.
Definition: dnnl.hpp:5254
dnnl::memory::get_desc
desc get_desc() const
Returns the associated memory descriptor.
Definition: dnnl.hpp:2004
dnnl::convolution_forward::primitive_desc
Primitive descriptor for a convolution forward propagation primitive.
Definition: dnnl.hpp:3771
DNNL_ARG_SRC
#define DNNL_ARG_SRC
A special mnemonic for source argument for primitives that have a single source.
Definition: dnnl_types.h:1995
dnnl::pooling_forward
Pooling forward propagation primitive.
Definition: dnnl.hpp:5206
dnnl::memory
Memory object.
Definition: dnnl.hpp:1098
dnnl::algorithm::convolution_auto
@ convolution_auto
Convolution algorithm that is chosen to be either direct or Winograd automatically.
dnnl::primitive_desc_base::scratchpad_desc
memory::desc scratchpad_desc() const
Returns the scratchpad memory descriptor.
Definition: dnnl.hpp:3001
dnnl::algorithm::pooling_max
@ pooling_max
Max pooling.
dnnl::primitive_desc_base::weights_desc
memory::desc weights_desc(int idx) const
Returns a weights memory descriptor.
Definition: dnnl.hpp:2918
dnnl::memory::format_tag::any
@ any
Placeholder memory format tag.
dnnl::memory::desc
A memory descriptor.
Definition: dnnl.hpp:1718
dnnl
oneDNN namespace
Definition: dnnl.hpp:74
dnnl::memory::format_tag::nchw
@ nchw
4D CNN activations tensor; an alias for dnnl::memory::format_tag::abcd
DNNL_ARG_WEIGHTS
#define DNNL_ARG_WEIGHTS
A special mnemonic for primitives that have a single weights argument.
Definition: dnnl_types.h:2042
DNNL_ARG_FROM
#define DNNL_ARG_FROM
A special mnemonic for reorder source argument.
Definition: dnnl_types.h:2001