| 96 | // try free all |
| 97 | MGB_TRY { cn.free_device(cn.alloc_device(tot_sz)); } |
| 98 | MGB_CATCH(MemAllocError&, {}) |
| 99 | |
| 100 | // sort blobs by created time, may be helpful for reduce memory fragment |
| 101 | std::sort( |
| 102 | blob_data_arrary.begin(), blob_data_arrary.end(), |
| 103 | [](auto& lhs, auto& rhs) { return lhs.blob->m_id < rhs.blob->m_id; }); |
| 104 | |
| 105 | // allocate for each storage |
| 106 | for (auto i : blob_data_arrary) { |
| 107 | DeviceTensorStorage d_storage = DeviceTensorStorage(cn); |
| 108 | d_storage.ensure_size(i.blob->m_size); |
| 109 | d_storage.copy_from(i.h_storage, i.blob->m_size); |
| 110 | i.blob->m_storage = d_storage.raw_storage(); |
| 111 | } |
| 112 | |
| 113 | // wait copy finish before destructing host values |
| 114 | cn.sync(); |
| 115 | } |
| 116 | |
| 117 | struct BlobManagerStub : BlobManager { |
| 118 | void alloc_direct(OwnedBlob* blob, size_t size) { |
| 119 | mgb_assert(0, "prohibited after global variable destruction"); |
| 120 | }; |
| 121 | void alloc_with_defrag(OwnedBlob* blob, size_t size) { |
| 122 | mgb_assert(0, "prohibited after global variable destruction"); |
| 123 | }; |
| 124 | void register_blob(OwnedBlob* blob) { |
| 125 | mgb_assert(0, "prohibited after global variable destruction"); |
| 126 | }; |
| 127 | void unregister_blob(OwnedBlob* blob){}; |
| 128 | void defrag(const CompNode& cn) { |
| 129 | mgb_assert(0, "prohibited after global variable destruction"); |
| 130 | }; |
| 131 | void set_allocator(allocator_t allocator) { |
| 132 | mgb_assert(0, "prohibited after global variable destruction"); |
| 133 | }; |
| 134 | }; |
| 135 | |
| 136 | BlobManager* BlobManager::inst() { |
| 137 | static std::aligned_union_t<0, BlobManagerImpl, BlobManagerStub> storage; |
| 138 | |
| 139 | struct Keeper { |
| 140 | Keeper() { new (&storage) BlobManagerImpl(); } |
| 141 | ~Keeper() { |
| 142 | reinterpret_cast<BlobManager*>(&storage)->~BlobManager(); |
| 143 | new (&storage) BlobManagerStub(); |