co-authored by
Aniket Shivam
parent
ca23ff7924
commit
b72cbf957d
@@ -110,6 +110,7 @@ cutlass_test_unit_add_executable(
|
||||
|
||||
# F16
|
||||
conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_simt_f16_sm60.cu
|
||||
depthwise_fprop_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_simt_f16_sm60.cu
|
||||
)
|
||||
|
||||
if (CUTLASS_NVCC_MAX_ARCH GREATER_EQUAL 80)
|
||||
@@ -177,12 +178,16 @@ if (CUTLASS_NVCC_MAX_ARCH GREATER_EQUAL 80)
|
||||
# Conv2d (small channel count specializations)
|
||||
conv2d_fprop_fixed_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.cu
|
||||
conv2d_fprop_few_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.cu
|
||||
|
||||
|
||||
# Conv2d (Strided Dgrad)
|
||||
conv2d_strided_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.cu
|
||||
conv2d_strided_dgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.cu
|
||||
|
||||
# Conv3d
|
||||
conv3d_wgrad_implicit_gemm_f16ndhwc_f16ndhwc_f32ndhwc_tensor_op_f32_sm80.cu
|
||||
|
||||
# Group Conv2d
|
||||
group_conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.cu
|
||||
)
|
||||
|
||||
# Conv - TF32 input, F32 output, F32 accumulation
|
||||
|
||||
+2
-2
@@ -109,7 +109,7 @@ std::vector<cutlass::conv::Conv2dProblemSize> Conv2dFewChannelProblemSizes(int c
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#if 0
|
||||
|
||||
TEST(SM80_Device_Conv2d_Fprop_Few_Channels_ImplicitGemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_channels_8,
|
||||
128x128_64x3_64x64x64) {
|
||||
|
||||
@@ -201,7 +201,7 @@ TEST(SM80_Device_Conv2d_Fprop_Few_Channels_ImplicitGemm_f16nhwc_f16nhwc_f16nhwc_
|
||||
EXPECT_TRUE(test::conv::device::TestSpecificConv2d<Conv2dFprop>(
|
||||
Conv2dFewChannelProblemSizes(kChannelCount)));
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST(SM80_Device_Conv2d_Fprop_Few_Channels_ImplicitGemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_channels_2,
|
||||
|
||||
@@ -684,6 +684,154 @@ struct TestbedConv2dProblemSizes {
|
||||
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
/// Structure TestbedGroupConv2dProblemSizes initializes and holds group conv default and
|
||||
/// important network sizes
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
struct TestbedGroupConv2dProblemSizes {
|
||||
|
||||
//
|
||||
// Data members
|
||||
//
|
||||
int threadblock_n;
|
||||
int threadblock_k;
|
||||
int minimum_channel_size;
|
||||
|
||||
Conv2dProblemVector default_single_group_sizes;
|
||||
Conv2dProblemVector default_multiple_group_sizes;
|
||||
|
||||
//
|
||||
// Methods
|
||||
//
|
||||
/// Default ctor
|
||||
TestbedGroupConv2dProblemSizes(
|
||||
int threadblock_n_,
|
||||
int threadblock_k_,
|
||||
int minimum_channel_size_ = 64)
|
||||
: threadblock_n (threadblock_n_),
|
||||
threadblock_k (threadblock_k_),
|
||||
minimum_channel_size (minimum_channel_size_) {
|
||||
initialize_group_conv2d_default_sizes();
|
||||
filter_all();
|
||||
}
|
||||
|
||||
/// Eliminates some illegal cases
|
||||
void filter_all() {
|
||||
|
||||
Conv2dProblemVector *problems_vectors[] = {
|
||||
&default_single_group_sizes,
|
||||
&default_multiple_group_sizes
|
||||
};
|
||||
|
||||
for (Conv2dProblemVector *problems : problems_vectors) {
|
||||
Conv2dProblemVector filtered;
|
||||
|
||||
for (cutlass::conv::Conv2dProblemSize const & problem : *problems) {
|
||||
if (!((problem.C / problem.groups) % minimum_channel_size)) {
|
||||
filtered.push_back(problem);
|
||||
}
|
||||
}
|
||||
|
||||
*problems = filtered;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a few standard convolution problem sizes
|
||||
void initialize_group_conv2d_default_sizes() {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// One group calculated by one or multiple CTAs: k_per_group % CTA::N = 0
|
||||
// One CTA calculates a single group
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
for (int cta_per_group_k = 1; cta_per_group_k < 4; ++cta_per_group_k) {
|
||||
// groups = 2, 3, 4
|
||||
for (int groups = 2; groups < 5; ++groups) {
|
||||
|
||||
int conv_k = cta_per_group_k * threadblock_n * groups;
|
||||
default_single_group_sizes.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 8, 8, threadblock_k * 2 * groups}, // input size (NHWC)
|
||||
{conv_k, 3, 3, threadblock_k * 2}, // filter size (KRSC)
|
||||
{1, 1, 1, 1}, // padding (pad_h, _, pad_w, _)
|
||||
{1, 1}, // stride (stride_h, stride_w)
|
||||
{1, 1}, // dilation (dilation_h, dilation_w)
|
||||
cutlass::conv::Mode::kCrossCorrelation,
|
||||
1, // split_k_slices
|
||||
groups // groups
|
||||
));
|
||||
|
||||
} // loop groups
|
||||
} // loop cta_per_group_k
|
||||
|
||||
// Partial gemm_k: k_per_group == CTA::N && channels_per_group < CTA::K
|
||||
default_single_group_sizes.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 8, 8, threadblock_k}, // input size (NHWC)
|
||||
{threadblock_n * 2, 3, 3, threadblock_k / 2}, // filter size (KRSC)
|
||||
{1, 1, 1, 1}, // padding (pad_h, _, pad_w, _)
|
||||
{1, 1}, // stride (stride_h, stride_w)
|
||||
{1, 1}, // dilation (dilation_h, dilation_w)
|
||||
cutlass::conv::Mode::kCrossCorrelation,
|
||||
1, // split_k_slices
|
||||
2 // groups
|
||||
));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// One CTA calculate multiple groups: CTA::N % k_per_group = 0
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 2 groups per CTA
|
||||
default_multiple_group_sizes.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 8, 8, threadblock_k * 4}, // input size (NHWC)
|
||||
{threadblock_n, 3, 3, threadblock_k * 2}, // filter size (KRSC)
|
||||
{1, 1, 1, 1}, // padding (pad_h, _, pad_w, _)
|
||||
{1, 1}, // stride (stride_h, stride_w)
|
||||
{1, 1}, // dilation (dilation_h, dilation_w)
|
||||
cutlass::conv::Mode::kCrossCorrelation,
|
||||
1, // split_k_slices
|
||||
2 // groups
|
||||
));
|
||||
|
||||
// 2 groups per CTA and partial gemm_k
|
||||
default_multiple_group_sizes.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 8, 8, threadblock_k}, // input size (NHWC)
|
||||
{threadblock_n, 3, 3, threadblock_k / 2}, // filter size (KRSC)
|
||||
{1, 1, 1, 1}, // padding (pad_h, _, pad_w, _)
|
||||
{1, 1}, // stride (stride_h, stride_w)
|
||||
{1, 1}, // dilation (dilation_h, dilation_w)
|
||||
cutlass::conv::Mode::kCrossCorrelation,
|
||||
1, // split_k_slices
|
||||
2 // groups
|
||||
));
|
||||
|
||||
// 4 groups per CTA
|
||||
default_multiple_group_sizes.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 8, 8, threadblock_k * 8}, // input size (NHWC)
|
||||
{threadblock_n / 2, 3, 3, threadblock_k * 2}, // filter size (KRSC)
|
||||
{1, 1, 1, 1}, // padding (pad_h, _, pad_w, _)
|
||||
{1, 1}, // stride (stride_h, stride_w)
|
||||
{1, 1}, // dilation (dilation_h, dilation_w)
|
||||
cutlass::conv::Mode::kCrossCorrelation,
|
||||
1, // split_k_slices
|
||||
4 // groups
|
||||
));
|
||||
|
||||
// 4 groups per CTA and partial gemm_k
|
||||
default_multiple_group_sizes.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 8, 8, threadblock_k * 2}, // input size (NHWC)
|
||||
{threadblock_n / 2, 3, 3, threadblock_k / 2}, // filter size (KRSC)
|
||||
{1, 1, 1, 1}, // padding (pad_h, _, pad_w, _)
|
||||
{1, 1}, // stride (stride_h, stride_w)
|
||||
{1, 1}, // dilation (dilation_h, dilation_w)
|
||||
cutlass::conv::Mode::kCrossCorrelation,
|
||||
1, // split_k_slices
|
||||
4 // groups
|
||||
));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace device
|
||||
} // namespace conv
|
||||
} // namespace test
|
||||
|
||||
+2
-5
@@ -85,7 +85,7 @@ TEST(SM80_Device_Conv2d_Strided_Dgrad_Analytic_ImplicitGemm_f16nhwc_f16nhwc_f32n
|
||||
test::conv::device::Conv2dProblemVector problem_size_list;
|
||||
|
||||
|
||||
#if 0 // run specific problem size in the unit test first
|
||||
// run specific problem size in the unit test first
|
||||
problem_size_list.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 4, 4, 8}, // input size (NHWC)
|
||||
{8, 3, 3, 8}, // filter size (KRSC)
|
||||
@@ -93,7 +93,6 @@ TEST(SM80_Device_Conv2d_Strided_Dgrad_Analytic_ImplicitGemm_f16nhwc_f16nhwc_f32n
|
||||
{3, 3}, // stride (stride_h, stride_w)
|
||||
{1, 1} // dilation (dilation_h, dilation_w)
|
||||
));
|
||||
#endif
|
||||
|
||||
/// Run all unit test sizes with device-level Conv2d instance
|
||||
EXPECT_TRUE(test::conv::device::TestAllConv2d<Conv2dDgrad>(problem_size_list));
|
||||
@@ -281,7 +280,7 @@ TEST(SM80_Device_Conv2d_Strided_Dgrad_Optimized_ImplicitGemm_f16nhwc_f16nhwc_f32
|
||||
|
||||
test::conv::device::Conv2dProblemVector problem_size_list;
|
||||
|
||||
#if 0 // run specific problem size in the unit test first
|
||||
// run specific problem size in the unit test first
|
||||
problem_size_list.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 56, 56, 8}, // input size (NHWC)
|
||||
{8, 1, 1, 8}, // filter size (KRSC)
|
||||
@@ -298,8 +297,6 @@ TEST(SM80_Device_Conv2d_Strided_Dgrad_Optimized_ImplicitGemm_f16nhwc_f16nhwc_f32
|
||||
{1, 1} // dilation (dilation_h, dilation_w)
|
||||
));
|
||||
|
||||
#endif
|
||||
|
||||
/// Run all unit test sizes with device-level Conv2d instance
|
||||
EXPECT_TRUE(test::conv::device::TestAllConv2d<Conv2dDgrad>(problem_size_list));
|
||||
}
|
||||
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/***************************************************************************************************
|
||||
* Copyright (c) 2017 - 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
**************************************************************************************************/
|
||||
/*! \file
|
||||
\brief Tests for device-wide Implicit GEMM interface
|
||||
*/
|
||||
|
||||
#include "../../common/cutlass_unit_test.h"
|
||||
#include "cutlass/cutlass.h"
|
||||
|
||||
#include "cutlass/conv/kernel/default_conv2d_dgrad.h"
|
||||
#include "cutlass/conv/device/implicit_gemm_convolution.h"
|
||||
|
||||
#include "conv2d_testbed.h"
|
||||
|
||||
#if defined(CUTLASS_ARCH_MMA_SM80_SUPPORTED)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST(SM80_Device_Conv2d_Strided_Dgrad_Optimized_ImplicitGemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_align4,
|
||||
64x64_32x5_32x32x32) {
|
||||
|
||||
/// Conv operation element types for the Gemm equivalent (ImplicitGemm)
|
||||
using ElementA = cutlass::tfloat32_t;
|
||||
using ElementB = cutlass::tfloat32_t;
|
||||
using ElementC = float;
|
||||
using ElementAccumulator = float;
|
||||
using ElementCompute = float;
|
||||
|
||||
/// Device-level Conv2d instance
|
||||
using Conv2dDgradKernel = typename cutlass::conv::kernel::DefaultConv2dDgrad<
|
||||
ElementA, cutlass::layout::TensorNHWC,
|
||||
ElementB, cutlass::layout::TensorNHWC,
|
||||
ElementC, cutlass::layout::TensorNHWC,
|
||||
ElementAccumulator,
|
||||
cutlass::arch::OpClassTensorOp,
|
||||
cutlass::arch::Sm80,
|
||||
cutlass::gemm::GemmShape<64, 64, 32>,
|
||||
cutlass::gemm::GemmShape<32, 32, 32>,
|
||||
cutlass::gemm::GemmShape<16, 8, 8>,
|
||||
cutlass::epilogue::thread::LinearCombination<
|
||||
ElementC,
|
||||
4,
|
||||
ElementAccumulator,
|
||||
ElementCompute
|
||||
>,
|
||||
cutlass::conv::threadblock::StridedDgradIdentityThreadblockSwizzle<>,
|
||||
5,
|
||||
cutlass::arch::OpMultiplyAdd,
|
||||
cutlass::conv::IteratorAlgorithm::kAnalytic,
|
||||
cutlass::conv::StrideSupport::kStrided,
|
||||
4,
|
||||
4
|
||||
>::Kernel;
|
||||
|
||||
using Conv2dDgrad = cutlass::conv::device::ImplicitGemmConvolution<Conv2dDgradKernel>;
|
||||
|
||||
|
||||
test::conv::device::Conv2dProblemVector problem_size_list;
|
||||
|
||||
// run specific problem size in the unit test first
|
||||
problem_size_list.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 1, 1, 16}, // input size (NHWC)
|
||||
{8, 3, 3, 16}, // filter size (KRSC)
|
||||
{1, 1, 1, 1}, // padding (pad_h, _, pad_w, _)
|
||||
{2, 1}, // stride (stride_h, stride_w)
|
||||
{1, 1} // dilation (dilation_h, dilation_w)
|
||||
));
|
||||
|
||||
// run specific problem size in the unit test first
|
||||
problem_size_list.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 1, 1, 16}, // input size (NHWC)
|
||||
{8, 3, 3, 16}, // filter size (KRSC)
|
||||
{1, 1, 1, 1}, // padding (pad_h, _, pad_w, _)
|
||||
{3, 3}, // stride (stride_h, stride_w)
|
||||
{1, 1} // dilation (dilation_h, dilation_w)
|
||||
));
|
||||
|
||||
/// Run all unit test sizes with device-level Conv2d instance
|
||||
EXPECT_TRUE(test::conv::device::TestAllConv2d<Conv2dDgrad>(problem_size_list));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // CUTLASS_ARCH_MMA_SM80_SUPPORTED
|
||||
@@ -602,7 +602,7 @@ bool TestAllConv2d(
|
||||
conv_test_sizes, // run user specified sizes
|
||||
conv_problems.conv2d_default_sizes, // run default and cudnn bug sizes
|
||||
//conv_problems.conv2d_resnet50_sizes, // run resnet50 sizes
|
||||
#if CUTLASS_CONV_UNIT_TEST_RIGOROUS_SIZE_ENABLED
|
||||
#if CUTLASS_CONV_UNIT_TEST_RIGOROUS_SIZE_ENABLED
|
||||
conv_problems.conv2d_rigorous_sizes, // run large and rigorous sizes if enabled
|
||||
#endif
|
||||
};
|
||||
@@ -716,7 +716,7 @@ bool TestAllConv2d(
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// CUTLASS DGRAD's *strided* specialization does not support split-k mode
|
||||
if ((ImplicitGemm::kConvolutionalOperator ==
|
||||
cutlass::conv::Operator::kDgrad) &&
|
||||
|
||||
+221
@@ -0,0 +1,221 @@
|
||||
/***************************************************************************************************
|
||||
* Copyright (c) 2017 - 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
**************************************************************************************************/
|
||||
/*! \file
|
||||
\brief Tests for device-wide Implicit GEMM interface
|
||||
*/
|
||||
|
||||
#include "../../common/cutlass_unit_test.h"
|
||||
#include "cutlass/cutlass.h"
|
||||
|
||||
|
||||
#include "cutlass/conv/kernel/default_depthwise_fprop.h"
|
||||
#include "cutlass/conv/device/implicit_gemm_convolution.h"
|
||||
|
||||
#include "conv2d_testbed.h"
|
||||
|
||||
|
||||
std::vector<cutlass::conv::Conv2dProblemSize> DepthwiseFpropProblemSizes() {
|
||||
|
||||
std::vector<cutlass::conv::Conv2dProblemSize> problems;
|
||||
|
||||
for ( int channels = 16; channels < 256 ; channels+=16){
|
||||
problems.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 8, 8, channels}, // input size (NHWC)
|
||||
{channels, 3, 3, 1}, // filter size (KRSC)
|
||||
{1, 1, 1, 1}, // padding (pad_h, _, pad_w, _)
|
||||
{2, 2}, // stride (stride_h, stride_w)
|
||||
{1, 1}, // dilation (dilation_h, dilation_w)
|
||||
cutlass::conv::Mode::kCrossCorrelation, // Convolution mode
|
||||
1, // split_k_slices
|
||||
channels // groups
|
||||
));
|
||||
|
||||
problems.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 16, 16, channels}, // input size (NHWC)
|
||||
{channels, 3, 3, 1}, // filter size (KRSC)
|
||||
{1, 1, 1, 1}, // padding (pad_h, _, pad_w, _)
|
||||
{2, 2}, // stride (stride_h, stride_w)
|
||||
{2, 2}, // dilation (dilation_h, dilation_w)
|
||||
cutlass::conv::Mode::kCrossCorrelation, // Convolution mode
|
||||
1, // split_k_slices
|
||||
channels // groups
|
||||
));
|
||||
|
||||
problems.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 16, 16, channels}, // input size (NHWC)
|
||||
{channels, 7, 7, 1}, // filter size (KRSC)
|
||||
{1, 1, 1, 1}, // padding (pad_h, _, pad_w, _)
|
||||
{1, 1}, // stride (stride_h, stride_w)
|
||||
{1, 1}, // dilation (dilation_h, dilation_w)
|
||||
cutlass::conv::Mode::kCrossCorrelation, // Convolution mode
|
||||
1, // split_k_slices
|
||||
channels // groups
|
||||
));
|
||||
|
||||
problems.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 112, 112, channels}, // input size (NHWC)
|
||||
{channels, 7, 7, 1}, // filter size (KRSC)
|
||||
{1, 1, 1, 1}, // padding (pad_h, _, pad_w, _)
|
||||
{1, 1}, // stride (stride_h, stride_w)
|
||||
{1, 1}, // dilation (dilation_h, dilation_w)
|
||||
cutlass::conv::Mode::kCrossCorrelation, // Convolution mode
|
||||
1, // split_k_slices
|
||||
channels // groups
|
||||
));
|
||||
|
||||
problems.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 112, 112, channels}, // input size (NHWC)
|
||||
{channels, 7, 7, 1}, // filter size (KRSC)
|
||||
{1, 1, 1, 1}, // padding (pad_h, _, pad_w, _)
|
||||
{2, 2}, // stride (stride_h, stride_w)
|
||||
{2, 2} , // dilation (dilation_h, dilation_w)
|
||||
cutlass::conv::Mode::kCrossCorrelation, // Convolution mode
|
||||
1, // split_k_slices
|
||||
channels // groups
|
||||
));
|
||||
|
||||
problems.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 112, 112, channels}, // input size (NHWC)
|
||||
{channels, 5, 5, 1}, // filter size (KRSC)
|
||||
{1, 1, 1, 1}, // padding (pad_h, _, pad_w, _)
|
||||
{1, 1}, // stride (stride_h, stride_w)
|
||||
{1, 1}, // dilation (dilation_h, dilation_w)
|
||||
cutlass::conv::Mode::kCrossCorrelation, // Convolution mode
|
||||
1, // split_k_slices
|
||||
channels // groups
|
||||
));
|
||||
|
||||
problems.push_back(cutlass::conv::Conv2dProblemSize(
|
||||
{1, 112, 112, channels}, // input size (NHWC)
|
||||
{channels, 5, 5, 1}, // filter size (KRSC)
|
||||
{1, 1, 1, 1}, // padding (pad_h, _, pad_w, _)
|
||||
{2, 2}, // stride (stride_h, stride_w)
|
||||
{2, 2} , // dilation (dilation_h, dilation_w)
|
||||
cutlass::conv::Mode::kCrossCorrelation, // Convolution mode
|
||||
1, // split_k_slices
|
||||
channels // groups
|
||||
));
|
||||
}
|
||||
|
||||
return problems;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST(SM60_Device_Depthwise_Fprop_Analytic_ImplicitGemm_f16nhwc_f16nhwc_f16nhwc_simt_f16,
|
||||
128x128_8x2_64x64x8) {
|
||||
|
||||
/// Conv operation element types for the Gemm equivalent (ImplicitGemm)
|
||||
using ElementA = cutlass::half_t;
|
||||
using ElementB = cutlass::half_t;
|
||||
using ElementC = cutlass::half_t;
|
||||
using ElementAccumulator = cutlass::half_t;
|
||||
using ElementCompute = cutlass::half_t;
|
||||
|
||||
|
||||
/// Device-level depthwiseFpropKernel instance
|
||||
using depthwiseFpropKernel = typename cutlass::conv::kernel::DefaultDepthwiseFprop<
|
||||
ElementA,
|
||||
cutlass::layout::TensorNHWC,
|
||||
ElementB,
|
||||
cutlass::layout::TensorNHWC,
|
||||
ElementC,
|
||||
cutlass::layout::TensorNHWC,
|
||||
ElementAccumulator,
|
||||
cutlass::arch::OpClassSimt,
|
||||
cutlass::arch::Sm60,
|
||||
cutlass::gemm::GemmShape<128, 128, 8>,
|
||||
cutlass::gemm::GemmShape<64, 64, 8>,
|
||||
cutlass::gemm::GemmShape<1, 1, 1>,
|
||||
cutlass::epilogue::thread::LinearCombination<
|
||||
ElementC,
|
||||
1,
|
||||
ElementAccumulator,
|
||||
ElementCompute
|
||||
>,
|
||||
cutlass::gemm::threadblock::GemmIdentityThreadblockSwizzle<>,
|
||||
2,
|
||||
cutlass::arch::OpMultiplyAdd,
|
||||
cutlass::conv::IteratorAlgorithm::kAnalytic
|
||||
>::Kernel;
|
||||
|
||||
using DepthwiseFprop = cutlass::conv::device::ImplicitGemmConvolution<depthwiseFpropKernel>;
|
||||
|
||||
/// Run all unit test sizes with device-level Conv2d instance
|
||||
EXPECT_TRUE(test::conv::device::TestSpecificConv2d<DepthwiseFprop>(
|
||||
DepthwiseFpropProblemSizes()));
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TEST(SM60_Device_Depthwise_Fprop_Analytic_ImplicitGemm_f16nhwc_f16nhwc_f16nhwc_simt_f16,
|
||||
64x64_8x2_32x32x8) {
|
||||
|
||||
/// Conv operation element types for the Gemm equivalent (ImplicitGemm)
|
||||
using ElementA = cutlass::half_t;
|
||||
using ElementB = cutlass::half_t;
|
||||
using ElementC = cutlass::half_t;
|
||||
using ElementAccumulator = cutlass::half_t;
|
||||
using ElementCompute = cutlass::half_t;
|
||||
|
||||
|
||||
/// Device-level depthwiseFpropKernel instance
|
||||
using depthwiseFpropKernel = typename cutlass::conv::kernel::DefaultDepthwiseFprop<
|
||||
ElementA,
|
||||
cutlass::layout::TensorNHWC,
|
||||
ElementB,
|
||||
cutlass::layout::TensorNHWC,
|
||||
ElementC,
|
||||
cutlass::layout::TensorNHWC,
|
||||
ElementAccumulator,
|
||||
cutlass::arch::OpClassSimt,
|
||||
cutlass::arch::Sm60,
|
||||
cutlass::gemm::GemmShape<64, 64, 8>,
|
||||
cutlass::gemm::GemmShape<32, 32, 8>,
|
||||
cutlass::gemm::GemmShape<1, 1, 1>,
|
||||
cutlass::epilogue::thread::LinearCombination<
|
||||
ElementC,
|
||||
1,
|
||||
ElementAccumulator,
|
||||
ElementCompute
|
||||
>,
|
||||
cutlass::gemm::threadblock::GemmIdentityThreadblockSwizzle<>,
|
||||
2,
|
||||
cutlass::arch::OpMultiplyAdd,
|
||||
cutlass::conv::IteratorAlgorithm::kAnalytic
|
||||
>::Kernel;
|
||||
|
||||
using DepthwiseFprop = cutlass::conv::device::ImplicitGemmConvolution<depthwiseFpropKernel>;
|
||||
|
||||
/// Run all unit test sizes with device-level Conv2d instance
|
||||
EXPECT_TRUE(test::conv::device::TestSpecificConv2d<DepthwiseFprop>(
|
||||
DepthwiseFpropProblemSizes()));
|
||||
|
||||
}
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
/***************************************************************************************************
|
||||
* Copyright (c) 2017 - 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
**************************************************************************************************/
|
||||
/*! \file
|
||||
\brief Tests for device-wide Implicit GEMM interface
|
||||
*/
|
||||
|
||||
#include "../../common/cutlass_unit_test.h"
|
||||
#include "cutlass/cutlass.h"
|
||||
|
||||
|
||||
#include "cutlass/conv/kernel/default_conv2d_group_fprop.h"
|
||||
#include "cutlass/conv/device/implicit_gemm_convolution.h"
|
||||
|
||||
#include "conv2d_testbed.h"
|
||||
|
||||
#if defined(CUTLASS_ARCH_MMA_SM80_SUPPORTED)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST(SM80_Device_Conv2d_Group_Fprop_Analytic_ImplicitGemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32,
|
||||
SingleGroupPerCTA_128x128_64x3_64x64x64) {
|
||||
|
||||
/// Conv operation element types for the Gemm equivalent (ImplicitGemm)
|
||||
using ElementA = cutlass::half_t;
|
||||
using ElementB = cutlass::half_t;
|
||||
using ElementC = cutlass::half_t;
|
||||
using ElementAccumulator = float;
|
||||
using ElementCompute = float;
|
||||
using ThreadblockShape = cutlass::gemm::GemmShape<128, 128, 64>;
|
||||
using WarpShape = cutlass::gemm::GemmShape<64, 64, 64>;
|
||||
using InstructionShape = cutlass::gemm::GemmShape<16, 8, 16>;
|
||||
|
||||
/// Device-level Conv2d instance
|
||||
using Conv2dGroupFpropKernel = typename cutlass::conv::kernel::DefaultConv2dGroupFprop<
|
||||
ElementA, cutlass::layout::TensorNHWC,
|
||||
ElementB, cutlass::layout::TensorNHWC,
|
||||
ElementC, cutlass::layout::TensorNHWC,
|
||||
ElementAccumulator,
|
||||
cutlass::arch::OpClassTensorOp,
|
||||
cutlass::arch::Sm80,
|
||||
ThreadblockShape,
|
||||
WarpShape,
|
||||
InstructionShape,
|
||||
cutlass::epilogue::thread::LinearCombination<
|
||||
ElementC,
|
||||
128 / cutlass::sizeof_bits<ElementC>::value,
|
||||
ElementAccumulator,
|
||||
ElementCompute
|
||||
>,
|
||||
cutlass::gemm::threadblock::GemmIdentityThreadblockSwizzle<>,
|
||||
3,
|
||||
cutlass::arch::OpMultiplyAdd,
|
||||
cutlass::conv::GroupMode::kSingleGroup,
|
||||
cutlass::conv::IteratorAlgorithm::kAnalytic
|
||||
>::Kernel;
|
||||
|
||||
using Conv2dGroupFprop = cutlass::conv::device::ImplicitGemmConvolution<Conv2dGroupFpropKernel>;
|
||||
|
||||
/// Run group conv unit test sizes with device-level Conv2d instance
|
||||
test::conv::device::TestbedGroupConv2dProblemSizes problem_sizes(
|
||||
ThreadblockShape::kN, ThreadblockShape::kK,
|
||||
128/cutlass::sizeof_bits<ElementA>::value
|
||||
);
|
||||
EXPECT_TRUE(test::conv::device::TestSpecificConv2d<Conv2dGroupFprop>(problem_sizes.default_single_group_sizes));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST(SM80_Device_Conv2d_Group_Fprop_Analytic_ImplicitGemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32,
|
||||
SingleGroupPerCTA_64x64_64x3_32x32x64) {
|
||||
|
||||
/// Conv operation element types for the Gemm equivalent (ImplicitGemm)
|
||||
using ElementA = cutlass::half_t;
|
||||
using ElementB = cutlass::half_t;
|
||||
using ElementC = cutlass::half_t;
|
||||
using ElementAccumulator = float;
|
||||
using ElementCompute = float;
|
||||
using ThreadblockShape = cutlass::gemm::GemmShape<64, 64, 64>;
|
||||
using WarpShape = cutlass::gemm::GemmShape<32, 32, 64>;
|
||||
using InstructionShape = cutlass::gemm::GemmShape<16, 8, 16>;
|
||||
|
||||
/// Device-level Conv2d instance
|
||||
using Conv2dGroupFpropKernel = typename cutlass::conv::kernel::DefaultConv2dGroupFprop<
|
||||
ElementA, cutlass::layout::TensorNHWC,
|
||||
ElementB, cutlass::layout::TensorNHWC,
|
||||
ElementC, cutlass::layout::TensorNHWC,
|
||||
ElementAccumulator,
|
||||
cutlass::arch::OpClassTensorOp,
|
||||
cutlass::arch::Sm80,
|
||||
ThreadblockShape,
|
||||
WarpShape,
|
||||
InstructionShape,
|
||||
cutlass::epilogue::thread::LinearCombination<
|
||||
ElementC,
|
||||
128 / cutlass::sizeof_bits<ElementC>::value,
|
||||
ElementAccumulator,
|
||||
ElementCompute
|
||||
>,
|
||||
cutlass::gemm::threadblock::GemmIdentityThreadblockSwizzle<>,
|
||||
3,
|
||||
cutlass::arch::OpMultiplyAdd,
|
||||
cutlass::conv::GroupMode::kSingleGroup,
|
||||
cutlass::conv::IteratorAlgorithm::kAnalytic
|
||||
>::Kernel;
|
||||
|
||||
using Conv2dGroupFprop = cutlass::conv::device::ImplicitGemmConvolution<Conv2dGroupFpropKernel>;
|
||||
|
||||
/// Run group conv unit test sizes with device-level Conv2d instance
|
||||
test::conv::device::TestbedGroupConv2dProblemSizes problem_sizes(
|
||||
ThreadblockShape::kN, ThreadblockShape::kK,
|
||||
128/cutlass::sizeof_bits<ElementA>::value
|
||||
);
|
||||
EXPECT_TRUE(test::conv::device::TestSpecificConv2d<Conv2dGroupFprop>(problem_sizes.default_single_group_sizes));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST(SM80_Device_Conv2d_Group_Fprop_Analytic_ImplicitGemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32,
|
||||
MultipleGroupPerCTA_128x128_64x3_64x64x64) {
|
||||
|
||||
/// Conv operation element types for the Gemm equivalent (ImplicitGemm)
|
||||
using ElementA = cutlass::half_t;
|
||||
using ElementB = cutlass::half_t;
|
||||
using ElementC = cutlass::half_t;
|
||||
using ElementAccumulator = float;
|
||||
using ElementCompute = float;
|
||||
using ThreadblockShape = cutlass::gemm::GemmShape<128, 128, 64>;
|
||||
using WarpShape = cutlass::gemm::GemmShape<64, 64, 64>;
|
||||
using InstructionShape = cutlass::gemm::GemmShape<16, 8, 16>;
|
||||
|
||||
/// Device-level Conv2d instance
|
||||
using Conv2dGroupFpropKernel = typename cutlass::conv::kernel::DefaultConv2dGroupFprop<
|
||||
ElementA, cutlass::layout::TensorNHWC,
|
||||
ElementB, cutlass::layout::TensorNHWC,
|
||||
ElementC, cutlass::layout::TensorNHWC,
|
||||
ElementAccumulator,
|
||||
cutlass::arch::OpClassTensorOp,
|
||||
cutlass::arch::Sm80,
|
||||
ThreadblockShape,
|
||||
WarpShape,
|
||||
InstructionShape,
|
||||
cutlass::epilogue::thread::LinearCombination<
|
||||
ElementC,
|
||||
128 / cutlass::sizeof_bits<ElementC>::value,
|
||||
ElementAccumulator,
|
||||
ElementCompute
|
||||
>,
|
||||
cutlass::gemm::threadblock::GemmIdentityThreadblockSwizzle<>,
|
||||
3,
|
||||
cutlass::arch::OpMultiplyAdd,
|
||||
cutlass::conv::GroupMode::kMultipleGroup,
|
||||
cutlass::conv::IteratorAlgorithm::kAnalytic
|
||||
>::Kernel;
|
||||
|
||||
using Conv2dGroupFprop = cutlass::conv::device::ImplicitGemmConvolution<Conv2dGroupFpropKernel>;
|
||||
|
||||
/// Run group conv unit test sizes with device-level Conv2d instance
|
||||
test::conv::device::TestbedGroupConv2dProblemSizes problem_sizes(
|
||||
ThreadblockShape::kN, ThreadblockShape::kK,
|
||||
128/cutlass::sizeof_bits<ElementA>::value
|
||||
);
|
||||
EXPECT_TRUE(test::conv::device::TestSpecificConv2d<Conv2dGroupFprop>(problem_sizes.default_multiple_group_sizes));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST(SM80_Device_Conv2d_Group_Fprop_Analytic_ImplicitGemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32,
|
||||
MutipleGroupPerCTA_64x64_64x3_32x32x64) {
|
||||
|
||||
/// Conv operation element types for the Gemm equivalent (ImplicitGemm)
|
||||
using ElementA = cutlass::half_t;
|
||||
using ElementB = cutlass::half_t;
|
||||
using ElementC = cutlass::half_t;
|
||||
using ElementAccumulator = float;
|
||||
using ElementCompute = float;
|
||||
using ThreadblockShape = cutlass::gemm::GemmShape<64, 64, 64>;
|
||||
using WarpShape = cutlass::gemm::GemmShape<32, 32, 64>;
|
||||
using InstructionShape = cutlass::gemm::GemmShape<16, 8, 16>;
|
||||
|
||||
/// Device-level Conv2d instance
|
||||
using Conv2dGroupFpropKernel = typename cutlass::conv::kernel::DefaultConv2dGroupFprop<
|
||||
ElementA, cutlass::layout::TensorNHWC,
|
||||
ElementB, cutlass::layout::TensorNHWC,
|
||||
ElementC, cutlass::layout::TensorNHWC,
|
||||
ElementAccumulator,
|
||||
cutlass::arch::OpClassTensorOp,
|
||||
cutlass::arch::Sm80,
|
||||
ThreadblockShape,
|
||||
WarpShape,
|
||||
InstructionShape,
|
||||
cutlass::epilogue::thread::LinearCombination<
|
||||
ElementC,
|
||||
128 / cutlass::sizeof_bits<ElementC>::value,
|
||||
ElementAccumulator,
|
||||
ElementCompute
|
||||
>,
|
||||
cutlass::gemm::threadblock::GemmIdentityThreadblockSwizzle<>,
|
||||
3,
|
||||
cutlass::arch::OpMultiplyAdd,
|
||||
cutlass::conv::GroupMode::kMultipleGroup,
|
||||
cutlass::conv::IteratorAlgorithm::kAnalytic
|
||||
>::Kernel;
|
||||
|
||||
using Conv2dGroupFprop = cutlass::conv::device::ImplicitGemmConvolution<Conv2dGroupFpropKernel>;
|
||||
|
||||
/// Run group conv unit test sizes with device-level Conv2d instance
|
||||
test::conv::device::TestbedGroupConv2dProblemSizes problem_sizes(
|
||||
ThreadblockShape::kN, ThreadblockShape::kK,
|
||||
128/cutlass::sizeof_bits<ElementA>::value
|
||||
);
|
||||
EXPECT_TRUE(test::conv::device::TestSpecificConv2d<Conv2dGroupFprop>(problem_sizes.default_multiple_group_sizes));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // CUTLASS_ARCH_MMA_SM80_SUPPORTED
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Reference in New Issue
Block a user