// 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/prior_box_kernel.h" #include "paddle/phi/backends/xpu/enforce_xpu.h" #include "paddle/phi/core/kernel_registry.h" #include "paddle/phi/kernels/full_kernel.h" #include "paddle/phi/kernels/funcs/eigen/common.h" namespace phi { template void PriorBoxKernel(const Context& dev_ctx, const DenseTensor& input, const DenseTensor& image, const std::vector& min_sizes, const std::vector& max_sizes, const std::vector& aspect_ratios, const std::vector& variances, bool flip, bool clip, float step_w, float step_h, float offset, bool min_max_aspect_ratios_order, DenseTensor* out, DenseTensor* var) { if (input.numel() == 0 || image.numel() == 0) { Full(dev_ctx, out->dims(), 0, out); Full(dev_ctx, var->dims(), 0, var); return; } std::vector new_aspect_ratios; ExpandAspectRatios(aspect_ratios, flip, &new_aspect_ratios); T new_step_w = static_cast(step_w); T new_step_h = static_cast(step_h); T new_offset = static_cast(offset); auto img_width = image.dims()[3]; auto img_height = image.dims()[2]; auto feature_width = input.dims()[3]; auto feature_height = input.dims()[2]; T step_width, step_height; if (new_step_w == 0 || new_step_h == 0) { step_width = static_cast(img_width) / feature_width; step_height = static_cast(img_height) / feature_height; } else { step_width = new_step_w; step_height = new_step_h; } int64_t num_priors = new_aspect_ratios.size() * min_sizes.size(); if (max_sizes.size() > 0) { num_priors += max_sizes.size(); } dev_ctx.template Alloc(out); dev_ctx.template Alloc(var); auto boxes_data = out->data(); auto var_data = var->data(); xpu::VectorParam aspect_ratios_param{ new_aspect_ratios.data(), static_cast(new_aspect_ratios.size()), nullptr}; xpu::VectorParam min_sizes_param{ min_sizes.data(), static_cast(min_sizes.size()), nullptr}; xpu::VectorParam max_sizes_param{ max_sizes.data(), static_cast(max_sizes.size()), nullptr}; int ret = xpu::gen_prior_box(dev_ctx.x_context(), boxes_data, aspect_ratios_param, min_sizes_param, max_sizes_param, feature_height, feature_width, img_height, img_width, new_offset, step_height, step_width, clip, min_max_aspect_ratios_order); PADDLE_ENFORCE_XDNN_SUCCESS(ret, "gen_prior_box"); int64_t box_num = feature_height * feature_width * num_priors; int64_t vlen = variances.size(); std::vector var_cpu(vlen * box_num); for (int64_t i = 0; i < box_num; ++i) { std::copy(variances.begin(), variances.end(), var_cpu.begin() + i * vlen); } dev_ctx.Wait(); PADDLE_ENFORCE_XPU_SUCCESS(xpu_memcpy(var_data, var_cpu.data(), var_cpu.size() * sizeof(T), XPUMemcpyKind::XPU_HOST_TO_DEVICE)); } } // namespace phi PD_REGISTER_KERNEL(prior_box, XPU, ALL_LAYOUT, phi::PriorBoxKernel, float) {}