Files
paddlepaddle--paddle/paddle/phi/backends/device_manager.h
T
2026-07-13 12:40:42 +08:00

457 lines
16 KiB
C++

// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <cstring>
#include <unordered_map>
#include <vector>
#include "paddle/phi/common/data_type.h"
#include "paddle/phi/common/place.h"
#include "paddle/phi/core/utils/rw_lock.h"
#include "paddle/phi/backends/c_comm_lib.h"
#include "paddle/phi/backends/c_cuda_graph_lib.h"
#include "paddle/phi/backends/device_base.h"
#include "paddle/phi/backends/device_ext.h"
#include "paddle/phi/backends/event.h"
#include "paddle/phi/backends/stream.h"
#include "paddle/phi/common/port.h"
struct C_CinnInterface;
namespace phi {
class PADDLE_API Device final {
public:
Device(size_t dev_id, DeviceInterface* impl) : dev_id_(dev_id), impl_(impl) {}
~Device();
void CheckInitialized();
// Stream
// ! Create an asynchronous stream
void CreateStream(
stream::Stream* stream,
const stream::Stream::Priority& priority =
stream::Stream::Priority::kNormal,
const stream::Stream::Flag& flag = stream::Stream::Flag::kDefaultFlag);
// ! Destroys an asynchronous stream.
void DestroyStream(stream::stream_t stream);
// ! Waits for stream tasks to complete.
void SynchronizeStream(stream::stream_t stream);
// ! Queries an asynchronous stream for completion status.
bool QueryStream(stream::stream_t stream);
// ! Add a callback to a compute stream.
void AddCallback(stream::Stream* stream, stream::Stream::Callback* callback);
// Event
// ! Create an event.
void CreateEvent(event::Event* event,
event::Event::Flag flags = event::Event::Flag::Default);
// ! Destroy an event.
void DestroyEvent(event::Event* event);
// ! Records an event.
void RecordEvent(const event::Event* event, const stream::Stream* stream);
// ! Waits for event to complete.
void SynchronizeEvent(const event::Event* event);
// ! Queries an event for completion status.
bool QueryEvent(const event::Event* event);
// ! Make a compute stream wait on an event
void StreamWaitEvent(const stream::Stream* stream, const event::Event* event);
// Memory
void MemoryCopyH2D(void* dst,
const void* src,
size_t size,
const stream::Stream* stream = nullptr);
void MemoryCopyD2H(void* dst,
const void* src,
size_t size,
const stream::Stream* stream = nullptr);
void MemoryCopyD2D(void* dst,
const void* src,
size_t size,
const stream::Stream* stream = nullptr);
void MemoryCopyP2P(const Place& dst_place,
void* dst,
const void* src,
size_t size,
const stream::Stream* stream = nullptr);
void* MemoryAllocate(size_t size);
void MemoryDeallocate(void* ptr, size_t size);
void* MemoryAllocateHost(size_t size);
void MemoryDeallocateHost(void* ptr, size_t size);
void* MemoryAllocateUnified(size_t size);
void MemoryDeallocateUnified(void* ptr, size_t size);
void MemorySet(void* ptr, uint8_t value, size_t size);
// Blas
// ! y = alpha * x + beta * y
template <typename T>
void BlasAXPBY(const stream::stream_t& stream,
size_t numel,
float alpha,
const T* x,
float beta,
T* y);
std::string Type();
struct C_CinnInterface* GetCinnInterface() const {
return impl_->GetCinnInterface();
}
private:
size_t dev_id_;
DeviceInterface* impl_;
std::once_flag initialized_once_flag_;
bool initialized_{false};
};
class PADDLE_API DeviceManager {
public:
static bool Register(std::unique_ptr<DeviceInterface> device);
static bool RegisterPinnedDevice(DeviceInterface* device);
static Device* GetDeviceWithPlace(const Place& place);
static std::vector<std::string> GetAllDeviceTypes();
static std::vector<std::string> GetAllCustomDeviceTypes();
static std::vector<std::string> GetAllDeviceList();
static std::vector<std::string> GetAllCustomDeviceList();
static bool HasDeviceType(const std::string& device_type);
static bool IsCustom(const std::string& device_type);
// platform & device
static void Initialize(const std::string& device_type);
static void Finalize(const std::string& device_type);
static void SynchronizeDevice(const Place& place);
static void SetDevice(const std::string& device_type, size_t device_id);
static void SetDevice(const Place& place);
static int GetDevice(const std::string& device_type);
static size_t GetMinChunkSize(const Place& place);
static size_t GetMaxChunkSize(const Place& place);
static size_t GetMaxAllocSize(const Place& place);
static size_t GetInitAllocSize(const Place& place);
static size_t GetReallocSize(const Place& place);
static size_t GetExtraPaddingSize(const Place& place);
static size_t GetComputeCapability(const Place& place);
static phi::DeviceProp& GetDeviceProperties(const std::string& device_type,
size_t device_id);
static size_t GetRuntimeVersion(const Place& place);
static size_t GetDriverVersion(const Place& place);
static size_t GetMultiProcessors(const Place& place);
static size_t GetMaxThreadsPerMultiProcessor(const Place& place);
static size_t GetMaxThreadsPerBlock(const Place& place);
static size_t GetMaxSharedMemPerBlock(const Place& place);
static size_t GetMaxBlocksPerMultiProcessor(const Place& place);
static size_t GetWarpSize(const Place& place);
static size_t GetMaxRegistersPerMultiProcessor(const Place& place);
static size_t GetPreferredVectorWidth(const Place& place);
static std::array<unsigned int, 3> GetMaxGridDimSize(const Place& place);
static std::array<unsigned int, 3> GetMaxBlockDimSize(const Place& place);
static bool IsFloat16Supported(const Place& place);
static bool IsBFloat16Supported(const Place& place);
static bool IsDnnAvailable(const Place& place);
static void* InitEigenDevice(const Place& place,
stream::stream_t stream,
phi::Allocator* allocator);
static void DestroyEigenDevice(const Place& place, void* eigen_device);
static void MemoryStats(const Place& place, size_t* total, size_t* free);
static size_t GetDeviceCount(const std::string& device_type);
static std::vector<size_t> GetDeviceList(const std::string& device_type);
static std::vector<size_t> GetSelectedDeviceList(
const std::string& device_type);
// CCL
static void CCLCommName(const std::string& device_type,
const ccl::CCLComm& ccl_comm,
char* comm_name);
static void CCLDestroyComm(const std::string& device_type,
ccl::CCLComm ccl_comm);
static void CCLCommInitRank(const std::string& device_type,
size_t num_ranks,
ccl::CCLRootId* root_id,
size_t rank_id,
ccl::CCLComm* ccl_comm);
static void CCLGetUniqueId(const std::string& device_type,
ccl::CCLRootId* root_id);
static void CCLBroadcast(const std::string& device_type,
void* data,
size_t num,
DataType data_type,
size_t root,
const ccl::CCLComm& ccl_comm,
const stream::stream_t& stream);
static void CCLAllReduce(const std::string& device_type,
void* in_data,
void* out_data,
size_t num,
DataType data_type,
ccl::CCLReduceOp reduce_op,
const ccl::CCLComm& ccl_comm,
const stream::stream_t& stream);
static void CCLReduce(const std::string& device_type,
void* in_data,
void* out_data,
size_t num,
DataType data_type,
ccl::CCLReduceOp reduce_op,
size_t root_id,
const ccl::CCLComm& ccl_comm,
const stream::stream_t& stream);
static void CCLAllGather(const std::string& device_type,
void* in_data,
void* out_data,
size_t num,
DataType data_type,
const ccl::CCLComm& ccl_comm,
const stream::stream_t& stream);
static void CCLReduceScatter(const std::string& device_type,
void* in_data,
void* out_data,
size_t num,
DataType data_type,
ccl::CCLReduceOp op,
const ccl::CCLComm& ccl_comm,
const stream::stream_t& stream);
static void CCLGroupStart(const std::string& device_type);
static void CCLGroupEnd(const std::string& device_type);
static void CCLSend(const std::string& device_type,
void* sendbuf,
size_t num,
DataType data_type,
size_t dst_rank,
const ccl::CCLComm& ccl_comm,
const stream::stream_t& stream);
static void CCLRecv(const std::string& device_type,
void* recvbuf,
size_t num,
DataType data_type,
size_t src_rank,
const ccl::CCLComm& ccl_comm,
const stream::stream_t& stream);
static void CCLAllToAll(const std::string& device_type,
const void** send_buf,
const size_t* send_count,
const DataType* send_dtype,
void** recv_buf,
const size_t* recv_count,
const DataType* recv_dtype,
size_t rank,
size_t nranks,
const ccl::CCLComm& comm,
const stream::stream_t& stream);
// profiler
static void ProfilerInitialize(const std::string& dev_type,
phi::TraceEventCollector* collector,
void** context);
static void ProfilerFinalize(const std::string& dev_type,
phi::TraceEventCollector* collector,
void* context);
static void ProfilerPrepareTracing(const std::string& dev_type,
phi::TraceEventCollector* collector,
void* context);
static void ProfilerStartTracing(const std::string& dev_type,
phi::TraceEventCollector* collector,
void* context);
static void ProfilerStopTracing(const std::string& dev_type,
phi::TraceEventCollector* collector,
void* context);
static void ProfilerCollectTraceData(const std::string& dev_type,
phi::TraceEventCollector* collector,
uint64_t start_ns,
void* context);
static void Release();
static void InitBlasHandle(const Place& place,
void** blas_handle,
stream::stream_t stream);
static void BlasSetMathMode(const Place& place,
void* blas_handle,
int math_mode);
static void InitBlasLtHandle(const Place& place, void** blaslt_handle);
static void DestroyBlasHandle(const Place& place, void* blas_handle);
static void DestroyBlasLtHandle(const Place& place, void* blaslt_handle);
static void InitDnnHandle(const Place& place,
void** dnn_handle,
stream::stream_t stream);
static void DestroyDnnHandle(const Place& place, void* dnn_handle);
// cudaGraph
static void CUDAStreamBeginCapture(const Place& place,
stream::stream_t stream,
graph::streamCaptureMode mode);
static void CudaStreamEndCapture(const Place& place,
stream::stream_t stream,
graph::CUDAGraph_t* pGraph);
static void CudaGraphLaunch(const Place& place,
graph::CUDAGraphExec_t exec,
stream::stream_t stream);
static void CudaGraphDestroy(const Place& place, graph::CUDAGraph_t Graph);
static void CudaGraphExecDestroy(const Place& place,
graph::CUDAGraphExec_t GraphExec);
static void CudaGraphInstantiate(const Place& place,
graph::CUDAGraphExec_t* pGraphExec,
graph::CUDAGraph_t* pGraph,
void** pErrorNode,
char* pLogBuffer,
size_t bufferSize);
static void CudaGraphGetNodes(const Place& place,
graph::CUDAGraph_t Graph,
graph::CUDAGraphNode_t* pNodes,
size_t* numNodes);
static void CudaGraphDebugDotPrint(const Place& place,
graph::CUDAGraph_t Graph,
const char* path,
unsigned int flags);
static void CudaStreamGetCaptureInfo(
const Place& place,
stream::stream_t stream,
graph::streamCaptureStatus* captureStatus_out,
unsigned long long* id_out = nullptr, // NOLINT
graph::CUDAGraph_t* graph_out = nullptr,
graph::CUDAGraphNode_t* dependencies_out = nullptr,
void** edgeData_out = nullptr,
size_t* numDependencies_out = nullptr);
static void GetParameterSetterForExecGraph(const Place& place,
graph::CUDAGraph_t graph,
graph::GraphHookManager* hook);
static void CudaThreadExchangeStreamCaptureMode(
const Place& place, graph::streamCaptureMode* mode);
private:
DISABLE_COPY_AND_ASSIGN(DeviceManager);
DeviceManager() {}
static DeviceManager& Instance();
static DeviceInterface* GetDeviceInterfaceWithType(
const std::string& device_type);
std::unordered_map<std::string, std::unique_ptr<DeviceInterface>>
device_impl_map_;
std::unordered_map<std::string, std::vector<std::unique_ptr<Device>>>
device_map_;
};
std::vector<std::string> ListAllLibraries(const std::string& library_dir);
#ifdef PADDLE_WITH_CUSTOM_DEVICE
class CustomDevicePassManager {
public:
explicit CustomDevicePassManager(const std::vector<std::string>& passes)
: all_passes_(passes) {}
~CustomDevicePassManager() = default;
static CustomDevicePassManager* Instance() {
std::vector<std::string> passes;
static CustomDevicePassManager manager(passes);
return &manager;
}
void SetCustomDevicePass(const std::vector<std::string>& passes) {
all_passes_ = passes;
}
const std::vector<std::string> GetCustomDevicePass() const {
return all_passes_;
}
private:
std::vector<std::string> all_passes_;
};
void LoadCustomRuntimeLib(const CustomRuntimeParams& runtime_params,
std::unique_ptr<C_DeviceInterface> device_interface,
const std::string& dso_lib_path,
void* dso_handle);
#endif
class Registrar {
public:
template <typename DeviceT>
explicit Registrar(DeviceT* device_ptr) {
DeviceManager::Register(std::unique_ptr<DeviceT>(device_ptr));
}
void Touch() {}
};
} // namespace phi