| 225 | } |
| 226 | |
| 227 | MGBOprDesc* PlaceholderMGBOprDesc::make( |
| 228 | size_t nr_input, const char* name, const TensorShapeArray& output_shapes, |
| 229 | const SmallVector<DType>& output_dtypes, const void* data, size_t data_len) { |
| 230 | constexpr size_t align = std::max(alignof(MGBOprDesc), alignof(UserData)), |
| 231 | desc_size = ((sizeof(MGBOprDesc) - 1) / align + 1) * align; |
| 232 | std::unique_ptr<uint8_t, void (*)(void*)> ptr( |
| 233 | static_cast<uint8_t*>(malloc(desc_size + sizeof(UserData))), ::free); |
| 234 | mgb_assert(ptr); |
| 235 | auto del_ud = [](UserData* p) { p->~UserData(); }; |
| 236 | std::unique_ptr<UserData, decltype(del_ud)> ud( |
| 237 | new (ptr.get() + desc_size) UserData, del_ud); |
| 238 | ud->name = name; |
| 239 | ud->output_shapes = output_shapes; |
| 240 | ud->output_dtypes = output_dtypes; |
| 241 | ud->data.reset(new uint8_t[data_len]); |
| 242 | ud->data_len = data_len; |
| 243 | memcpy(ud->data.get(), data, data_len); |
| 244 | |
| 245 | auto desc = new (ptr.get()) MGBOprDesc; |
| 246 | mgb_init_opr_desc(desc, output_shapes.size(), PLACEHOLDER_TYPE_NAME); |
| 247 | desc->user_data = ud.release(); |
| 248 | #define s(n) desc->n = &PlaceholderMGBOprDesc::n; |
| 249 | MGB_OPR_DESC_FOREACH_MEM_FN(s); |
| 250 | if (!output_dtypes.empty()) { |
| 251 | desc->infer_dtype = &PlaceholderMGBOprDesc::infer_dtype; |
| 252 | } |
| 253 | #undef s |
| 254 | return reinterpret_cast<MGBOprDesc*>(ptr.release()); |
| 255 | } |
| 256 | |
| 257 | void PlaceholderMGBOprDesc::dump(OprDumpContext& ctx, MGBOprDesc* desc) { |
| 258 | mgb_assert( |