// Copyright © Advanced Micro Devices, Inc., or its affiliates. // SPDX-License-Identifier: MIT #pragma once #include "ConvShapeCase.hpp" #include #include #include #include #include #include #include #include #include // ============================================================================ // Shared infrastructure for backward-data (dgrad) GPU-vs-CPU reference tests. // ============================================================================ namespace gpu_conv_bwd_ref_test { using namespace hipdnn_data_sdk::utilities; using namespace hipdnn_data_sdk::types; using namespace hipdnn_test_sdk::utilities; using namespace hipdnn_gpu_ref; using gpu_conv_ref_test::assertAllClose; using gpu_conv_ref_test::ConvShapeCase; using ConvBwdShapeCase = ConvShapeCase; // Core helper: fills tensors, runs GPU and CPU dgrad, compares results. template void compareGpuVsCpuConvBwd(Tensor& dxCpu, Tensor& dxGpu, Tensor& wTensor, Tensor& dyTensor, const std::vector& strides, const std::vector& dilations, const std::vector& prePadding, const std::vector& postPadding, float tolerance, float fillRange) { const unsigned int seed = 42; dyTensor.fillWithRandomValues( static_cast(-fillRange), static_cast(fillRange), seed); wTensor.fillWithRandomValues( static_cast(-fillRange), static_cast(fillRange), seed + 1); CpuFpReferenceConvolution::dgrad( dxCpu, wTensor, dyTensor, strides, dilations, prePadding, postPadding); GpuFpReferenceConvolution::dgrad( dxGpu, wTensor, dyTensor, strides, dilations, prePadding, postPadding); assertAllClose(dxCpu, dxGpu, tolerance); } // Asymmetric padding with optional layout. template void runGpuVsCpuConvBwd(const std::vector& xDims, const std::vector& wDims, const std::vector& yDims, const std::vector& strides, const std::vector& dilations, const std::vector& prePadding, const std::vector& postPadding, float tolerance, const TensorLayout* layout = nullptr, float fillRange = 1.0f) { auto dxCpu = layout != nullptr ? Tensor(xDims, *layout) : Tensor(xDims); auto dxGpu = layout != nullptr ? Tensor(xDims, *layout) : Tensor(xDims); auto wTensor = Tensor(wDims); auto dyTensor = layout != nullptr ? Tensor(yDims, *layout) : Tensor(yDims); compareGpuVsCpuConvBwd(dxCpu, dxGpu, wTensor, dyTensor, strides, dilations, prePadding, postPadding, tolerance, fillRange); } // ============================================================================ // ConvBwdShapeSuite — parameterized fixture for shape-based GPU-vs-CPU tests // ============================================================================ template class ConvBwdShapeSuite : public ::testing::TestWithParam { protected: static float tolerance(const ConvBwdShapeCase& tc) { constexpr double FILL_RANGE = 1.0; return hipdnn_test_sdk::utilities::conv:: calculateConvDgradTolerance( -FILL_RANGE, FILL_RANGE, -FILL_RANGE, FILL_RANGE, tc.wDims); } void runConvBwdShapeTest() { SKIP_IF_NO_DEVICES(); const auto& tc = GetParam(); auto yDims = tc.computeOutputDims(); runGpuVsCpuConvBwd(tc.xDims, tc.wDims, yDims, tc.strides, tc.dilations, tc.padding, tc.padding, tolerance(tc), tc.layout); } }; } // namespace gpu_conv_bwd_ref_test