/* 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/api/lib/api_gen_utils.h" #include "paddle/common/flags.h" #include "paddle/phi/backends/gpu/gpu_info.h" #include "paddle/phi/core/memory/malloc.h" #include "paddle/phi/core/memory/mem_utils.h" #include "paddle/phi/core/memory/stats.h" #include "paddle/phi/core/visit_type.h" #include "paddle/phi/kernels/strided_copy_kernel.h" PHI_DECLARE_bool(use_stride_kernel); COMMON_DECLARE_bool(enable_compact_mem); COMMON_DECLARE_int64(max_reserved_threshold_in_gb); COMMON_DECLARE_int64(cur_allocated_threshold_in_gb); COMMON_DECLARE_bool(try_allocate); #include "glog/logging.h" #include "paddle/phi/core/distributed/auto_parallel/dist_attr.h" #include "paddle/phi/core/distributed/auto_parallel/dist_meta_tensor.h" #include "paddle/phi/core/distributed/auto_parallel/dist_tensor.h" #include "paddle/phi/core/kernel_factory.h" namespace paddle::experimental { /* ------------------ for input ----------------------- */ std::shared_ptr TensorToDenseTensor(const Tensor& tensor) { return std::static_pointer_cast(tensor.impl()); } paddle::optional TensorToDenseTensor( const paddle::optional& tensor) { if (tensor) { return {*std::static_pointer_cast(tensor->impl())}; } return nullptr; } std::unique_ptr> TensorToDenseTensor( const std::vector& tensors) { auto pt_tensors = std::make_unique>(); pt_tensors->reserve(tensors.size()); for (const auto& t : tensors) { pt_tensors->push_back( std::dynamic_pointer_cast(t.impl()).get()); } return pt_tensors; } std::vector TensorToConstDenseTensorPtr( const std::vector& tensors) { std::vector pt_tensors(tensors.size()); for (size_t i = 0; i < tensors.size(); ++i) { pt_tensors[i] = static_cast(tensors[i].impl().get()); } return pt_tensors; } paddle::optional> TensorToConstDenseTensorPtr( const paddle::optional>& tensors) { paddle::optional> pt_tensors; if (tensors) { pt_tensors = paddle::optional>(tensors->size()); for (size_t i = 0; i < tensors->size(); ++i) { pt_tensors->at(i) = static_cast(tensors->at(i).impl().get()); } } return pt_tensors; } std::shared_ptr TensorToSelectedRows(const Tensor& tensor) { return std::static_pointer_cast(tensor.impl()); } paddle::optional TensorToSelectedRows( const paddle::optional& tensor) { if (tensor) { return {*std::static_pointer_cast(tensor->impl())}; } return nullptr; } std::shared_ptr TensorToStringTensor(const Tensor& tensor) { return std::dynamic_pointer_cast(tensor.impl()); } std::shared_ptr TensorToSparseCooTensor( const Tensor& tensor) { return std::static_pointer_cast(tensor.impl()); } /* ----------------- for infer_meta --------------------- */ phi::MetaTensor MakeMetaTensor(const phi::TensorBase& tensor) { return phi::MetaTensor(tensor); } std::vector MakeMetaTensor( const std::vector& tensors) { std::vector meta_tensors; meta_tensors.reserve(tensors.size()); for (const auto* t : tensors) { meta_tensors.emplace_back(*t); } return meta_tensors; } phi::MetaTensor MakeMetaTensor( const paddle::optional& tensor) { if (tensor) { return {phi::MetaTensor(*tensor)}; } return phi::MetaTensor(); } std::vector MakeMetaTensor( const std::vector& tensors) { std::vector meta_tensors; meta_tensors.reserve(tensors.size()); for (const auto* t : tensors) { meta_tensors.emplace_back(*t); } return meta_tensors; } std::vector MakeMetaTensor( const std::vector& tensors) { std::vector meta_tensors; meta_tensors.reserve(tensors.size()); for (const auto* t : tensors) { meta_tensors.emplace_back(*t); } return meta_tensors; } std::vector MakeMetaTensor( const std::vector& tensors) { std::vector meta_tensors; meta_tensors.reserve(tensors.size()); for (auto* t : tensors) { meta_tensors.emplace_back(*t); } return meta_tensors; } phi::MetaTensor MakeMetaTensor( const paddle::optional& tensor) { if (tensor) { return {phi::MetaTensor(*tensor)}; } return phi::MetaTensor(); } phi::MetaTensor MakeMetaTensor( const paddle::optional& tensor) { if (tensor) { return {phi::MetaTensor(*tensor)}; } return phi::MetaTensor(); } phi::MetaTensor MakeMetaTensor( const paddle::optional& tensor) { if (tensor) { return {phi::MetaTensor(*tensor)}; } return phi::MetaTensor(); } std::vector MakeMetaTensor( const paddle::optional>& tensors) { std::vector meta_tensors; if (tensors) { meta_tensors.reserve(tensors->size()); for (auto* t : tensors.get()) { meta_tensors.emplace_back(*t); } } return meta_tensors; } phi::DenseTensor* SetKernelOutput(Tensor* out) { if (out) { if (out->impl() == nullptr) { out->set_impl(std::make_shared()); } return static_cast(out->impl().get()); } return nullptr; } std::vector SetKernelOutput(size_t out_size, std::vector* out) { out->reserve(out_size); std::vector results(out_size); for (size_t i = 0; i < out_size; ++i) { auto tensor_ptr = std::make_shared(); results[i] = tensor_ptr.get(); out->emplace_back(); out->back().set_impl(tensor_ptr); } return results; } std::vector SetInplaceVectorKernelOutput( size_t out_size, std::vector* out) { std::vector results(out->size(), nullptr); for (size_t i = 0; i < out->size(); ++i) { results[i] = static_cast(out->at(i).impl().get()); } return results; } std::vector SetInplaceOptionalVectorKernelOutput( size_t out_size, const paddle::optional>& out) { std::vector results; if (out) { results = std::vector(out->size(), nullptr); for (size_t i = 0; i < out->size(); ++i) { results[i] = static_cast(out->at(i).impl().get()); } } return results; } std::vector SetKernelOutput(std::vector* out) { std::vector results(out->size(), nullptr); for (size_t i = 0; i < out->size(); ++i) { if (out->at(i)) { auto tensor_ptr = std::make_shared(); results[i] = tensor_ptr.get(); (*out)[i]->set_impl(tensor_ptr); } } return results; } phi::SelectedRows* SetSelectedRowsKernelOutput(Tensor* out) { if (!out->initialized()) { auto select_rows = std::make_shared(); out->set_impl(select_rows); return select_rows.get(); } return static_cast(out->impl().get()); } phi::TensorBase* SetSparseKernelOutput(Tensor* out, TensorType type) { if (!out) { return nullptr; } if (!out->initialized()) { if (type == TensorType::SPARSE_COO) { auto sparse_tensor = std::make_shared( phi::DenseTensor(), phi::DenseTensor(), phi::DDim{-1}); out->set_impl(sparse_tensor); return sparse_tensor.get(); } else if (type == TensorType::SPARSE_CSR) { auto sparse_tensor = std::make_shared(phi::DenseTensor(), phi::DenseTensor(), phi::DenseTensor(), phi::DDim{-1, -1}); out->set_impl(sparse_tensor); return sparse_tensor.get(); } else { auto dense_tensor = std::make_shared(); out->set_impl(dense_tensor); return dense_tensor.get(); } } return out->impl().get(); } phi::TensorBase* SetStringsKernelOutput(Tensor* out, TensorType type) { if (!out->initialized()) { if (type == TensorType::STRING_TENSOR) { if (out->impl() == nullptr) { auto strings_tensor = std::make_shared(); out->set_impl(strings_tensor); } return out->impl().get(); } } return out->impl().get(); } phi::DenseTensor* ProcessStrideBackup(phi::DenseTensor** tensor) { if (!FLAGS_use_stride_kernel || *tensor == nullptr || !(*tensor)->IsInitialized() || (*tensor)->meta().is_contiguous()) { return nullptr; } else { phi::DenseTensor* backup = *tensor; *tensor = new phi::DenseTensor(); return backup; } } std::vector ProcessStrideBackup( std::vector* tensor) { std::vector backup; backup.reserve(tensor->size()); for (auto& t : *tensor) { if (!FLAGS_use_stride_kernel || t == nullptr || !t->IsInitialized() || t->meta().is_contiguous()) { backup.emplace_back(nullptr); } else { backup.emplace_back(t); t = new phi::DenseTensor(); } } return backup; } phi::SelectedRows* ProcessStrideBackup(phi::SelectedRows** tensor) { return nullptr; } template void TransStride(const Context& dev_ctx, phi::DenseTensor* from, phi::DenseTensor* to) { if (to) { PD_VISIT_ALL_TYPES(to->dtype(), "StridedCopyKernel", ([&] { phi::StridedCopyKernel( dev_ctx, *from, common::vectorize(to->dims()), common::vectorize(to->strides()), to->offset(), to); })); delete from; } } template void TransStride(const Context& dev_ctx, const std::vector& from, const std::vector& to) { for (size_t i = 0; i < to.size(); i++) { if (to[i]) { PD_VISIT_ALL_TYPES(to[i]->dtype(), "StridedCopyKernel", ([&] { phi::StridedCopyKernel( dev_ctx, *from[i], common::vectorize(to[i]->dims()), common::vectorize(to[i]->strides()), to[i]->offset(), to[i]); })); delete from[i]; } } } void TransStride(phi::DeviceContext* dev_ctx, phi::DenseTensor* from, phi::DenseTensor* to) { if (to) { auto* cpu_ctx = dynamic_cast(dev_ctx); if (cpu_ctx) { PD_VISIT_ALL_TYPES(to->dtype(), "StridedCopyKernel", ([&] { phi::StridedCopyKernel( *cpu_ctx, *from, common::vectorize(to->dims()), common::vectorize(to->strides()), to->offset(), to); })); delete from; return; } #if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP) auto* gpu_ctx = dynamic_cast(dev_ctx); if (gpu_ctx) { PD_VISIT_ALL_TYPES(to->dtype(), "StridedCopyKernel", ([&] { phi::StridedCopyKernel( *gpu_ctx, *from, common::vectorize(to->dims()), common::vectorize(to->strides()), to->offset(), to); })); delete from; return; } #endif #ifdef PADDLE_WITH_XPU auto* xpu_ctx = dynamic_cast(dev_ctx); if (xpu_ctx) { PD_VISIT_ALL_TYPES(to->dtype(), "StridedCopyKernel", ([&] { phi::StridedCopyKernel( *xpu_ctx, *from, common::vectorize(to->dims()), common::vectorize(to->strides()), to->offset(), to); })); delete from; return; } #endif #ifdef PADDLE_WITH_CUSTOM_DEVICE auto* custom_ctx = dynamic_cast(dev_ctx); if (custom_ctx) { const phi::KernelKey& kernel_key = {phi::TransToPhiBackend(to->place()), phi::DataLayout::ALL_LAYOUT, to->dtype()}; using kernel_signature = void (*)(const phi::DeviceContext&, const phi::DenseTensor&, const std::vector&, const std::vector&, int64_t, phi::DenseTensor*); PD_VISIT_KERNEL("strided_copy", kernel_key, kernel_signature, false, *custom_ctx, *from, common::vectorize(to->dims()), common::vectorize(to->strides()), to->offset(), to); delete from; return; } #endif } } void TransStrideLegacy(phi::DeviceContext* dev_ctx, phi::DenseTensor* from, phi::DenseTensor* to) { if (to) { auto* cpu_ctx = dynamic_cast(dev_ctx); if (cpu_ctx) { PD_VISIT_ALL_TYPES(to->dtype(), "StridedCopyKernel", ([&] { phi::StridedCopyKernel( *cpu_ctx, *from, common::vectorize(to->dims()), common::vectorize(to->strides()), to->offset(), to); })); return; } #if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP) auto* gpu_ctx = dynamic_cast(dev_ctx); if (gpu_ctx) { PD_VISIT_ALL_TYPES(to->dtype(), "StridedCopyKernel", ([&] { phi::StridedCopyKernel( *gpu_ctx, *from, common::vectorize(to->dims()), common::vectorize(to->strides()), to->offset(), to); })); return; } #endif #ifdef PADDLE_WITH_XPU auto* xpu_ctx = dynamic_cast(dev_ctx); if (xpu_ctx) { PD_VISIT_ALL_TYPES(to->dtype(), "StridedCopyKernel", ([&] { phi::StridedCopyKernel( *xpu_ctx, *from, common::vectorize(to->dims()), common::vectorize(to->strides()), to->offset(), to); })); return; } #endif #ifdef PADDLE_WITH_CUSTOM_DEVICE auto* custom_ctx = dynamic_cast(dev_ctx); if (custom_ctx) { const phi::KernelKey& kernel_key = {phi::TransToPhiBackend(to->place()), phi::DataLayout::ALL_LAYOUT, to->dtype()}; using kernel_signature = void (*)(const phi::DeviceContext&, const phi::DenseTensor&, const std::vector&, const std::vector&, int64_t, phi::DenseTensor*); PD_VISIT_KERNEL("strided_copy", kernel_key, kernel_signature, false, *custom_ctx, *from, common::vectorize(to->dims()), common::vectorize(to->strides()), to->offset(), to); return; } #endif } } void TransStride(phi::DeviceContext* dev_ctx, const std::vector& from, const std::vector& to) { for (size_t i = 0; i < to.size(); i++) { if (to[i]) { auto* cpu_ctx = dynamic_cast(dev_ctx); if (cpu_ctx) { PD_VISIT_ALL_TYPES(to[i]->dtype(), "StridedCopyKernel", ([&] { phi::StridedCopyKernel( *cpu_ctx, *from[i], common::vectorize(to[i]->dims()), common::vectorize(to[i]->strides()), to[i]->offset(), to[i]); })); delete from[i]; continue; } #if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP) auto* gpu_ctx = dynamic_cast(dev_ctx); if (gpu_ctx) { PD_VISIT_ALL_TYPES(to[i]->dtype(), "StridedCopyKernel", ([&] { phi::StridedCopyKernel( *gpu_ctx, *from[i], common::vectorize(to[i]->dims()), common::vectorize(to[i]->strides()), to[i]->offset(), to[i]); })); delete from[i]; continue; } #endif #ifdef PADDLE_WITH_XPU auto* xpu_ctx = dynamic_cast(dev_ctx); if (xpu_ctx) { PD_VISIT_ALL_TYPES(to[i]->dtype(), "StridedCopyKernel", ([&] { phi::StridedCopyKernel( *xpu_ctx, *from[i], common::vectorize(to[i]->dims()), common::vectorize(to[i]->strides()), to[i]->offset(), to[i]); })); delete from[i]; continue; } #endif #ifdef PADDLE_WITH_CUSTOM_DEVICE auto* custom_ctx = dynamic_cast(dev_ctx); if (custom_ctx) { const phi::KernelKey& kernel_key = { phi::TransToPhiBackend(to[i]->place()), phi::DataLayout::ALL_LAYOUT, to[i]->dtype()}; using kernel_signature = void (*)(const phi::DeviceContext&, const phi::DenseTensor&, const std::vector&, const std::vector&, int64_t, phi::DenseTensor*); PD_VISIT_KERNEL("strided_copy", kernel_key, kernel_signature, false, *custom_ctx, *from[i], common::vectorize(to[i]->dims()), common::vectorize(to[i]->strides()), to[i]->offset(), to[i]); delete from[i]; continue; } #endif } } } void TransStride(phi::DeviceContext* dev_ctx, phi::SelectedRows* from, phi::SelectedRows* to) {} /* ------------------ for auto parallel ----------------------- */ phi::distributed::DistMetaTensor MakeDistMetaTensor( const phi::TensorBase& tensor) { return phi::distributed::DistMetaTensor(tensor); } std::vector MakeDistMetaTensor( const std::vector& tensors) { std::vector meta_tensors; meta_tensors.reserve(tensors.size()); for (const auto* t : tensors) { meta_tensors.emplace_back(*t); } return meta_tensors; } phi::distributed::DistTensor* SetKernelDistOutput( Tensor* out, const phi::distributed::ArgDistAttr& dist_attr) { PADDLE_ENFORCE_EQ( paddle::holds_alternative(dist_attr), true, common::errors::PreconditionNotMet( "Arg must be a single TensorDistAttr")); if (out) { if (out->impl() == nullptr) { auto dist_t = std::make_shared( phi::DDim(), paddle::get<0>(dist_attr)); out->set_impl(dist_t); } return static_cast(out->impl().get()); } return nullptr; } std::vector SetKernelDistOutput( size_t out_size, std::vector* out) { std::vector results(out_size); if (out->size() != out_size) { // Empty out vector out->reserve(out_size); } for (size_t i = 0; i < out_size; ++i) { if (out->size() != out_size) { auto dist_t = std::make_shared(); out->emplace_back(); out->back().set_impl(dist_t); } results[i] = static_cast(out->at(i).impl().get()); } return results; } std::vector SetKernelDistOutput( const phi::distributed::ArgDistAttr& dist_attr, std::vector* out) { PADDLE_ENFORCE_EQ( paddle::holds_alternative>( dist_attr), true, common::errors::PreconditionNotMet( "Arg must be a vector of TensorDistAttr")); const std::vector& dist_attrs = PADDLE_GET_CONST(std::vector, dist_attr); auto out_size = dist_attrs.size(); std::vector results(out_size); // TODO(GhostScreaming): Inplace outputs are initialized, just set their // dist_attr. if (out->size() == out_size) { VLOG(3) << "Outputs are inplace vector Tensors, SKIP set dist_attr for out " << "to avoid changing the inplaced input"; for (size_t i = 0; i < out_size; ++i) { results[i] = static_cast(out->at(i).impl().get()); continue; // auto t = // static_cast(out->at(i).impl().get()); // auto dist_t = std::make_shared( // t->shared_value(), t->dims(), dist_attrs[i]); // out->at(i) = Tensor(); // out->at(i).set_impl(dist_t); // results[i] = dist_t.get(); } } else { out->reserve(out_size); for (size_t i = 0; i < out_size; ++i) { auto dist_t = std::make_shared( phi::DDim(), dist_attrs[i]); results[i] = dist_t.get(); out->emplace_back(); out->back().set_impl(dist_t); } } return results; } // For backward std::vector SetKernelDistOutput( std::vector out) { std::vector result; for (auto tmp : out) { if (tmp) { // TODO(GhostScreaming): now all dist case are nullptr if (tmp->impl() == nullptr) { auto dist_t = std::make_shared(); tmp->set_impl(dist_t); } result.emplace_back( static_cast(tmp->impl().get())); } else { result.emplace_back(nullptr); } } return result; } std::shared_ptr CreateKernelDistOutput( Tensor* out, bool set_dist_output_as_tensor_impl, const phi::distributed::TensorDistAttr& dist_attr) { if (out) { auto dist_output = std::make_shared(phi::DDim(), dist_attr); if (set_dist_output_as_tensor_impl) { VLOG(3) << "CreateKernelDistOutput function set generated output " "dist_tensor as Tensor's impl"; if (out->is_dist_tensor()) { VLOG(3) << "out is DistTensor, set DistAttr:" << dist_attr << " to generated DistOutput."; dist_output->unsafe_set_dist_attr(dist_attr); } out->set_impl(dist_output); } return dist_output; } VLOG(4) << "CreateKernelDistOutput with NULL out"; return nullptr; } std::shared_ptr CreateKernelDistOutput( Tensor* out, bool set_dist_output_as_tensor_impl, const phi::distributed::ArgDistAttr& dist_attr) { auto& tensor_dist_attr = PADDLE_GET_CONST(phi::distributed::TensorDistAttr, dist_attr); return CreateKernelDistOutput( out, set_dist_output_as_tensor_impl, tensor_dist_attr); } std::shared_ptr CreateKernelDistOutput( Tensor* out, const phi::distributed::ArgDistAttr& dist_attr) { auto& tensor_dist_attr = PADDLE_GET_CONST(phi::distributed::TensorDistAttr, dist_attr); return CreateKernelDistOutput(out, false, tensor_dist_attr); } std::vector> CreateKernelDistOutput(std::vector out, bool set_dist_output_as_tensor_impl, const phi::distributed::ArgDistAttr& dist_attr) { auto tensor_dist_attrs = PADDLE_GET_CONST( std::vector, dist_attr); PADDLE_ENFORCE_EQ( out.size(), tensor_dist_attrs.size(), common::errors::PreconditionNotMet( "out.size() [%d] and tensor_dist_attrs.size() [%d] not match", out.size(), tensor_dist_attrs.size())); auto size = tensor_dist_attrs.size(); std::vector> results; results.reserve(size); for (size_t i = 0; i < size; i++) { results.emplace_back(CreateKernelDistOutput( out[i], set_dist_output_as_tensor_impl, tensor_dist_attrs[i])); } return results; } std::vector> CreateKernelDistOutput(std::vector out, bool set_dist_output_as_tensor_impl) { auto size = out.size(); std::vector> results; results.reserve(size); for (size_t i = 0; i < size; i++) { results.emplace_back( CreateKernelDistOutput(out[i], set_dist_output_as_tensor_impl)); } return results; } void SetReplicatedDistAttrForOutput( phi::distributed::DistTensor* out, const phi::distributed::ProcessMesh& process_mesh) { if (out) { if (out->dims().size() == -1 || out->dims().size() == 0) { if (out->local_dims().size() != -1 && out->local_dims().size() != 0) { out->unsafe_set_dims(out->local_dims()); VLOG(3) << "DistTensor out has empty shape, use its local value's shape"; } } // For inplace output, we also need to set replicated dist attr auto dist_attr = phi::distributed::TensorDistAttr(common::vectorize(out->dims())); dist_attr.set_process_mesh(process_mesh); out->unsafe_set_dist_attr(dist_attr); } } /* ------------------ for Allocator ----------------------- */ void CheckAndDoCompact(const std::vector& meta_tensors, std::string api) { if (!FLAGS_enable_compact_mem) return; #if defined(PADDLE_WITH_CUDA) const auto current_device_id = phi::backends::gpu::GetCurrentDeviceId(); const auto max_reserved = paddle::memory::DeviceMemoryStatPeakValue("Reserved", current_device_id); const auto max_allocated = paddle::memory::DeviceMemoryStatPeakValue("Allocated", current_device_id); const auto cur_allocated = paddle::memory::DeviceMemoryStatCurrentValue( "Allocated", current_device_id); float divisor = 1 << 30; // calculate total size by meta information auto CalTensorSize = [&](const std::vector& meta_tensors) -> std::pair> { size_t req_total_size = 0; size_t tensor_size = 0; std::vector sizes; for (auto& meta_tensor : meta_tensors) { if (meta_tensor == nullptr) continue; if (meta_tensor->numel() == 0) continue; if (meta_tensor->numel() < 0) { VLOG(1) << "meta_tensor->numel():" << meta_tensor->numel() << " < 0, skip this tensor in " << api; continue; } tensor_size = meta_tensor->numel() * phi::SizeOf(meta_tensor->dtype()); sizes.push_back(tensor_size); req_total_size += tensor_size; } return {req_total_size, sizes}; }; // judge whether compact is needed according to the following conditions in // sequence. // 1. mem_max_reserved < max_reserved_threshold ==> dont need compact // 2. mem_cur_allocated < cur_allocated_threshold ==> dont need compact // 3. max_free_size > req_total_size ==> dont need compact // 4. large_N_free_size < req_total_size ==> need compact // 5. try_allocate result ==> need compact auto NeedCompact = [&](const std::vector& meta_tensors) { if (max_reserved < FLAGS_max_reserved_threshold_in_gb << 30) return false; if (cur_allocated < FLAGS_cur_allocated_threshold_in_gb << 30) return false; const auto [max_free_size, large_N_free_size] = paddle::memory::VmmMaxFreeSize(phi::GPUPlace(current_device_id), meta_tensors.size()); const auto& [req_total_size, size_vec] = CalTensorSize(meta_tensors); VLOG(10) << "run api: " << api << " req_total_size: " << req_total_size << ", max_free_size: " << max_free_size << ", large_N_free_size: " << large_N_free_size << ", max_reserved: " << max_reserved << ", max_allocated: " << max_allocated << ", cur_allocated: " << cur_allocated; if (req_total_size < max_free_size) return false; if (req_total_size > large_N_free_size) { VLOG(1) << "Need Compact in api: " << api << " req_total_size: " << req_total_size << ", large_N_free_size: " << large_N_free_size << ", max_free_size: " << max_free_size << ", max_reserved: " << max_reserved << ", max_allocated: " << max_allocated << ", cur_allocated: " << cur_allocated; return true; } if (FLAGS_try_allocate) { auto alloc_succ = paddle::memory::TryAllocBatch( phi::GPUPlace(current_device_id), size_vec); VLOG(1) << "TryAllocBatch api: " << api << " ret: " << alloc_succ << ", req_total_size: " << req_total_size << ", large_N_free_size: " << large_N_free_size << ", max_free_size: " << max_free_size << ", max_reserved: " << max_reserved << ", max_allocated: " << max_allocated << ", cur_allocated: " << cur_allocated; return !alloc_succ; } return false; }; if (NeedCompact(meta_tensors)) { VLOG(1) << "Before Compact max_reserved: " << max_reserved / divisor << "GB, max_allocated: " << max_allocated / divisor << "GB, cur_allocated: " << cur_allocated / divisor << "GB"; paddle::memory::Compact(phi::GPUPlace(current_device_id)); } #endif } } // namespace paddle::experimental