You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

common.cpp 7.4 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /**
  2. * \file imperative/python/src/common.cpp
  3. * MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
  4. *
  5. * Copyright (c) 2014-2021 Megvii Inc. All rights reserved.
  6. *
  7. * Unless required by applicable law or agreed to in writing,
  8. * software distributed under the License is distributed on an
  9. * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. */
  11. #include "./common.h"
  12. #include <pybind11/operators.h>
  13. #include "megbrain/comp_node.h"
  14. #include "megbrain/graph.h"
  15. #include "megbrain/imperative/physical_tensor.h"
  16. #include "./numpy_dtypes.h"
  17. #include "./helper.h"
  18. namespace py = pybind11;
  19. using namespace mgb;
  20. using namespace imperative;
  21. namespace {
  22. template<typename XTensorND>
  23. auto def_TensorND(py::object parent, const char* name) {
  24. return py::class_<XTensorND>(parent, name)
  25. .def_property_readonly("shape", py::overload_cast<>(&XTensorND::shape, py::const_))
  26. .def_property_readonly("dtype", py::overload_cast<>(&XTensorND::dtype, py::const_))
  27. .def_property_readonly("comp_node", py::overload_cast<>(&XTensorND::comp_node, py::const_))
  28. .def("copy_from", &XTensorND::template copy_from<DeviceTensorStorage>)
  29. .def("copy_from", &XTensorND::template copy_from<HostTensorStorage>)
  30. .def("copy_from_fixlayout", py::overload_cast<const DeviceTensorND&>(
  31. &XTensorND::template copy_from_fixlayout<DeviceTensorStorage>))
  32. .def("copy_from_fixlayout", py::overload_cast<const HostTensorND&>(
  33. &XTensorND::template copy_from_fixlayout<HostTensorStorage>));
  34. }
  35. std::string default_device = "xpux";
  36. } // namespace
  37. void set_default_device(const std::string &device) {
  38. default_device = device;
  39. }
  40. std::string get_default_device() {
  41. return default_device;
  42. }
  43. void init_common(py::module m) {
  44. auto&& PyCompNode = py::class_<CompNode>(m, "CompNode")
  45. .def(py::init())
  46. .def(py::init(py::overload_cast<const std::string&>(&CompNode::load)))
  47. .def_property_readonly("logical_name", [](const CompNode& cn) {
  48. return cn.to_string_logical();
  49. })
  50. .def_property_readonly("get_mem_status_bytes", [](const CompNode& cn) {
  51. return cn.get_mem_status_bytes();
  52. })
  53. .def("create_event", &CompNode::create_event, py::arg("flags") = 0ul)
  54. .def("_set_default_device", &set_default_device)
  55. .def("_get_default_device", &get_default_device)
  56. .def("__str__", &CompNode::to_string_logical)
  57. .def("__repr__", [](const CompNode& cn) {
  58. return py::str("\"" + cn.to_string() + "\" from \"" + cn.to_string_logical() + "\"");
  59. })
  60. .def_static("_sync_all", &CompNode::sync_all)
  61. .def(py::self == py::self)
  62. .def_static("_get_device_count", &CompNode::get_device_count,
  63. "Get total number of specific devices on this system")
  64. .def(py::pickle(
  65. [](const CompNode& cn) {
  66. return py::str(cn.to_string_logical());
  67. },
  68. [](py::str cn) {
  69. return CompNode::load(cn);
  70. }));
  71. py::class_<CompNode::Event, std::shared_ptr<CompNode::Event>>(PyCompNode, "Event")
  72. .def("record", &CompNode::Event::record)
  73. .def("wait", &CompNode::Event::host_wait);
  74. py::implicitly_convertible<std::string, CompNode>();
  75. def_TensorND<DeviceTensorND>(m, "DeviceTensorND")
  76. .def("numpy", [](const DeviceTensorND& self) {
  77. HostTensorND hv;
  78. hv.copy_from(self).sync();
  79. return py::handle(npy::ndarray_from_tensor(hv, npy::ShareType::TRY_SHARE));
  80. });
  81. def_TensorND<HostTensorND>(m, "HostTensorND")
  82. .def(py::init([](py::array data, CompNode cn, DType dtype) {
  83. if (!cn.valid()) {
  84. throw py::type_error("device must not be None");
  85. }
  86. return npy::np2tensor(data.ptr(), npy::Meth::borrow(cn), dtype);
  87. }))
  88. .def("numpy", [](const HostTensorND& self) {
  89. return py::reinterpret_steal<py::object>(npy::ndarray_from_tensor(self, npy::ShareType::TRY_SHARE));
  90. });
  91. py::class_<cg::OperatorNodeConfig>(m, "OperatorNodeConfig")
  92. .def(py::init())
  93. .def_property("name",
  94. [](const OperatorNodeConfig& config) -> py::object {
  95. auto name = config.name();
  96. if (name.valid()) {
  97. return py::str(name.val());
  98. } else {
  99. return py::none();
  100. }
  101. },
  102. [](OperatorNodeConfig& config, std::string name){
  103. config.name(std::move(name));
  104. })
  105. .def_property("dtype",
  106. [](const OperatorNodeConfig& config) {
  107. return config.output_dtype();
  108. },
  109. [](OperatorNodeConfig& config, DType dtype) {
  110. config.output_dtype(dtype);
  111. })
  112. .def_property("comp_node_arr",
  113. [](const OperatorNodeConfig& config) -> py::tuple {
  114. auto arr = config.comp_node();
  115. std::vector<CompNode> tmp(arr.begin(), arr.end());
  116. return py::cast(tmp);
  117. },
  118. [](OperatorNodeConfig& config, std::vector<CompNode> cns) {
  119. config.comp_node_arr({cns.begin(), cns.end()});
  120. })
  121. .def_property("comp_node",
  122. [](const OperatorNodeConfig& config) {
  123. auto arr = config.comp_node();
  124. if (arr.size() != 1) {
  125. throw py::value_error("invalid number of comp_node");
  126. }
  127. return arr[0];
  128. },
  129. [](OperatorNodeConfig& config, CompNode cn) {
  130. OperatorNodeConfig::CompNodeArray arr{cn};
  131. config.comp_node_arr(arr);
  132. });
  133. py::class_<LogicalTensorDesc>(m, "TensorAttr")
  134. .def(py::init())
  135. .def(py::init([](const TensorShape& shape, const DType& dtype, const CompNode& comp_node){
  136. return LogicalTensorDesc{TensorLayout{shape, dtype}, comp_node};
  137. }))
  138. .def_property("shape",
  139. [](const LogicalTensorDesc& desc) {
  140. return static_cast<TensorShape>(desc.layout);
  141. },
  142. [](LogicalTensorDesc& desc, TensorShape shape) {
  143. })
  144. .def_property("dtype",
  145. [](const LogicalTensorDesc& desc) {
  146. return desc.layout.dtype;
  147. },
  148. [](LogicalTensorDesc& desc, DType dtype) {
  149. desc.layout.dtype = dtype;
  150. })
  151. .def_readwrite("comp_node", &LogicalTensorDesc::comp_node);
  152. py::enum_<CompNode::DeviceType>(m, "DeviceType")
  153. .value("UNSPEC", CompNode::DeviceType::UNSPEC)
  154. .value("CUDA", CompNode::DeviceType::CUDA)
  155. .value("CPU", CompNode::DeviceType::CPU)
  156. .value("CAMBRICON", CompNode::DeviceType::CAMBRICON)
  157. .value("ATLAS", CompNode::DeviceType::ATLAS)
  158. .value("MULTITHREAD", CompNode::DeviceType::MULTITHREAD)
  159. .value("MAX_DEVICE_ID", CompNode::DeviceType::MAX_DEVICE_ID);
  160. m.def("set_prealloc_config", &CompNode::set_prealloc_config,
  161. "specifies how to pre-allocate from raw dev allocator");
  162. init_npy_num_bfloat16(m);
  163. init_npy_num_intbx(m);
  164. init_dtypes(m);
  165. }

MegEngine 安装包中集成了使用 GPU 运行代码所需的 CUDA 环境,不用区分 CPU 和 GPU 版。 如果想要运行 GPU 程序,请确保机器本身配有 GPU 硬件设备并安装好驱动。 如果你想体验在云端 GPU 算力平台进行深度学习开发的感觉,欢迎访问 MegStudio 平台