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.

json_loader.cpp 7.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /**
  2. * \file sdk/load-and-run/src/json_loader.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
  10. * implied.
  11. */
  12. #include "json_loader.h"
  13. using namespace mgb;
  14. template <typename T>
  15. T* JsonLoader::Value::safe_cast() {
  16. T* ptr = (T*)(this);
  17. if (nullptr == ptr) {
  18. fprintf(stderr, "cast ptr is null\n");
  19. }
  20. return ptr;
  21. }
  22. std::unique_ptr<JsonLoader::Value>& JsonLoader::Value::operator[](
  23. const std::string& key) {
  24. mgb_assert(Type::OBJECT == m_type);
  25. auto t = safe_cast<JsonLoader::ObjectValue>();
  26. return t->m_obj.at(key);
  27. }
  28. std::unique_ptr<JsonLoader::Value>& JsonLoader::Value::operator[](
  29. const size_t index) {
  30. mgb_assert(Type::ARRAY == m_type);
  31. auto t = safe_cast<JsonLoader::ArrayValue>();
  32. return t->m_obj[index];
  33. }
  34. std::map<std::string, std::unique_ptr<JsonLoader::Value>>&
  35. JsonLoader::Value::objects() {
  36. mgb_assert(Type::OBJECT == m_type);
  37. auto t = safe_cast<JsonLoader::ObjectValue>();
  38. return t->m_obj;
  39. }
  40. size_t JsonLoader::Value::len() {
  41. if (Type::ARRAY == m_type) {
  42. auto t = safe_cast<JsonLoader::ArrayValue>();
  43. return t->m_obj.size();
  44. } else if (Type::OBJECT == m_type) {
  45. auto t = safe_cast<JsonLoader::ObjectValue>();
  46. return t->m_obj.size();
  47. }
  48. return 0;
  49. }
  50. megdnn::SmallVector<std::unique_ptr<JsonLoader::Value>>&
  51. JsonLoader::Value::array() {
  52. mgb_assert(Type::ARRAY == m_type);
  53. auto t = safe_cast<JsonLoader::ArrayValue>();
  54. return t->m_obj;
  55. }
  56. double JsonLoader::Value::number() {
  57. mgb_assert(Type::NUMBER == m_type);
  58. auto t = safe_cast<JsonLoader::NumberValue>();
  59. return t->value();
  60. }
  61. std::string JsonLoader::Value::str() {
  62. if (Type::STRING == m_type) {
  63. auto t = safe_cast<StringValue>();
  64. return t->value();
  65. }
  66. return std::string();
  67. }
  68. void JsonLoader::expect(char c) {
  69. mgb_assert(c == (*m_buf));
  70. m_buf++;
  71. }
  72. void JsonLoader::skip_whitespace() {
  73. const char* p = m_buf;
  74. while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') {
  75. ++p;
  76. }
  77. m_buf = p;
  78. }
  79. std::unique_ptr<JsonLoader::Value> JsonLoader::parse_object() {
  80. expect('{');
  81. skip_whitespace();
  82. std::unique_ptr<JsonLoader::Value> ret;
  83. JsonLoader::ObjectValue* pObject = new JsonLoader::ObjectValue();
  84. if ('}' == *m_buf) {
  85. m_buf = m_buf + 1;
  86. ret.reset((JsonLoader::Value*)(pObject));
  87. return ret;
  88. }
  89. while (true) {
  90. std::unique_ptr<JsonLoader::Value> key = parse_string();
  91. if (m_state != State::OK) {
  92. return ret;
  93. }
  94. skip_whitespace();
  95. if (':' != (*m_buf)) {
  96. m_state = State::MISS_COLON;
  97. return ret;
  98. }
  99. m_buf++;
  100. skip_whitespace();
  101. std::unique_ptr<JsonLoader::Value> pVal = parse_value();
  102. if (m_state != State::OK) {
  103. return ret;
  104. }
  105. if (pObject->m_obj.find(pVal->str()) != pObject->m_obj.end()) {
  106. m_state = State::KEY_NOT_UNIQUE;
  107. return ret;
  108. }
  109. pObject->m_obj.insert(std::make_pair(key->str(), std::move(pVal)));
  110. skip_whitespace();
  111. if (',' == (*m_buf)) {
  112. m_buf++;
  113. skip_whitespace();
  114. } else if ('}' == (*m_buf)) {
  115. m_buf++;
  116. break;
  117. } else {
  118. m_state = State::MISS_BRACE;
  119. break;
  120. }
  121. }
  122. ret.reset((JsonLoader::Value*)(pObject));
  123. return ret;
  124. }
  125. std::unique_ptr<JsonLoader::Value> JsonLoader::parse_array() {
  126. expect('[');
  127. skip_whitespace();
  128. std::unique_ptr<JsonLoader::Value> ret;
  129. JsonLoader::ArrayValue* pArray = new JsonLoader::ArrayValue();
  130. if (']' == *m_buf) {
  131. m_buf = m_buf + 1;
  132. ret.reset((JsonLoader::Value*)(pArray));
  133. return ret;
  134. }
  135. while (true) {
  136. std::unique_ptr<JsonLoader::Value> pVal = parse_value();
  137. if (m_state != State::OK) {
  138. mgb_assert(0, "parse value failed during pase array");
  139. return ret;
  140. }
  141. pArray->m_obj.emplace_back(pVal.get());
  142. pVal.release();
  143. skip_whitespace();
  144. if (',' == *m_buf) {
  145. m_buf++;
  146. skip_whitespace();
  147. } else if (']' == *m_buf) {
  148. m_buf++;
  149. break;
  150. } else {
  151. m_state = State::BAD_ARRAY;
  152. return ret;
  153. }
  154. }
  155. ret.reset((JsonLoader::Value*)(pArray));
  156. return ret;
  157. }
  158. std::unique_ptr<JsonLoader::Value> JsonLoader::parse_string() {
  159. expect('\"');
  160. std::unique_ptr<JsonLoader::Value> ret;
  161. JsonLoader::StringValue* pStr = new JsonLoader::StringValue();
  162. const char* p = m_buf;
  163. while (true) {
  164. if (*p == '\"') {
  165. p++;
  166. break;
  167. } else {
  168. pStr->m_value += (*p);
  169. p++;
  170. }
  171. }
  172. m_buf = p;
  173. ret.reset((JsonLoader::Value*)(pStr));
  174. return ret;
  175. }
  176. std::unique_ptr<JsonLoader::Value> JsonLoader::parse_number() {
  177. const char* p = m_buf;
  178. auto loop_digit = [this](const char*& p) {
  179. if (not std::isdigit(*p)) {
  180. m_state = State::BAD_DIGIT;
  181. return;
  182. }
  183. while (std::isdigit(*p)) {
  184. p++;
  185. }
  186. return;
  187. };
  188. if (*p == '-')
  189. p++;
  190. if (*p == '0')
  191. p++;
  192. else {
  193. loop_digit(std::ref(p));
  194. }
  195. if (*p == '.') {
  196. p++;
  197. loop_digit(std::ref(p));
  198. }
  199. if (*p == 'e' || *p == 'E') {
  200. p++;
  201. if (*p == '+' || *p == '-')
  202. p++;
  203. loop_digit(std::ref(p));
  204. }
  205. JsonLoader::NumberValue* pNum = new JsonLoader::NumberValue();
  206. pNum->m_value = strtod(m_buf, nullptr);
  207. m_buf = p;
  208. std::unique_ptr<JsonLoader::Value> ret;
  209. ret.reset((JsonLoader::Value*)(pNum));
  210. return ret;
  211. }
  212. std::unique_ptr<JsonLoader::Value> JsonLoader::parse_value() {
  213. switch (*m_buf) {
  214. case '[':
  215. return parse_array();
  216. case '{':
  217. return parse_object();
  218. case '\"':
  219. return parse_string();
  220. case '\0':
  221. m_state = State::BAD_TYPE;
  222. break;
  223. default:
  224. return parse_number();
  225. }
  226. return nullptr;
  227. }
  228. std::unique_ptr<JsonLoader::Value> JsonLoader::load(const char* content,
  229. const size_t size) {
  230. m_buf = content;
  231. skip_whitespace();
  232. std::unique_ptr<JsonLoader::Value> value = parse_value();
  233. skip_whitespace();
  234. if (m_state != State::OK) {
  235. return nullptr;
  236. }
  237. mgb_assert(size == static_cast<size_t>(m_buf - content));
  238. return value;
  239. }
  240. std::unique_ptr<JsonLoader::Value> JsonLoader::load(const char* path) {
  241. std::unique_ptr<std::FILE, void (*)(std::FILE*)> fin(
  242. std::fopen(path, "rb"), [](std::FILE* fp) { std::fclose(fp); });
  243. mgb_assert(fin.get(), "failed to open %s: %s", path, strerror(errno));
  244. std::fseek(fin.get(), 0, SEEK_END);
  245. const size_t size = ftell(fin.get());
  246. std::fseek(fin.get(), 0, SEEK_SET);
  247. std::unique_ptr<char> buf(static_cast<char*>(malloc(size)));
  248. auto nr = std::fread(buf.get(), 1, size, fin.get());
  249. mgb_assert(nr == size);
  250. return load(buf.get(), size);
  251. }

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