mxnet
base.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 
25 #ifndef MXNET_BASE_H_
26 #define MXNET_BASE_H_
27 
28 #include <dmlc/base.h>
29 #include <dmlc/io.h>
30 #include <dmlc/type_traits.h>
31 #include <dmlc/parameter.h>
32 #include <mshadow/tensor.h>
33 // nnvm headers for symbolic construction.
34 #include <nnvm/op.h>
35 #include <nnvm/tuple.h>
36 #include <nnvm/symbolic.h>
37 #include <string>
38 
42 #ifndef MXNET_USE_OPENCV
43 #define MXNET_USE_OPENCV 1
44 #endif
45 
49 #ifndef MXNET_USE_CUDA
50 #define MXNET_USE_CUDA MSHADOW_USE_CUDA
51 #endif
52 
56 #ifndef MXNET_USE_CUDNN
57 #define MXNET_USE_CUDNN MSHADOW_USE_CUDNN
58 #endif
59 
63 #ifndef MXNET_USE_CUSOLVER
64 #define MXNET_USE_CUSOLVER MSHADOW_USE_CUSOLVER
65 #endif
66 
68 #define MXNET_GPU_NOT_ENABLED_ERROR "GPU is not enabled"
69 
74 #if DMLC_USE_CXX11 && defined(__GNUC__) && !defined(__clang_version__)
75 #if __GNUC__ == 4 && __GNUC_MINOR__ < 8
76 #error "Currently we need g++ 4.8 or higher to fully support c++11 features"
77 #define override
78 #define final
79 #endif
80 #endif
81 
85 #ifdef _MSC_VER
86 #ifdef MXNET_EXPORTS
87 #define MXNET_API __declspec(dllexport)
88 #else
89 #define MXNET_API __declspec(dllimport)
90 #endif
91 #else
92 #define MXNET_API
93 #endif
94 
98 #ifndef MXNET_PREDICT_ONLY
99 #define MXNET_PREDICT_ONLY 0
100 #endif
101 
103 #define MXNET_MAJOR 1
104 
105 #define MXNET_MINOR 4
106 
107 #define MXNET_PATCH 1
108 
109 #define MXNET_VERSION (MXNET_MAJOR*10000 + MXNET_MINOR*100 + MXNET_PATCH)
110 
111 #define MXNET_MAKE_VERSION(major, minor, patch) ((major)*10000 + (minor)*100 + patch)
112 
115 #define PROFILER_MESSAGE_FUNCNAME (__FUNCTION__)
116 
118 namespace mxnet {
126 typedef mshadow::default_real_t real_t;
130 using Op = nnvm::Op;
131 
133 struct Context {
135  enum DeviceType {
136  kCPU = cpu::kDevMask,
137  kGPU = gpu::kDevMask,
140  };
144  int32_t dev_id;
146  Context() : dev_type(kCPU), dev_id(0) {}
151  inline DeviceType dev_mask() const {
152  if (dev_type == kCPUPinned || dev_type == kCPUShared) return kCPU;
153  return dev_type;
154  }
158  inline int real_dev_id() const {
159  if (dev_type == kCPUPinned || dev_type == kGPU) return dev_id;
160  return 0;
161  }
167  inline bool operator<(const Context &b) const;
173  inline bool operator==(const Context &b) const {
174  return dev_type == b.dev_type && dev_id == b.dev_id;
175  }
181  inline bool operator!=(const Context &b) const {
182  return !(*this == b);
183  }
188  inline void Save(dmlc::Stream *strm) const {
189  strm->Write(&dev_type, sizeof(dev_type));
190  strm->Write(&dev_id, sizeof(dev_id));
191  }
197  inline bool Load(dmlc::Stream *strm) {
198  if (strm->Read(&dev_type, sizeof(dev_type)) != sizeof(dev_type)) return false;
199  if (strm->Read(&dev_id, sizeof(int32_t)) != sizeof(int32_t)) return false;
200  return true;
201  }
203  static const int32_t kMaxDevType = 6;
205  static const int32_t kMaxDevID = 16;
211  inline static Context Create(DeviceType dev_type, int32_t dev_id = -1);
213  inline static Context CPU(int32_t dev_id = 0);
219  inline static Context GPU(int32_t dev_id = -1);
224  inline static int32_t GetGPUCount();
232  inline static void GetGPUMemoryInformation(int dev, uint64_t *free, uint64_t *total);
238  inline static Context CPUPinned(int32_t dev_id = -1);
244  inline static Context CPUShared(int32_t dev_id = 0);
250  inline static Context FromString(const std::string& str);
251 };
252 
257 struct RunContext {
263  void *stream;
269  template<typename xpu>
270  inline mshadow::Stream<xpu>* get_stream() const {
271  return static_cast<mshadow::Stream<xpu>*>(stream);
272  }
274  inline const Context& get_ctx() const {
275  return ctx;
276  }
277 };
278 } // namespace mxnet
279 
281 namespace mxnet {
282 // implementing Context
283 inline bool Context::operator<(const Context &b) const {
284  if (dev_type == b.dev_type) {
285  return dev_id < b.dev_id;
286  } else {
287  return dev_type < b.dev_type;
288  }
289 }
291  Context ctx;
292  ctx.dev_type = dev_type;
293  if (dev_id < 0) {
294  ctx.dev_id = 0;
295  if (dev_type & kGPU) {
296 #if MXNET_USE_CUDA
297  CHECK_EQ(cudaGetDevice(&ctx.dev_id), cudaSuccess);
298 #else
299  LOG(FATAL) << "Please compile with CUDA enabled for cuda features";
300 #endif
301  }
302  } else {
303  ctx.dev_id = dev_id;
304  }
305  return ctx;
306 }
307 inline Context Context::CPU(int32_t dev_id) {
308  return Create(kCPU, dev_id);
309 }
310 
311 inline Context Context::CPUPinned(int32_t dev_id) {
312  return Create(kCPUPinned, dev_id);
313 }
314 
315 inline Context Context::CPUShared(int32_t dev_id) {
316  return Create(kCPUShared, dev_id);
317 }
318 
319 inline Context Context::GPU(int32_t dev_id) {
320  return Create(kGPU, dev_id);
321 }
322 
323 inline int32_t Context::GetGPUCount() {
324 #if MXNET_USE_CUDA
325  int32_t count;
326  cudaError_t e = cudaGetDeviceCount(&count);
327  if (e == cudaErrorNoDevice) {
328  return 0;
329  }
330  CHECK_EQ(e, cudaSuccess) << " CUDA: " << cudaGetErrorString(e);
331  return count;
332 #else
333  return 0;
334 #endif
335 }
336 
337 inline void Context::GetGPUMemoryInformation(int dev, uint64_t *free_mem,
338  uint64_t *total_mem) {
339 #if MXNET_USE_CUDA
340 
341  size_t memF, memT;
342  cudaError_t e;
343 
344  int curDevice;
345  e = cudaGetDevice(&curDevice);
346  CHECK_EQ(e, cudaSuccess) << " CUDA: " << cudaGetErrorString(e);
347 
348  e = cudaSetDevice(dev);
349  CHECK_EQ(e, cudaSuccess) << " CUDA: " << cudaGetErrorString(e);
350 
351  e = cudaMemGetInfo(&memF, &memT);
352  CHECK_EQ(e, cudaSuccess) << " CUDA: " << cudaGetErrorString(e);
353 
354  e = cudaSetDevice(curDevice);
355  CHECK_EQ(e, cudaSuccess) << " CUDA: " << cudaGetErrorString(e);
356 
357  *free_mem = static_cast<uint64_t>(memF);
358  *total_mem = static_cast<uint64_t>(memT);
359 
360 #else
361  LOG(FATAL)
362  << "This call is only supported for MXNet built with CUDA support.";
363 #endif
364 }
365 
366 inline Context Context::FromString(const std::string& str) {
367  Context ret;
368  try {
369  const std::string::size_type l = str.find('(');
370  CHECK_NE(l, std::string::npos);
371  const std::string::size_type r = str.find(')');
372  CHECK_EQ(r, str.length()-1);
373 
374  const std::string type = str.substr(0, l);
375  int id = std::stoi(str.substr(l+1, r-l-1));
376  if (type == "cpu") {
377  ret = CPU(id);
378  } else if (type == "gpu") {
379  ret = GPU(id);
380  } else if (type == "cpu_pinned") {
381  ret = CPUPinned(id);
382  } else if (type == "cpu_shared") {
383  ret = CPUShared(id);
384  } else {
385  LOG(FATAL) << "Invalid context string " << str;
386  }
387  } catch (...) {
388  LOG(FATAL) << "Invalid context string " << str;
389  }
390  return ret;
391 }
392 
393 inline std::ostream& operator<<(std::ostream &out, const Context &ctx) {
394  if (ctx.dev_type == Context::kCPU) {
395  out << "cpu(";
396  } else if (ctx.dev_type == Context::kGPU) {
397  out << "gpu(";
398  } else if (ctx.dev_type == Context::kCPUPinned) {
399  out << "cpu_pinned(";
400  } else if (ctx.dev_type == Context::kCPUShared) {
401  out << "cpu_shared(";
402  } else {
403  out << "unknown(";
404  }
405  out << ctx.dev_id << ")";
406  return out;
407 }
408 
409 // describe op registration point
410 #define STRINGIZE_DETAIL(x) #x
411 #define STRINGIZE(x) STRINGIZE_DETAIL(x)
412 #define MXNET_DESCRIBE(...) describe(__VA_ARGS__ "\n\nFrom:" __FILE__ ":" STRINGIZE(__LINE__))
413 #define ADD_FILELINE "\n\nDefined in " __FILE__ ":L" STRINGIZE(__LINE__)
414 
415 #if MXNET_USE_MKLDNN == 1
416 constexpr size_t kMKLDNNAlign = 64;
417 #endif
418 
419 } // namespace mxnet
420 
421 namespace std {
422 template<> struct hash<mxnet::Context> {
423  size_t operator()(const mxnet::Context& ctx) const {
424  size_t res = 0;
425  res = dmlc::HashCombine(res, static_cast<size_t>(ctx.dev_type));
426  res = dmlc::HashCombine(res, static_cast<size_t>(ctx.dev_id));
427  return res;
428  }
429 };
430 }
431 
432 #include "./tensor_blob.h"
434 #endif // MXNET_BASE_H_
DeviceType dev_mask() const
Get corresponding device mask.
Definition: base.h:151
static const int32_t kMaxDevID
the maximal device index
Definition: base.h:205
namespace of mxnet
Definition: base.h:118
static void GetGPUMemoryInformation(int dev, uint64_t *free, uint64_t *total)
get the free and total available memory on a GPU
mshadow::Stream< xpu > * get_stream() const
get mshadow stream from Context
Definition: base.h:270
static int32_t GetGPUCount()
bool Load(dmlc::Stream *strm)
load the content from binary stream
Definition: base.h:197
mshadow::default_real_t real_t
data type that will be used to store ndarray
Definition: base.h:126
static Context GPU(int32_t dev_id=-1)
nnvm::TShape TShape
Shape data structure used to record shape information.
Definition: base.h:128
Context ctx
base Context
Definition: base.h:259
bool operator<(const Context &b) const
Comparator, used to enable Context as std::map key.
static const int32_t kMaxDevType
the maximal device type
Definition: base.h:203
execution time context. The information needed in runtime for actual execution.
Definition: base.h:257
DeviceType dev_type
the device type we run the op on
Definition: base.h:142
Definition: base.h:136
int32_t dev_id
device id we are going to run it on
Definition: base.h:144
Definition: base.h:138
void * stream
the stream of the device, can be NULL or Stream<gpu>* in GPU mode
Definition: base.h:263
void Save(dmlc::Stream *strm) const
save the content into binary stream
Definition: base.h:188
mshadow::gpu gpu
mxnet gpu
Definition: base.h:122
const Context & get_ctx() const
get the base Context from RunContext
Definition: base.h:274
Definition: base.h:137
DeviceType
Type of device.
Definition: base.h:135
static Context CPUShared(int32_t dev_id=0)
mshadow::cpu cpu
mxnet cpu
Definition: base.h:120
int real_dev_id() const
Returns dev_id for kGPU and kCPUPinned, 0 otherwise.
Definition: base.h:158
nnvm::Op Op
operator structure from NNVM
Definition: base.h:130
Context()
default constructor
Definition: base.h:146
static Context Create(DeviceType dev_type, int32_t dev_id=-1)
Create a new context.
bool operator!=(const Context &b) const
check if current context not equals another one
Definition: base.h:181
static Context CPU(int32_t dev_id=0)
std::ostream & operator<<(std::ostream &out, const NDArray &ndarray)
static Context CPUPinned(int32_t dev_id=-1)
Definition: base.h:139
static Context FromString(const std::string &str)
mshadow::index_t index_t
index type usually use unsigned
Definition: base.h:124
TBlob class that holds common representation of arbirary dimension tensor, can be used to transformed...
Context information about the execution environment.
Definition: base.h:133
bool operator==(const Context &b) const
check if current context equals another one
Definition: base.h:173
unsigned index_t
Definition: base.h:37