/*************************************************************************************************** * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted * provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 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. * * Neither the name of the NVIDIA CORPORATION 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 NVIDIA CORPORATION 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 TOR (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 Defies structural properties of half-precision GEMM computation. */ #pragma once #include #include #include #include #include #include #include #include #include #include #include namespace cutlass { namespace gemm { //////////////////////////////////////////////////////////////////////////////////////////////////// template < /// The tile size for the GEMM KxNxM. typename OutputTile_, /// The number of accumulators per thread. typename AccumulatorsPerThread_, /// The number of scalars per LDG for A. int kScalarsPerLdgA_ = 2, /// The number of scalars per LDG for B. int kScalarsPerLdgB_ = 2> struct HgemmConfig : public GemmConfig< /// The scalar type for A. half, /// The scalar type for B. half, /// The scalar type for C. half, /// The scalar type for D. half, /// The tile size for the GEMM KxNxM. OutputTile_, /// The functor to do the math in the main loop. ThreadMultiplyAdd, half, half, half>, /// The number of scalars per LDG for A. kScalarsPerLdgA_, /// The number of scalars per STS for A. kScalarsPerLdgA_, /// The number of scalars per LDS for A. 8, /// The number of scalars per LDG for B. kScalarsPerLdgB_, /// The number of scalars per STS for B. kScalarsPerLdgB_, /// The number of scalars per LDS for B. 8, /// The number of scalars per LDG for C and STG for D. 2, /// The number of scalars per STS for D. 8, /// The number of scalars per LDS for D. 2, /// The number of stages in shared memory. 2> {}; //////////////////////////////////////////////////////////////////////////////////////////////////// template struct HgemmTransformerA {}; template struct HgemmTransformerA { typedef Convert Transformer; }; template struct HgemmTransformerA { typedef HgemmSwizzle Transformer; }; //////////////////////////////////////////////////////////////////////////////////////////////////// template struct HgemmTransformerB {}; template struct HgemmTransformerB { typedef Convert Transformer; }; template struct HgemmTransformerB { typedef HgemmSwizzle Transformer; }; //////////////////////////////////////////////////////////////////////////////////////////////////// template struct HgemmTileTraitsHelperA : public GemmTileTraitsHelperA {}; //////////////////////////////////////////////////////////////////////////////////////////////////// template struct HgemmTileTraitsHelperA : public GemmTileTraitsHelperA { /// The base config. typedef GemmTileTraitsHelperA Base; /// The traits class to build the iterator to load data from global memory for A^T. typedef HgemmCrosswiseGlobalTileTraits< GemmOperand::kA, // The layout. MatrixLayout::kRowMajor, // The pointer. half const, // The tile has size MxK in GEMM's terminology. Shape<1, GemmConfig_::OutputTile::kW, GemmConfig_::OutputTile::kD>, // The threads are distributed as (threads / K ) x K (the traits may reorganize). Shape<1, GemmConfig_::kThreads / GemmConfig_::OutputTile::kD, GemmConfig_::OutputTile::kD>, // The number of scalars per LDG (LDG.32 or LDG.128, etc) GemmConfig_::kScalarsPerLdgA> GlobalTileTraits; /// The skew. static int const kSkewA = 128 / sizeof(half) / GlobalTileTraits::Threads::kW / 2; /// The traits class to build the iterator to store data to shared memory for A^T. typedef GemmSharedStoreWithSkewTileAbTraits < // The pointer. half, // The tile has size KxM in GEMM's terminology. Shape, // The threads are distributed as warps x 32(the traits may reorganize). typename GlobalTileTraits::Threads, // The number of scalars per STS (STS.32 or STS.128, etc). 2, // The skew to avoid bank conflicts added in the tile W dimension. kSkewA SharedStoreTileTraits; /// The traits class to build the iterator to load from shared memory for A^T. typedef GemmSharedLoadTileATraits< // The pointer. half const, // The output tile size. typename GemmConfig_::OutputTile, // The number of warps. typename GemmConfig_::Warps, // The number of threads per warp. typename GemmConfig_::MultiplyAdd::ThreadsPerWarp, // The shape of the FMA instruction. typename GemmConfig_::InstructionShape, // The number of stages. GemmConfig_::kStages, // The number of scalars per LDS. 8, // The skew. SharedStoreTileTraits::kSkew> SharedLoadTileTraits; }; //////////////////////////////////////////////////////////////////////////////////////////////////// template struct HgemmTileTraitsHelperB : public GemmTileTraitsHelperB {}; //////////////////////////////////////////////////////////////////////////////////////////////////// template struct HgemmTileTraitsHelperB : public GemmTileTraitsHelperB { /// The base config. typedef GemmTileTraitsHelperB Base; /// The traits class to build the iterator to load data from global memory for B^N. typedef HgemmCrosswiseGlobalTileTraits< GemmOperand::kB, // The layout. MatrixLayout::kColumnMajor, // The pointer. half const, // The tile has size KxN in GEMM's terminology. Shape<1, GemmConfig_::OutputTile::kH, GemmConfig_::OutputTile::kD>, // The threads are distributed as (threads / K) x K (the traits may reorganize). Shape<1, GemmConfig_::kThreads / GemmConfig_::OutputTile::kD, GemmConfig_::OutputTile::kD>, // The number of scalars per LDG (LDG.32 or LDG.128, etc) GemmConfig_::kScalarsPerLdgB> GlobalTileTraits; /// The skew for B. static int const kSkewB = 128 / sizeof(half) / GlobalTileTraits::Threads::kW / 2; /// The traits class to build the iterator to store data to shared memory for B^N. typedef GemmSharedStoreWithSkewTileAbTraits < // The pointer. half, // The tile has size KxN in GEMM's terminology. Shape, // The threads are distributed as (threads / K) x K (the traits may reorganize). typename GlobalTileTraits::Threads, // The number of scalars per STS (STS.32 or STS.128, etc). 2, // The skew to avoid bank conflicts added in the tile W dimension. kSkewB SharedStoreTileTraits; /// The traits class to build the iterator to load from shared memory for B^N. typedef GemmSharedLoadTileBTraits< // The pointer. half const, // The output tile size. typename GemmConfig_::OutputTile, // The number of warps. typename GemmConfig_::Warps, // The number of threads per warp. typename GemmConfig_::MultiplyAdd::ThreadsPerWarp, // The shape of the FMA instruction. typename GemmConfig_::InstructionShape, // The number of stages. GemmConfig_::kStages, // The number of scalars per LDS. 8, // The skew. SharedStoreTileTraits::kSkew> SharedLoadTileTraits; }; //////////////////////////////////////////////////////////////////////////////////////////////////// template < /// The layout for A. MatrixLayout::Kind kLayoutA_, /// The layout for B. MatrixLayout::Kind kLayoutB_, /// The output tile. typename OutputTile_, /// The functor to do the math in the epilogue. typename EpilogueFunctor_, /// The number of accumulators per thread. typename AccumulatorsPerThread_ = Shape<8, 8, 16>, /// The number of halfs loaded in one LDG for A. int kScalarsPerLdgA_ = 2, /// The number of halfs loaded in one LDG for B. int kScalarsPerLdgB_ = 2, /// The index. typename Index_ = int> struct HgemmTraitsHelper { /// The HGEMM config. typedef HgemmConfig GemmConfig; /// The GEMM config for A. typedef HgemmTileTraitsHelperA GemmTileTraitsHelperA; /// The GEMM config for B. typedef HgemmTileTraitsHelperB GemmTileTraitsHelperB; /// The iterator to load A from global memory. typedef GemmGlobalIteratorAb GlobalLoadIteratorA; /// The default transformer for A. typedef typename HgemmTransformerA::Transformer GlobalTransformerA; /// The iterator to store A to shared memory. typedef TileStoreIterator SharedStoreIteratorA; /// The stream to load A from global memory to shared memory. typedef GlobalLoadStream GlobalLoadStreamA; /// The iterator to load B from global memory. typedef GemmGlobalIteratorAb GlobalLoadIteratorB; // The default transformer for B. typedef typename HgemmTransformerB::Transformer GlobalTransformerB; /// The iterator to store B to shared memory. typedef TileStoreIterator SharedStoreIteratorB; /// The stream to load B from global memory to shared memory. typedef GlobalLoadStream GlobalLoadStreamB; /// The iterator to load A from shared memory typedef TileLoadIterator SharedLoadIteratorA; /// The stream to load A from shared memory. typedef SharedLoadStream SharedLoadStreamA; /// The iterator to load B from shared memory. typedef TileLoadIterator SharedLoadIteratorB; /// The stream to load B from shared memory. typedef SharedLoadStream SharedLoadStreamB; /// The functor to do the multiply-add in the main loop. typedef typename GemmConfig::MultiplyAdd MultiplyAdd; /// The object to clear accumulators. typedef ClearAccumulators ClearAccumulators; /// The traits class for the epilogue. typedef SimplifiedGemmEpilogueTraits GemmEpilogueTraits; /// The epilogue. typedef GemmEpilogue Epilogue; }; //////////////////////////////////////////////////////////////////////////////////////////////////// template < /// The layout for A. MatrixLayout::Kind kLayoutA_, /// The layout for B. MatrixLayout::Kind kLayoutB_, /// The output tile. typename OutputTile_ = Shape<8, 128, 128>, /// The functor to do the math in the epilogue. typename EpilogueFunctor_ = LinearScaling, /// The number of accumulators per thread. typename AccumulatorsPerThread_ = Shape<8, 8, 16>, /// The number of halfs loaded in one LDG for A. int kScalarsPerLdgA_ = 2, /// The number of halfs loaded in one LDG for B. int kScalarsPerLdgB_ = 2, /// The index. typename Index_ = int, /// The helper class. typename Helper_ = HgemmTraitsHelper > struct HgemmTraits : public GemmTraits< // The config. typename Helper_::GemmConfig, // The stream to load A from global memory to shared memory. typename Helper_::GlobalLoadStreamA, // The stream to load B from global memory to shared memory. typename Helper_::GlobalLoadStreamB, // The stream to load A from shared memory. typename Helper_::SharedLoadStreamA, // The stream to load B from shared memory. typename Helper_::SharedLoadStreamB, // The epilogue. typename Helper_::Epilogue, // The block swizzle to reorganize the grid. IdentityBlockSwizzle, // The index. Index_, // The tool used to clear accumulators. typename Helper_::ClearAccumulators> {}; //////////////////////////////////////////////////////////////////////////////////////////////////// } // namespace gemm } // namespace cutlass