mxnet
exec_utils.h
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
24 #ifndef MXNET_COMMON_EXEC_UTILS_H_
25 #define MXNET_COMMON_EXEC_UTILS_H_
26 
27 #include <vector>
28 #include "../common/utils.h"
29 
30 namespace mxnet {
31 namespace common {
32 
33 /*
34  * \brief setup default-storage tblobs from source NDArrays. If any source NDArray has non-default
35  * storage, it creates a temp NDArray with default storage and uses the temp tblob. The
36  * function also records the indices of non-default source NDArrays and the indices of
37  * their corresponding temporary NDArrays in the temp array.
38  * \param src list of source NDArray
39  * \param blobs list of tblobs to return
40  * \param temp_src list of source NDArrays which requires temporary default storage representation
41  * \param temp_dst list of temporary destination NDArrays for default storage representation
42  * \param idx_map mapping from indices in source NDArrays to indices in temp_dst. When not set,
43  indices are not recorded
44  * \return true if any source NDArray need to cast storage
45  */
46 inline bool SetupDefaultBlobsIn(const std::vector<NDArray>& src,
47  const std::vector<NDArray> *bufs,
48  std::vector<TBlob> *blobs,
49  std::vector<NDArray> *temp_src,
50  std::vector<NDArray> *temp_dst,
51  std::unordered_map<uint32_t, uint32_t> *idx_map) {
52  bool require_cast = false;
53  for (size_t i = 0; i < src.size(); i++) {
54  auto& nd = src[i];
55  bool is_default = nd.storage_type() == kDefaultStorage;
56 #if MXNET_USE_MKLDNN == 1
57  // We have to make sure it's default storage and default layout.
58  is_default = nd.IsDefaultData();
59 #endif
60  if (!is_default) {
61  (*idx_map)[i] = temp_dst->size();
62  NDArray temp = bufs != nullptr ? bufs->at(i) : NDArray(nd.shape(), nd.ctx(),
63  true, nd.dtype());
64 #if MXNET_USE_MKLDNN == 1
65  CHECK(temp.IsDefaultData());
66 #endif
67  temp_src->emplace_back(nd);
68  temp_dst->emplace_back(temp);
69  blobs->emplace_back(temp.data());
70  require_cast = true;
71  } else {
72  blobs->push_back(nd.data());
73  }
74  }
75  return require_cast;
76 }
77 
78 inline bool SetupDefaultBlobsOut(const std::vector<NDArray>& src,
79  const std::vector<NDArray> *bufs,
80  std::vector<OpReqType> *req,
81  std::vector<TBlob> *blobs,
82  std::vector<NDArray> *temp_src,
83  std::vector<NDArray> *temp_dst) {
84  bool require_cast = false;
85  for (size_t i = 0; i < src.size(); i++) {
86  auto& nd = src[i];
87  bool is_default = nd.storage_type() == kDefaultStorage;
88 #if MXNET_USE_MKLDNN == 1
89  if (req->at(i) == kWriteInplace && nd.IsMKLDNNData())
90  // If it's write inplace and the output array doesn't use the default
91  // layout, we'll generate a temporary output array below, which means
92  // the input array and the output array are no longer the same array.
93  // we should change the request type.
94  req->at(i) = kWriteTo;
95  // We have to make sure it's default storage and default layout.
96  is_default = nd.IsDefaultData();
97 #endif
98  if (!is_default) {
99  NDArray temp = bufs != nullptr ? bufs->at(i) : NDArray(nd.shape(), nd.ctx(),
100  true, nd.dtype());
101 #if MXNET_USE_MKLDNN == 1
102  CHECK(temp.IsDefaultData());
103 #endif
104  temp_src->emplace_back(nd);
105  temp_dst->emplace_back(temp);
106  blobs->emplace_back(temp.data());
107  require_cast = true;
108  } else {
109  blobs->push_back(nd.data());
110  }
111  }
112  return require_cast;
113 }
114 
115 /*
116  * \brief setup default-storage tblobs for input and output NDArrays.
117  * If any NDArray has non-default storage,
118  * it creates a temp NDArray with default storage and uses the temp tblob. The
119  * function also records the indices of non-default source NDArrays and the indices of
120  * their corresponding temporary NDArrays in the temp array.
121  */
122 inline void SetupDefaultBlobsInOut(const std::vector<NDArray> &ndinputs,
123  const std::vector<NDArray> &ndoutputs,
124  const std::vector<NDArray> *in_bufs,
125  const std::vector<NDArray> *out_bufs,
126  std::vector<OpReqType> *req,
127  std::vector<TBlob> *input_blobs,
128  std::vector<TBlob> *output_blobs,
129  std::vector<NDArray> *pre_temp_src,
130  std::vector<NDArray> *pre_temp_dst,
131  std::vector<NDArray> *post_temp_src,
132  std::vector<NDArray> *post_temp_dst,
133  std::unordered_map<uint32_t, uint32_t> *in_temp_idx_map,
134  const std::vector<uint32_t> &mutate_idx) {
135  // populate input blobs
136  SetupDefaultBlobsIn(ndinputs, in_bufs, input_blobs, pre_temp_src, pre_temp_dst,
137  in_temp_idx_map);
138  // populate output blobs
139  SetupDefaultBlobsOut(ndoutputs, out_bufs, req, output_blobs, post_temp_dst,
140  post_temp_src);
141  // add mutable inputs to post temp list
142  for (const auto idx : mutate_idx) {
143  auto map_iter = in_temp_idx_map->find(idx);
144  if (map_iter != in_temp_idx_map->end()) {
145  post_temp_src->push_back(pre_temp_dst->at(map_iter->second));
146  post_temp_dst->push_back(ndinputs[idx]);
147  }
148  }
149 }
150 
151 /*
152  * \brief cast the NDArrays in `src` and store the result in NDArrays in `dst`.
153  * This is only used for storage fallback in executor.
154  * \param src list of source NDArray to cast
155  * \param dst list of destionation NDArray which hold the result of cast_storage operation
156  * \param ctx operator context for cast_storage operation
157  */
158 inline void CastNonDefaultStorage(const std::vector<NDArray>& src,
159  const std::vector<NDArray>& dst,
160  const OpContext& ctx,
161  const bool is_gpu) {
162  CHECK_EQ(dst.size(), src.size());
163  for (size_t i = 0; i < src.size(); i++) {
164  if (is_gpu) {
165 #if MXNET_USE_CUDA
166  CastStorageDispatch<gpu>(ctx, src[i], dst[i]);
167 #else
168  LOG(FATAL) << MXNET_GPU_NOT_ENABLED_ERROR;
169 #endif
170  } else {
171  CastStorageDispatch<cpu>(ctx, src[i], dst[i]);
172  }
173  }
174 }
175 
179 inline bool SameType(const nnvm::NodeAttrs& attrs,
180  std::vector<int> *iattr,
181  std::vector<int> *oattr) {
182  int def_v = -1;
183  for (int v : *oattr) {
184  if (v != -1) {
185  def_v = v; break;
186  }
187  }
188  if (def_v == -1) {
189  for (int v : *iattr) {
190  if (v != -1) {
191  def_v = v; break;
192  }
193  }
194  }
195  if (def_v == -1) return false;
196  for (int& v : *oattr) {
197  v = def_v;
198  }
199  for (int& v : *iattr) {
200  v = def_v;
201  }
202  return true;
203 }
204 
205 
211 inline bool DefaultStorageType(const nnvm::NodeAttrs& attrs,
212  const int dev_mask,
213  DispatchMode* dispatch_mode,
214  std::vector<int> *iattr,
215  std::vector<int> *oattr) {
216  bool fallback = false;
217  for (int& v : *oattr) {
218  if (v == -1) v = kDefaultStorage;
219  if (v != kDefaultStorage) fallback = true;
220  }
221  for (int& v : *iattr) {
222  if (v == -1) v = kDefaultStorage;
223  if (v != kDefaultStorage) fallback = true;
224  }
225  if (*dispatch_mode == DispatchMode::kUndefined) {
226  if (fallback) {
227  *dispatch_mode = DispatchMode::kFComputeFallback;
228  } else {
229  *dispatch_mode = DispatchMode::kFCompute;
230  }
231  }
232  return true;
233 }
234 
235 
236 } // namespace common
237 } // namespace mxnet
238 #endif // MXNET_COMMON_EXEC_UTILS_H_
Definition: ndarray.h:63
bool SameType(const nnvm::NodeAttrs &attrs, std::vector< int > *iattr, std::vector< int > *oattr)
The default type inference function, which assigns all undefined types to the same type of one of the...
Definition: exec_utils.h:179
#define MXNET_GPU_NOT_ENABLED_ERROR
Error message for using gpu when MXNET_USE_CUDA==0.
Definition: base.h:68
write gradient to provided space
Definition: op_attr_types.h:49
namespace of mxnet
Definition: base.h:118
DispatchMode
the dispatch mode of the operator
Definition: op_attr_types.h:105
All the possible information needed by Operator.Forward and Backward This is the superset of RunConte...
Definition: op_attr_types.h:66
void CastNonDefaultStorage(const std::vector< NDArray > &src, const std::vector< NDArray > &dst, const OpContext &ctx, const bool is_gpu)
Definition: exec_utils.h:158
bool SetupDefaultBlobsIn(const std::vector< NDArray > &src, const std::vector< NDArray > *bufs, std::vector< TBlob > *blobs, std::vector< NDArray > *temp_src, std::vector< NDArray > *temp_dst, std::unordered_map< uint32_t, uint32_t > *idx_map)
Definition: exec_utils.h:46
perform an inplace write, This option only happen when Target shares memory with one of input argumen...
Definition: op_attr_types.h:55
const TBlob & data() const
Definition: ndarray.h:215
void SetupDefaultBlobsInOut(const std::vector< NDArray > &ndinputs, const std::vector< NDArray > &ndoutputs, const std::vector< NDArray > *in_bufs, const std::vector< NDArray > *out_bufs, std::vector< OpReqType > *req, std::vector< TBlob > *input_blobs, std::vector< TBlob > *output_blobs, std::vector< NDArray > *pre_temp_src, std::vector< NDArray > *pre_temp_dst, std::vector< NDArray > *post_temp_src, std::vector< NDArray > *post_temp_dst, std::unordered_map< uint32_t, uint32_t > *in_temp_idx_map, const std::vector< uint32_t > &mutate_idx)
Definition: exec_utils.h:122
bool SetupDefaultBlobsOut(const std::vector< NDArray > &src, const std::vector< NDArray > *bufs, std::vector< OpReqType > *req, std::vector< TBlob > *blobs, std::vector< NDArray > *temp_src, std::vector< NDArray > *temp_dst)
Definition: exec_utils.h:78
bool DefaultStorageType(const nnvm::NodeAttrs &attrs, const int dev_mask, DispatchMode *dispatch_mode, std::vector< int > *iattr, std::vector< int > *oattr)
The default storage type inference function, which assigns all undefined storage types to kDefaultSto...
Definition: exec_utils.h:211
ndarray interface
Definition: ndarray.h:82