From 4acf1ef7016fa1ce3c9ff82f463b4e0041c23fb8 Mon Sep 17 00:00:00 2001 From: ykkk2333 <77383312+ykkk2333@users.noreply.github.com> Date: Tue, 6 Sep 2022 14:33:08 +0800 Subject: [PATCH] migrate unsqueeze kernels to phi, test=kunlun (#45673) --- paddle/fluid/operators/unsqueeze_op_xpu.cc | 62 -------- paddle/fluid/operators/where_op_xpu.cc | 66 -------- .../phi/kernels/cpu/unsqueeze_grad_kernel.cc | 35 ----- paddle/phi/kernels/cpu/unsqueeze_kernel.cc | 51 ------ .../phi/kernels/gpu/unsqueeze_grad_kernel.cu | 36 ----- .../kernels/impl/unsqueeze_grad_kernel_impl.h | 31 ---- .../phi/kernels/impl/unsqueeze_kernel_impl.h | 50 ------ ...eze_kernel.cu => unsqueeze_grad_kernel.cc} | 51 ++++-- paddle/phi/kernels/unsqueeze_kernel.cc | 147 ++++++++++++++++++ paddle/phi/kernels/xpu/where_kernel.cc | 49 ++++++ 10 files changed, 238 insertions(+), 340 deletions(-) delete mode 100644 paddle/fluid/operators/unsqueeze_op_xpu.cc delete mode 100644 paddle/fluid/operators/where_op_xpu.cc delete mode 100644 paddle/phi/kernels/cpu/unsqueeze_grad_kernel.cc delete mode 100644 paddle/phi/kernels/cpu/unsqueeze_kernel.cc delete mode 100644 paddle/phi/kernels/gpu/unsqueeze_grad_kernel.cu delete mode 100644 paddle/phi/kernels/impl/unsqueeze_grad_kernel_impl.h delete mode 100644 paddle/phi/kernels/impl/unsqueeze_kernel_impl.h rename paddle/phi/kernels/{gpu/unsqueeze_kernel.cu => unsqueeze_grad_kernel.cc} (54%) create mode 100644 paddle/phi/kernels/unsqueeze_kernel.cc create mode 100644 paddle/phi/kernels/xpu/where_kernel.cc diff --git a/paddle/fluid/operators/unsqueeze_op_xpu.cc b/paddle/fluid/operators/unsqueeze_op_xpu.cc deleted file mode 100644 index 93006f3688d..00000000000 --- a/paddle/fluid/operators/unsqueeze_op_xpu.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (c) 2019 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/fluid/operators/unsqueeze_op.h" -#ifdef PADDLE_WITH_XPU -namespace ops = paddle::operators; -namespace plat = paddle::platform; - -REGISTER_OP_XPU_KERNEL( - unsqueeze, - ops::UnsqueezeKernel, - ops::UnsqueezeKernel, - ops::UnsqueezeKernel, - ops::UnsqueezeKernel, - ops::UnsqueezeKernel, - ops::UnsqueezeKernel, - ops::UnsqueezeKernel, - ops::UnsqueezeKernel); -REGISTER_OP_XPU_KERNEL( - unsqueeze_grad, - ops::UnsqueezeGradKernel, - ops::UnsqueezeGradKernel, - ops::UnsqueezeGradKernel, - ops::UnsqueezeGradKernel, - ops::UnsqueezeGradKernel, - ops::UnsqueezeGradKernel, - ops::UnsqueezeGradKernel, - ops::UnsqueezeGradKernel); -REGISTER_OP_XPU_KERNEL( - unsqueeze2, - ops::UnsqueezeKernel, - ops::UnsqueezeKernel, - ops::UnsqueezeKernel, - ops::UnsqueezeKernel, - ops::UnsqueezeKernel, - ops::UnsqueezeKernel, - ops::UnsqueezeKernel, - ops::UnsqueezeKernel); -REGISTER_OP_XPU_KERNEL( - unsqueeze2_grad, - ops::Unsqueeze2GradKernel, - ops::Unsqueeze2GradKernel, - ops::Unsqueeze2GradKernel, - ops::Unsqueeze2GradKernel, - ops::Unsqueeze2GradKernel, - ops::Unsqueeze2GradKernel, - ops::Unsqueeze2GradKernel, - ops::Unsqueeze2GradKernel); - -#endif diff --git a/paddle/fluid/operators/where_op_xpu.cc b/paddle/fluid/operators/where_op_xpu.cc deleted file mode 100644 index fbeeacc25a5..00000000000 --- a/paddle/fluid/operators/where_op_xpu.cc +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2020 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. - -#ifdef PADDLE_WITH_XPU - -#include "paddle/fluid/framework/op_registry.h" - -namespace paddle { -namespace operators { - -template -class WhereXPUKernel : public framework::OpKernel { - public: - void Compute(const framework::ExecutionContext& context) const override { - auto* condition = context.Input("Condition"); - auto* X = context.Input("X"); - auto* Y = context.Input("Y"); - auto* out = context.Output("Out"); - - const bool* cond_data = condition->data(); - const T* x_data = X->data(); - const T* y_data = Y->data(); - T* out_data = out->mutable_data(context.GetPlace()); - - auto cond_dims = phi::vectorize(condition->dims()); - auto input_dims = phi::vectorize(X->dims()); - - auto& dev_ctx = context.template device_context(); - int ret = xpu::select(dev_ctx.x_context(), - cond_data, - x_data, - y_data, - out_data, - cond_dims, - input_dims); - PADDLE_ENFORCE_EQ(ret, - XPU_SUCCESS, - platform::errors::External( - "XPU select kernel return wrong value[%d %s]", - ret, - XPUAPIErrorMsg[ret])); - } -}; - -} // namespace operators -} // namespace paddle - -namespace ops = paddle::operators; - -REGISTER_OP_XPU_KERNEL( - where, - ops::WhereXPUKernel, - ops::WhereXPUKernel, - ops::WhereXPUKernel); -#endif diff --git a/paddle/phi/kernels/cpu/unsqueeze_grad_kernel.cc b/paddle/phi/kernels/cpu/unsqueeze_grad_kernel.cc deleted file mode 100644 index 0cbccac4734..00000000000 --- a/paddle/phi/kernels/cpu/unsqueeze_grad_kernel.cc +++ /dev/null @@ -1,35 +0,0 @@ -// 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/unsqueeze_grad_kernel.h" - -#include "paddle/phi/backends/cpu/cpu_context.h" -#include "paddle/phi/core/kernel_registry.h" -#include "paddle/phi/kernels/impl/unsqueeze_grad_kernel_impl.h" - -PD_REGISTER_KERNEL(unsqueeze_grad, - CPU, - ALL_LAYOUT, - phi::UnsqueezeGradKernel, - phi::dtype::bfloat16, - bool, - int, - int16_t, - uint8_t, - int8_t, - int64_t, - phi::dtype::complex, - phi::dtype::complex, - float, - double) {} diff --git a/paddle/phi/kernels/cpu/unsqueeze_kernel.cc b/paddle/phi/kernels/cpu/unsqueeze_kernel.cc deleted file mode 100644 index 612e1a78cc5..00000000000 --- a/paddle/phi/kernels/cpu/unsqueeze_kernel.cc +++ /dev/null @@ -1,51 +0,0 @@ -// 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/unsqueeze_kernel.h" - -#include "paddle/phi/backends/cpu/cpu_context.h" -#include "paddle/phi/core/kernel_registry.h" -#include "paddle/phi/kernels/impl/unsqueeze_kernel_impl.h" - -PD_REGISTER_KERNEL(unsqueeze, - CPU, - ALL_LAYOUT, - phi::UnsqueezeKernel, - float, - double, - phi::dtype::bfloat16, - bool, - int, - int16_t, - uint8_t, - int8_t, - int64_t, - phi::dtype::complex, - phi::dtype::complex) {} - -PD_REGISTER_KERNEL(unsqueeze_with_xshape, - CPU, - ALL_LAYOUT, - phi::UnsqueezeWithXShapeKernel, - float, - double, - phi::dtype::bfloat16, - bool, - int, - int16_t, - uint8_t, - int8_t, - int64_t, - phi::dtype::complex, - phi::dtype::complex) {} diff --git a/paddle/phi/kernels/gpu/unsqueeze_grad_kernel.cu b/paddle/phi/kernels/gpu/unsqueeze_grad_kernel.cu deleted file mode 100644 index 6c3a2066f0f..00000000000 --- a/paddle/phi/kernels/gpu/unsqueeze_grad_kernel.cu +++ /dev/null @@ -1,36 +0,0 @@ -// 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/unsqueeze_grad_kernel.h" - -#include "paddle/phi/backends/gpu/gpu_context.h" -#include "paddle/phi/core/kernel_registry.h" -#include "paddle/phi/kernels/impl/unsqueeze_grad_kernel_impl.h" - -PD_REGISTER_KERNEL(unsqueeze_grad, - GPU, - ALL_LAYOUT, - phi::UnsqueezeGradKernel, - phi::dtype::bfloat16, - phi::dtype::float16, - bool, - int, - int16_t, - uint8_t, - int8_t, - int64_t, - phi::dtype::complex, - phi::dtype::complex, - float, - double) {} diff --git a/paddle/phi/kernels/impl/unsqueeze_grad_kernel_impl.h b/paddle/phi/kernels/impl/unsqueeze_grad_kernel_impl.h deleted file mode 100644 index ff45ec49b7c..00000000000 --- a/paddle/phi/kernels/impl/unsqueeze_grad_kernel_impl.h +++ /dev/null @@ -1,31 +0,0 @@ -// 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. - -#pragma once -#include "paddle/phi/core/dense_tensor.h" -#include "paddle/phi/core/tensor_utils.h" - -namespace phi { -template -void UnsqueezeGradKernel(const Context& dev_ctx, - const DenseTensor& x_shape, - const DenseTensor& dout, - DenseTensor* dx) { - auto xshape_dims = x_shape.dims(); - auto x_dims = phi::slice_ddim(xshape_dims, 1, xshape_dims.size()); - dev_ctx.template Alloc(dx); - phi::Copy(dev_ctx, dout, dev_ctx.GetPlace(), true, dx); - dx->Resize(x_dims); -} -} // namespace phi diff --git a/paddle/phi/kernels/impl/unsqueeze_kernel_impl.h b/paddle/phi/kernels/impl/unsqueeze_kernel_impl.h deleted file mode 100644 index 5bef856d19b..00000000000 --- a/paddle/phi/kernels/impl/unsqueeze_kernel_impl.h +++ /dev/null @@ -1,50 +0,0 @@ -// 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. - -#pragma once -#include "paddle/phi/core/dense_tensor.h" -#include "paddle/phi/core/tensor_utils.h" -#include "paddle/phi/kernels/funcs/unsqueeze.h" - -namespace phi { -template -void UnsqueezeKernel(const Context& dev_ctx, - const DenseTensor& x, - const IntArray& axes, - DenseTensor* out) { - auto x_dims = x.dims(); - auto out_dims = out->dims(); - if (axes.FromTensor()) { - std::vector tmp; - tmp.reserve(axes.GetData().size()); - std::for_each(axes.GetData().begin(), - axes.GetData().end(), - [&tmp](const int64_t& t) { tmp.push_back(t); }); - out_dims = funcs::GetUnsqueezeShape(tmp, x_dims); - } - out->Resize(out_dims); - dev_ctx.template Alloc(out); - phi::Copy(dev_ctx, x, dev_ctx.GetPlace(), false, out); - out->Resize(out_dims); // copy will reset the dims. -} - -template -void UnsqueezeWithXShapeKernel(const Context& dev_ctx, - const DenseTensor& x, - const IntArray& axes, - DenseTensor* out, - DenseTensor* xshape) { - UnsqueezeKernel(dev_ctx, x, axes, out); -} -} // namespace phi diff --git a/paddle/phi/kernels/gpu/unsqueeze_kernel.cu b/paddle/phi/kernels/unsqueeze_grad_kernel.cc similarity index 54% rename from paddle/phi/kernels/gpu/unsqueeze_kernel.cu rename to paddle/phi/kernels/unsqueeze_grad_kernel.cc index 2e7bae8666d..3c119db2c73 100644 --- a/paddle/phi/kernels/gpu/unsqueeze_kernel.cu +++ b/paddle/phi/kernels/unsqueeze_grad_kernel.cc @@ -12,19 +12,33 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "paddle/phi/kernels/unsqueeze_kernel.h" +#include "paddle/phi/kernels/unsqueeze_grad_kernel.h" -#include "paddle/phi/backends/gpu/gpu_context.h" +#include "paddle/phi/backends/all_context.h" #include "paddle/phi/core/kernel_registry.h" -#include "paddle/phi/kernels/impl/unsqueeze_kernel_impl.h" +#include "paddle/phi/core/tensor_utils.h" +#include "paddle/phi/kernels/funcs/unsqueeze.h" -PD_REGISTER_KERNEL(unsqueeze, - GPU, +namespace phi { +template +void UnsqueezeGradKernel(const Context& dev_ctx, + const DenseTensor& x_shape, + const DenseTensor& dout, + DenseTensor* dx) { + auto xshape_dims = x_shape.dims(); + auto x_dims = phi::slice_ddim(xshape_dims, 1, xshape_dims.size()); + dev_ctx.template Alloc(dx); + phi::Copy(dev_ctx, dout, dev_ctx.GetPlace(), true, dx); + dx->Resize(x_dims); +} +} // namespace phi + +PD_REGISTER_KERNEL(unsqueeze_grad, + CPU, ALL_LAYOUT, - phi::UnsqueezeKernel, + phi::UnsqueezeGradKernel, float, double, - phi::dtype::float16, phi::dtype::bfloat16, bool, int, @@ -35,10 +49,11 @@ PD_REGISTER_KERNEL(unsqueeze, phi::dtype::complex, phi::dtype::complex) {} -PD_REGISTER_KERNEL(unsqueeze_with_xshape, +#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP) +PD_REGISTER_KERNEL(unsqueeze_grad, GPU, ALL_LAYOUT, - phi::UnsqueezeWithXShapeKernel, + phi::UnsqueezeGradKernel, float, double, phi::dtype::float16, @@ -51,3 +66,21 @@ PD_REGISTER_KERNEL(unsqueeze_with_xshape, int64_t, phi::dtype::complex, phi::dtype::complex) {} + +#endif + +#ifdef PADDLE_WITH_XPU +PD_REGISTER_KERNEL(unsqueeze_grad, + XPU, + ALL_LAYOUT, + phi::UnsqueezeGradKernel, + float, + double, + phi::dtype::float16, + bool, + int, + uint8_t, + int8_t, + int64_t) {} + +#endif diff --git a/paddle/phi/kernels/unsqueeze_kernel.cc b/paddle/phi/kernels/unsqueeze_kernel.cc new file mode 100644 index 00000000000..1887c5abf7a --- /dev/null +++ b/paddle/phi/kernels/unsqueeze_kernel.cc @@ -0,0 +1,147 @@ +// 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/unsqueeze_kernel.h" + +#include "paddle/phi/backends/all_context.h" +#include "paddle/phi/core/kernel_registry.h" +#include "paddle/phi/core/tensor_utils.h" +#include "paddle/phi/kernels/funcs/unsqueeze.h" + +namespace phi { +template +void UnsqueezeKernel(const Context& dev_ctx, + const DenseTensor& x, + const IntArray& axes, + DenseTensor* out) { + auto x_dims = x.dims(); + auto out_dims = out->dims(); + if (axes.FromTensor()) { + std::vector tmp; + tmp.reserve(axes.GetData().size()); + std::for_each(axes.GetData().begin(), + axes.GetData().end(), + [&tmp](const int64_t& t) { tmp.push_back(t); }); + out_dims = funcs::GetUnsqueezeShape(tmp, x_dims); + } + out->Resize(out_dims); + dev_ctx.template Alloc(out); + phi::Copy(dev_ctx, x, dev_ctx.GetPlace(), false, out); + out->Resize(out_dims); // copy will reset the dims. +} + +template +void UnsqueezeWithXShapeKernel(const Context& dev_ctx, + const DenseTensor& x, + const IntArray& axes, + DenseTensor* out, + DenseTensor* xshape) { + UnsqueezeKernel(dev_ctx, x, axes, out); +} +} // namespace phi + +PD_REGISTER_KERNEL(unsqueeze, + CPU, + ALL_LAYOUT, + phi::UnsqueezeKernel, + float, + double, + phi::dtype::bfloat16, + bool, + int, + int16_t, + uint8_t, + int8_t, + int64_t, + phi::dtype::complex, + phi::dtype::complex) {} + +PD_REGISTER_KERNEL(unsqueeze_with_xshape, + CPU, + ALL_LAYOUT, + phi::UnsqueezeWithXShapeKernel, + float, + double, + phi::dtype::bfloat16, + bool, + int, + int16_t, + uint8_t, + int8_t, + int64_t, + phi::dtype::complex, + phi::dtype::complex) {} +#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP) +PD_REGISTER_KERNEL(unsqueeze, + GPU, + ALL_LAYOUT, + phi::UnsqueezeKernel, + float, + double, + phi::dtype::float16, + phi::dtype::bfloat16, + bool, + int, + int16_t, + uint8_t, + int8_t, + int64_t, + phi::dtype::complex, + phi::dtype::complex) {} + +PD_REGISTER_KERNEL(unsqueeze_with_xshape, + GPU, + ALL_LAYOUT, + phi::UnsqueezeWithXShapeKernel, + float, + double, + phi::dtype::float16, + phi::dtype::bfloat16, + bool, + int, + int16_t, + uint8_t, + int8_t, + int64_t, + phi::dtype::complex, + phi::dtype::complex) {} +#endif + +#ifdef PADDLE_WITH_XPU +PD_REGISTER_KERNEL(unsqueeze, + XPU, + ALL_LAYOUT, + phi::UnsqueezeKernel, + float, + double, + phi::dtype::float16, + bool, + int, + uint8_t, + int8_t, + int64_t) {} + +PD_REGISTER_KERNEL(unsqueeze_with_xshape, + XPU, + ALL_LAYOUT, + phi::UnsqueezeWithXShapeKernel, + float, + double, + phi::dtype::float16, + bool, + int, + uint8_t, + int8_t, + int64_t) {} +#endif diff --git a/paddle/phi/kernels/xpu/where_kernel.cc b/paddle/phi/kernels/xpu/where_kernel.cc new file mode 100644 index 00000000000..59650a9e896 --- /dev/null +++ b/paddle/phi/kernels/xpu/where_kernel.cc @@ -0,0 +1,49 @@ +// 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/where_kernel.h" + +#include "paddle/phi/backends/xpu/enforce_xpu.h" +#include "paddle/phi/core/kernel_registry.h" + +namespace phi { + +template +void WhereKernel(const Context& ctx, + const DenseTensor& condition, + const DenseTensor& x, + const DenseTensor& y, + DenseTensor* out) { + const bool* cond_data = condition.data(); + const T* x_data = x.data(); + const T* y_data = y.data(); + T* out_data = ctx.template Alloc(out); + + auto cond_dims = phi::vectorize(condition.dims()); + auto input_dims = phi::vectorize(x.dims()); + + int ret = xpu::select(ctx.x_context(), + cond_data, + x_data, + y_data, + out_data, + cond_dims, + input_dims); + PADDLE_ENFORCE_XDNN_SUCCESS(ret, "select"); +} + +} // namespace phi + +PD_REGISTER_KERNEL( + where, XPU, ALL_LAYOUT, phi::WhereKernel, float, int, int64_t) {} -- GitLab