Files
paddlepaddle--paddle/paddle/phi/backends/custom/custom_device.cc
T
2026-07-13 12:40:42 +08:00

1510 lines
54 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.
#include "glog/logging.h"
#include "paddle/phi/api/profiler/trace_event_collector.h"
#include "paddle/phi/backends/callback_manager.h"
#include "paddle/phi/backends/context_pool.h"
#include "paddle/phi/backends/custom/enforce_custom.h"
#include "paddle/phi/backends/device_base.h"
#include "paddle/phi/backends/device_guard.h"
#include "paddle/phi/backends/device_manager.h"
#include "paddle/phi/backends/event.h"
#include "paddle/phi/backends/stream.h"
#include "paddle/phi/common/data_type.h"
static bool operator==(const C_Device_st& d1, const C_Device_st& d2) {
return d1.id == d2.id;
}
static void ConvertEnum(const void* in, void* out) {
int value = *(const int*)in;
*reinterpret_cast<int*>(out) = value;
}
namespace phi {
inline void ConvertCToCpp(C_GraphHookManager* c_mgr,
graph::GraphHookManager* cpp_mgr) {
for (size_t i = 0; i < c_mgr->size; i++) {
auto fn_c = c_mgr->hooks[i];
void* userdata = c_mgr->user_data[i];
cpp_mgr->hooks.emplace_back(([fn_c, userdata](graph::CUDAGraphExec_t exec) {
fn_c(reinterpret_cast<C_GraphExec>(exec), userdata);
}));
}
}
#define INTERFACE_UNIMPLEMENT \
PADDLE_THROW(common::errors::Unimplemented( \
"%s is not implemented on %s device.", __func__, Type()));
#define CHECK_PTR(x) \
if (x == nullptr) { \
INTERFACE_UNIMPLEMENT; \
}
class CustomDevice : public DeviceInterface {
public:
CustomDevice(const std::string& type,
int priority,
bool is_custom,
std::unique_ptr<C_DeviceInterface> pimpl,
void* dso_handle)
: DeviceInterface(type, priority, is_custom),
pimpl_(std::move(pimpl)),
dso_handle_(dso_handle) {
Initialize();
}
~CustomDevice() override { Finalize(); }
size_t GetDeviceCount() override {
if (!device_init_flag_) {
if (pimpl_->get_device_count(&device_count_) != C_SUCCESS) {
device_count_ = 0;
} else {
device_init_flag_ = true;
}
}
return device_count_;
}
std::vector<size_t> GetDeviceList() override {
size_t count = GetDeviceCount();
std::vector<size_t> devices(count);
pimpl_->get_device_list(devices.data());
return devices;
}
C_DeviceInterface* Impl() { return pimpl_.get(); }
void SynchronizeDevice(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->synchronize_device(device));
}
void Initialize() override {
if (pimpl_->initialize && pimpl_->initialize() != C_SUCCESS) {
LOG(ERROR) << "Initialize " << Type() << " Failed\n";
exit(-1);
}
auto devices = GetDeviceList();
for (auto dev_id : devices) {
C_Device_st device;
device.id = dev_id;
devices_pool[dev_id] = device;
}
}
void Finalize() override {
bool ok = true;
if (pimpl_->finalize && pimpl_->finalize() != C_SUCCESS) {
LOG(ERROR) << "Finalize " << Type() << " Failed\n";
ok = false;
}
if (dso_handle_) {
dlclose(dso_handle_);
dso_handle_ = nullptr;
}
if (!ok) {
exit(1);
}
}
void InitDevice(size_t dev_id) override {
if (pimpl_->init_device) {
// Core set logical id, and Plugin replace it with physical id
const auto device = &devices_pool[dev_id];
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->init_device(device));
}
}
void DeInitDevice(size_t dev_id) override {
if (pimpl_->deinit_device) {
const auto device = &devices_pool[dev_id];
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->deinit_device(device));
}
}
void SetDevice(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->set_device(device));
}
int GetDevice() override {
C_Device_st device;
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->get_device(&device));
return device.id;
}
void CreateStream(size_t dev_id,
stream::Stream* stream,
const stream::Stream::Priority& priority =
stream::Stream::Priority::kNormal,
const stream::Stream::Flag& flag =
stream::Stream::Flag::kDefaultFlag) override {
const auto device = &devices_pool[dev_id];
C_Stream c_stream;
if (pimpl_->create_stream) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->create_stream(device, &c_stream));
} else {
c_stream = nullptr;
}
stream->set_stream(c_stream);
}
void DestroyStream(size_t dev_id, stream::stream_t stream) override {
if (pimpl_->destroy_stream) {
const auto device = &devices_pool[dev_id];
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->destroy_stream(device, reinterpret_cast<C_Stream>(stream)));
}
}
void SynchronizeStream(size_t dev_id, stream::stream_t stream) override {
if (pimpl_->synchronize_stream) {
const auto device = &devices_pool[dev_id];
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->synchronize_stream(
device, reinterpret_cast<C_Stream>(stream)));
}
}
bool QueryStream(size_t dev_id, stream::stream_t stream) override {
if (!pimpl_->query_stream) {
SynchronizeStream(dev_id, stream);
return true;
} else {
const auto device = &devices_pool[dev_id];
return pimpl_->query_stream(device, reinterpret_cast<C_Stream>(stream)) ==
C_SUCCESS;
}
}
void AddCallback(size_t dev_id,
stream::Stream* stream,
stream::Stream::Callback* callback) override {
if (!pimpl_->stream_add_callback) {
PADDLE_THROW(common::errors::Unavailable(
"AddCallback is not supported on %s.", Type()));
} else {
const auto device = &devices_pool[dev_id];
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->stream_add_callback(
device,
reinterpret_cast<C_Stream>(stream->raw_stream()),
[](C_Device device,
C_Stream stream,
void* user_data,
C_Status* status) {
std::unique_ptr<std::function<void()>> func(
reinterpret_cast<std::function<void()>*>(user_data));
(*func)();
},
callback));
}
}
void CreateEvent(size_t dev_id,
event::Event* event,
event::Event::Flag flags) override {
const auto device = &devices_pool[dev_id];
C_Event c_event;
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->create_event(device, &c_event));
event->set_event(c_event);
}
void DestroyEvent(size_t dev_id, event::Event* event) override {
const auto device = &devices_pool[dev_id];
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->destroy_event(
device, reinterpret_cast<C_Event>(event->raw_event())));
}
void RecordEvent(size_t dev_id,
const event::Event* event,
const stream::Stream* stream) override {
const auto device = &devices_pool[dev_id];
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->record_event(device,
reinterpret_cast<C_Stream>(stream->raw_stream()),
reinterpret_cast<C_Event>(event->raw_event())));
}
void SynchronizeEvent(size_t dev_id, const event::Event* event) override {
const auto device = &devices_pool[dev_id];
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->synchronize_event(
device, reinterpret_cast<C_Event>(event->raw_event())));
}
bool QueryEvent(size_t dev_id, const event::Event* event) override {
const auto device = &devices_pool[dev_id];
if (!pimpl_->query_event) {
SynchronizeEvent(dev_id, event);
return true;
}
if (pimpl_->query_event(device,
reinterpret_cast<C_Event>(event->raw_event())) ==
C_SUCCESS) {
return true;
}
return false;
}
void StreamWaitEvent(size_t dev_id,
const stream::Stream* stream,
const event::Event* event) override {
if (pimpl_->stream_wait_event) {
const auto device = &devices_pool[dev_id];
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->stream_wait_event(
device,
reinterpret_cast<C_Stream>(stream->raw_stream()),
reinterpret_cast<C_Event>(event->raw_event())));
}
}
void MemoryCopyH2D(size_t dev_id,
void* dst,
const void* src,
size_t size,
const stream::Stream* stream = nullptr) override {
const auto device = &devices_pool[dev_id];
auto place = CustomPlace(Type(), dev_id);
if (stream && stream->raw_stream() && pimpl_->async_memory_copy_h2d) {
C_Stream c_stream = reinterpret_cast<C_Stream>(stream->raw_stream());
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->async_memory_copy_h2d(device, c_stream, dst, src, size));
} else if (pimpl_->memory_copy_h2d) {
phi::DeviceContextPool& pool = phi::DeviceContextPool::Instance();
pool.Get(place)->Wait();
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->memory_copy_h2d(device, dst, src, size));
}
}
void MemoryCopyD2H(size_t dev_id,
void* dst,
const void* src,
size_t size,
const stream::Stream* stream = nullptr) override {
const auto device = &devices_pool[dev_id];
auto place = CustomPlace(Type(), dev_id);
if (stream && stream->raw_stream() && pimpl_->async_memory_copy_d2h) {
C_Stream c_stream = reinterpret_cast<C_Stream>(stream->raw_stream());
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->async_memory_copy_d2h(device, c_stream, dst, src, size));
} else if (pimpl_->memory_copy_d2h) {
phi::DeviceContextPool& pool = phi::DeviceContextPool::Instance();
pool.Get(place)->Wait();
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->memory_copy_d2h(device, dst, src, size));
}
}
void MemoryCopyD2D(size_t dev_id,
void* dst,
const void* src,
size_t size,
const stream::Stream* stream = nullptr) override {
const auto device = &devices_pool[dev_id];
auto place = CustomPlace(Type(), dev_id);
if (stream && stream->raw_stream() && pimpl_->async_memory_copy_d2d) {
C_Stream c_stream = reinterpret_cast<C_Stream>(stream->raw_stream());
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->async_memory_copy_d2d(device, c_stream, dst, src, size));
} else if (pimpl_->memory_copy_d2d) {
phi::DeviceContextPool& pool = phi::DeviceContextPool::Instance();
pool.Get(place)->Wait();
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->memory_copy_d2d(device, dst, src, size));
}
}
void MemoryCopyP2P(const Place& dst_place,
void* dst,
size_t src_dev_id,
const void* src,
size_t size,
const stream::Stream* stream = nullptr) override {
int dst_dev_id = PlaceToId(dst_place);
auto dst_device = &devices_pool[dst_dev_id];
auto src_device = &devices_pool[src_dev_id];
if (stream && stream->raw_stream()) {
if (!pimpl_->async_memory_copy_p2p) {
MemoryCopyP2P(dst_place, dst, src_dev_id, src, size);
} else {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->async_memory_copy_p2p(
dst_device,
src_device,
reinterpret_cast<C_Stream>(stream->raw_stream()),
dst,
src,
size));
}
} else {
if (!pimpl_->memory_copy_p2p) {
std::unique_ptr<uint8_t[]> tmp(new uint8_t[size]); // NOLINT
MemoryCopyD2H(src_dev_id, tmp.get(), src, size);
MemoryCopyH2D(dst_dev_id, dst, tmp.get(), size);
} else {
auto src_place = CustomPlace(Type(), src_dev_id);
phi::DeviceContextPool& pool = phi::DeviceContextPool::Instance();
pool.Get(src_place)->Wait();
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->memory_copy_p2p(dst_device, src_device, dst, src, size));
}
}
}
void* MemoryAllocate(size_t dev_id, size_t size) override {
void* ptr = nullptr;
const auto device = &devices_pool[dev_id];
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->device_memory_allocate(device, &ptr, size));
return ptr;
}
void MemoryDeallocate(size_t dev_id, void* ptr, size_t size) override {
const auto device = &devices_pool[dev_id];
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->device_memory_deallocate(device, ptr, size));
}
void* MemoryAllocateHost(size_t dev_id, size_t size) override {
void* ptr = nullptr;
const auto device = &devices_pool[dev_id];
if (!pimpl_->host_memory_allocate) {
PADDLE_THROW(common::errors::Unavailable(
"MemoryAllocateHost is not supported on %s.", Type()));
} else {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->host_memory_allocate(device, &ptr, size));
}
return ptr;
}
void MemoryDeallocateHost(size_t dev_id, void* ptr, size_t size) override {
const auto device = &devices_pool[dev_id];
if (!pimpl_->host_memory_deallocate) {
PADDLE_THROW(common::errors::Unavailable(
"MemoryDeallocateHost is not supported on %s.", Type()));
} else {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->host_memory_deallocate(device, ptr, size));
}
}
void* MemoryAllocateUnified(size_t dev_id, size_t size) override {
void* ptr = nullptr;
const auto device = &devices_pool[dev_id];
if (!pimpl_->unified_memory_allocate) {
PADDLE_THROW(common::errors::Unavailable(
"MemoryAllocateUnified is not supported on %s.", Type()));
} else {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->unified_memory_allocate(device, &ptr, size));
}
return ptr;
}
void MemoryDeallocateUnified(size_t dev_id, void* ptr, size_t size) override {
const auto device = &devices_pool[dev_id];
if (!pimpl_->unified_memory_deallocate) {
PADDLE_THROW(common::errors::Unavailable(
"MemoryDeallocateUnified is not supported on %s.", Type()));
} else {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->unified_memory_deallocate(device, ptr, size));
}
}
void MemorySet(size_t dev_id,
void* ptr,
uint8_t value,
size_t size) override {
const auto device = &devices_pool[dev_id];
if (pimpl_->device_memory_set) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->device_memory_set(device, ptr, value, size));
} else {
std::unique_ptr<uint8_t[]> tmp(new uint8_t[size]); // NOLINT
memset(tmp.get(), value, size);
MemoryCopyH2D(dev_id, ptr, tmp.get(), size);
}
}
void MemoryStats(size_t dev_id, size_t* total, size_t* free) override {
if (pimpl_->device_memory_stats) {
const auto device = &devices_pool[dev_id];
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->device_memory_stats(device, total, free));
size_t used = *total - *free;
VLOG(10) << Type() << " memory usage " << (used >> 20) << "M/"
<< (*total >> 20) << "M, " << (*free >> 20)
<< "M available to allocate";
} else {
*total = 0;
*free = 0;
}
}
size_t GetMinChunkSize(size_t dev_id) override {
if (pimpl_->device_min_chunk_size) {
const auto device = &devices_pool[dev_id];
size_t size = 0;
pimpl_->device_min_chunk_size(device, &size);
VLOG(10) << Type() << " min chunk size " << size << "B";
return size;
} else {
return 1;
}
}
size_t GetMaxChunkSize(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
size_t size = 0;
if (pimpl_->device_max_chunk_size) {
pimpl_->device_max_chunk_size(device, &size);
VLOG(10) << Type() << " max chunk size " << size << "B";
} else {
return DeviceInterface::GetMaxChunkSize(dev_id);
}
return size;
}
size_t GetMaxAllocSize(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
size_t size = 0;
if (pimpl_->device_max_alloc_size) {
pimpl_->device_max_alloc_size(device, &size);
VLOG(10) << Type() << " max alloc size " << (size >> 20) << "M";
} else {
return DeviceInterface::GetMaxAllocSize(dev_id);
}
return size;
}
size_t GetInitAllocSize(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
size_t size = 0;
if (pimpl_->device_init_alloc_size) {
pimpl_->device_init_alloc_size(device, &size);
VLOG(10) << Type() << " init alloc size " << (size >> 20) << "M";
} else {
return DeviceInterface::GetInitAllocSize(dev_id);
}
return size;
}
size_t GetReallocSize(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
size_t size = 0;
if (pimpl_->device_realloc_size) {
pimpl_->device_realloc_size(device, &size);
VLOG(10) << Type() << " realloc size " << (size >> 20) << "M";
} else {
return DeviceInterface::GetReallocSize(dev_id);
}
return size;
}
size_t GetExtraPaddingSize(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
size_t padding_size = 0;
if (pimpl_->device_extra_padding_size) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->device_extra_padding_size(device, &padding_size));
VLOG(10) << Type() << " extra padding size:" << padding_size;
return padding_size;
} else {
return DeviceInterface::GetExtraPaddingSize(dev_id);
}
return 0;
}
size_t GetComputeCapability(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
size_t compute_capability = 0;
if (pimpl_->get_compute_capability) {
pimpl_->get_compute_capability(device, &compute_capability);
}
VLOG(10) << Type() << " get compute capability " << compute_capability;
return compute_capability;
}
DeviceProp& GetDeviceProperties(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
static DeviceProp prop;
if (pimpl_->get_device_properties) {
pimpl_->get_device_properties(device, &prop);
}
VLOG(10) << Type() << " get device properties"
<< "DeviceProperties(name='" << prop.name
<< "', major=" << prop.deviceMajor
<< ", minor=" << prop.deviceMajor
<< ", total_memory=" << prop.totalGlobalMem / (1024 * 1024)
<< "MB, multi_processor_count=" << prop.multiProcessorCount << ")";
return prop;
}
size_t GetRuntimeVersion(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
size_t version = 0;
if (pimpl_->get_runtime_version) {
pimpl_->get_runtime_version(device, &version);
}
VLOG(10) << Type() << " get runtime version " << version;
return version;
}
size_t GetDriverVersion(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
size_t version = 0;
if (pimpl_->get_driver_version) {
pimpl_->get_driver_version(device, &version);
}
VLOG(10) << Type() << " get driver version " << version;
return version;
}
size_t GetMultiProcessors(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
size_t multi_process = 0;
if (pimpl_->get_multi_process) {
pimpl_->get_multi_process(device, &multi_process);
}
VLOG(10) << Type() << " get multiprocessors " << multi_process;
return multi_process;
}
size_t GetMaxThreadsPerMultiProcessor(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
size_t threads_per_mp = 0;
if (pimpl_->get_max_threads_per_mp) {
pimpl_->get_max_threads_per_mp(device, &threads_per_mp);
}
VLOG(10) << Type() << " get max threads per multiprocessor "
<< threads_per_mp;
return threads_per_mp;
}
size_t GetMaxThreadsPerBlock(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
size_t threads_per_block = 0;
if (pimpl_->get_max_threads_per_block) {
pimpl_->get_max_threads_per_block(device, &threads_per_block);
}
VLOG(10) << Type() << " get max threads per block " << threads_per_block;
return threads_per_block;
}
size_t GetMaxSharedMemPerBlock(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
size_t shared_mem_per_block = 0;
if (pimpl_->get_max_shared_mem_per_block) {
pimpl_->get_max_shared_mem_per_block(device, &shared_mem_per_block);
}
VLOG(10) << Type() << " get max shared mem per block "
<< shared_mem_per_block;
return shared_mem_per_block;
}
size_t GetMaxBlocksPerMultiProcessor(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
size_t blocks_per_mp = 0;
if (pimpl_->get_max_blocks_per_mp) {
pimpl_->get_max_blocks_per_mp(device, &blocks_per_mp);
}
VLOG(10) << Type() << " get blocks per multiprocessor " << blocks_per_mp;
return blocks_per_mp;
}
size_t GetWarpSize(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
size_t warp_size = 0;
if (pimpl_->get_warp_size) {
pimpl_->get_warp_size(device, &warp_size);
}
VLOG(10) << Type() << " get warp size " << warp_size;
return warp_size;
}
size_t GetMaxRegistersPerMultiProcessor(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
size_t registers_per_mp = 0;
if (pimpl_->get_max_registers_per_mp) {
pimpl_->get_max_registers_per_mp(device, &registers_per_mp);
}
VLOG(10) << Type() << " get registers per multiprocessor "
<< registers_per_mp;
return registers_per_mp;
}
size_t GetPreferredVectorWidth(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
size_t vector_width = 0;
if (pimpl_->get_vector_width) {
pimpl_->get_vector_width(device, &vector_width);
}
VLOG(10) << Type() << " get preferred vector width " << vector_width;
return vector_width;
}
std::array<unsigned int, 3> GetMaxGridDimSize(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
std::array<unsigned int, 3> grid_dim_size = {0, 0, 0};
if (pimpl_->get_max_grid_dim_size) {
pimpl_->get_max_grid_dim_size(device, &grid_dim_size);
}
VLOG(10) << Type() << " get max grid dim size [" << grid_dim_size[0] << ", "
<< grid_dim_size[1] << ", " << grid_dim_size[2] << "]";
return grid_dim_size;
}
std::array<unsigned int, 3> GetMaxBlockDimSize(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
std::array<unsigned int, 3> block_dim_size = {0, 0, 0};
if (pimpl_->get_max_block_dim_size) {
pimpl_->get_max_block_dim_size(device, &block_dim_size);
}
VLOG(10) << Type() << " get max block dim size [" << block_dim_size[0]
<< ", " << block_dim_size[1] << ", " << block_dim_size[2] << "]";
return block_dim_size;
}
bool IsFloat16Supported(size_t dev_id) {
const auto device = &devices_pool[dev_id];
bool supported = false;
if (pimpl_->is_float16_supported) {
pimpl_->is_float16_supported(device, &supported);
}
VLOG(10) << Type() << " is float16 supported: " << supported;
return supported;
}
bool IsBFloat16Supported(size_t dev_id) {
const auto device = &devices_pool[dev_id];
bool supported = false;
if (pimpl_->is_bfloat16_supported) {
pimpl_->is_bfloat16_supported(device, &supported);
}
VLOG(10) << Type() << " is bfloat16 supported: " << false;
return supported;
}
bool IsDnnAvailable(size_t dev_id) override {
const auto device = &devices_pool[dev_id];
bool supported = false;
if (pimpl_->is_dnn_supported) {
pimpl_->is_dnn_supported(device, &supported);
}
VLOG(10) << Type() << " is dnn available: " << supported;
return supported;
}
void* InitEigenDevice(const Place& place,
stream::stream_t stream,
phi::Allocator* allocator) override {
void* eigen_device = nullptr;
Place place_t = place;
if (pimpl_->init_eigen_device) {
pimpl_->init_eigen_device(reinterpret_cast<C_Place>(&place_t),
reinterpret_cast<C_EigenDevice*>(&eigen_device),
reinterpret_cast<C_Stream>(stream),
reinterpret_cast<C_Allocator>(allocator));
}
VLOG(10) << Type() << " init eigen device ";
return eigen_device;
}
void DestroyEigenDevice(size_t dev_id, void* eigen_device) override {
const auto device = &devices_pool[dev_id];
if (pimpl_->destroy_eigen_device) {
pimpl_->destroy_eigen_device(
device, reinterpret_cast<C_EigenDevice*>(&eigen_device));
}
VLOG(10) << Type() << " destroy eigen device ";
}
C_CCLReduceOp ToXCCLReduceOp(ccl::CCLReduceOp reduce_op) {
#define return_result(in, ret) \
case ccl::CCLReduceOp::in: \
return C_CCLReduceOp::ret
switch (reduce_op) {
return_result(SUM, SUM);
return_result(AVG, AVG);
return_result(MAX, MAX);
return_result(MIN, MIN);
return_result(PRODUCT, PRODUCT);
default: {
PADDLE_THROW(common::errors::Unavailable(
"ReduceOp is not supported on %s.", Type()));
}
}
#undef return_result
}
C_DataType ToCDataType(phi::DataType data_type) {
#define return_result(in, ret) \
case in: \
return C_DataType::ret
switch (data_type) {
return_result(phi::DataType::BOOL, BOOL);
return_result(phi::DataType::UINT8, UINT8);
return_result(phi::DataType::UINT16, UINT16);
return_result(phi::DataType::UINT32, UINT32);
return_result(phi::DataType::UINT64, UINT64);
return_result(phi::DataType::INT8, INT8);
return_result(phi::DataType::INT16, INT16);
return_result(phi::DataType::INT32, INT32);
return_result(phi::DataType::INT64, INT64);
return_result(phi::DataType::FLOAT16, FLOAT16);
return_result(phi::DataType::FLOAT32, FLOAT32);
return_result(phi::DataType::FLOAT64, FLOAT64);
return_result(phi::DataType::BFLOAT16, BFLOAT16);
return_result(phi::DataType::COMPLEX64, COMPLEX64);
return_result(phi::DataType::COMPLEX128, COMPLEX128);
default: {
PADDLE_THROW(common::errors::Unavailable(
"DataType is not supported on %s.", Type()));
return C_DataType::UNDEFINED;
}
}
#undef return_result
}
void CCLGetUniqueId(ccl::CCLRootId* unique_id) override {
CHECK_PTR(pimpl_->xccl_get_unique_id_size);
CHECK_PTR(pimpl_->xccl_get_unique_id);
C_CCLRootId root_id;
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->xccl_get_unique_id_size(&(root_id.sz)));
root_id.data = new uint8_t[root_id.sz];
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->xccl_get_unique_id(&root_id));
uint8_t* ptr = reinterpret_cast<uint8_t*>(root_id.data);
*unique_id = std::vector<uint8_t>(ptr, ptr + root_id.sz);
delete[] ptr;
}
void CCLCommInitRank(size_t nranks,
ccl::CCLRootId* unique_id,
size_t rank,
ccl::CCLComm* comm) override {
CHECK_PTR(pimpl_->xccl_comm_init_rank);
C_CCLRootId root_id;
root_id.sz = unique_id->size();
root_id.data = unique_id->data();
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->xccl_comm_init_rank(
nranks, &root_id, rank, reinterpret_cast<C_CCLComm*>(comm)));
}
void CCLDestroyComm(ccl::CCLComm comm) override {
CHECK_PTR(pimpl_->xccl_destroy_comm);
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->xccl_destroy_comm(reinterpret_cast<C_CCLComm>(comm)));
}
void CCLCommName(ccl::CCLComm comm, char* comm_name) {
CHECK_PTR(pimpl_->xccl_get_comm_name);
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->xccl_get_comm_name(
reinterpret_cast<C_CCLComm>(comm), comm_name));
}
void CCLAllReduce(void* send_buf,
void* recv_buf,
size_t count,
phi::DataType data_type,
ccl::CCLReduceOp op,
const ccl::CCLComm& comm,
const stream::stream_t& stream) override {
CHECK_PTR(pimpl_->xccl_all_reduce);
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->xccl_all_reduce(send_buf,
recv_buf,
count,
ToCDataType(data_type),
ToXCCLReduceOp(op),
reinterpret_cast<C_CCLComm>(comm),
reinterpret_cast<C_Stream>(stream)));
}
void CCLBroadcast(void* buf,
size_t count,
phi::DataType data_type,
size_t root,
const ccl::CCLComm& comm,
const stream::stream_t& stream) override {
CHECK_PTR(pimpl_->xccl_broadcast);
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->xccl_broadcast(buf,
count,
ToCDataType(data_type),
root,
reinterpret_cast<C_CCLComm>(comm),
reinterpret_cast<C_Stream>(stream)));
}
void CCLReduce(void* in_data,
void* out_data,
size_t num,
phi::DataType data_type,
ccl::CCLReduceOp reduce_op,
size_t root_id,
const ccl::CCLComm& comm,
const stream::stream_t& stream) override {
CHECK_PTR(pimpl_->xccl_reduce);
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->xccl_reduce(in_data,
out_data,
num,
ToCDataType(data_type),
ToXCCLReduceOp(reduce_op),
root_id,
reinterpret_cast<C_CCLComm>(comm),
reinterpret_cast<C_Stream>(stream)));
}
void CCLAllGather(void* send_buf,
void* recv_buf,
size_t count,
phi::DataType data_type,
const ccl::CCLComm& comm,
const stream::stream_t& stream) override {
CHECK_PTR(pimpl_->xccl_all_gather);
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->xccl_all_gather(send_buf,
recv_buf,
count,
ToCDataType(data_type),
reinterpret_cast<C_CCLComm>(comm),
reinterpret_cast<C_Stream>(stream)));
}
void CCLReduceScatter(void* send_buf,
void* recv_buf,
size_t count,
phi::DataType data_type,
ccl::CCLReduceOp reduce_op,
const ccl::CCLComm& comm,
const stream::stream_t& stream) override {
CHECK_PTR(pimpl_->xccl_reduce_scatter);
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->xccl_reduce_scatter(send_buf,
recv_buf,
count,
ToCDataType(data_type),
ToXCCLReduceOp(reduce_op),
reinterpret_cast<C_CCLComm>(comm),
reinterpret_cast<C_Stream>(stream)));
}
void CCLGroupStart() override {
if (pimpl_->xccl_group_start) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->xccl_group_start());
}
}
void CCLGroupEnd() override {
if (pimpl_->xccl_group_end) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->xccl_group_end());
}
}
void CCLSend(void* send_buf,
size_t count,
phi::DataType data_type,
size_t dest_rank,
const ccl::CCLComm& comm,
const stream::stream_t& stream) override {
CHECK_PTR(pimpl_->xccl_send);
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->xccl_send(send_buf,
count,
ToCDataType(data_type),
dest_rank,
reinterpret_cast<C_CCLComm>(comm),
reinterpret_cast<C_Stream>(stream)));
}
void CCLRecv(void* recv_buf,
size_t count,
phi::DataType data_type,
size_t src_rank,
const ccl::CCLComm& comm,
const stream::stream_t& stream) override {
CHECK_PTR(pimpl_->xccl_recv);
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->xccl_recv(recv_buf,
count,
ToCDataType(data_type),
src_rank,
reinterpret_cast<C_CCLComm>(comm),
reinterpret_cast<C_Stream>(stream)));
}
void CCLAllToAll(const void** send_buf,
const size_t* send_count,
const phi::DataType* send_dtype,
void** recv_buf,
const size_t* recv_count,
const phi::DataType* recv_dtype,
size_t rank,
size_t nranks,
const ccl::CCLComm& comm,
const stream::stream_t& stream) override {
if (pimpl_->xccl_all_to_all) {
std::vector<C_DataType> c_send_dtype, c_recv_dtype;
for (size_t i = 0; i < nranks; ++i) {
c_send_dtype.push_back(ToCDataType(send_dtype[i]));
c_recv_dtype.push_back(ToCDataType(recv_dtype[i]));
}
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->xccl_all_to_all(send_buf,
send_count,
c_send_dtype.data(),
recv_buf,
recv_count,
c_recv_dtype.data(),
rank,
nranks,
reinterpret_cast<C_CCLComm>(comm),
reinterpret_cast<C_Stream>(stream)));
} else if (pimpl_->xccl_send && pimpl_->xccl_recv) {
// NOTE(wangran16): fallback to send and recv, while avoiding some devices
// not supporting asynchronous send and recv.
for (size_t i = 0; i < rank; ++i) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->xccl_recv(recv_buf[i],
recv_count[i],
ToCDataType(recv_dtype[i]),
i,
reinterpret_cast<C_CCLComm>(comm),
reinterpret_cast<C_Stream>(stream)));
}
for (size_t i = 0; i < nranks; ++i) {
if (i != rank) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->xccl_send(const_cast<void*>(send_buf[i]),
send_count[i],
ToCDataType(send_dtype[i]),
i,
reinterpret_cast<C_CCLComm>(comm),
reinterpret_cast<C_Stream>(stream)));
}
}
const stream::Stream stream_wrapper(Place(AllocationType::CUSTOM, Type()),
stream);
int current_device_id = GetDevice();
MemoryCopyD2D(current_device_id,
recv_buf[rank],
send_buf[rank],
send_count[rank] * phi::SizeOf(send_dtype[rank]),
&stream_wrapper);
for (size_t i = rank + 1; i < nranks; ++i) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->xccl_recv(recv_buf[i],
recv_count[i],
ToCDataType(recv_dtype[i]),
i,
reinterpret_cast<C_CCLComm>(comm),
reinterpret_cast<C_Stream>(stream)));
}
} else {
PADDLE_THROW(common::errors::Unavailable(
"CCLAllToAll is not supported on %s.", Type()));
}
}
void BlasAXPBY(size_t dev_id,
const stream::stream_t& stream,
phi::DataType dtype,
size_t numel,
float alpha,
void* x,
float beta,
void* y) override {
CHECK_PTR(pimpl_->blas_axpby);
const auto device = &devices_pool[dev_id];
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->blas_axpby(device,
reinterpret_cast<C_Stream>(stream),
ToCDataType(dtype),
numel,
alpha,
x,
beta,
y));
}
// Profiler
void ProfilerInitialize(phi::TraceEventCollector* collector,
void** user_data) override {
CHECK_PTR(pimpl_->profiler_initialize);
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->profiler_initialize(
reinterpret_cast<C_Profiler>(collector), user_data));
}
void ProfilerFinalize(phi::TraceEventCollector* collector,
void* user_data) override {
CHECK_PTR(pimpl_->profiler_finalize);
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->profiler_finalize(
reinterpret_cast<C_Profiler>(collector), user_data));
}
void ProfilerPrepareTracing(phi::TraceEventCollector* collector,
void* user_data) override {
CHECK_PTR(pimpl_->profiler_prepare_tracing);
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->profiler_prepare_tracing(
reinterpret_cast<C_Profiler>(collector), user_data));
}
void ProfilerStartTracing(phi::TraceEventCollector* collector,
void* user_data) override {
CHECK_PTR(pimpl_->profiler_start_tracing);
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->profiler_start_tracing(
reinterpret_cast<C_Profiler>(collector), user_data));
}
void ProfilerStopTracing(phi::TraceEventCollector* collector,
void* user_data) override {
CHECK_PTR(pimpl_->profiler_stop_tracing);
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->profiler_stop_tracing(
reinterpret_cast<C_Profiler>(collector), user_data));
}
void ProfilerCollectTraceData(phi::TraceEventCollector* collector,
uint64_t start_ns,
void* user_data) override {
CHECK_PTR(pimpl_->profiler_collect_trace_data);
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->profiler_collect_trace_data(
reinterpret_cast<C_Profiler>(collector), start_ns, user_data));
}
void InitBlasHandle(size_t dev_id,
void** blas_handle,
stream::stream_t stream) override {
const auto device = &devices_pool[dev_id];
if (pimpl_->init_blas_handle) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->init_blas_handle(device,
reinterpret_cast<C_BLASHandle*>(blas_handle),
reinterpret_cast<C_Stream>(stream)));
}
}
void BlasSetMathMode(size_t dev_id,
void* blas_handle,
int math_mode) override {
const auto device = &devices_pool[dev_id];
if (pimpl_->blas_set_math_mode) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->blas_set_math_mode(
device, reinterpret_cast<C_BLASHandle>(blas_handle), math_mode));
}
}
void InitBlasLtHandle(size_t dev_id, void** blaslt_handle) override {
const auto device = &devices_pool[dev_id];
if (pimpl_->init_blaslt_handle) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->init_blaslt_handle(
device, reinterpret_cast<C_BLASLtHandle*>(blaslt_handle)));
}
}
void DestroyBlasHandle(size_t dev_id, void* blas_handle) override {
const auto device = &devices_pool[dev_id];
if (pimpl_->destroy_blas_handle) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->destroy_blas_handle(
device, reinterpret_cast<C_BLASHandle>(blas_handle)));
}
}
void DestroyBlasLtHandle(size_t dev_id, void* blaslt_handle) override {
const auto device = &devices_pool[dev_id];
if (pimpl_->destroy_blaslt_handle) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->destroy_blaslt_handle(
device, reinterpret_cast<C_BLASLtHandle>(blaslt_handle)));
}
}
void InitDnnHandle(size_t dev_id,
void** dnn_handle,
phi::stream::stream_t stream) override {
const auto device = &devices_pool[dev_id];
if (pimpl_->init_dnn_handle) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->init_dnn_handle(device,
reinterpret_cast<C_DNNHandle*>(dnn_handle),
reinterpret_cast<C_Stream>(stream)));
}
}
void DestroyDnnHandle(size_t dev_id, void* dnn_handle) override {
const auto device = &devices_pool[dev_id];
if (pimpl_->destroy_dnn_handle) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->destroy_dnn_handle(
device, reinterpret_cast<C_DNNHandle>(dnn_handle)));
}
}
void CUDAStreamBeginCapture(size_t dev_id,
stream::stream_t stream,
graph::streamCaptureMode mode) {
const auto device = &devices_pool[dev_id];
if (pimpl_->cuda_stream_begin_capture) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->cuda_stream_begin_capture(
device,
reinterpret_cast<C_Stream>(stream),
static_cast<C_StreamCaptureMode>(mode)));
}
}
void CudaStreamEndCapture(size_t dev_id,
stream::stream_t stream,
graph::CUDAGraph_t* pGraph) {
const auto device = &devices_pool[dev_id];
if (pimpl_->cuda_stream_end_captrue) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->cuda_stream_end_captrue(
device,
reinterpret_cast<C_Stream>(stream),
reinterpret_cast<C_CudaGraph*>(pGraph)));
}
}
void CudaGraphLaunch(size_t dev_id,
graph::CUDAGraphExec_t exec,
stream::stream_t stream) {
const auto device = &devices_pool[dev_id];
if (pimpl_->cuda_graph_launch) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->cuda_graph_launch(device,
reinterpret_cast<C_GraphExec>(exec),
reinterpret_cast<C_Stream>(stream)));
}
}
void CudaGraphDestroy(graph::CUDAGraph_t graph) {
if (pimpl_->cuda_graph_destroy) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->cuda_graph_destroy(reinterpret_cast<C_CudaGraph>(graph)));
}
}
void CudaGraphExecDestroy(graph::CUDAGraphExec_t graphExec) {
if (pimpl_->cuda_graph_exec_destroy) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->cuda_graph_exec_destroy(
reinterpret_cast<C_GraphExec>(graphExec)));
}
}
void CudaGraphInstantiate(graph::CUDAGraphExec_t* pGraphExec,
graph::CUDAGraph_t* pGraph,
void** pErrorNode,
char* pLogBuffer,
size_t bufferSize) {
if (pimpl_->cuda_graph_instantiate) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->cuda_graph_instantiate(
reinterpret_cast<C_GraphExec*>(pGraphExec),
reinterpret_cast<C_CudaGraph*>(pGraph),
pErrorNode,
pLogBuffer,
bufferSize));
}
}
void CudaGraphGetNodes(graph::CUDAGraph_t graph,
graph::CUDAGraphNode_t* pNodes,
size_t* numNodes) {
if (pimpl_->cuda_graph_get_nodes) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->cuda_graph_get_nodes(
reinterpret_cast<C_CudaGraph>(graph),
reinterpret_cast<C_CudaGraphNode*>(pNodes),
numNodes));
}
}
void CudaStreamGetCaptureInfo(
size_t dev_id,
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) {
const auto device = &devices_pool[dev_id];
if (pimpl_->cuda_graph_get_nodes) {
C_StreamCaptureStatus c_status = C_StreamCaptureStatusNone;
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->cuda_stream_capture_info(
device,
reinterpret_cast<C_Stream>(stream),
&c_status,
id_out,
reinterpret_cast<C_CudaGraph*>(graph_out),
reinterpret_cast<C_CudaGraphNode*>(dependencies_out),
edgeData_out,
numDependencies_out));
ConvertEnum(&c_status, captureStatus_out);
}
}
void GetParameterSetterForExecGraph(graph::CUDAGraph_t graph,
graph::GraphHookManager* hook) {
if (pimpl_->get_parameter_setter_for_exec_graph) {
C_GraphHookManager c_hook;
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->get_parameter_setter_for_exec_graph(
reinterpret_cast<C_CudaGraph>(graph), &c_hook));
ConvertCToCpp(&c_hook, hook);
}
}
void CudaGraphDebugDotPrint(graph::CUDAGraph_t graph,
const char* path,
unsigned int flags) {
if (pimpl_->cuda_graph_debug_dot_print) {
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(pimpl_->cuda_graph_debug_dot_print(
reinterpret_cast<C_CudaGraph>(graph), path, flags));
}
}
void CudaThreadExchangeStreamCaptureMode(graph::streamCaptureMode* mode) {
if (pimpl_->cuda_thread_exchange_stream_capthure_mode) {
C_StreamCaptureMode c_mode = C_StreamCaptureModeGlobal;
ConvertEnum(mode, &c_mode);
PADDLE_ENFORCE_CUSTOM_DEVICE_SUCCESS(
pimpl_->cuda_thread_exchange_stream_capthure_mode(&c_mode));
ConvertEnum(&c_mode, mode);
}
}
// Returns the CINN plugin interface registered by the vendor for this device.
C_CinnInterface* GetCinnInterface() override {
return pimpl_->cinn_interface;
}
private:
inline int PlaceToIdNoCheck(const Place& place) {
int dev_id = place.GetDeviceId(); // NOLINT
return dev_id;
}
inline int PlaceToId(const Place& place) {
int dev_id = PlaceToIdNoCheck(place);
PADDLE_ENFORCE_NE(devices_pool.find(dev_id),
devices_pool.end(),
common::errors::NotFound(
"Cannot found %s %d, please check visible devices",
Type(),
dev_id));
return dev_id;
}
std::unique_ptr<C_DeviceInterface> pimpl_;
void* dso_handle_;
std::unordered_map<size_t, C_Device_st> devices_pool;
bool device_init_flag_ = false;
size_t device_count_;
};
bool ValidCustomCustomRuntimeParams(const CustomRuntimeParams* params) {
#define CHECK_INTERFACE(ptr, required) \
if (params->interface->ptr == nullptr && required) { \
LOG(WARNING) << "CustomRuntime [type: " << params->device_type \
<< "] pointer: " << #ptr << " is not set."; \
return false; \
}
int version = params->version.major * 10000 + params->version.minor * 100 +
params->version.patch;
const int runtime_version = PADDLE_CUSTOM_RUNTIME_MAJOR_VERSION * 10000 +
PADDLE_CUSTOM_RUNTIME_MINOR_VERSION * 100 +
PADDLE_CUSTOM_RUNTIME_PATCH_VERSION;
if (version < runtime_version) {
LOG(WARNING) << "CustomRuntime [type: " << params->device_type
<< "] version: " << version
<< " < PADDLE_CUSTOM_RUNTIME_VERSION " << runtime_version;
return false;
}
CHECK_INTERFACE(initialize, false);
CHECK_INTERFACE(finalize, false)
CHECK_INTERFACE(init_device, false);
CHECK_INTERFACE(set_device, true);
CHECK_INTERFACE(get_device, true);
CHECK_INTERFACE(deinit_device, false);
CHECK_INTERFACE(create_stream, false);
CHECK_INTERFACE(destroy_stream, false);
CHECK_INTERFACE(query_stream, false);
CHECK_INTERFACE(stream_add_callback, false);
CHECK_INTERFACE(create_event, true);
CHECK_INTERFACE(record_event, true);
CHECK_INTERFACE(destroy_event, true);
CHECK_INTERFACE(query_event, false);
CHECK_INTERFACE(synchronize_device, false);
CHECK_INTERFACE(synchronize_stream, false);
CHECK_INTERFACE(synchronize_event, true);
CHECK_INTERFACE(stream_wait_event, false);
CHECK_INTERFACE(device_memory_allocate, true);
CHECK_INTERFACE(device_memory_deallocate, true);
CHECK_INTERFACE(host_memory_allocate, false);
CHECK_INTERFACE(host_memory_deallocate, false);
CHECK_INTERFACE(unified_memory_allocate, false);
CHECK_INTERFACE(unified_memory_deallocate, false);
CHECK_INTERFACE(memory_copy_h2d, false);
CHECK_INTERFACE(memory_copy_d2h, false);
CHECK_INTERFACE(memory_copy_d2d, false);
CHECK_INTERFACE(memory_copy_p2p, false);
CHECK_INTERFACE(async_memory_copy_h2d, false);
CHECK_INTERFACE(async_memory_copy_d2h, false);
CHECK_INTERFACE(async_memory_copy_d2d, false);
CHECK_INTERFACE(async_memory_copy_p2p, false);
CHECK_INTERFACE(get_device_count, true);
CHECK_INTERFACE(get_device_list, true);
CHECK_INTERFACE(device_memory_stats, false);
CHECK_INTERFACE(device_min_chunk_size, false);
CHECK_INTERFACE(device_max_chunk_size, false);
CHECK_INTERFACE(device_max_alloc_size, false);
CHECK_INTERFACE(device_extra_padding_size, false);
CHECK_INTERFACE(get_compute_capability, false);
CHECK_INTERFACE(get_runtime_version, false);
CHECK_INTERFACE(get_driver_version, false);
CHECK_INTERFACE(get_multi_process, false);
CHECK_INTERFACE(get_max_threads_per_mp, false);
CHECK_INTERFACE(get_max_threads_per_block, false);
CHECK_INTERFACE(get_max_shared_mem_per_block, false);
CHECK_INTERFACE(get_max_blocks_per_mp, false);
CHECK_INTERFACE(get_warp_size, false);
CHECK_INTERFACE(get_max_registers_per_mp, false);
CHECK_INTERFACE(get_vector_width, false);
CHECK_INTERFACE(get_max_grid_dim_size, false);
CHECK_INTERFACE(get_max_block_dim_size, false);
CHECK_INTERFACE(init_eigen_device, false);
CHECK_INTERFACE(destroy_eigen_device, false);
CHECK_INTERFACE(xccl_get_unique_id, false);
CHECK_INTERFACE(xccl_get_unique_id_size, false);
CHECK_INTERFACE(xccl_comm_init_rank, false);
CHECK_INTERFACE(xccl_destroy_comm, false);
CHECK_INTERFACE(xccl_all_reduce, false);
CHECK_INTERFACE(xccl_broadcast, false);
CHECK_INTERFACE(xccl_reduce, false);
CHECK_INTERFACE(xccl_all_gather, false);
CHECK_INTERFACE(xccl_reduce_scatter, false);
CHECK_INTERFACE(xccl_group_start, false);
CHECK_INTERFACE(xccl_group_end, false);
CHECK_INTERFACE(xccl_send, false);
CHECK_INTERFACE(xccl_recv, false);
CHECK_INTERFACE(blas_axpby, false);
CHECK_INTERFACE(profiler_initialize, false);
CHECK_INTERFACE(profiler_finalize, false);
CHECK_INTERFACE(profiler_prepare_tracing, false);
CHECK_INTERFACE(profiler_start_tracing, false);
CHECK_INTERFACE(profiler_stop_tracing, false);
CHECK_INTERFACE(profiler_collect_trace_data, false);
CHECK_INTERFACE(init_blas_handle, false);
CHECK_INTERFACE(destroy_blas_handle, false);
CHECK_INTERFACE(blas_set_math_mode, false);
CHECK_INTERFACE(init_blaslt_handle, false);
CHECK_INTERFACE(destroy_blaslt_handle, false);
CHECK_INTERFACE(init_dnn_handle, false);
CHECK_INTERFACE(destroy_dnn_handle, false);
CHECK_INTERFACE(cuda_stream_begin_capture, false);
CHECK_INTERFACE(cuda_stream_end_captrue, false);
CHECK_INTERFACE(cuda_graph_launch, false);
CHECK_INTERFACE(cuda_graph_destroy, false);
CHECK_INTERFACE(cuda_graph_exec_destroy, false);
CHECK_INTERFACE(cuda_graph_instantiate, false);
CHECK_INTERFACE(cuda_graph_get_nodes, false);
CHECK_INTERFACE(cuda_stream_capture_info, false);
CHECK_INTERFACE(get_parameter_setter_for_exec_graph, false);
CHECK_INTERFACE(cuda_graph_debug_dot_print, false);
CHECK_INTERFACE(cuda_thread_exchange_stream_capthure_mode, false);
return true;
#undef CHECK_INTERFACE
}
void LoadCustomRuntimeLib(const CustomRuntimeParams& runtime_params,
std::unique_ptr<C_DeviceInterface> device_interface,
const std::string& dso_lib_path,
void* dso_handle) {
if (ValidCustomCustomRuntimeParams(&runtime_params)) {
auto device = std::make_unique<CustomDevice>(runtime_params.device_type,
255,
true,
std::move(device_interface),
dso_handle);
if (false == DeviceManager::Register(std::move(device))) {
LOG(WARNING) << "Skipped lib [" << dso_lib_path
<< "]. Register failed!!! there may be a "
"Custom Runtime with the same name.";
}
if (runtime_params.pir_default_passes != nullptr) {
CustomDevicePassManager::Instance()->SetCustomDevicePass(
*(reinterpret_cast<std::vector<std::string>*>(
runtime_params.pir_default_passes)));
}
} else {
LOG(WARNING) << "Skipped lib [" << dso_lib_path
<< "]. Wrong Runtime parameters!!! please check the version "
"compatibility between PaddlePaddle and Custom Runtime.";
}
}
#undef INTERFACE_UNIMPLEMENT
} // namespace phi