| 526 | |
| 527 | using Callback = std::function<void()>; |
| 528 | void test_free_mem( |
| 529 | CompNode::Locator loc0, CompNode::Locator loc1, DevicePolicy* policy, |
| 530 | const Callback& before_run, const Callback& after_run) { |
| 531 | size_t tot, free; |
| 532 | policy->set_device(0); |
| 533 | policy->get_mem_info(free, tot); |
| 534 | |
| 535 | // exception |
| 536 | auto do_run = [loc0, loc1, policy, free]() { |
| 537 | void* tmp; |
| 538 | policy->raw_dev_malloc(&tmp, free / 3); |
| 539 | auto dev_free = [&](void* ptr) { policy->raw_dev_free(ptr); }; |
| 540 | auto cn0 = CompNode::load(loc0), cn1 = CompNode::load(loc1); |
| 541 | std::unique_ptr<void, decltype(dev_free)> tmp_owner{tmp, dev_free}; |
| 542 | auto check_free = [&](const char* msg, size_t expect) { |
| 543 | auto get = cn0.get_mem_status_bytes().second; |
| 544 | ASSERT_LE( |
| 545 | std::abs( |
| 546 | static_cast<intptr_t>(get) - static_cast<intptr_t>(expect)), |
| 547 | static_cast<intptr_t>(free) / 4) |
| 548 | << ssprintf( |
| 549 | "%s: get=%.2fMiB expect=%.2fMiB", msg, |
| 550 | get / 1024.0 / 1024, expect / 1024.0 / 1024); |
| 551 | }; |
| 552 | |
| 553 | check_free("direct get", free * 2 / 3); |
| 554 | DeviceTensorStorage tensor{cn0}; |
| 555 | tensor.ensure_size(free / 3).ptr(); |
| 556 | check_free("after dev alloc", free / 3); |
| 557 | tmp_owner.reset(); |
| 558 | check_free("after outer release", free * 2 / 3); |
| 559 | tensor = {cn0}; |
| 560 | check_free("after all release", free); |
| 561 | |
| 562 | DeviceTensorStorage tensor1{cn1}; |
| 563 | tensor.ensure_size(free / 6).ptr(); |
| 564 | tensor1.ensure_size(free / 6).ptr(); |
| 565 | check_free("multiple streams", free * 2 / 3); |
| 566 | }; |
| 567 | |
| 568 | before_run(); |
| 569 | MGB_TRY { do_run(); } |
| 570 | MGB_FINALLY(after_run();); |
| 571 | } |
| 572 |
no test coverage detected