v3.8.0 update (#2082)

* 3.8 update

* fix Markus' name

---------

Co-authored-by: yuzhai <yuzhai@nvidia.com>
This commit is contained in:
Yujia Zhai
2025-02-06 21:33:40 -05:00
committed by GitHub
co-authored by yuzhai
parent affd1b693d
commit 833f6990e0
168 changed files with 24945 additions and 3436 deletions
@@ -108,6 +108,8 @@ public:
bool use_pdl{false};
bool enable_sm90_mixed_dtype_shuffle_test{false};
//
// Methods
//
@@ -160,6 +162,13 @@ public:
/// Buffer used for the cutlass reduction operations' host workspace
std::vector<uint8_t> reduction_host_workspace;
/// For mixed input dtype kernels
DeviceAllocation *Scale{nullptr}; // Scale tensor
DeviceAllocation *Zero{nullptr}; // Zero tensor
DeviceAllocation *dequantized_AB{nullptr}; // Dequantized A or B tensor for verification
DeviceAllocation *encoded_AB{nullptr}; // Encoded A or B in int4 x fp8 or shuffle
DeviceAllocation *packed_Scale{nullptr}; // Packed scale for int4 * fp8
cudaStream_t stream;
};
@@ -0,0 +1,263 @@
/***************************************************************************************************
* Copyright (c) 2025 - 2025 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 GroupedGemm Profiler
*/
#pragma once
#include <algorithm>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
// CUTLASS Library includes
#include "cutlass/library/library.h"
// Profiler includes
#include "device_context.h"
#include "operation_profiler.h"
#include "options.h"
#include "performance_result.h"
#include "problem_space.h"
/////////////////////////////////////////////////////////////////////////////////////////////////
namespace cutlass {
namespace profiler {
/////////////////////////////////////////////////////////////////////////////////////////////////
/// Abstract base class for each math function
class GroupedGemmOperationProfiler : public OperationProfiler {
public:
/// Problem structure obtained from problem space
struct GroupedGemmProblem {
cutlass::library::GemmUniversalMode mode{library::GemmUniversalMode::kGrouped};
std::vector<gemm::GemmCoord> problem_sizes;
std::vector<cute::Shape<int, int, int>> problem_sizes_3x;
int cluster_m{1};
int cluster_n{1};
int cluster_k{1};
int cluster_m_fallback{1};
int cluster_n_fallback{1};
int cluster_k_fallback{1};
std::vector<int64_t> lda{0};
std::vector<int64_t> ldb{0};
std::vector<int64_t> ldc{0};
std::vector<uint8_t> alpha;
std::vector<uint8_t> beta;
/// Parses the problem
Status parse(
library::GemmDescription const& operation_desc,
ProblemSpace const& problem_space,
ProblemSpace::Problem const& problem);
int64_t m(int group_idx) const { return problem_sizes[group_idx].m(); };
int64_t n(int group_idx) const { return problem_sizes[group_idx].n(); };
int64_t k(int group_idx) const { return problem_sizes[group_idx].k(); };
/// Total number of bytes loaded
int64_t bytes(library::GemmDescription const& operation_desc) const;
/// Total number of flops computed
int64_t flops(library::GemmDescription const& operation_desc) const;
/// Initializes a performance result
void initialize_result(
PerformanceResult& result,
library::GemmDescription const& operation_desc,
ProblemSpace const& problem_space);
};
// workspace contains the allocated blocks, arguments just contain the raw
// pointers
struct GroupedGemmWorkspace {
std::vector<DeviceAllocation*> A_ptr_array_device;
std::vector<DeviceAllocation*> B_ptr_array_device;
std::vector<DeviceAllocation*> C_ptr_array_device;
std::vector<DeviceAllocation*> D_ptr_array_device;
std::vector<DeviceAllocation*> reference_ptr_array_host;
std::vector<DeviceAllocation*> A_ptr_array_host;
std::vector<DeviceAllocation*> B_ptr_array_host;
std::vector<DeviceAllocation*> C_ptr_array_host;
std::vector<DeviceAllocation*> D_ptr_array_host;
/// Number of copies of the problem workspace which are visited sequentially during
/// profiling to avoid camping in the last level cache.
/// *NOT* the number of groups in the grouped GEMM
int problem_count{1};
DeviceAllocation* problem_sizes_array_device{nullptr};
DeviceAllocation* problem_sizes_3x_array_device{nullptr};
DeviceAllocation* lda_array_device{nullptr};
DeviceAllocation* ldb_array_device{nullptr};
DeviceAllocation* ldc_array_device{nullptr};
DeviceAllocation* ldd_array_device{nullptr};
library::GemmGroupedConfiguration configuration;
library::GemmGroupedArguments arguments;
std::vector<uint8_t> host_workspace;
DeviceAllocation device_workspace;
};
private:
void init_arguments(Options const& options) {
gemm_workspace_.arguments.ptr_A = gemm_workspace_.A_ptr_array_device[0]->data();
gemm_workspace_.arguments.ptr_B = gemm_workspace_.B_ptr_array_device[0]->data();
gemm_workspace_.arguments.ptr_C = gemm_workspace_.C_ptr_array_device[0]->data();
gemm_workspace_.arguments.ptr_D = gemm_workspace_.D_ptr_array_device[0]->data();
gemm_workspace_.arguments.alpha = problem_.alpha.data();
gemm_workspace_.arguments.beta = problem_.beta.data();
gemm_workspace_.arguments.pointer_mode = library::ScalarPointerMode::kHost;
gemm_workspace_.arguments.lda = static_cast<int64_t*>(gemm_workspace_.lda_array_device->data());
gemm_workspace_.arguments.ldb = static_cast<int64_t*>(gemm_workspace_.ldb_array_device->data());
gemm_workspace_.arguments.ldc = static_cast<int64_t*>(gemm_workspace_.ldc_array_device->data());
gemm_workspace_.arguments.ldd = static_cast<int64_t*>(gemm_workspace_.ldc_array_device->data());
gemm_workspace_.arguments.problem_sizes =
static_cast<gemm::GemmCoord*>(gemm_workspace_.problem_sizes_array_device->data());
gemm_workspace_.arguments.problem_sizes_3x = static_cast<cute::Shape<int, int, int>*>(
gemm_workspace_.problem_sizes_3x_array_device->data());
gemm_workspace_.arguments.problem_sizes_3x_host = problem_.problem_sizes_3x.data();
gemm_workspace_.arguments.problem_count = problem_.problem_sizes.size();
gemm_workspace_.arguments.cluster_shape = {int(problem_.cluster_m), int(problem_.cluster_n), int(problem_.cluster_k)};
gemm_workspace_.arguments.cluster_shape_fallback = {int(problem_.cluster_m_fallback), int(problem_.cluster_n_fallback), int(problem_.cluster_k_fallback)};
/* Query device SM count to pass onto the kernel as an argument, where needed */
gemm_workspace_.arguments.sm_count = options.device.properties[0].multiProcessorCount;
}
protected:
/// GEMM problem obtained from problem space
GroupedGemmProblem problem_;
/// Device memory allocations
GroupedGemmWorkspace gemm_workspace_;
public:
GroupedGemmOperationProfiler(Options const& options);
virtual ~GroupedGemmOperationProfiler();
GroupedGemmProblem const& problem() const { return problem_; }
/// Prints usage statement for the math function
virtual void print_usage(std::ostream& out) const;
/// Prints examples
virtual void print_examples(std::ostream& out) const;
/// Extracts the problem dimensions
virtual Status initialize_configuration(
Options const& options,
PerformanceReport& report,
DeviceContext& device_context,
library::Operation const* operation,
ProblemSpace const& problem_space,
ProblemSpace::Problem const& problem);
/// Initializes workspace
virtual Status initialize_workspace(
Options const& options,
PerformanceReport& report,
DeviceContext& device_context,
library::Operation const* operation,
ProblemSpace const& problem_space,
ProblemSpace::Problem const& problem);
/// Verifies CUTLASS against references
virtual bool verify_cutlass(
Options const& options,
PerformanceReport& report,
DeviceContext& device_context,
library::Operation const* operation,
ProblemSpace const& problem_space,
ProblemSpace::Problem const& problem);
/// Measures performance results
virtual bool profile(
Options const& options,
PerformanceReport& report,
DeviceContext& device_context,
library::Operation const* operation,
ProblemSpace const& problem_space,
ProblemSpace::Problem const& problem);
protected:
/// Initializes the performance result
void initialize_result_(
PerformanceResult& result,
Options const& options,
library::GemmDescription const& operation_desc,
ProblemSpace const& problem_space);
/// Verifies CUTLASS against host and device references
bool verify_with_reference_(
Options const& options,
PerformanceReport& report,
DeviceContext& device_context,
library::Operation const* operation,
ProblemSpace const& problem_space,
ProblemSpace::Problem const& problem,
cutlass::library::NumericTypeID element_A,
cutlass::library::NumericTypeID element_B);
/// Method to profile a CUTLASS Operation
Status profile_cutlass_(
PerformanceResult& result,
Options const& options,
library::Operation const* operation,
void* arguments,
void* host_workspace,
void* device_workspace) override;
/// Initialize reduction problem dimensions and library::Operation
bool initialize_reduction_configuration_(
library::Operation const* operation,
ProblemSpace::Problem const& problem);
};
/////////////////////////////////////////////////////////////////////////////////////////////////
} // namespace profiler
} // namespace cutlass
/////////////////////////////////////////////////////////////////////////////////////////////////
@@ -241,17 +241,30 @@ protected:
/// Profiles the GPU kernel launched in `func` running simultaneously on all
/// requested devices.
Status profile_kernel_w_cuda_graphs_(
PerformanceResult& result,
Options const& options,
std::function<Status(int, cudaStream_t, int)> const& func,
std::vector<cudaStream_t> const& streams);
Status profile_kernel_(
PerformanceResult &result,
Options const &options,
const std::function<Status(int, cudaStream_t, int)> &func,
const std::vector<cudaStream_t> &streams);
PerformanceResult& result,
Options const& options,
std::function<Status(int, cudaStream_t, int)> const& func,
std::vector<cudaStream_t> const& streams);
/// Profiles the GPU kernel launched in `func` on the `stream`
Status profile_kernel_(
PerformanceResult &result,
Options const &options,
const std::function<Status(cudaStream_t, int)> &func,
PerformanceResult& result,
Options const& options,
std::function<Status(cudaStream_t, int)> const& func,
cudaStream_t stream = nullptr);
/// Profiles the GPU kernel launched in `func` on the `stream`
Status profile_kernel_no_cuda_graphs_(
PerformanceResult& result,
Options const& options,
std::function<Status(cudaStream_t, int)> const& func,
cudaStream_t stream = nullptr);
private:
@@ -208,6 +208,8 @@ public:
/// Minimum number of iterations to profile
int min_iterations{10};
bool use_cuda_graphs{false};
/// Number of ms to sleep between profiling periods (ms)
int sleep_duration{50};
@@ -988,6 +988,12 @@ bool arg_as_scalar(
ProblemSpace const &problem_space,
ProblemSpace::Problem const &problem);
bool arg_as_string(
std::string& arg,
char const* name,
ProblemSpace const& problem_space,
ProblemSpace::Problem const& problem);
/// Returns true if a tensor description satisfies a `tensor` value
bool tensor_description_satisfies(
library::TensorDescription const &tensor_desc,