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

773 lines
24 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 "paddle/phi/backends/xpu/xpu_context.h"
#include "paddle/phi/backends/context_pool.h"
#ifdef PADDLE_WITH_XPU
#include <cuda.h>
#include <cuda_runtime.h>
#include "paddle/phi/core/xpu_cuda_stream.h"
#endif
#include <memory>
#include "glog/logging.h"
#include "paddle/common/exception.h"
#include "paddle/phi/backends/xpu/enforce_xpu.h"
#include "paddle/phi/common/memory_utils.h"
#include "paddle/phi/common/place.h"
#include "paddle/phi/core/allocator.h"
#include "paddle/phi/core/dense_tensor.h"
#include "paddle/phi/core/os_info.h"
#include "xpu/runtime.h"
#include "xpu/runtime_ex.h"
#include "xpu/xdnn.h"
#if !defined(PADDLE_WITH_XPU_KP) || defined(__xpu_on_host__)
#include "unsupported/Eigen/CXX11/Tensor"
#endif
namespace xpu = baidu::xpu::api;
namespace phi {
struct XPUContext::Impl {
void SetL3Cache(int64_t l3_size = 1024) {
PADDLE_ENFORCE_XPU_SUCCESS(xpu_wait(context_->xpu_stream));
context_->_l3_mgr.set(nullptr, 0, true); // free origin l3
void* l3_ptr = nullptr;
xpu_malloc(static_cast<void**>(&l3_ptr), l3_size, XPU_MEM_L3);
if (l3_ptr != nullptr) {
VLOG(3) << "xpu place " << static_cast<int>(place_.GetDeviceId())
<< "context " << context_ << " set l3 size " << l3_size;
context_->_l3_mgr.set(l3_ptr, l3_size, true);
}
}
Impl() : place_(XPUPlace()) {}
explicit Impl(const Place& place) : place_(place) {}
~Impl() {
for (auto& ctx_it : context_map_) {
auto& ctx = ctx_it.second;
if (ctx != nullptr) {
xpu_wait(ctx->xpu_stream);
if (ctx->xpu_stream) {
xpu_stream_destroy(ctx->xpu_stream);
ctx->xpu_stream = nullptr;
}
ctx = nullptr;
}
}
context_map_.clear();
if (owned_ && context_ != nullptr) {
backends::xpu::XPUDeviceGuard guard(place_.GetDeviceId());
xpu_wait(context_->xpu_stream);
if (context_->xpu_stream && stream_owned_) {
// manually destroy XPUStream here until xpu::api integrates this work
// into Context dtor
xpu_stream_destroy(context_->xpu_stream);
context_->xpu_stream = nullptr;
}
xpu::destroy_context(context_);
context_ = nullptr;
}
}
const Place& GetPlace() const { return place_; }
XPUStream stream() const {
xpu::Context* ctx_t = GetXdlCtx();
if (ctx_t) {
return ctx_t->xpu_stream;
}
return context_->xpu_stream;
}
// Set external stream for context
void SetStream(void* stream, bool clear = true) {
if (clear && context_->xpu_stream != nullptr && stream_owned_) {
xpu_stream_destroy(context_->xpu_stream);
}
stream_owned_ = false;
context_->set_stream(static_cast<XPUStream>(stream));
}
xpu::Context* GetXContext() const {
PD_CHECK(context_ != nullptr, "the xpu context is nullptr.");
return context_;
}
xpu::BKCLContext_t GetBkclContext() const {
PD_CHECK(bkcl_context_ != nullptr, "the xpu bkcl_context is nullptr.");
return bkcl_context_;
}
// Overload GetXContext function to set and get
// contexts of XPU Dataloader threads, and keep old GetXContext Method
xpu::Context* GetXContext() {
SetXdlCtx();
xpu::Context* ctx_t = GetXdlCtx();
if (ctx_t) {
PD_CHECK(ctx_t != nullptr, "the xpu context is nullptr.");
return ctx_t;
}
PD_CHECK(context_ != nullptr, "the xpu context is nullptr.");
return context_;
}
void Wait() {
backends::xpu::XPUDeviceGuard guard(place_.GetDeviceId());
PD_CHECK(context_ != nullptr, "the xpu context is nullptr.");
PADDLE_ENFORCE_XRE_SUCCESS(xpu_wait(context_->xpu_stream));
xpu::Context* ctx_t = GetXdlCtx();
if (ctx_t) {
PD_CHECK(ctx_t != nullptr, "the xpu context is nullptr.");
PADDLE_ENFORCE_XRE_SUCCESS(xpu_wait(ctx_t->xpu_stream));
}
ClearStashedMemory();
}
class XHPCBufferManager {
public:
void* Alloc(const Place& place, size_t size, XPUStream xpu_stream) {
VLOG(3) << "Alloc " << size << " bytes from XHPC on stream "
<< xpu_stream;
phi::Stream stream(reinterpret_cast<StreamId>(xpu_stream));
auto allocation = memory_utils::Alloc(place, size, stream);
void* ret = allocation.get()->ptr();
allocations_to_free_.back().push_back(std::move(allocation));
return ret;
}
void Save() {
allocations_to_free_.emplace_back();
VLOG(3) << "XHPC ctx_guard created, " << GetStackLevel()
<< " are in use now.";
}
void Free() {
PADDLE_ENFORCE_GT(GetStackLevel(),
0,
errors::PreconditionNotMet(
"No ctx_guard when overload_free is called"));
allocations_to_free_.pop_back();
VLOG(3) << "XHPC ctx_guard destroyed, " << GetStackLevel()
<< " are in use now.";
}
private:
size_t GetStackLevel() const { return allocations_to_free_.size(); }
std::vector<std::vector<Allocator::AllocationPtr>> allocations_to_free_;
};
void Init(int64_t gm_default_size = 1024,
int64_t l3_default_size = 1024,
bool is_comm_context = false) {
owned_ = true;
backends::xpu::XPUDeviceGuard guard(place_.GetDeviceId());
LOG_FIRST_N(WARNING, 1)
<< "Please NOTE: xpu device: " << static_cast<int>(place_.device);
context_ = xpu::create_context();
if (std::getenv("XPU_CDNN_CLUSTER_PARALLEL") != nullptr &&
!is_comm_context) {
XPUStream s;
xpu_stream_create(&s);
context_->set_stream(s);
}
if (std::getenv("XPU_PADDLE_DISABLE_ALLOC_OVERLOAD") == nullptr) {
// overload ctx alloc/free to avoid xpu_malloc/xpu_wait
auto overload_alloc_fn =
[&xhpc_buf_mgr = xhpc_buf_mgr_,
&place = place_,
&s = context_->xpu_stream](size_t size) -> void* {
return xhpc_buf_mgr.Alloc(place, size, s);
};
auto overload_save_fn = [&xhpc_buf_mgr = xhpc_buf_mgr_]() {
xhpc_buf_mgr.Save();
};
auto overload_free_fn = [&xhpc_buf_mgr = xhpc_buf_mgr_]() {
xhpc_buf_mgr.Free();
};
context_->set_overload_alloc(
overload_alloc_fn, overload_free_fn, overload_save_fn);
gm_default_size = 1;
VLOG(1) << "XPUAPI_DEFUAULT_SIZE is disabled because you overload the "
"alloc of xhpc. If you want to use XPUAPI_DEFAULT_SIZE, "
"please set XPU_PADDLE_DISABLE_ALLOC_OVERLOAD=1";
}
context_->set_option("XPUAPI_DEFAULT_SIZE",
std::to_string(gm_default_size).c_str());
VLOG(3) << "xpu place " << static_cast<int>(place_.GetDeviceId())
<< "context " << context_ << " set xpuapi_default_size "
<< gm_default_size;
xpu_version_ = backends::xpu::get_xpu_version(place_.device);
SetL3Cache(l3_default_size);
}
void SetXContext(xpu::Context* context) {
if (context_ != nullptr) {
backends::xpu::XPUDeviceGuard guard(place_.GetDeviceId());
PADDLE_ENFORCE_XRE_SUCCESS(xpu_wait(context_->xpu_stream));
if (context_->xpu_stream != nullptr && stream_owned_) {
xpu_stream_destroy(context_->xpu_stream);
stream_owned_ = false;
context_->xpu_stream = nullptr;
}
if (owned_) {
xpu::destroy_context(context_);
}
}
context_ = context;
owned_ = false;
}
void SetBkclContext(xpu::BKCLContext_t context) { bkcl_context_ = context; }
void CreateStream() {
if (context_->xpu_stream) {
VLOG(3) << "xpu stream is already created for current context";
return;
}
PADDLE_ENFORCE_XPU_SUCCESS(xpu_stream_create(&context_->xpu_stream));
stream_owned_ = true;
}
void SetXdlCtx() {
std::string tname = phi::GetCurrentThreadName();
if (tname.substr(0, 10) == "Dataloader" &&
context_map_.find(tname) == context_map_.end()) {
VLOG(4) << "Set XPU Dataloader Context with current thread name = "
<< tname << " currently " << context_map_.size()
<< " contexts existing";
xpu::Context* ctx_t = xpu::create_context();
// DataLoader does not require a pre-allocated GM buffer
// to avoid xpu_wait calls
ctx_t->set_option("XPUAPI_DEFAULT_SIZE", "1");
context_map_[tname] = ctx_t;
}
}
xpu::Context* GetXdlCtx() const {
std::string tname = phi::GetCurrentThreadName();
VLOG(4) << "Get XPU Context with current thread name = " << tname
<< " currently " << context_map_.size() << " contexts existing";
if (tname.substr(0, 10) != "Dataloader") {
return context_;
} else {
return (context_map_.find(tname) == context_map_.end())
? nullptr
: context_map_.find(tname)->second;
}
}
void AddStashedMemory(const DenseTensor& tensor) {
stashed_mem_for_free_.push_back(tensor.Holder());
}
void ClearStashedMemory() { stashed_mem_for_free_.clear(); }
bool owned_{false};
bool stream_owned_{false};
Place place_;
backends::xpu::XPUVersion xpu_version_;
int runtime_version_;
int driver_version_;
xpu::Context* context_{nullptr};
std::unordered_map<std::string, xpu::Context*> context_map_;
// NOTE: Distributed communicator, distributed framework manages its
// resources, XPUContext only holds references.
xpu::BKCLContext_t bkcl_context_{nullptr};
XHPCBufferManager xhpc_buf_mgr_;
std::vector<std::shared_ptr<Allocation>> stashed_mem_for_free_;
};
static int64_t get_gm_size(int i) {
int64_t default_size = 1024;
if (std::getenv("XPUAPI_DEFAULT_SIZE") != nullptr) {
default_size = std::atoll(std::getenv("XPUAPI_DEFAULT_SIZE"));
}
std::string cur_env = std::string("XPUAPI_DEFAULT_SIZE") + std::to_string(i);
if (std::getenv(cur_env.c_str()) != nullptr) {
default_size = std::atoll(std::getenv(cur_env.c_str()));
}
return default_size;
}
static int64_t get_l3_size(int i) {
int64_t default_size = 1024;
if (std::getenv("XPU_PADDLE_L3_SIZE") != nullptr) {
default_size = std::atoll(std::getenv("XPU_PADDLE_L3_SIZE"));
}
std::string cur_env = std::string("XPU_PADDLE_L3_SIZE") + std::to_string(i);
if (std::getenv(cur_env.c_str()) != nullptr) {
default_size = std::atoll(std::getenv(cur_env.c_str()));
}
return default_size;
}
XPUContext::XPUContext() : DeviceContext() {
if (std::getenv("XPU_CDNN_CLUSTER_PARALLEL") != nullptr) {
int default_num_stream = 2;
if (std::getenv("XPU_CDNN_CLUSTER_PARALLEL_STREAM_NUMBER") != nullptr) {
default_num_stream =
atoi(std::getenv("XPU_CDNN_CLUSTER_PARALLEL_STREAM_NUMBER"));
}
for (int i = 0; i < default_num_stream; i++) {
impls_.push_back(std::make_unique<Impl>());
impls_[i]->Init(get_gm_size(i), get_l3_size(i));
}
} else {
impls_.push_back(std::make_unique<Impl>());
impls_[0]->Init(get_gm_size(0), get_l3_size(0));
stream_pool.push_back(impls_[0]->context_->get_stream());
idle_stream_flags.push_back(false);
current_stream_handle =
XPUStreamHandle(impls_[0]->context_->get_stream(), 0);
if (std::getenv("XPU_DEFAULT_STREAM_NUMBER") != nullptr) {
int default_num_stream = atoi(std::getenv("XPU_DEFAULT_STREAM_NUMBER"));
for (int i = 0; i < default_num_stream; i++) {
XPUStream s;
PADDLE_ENFORCE_XPU_SUCCESS(xpu_stream_create(&s));
stream_pool.push_back(s);
idle_stream_flags.push_back(true);
}
}
}
current_stream_idx = 0;
}
XPUContext::XPUContext(const XPUPlace& place, bool is_comm_context)
: DeviceContext() {
if (is_comm_context) {
// for communication context init, with gm_size=1 and l3_size=1
impls_.push_back(std::make_unique<Impl>(place));
impls_[0]->Init(0, 0, true);
} else if (std::getenv("XPU_CDNN_CLUSTER_PARALLEL") != nullptr) {
int default_num_stream = 4;
if (std::getenv("XPU_CDNN_CLUSTER_PARALLEL_STREAM_NUMBER") != nullptr) {
default_num_stream =
atoi(std::getenv("XPU_CDNN_CLUSTER_PARALLEL_STREAM_NUMBER"));
}
for (int i = 0; i < default_num_stream; i++) {
impls_.push_back(std::make_unique<Impl>(place));
impls_[i]->Init(get_gm_size(i), get_l3_size(i));
}
stream_pool.push_back(impls_[0]->context_->get_stream());
idle_stream_flags.push_back(false);
} else {
impls_.push_back(std::make_unique<Impl>(place));
impls_[0]->Init(get_gm_size(0), get_l3_size(0));
stream_pool.push_back(impls_[0]->context_->get_stream());
idle_stream_flags.push_back(false);
current_stream_handle =
XPUStreamHandle(impls_[0]->context_->get_stream(), 0);
}
current_stream_idx = 0;
}
XPUContext::~XPUContext() = default;
const Place& XPUContext::GetPlace() const { return impls_[0]->GetPlace(); }
XPUStream XPUContext::stream(int i) const {
CheckValidStreamId(i);
return impls_[i]->stream();
}
void XPUContext::SetStream(void* stream, int i) {
CheckValidStreamId(i);
impls_[i]->SetStream(stream);
if (i == 0) {
current_stream_handle.set_stream(static_cast<XPUStream>(stream));
}
}
void XPUContext::CheckValidStreamId(int i) const {
PADDLE_ENFORCE_GE(
i,
0,
errors::InvalidArgument(
"The stream index must be greater than or equal to 0."));
PADDLE_ENFORCE_LT(
i,
GetStreamNum(),
errors::InvalidArgument("The stream index should be less than the number "
"of stream used (%d), but got %d",
GetStreamNum(),
i));
}
void XPUContext::CheckValidIdxInRange(int i, int i_max) const {
PADDLE_ENFORCE_GE(
i,
0,
errors::InvalidArgument(
"The stream index must be greater than or equal to 0."));
PADDLE_ENFORCE_LT(
i,
i_max,
errors::InvalidArgument("The stream index should be less than the number "
"of stream used (%d), but got %d",
i_max,
i));
}
void XPUContext::SetXpuVersion(int version) {
impls_[0]->xpu_version_ = static_cast<backends::xpu::XPUVersion>(version);
}
void XPUContext::SetRuntimeVersion(int version) {
impls_[0]->runtime_version_ = version;
}
void XPUContext::SetDriverVersion(int version) {
impls_[0]->driver_version_ = version;
}
backends::xpu::XPUVersion XPUContext::xpu_version() const {
return impls_[0]->xpu_version_;
}
xpu::Context* XPUContext::x_context(int i) const {
CheckValidStreamId(i);
return impls_[i]->GetXContext();
}
xpu::BKCLContext_t XPUContext::bkcl_context() const {
return impls_[0]->GetBkclContext();
}
void XPUContext::Wait() const {
for (uint64_t i = 0; i < impls_.size(); i++) {
impls_[i]->Wait();
}
}
void XPUContext::SetXContext(xpu::Context* context, int i) {
CheckValidStreamId(i);
impls_[i]->SetXContext(context);
}
void XPUContext::SetL3Cache(int64_t l3_size, int i) {
CheckValidStreamId(i);
impls_[i]->SetL3Cache(l3_size);
}
void XPUContext::SetBkclContext(xpu::BKCLContext_t context) {
impls_[0]->SetBkclContext(context);
}
void XPUContext::CreateStream(int i) {
CheckValidStreamId(i);
impls_[i]->CreateStream();
// Update stream pool and handle after creating the stream
if (i == 0 && current_stream_idx == 0 && stream_pool.size() > 0) {
stream_pool[current_stream_idx] = impls_[i]->context_->get_stream();
current_stream_handle.set_stream(impls_[i]->context_->get_stream());
idle_stream_flags[current_stream_idx] = false;
}
}
void XPUContext::RecordEvent(XPUEvent event, int s) const {
CheckValidStreamId(s);
int r = xpu_event_record(event, stream(s));
PADDLE_ENFORCE_XRE_SUCCESS(r);
}
void XPUContext::StreamWaitEvent(XPUEvent event, int s) const {
CheckValidStreamId(s);
int r = xpu_stream_wait_event(stream(s), event);
PADDLE_ENFORCE_XRE_SUCCESS(r);
}
void XPUContext::StreamWaitStream(int wait_stream, int record_stream) const {
CheckValidStreamId(wait_stream);
CheckValidStreamId(record_stream);
XPUEvent event = XPUEventPool::Instance().CreateEventFromPool();
RecordEvent(event, record_stream);
StreamWaitEvent(event, wait_stream);
impls_[record_stream]->ClearStashedMemory();
}
int64_t XPUContext::GetStreamNum() const { return impls_.size(); }
int XPUContext::SetCurrentStream(int idx) {
int prev_stream_idx = current_stream_idx;
if (prev_stream_idx != idx) {
impls_[0]->SetStream(stream_pool[idx]);
current_stream_handle.set_stream(stream_pool[idx]);
current_stream_idx = idx;
idle_stream_flags[prev_stream_idx] = true;
idle_stream_flags[current_stream_idx] = false;
}
return prev_stream_idx;
}
void XPUContext::StreamWaitStreamInPool(int wait_stream,
int record_stream) const {
CheckValidIdxInRange(wait_stream, stream_pool.size());
CheckValidIdxInRange(record_stream, stream_pool.size());
XPUEvent event = XPUEventPool::Instance().CreateEventFromPool();
int r = xpu_event_record(event, stream_pool[record_stream]);
PADDLE_ENFORCE_XRE_SUCCESS(r);
r = xpu_stream_wait_event(stream_pool[wait_stream], event);
PADDLE_ENFORCE_XRE_SUCCESS(r);
}
void XPUContext::StreamWaitEventInPool(int wait_stream, XPUEvent event) const {
CheckValidIdxInRange(wait_stream, stream_pool.size());
int r = xpu_stream_wait_event(stream_pool[wait_stream], event);
PADDLE_ENFORCE_XRE_SUCCESS(r);
}
int XPUContext::get_idle_stream() {
bool found_idle_stream = false;
int stream_idx = 0;
int num_streams = idle_stream_flags.size();
for (; stream_idx < num_streams; stream_idx++) {
if (idle_stream_flags[stream_idx]) {
found_idle_stream = true;
break;
}
}
if (found_idle_stream) {
idle_stream_flags[stream_idx] = false;
return stream_idx;
} else {
add_stream_to_pool();
return stream_pool.size() - 1;
}
}
void XPUContext::add_stream_to_pool() {
XPUStream s;
PADDLE_ENFORCE_XPU_SUCCESS(xpu_stream_create(&s));
stream_pool.push_back(s);
idle_stream_flags.push_back(false);
}
XPUStream XPUContext::get_stream_from_pool(int idx) const {
PADDLE_ENFORCE_GE(
idx,
0,
errors::InvalidArgument(
"The stream index must be greater than or equal to 0."));
PADDLE_ENFORCE_LT(
idx,
stream_pool.size(),
errors::InvalidArgument("The stream index should be less than the number "
"of stream used (%d), but got %d",
stream_pool.size(),
idx));
return stream_pool[idx];
}
int XPUContext::get_current_stream_idx() { return current_stream_idx; }
void XPUContext::AddStashedMemory(int stream, const DenseTensor& tensor) {
CheckValidStreamId(stream);
impls_[stream]->AddStashedMemory(tensor);
}
XPUStream XPUContext::get_current_stream() { return impls_[0]->stream(); }
XPUStreamHandle* XPUContext::get_current_stream_handle() {
if (impls_[0]->context_->get_stream() == nullptr) {
XPUStream s;
PADDLE_ENFORCE_XPU_SUCCESS(xpu_stream_create(&s));
impls_[0]->SetStream(s);
stream_pool[current_stream_idx] = s;
current_stream_handle.set_stream(s);
}
return &current_stream_handle;
}
void XPUContext::Init() { impls_[0]->Init(); }
XPUContext* get_xpu_context(int device_id) {
auto place_tmp = phi::XPUPlace(
device_id > -1 ? device_id : phi::backends::xpu::GetXPUCurrentDeviceId());
phi::XPUContext* dev_ctx = static_cast<phi::XPUContext*>(
phi::DeviceContextPool::Instance().Get(place_tmp));
return dev_ctx;
}
XPUStreamHandle::XPUStreamHandle() {}
XPUStreamHandle::XPUStreamHandle(const int idx) {
auto* dev_ctx = phi::get_xpu_context();
stream_id = idx;
stream = dev_ctx->get_stream_from_pool(stream_id);
}
XPUStreamHandle::XPUStreamHandle(const phi::XPUPlace& place) {
phi::XPUContext* dev_ctx = static_cast<phi::XPUContext*>(
phi::DeviceContextPool::Instance().Get(place));
stream_id = dev_ctx->get_idle_stream();
stream = dev_ctx->get_stream_from_pool(stream_id);
}
XPUStreamHandle::XPUStreamHandle(const XPUStream xpu_stream, const int id) {
stream = xpu_stream;
stream_id = id;
}
void XPUStreamHandle::Init() {
auto* dev_ctx = phi::get_xpu_context();
stream_id = dev_ctx->get_idle_stream();
stream = dev_ctx->get_stream_from_pool(stream_id);
}
void XPUStreamHandle::wait_event(XPUEvent event) const {
int r = xpu_stream_wait_event(stream, event);
PADDLE_ENFORCE_XRE_SUCCESS(r);
}
void XPUStreamHandle::synchronize() const {
int r = xpu_wait(stream);
PADDLE_ENFORCE_XRE_SUCCESS(r);
}
void XPUStreamHandle::set_stream(XPUStream stream_) { stream = stream_; }
void XPUStreamHandle::record_event(XPUEvent event) const {
int r = xpu_event_record(event, stream);
PADDLE_ENFORCE_XRE_SUCCESS(r);
}
XPUStreamHandle get_current_stream_handle(int device_id) {
auto* dev_ctx = get_xpu_context(device_id);
return *dev_ctx->get_current_stream_handle();
}
XPUStreamHandle get_stream_handle(int device_id) {
auto* dev_ctx = get_xpu_context(device_id);
return XPUStreamHandle(dev_ctx->get_idle_stream());
}
void set_current_stream(XPUStreamHandle* s) {
auto* dev_ctx = get_xpu_context();
dev_ctx->SetStream(s->raw_stream(), 0);
}
XPUEventPool& XPUEventPool::Instance() {
static XPUEventPool pool;
return pool;
}
XPUEventPool::~XPUEventPool() {
const auto& DestroyEvent = [](XPUEvent event) {
int r = xpu_event_destroy(event);
PADDLE_ENFORCE_XRE_SUCCESS(r);
};
const auto& CheckComplishAndDestroy = [&](XPUEvent event) -> bool {
if (xpu_event_query(event) == XPU_SUCCESS) {
DestroyEvent(event);
return true;
} else {
return false;
}
};
std::unique_lock<std::mutex> lock(mtx_);
while (!incomplished_events_.empty()) {
XPUEvent event = incomplished_events_.front();
if (!CheckComplishAndDestroy(event)) {
LOG(ERROR) << "failed on destroying event when destroying event pool.";
}
incomplished_events_.pop();
}
}
XPUEvent XPUEventPool::CreateEventFromPool() {
std::unique_lock<std::mutex> lock(mtx_);
const auto& CreateNewEvent = [&]() -> XPUEvent {
XPUEvent new_event;
PADDLE_ENFORCE_XPU_SUCCESS(xpu_event_create(&new_event));
incomplished_events_.push(new_event);
return new_event;
};
const auto& CreateNewOrReuseEvent = [&]() -> XPUEvent {
XPUEvent front_event = incomplished_events_.front();
incomplished_events_.pop();
incomplished_events_.push(front_event);
if (xpu_event_query(front_event) == XPU_SUCCESS) {
return front_event;
}
return CreateNewEvent();
};
if (incomplished_events_.empty()) {
return CreateNewEvent();
}
return CreateNewOrReuseEvent();
}
XPUEventHandle::XPUEventHandle() {
event_ = XPUEventPool::Instance().CreateEventFromPool();
}
XPUEventHandle::XPUEventHandle(XPUStream stream) {
event_ = XPUEventPool::Instance().CreateEventFromPool();
PADDLE_ENFORCE_XRE_SUCCESS(xpu_event_record(event_, stream));
}
void XPUEventHandle::record(XPUStream stream) {
PADDLE_ENFORCE_XRE_SUCCESS(xpu_event_record(event_, stream));
}
bool XPUEventHandle::query() {
int result = xpu_event_query(event_);
if (result == XPU_SUCCESS) {
return true;
}
return false;
}
void XPUEventHandle::synchronize() {
PADDLE_ENFORCE_XRE_SUCCESS(xpu_event_wait(event_));
}
#if defined(PADDLE_WITH_XPU)
XPUPinnedContext::XPUPinnedContext() {
eigen_device_ = std::make_unique<Eigen::DefaultDevice>();
}
XPUPinnedContext::XPUPinnedContext(XPUPinnedPlace place) : place_(place) {
eigen_device_ = std::make_unique<Eigen::DefaultDevice>();
}
Eigen::DefaultDevice* XPUPinnedContext::eigen_device() const {
return eigen_device_.get();
}
const Place& XPUPinnedContext::GetPlace() const { return place_; }
#endif
} // namespace phi