| 86 | |
| 87 | #if MGB_CUDA && MGB_ENABLE_EXCEPTION |
| 88 | void run_graph(size_t mem_reserved) { |
| 89 | CompNode::try_coalesce_all_free_memory(); |
| 90 | CompNode::finalize(); |
| 91 | |
| 92 | auto cn = CompNode::load("gpux"); |
| 93 | cn.sync(); // wait for async init to finish |
| 94 | |
| 95 | HostTensorGenerator<> gen; |
| 96 | using TensorPtr = std::shared_ptr<Tensor>; |
| 97 | TensorPtr ptr_a[100]; |
| 98 | |
| 99 | size_t unit_size = mem_reserved / (100.5 * 4); |
| 100 | auto host_a = gen({unit_size}); |
| 101 | for (int i = 0; i < 100; ++i) { |
| 102 | ptr_a[i] = Tensor::make(*host_a); |
| 103 | } |
| 104 | |
| 105 | // free half |
| 106 | for (int i = 0; i < 100; i += 2) { |
| 107 | ptr_a[i].reset(); |
| 108 | } |
| 109 | |
| 110 | auto op = OprAttr::make("Elemwise"); |
| 111 | auto&& attr = op->cast_final_safe<OprAttr>(); |
| 112 | using Param = opr::Elemwise::Param; |
| 113 | Param param{Param::Mode::MUL}; |
| 114 | attr.param.write_pod(param); |
| 115 | |
| 116 | SmallVector<LogicalTensorDesc> output_descs; |
| 117 | auto out = OpDef::apply_on_physical_tensor( |
| 118 | *op, {ptr_a[1], ptr_a[99]}, output_descs, false) |
| 119 | .at(0); |
| 120 | |
| 121 | // value before defrag |
| 122 | HostTensorND host_out_before; |
| 123 | host_out_before.copy_from(out->dev_tensor()).sync(); |
| 124 | |
| 125 | // make defrag work |
| 126 | auto e = Tensor::make(*gen({unit_size * 10})); |
| 127 | |
| 128 | // value after defrag |
| 129 | HostTensorND host_out_after; |
| 130 | host_out_after.copy_from(out->dev_tensor()).sync(); |
| 131 | |
| 132 | // make sure defragment do not change the value |
| 133 | for (size_t i = 0; i < unit_size; ++i) { |
| 134 | ASSERT_EQ(host_out_before.ptr<float>()[i], host_out_after.ptr<float>()[i]); |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | TEST(TestImperative, Defragment) { |
| 139 | #if WIN32 |