1/*******************************************************************************
2* Copyright 2018-2021 Intel Corporation
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*******************************************************************************/
16
17#ifndef COMMON_PRIMITIVE_EXEC_TYPES_HPP
18#define COMMON_PRIMITIVE_EXEC_TYPES_HPP
19
20#include <unordered_map>
21
22#include "oneapi/dnnl/dnnl_types.h"
23
24#include "c_types_map.hpp"
25#include "memory.hpp"
26#include "memory_storage.hpp"
27
28#define CTX_IN_STORAGE(arg) \
29 (ctx.input(arg) ? *(ctx.input(arg)->memory_storage()) \
30 : dnnl::impl::memory_storage_t::empty_storage())
31
32// Returns destination memory which may not have been zero pad initialized.
33#define CTX_OUT_STORAGE(arg) \
34 (ctx.output(arg) ? *(ctx.output(arg)->memory_storage()) \
35 : dnnl::impl::memory_storage_t::empty_storage())
36
37// Returns destination memory which has been zero pad initialized. This macro
38// may result in a failure returned via the `status` input since zero pad
39// may fail.
40#define CTX_OUT_CLEAN_STORAGE(arg, status) \
41 (ctx.output(arg) ? *(ctx.output(arg)->memory_storage_clean(ctx, status)) \
42 : dnnl::impl::memory_storage_t::empty_storage())
43
44namespace dnnl {
45namespace impl {
46
47namespace memory_tracking {
48struct grantor_t;
49} // namespace memory_tracking
50
51struct memory_arg_t {
52 memory_t *mem;
53 bool is_const;
54};
55
56struct primitive_desc_t;
57
58using exec_args_t = std::unordered_map<int, memory_arg_t>;
59
60status_t cvt_primitive_args(const primitive_desc_t *pd, int nargs,
61 const dnnl_exec_arg_t *c_args, exec_args_t &args);
62
63/** Primitive execution context (helps passing stream, memories, and events. */
64struct resource_mapper_t;
65struct exec_ctx_t {
66 explicit exec_ctx_t(stream_t *stream) : stream_(stream) {}
67 exec_ctx_t(stream_t *stream, exec_args_t &&args)
68 : stream_(stream), args_(std::move(args)) {}
69 exec_ctx_t(const exec_ctx_t &other, exec_args_t &&args)
70 : stream_(other.stream_)
71 , args_(std::move(args))
72 , memory_mapping_(other.memory_mapping_)
73 , resource_mapper_(other.resource_mapper_) {}
74
75 stream_t *stream() const { return stream_; }
76 const exec_args_t &args() const { return args_; }
77
78 memory_t *input(int arg) const;
79 memory_t *output(int arg) const;
80 memory_t *memory(int arg) const;
81
82 status_t zero_pad_output(int arg) const;
83
84 void register_memory_mapping(void *handle, void *host_ptr);
85
86 void *host_ptr(
87 int arg, bool do_zeropad = false, status_t *status = nullptr) const;
88 void *host_ptr(const memory_storage_t *mem_storage) const;
89
90 void *map_memory_storage(const memory_storage_t *storage, stream_t *stream,
91 size_t size) const;
92 void unmap_memory_storage(const memory_storage_t *storage, void *mapped_ptr,
93 stream_t *stream) const;
94
95 // Returns memory descriptor wrapper for the corresponding memory argument.
96 //
97 // To support sub-memory flow (when primitive descriptor was created with
98 // a sub-memory, but the primitive is executed on the original memory),
99 // it is recommended to pass the memory descriptor from the primitive
100 // descriptor. If this memory descriptor is fully defined (i.e. no reason
101 // to use memory descriptor from the input memory), exactly it will be
102 // returned.
103 //
104 // Note: fully defined memory descriptor mentioned above is a synonym to
105 // `mdw::has_runtime_dims_or_strides() == false`.
106 //
107 // XXX: revisit this behavior in oneDNN v2.0. It would be more consistent to
108 // take memory description from the incoming argument. This will
109 // require a sub-memory object, though...
110 memory_desc_wrapper memory_mdw(int arg,
111 const memory_desc_t *md_from_primitive_desc = nullptr) const;
112
113 void set_scratchpad_grantor(
114 const memory_tracking::grantor_t *scratchpad_grantor) {
115 scratchpad_grantor_ = scratchpad_grantor;
116 }
117
118 const memory_tracking::grantor_t &get_scratchpad_grantor() const {
119 return *scratchpad_grantor_;
120 }
121
122 const memory_tracking::grantor_t *grantor_handle() const {
123 return scratchpad_grantor_;
124 }
125
126 const resource_mapper_t *get_resource_mapper() const;
127 void set_resource_mapper(const resource_mapper_t *resource_mapper);
128
129private:
130 stream_t *stream_;
131 exec_args_t args_;
132
133 std::unordered_map<void *, void *> memory_mapping_;
134 const resource_mapper_t *resource_mapper_ = nullptr;
135 const memory_tracking::grantor_t *scratchpad_grantor_ = nullptr;
136};
137
138} // namespace impl
139} // namespace dnnl
140
141#endif
142