| 273 | #endif |
| 274 | |
| 275 | std::string mgb::output_file(const std::string& fname, bool check_writable) { |
| 276 | static std::string cwd; |
| 277 | static std::mutex cwd_mtx; |
| 278 | MGB_LOCK_GUARD(cwd_mtx); |
| 279 | if (cwd.empty()) { |
| 280 | #if defined(IOS) |
| 281 | char* buf = nullptr; |
| 282 | ios_get_mgb_output_dir(&buf); |
| 283 | #else |
| 284 | auto buf = getcwd(nullptr, 0); |
| 285 | #endif |
| 286 | mgb_assert(buf); |
| 287 | cwd = buf; |
| 288 | free(buf); |
| 289 | cwd.append("/output"); |
| 290 | mgb_log("use test output dir: %s", cwd.c_str()); |
| 291 | mkdir(cwd.c_str(), 0755); |
| 292 | } |
| 293 | if (fname.empty()) |
| 294 | return cwd; |
| 295 | auto ret = cwd + "/" + fname; |
| 296 | if (check_writable) { |
| 297 | FILE* fout = fopen(ret.c_str(), "w"); |
| 298 | mgb_assert(fout, "failed to open %s: %s", ret.c_str(), strerror(errno)); |
| 299 | fclose(fout); |
| 300 | } |
| 301 | return ret; |
| 302 | } |
| 303 | |
| 304 | std::vector<CompNode> mgb::load_multiple_xpus(size_t num) { |
| 305 | auto cn0 = CompNode::load("xpu0"); |