// 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/kernels/assign_kernel.h" #include "paddle/phi/core/kernel_registry.h" #include "paddle/phi/kernels/copy_kernel.h" #include "paddle/utils/optional.h" #include "paddle/fluid/framework/tensor_util.h" namespace phi { template void AssignKernel(const Context& dev_ctx, const DenseTensor& x, DenseTensor* out) { paddle::framework::TensorCopy(x, x.place(), out); } template void AssignRawKernel(const Context& dev_ctx, const paddle::optional& x, DenseTensor* out) { if (x) { if (!x->IsInitialized()) { return; } auto& x_tensor = *x.get_ptr(); AssignKernel(dev_ctx, x_tensor, out); } } // Note: use `const paddle::optional&> x` // as input if needed template void AssignArrayKernel(const Context& dev_ctx, const std::vector& x, std::vector out) { for (size_t i = 0; i < x.size(); ++i) { AssignKernel(dev_ctx, *x[i], out.at(i)); } } template typename std::enable_if::value>::type CopyVectorToTensor( const Context& dev_ctx, const std::vector& values, DenseTensor* out) { // If attribute value dtype is vector, it will be converted to // vector. at the same time, we can not use vector to hold // the value, because the c++ use bit value to replace byte value. std::vector assign_values; assign_values.reserve(values.size()); for (const auto& val : values) { assign_values.emplace_back(val.to()); } paddle::framework::TensorFromVector(assign_values, dev_ctx, out); // use the array to replace to vector bool* array_ptr = new T[assign_values.size()]; for (unsigned int i = 0; i < assign_values.size(); i++) { array_ptr[i] = static_cast(assign_values[i]); } paddle::framework::TensorFromArray( array_ptr, assign_values.size(), dev_ctx, out); delete[] array_ptr; } template typename std::enable_if::value>::type CopyVectorToTensor( const Context& dev_ctx, const std::vector& values, DenseTensor* out) { std::vector assign_values; assign_values.reserve(values.size()); for (const auto& val : values) { assign_values.emplace_back(val.to()); } paddle::framework::TensorFromVector(assign_values, dev_ctx, out); } template void AssignValueKernel(const Context& dev_ctx, const std::vector& shape, DataType dtype, const std::vector& values, DenseTensor* out) { auto template_dtype = paddle::experimental::CppTypeToDataType::Type(); PADDLE_ENFORCE_EQ( dtype, template_dtype, phi::errors::InvalidArgument("Argument dtype mismatch for kernel dtype, " "argument dtype is %s, kernel dtype is %s.", dtype, template_dtype)); CopyVectorToTensor(dev_ctx, values, out); out->Resize(phi::make_ddim(shape)); } } // namespace phi PD_REGISTER_GENERAL_KERNEL( assign, CPU, ALL_LAYOUT, phi::AssignKernel, ALL_DTYPE) {} PD_REGISTER_GENERAL_KERNEL(assign_raw, CPU, ALL_LAYOUT, phi::AssignRawKernel, ALL_DTYPE) { kernel->InputAt(0).SetBackend(phi::Backend::ALL_BACKEND); } PD_REGISTER_GENERAL_KERNEL(assign_array, CPU, ALL_LAYOUT, phi::AssignArrayKernel, ALL_DTYPE) {} PD_REGISTER_KERNEL(assign_value, CPU, ALL_LAYOUT, phi::AssignValueKernel, bool, int, float, int64_t) {} #if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP) PD_REGISTER_GENERAL_KERNEL( assign, GPU, ALL_LAYOUT, phi::AssignKernel, ALL_DTYPE) {} PD_REGISTER_GENERAL_KERNEL(assign_raw, GPU, ALL_LAYOUT, phi::AssignRawKernel, ALL_DTYPE) { kernel->InputAt(0).SetBackend(phi::Backend::ALL_BACKEND); } PD_REGISTER_GENERAL_KERNEL(assign_array, GPU, ALL_LAYOUT, phi::AssignArrayKernel, ALL_DTYPE) {} PD_REGISTER_KERNEL(assign_value, GPU, ALL_LAYOUT, phi::AssignValueKernel, bool, int, float, int64_t) {} #endif