DeviceAPIManager() { std::fill(api_.begin(), api_.end(), nullptr); }
// Global static variable.
static DeviceAPIManager* Global() {
- static DeviceAPIManager inst;
- return &inst;
+ static DeviceAPIManager* inst = new DeviceAPIManager();
+ return inst;
}
// Get or initialize API.
DeviceAPI* GetAPI(int type, bool allow_missing) {
void* AllocWorkspace(TVMContext ctx, size_t size, DLDataType type_hint) final;
void FreeWorkspace(TVMContext ctx, void* data) final;
- static const std::shared_ptr<CPUDeviceAPI>& Global() {
- static std::shared_ptr<CPUDeviceAPI> inst = std::make_shared<CPUDeviceAPI>();
+ static CPUDeviceAPI* Global() {
+ // NOTE: explicitly use new to avoid exit-time destruction of global state
+ // Global state will be recycled by OS as the process exits.
+ static auto* inst = new CPUDeviceAPI();
return inst;
}
};
}
TVM_REGISTER_GLOBAL("device_api.cpu").set_body([](TVMArgs args, TVMRetValue* rv) {
- DeviceAPI* ptr = CPUDeviceAPI::Global().get();
+ DeviceAPI* ptr = CPUDeviceAPI::Global();
*rv = static_cast<void*>(ptr);
});
} // namespace runtime
CUDAThreadEntry::ThreadLocal()->pool.FreeWorkspace(ctx, data);
}
- static const std::shared_ptr<CUDADeviceAPI>& Global() {
- static std::shared_ptr<CUDADeviceAPI> inst = std::make_shared<CUDADeviceAPI>();
+ static CUDADeviceAPI* Global() {
+ // NOTE: explicitly use new to avoid exit-time destruction of global state
+ // Global state will be recycled by OS as the process exits.
+ static auto* inst = new CUDADeviceAPI();
return inst;
}
CUDAThreadEntry* CUDAThreadEntry::ThreadLocal() { return CUDAThreadStore::Get(); }
TVM_REGISTER_GLOBAL("device_api.gpu").set_body([](TVMArgs args, TVMRetValue* rv) {
- DeviceAPI* ptr = CUDADeviceAPI::Global().get();
+ DeviceAPI* ptr = CUDADeviceAPI::Global();
*rv = static_cast<void*>(ptr);
});
TVM_REGISTER_GLOBAL("device_api.cpu_pinned").set_body([](TVMArgs args, TVMRetValue* rv) {
- DeviceAPI* ptr = CUDADeviceAPI::Global().get();
+ DeviceAPI* ptr = CUDADeviceAPI::Global();
*rv = static_cast<void*>(ptr);
});
void* AllocWorkspace(TVMContext ctx, size_t nbytes, DLDataType type_hint = {}) final;
void FreeWorkspace(TVMContext ctx, void* ptr) final;
- static const std::shared_ptr<HexagonDeviceAPI>& Global() {
- static std::shared_ptr<HexagonDeviceAPI> inst = std::make_shared<HexagonDeviceAPI>();
+ static HexagonDeviceAPI* Global() {
+ // NOTE: explicitly use new to avoid destruction of global state
+ // Global state will be recycled by OS as the process exits.
+ static HexagonDeviceAPI* inst = new HexagonDeviceAPI();
return inst;
}
};
}
TVM_REGISTER_GLOBAL("device_api.hexagon").set_body([](TVMArgs args, TVMRetValue* rv) {
- DeviceAPI* ptr = HexagonDeviceAPI::Global().get();
+ DeviceAPI* ptr = HexagonDeviceAPI::Global();
*rv = ptr;
});
} // namespace runtime
void* AllocWorkspace(TVMContext ctx, size_t size, DLDataType type_hint) final;
void FreeWorkspace(TVMContext ctx, void* data) final;
// get the global workspace
- static const std::shared_ptr<MetalWorkspace>& Global();
+ static MetalWorkspace* Global();
};
/*! \brief Thread local workspace */
namespace runtime {
namespace metal {
-const std::shared_ptr<MetalWorkspace>& MetalWorkspace::Global() {
- static std::shared_ptr<MetalWorkspace> inst = std::make_shared<MetalWorkspace>();
+MetalWorkspace* MetalWorkspace::Global() {
+ // NOTE: explicitly use new to avoid exit-time destruction of global state
+ // Global state will be recycled by OS as the process exits.
+ static MetalWorkspace* inst = new MetalWorkspace();
return inst;
}
MetalThreadEntry* MetalThreadEntry::ThreadLocal() { return MetalThreadStore::Get(); }
TVM_REGISTER_GLOBAL("device_api.metal").set_body([](TVMArgs args, TVMRetValue* rv) {
- DeviceAPI* ptr = MetalWorkspace::Global().get();
+ DeviceAPI* ptr = MetalWorkspace::Global();
*rv = static_cast<void*>(ptr);
});
}
// get a from primary context in device_id
id<MTLComputePipelineState> GetPipelineState(size_t device_id, const std::string& func_name) {
- metal::MetalWorkspace* w = metal::MetalWorkspace::Global().get();
+ metal::MetalWorkspace* w = metal::MetalWorkspace::Global();
CHECK_LT(device_id, w->devices.size());
// start lock scope.
std::lock_guard<std::mutex> lock(mutex_);
void Init(MetalModuleNode* m, ObjectPtr<Object> sptr, const std::string& func_name,
size_t num_buffer_args, size_t num_pack_args,
const std::vector<std::string>& thread_axis_tags) {
- w_ = metal::MetalWorkspace::Global().get();
+ w_ = metal::MetalWorkspace::Global();
m_ = m;
sptr_ = sptr;
func_name_ = func_name;
* \brief obtain a global singleton of MicroDeviceAPI
* \return global shared pointer to MicroDeviceAPI
*/
- static const std::shared_ptr<MicroDeviceAPI>& Global() {
- static std::shared_ptr<MicroDeviceAPI> inst = std::make_shared<MicroDeviceAPI>();
+ static MicroDeviceAPI* Global() {
+ static MicroDeviceAPI* inst = new MicroDeviceAPI();
return inst;
}
// register device that can be obtained from Python frontend
TVM_REGISTER_GLOBAL("device_api.micro_dev").set_body([](TVMArgs args, TVMRetValue* rv) {
- DeviceAPI* ptr = MicroDeviceAPI::Global().get();
+ DeviceAPI* ptr = MicroDeviceAPI::Global();
*rv = static_cast<void*>(ptr);
});
} // namespace runtime
bool IsOpenCLDevice(TVMContext ctx) final;
OpenCLThreadEntry* GetThreadEntry() final;
// get the global workspace
- static const std::shared_ptr<OpenCLWorkspace>& Global();
+ static OpenCLWorkspace* Global();
};
/*! \brief Thread local workspace for AOCL */
OpenCLThreadEntry* AOCLWorkspace::GetThreadEntry() { return AOCLThreadEntry::ThreadLocal(); }
-const std::shared_ptr<OpenCLWorkspace>& AOCLWorkspace::Global() {
- static std::shared_ptr<OpenCLWorkspace> inst = std::make_shared<AOCLWorkspace>();
+OpenCLWorkspace* AOCLWorkspace::Global() {
+ static OpenCLWorkspace* inst = new AOCLWorkspace();
return inst;
}
AOCLThreadEntry* AOCLThreadEntry::ThreadLocal() { return AOCLThreadStore::Get(); }
TVM_REGISTER_GLOBAL("device_api.aocl").set_body([](TVMArgs args, TVMRetValue* rv) {
- DeviceAPI* ptr = AOCLWorkspace::Global().get();
+ DeviceAPI* ptr = AOCLWorkspace::Global();
*rv = static_cast<void*>(ptr);
});
explicit AOCLModuleNode(std::string data, std::string fmt,
std::unordered_map<std::string, FunctionInfo> fmap, std::string source)
: OpenCLModuleNode(data, fmt, fmap, source) {}
- const std::shared_ptr<cl::OpenCLWorkspace>& GetGlobalWorkspace() final;
+ cl::OpenCLWorkspace* GetGlobalWorkspace() final;
};
-const std::shared_ptr<cl::OpenCLWorkspace>& AOCLModuleNode::GetGlobalWorkspace() {
- return cl::AOCLWorkspace::Global();
-}
+cl::OpenCLWorkspace* AOCLModuleNode::GetGlobalWorkspace() { return cl::AOCLWorkspace::Global(); }
Module AOCLModuleCreate(std::string data, std::string fmt,
std::unordered_map<std::string, FunctionInfo> fmap, std::string source) {
virtual OpenCLThreadEntry* GetThreadEntry();
// get the global workspace
- static const std::shared_ptr<OpenCLWorkspace>& Global();
+ static OpenCLWorkspace* Global();
};
/*! \brief Thread local workspace */
/*! \brief workspace pool */
WorkspacePool pool;
// constructor
- OpenCLThreadEntry(DLDeviceType device_type, std::shared_ptr<DeviceAPI> device)
- : pool(device_type, device) {
+ OpenCLThreadEntry(DLDeviceType device_type, DeviceAPI* device) : pool(device_type, device) {
context.device_id = 0;
context.device_type = device_type;
}
/*!
* \brief Get the global workspace
*/
- virtual const std::shared_ptr<cl::OpenCLWorkspace>& GetGlobalWorkspace();
+ virtual cl::OpenCLWorkspace* GetGlobalWorkspace();
const char* type_key() const final { return workspace_->type_key.c_str(); }
private:
// The workspace, need to keep reference to use it in destructor.
// In case of static destruction order problem.
- std::shared_ptr<cl::OpenCLWorkspace> workspace_;
+ cl::OpenCLWorkspace* workspace_;
// the binary data
std::string data_;
// The format
OpenCLThreadEntry* OpenCLWorkspace::GetThreadEntry() { return OpenCLThreadEntry::ThreadLocal(); }
-const std::shared_ptr<OpenCLWorkspace>& OpenCLWorkspace::Global() {
- static std::shared_ptr<OpenCLWorkspace> inst = std::make_shared<OpenCLWorkspace>();
+OpenCLWorkspace* OpenCLWorkspace::Global() {
+ static OpenCLWorkspace* inst = new OpenCLWorkspace();
return inst;
}
}
TVM_REGISTER_GLOBAL("device_api.opencl").set_body([](TVMArgs args, TVMRetValue* rv) {
- DeviceAPI* ptr = OpenCLWorkspace::Global().get();
+ DeviceAPI* ptr = OpenCLWorkspace::Global();
*rv = static_cast<void*>(ptr);
});
void Init(OpenCLModuleNode* m, ObjectPtr<Object> sptr, OpenCLModuleNode::KTRefEntry entry,
std::string func_name, std::vector<size_t> arg_size,
const std::vector<std::string>& thread_axis_tags) {
- w_ = m->GetGlobalWorkspace().get();
+ w_ = m->GetGlobalWorkspace();
m_ = m;
sptr_ = sptr;
entry_ = entry;
}
}
-const std::shared_ptr<cl::OpenCLWorkspace>& OpenCLModuleNode::GetGlobalWorkspace() {
+cl::OpenCLWorkspace* OpenCLModuleNode::GetGlobalWorkspace() {
return cl::OpenCLWorkspace::Global();
}
bool IsOpenCLDevice(TVMContext ctx) final;
OpenCLThreadEntry* GetThreadEntry() final;
// get the global workspace
- static const std::shared_ptr<OpenCLWorkspace>& Global();
+ static OpenCLWorkspace* Global();
};
/*! \brief Thread local workspace for SDAccel*/
OpenCLThreadEntry* SDAccelWorkspace::GetThreadEntry() { return SDAccelThreadEntry::ThreadLocal(); }
-const std::shared_ptr<OpenCLWorkspace>& SDAccelWorkspace::Global() {
- static std::shared_ptr<OpenCLWorkspace> inst = std::make_shared<SDAccelWorkspace>();
+OpenCLWorkspace* SDAccelWorkspace::Global() {
+ static OpenCLWorkspace* inst = new SDAccelWorkspace();
return inst;
}
SDAccelThreadEntry* SDAccelThreadEntry::ThreadLocal() { return SDAccelThreadStore::Get(); }
TVM_REGISTER_GLOBAL("device_api.sdaccel").set_body([](TVMArgs args, TVMRetValue* rv) {
- DeviceAPI* ptr = SDAccelWorkspace::Global().get();
+ DeviceAPI* ptr = SDAccelWorkspace::Global();
*rv = static_cast<void*>(ptr);
});
explicit SDAccelModuleNode(std::string data, std::string fmt,
std::unordered_map<std::string, FunctionInfo> fmap, std::string source)
: OpenCLModuleNode(data, fmt, fmap, source) {}
- const std::shared_ptr<cl::OpenCLWorkspace>& GetGlobalWorkspace() final;
+ cl::OpenCLWorkspace* GetGlobalWorkspace() final;
};
-const std::shared_ptr<cl::OpenCLWorkspace>& SDAccelModuleNode::GetGlobalWorkspace() {
+cl::OpenCLWorkspace* SDAccelModuleNode::GetGlobalWorkspace() {
return cl::SDAccelWorkspace::Global();
}
ROCMThreadEntry::ThreadLocal()->pool.FreeWorkspace(ctx, data);
}
- static const std::shared_ptr<ROCMDeviceAPI>& Global() {
- static std::shared_ptr<ROCMDeviceAPI> inst = std::make_shared<ROCMDeviceAPI>();
+ static ROCMDeviceAPI* Global() {
+ static ROCMDeviceAPI* inst = new ROCMDeviceAPI();
return inst;
}
ROCMThreadEntry* ROCMThreadEntry::ThreadLocal() { return ROCMThreadStore::Get(); }
TVM_REGISTER_GLOBAL("device_api.rocm").set_body([](TVMArgs args, TVMRetValue* rv) {
- DeviceAPI* ptr = ROCMDeviceAPI::Global().get();
+ DeviceAPI* ptr = ROCMDeviceAPI::Global();
*rv = static_cast<void*>(ptr);
});
} // namespace runtime
VulkanThreadEntry::ThreadLocal()->pool->FreeWorkspace(ctx, data);
}
- static const std::shared_ptr<VulkanDeviceAPI>& Global() {
- static std::shared_ptr<VulkanDeviceAPI> inst = std::make_shared<VulkanDeviceAPI>();
+ static VulkanDeviceAPI* Global() {
+ static VulkanDeviceAPI* inst = new VulkanDeviceAPI();
return inst;
}
TVM_REGISTER_GLOBAL("runtime.module.loadbinary_vulkan").set_body_typed(VulkanModuleLoadBinary);
TVM_REGISTER_GLOBAL("device_api.vulkan").set_body([](TVMArgs args, TVMRetValue* rv) {
- DeviceAPI* ptr = VulkanDeviceAPI::Global().get();
+ DeviceAPI* ptr = VulkanDeviceAPI::Global();
*rv = static_cast<void*>(ptr);
});
std::vector<Entry> allocated_;
};
-WorkspacePool::WorkspacePool(DLDeviceType device_type, std::shared_ptr<DeviceAPI> device)
+WorkspacePool::WorkspacePool(DLDeviceType device_type, DeviceAPI* device)
: device_type_(device_type), device_(device) {}
WorkspacePool::~WorkspacePool() {
TVMContext ctx;
ctx.device_type = device_type_;
ctx.device_id = static_cast<int>(i);
- array_[i]->Release(ctx, device_.get());
+ array_[i]->Release(ctx, device_);
delete array_[i];
}
}
if (array_[ctx.device_id] == nullptr) {
array_[ctx.device_id] = new Pool();
}
- return array_[ctx.device_id]->Alloc(ctx, device_.get(), size);
+ return array_[ctx.device_id]->Alloc(ctx, device_, size);
}
void WorkspacePool::FreeWorkspace(TVMContext ctx, void* ptr) {
/*!
* \brief Create pool with specific device type and device.
* \param device_type The device type.
- * \param device The device API.
+ * \param device_api The device API.
*/
- WorkspacePool(DLDeviceType device_type, std::shared_ptr<DeviceAPI> device);
+ WorkspacePool(DLDeviceType device_type, DeviceAPI* device_api);
/*! \brief destructor */
~WorkspacePool();
/*!
/*! \brief device type this pool support */
DLDeviceType device_type_;
/*! \brief The device API */
- std::shared_ptr<DeviceAPI> device_;
+ DeviceAPI* device_;
};
} // namespace runtime
void FreeWorkspace(TVMContext ctx, void* data) final;
- static const std::shared_ptr<VTADeviceAPI>& Global() {
- static std::shared_ptr<VTADeviceAPI> inst = std::make_shared<VTADeviceAPI>();
+ static VTADeviceAPI* Global() {
+ static VTADeviceAPI* inst = new VTADeviceAPI();
return inst;
}
};
static TVM_ATTRIBUTE_UNUSED auto& __register_dev__ =
::tvm::runtime::Registry::Register("device_api.ext_dev", true)
.set_body([](TVMArgs args, TVMRetValue* rv) {
- DeviceAPI* ptr = VTADeviceAPI::Global().get();
+ DeviceAPI* ptr = VTADeviceAPI::Global();
*rv = static_cast<void*>(ptr);
});
} // namespace runtime
WebGPUThreadEntry::ThreadLocal()->pool.FreeWorkspace(ctx, data);
}
- static const std::shared_ptr<WebGPUDeviceAPI>& Global() {
- static std::shared_ptr<WebGPUDeviceAPI> inst = std::make_shared<WebGPUDeviceAPI>();
+ static WebGPUDeviceAPI* Global() {
+ static WebGPUDeviceAPI* inst = new WebGPUDeviceAPI();
return inst;
}
TVM_REGISTER_GLOBAL("runtime.module.loadbinary_vulkan").set_body_typed(WebGPUModuleLoadBinary);
TVM_REGISTER_GLOBAL("device_api.webgpu").set_body([](TVMArgs args, TVMRetValue* rv) {
- DeviceAPI* ptr = WebGPUDeviceAPI::Global().get();
+ DeviceAPI* ptr = WebGPUDeviceAPI::Global();
*rv = static_cast<void*>(ptr);
});