@@ -139,24 +139,24 @@ public:
|
||||
ComplexTransform transform_A, /// Complex transformation applied to A matrix - ignored for real-valued matrices
|
||||
|
||||
void const * ptr_A, /// Pointer to A matrix in Global Memory
|
||||
int lda, /// Leading dimension of A matrix
|
||||
int64_t lda, /// Leading dimension of A matrix
|
||||
|
||||
NumericTypeID element_B, /// Data type of B matrix elements
|
||||
LayoutTypeID layout_B, /// Layout of B matrix
|
||||
ComplexTransform transform_B, /// Complex transformation applied to B matrix - ignored for real-valued matrices
|
||||
|
||||
void const * ptr_B, /// Pointer to B matrix in Global Memory
|
||||
int ldb, /// Leading dimension of B matrix
|
||||
int64_t ldb, /// Leading dimension of B matrix
|
||||
|
||||
void const * beta, /// Pointer to beta scalar
|
||||
|
||||
NumericTypeID element_C, /// Data type of C and D matrices
|
||||
|
||||
void const * ptr_C, /// Pointer to C matrix
|
||||
int ldc, /// Leading dimension of C matrix
|
||||
int64_t ldc, /// Leading dimension of C matrix
|
||||
|
||||
void * ptr_D, /// Pointer to D matrix
|
||||
int ldd /// Leading dimension of D matrix
|
||||
int64_t ldd /// Leading dimension of D matrix
|
||||
);
|
||||
|
||||
/// Executes a GEMM computation: D <= alpha * A*B + beta * C.
|
||||
@@ -182,24 +182,24 @@ public:
|
||||
ComplexTransform transform_A, /// Complex transformation applied to A matrix - ignored for real-valued matrices
|
||||
|
||||
void const * ptr_A, /// Pointer to A matrix in Global Memory
|
||||
int lda, /// Leading dimension of A matrix
|
||||
int64_t lda, /// Leading dimension of A matrix
|
||||
|
||||
NumericTypeID element_B, /// Data type of B matrix elements
|
||||
LayoutTypeID layout_B, /// Layout of B matrix
|
||||
ComplexTransform transform_B, /// Complex transformation applied to B matrix - ignored for real-valued matrices
|
||||
|
||||
void const * ptr_B, /// Pointer to B matrix in Global Memory
|
||||
int ldb, /// Leading dimension of B matrix
|
||||
int64_t ldb, /// Leading dimension of B matrix
|
||||
|
||||
void const * beta, /// Pointer to beta scalar
|
||||
|
||||
NumericTypeID element_C, /// Data type of C and D matrices
|
||||
|
||||
void const * ptr_C, /// Pointer to C matrix
|
||||
int ldc, /// Leading dimension of C matrix
|
||||
int64_t ldc, /// Leading dimension of C matrix
|
||||
|
||||
void * ptr_D, /// Pointer to D matrix
|
||||
int ldd, /// Leading dimension of D matrix
|
||||
int64_t ldd, /// Leading dimension of D matrix
|
||||
|
||||
int batch_count = 1, /// Batch count or number of split-K slices
|
||||
|
||||
@@ -231,8 +231,8 @@ public:
|
||||
|
||||
void const * ptr_A_real, /// Pointer to real part of A matrix
|
||||
void const * ptr_A_imag, /// Pointer to imaginary part of A matrix
|
||||
int lda_real, /// Leading dimension of real part of A matrix
|
||||
int lda_imag, /// Leading dimension of imaginary part of A matrix
|
||||
int64_t lda_real, /// Leading dimension of real part of A matrix
|
||||
int64_t lda_imag, /// Leading dimension of imaginary part of A matrix
|
||||
|
||||
NumericTypeID element_B, /// Data type of B matrix elements
|
||||
LayoutTypeID layout_B, /// Layout of B matrix
|
||||
@@ -240,8 +240,8 @@ public:
|
||||
|
||||
void const * ptr_B_real, /// Pointer to real part of B matrix
|
||||
void const * ptr_B_imag, /// Pointer to imaginary part of B matrix
|
||||
int ldb_real, /// Leading dimension of real part of B matrix
|
||||
int ldb_imag, /// Leading dimension of imaginary part of B matrix
|
||||
int64_t ldb_real, /// Leading dimension of real part of B matrix
|
||||
int64_t ldb_imag, /// Leading dimension of imaginary part of B matrix
|
||||
|
||||
void const * beta, /// Pointer to beta scalar
|
||||
|
||||
@@ -249,13 +249,13 @@ public:
|
||||
|
||||
void const * ptr_C_real, /// Pointer to real part of C matrix
|
||||
void const * ptr_C_imag, /// Pointer to imaginary part of C matrix
|
||||
int ldc_real, /// Leading dimension of real part of C matrix
|
||||
int ldc_imag, /// Leading dimension of imaginary part of C matrix
|
||||
int64_t ldc_real, /// Leading dimension of real part of C matrix
|
||||
int64_t ldc_imag, /// Leading dimension of imaginary part of C matrix
|
||||
|
||||
void * ptr_D_real, /// Pointer to real part of D matrix
|
||||
void * ptr_D_imag, /// Pointer to imaginary part of D matrix
|
||||
int ldd_real, /// Leading dimension of real part of D matrix
|
||||
int ldd_imag, /// Leading dimension of imaginary part of D matrix
|
||||
int64_t ldd_real, /// Leading dimension of real part of D matrix
|
||||
int64_t ldd_imag, /// Leading dimension of imaginary part of D matrix
|
||||
|
||||
int batch_count = 1, /// Number of batched GEMMs to execute
|
||||
|
||||
@@ -297,8 +297,8 @@ public:
|
||||
void const * const * ptr_A_real, /// Pointer to array containing pointers to real part of A matrices
|
||||
void const * const * ptr_A_imag, /// Pointer to array containing pointers to imaginary part of A matrices
|
||||
|
||||
int lda_real, /// Leading dimension of real part of A matrix
|
||||
int lda_imag, /// Leading dimension of imaginary part of A matrix
|
||||
int64_t lda_real, /// Leading dimension of real part of A matrix
|
||||
int64_t lda_imag, /// Leading dimension of imaginary part of A matrix
|
||||
|
||||
NumericTypeID element_B, /// Data type of B matrix elements
|
||||
LayoutTypeID layout_B, /// Layout of B matrix
|
||||
@@ -307,8 +307,8 @@ public:
|
||||
void const * const * ptr_B_real, /// Pointer to array containing pointers to real part of B matrices
|
||||
void const * const * ptr_B_imag, /// Pointer to array containing pointers to imaginary part of B matrices
|
||||
|
||||
int ldb_real, /// Leading dimension of real part of B matrix
|
||||
int ldb_imag, /// Leading dimension of imaginary part of B matrix
|
||||
int64_t ldb_real, /// Leading dimension of real part of B matrix
|
||||
int64_t ldb_imag, /// Leading dimension of imaginary part of B matrix
|
||||
|
||||
void const * beta, /// Pointer to beta scalar
|
||||
|
||||
@@ -317,14 +317,14 @@ public:
|
||||
void const * const * ptr_C_real, /// Pointer to array containing pointers to real part of C matrices
|
||||
void const * const * ptr_C_imag, /// Pointer to array containing poitners to imaginary part of C matrices
|
||||
|
||||
int ldc_real, /// Leading dimension of real part of C matrix
|
||||
int ldc_imag, /// Leading dimension of imaginary part of C matrix
|
||||
int64_t ldc_real, /// Leading dimension of real part of C matrix
|
||||
int64_t ldc_imag, /// Leading dimension of imaginary part of C matrix
|
||||
|
||||
void * const * ptr_D_real, /// Pointer to array containing pointers to real part of D matrices
|
||||
void * const * ptr_D_imag, /// Pointer to array containing poitners to imaginary part of D matrices
|
||||
|
||||
int ldd_real, /// Leading dimension of real part of D matrix
|
||||
int ldd_imag /// Leading dimension of imaginary part of D matrix
|
||||
int64_t ldd_real, /// Leading dimension of real part of D matrix
|
||||
int64_t ldd_imag /// Leading dimension of imaginary part of D matrix
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
@@ -933,13 +933,13 @@ struct Conv2dConfiguration {
|
||||
conv::Conv2dProblemSize problem_size;
|
||||
|
||||
// stride of operand A
|
||||
std::vector<int> stride_a;
|
||||
std::vector<int64_t> stride_a;
|
||||
|
||||
// stride of operand B
|
||||
std::vector<int> stride_b;
|
||||
std::vector<int64_t> stride_b;
|
||||
|
||||
// stride of operand C
|
||||
std::vector<int> stride_c;
|
||||
std::vector<int64_t> stride_c;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ from library import *
|
||||
class Conv2dOperation:
|
||||
#
|
||||
def __init__(self, conv_kind, iterator_algorithm, arch, tile_description, A, B, C, element_epilogue, \
|
||||
stride_support, epilogue_functor = EpilogueFunctor.LinearCombination, swizzling_functor = SwizzlingFunctor.Identity4):
|
||||
stride_support, epilogue_functor = EpilogueFunctor.LinearCombination, swizzling_functor = SwizzlingFunctor.Identity1):
|
||||
|
||||
self.operation_kind = OperationKind.Conv2d
|
||||
self.arch = arch
|
||||
|
||||
@@ -141,18 +141,19 @@ def CreateGemmPlanarComplexOperator(manifest, layouts, tile_descriptions, data_t
|
||||
###########################################################################################################
|
||||
# ConvolutionOperator support variations
|
||||
# ____________________________________________________________________
|
||||
# ConvolutionalOperator | Analytic | Optimized
|
||||
# ConvolutionalOperator | Analytic | Optimized
|
||||
# ____________________________________________________________________
|
||||
# | Fprop | (strided) | (strided)
|
||||
# | Dgrad | (strided, unity*) | (unity)
|
||||
# | Wgrad | (strided) | (strided)
|
||||
# | Fprop | (strided) | (strided)
|
||||
# | Dgrad | (strided, unity*) | (strided, unity)
|
||||
# | Wgrad | (strided) | (strided)
|
||||
# ____________________________________________________________________
|
||||
#
|
||||
# Note : Operator marked (*) are supported but not generated to keep the instantiated kernel count low
|
||||
###########################################################################################################
|
||||
# Convolution for 2D operations
|
||||
def CreateConv2dOperator(manifest, layout, tile_descriptions, data_type, alignment, \
|
||||
conv_kinds = [ConvKind.Fprop, ConvKind.Dgrad, ConvKind.Wgrad], epilogue_functor = EpilogueFunctor.LinearCombination):
|
||||
conv_kinds = [ConvKind.Fprop, ConvKind.Dgrad, ConvKind.Wgrad], \
|
||||
epilogue_functor = EpilogueFunctor.LinearCombination, swizzling_functor = SwizzlingFunctor.Identity4):
|
||||
|
||||
element_a, element_b, element_c, element_epilogue = data_type
|
||||
|
||||
@@ -169,33 +170,66 @@ def CreateConv2dOperator(manifest, layout, tile_descriptions, data_type, alignme
|
||||
operations = []
|
||||
|
||||
for tile in tile_descriptions:
|
||||
for conv_kind in conv_kinds:
|
||||
A = TensorDescription(element_a, layout[0], alignment)
|
||||
B = TensorDescription(element_b, layout[1], alignment)
|
||||
C = TensorDescription(element_c, layout[2], alignment_c)
|
||||
|
||||
swizzling_functor_ = swizzling_functor
|
||||
|
||||
#
|
||||
# Conv2d Fprop
|
||||
#
|
||||
if ConvKind.Fprop in conv_kinds:
|
||||
|
||||
# Strided support for Analytic and Optimized Fprop
|
||||
for iterator_algorithm in iterator_algorithms:
|
||||
A = TensorDescription(element_a, layout[0], alignment)
|
||||
B = TensorDescription(element_b, layout[1], alignment)
|
||||
C = TensorDescription(element_c, layout[2], alignment_c)
|
||||
new_operation = Conv2dOperation(ConvKind.Fprop, iterator_algorithm, tile.minimum_compute_capability, tile,\
|
||||
A, B, C, element_epilogue, StrideSupport.Strided, epilogue_functor, swizzling_functor_)
|
||||
|
||||
# unity stride only for Optimized Dgrad
|
||||
if (iterator_algorithm == IteratorAlgorithm.Optimized) and (conv_kind == ConvKind.Dgrad):
|
||||
new_operation = Conv2dOperation(conv_kind, iterator_algorithm, tile.minimum_compute_capability, tile,\
|
||||
A, B, C, element_epilogue, StrideSupport.Unity, epilogue_functor)
|
||||
manifest.append(new_operation)
|
||||
operations.append(new_operation)
|
||||
|
||||
manifest.append(new_operation)
|
||||
operations.append(new_operation)
|
||||
#
|
||||
# Conv2d Dgrad
|
||||
#
|
||||
if ConvKind.Dgrad in conv_kinds:
|
||||
|
||||
# strided dgrad is not supported by Optimized Dgrad
|
||||
if (iterator_algorithm == IteratorAlgorithm.Optimized) and (conv_kind == ConvKind.Dgrad):
|
||||
continue
|
||||
# Unity stride for Analytic and Optimized Dgrad
|
||||
for iterator_algorithm in iterator_algorithms:
|
||||
new_operation = Conv2dOperation(ConvKind.Dgrad, iterator_algorithm, tile.minimum_compute_capability, tile,\
|
||||
A, B, C, element_epilogue, StrideSupport.Unity, epilogue_functor, swizzling_functor_)
|
||||
|
||||
# strided support for Fprop (Analytic/Optimized), Dgrad (Analytic), and Wgrad (Analytic)
|
||||
new_operation = Conv2dOperation(conv_kind, iterator_algorithm, tile.minimum_compute_capability, tile,\
|
||||
A, B, C, element_epilogue, StrideSupport.Strided, epilogue_functor)
|
||||
manifest.append(new_operation)
|
||||
operations.append(new_operation)
|
||||
|
||||
# Strided support for Analytic Dgrad
|
||||
# strided dgrad uses a special threadblock swizzle
|
||||
# note that SwizzlingFunctor.StridedDgradHorizontal might be
|
||||
# better for problem sizes with large activation channel count
|
||||
swizzling_functor_strided_dgrad_ = SwizzlingFunctor.StridedDgradIdentity1
|
||||
|
||||
new_operation = Conv2dOperation(ConvKind.Dgrad, IteratorAlgorithm.Analytic, tile.minimum_compute_capability, tile,\
|
||||
A, B, C, element_epilogue, StrideSupport.Strided, epilogue_functor, swizzling_functor_strided_dgrad_)
|
||||
|
||||
manifest.append(new_operation)
|
||||
operations.append(new_operation)
|
||||
|
||||
#
|
||||
# Conv2d Wgrad
|
||||
#
|
||||
if ConvKind.Wgrad in conv_kinds:
|
||||
|
||||
# Strided support for Analytic and Optimized Wgrad
|
||||
for iterator_algorithm in iterator_algorithms:
|
||||
new_operation = Conv2dOperation(ConvKind.Wgrad, iterator_algorithm, tile.minimum_compute_capability, tile,\
|
||||
A, B, C, element_epilogue, StrideSupport.Strided, epilogue_functor, swizzling_functor_)
|
||||
|
||||
manifest.append(new_operation)
|
||||
operations.append(new_operation)
|
||||
|
||||
return operations
|
||||
|
||||
|
||||
# Convolution for 3D operations
|
||||
def CreateConv3dOperator(manifest, layout, tile_descriptions, data_type, alignment, \
|
||||
conv_kinds = [ConvKind.Fprop, ConvKind.Dgrad, ConvKind.Wgrad], epilogue_functor = EpilogueFunctor.LinearCombination):
|
||||
@@ -315,6 +349,11 @@ def GenerateSM50_Simt_complex(manifest, args):
|
||||
|
||||
for math_inst in math_instructions:
|
||||
tile_descriptions = [
|
||||
TileDescription([128, 64, 8], 2, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([ 64, 128, 8], 2, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([ 64, 64, 8], 2, [2, 1, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([128, 32, 8], 2, [2, 1, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([ 32, 128, 8], 2, [1, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([128, 128, 8], 2, [4, 2, 1], math_inst, min_cc, max_cc),
|
||||
]
|
||||
|
||||
@@ -1272,6 +1311,7 @@ def GenerateSM80_TensorOp_16816(manifest, args):
|
||||
TileDescription([128, 256, 32], 3, [2, 4, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([256, 64, 32], 4, [4, 1, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([ 64, 256, 32], 4, [1, 4, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([128, 128, 32], 3, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([128, 128, 32], 5, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([128, 64, 32], 6, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([ 64, 128, 32], 6, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
@@ -1698,9 +1738,10 @@ def GenerateSM80_TensorOp_16864_TN(manifest, args):
|
||||
TileDescription([256, 64, 256], 4, [4, 1, 1], math_inst, min_cc, max_cc_smem_limited),
|
||||
TileDescription([ 64, 256, 256], 4, [1, 4, 1], math_inst, min_cc, max_cc_smem_limited),
|
||||
TileDescription([128, 128, 256], 4, [2, 2, 1], math_inst, min_cc, max_cc_smem_limited),
|
||||
TileDescription([128, 128, 256], 3, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([128, 64, 256], 3, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([ 64, 128, 256], 3, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([ 64, 64, 256], 5, [2, 2, 1], math_inst, min_cc, max_cc_smem_limited),
|
||||
TileDescription([ 64, 64, 256], 5, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
]
|
||||
|
||||
data_type = [math_inst.element_a, math_inst.element_b, math_inst.element_accumulator, DataType.s32]
|
||||
@@ -1713,14 +1754,14 @@ def GenerateSM80_TensorOp_16864_TN(manifest, args):
|
||||
|
||||
operations += CreateGemmOperator(manifest, layouts, tile_descriptions, \
|
||||
data_type_mixed, alignment_constraints, None, EpilogueFunctor.LinearCombinationClamp)
|
||||
|
||||
|
||||
conv_layout = (LayoutType.TensorNHWC, LayoutType.TensorNHWC, LayoutType.TensorNHWC)
|
||||
CreateConv2dOperator(manifest, conv_layout, tile_descriptions,
|
||||
data_type, 32, [ConvKind.Fprop], EpilogueFunctor.LinearCombinationClamp)
|
||||
|
||||
|
||||
operations += CreateConv2dOperator(manifest, conv_layout, tile_descriptions,
|
||||
data_type_mixed, 32, [ConvKind.Fprop], EpilogueFunctor.LinearCombinationClamp)
|
||||
|
||||
|
||||
for op in operations:
|
||||
if op.tile_description.threadblock_shape[1] >= 128:
|
||||
op.C.alignment = 8
|
||||
@@ -1934,6 +1975,7 @@ def GenerateSM80_TensorOp_1688(manifest, args):
|
||||
TileDescription([256, 64, 32], 4, [4, 1, 1], math_inst, min_cc, max_cc_smem_limited),
|
||||
TileDescription([ 64, 256, 32], 4, [1, 4, 1], math_inst, min_cc, max_cc_smem_limited),
|
||||
TileDescription([128, 128, 32], 4, [2, 2, 1], math_inst, min_cc, max_cc_smem_limited),
|
||||
TileDescription([128, 128, 32], 3, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([128, 64, 32], 3, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([64, 128, 32], 3, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([ 64, 64, 32], 5, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
@@ -1993,7 +2035,7 @@ def GenerateSM80_TensorOp_1688_fast_math(manifest, args):
|
||||
[16, 8, 8], \
|
||||
DataType.bf16, DataType.bf16, DataType.f32, \
|
||||
OpcodeClass.TensorOp, \
|
||||
MathOperation.multiply_add_fast_bf16)
|
||||
MathOperation.multiply_add_fast_bf16),
|
||||
]
|
||||
|
||||
min_cc = 80
|
||||
@@ -2017,6 +2059,7 @@ def GenerateSM80_TensorOp_1688_fast_math(manifest, args):
|
||||
TileDescription([256, 64, 32], 4, [4, 1, 1], math_inst, min_cc, max_cc_smem_limited),
|
||||
TileDescription([ 64, 256, 32], 4, [1, 4, 1], math_inst, min_cc, max_cc_smem_limited),
|
||||
TileDescription([128, 128, 32], 4, [2, 2, 1], math_inst, min_cc, max_cc_smem_limited),
|
||||
TileDescription([128, 128, 32], 3, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([128, 64, 32], 3, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([ 64, 128, 32], 3, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([ 64, 64, 32], 5, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
@@ -2031,6 +2074,7 @@ def GenerateSM80_TensorOp_1688_fast_math(manifest, args):
|
||||
CreateConv2dOperator(manifest, conv_layout, tile_descriptions, data_type, 4)
|
||||
#
|
||||
|
||||
#
|
||||
#
|
||||
def GenerateSM80_SparseTensorOp_16816_fast_math(manifest, args):
|
||||
|
||||
@@ -2155,9 +2199,9 @@ def GenerateSM80_TensorOp_884(manifest, args):
|
||||
alignment_constraints = [1,]
|
||||
|
||||
tile_descriptions = [
|
||||
TileDescription([128, 128, 16], 3, [4, 2, 1], math_inst, min_cc, max_cc_smem_limited),
|
||||
TileDescription([64, 128, 16], 3, [2, 2, 1], math_inst, min_cc, max_cc_smem_limited),
|
||||
TileDescription([128, 64, 16], 3, [2, 2, 1], math_inst, min_cc, max_cc_smem_limited),
|
||||
TileDescription([128, 128, 16], 3, [4, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([64, 128, 16], 3, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([128, 64, 16], 3, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([64, 64, 16], 4, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([64, 32, 16], 4, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
TileDescription([32, 64, 16], 4, [2, 2, 1], math_inst, min_cc, max_cc),
|
||||
@@ -2463,6 +2507,7 @@ if __name__ == "__main__":
|
||||
parser.add_argument('--kernel-filter-file', type=str, default=None, required=False, help='Full path of filter file')
|
||||
parser.add_argument('--selected-kernel-list', type=str, default=None, required=False,
|
||||
help='Specify the output log file containing all enabled kernels in this build')
|
||||
parser.add_argument("--interface-dir", default=None, required=False, help="Interface header to kernels")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
@@ -437,6 +437,10 @@ class SwizzlingFunctor(enum.Enum):
|
||||
Identity2 = enum_auto()
|
||||
Identity4 = enum_auto()
|
||||
Identity8 = enum_auto()
|
||||
Horizontal = enum_auto()
|
||||
StridedDgradIdentity1 = enum_auto()
|
||||
StridedDgradIdentity4 = enum_auto()
|
||||
StridedDgradHorizontal = enum_auto()
|
||||
|
||||
#
|
||||
SwizzlingFunctorTag = {
|
||||
@@ -444,6 +448,10 @@ SwizzlingFunctorTag = {
|
||||
SwizzlingFunctor.Identity2: 'cutlass::gemm::threadblock::GemmIdentityThreadblockSwizzle<2>',
|
||||
SwizzlingFunctor.Identity4: 'cutlass::gemm::threadblock::GemmIdentityThreadblockSwizzle<4>',
|
||||
SwizzlingFunctor.Identity8: 'cutlass::gemm::threadblock::GemmIdentityThreadblockSwizzle<8>',
|
||||
SwizzlingFunctor.Horizontal: 'cutlass::gemm::threadblock::GemmHorizontalThreadblockSwizzle',
|
||||
SwizzlingFunctor.StridedDgradIdentity1: 'cutlass::conv::threadblock::StridedDgradIdentityThreadblockSwizzle<1>',
|
||||
SwizzlingFunctor.StridedDgradIdentity4: 'cutlass::conv::threadblock::StridedDgradIdentityThreadblockSwizzle<4>',
|
||||
SwizzlingFunctor.StridedDgradHorizontal: 'cutlass::conv::threadblock::StridedDgradHorizontalThreadblockSwizzle',
|
||||
}
|
||||
|
||||
###################################################################################################
|
||||
|
||||
@@ -101,6 +101,70 @@ void initialize_all_${operation_name}_operations(Manifest &manifest) {
|
||||
self.top_level_file.write(self.epilogue_template)
|
||||
self.top_level_file.close()
|
||||
|
||||
class EmitInterfaceLibrary:
|
||||
def __init__(self, generated_path, operation_count, args):
|
||||
self.generated_path = generated_path
|
||||
self.args = args
|
||||
|
||||
|
||||
self.prototypes = []
|
||||
self.fn_calls = []
|
||||
self.operation_count = str(operation_count)
|
||||
|
||||
self.top_level_hdr_template = '''
|
||||
/*
|
||||
Generated by manifest.py - Do not edit.
|
||||
*/
|
||||
'''
|
||||
self.top_level_prologue = '''
|
||||
|
||||
#include "cutlass/library/library.h"
|
||||
#include "cutlass/library/manifest.h"
|
||||
|
||||
namespace cutlass {
|
||||
\tnamespace library {
|
||||
|
||||
${prototypes}
|
||||
|
||||
\t\tvoid initialize_all(Manifest &manifest) {
|
||||
\t\t\tmanifest.reserve(${operation_count});\n\n
|
||||
${fn_calls}
|
||||
\t\t\t}
|
||||
|
||||
\t} // namespace library
|
||||
} // namespace cutlass
|
||||
|
||||
'''
|
||||
|
||||
#
|
||||
def __enter__(self):
|
||||
self.top_level_path = os.path.join(self.generated_path, 'initialize_all.cpp')
|
||||
|
||||
self.top_level_file = open(self.top_level_path, "w")
|
||||
self.top_level_file.write(self.top_level_hdr_template)
|
||||
|
||||
self.source_files = [self.top_level_path,]
|
||||
|
||||
return self
|
||||
|
||||
#
|
||||
def emit(self, operation_name):
|
||||
self.prototypes.append(SubstituteTemplate(
|
||||
"\t\tvoid initialize_all_${operation_kind}_operations(Manifest &manifest);",
|
||||
{'operation_kind': operation_name}))
|
||||
self.fn_calls.append(SubstituteTemplate(
|
||||
"\t\t\tinitialize_all_${operation_kind}_operations(manifest);",
|
||||
{'operation_kind': operation_name}))
|
||||
|
||||
|
||||
|
||||
#
|
||||
def __exit__(self, exception_type, exception_value, traceback):
|
||||
self.top_level_file.write(SubstituteTemplate(self.top_level_prologue, {'prototypes':"\n".join(self.prototypes),
|
||||
'fn_calls':"\n".join(self.fn_calls),
|
||||
'operation_count': self.operation_count}))
|
||||
self.top_level_file.close()
|
||||
|
||||
###################################################################################################
|
||||
###################################################################################################
|
||||
|
||||
@@ -150,27 +214,6 @@ class Manifest:
|
||||
|
||||
self.operation_count = 0
|
||||
self.operations_by_name = {}
|
||||
self.top_level_prologue = '''
|
||||
|
||||
#include "cutlass/library/library.h"
|
||||
#include "cutlass/library/manifest.h"
|
||||
|
||||
namespace cutlass {
|
||||
namespace library {
|
||||
|
||||
${prototypes}
|
||||
|
||||
void initialize_all(Manifest &manifest) {
|
||||
|
||||
'''
|
||||
self.top_level_reserve = ' manifest.reserve(${operation_count});\n\n'
|
||||
self.top_level_epilogue = '''
|
||||
}
|
||||
|
||||
} // namespace library
|
||||
} // namespace cutlass
|
||||
|
||||
'''
|
||||
|
||||
|
||||
def get_kernel_filters (self, kernelListFile):
|
||||
@@ -288,6 +331,9 @@ void initialize_all(Manifest &manifest) {
|
||||
operation_emitters = {
|
||||
GeneratorTarget.Library: EmitOperationKindLibrary
|
||||
}
|
||||
interface_emitters = {
|
||||
GeneratorTarget.Library: EmitInterfaceLibrary
|
||||
}
|
||||
|
||||
generated_path = os.path.join(self.args.curr_build_dir, 'generated')
|
||||
|
||||
@@ -299,38 +345,20 @@ void initialize_all(Manifest &manifest) {
|
||||
|
||||
source_files = []
|
||||
|
||||
top_level_path = os.path.join(generated_path, 'initialize_all.cpp')
|
||||
with open(top_level_path, 'w') as top_level_file:
|
||||
|
||||
if target == GeneratorTarget.Library:
|
||||
source_files.append(top_level_path)
|
||||
|
||||
prototypes = []
|
||||
with interface_emitters[target](generated_path, self.operation_count, self.args) as iface_emitter:
|
||||
for operation_kind, configurations in self.operations.items():
|
||||
prototypes.append(SubstituteTemplate(
|
||||
"void initialize_all_${operation_kind}_operations(Manifest &manifest);",
|
||||
{'operation_kind': OperationKindNames[operation_kind]}))
|
||||
iface_emitter.emit(OperationKindNames[operation_kind])
|
||||
|
||||
top_level_file.write(SubstituteTemplate(self.top_level_prologue,
|
||||
{'prototypes': "\n".join(prototypes)}))
|
||||
source_files += iface_emitter.source_files
|
||||
|
||||
top_level_file.write(SubstituteTemplate(
|
||||
self.top_level_reserve, {'operation_count': str(self.operation_count)}))
|
||||
|
||||
# for each operation kind, emit initializer for all configurations
|
||||
for operation_kind, configurations in self.operations.items():
|
||||
|
||||
with operation_emitters[target](generated_path, operation_kind, self.args) as operation_kind_emitter:
|
||||
for configuration_name, operations in configurations.items():
|
||||
operation_kind_emitter.emit(configuration_name, operations)
|
||||
# for each operation kind, emit initializer for all configurations
|
||||
for operation_kind, configurations in self.operations.items():
|
||||
with operation_emitters[target](generated_path, operation_kind, self.args) as operation_kind_emitter:
|
||||
for configuration_name, operations in configurations.items():
|
||||
operation_kind_emitter.emit(configuration_name, operations)
|
||||
|
||||
source_files += operation_kind_emitter.source_files
|
||||
|
||||
top_level_file.write(SubstituteTemplate(
|
||||
" initialize_all_${operation_kind}_operations(manifest);\n",
|
||||
{'operation_kind': OperationKindNames[operation_kind]}))
|
||||
|
||||
top_level_file.write(self.top_level_epilogue)
|
||||
source_files += operation_kind_emitter.source_files
|
||||
|
||||
# write the manifest.cmake file containing paths from all targets
|
||||
manifest_path = os.path.join(generated_path, "manifest.cmake")
|
||||
|
||||
@@ -58,6 +58,8 @@ public:
|
||||
using LayoutB = typename Operator::LayoutB;
|
||||
using ElementC = typename Operator::ElementC;
|
||||
using LayoutC = typename Operator::LayoutC;
|
||||
// assuming all tensors use same type for StrideIndex
|
||||
using StrideIndex = typename Operator::LayoutA::Index;
|
||||
using ElementAccumulator = typename Operator::ElementAccumulator;
|
||||
using ElementCompute = typename Operator::EpilogueOutputOp::ElementCompute;
|
||||
|
||||
@@ -102,7 +104,7 @@ public:
|
||||
OpcodeClassMap<typename Operator::OperatorClass>::kId;
|
||||
|
||||
description_.tile_description.math_instruction.math_operation =
|
||||
MathOperationMap<typename Operator::Operator>::kId;
|
||||
MathOperationMap<typename Operator::MathOperator>::kId;
|
||||
|
||||
description_.tile_description.minimum_compute_capability =
|
||||
ArchMap<typename Operator::ArchTag, typename Operator::OperatorClass>::kMin;
|
||||
@@ -141,7 +143,6 @@ public:
|
||||
using LayoutC = typename Operator::LayoutC;
|
||||
using ElementAccumulator = typename Operator::ElementAccumulator;
|
||||
using ElementCompute = typename Operator::EpilogueOutputOp::ElementCompute;
|
||||
|
||||
using OperatorArguments = typename Operator::Arguments;
|
||||
|
||||
public:
|
||||
@@ -160,10 +161,12 @@ protected:
|
||||
GemmConfiguration const *configuration) {
|
||||
|
||||
operator_args.problem_size = configuration->problem_size;
|
||||
operator_args.ref_A = {nullptr, int(configuration->lda)};
|
||||
operator_args.ref_B = {nullptr, int(configuration->ldb)};
|
||||
operator_args.ref_C = {nullptr, int(configuration->ldc)};
|
||||
operator_args.ref_D = {nullptr, int(configuration->ldd)};
|
||||
|
||||
operator_args.ref_A = {nullptr, configuration->lda};
|
||||
operator_args.ref_B = {nullptr, configuration->ldb};
|
||||
operator_args.ref_C = {nullptr, configuration->ldc};
|
||||
operator_args.ref_D = {nullptr, configuration->ldd};
|
||||
|
||||
operator_args.split_k_slices = configuration->split_k_slices;
|
||||
|
||||
return Status::kSuccess;
|
||||
@@ -360,11 +363,11 @@ protected:
|
||||
SparseGemmConfiguration const *configuration) {
|
||||
|
||||
operator_args.problem_size = configuration->problem_size;
|
||||
operator_args.ref_A = {nullptr, int(configuration->lda)};
|
||||
operator_args.ref_B = {nullptr, int(configuration->ldb)};
|
||||
operator_args.ref_C = {nullptr, int(configuration->ldc)};
|
||||
operator_args.ref_D = {nullptr, int(configuration->ldd)};
|
||||
operator_args.ref_E = {nullptr, int(configuration->lde)};
|
||||
operator_args.ref_A = {nullptr, configuration->lda};
|
||||
operator_args.ref_B = {nullptr, configuration->ldb};
|
||||
operator_args.ref_C = {nullptr, configuration->ldc};
|
||||
operator_args.ref_D = {nullptr, configuration->ldd};
|
||||
operator_args.ref_E = {nullptr, configuration->lde};
|
||||
|
||||
return Status::kSuccess;
|
||||
}
|
||||
@@ -562,10 +565,10 @@ protected:
|
||||
operator_args.problem_size = configuration->problem_size;
|
||||
operator_args.batch_count = configuration->batch_count;
|
||||
|
||||
operator_args.lda = int(configuration->lda);
|
||||
operator_args.ldb = int(configuration->ldb);
|
||||
operator_args.ldc = int(configuration->ldc);
|
||||
operator_args.ldd = int(configuration->ldd);
|
||||
operator_args.lda = (configuration->lda);
|
||||
operator_args.ldb = (configuration->ldb);
|
||||
operator_args.ldc = (configuration->ldc);
|
||||
operator_args.ldd = (configuration->ldd);
|
||||
|
||||
return Status::kSuccess;
|
||||
}
|
||||
@@ -755,14 +758,15 @@ protected:
|
||||
operator_args.problem_size = configuration->problem_size;
|
||||
operator_args.batch_count = configuration->batch_count;
|
||||
|
||||
operator_args.lda_real = int(configuration->lda_real);
|
||||
operator_args.lda_imag = int(configuration->lda_imag);
|
||||
operator_args.ldb_real = int(configuration->ldb_real);
|
||||
operator_args.ldb_imag = int(configuration->ldb_imag);
|
||||
operator_args.ldc_real = int(configuration->ldc_real);
|
||||
operator_args.ldc_imag = int(configuration->ldc_imag);
|
||||
operator_args.ldd_real = int(configuration->ldd_real);
|
||||
operator_args.ldd_imag = int(configuration->ldd_imag);
|
||||
|
||||
operator_args.lda_real = configuration->lda_real;
|
||||
operator_args.lda_imag = configuration->lda_imag;
|
||||
operator_args.ldb_real = configuration->ldb_real;
|
||||
operator_args.ldb_imag = configuration->ldb_imag;
|
||||
operator_args.ldc_real = configuration->ldc_real;
|
||||
operator_args.ldc_imag = configuration->ldc_imag;
|
||||
operator_args.ldd_real = configuration->ldd_real;
|
||||
operator_args.ldd_imag = configuration->ldd_imag;
|
||||
|
||||
return Status::kSuccess;
|
||||
}
|
||||
@@ -960,14 +964,14 @@ protected:
|
||||
operator_args.problem_size = configuration->problem_size;
|
||||
operator_args.batch_count = configuration->batch_count;
|
||||
|
||||
operator_args.lda_real = int(configuration->lda_real);
|
||||
operator_args.lda_imag = int(configuration->lda_imag);
|
||||
operator_args.ldb_real = int(configuration->ldb_real);
|
||||
operator_args.ldb_imag = int(configuration->ldb_imag);
|
||||
operator_args.ldc_real = int(configuration->ldc_real);
|
||||
operator_args.ldc_imag = int(configuration->ldc_imag);
|
||||
operator_args.ldd_real = int(configuration->ldd_real);
|
||||
operator_args.ldd_imag = int(configuration->ldd_imag);
|
||||
operator_args.lda_real = configuration->lda_real;
|
||||
operator_args.lda_imag = configuration->lda_imag;
|
||||
operator_args.ldb_real = configuration->ldb_real;
|
||||
operator_args.ldb_imag = configuration->ldb_imag;
|
||||
operator_args.ldc_real = configuration->ldc_real;
|
||||
operator_args.ldc_imag = configuration->ldc_imag;
|
||||
operator_args.ldd_real = configuration->ldd_real;
|
||||
operator_args.ldd_imag = configuration->ldd_imag;
|
||||
|
||||
return Status::kSuccess;
|
||||
}
|
||||
|
||||
+28
-28
@@ -204,18 +204,18 @@ static int gemm_problem_alignment(
|
||||
int K,
|
||||
NumericTypeID element_A,
|
||||
void const *ptr_A,
|
||||
int lda,
|
||||
int64_t lda,
|
||||
int64_t batch_stride_A,
|
||||
NumericTypeID element_B,
|
||||
void const *ptr_B,
|
||||
int ldb,
|
||||
int64_t ldb,
|
||||
int64_t batch_stride_B,
|
||||
NumericTypeID element_C,
|
||||
void const * ptr_C,
|
||||
int ldc,
|
||||
int64_t ldc,
|
||||
int64_t batch_stride_C,
|
||||
void const * ptr_D,
|
||||
int ldd,
|
||||
int64_t ldd,
|
||||
int64_t batch_stride_D,
|
||||
int max_alignment_in_bytes = 16
|
||||
) {
|
||||
@@ -338,24 +338,24 @@ Status Handle::gemm(
|
||||
ComplexTransform transform_A, /// Complex transformation applied to A matrix - ignored for real-valued matrices
|
||||
|
||||
void const * ptr_A, /// Pointer to A matrix in Global Memory
|
||||
int lda, /// Leading dimension of A matrix
|
||||
int64_t lda, /// Leading dimension of A matrix
|
||||
|
||||
NumericTypeID element_B, /// Data type of B matrix elements
|
||||
LayoutTypeID layout_B, /// Layout of B matrix
|
||||
ComplexTransform transform_B, /// Complex transformation applied to B matrix - ignored for real-valued matrices
|
||||
|
||||
void const * ptr_B, /// Pointer to B matrix in Global Memory
|
||||
int ldb, /// Leading dimension of B matrix
|
||||
int64_t ldb, /// Leading dimension of B matrix
|
||||
|
||||
void const * beta, /// Pointer to beta scalar
|
||||
|
||||
NumericTypeID element_C, /// Data type of C and D matrices
|
||||
|
||||
void const * ptr_C, /// Pointer to C matrix
|
||||
int ldc, /// Leading dimension of C matrix
|
||||
int64_t ldc, /// Leading dimension of C matrix
|
||||
|
||||
void * ptr_D, /// Pointer to D matrix
|
||||
int ldd /// Leading dimension of D matrix
|
||||
int64_t ldd /// Leading dimension of D matrix
|
||||
) {
|
||||
|
||||
//
|
||||
@@ -494,24 +494,24 @@ Status Handle::gemm_universal(
|
||||
ComplexTransform transform_A, /// Complex transformation applied to A matrix - ignored for real-valued matrices
|
||||
|
||||
void const * ptr_A, /// Pointer to A matrix in Global Memory
|
||||
int lda, /// Leading dimension of A matrix
|
||||
int64_t lda, /// Leading dimension of A matrix
|
||||
|
||||
NumericTypeID element_B, /// Data type of B matrix elements
|
||||
LayoutTypeID layout_B, /// Layout of B matrix
|
||||
ComplexTransform transform_B, /// Complex transformation applied to B matrix - ignored for real-valued matrices
|
||||
|
||||
void const * ptr_B, /// Pointer to B matrix in Global Memory
|
||||
int ldb, /// Leading dimension of B matrix
|
||||
int64_t ldb, /// Leading dimension of B matrix
|
||||
|
||||
void const * beta, /// Pointer to beta scalar
|
||||
|
||||
NumericTypeID element_C, /// Data type of C and D matrices
|
||||
|
||||
void const * ptr_C, /// Pointer to C matrix
|
||||
int ldc, /// Leading dimension of C matrix
|
||||
int64_t ldc, /// Leading dimension of C matrix
|
||||
|
||||
void * ptr_D, /// Pointer to D matrix
|
||||
int ldd, /// Leading dimension of D matrix
|
||||
int64_t ldd, /// Leading dimension of D matrix
|
||||
|
||||
int batch_count, /// Batch count or number of split-K slices
|
||||
|
||||
@@ -672,8 +672,8 @@ Status Handle::gemm_planar_complex(
|
||||
|
||||
void const * ptr_A_real, /// Pointer to real part of A matrix
|
||||
void const * ptr_A_imag, /// Pointer to imaginary part of A matrix
|
||||
int lda_real, /// Leading dimension of real part of A matrix
|
||||
int lda_imag, /// Leading dimension of imaginary part of A matrix
|
||||
int64_t lda_real, /// Leading dimension of real part of A matrix
|
||||
int64_t lda_imag, /// Leading dimension of imaginary part of A matrix
|
||||
|
||||
NumericTypeID element_B, /// Data type of B matrix elements
|
||||
LayoutTypeID layout_B, /// Layout of B matrix
|
||||
@@ -681,8 +681,8 @@ Status Handle::gemm_planar_complex(
|
||||
|
||||
void const * ptr_B_real, /// Pointer to real part of B matrix
|
||||
void const * ptr_B_imag, /// Pointer to imaginary part of B matrix
|
||||
int ldb_real, /// Leading dimension of real part of B matrix
|
||||
int ldb_imag, /// Leading dimension of imaginary part of B matrix
|
||||
int64_t ldb_real, /// Leading dimension of real part of B matrix
|
||||
int64_t ldb_imag, /// Leading dimension of imaginary part of B matrix
|
||||
|
||||
void const * beta, /// Pointer to beta scalar
|
||||
|
||||
@@ -690,13 +690,13 @@ Status Handle::gemm_planar_complex(
|
||||
|
||||
void const * ptr_C_real, /// Pointer to real part of C matrix
|
||||
void const * ptr_C_imag, /// Pointer to imaginary part of C matrix
|
||||
int ldc_real, /// Leading dimension of real part of C matrix
|
||||
int ldc_imag, /// Leading dimension of imaginary part of C matrix
|
||||
int64_t ldc_real, /// Leading dimension of real part of C matrix
|
||||
int64_t ldc_imag, /// Leading dimension of imaginary part of C matrix
|
||||
|
||||
void * ptr_D_real, /// Pointer to real part of D matrix
|
||||
void * ptr_D_imag, /// Pointer to imaginary part of D matrix
|
||||
int ldd_real, /// Leading dimension of real part of D matrix
|
||||
int ldd_imag, /// Leading dimension of imaginary part of D matrix
|
||||
int64_t ldd_real, /// Leading dimension of real part of D matrix
|
||||
int64_t ldd_imag, /// Leading dimension of imaginary part of D matrix
|
||||
|
||||
int batch_count, /// Number of batched GEMMs to execute
|
||||
|
||||
@@ -877,8 +877,8 @@ Status Handle::gemm_planar_complex_array(
|
||||
void const * const * ptr_A_real, /// Pointer to array containing pointers to real part of A matrices
|
||||
void const * const * ptr_A_imag, /// Pointer to array containing pointers to imaginary part of A matrices
|
||||
|
||||
int lda_real, /// Leading dimension of real part of A matrix
|
||||
int lda_imag, /// Leading dimension of imaginary part of A matrix
|
||||
int64_t lda_real, /// Leading dimension of real part of A matrix
|
||||
int64_t lda_imag, /// Leading dimension of imaginary part of A matrix
|
||||
|
||||
NumericTypeID element_B, /// Data type of B matrix elements
|
||||
LayoutTypeID layout_B, /// Layout of B matrix
|
||||
@@ -887,8 +887,8 @@ Status Handle::gemm_planar_complex_array(
|
||||
void const * const * ptr_B_real, /// Pointer to array containing pointers to real part of B matrices
|
||||
void const * const * ptr_B_imag, /// Pointer to array containing pointers to imaginary part of B matrices
|
||||
|
||||
int ldb_real, /// Leading dimension of real part of B matrix
|
||||
int ldb_imag, /// Leading dimension of imaginary part of B matrix
|
||||
int64_t ldb_real, /// Leading dimension of real part of B matrix
|
||||
int64_t ldb_imag, /// Leading dimension of imaginary part of B matrix
|
||||
|
||||
void const * beta, /// Pointer to beta scalar
|
||||
|
||||
@@ -897,14 +897,14 @@ Status Handle::gemm_planar_complex_array(
|
||||
void const * const * ptr_C_real, /// Pointer to array containing pointers to real part of C matrices
|
||||
void const * const * ptr_C_imag, /// Pointer to array containing poitners to imaginary part of C matrices
|
||||
|
||||
int ldc_real, /// Leading dimension of real part of C matrix
|
||||
int ldc_imag, /// Leading dimension of imaginary part of C matrix
|
||||
int64_t ldc_real, /// Leading dimension of real part of C matrix
|
||||
int64_t ldc_imag, /// Leading dimension of imaginary part of C matrix
|
||||
|
||||
void * const * ptr_D_real, /// Pointer to array containing pointers to real part of D matrices
|
||||
void * const * ptr_D_imag, /// Pointer to array containing poitners to imaginary part of D matrices
|
||||
|
||||
int ldd_real, /// Leading dimension of real part of D matrix
|
||||
int ldd_imag /// Leading dimension of imaginary part of D matrix
|
||||
int64_t ldd_real, /// Leading dimension of real part of D matrix
|
||||
int64_t ldd_imag /// Leading dimension of imaginary part of D matrix
|
||||
) {
|
||||
|
||||
//
|
||||
|
||||
@@ -115,13 +115,19 @@ struct ConvReferenceDispatcher<
|
||||
layout::TensorNHWC layout_c;
|
||||
|
||||
layout_a.stride() =
|
||||
make_Coord(config.stride_a[0], config.stride_a[1], config.stride_a[2]);
|
||||
make_Coord(int32_t(config.stride_a[0]),
|
||||
int32_t(config.stride_a[1]),
|
||||
int32_t(config.stride_a[2]));
|
||||
|
||||
layout_b.stride() =
|
||||
make_Coord(config.stride_b[0], config.stride_b[1], config.stride_b[2]);
|
||||
make_Coord(int32_t(config.stride_b[0]),
|
||||
int32_t(config.stride_b[1]),
|
||||
int32_t(config.stride_b[2]));
|
||||
|
||||
layout_c.stride() =
|
||||
make_Coord(config.stride_c[0], config.stride_c[1], config.stride_c[2]);
|
||||
make_Coord(int32_t(config.stride_c[0]),
|
||||
int32_t(config.stride_c[1]),
|
||||
int32_t(config.stride_c[2]));
|
||||
|
||||
if (kProvider == Provider::kReferenceHost) {
|
||||
|
||||
|
||||
@@ -274,9 +274,9 @@ public:
|
||||
library::LayoutTypeID const &layout_a,
|
||||
library::LayoutTypeID const &layout_b,
|
||||
library::LayoutTypeID const &layout_c) {
|
||||
std::vector<int> stride_activations;
|
||||
std::vector<int> stride_filters;
|
||||
std::vector<int> stride_output;
|
||||
std::vector<int64_t> stride_activations;
|
||||
std::vector<int64_t> stride_filters;
|
||||
std::vector<int64_t> stride_output;
|
||||
|
||||
// Strides for interleaved fprop
|
||||
if (conv_kind == library::ConvKind::kFprop &&
|
||||
|
||||
@@ -268,7 +268,7 @@ public:
|
||||
A(nullptr), B(nullptr), C(nullptr), Computed(nullptr), Reference(nullptr) { }
|
||||
|
||||
// Returns stride vector for tensor A
|
||||
std::vector<int> stride_a(library::ConvKind const &conv_kind) {
|
||||
std::vector<int64_t> stride_a(library::ConvKind const &conv_kind) {
|
||||
return {
|
||||
configuration.layout_a(conv_kind).stride()[0],
|
||||
configuration.layout_a(conv_kind).stride()[1],
|
||||
@@ -278,7 +278,7 @@ public:
|
||||
}
|
||||
|
||||
// Returns stride vector for tensor B
|
||||
std::vector<int> stride_b(library::ConvKind const &conv_kind) {
|
||||
std::vector<int64_t> stride_b(library::ConvKind const &conv_kind) {
|
||||
|
||||
return {
|
||||
configuration.layout_b(conv_kind).stride()[0],
|
||||
@@ -289,7 +289,7 @@ public:
|
||||
}
|
||||
|
||||
// Returns stride vector for tensor C
|
||||
std::vector<int> stride_c(library::ConvKind const &conv_kind) {
|
||||
std::vector<int64_t> stride_c(library::ConvKind const &conv_kind) {
|
||||
|
||||
return {
|
||||
configuration.layout_c(conv_kind).stride()[0],
|
||||
|
||||
@@ -67,6 +67,15 @@ CutlassProfiler::~CutlassProfiler() {
|
||||
/// Execute the program
|
||||
int CutlassProfiler::operator()() {
|
||||
|
||||
if (options_.cmdline.num_naked_args() > 0) {
|
||||
std::cerr << "Unknown args: \n";
|
||||
options_.cmdline.print_naked_args(std::cerr);
|
||||
std::cerr << "\n\n\n";
|
||||
|
||||
print_usage_(std::cout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (options_.about.help) {
|
||||
if (options_.operation_kind == library::OperationKind::kInvalid) {
|
||||
print_usage_(std::cout);
|
||||
|
||||
@@ -54,7 +54,7 @@ size_t DeviceAllocation::bytes(library::NumericTypeID type, size_t capacity) {
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename Layout>
|
||||
static std::vector<int> get_packed_layout_stride(std::vector<int> const &extent) {
|
||||
static std::vector<int64_t> get_packed_layout_stride(std::vector<int> const &extent) {
|
||||
|
||||
typename Layout::TensorCoord extent_coord;
|
||||
typename Layout::Stride stride_coord;
|
||||
@@ -67,25 +67,25 @@ static std::vector<int> get_packed_layout_stride(std::vector<int> const &extent)
|
||||
extent_coord[i] = extent.at(i);
|
||||
}
|
||||
|
||||
std::vector<int> stride;
|
||||
std::vector<int64_t> stride;
|
||||
stride.resize(Layout::kStrideRank, 0);
|
||||
|
||||
Layout layout = Layout::packed(extent_coord);
|
||||
stride_coord = layout.stride();
|
||||
|
||||
for (int i = 0; i < Layout::kStrideRank; ++i) {
|
||||
stride.at(i) = stride_coord[i];
|
||||
stride.at(i) = (int64_t)stride_coord[i];
|
||||
}
|
||||
|
||||
return stride;
|
||||
}
|
||||
|
||||
/// Returns the stride of a packed layout
|
||||
std::vector<int> DeviceAllocation::get_packed_layout(
|
||||
std::vector<int64_t> DeviceAllocation::get_packed_layout(
|
||||
library::LayoutTypeID layout_id,
|
||||
std::vector<int> const &extent) {
|
||||
|
||||
std::vector<int> stride;
|
||||
std::vector<int64_t> stride;
|
||||
|
||||
switch (layout_id) {
|
||||
case library::LayoutTypeID::kColumnMajor:
|
||||
@@ -159,7 +159,7 @@ static size_t construct_layout_(
|
||||
void *bytes,
|
||||
library::LayoutTypeID layout_id,
|
||||
std::vector<int> const &extent,
|
||||
std::vector<int> &stride) {
|
||||
std::vector<int64_t> &stride) {
|
||||
|
||||
if (extent.size() != Layout::kRank) {
|
||||
throw std::runtime_error(
|
||||
@@ -183,7 +183,7 @@ static size_t construct_layout_(
|
||||
|
||||
typename Layout::Stride stride_coord;
|
||||
for (int i = 0; i < Layout::kStrideRank; ++i) {
|
||||
stride_coord[i] = stride.at(i);
|
||||
stride_coord[i] = (int)stride.at(i);
|
||||
}
|
||||
|
||||
typename Layout::TensorCoord extent_coord;
|
||||
@@ -210,7 +210,7 @@ size_t DeviceAllocation::construct_layout(
|
||||
void *bytes,
|
||||
library::LayoutTypeID layout_id,
|
||||
std::vector<int> const &extent,
|
||||
std::vector<int> &stride) {
|
||||
std::vector<int64_t> &stride) {
|
||||
|
||||
switch (layout_id) {
|
||||
case library::LayoutTypeID::kColumnMajor:
|
||||
@@ -309,7 +309,7 @@ DeviceAllocation::DeviceAllocation(
|
||||
library::NumericTypeID type,
|
||||
library::LayoutTypeID layout_id,
|
||||
std::vector<int> const &extent,
|
||||
std::vector<int> const &stride,
|
||||
std::vector<int64_t> const &stride,
|
||||
int batch_count
|
||||
):
|
||||
type_(type), batch_stride_(size_t(0)), capacity_(size_t(0)), pointer_(nullptr), batch_count_(1) {
|
||||
@@ -370,12 +370,12 @@ DeviceAllocation &DeviceAllocation::reset(
|
||||
library::NumericTypeID type,
|
||||
library::LayoutTypeID layout_id,
|
||||
std::vector<int> const &extent,
|
||||
std::vector<int> const &stride,
|
||||
std::vector<int64_t> const &stride,
|
||||
int batch_count) {
|
||||
|
||||
reset();
|
||||
|
||||
tensor_ref_buffer_.resize(sizeof(pointer_) + (sizeof(int) * library::get_layout_stride_rank(layout_id)), 0);
|
||||
tensor_ref_buffer_.resize(sizeof(pointer_) + (sizeof(int64_t) * library::get_layout_stride_rank(layout_id)), 0);
|
||||
|
||||
type_ = type;
|
||||
|
||||
@@ -422,7 +422,7 @@ library::LayoutTypeID DeviceAllocation::layout() const {
|
||||
return layout_;
|
||||
}
|
||||
|
||||
std::vector<int> const & DeviceAllocation::stride() const {
|
||||
std::vector<int64_t> const & DeviceAllocation::stride() const {
|
||||
return stride_;
|
||||
}
|
||||
|
||||
@@ -1277,6 +1277,15 @@ struct vector_to_coord {
|
||||
vector_to_coord<TensorCoord, Rank - 1>(coord, vec);
|
||||
}
|
||||
}
|
||||
|
||||
vector_to_coord(TensorCoord &coord, std::vector<int64_t> const &vec) {
|
||||
|
||||
coord[Rank - 1] = (int)vec.at(Rank - 1);
|
||||
|
||||
if (Rank > 1) {
|
||||
vector_to_coord<TensorCoord, Rank - 1>(coord, vec);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// Permits copying dynamic vectors into static-length vectors
|
||||
@@ -1287,6 +1296,11 @@ struct vector_to_coord<TensorCoord, 1> {
|
||||
|
||||
coord[0] = vec.at(0);
|
||||
}
|
||||
|
||||
vector_to_coord(TensorCoord &coord, std::vector<int64_t> const &vec) {
|
||||
|
||||
coord[0] = (int)vec.at(0);
|
||||
}
|
||||
};
|
||||
|
||||
/// Permits copying dynamic vectors into static-length vectors
|
||||
@@ -1306,7 +1320,7 @@ static void write_tensor_csv_static_tensor_view(
|
||||
DeviceAllocation &allocation) {
|
||||
|
||||
Coord<Layout::kRank> extent;
|
||||
Coord<Layout::kStrideRank> stride;
|
||||
Coord<Layout::kStrideRank, typename Layout::Stride::Index> stride;
|
||||
|
||||
if (allocation.extent().size() != Layout::kRank) {
|
||||
throw std::runtime_error("Allocation extent has invalid rank");
|
||||
@@ -1317,7 +1331,8 @@ static void write_tensor_csv_static_tensor_view(
|
||||
}
|
||||
|
||||
vector_to_coord<Coord<Layout::kRank>, Layout::kRank>(extent, allocation.extent());
|
||||
vector_to_coord<Coord<Layout::kStrideRank>, Layout::kStrideRank>(stride, allocation.stride());
|
||||
vector_to_coord<Coord<Layout::kStrideRank, typename Layout::Stride::Index>,
|
||||
Layout::kStrideRank>(stride, allocation.stride());
|
||||
|
||||
Layout layout(stride);
|
||||
HostTensor<Element, Layout> host_tensor(extent, layout, false);
|
||||
@@ -1498,6 +1513,162 @@ void DeviceAllocation::write_tensor_csv(
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Element, typename Layout>
|
||||
static void tensor_fill_tensor_view(DeviceAllocation &allocation, Element val = Element()) {
|
||||
Coord<Layout::kRank> extent;
|
||||
Coord<Layout::kStrideRank, typename Layout::LongIndex> stride;
|
||||
|
||||
if (allocation.extent().size() != Layout::kRank) {
|
||||
throw std::runtime_error("Allocation extent has invalid rank");
|
||||
}
|
||||
|
||||
if (allocation.stride().size() != Layout::kStrideRank) {
|
||||
throw std::runtime_error("Allocation stride has invalid rank");
|
||||
}
|
||||
|
||||
vector_to_coord<Coord<Layout::kRank>, Layout::kRank>(extent, allocation.extent());
|
||||
vector_to_coord<Coord<Layout::kStrideRank, typename Layout::LongIndex>,
|
||||
Layout::kStrideRank>(stride, allocation.stride());
|
||||
|
||||
TensorView<Element, Layout> view(
|
||||
static_cast<Element *>(allocation.data()),
|
||||
Layout(stride),
|
||||
extent
|
||||
);
|
||||
|
||||
|
||||
cutlass::reference::device::TensorFill<Element, Layout>(
|
||||
view,
|
||||
val
|
||||
);
|
||||
}
|
||||
|
||||
template <typename Element>
|
||||
static void tensor_fill(DeviceAllocation &allocation, Element val = Element()) {
|
||||
switch (allocation.layout()) {
|
||||
case library::LayoutTypeID::kRowMajor:
|
||||
tensor_fill_tensor_view<Element, layout::RowMajor>(allocation, val);
|
||||
break;
|
||||
case library::LayoutTypeID::kColumnMajor:
|
||||
tensor_fill_tensor_view<Element, layout::ColumnMajor>(allocation, val);
|
||||
break;
|
||||
case library::LayoutTypeID::kTensorNHWC:
|
||||
tensor_fill_tensor_view<Element, layout::TensorNHWC>(allocation, val);
|
||||
break;
|
||||
case library::LayoutTypeID::kTensorNDHWC:
|
||||
tensor_fill_tensor_view<Element, layout::TensorNDHWC>(allocation, val);
|
||||
break;
|
||||
case library::LayoutTypeID::kTensorNC32HW32:
|
||||
tensor_fill_tensor_view<Element, layout::TensorNCxHWx<32>>(allocation, val);
|
||||
break;
|
||||
case library::LayoutTypeID::kTensorNC64HW64:
|
||||
tensor_fill_tensor_view<Element, layout::TensorNCxHWx<64>>(allocation, val);
|
||||
break;
|
||||
case library::LayoutTypeID::kTensorC32RSK32:
|
||||
tensor_fill_tensor_view<Element, layout::TensorCxRSKx<32>>(allocation, val);
|
||||
break;
|
||||
case library::LayoutTypeID::kTensorC64RSK64:
|
||||
tensor_fill_tensor_view<Element, layout::TensorCxRSKx<64>>(allocation, val);
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Unsupported layout");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// Fills a tensor uniformly with a value (most frequently used to clear the tensor)
|
||||
void DeviceAllocation::fill(double val = 0.0) {
|
||||
|
||||
switch (this->type()) {
|
||||
case library::NumericTypeID::kF16:
|
||||
tensor_fill<half_t>(*this, static_cast<half_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kBF16:
|
||||
tensor_fill<bfloat16_t>(*this, static_cast<bfloat16_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kTF32:
|
||||
tensor_fill<tfloat32_t>(*this, static_cast<tfloat32_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kF32:
|
||||
tensor_fill<float>(*this, static_cast<float>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kF64:
|
||||
tensor_fill<double>(*this, static_cast<double>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kS2:
|
||||
tensor_fill<int2b_t>(*this, static_cast<int2b_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kS4:
|
||||
tensor_fill<int4b_t>(*this, static_cast<int4b_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kS8:
|
||||
tensor_fill<int8_t>(*this, static_cast<int8_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kS16:
|
||||
tensor_fill<int16_t>(*this, static_cast<int16_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kS32:
|
||||
tensor_fill<int32_t>(*this, static_cast<int32_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kS64:
|
||||
tensor_fill<int64_t>(*this, static_cast<int64_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kB1:
|
||||
tensor_fill<uint1b_t>(*this, static_cast<uint1b_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kU2:
|
||||
tensor_fill<uint2b_t>(*this, static_cast<uint2b_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kU4:
|
||||
tensor_fill<uint4b_t>(*this, static_cast<uint4b_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kU8:
|
||||
tensor_fill<uint8_t>(*this, static_cast<uint8_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kU16:
|
||||
tensor_fill<uint16_t>(*this, static_cast<uint16_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kU32:
|
||||
tensor_fill<uint32_t>(*this, static_cast<uint32_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kU64:
|
||||
tensor_fill<uint64_t>(*this, static_cast<uint64_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kCF16:
|
||||
tensor_fill<cutlass::complex<half_t> >(*this, from_real<half_t>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kCF32:
|
||||
tensor_fill<cutlass::complex<float> >(*this, from_real<float>(val));
|
||||
break;
|
||||
|
||||
case library::NumericTypeID::kCF64:
|
||||
tensor_fill<cutlass::complex<double> >(*this, from_real<double>(val));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw std::runtime_error("Unsupported numeric type");
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace profiler
|
||||
|
||||
@@ -64,7 +64,7 @@ private:
|
||||
library::LayoutTypeID layout_;
|
||||
|
||||
/// Stride vector
|
||||
std::vector<int> stride_;
|
||||
std::vector<int64_t> stride_;
|
||||
|
||||
/// Extent vector
|
||||
std::vector<int> extent_;
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
static size_t bytes(library::NumericTypeID type, size_t capacity);
|
||||
|
||||
/// Returns the stride of a packed layout
|
||||
static std::vector<int> get_packed_layout(
|
||||
static std::vector<int64_t> get_packed_layout(
|
||||
library::LayoutTypeID layout_id,
|
||||
std::vector<int> const &extent);
|
||||
|
||||
@@ -93,7 +93,7 @@ public:
|
||||
void *bytes,
|
||||
library::LayoutTypeID layout_id,
|
||||
std::vector<int> const &extent,
|
||||
std::vector<int> &stride);
|
||||
std::vector<int64_t> &stride);
|
||||
|
||||
/// Returns true if two blocks have exactly the same value
|
||||
static bool block_compare_equal(
|
||||
@@ -124,7 +124,7 @@ public:
|
||||
library::NumericTypeID type,
|
||||
library::LayoutTypeID layout_id,
|
||||
std::vector<int> const &extent,
|
||||
std::vector<int> const &stride = std::vector<int>(),
|
||||
std::vector<int64_t> const &stride = std::vector<int64_t>(),
|
||||
int batch_count = 1);
|
||||
|
||||
~DeviceAllocation();
|
||||
@@ -139,7 +139,7 @@ public:
|
||||
library::NumericTypeID type,
|
||||
library::LayoutTypeID layout_id,
|
||||
std::vector<int> const &extent,
|
||||
std::vector<int> const &stride = std::vector<int>(),
|
||||
std::vector<int64_t> const &stride = std::vector<int64_t>(),
|
||||
int batch_count = 1);
|
||||
|
||||
/// Returns a buffer owning the tensor reference
|
||||
@@ -162,7 +162,7 @@ public:
|
||||
library::LayoutTypeID layout() const;
|
||||
|
||||
/// Gets the stride vector
|
||||
std::vector<int> const & stride() const;
|
||||
std::vector<int64_t> const & stride() const;
|
||||
|
||||
/// Gets the extent vector
|
||||
std::vector<int> const & extent() const;
|
||||
@@ -193,6 +193,9 @@ public:
|
||||
|
||||
/// Initializes a host allocation to a random distribution using std::cout
|
||||
void initialize_random_sparsemeta_host(int seed, int MetaSizeInBits);
|
||||
|
||||
/// Uniformly fills a tensor with a value when provided o.w. zero
|
||||
void fill(double value);
|
||||
|
||||
/// Copies from an equivalent-sized tensor in device memory
|
||||
void copy_from_device(void const *ptr);
|
||||
|
||||
@@ -52,7 +52,7 @@ DeviceAllocation *DeviceContext::allocate_tensor(
|
||||
library::NumericTypeID type,
|
||||
library::LayoutTypeID layout_id,
|
||||
std::vector<int> const &extent,
|
||||
std::vector<int> const &stride,
|
||||
std::vector<int64_t> const &stride,
|
||||
int batch_count) {
|
||||
|
||||
device_memory_.emplace_back(type, layout_id, extent, stride, batch_count);
|
||||
@@ -69,7 +69,7 @@ DeviceAllocation *DeviceContext::allocate_tensor(
|
||||
library::NumericTypeID type,
|
||||
library::LayoutTypeID layout_id,
|
||||
std::vector<int> const &extent,
|
||||
std::vector<int> const &stride,
|
||||
std::vector<int64_t> const &stride,
|
||||
int batch_count) {
|
||||
|
||||
DeviceAllocation *allocation =
|
||||
@@ -133,7 +133,7 @@ DeviceAllocation *DeviceContext::allocate_sparsemeta_tensor(
|
||||
library::LayoutTypeID layout_id,
|
||||
library::NumericTypeID type_a,
|
||||
std::vector<int> const &extent,
|
||||
std::vector<int> const &stride,
|
||||
std::vector<int64_t> const &stride,
|
||||
int batch_count) {
|
||||
|
||||
DeviceAllocation *allocation =
|
||||
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
library::NumericTypeID type,
|
||||
library::LayoutTypeID layout_id,
|
||||
std::vector<int> const &extent,
|
||||
std::vector<int> const &stride = std::vector<int>(),
|
||||
std::vector<int64_t> const &stride = std::vector<int64_t>(),
|
||||
int batch_count = 1);
|
||||
|
||||
/// Allocates memory of a given type, capacity (elements), and name
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
library::NumericTypeID type,
|
||||
library::LayoutTypeID layout_id,
|
||||
std::vector<int> const &extent,
|
||||
std::vector<int> const &stride = std::vector<int>(),
|
||||
std::vector<int64_t> const &stride = std::vector<int64_t>(),
|
||||
int batch_count = 1);
|
||||
|
||||
/// Allocates memory for sparse meta data
|
||||
@@ -98,7 +98,7 @@ public:
|
||||
library::LayoutTypeID layout_id,
|
||||
library::NumericTypeID type_a,
|
||||
std::vector<int> const &extent,
|
||||
std::vector<int> const &stride = std::vector<int>(),
|
||||
std::vector<int64_t> const &stride = std::vector<int64_t>(),
|
||||
int batch_count = 1);
|
||||
|
||||
/// Clears named allocations (but does not necessarily free memory)
|
||||
|
||||
@@ -90,11 +90,19 @@ struct CommandLine {
|
||||
/**
|
||||
* Returns number of naked (non-flag and non-key-value) commandline parameters
|
||||
*/
|
||||
template <typename value_t>
|
||||
int num_naked_args() const {
|
||||
size_t num_naked_args() const {
|
||||
return args.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print naked (non-flag and non-key-value) commandline parameters
|
||||
*/
|
||||
void print_naked_args(std::ostream &out) const {
|
||||
for (auto arg : args) {
|
||||
out << " " << arg <<"\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the commandline parameter for a given index (not including flags)
|
||||
*/
|
||||
|
||||
@@ -325,12 +325,12 @@ public:
|
||||
}
|
||||
|
||||
/// Returns the layout object's stride in a given physical dimension
|
||||
Index stride(int dim) const {
|
||||
LongIndex stride(int dim) const {
|
||||
return layout_.stride().at(dim);
|
||||
}
|
||||
|
||||
/// Returns the layout object's stride in a given physical dimension
|
||||
Index & stride(int dim) {
|
||||
LongIndex & stride(int dim) {
|
||||
return layout_.stride().at(dim);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/***************************************************************************************************
|
||||
* Copyright (c) 2017-2021, 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.
|
||||
*
|
||||
**************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include "cutlass/cutlass.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief C++11 version of index_sequence.
|
||||
*/
|
||||
|
||||
namespace cutlass {
|
||||
|
||||
template <size_t... Seq>
|
||||
struct index_sequence;
|
||||
|
||||
template <size_t N, size_t... Next>
|
||||
struct index_sequence_helper : index_sequence_helper<N - 1, N - 1, Next...> {};
|
||||
|
||||
template <size_t... Next>
|
||||
struct index_sequence_helper<0, 0, Next...> {
|
||||
using type = index_sequence<0, Next...>;
|
||||
};
|
||||
|
||||
template <size_t N>
|
||||
using make_index_sequence = typename index_sequence_helper<N>::type;
|
||||
|
||||
} // namespace cutlass
|
||||
@@ -65,8 +65,8 @@ __global__ void Gemm(
|
||||
|
||||
// Map each thread to a unique tile of the output matrix
|
||||
MatrixCoord output_coord(
|
||||
(threadIdx.x + blockIdx.x * blockDim.x) * OutputTile::kRow,
|
||||
(threadIdx.y + blockIdx.y * blockDim.y) * OutputTile::kColumn
|
||||
MatrixCoord::Index((threadIdx.x + blockIdx.x * blockDim.x) * OutputTile::kRow),
|
||||
MatrixCoord::Index((threadIdx.y + blockIdx.y * blockDim.y) * OutputTile::kColumn)
|
||||
);
|
||||
|
||||
// Compute the general matrix product
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "cutlass/conv/convolution.h"
|
||||
#include "cutlass/conv/conv2d_problem_size.h"
|
||||
#include "cutlass/conv/conv3d_problem_size.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace cutlass {
|
||||
namespace reference {
|
||||
@@ -243,7 +244,21 @@ void Conv2dDgrad(
|
||||
|
||||
p = p / problem_size.stride_h;
|
||||
q = q / problem_size.stride_w;
|
||||
|
||||
#if 0
|
||||
std::cout << "row:"
|
||||
<< n * problem_size.H * problem_size.W +
|
||||
h * problem_size.W +
|
||||
w << " "
|
||||
<< "n, p, q: ("
|
||||
<< n << ", "
|
||||
<< p << ", "
|
||||
<< q << ") * "
|
||||
<< "r, s: ("
|
||||
<< r << ", "
|
||||
<< s << ") ["
|
||||
<< ((p < problem_size.P && q < problem_size.Q) ? "true":"false") << "]"
|
||||
<< std::endl;
|
||||
#endif
|
||||
if (p < problem_size.P && q < problem_size.Q) {
|
||||
|
||||
ElementA a = tensor_dy.at(cutlass::make_Coord(n, p, q, k));
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
|
||||
/***************************************************************************************************
|
||||
* Copyright (c) 2017-2021, 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.
|
||||
*
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "cutlass/cutlass.h"
|
||||
#include "cutlass/complex.h"
|
||||
#include "cutlass/util/reference/host/tensor_reduce.h"
|
||||
#include "cutlass/core_io.h"
|
||||
|
||||
namespace cutlass {
|
||||
namespace reference {
|
||||
namespace host {
|
||||
|
||||
/// Helper to compute the relative error metric for tensor A_computed w.r.t. to tensor A_reference
|
||||
template <
|
||||
typename Element,
|
||||
typename Layout,
|
||||
typename ComputeType = double
|
||||
>
|
||||
ComputeType TensorRelativeErrorMetric(
|
||||
TensorView<Element, Layout> view_A_computed,
|
||||
TensorView<Element, Layout> view_B_reference,
|
||||
ComputeType identity = ComputeType()
|
||||
) {
|
||||
|
||||
return cutlass::reference::host::TensorNormDiff(view_A_computed, view_B_reference, identity) /
|
||||
cutlass::reference::host::TensorNorm(view_B_reference, identity);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace host
|
||||
} // namespace reference
|
||||
} // namespace cutlass
|
||||
@@ -36,6 +36,7 @@
|
||||
// Cutlass includes
|
||||
#include "cutlass/cutlass.h"
|
||||
#include "cutlass/complex.h"
|
||||
#include "cutlass/quaternion.h"
|
||||
#include "cutlass/array.h"
|
||||
#include "cutlass/numeric_types.h"
|
||||
#include "cutlass/subbyte_reference.h"
|
||||
@@ -219,6 +220,56 @@ struct RandomGaussianFunc<complex<Element> > {
|
||||
}
|
||||
};
|
||||
|
||||
/// Partial specialization for initializing a complex value.
|
||||
template <typename Element>
|
||||
struct RandomGaussianFunc<Quaternion<Element> > {
|
||||
|
||||
uint64_t seed;
|
||||
double mean;
|
||||
double stddev;
|
||||
int int_scale;
|
||||
double pi;
|
||||
|
||||
//
|
||||
// Methods
|
||||
//
|
||||
RandomGaussianFunc(
|
||||
uint64_t seed_ = 0,
|
||||
double mean_ = 0,
|
||||
double stddev_ = 1,
|
||||
int int_scale_ = -1
|
||||
):
|
||||
seed(seed_), mean(mean_), stddev(stddev_), int_scale(int_scale_), pi(std::acos(-1)) {
|
||||
std::srand((unsigned)seed);
|
||||
}
|
||||
|
||||
/// Compute random value and update RNG state
|
||||
Quaternion<Element> operator()() const {
|
||||
|
||||
Element reals[4];
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
// Box-Muller transform to generate random numbers with Normal distribution
|
||||
double u1 = double(std::rand()) / double(RAND_MAX);
|
||||
double u2 = double(std::rand()) / double(RAND_MAX);
|
||||
|
||||
// Compute Gaussian random value
|
||||
double rnd = std::sqrt(-2 * std::log(u1)) * std::cos(2 * pi * u2);
|
||||
rnd = mean + stddev * rnd;
|
||||
|
||||
if (int_scale >= 0) {
|
||||
rnd = double(int(rnd * double(1 << int_scale)));
|
||||
reals[i] = from_real<Element>(rnd / double(1 << int_scale));
|
||||
}
|
||||
else {
|
||||
reals[i] = from_real<Element>(rnd);
|
||||
}
|
||||
}
|
||||
|
||||
return Quaternion<Element>(reals[0], reals[1], reals[2], reals[3]);
|
||||
}
|
||||
};
|
||||
|
||||
/// Computes a random Gaussian distribution
|
||||
template <
|
||||
typename Element, ///< Element type
|
||||
@@ -429,6 +480,58 @@ struct RandomUniformFunc<complex<Element> > {
|
||||
}
|
||||
};
|
||||
|
||||
/// Partial specialization for initializing a Quaternion value.
|
||||
template <typename Element>
|
||||
struct RandomUniformFunc<Quaternion<Element> > {
|
||||
|
||||
using Real = typename RealType<Element>::Type;
|
||||
|
||||
uint64_t seed;
|
||||
double range;
|
||||
double min;
|
||||
int int_scale;
|
||||
|
||||
//
|
||||
// Methods
|
||||
//
|
||||
|
||||
RandomUniformFunc(
|
||||
uint64_t seed_ = 0,
|
||||
double max = 1,
|
||||
double min_ = 0,
|
||||
int int_scale_ = -1
|
||||
):
|
||||
seed(seed_), range(max - min_), min(min_), int_scale(int_scale_) {
|
||||
std::srand((unsigned)seed);
|
||||
}
|
||||
|
||||
|
||||
/// Compute random value and update RNG state
|
||||
Quaternion<Element> operator()() const {
|
||||
|
||||
Element reals[4];
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
double rnd = double(std::rand()) / double(RAND_MAX);
|
||||
|
||||
rnd = min + range * rnd;
|
||||
|
||||
// Random values are cast to integer after scaling by a power of two to facilitate error
|
||||
// testing
|
||||
|
||||
if (int_scale >= 0) {
|
||||
rnd = double(int(rnd * double(1 << int_scale)));
|
||||
reals[i] = from_real<Element>(Real(rnd / double(1 << int_scale)));
|
||||
}
|
||||
else {
|
||||
reals[i] = from_real<Element>(Real(rnd));
|
||||
}
|
||||
}
|
||||
|
||||
return make_Quaternion(reals[0], reals[1], reals[2], reals[3]);
|
||||
}
|
||||
};
|
||||
|
||||
/// Computes a random Gaussian distribution
|
||||
template <
|
||||
typename Element, ///< Element type
|
||||
@@ -510,6 +613,32 @@ void TensorFillRandomUniform(
|
||||
TensorFillRandomUniform(dst.view_imag(), ~seed, max, min, bits);
|
||||
}
|
||||
|
||||
|
||||
/// Fills a tensor with random values with a uniform random distribution.
|
||||
template <
|
||||
typename Element, ///< Element type
|
||||
typename Layout> ///< Layout function
|
||||
void TensorFillRandomUniform(
|
||||
TensorView<Quaternion<Element>, Layout> dst, ///< destination tensor
|
||||
uint64_t seed, ///< seed for RNG
|
||||
double max = 1, ///< upper bound of distribution
|
||||
double min = 0, ///< lower bound for distribution
|
||||
int bits = -1) { ///< If non-negative, specifies number of fractional bits that
|
||||
/// are not truncated to zero. Permits reducing precision of
|
||||
/// data.
|
||||
detail::RandomUniformFunc<Quaternion<Element>> random_func(seed, max, min, bits);
|
||||
|
||||
detail::TensorFillRandomUniformFunc<Quaternion<Element>, Layout> func(
|
||||
dst,
|
||||
random_func
|
||||
);
|
||||
|
||||
TensorForEach(
|
||||
dst.extent(),
|
||||
func
|
||||
);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Fills a tensor with random values with a uniform random distribution.
|
||||
template <
|
||||
|
||||
Reference in New Issue
Block a user