CUTLASS 3.6.0 (#1850)

* v3.6

* update changelog

* update readme

* fix typo

* fixing typos

* hopper gemm with weight prefetch

---------

Co-authored-by: yuzhai <yuzhai@nvidia.com>
Co-authored-by: Haicheng Wu <haichengw@nvidia.com>
This commit is contained in:
Yujia Zhai
2024-10-09 15:33:27 -04:00
committed by GitHub
co-authored by yuzhai Haicheng Wu
parent 0837a2a00a
commit cc3c29a81a
354 changed files with 105937 additions and 8197 deletions
+122 -62
View File
@@ -33,6 +33,7 @@
*/
#include <algorithm>
#include <set>
#include "cutlass/cutlass.h"
#include "cutlass/version.h"
@@ -55,45 +56,97 @@ static char const *end_of_line = "\n
Options::Device::Device(cutlass::CommandLine const &cmdline) {
cmdline.get_cmd_line_argument("device", device, 0);
// Gets the number of devices for future validation
cudaError_t result;
result = cudaGetDeviceProperties(&properties, device);
result = cudaGetDeviceCount(&num_devices);
if (result != cudaSuccess) {
throw std::runtime_error("cudaGetDeviceProperties() failed for given device");
throw std::runtime_error("cudaGetNumDevices() failed");
}
result = cudaSetDevice(device);
if (result != cudaSuccess) {
throw std::runtime_error("cudaSetDevice() failed for given device.");
}
// Permit overriding the compute capability
if (cmdline.check_cmd_line_flag("compute-capability")) {
int cc = compute_capability();
cmdline.get_cmd_line_argument("compute-capability", cc, cc);
properties.major = cc / 10;
properties.minor = cc % 10;
}
// Permit overriding the L2 cache capacity
if (cmdline.check_cmd_line_flag("llc-capacity")) {
int llc_capacity = 0;
cmdline.get_cmd_line_argument("llc-capacity", llc_capacity, 0);
if (llc_capacity >= 0) {
properties.l2CacheSize = (llc_capacity << 10);
// Gets the devices specified by the user
// This preserves the user specified order and checks for duplicates
{
std::vector<int> temp_device_list;
cmdline.get_cmd_line_arguments("devices", temp_device_list);
if (temp_device_list.empty()) {
temp_device_list.push_back(0);
}
{
std::set<int> temp_device_set;
for (int device : temp_device_list) {
auto res = temp_device_set.insert(device);
if (!res.second) {
throw std::runtime_error("Duplicate device specified: " +
std::to_string(device));
} else if (device > num_devices) {
throw std::runtime_error("Bad device ID: " +
std::to_string(device));
} else {
devices.push_back(device);
}
}
}
}
properties.resize(devices.size());
// Retrieves properties for all specified devices
for (size_t device_index = 0; device_index < devices.size(); device_index++) {
int device = devices[device_index];
result = cudaGetDeviceProperties(&properties[device_index], device);
if (result != cudaSuccess) {
throw std::runtime_error("cudaGetDeviceProperties() failed for given device");
}
// Check that all devices are the same
if (device_index > 0) {
if ((properties[device_index].major != properties[0].major) ||
(properties[device_index].minor != properties[0].minor)) {
throw std::runtime_error("All selected devices must have the same "
"compute capability");
}
if (properties[device_index].l2CacheSize != properties[0].l2CacheSize) {
throw std::runtime_error("All selected devices must have the same "
"L2 cache size");
}
if (properties[device_index].multiProcessorCount != properties[0].multiProcessorCount) {
throw std::runtime_error("All selected devices must have the same "
"SM count");
}
}
result = cudaSetDevice(device);
if (result != cudaSuccess) {
throw std::runtime_error("cudaSetDevice() failed for given device.");
}
// Permit overriding the compute capability
if (cmdline.check_cmd_line_flag("compute-capability")) {
int cc = compute_capability(device_index);
cmdline.get_cmd_line_argument("compute-capability", cc, cc);
properties[device_index].major = cc / 10;
properties[device_index].minor = cc % 10;
}
// Permit overriding the L2 cache capacity
if (cmdline.check_cmd_line_flag("llc-capacity")) {
int llc_capacity = 0;
cmdline.get_cmd_line_argument("llc-capacity", llc_capacity, 0);
if (llc_capacity >= 0) {
properties[device_index].l2CacheSize = (llc_capacity << 10);
}
}
}
}
void Options::Device::print_usage(std::ostream &out) const {
out << "Device:\n"
<< " --device=<int> "
<< " CUDA Device ID\n\n";
<< " --devices=<int>,<int>,... "
<< " CUDA Device IDs\n\n";
int device_count = 0;
cudaError_t result = cudaGetDeviceCount(&device_count);
@@ -111,11 +164,11 @@ void Options::Device::print_usage(std::ostream &out) const {
break;
}
else {
out << " [" << idx << "] - "
<< prop.name << " - SM " << prop.major << "." << prop.minor << ", "
<< prop.multiProcessorCount << " SMs @ " << (prop.clockRate / 1000.0) << " MHz, "
out << " [" << idx << "] - "
<< prop.name << " - SM " << prop.major << "." << prop.minor << ", "
<< prop.multiProcessorCount << " SMs @ " << (prop.clockRate / 1000.0) << " MHz, "
<< "L2 cache: " << (prop.l2CacheSize >> 20) << " MB, Global Memory: " << (prop.totalGlobalMem >> 30) << " GB"
<< std::endl;
<< std::endl;
}
}
out << "\n";
@@ -133,15 +186,8 @@ void Options::Device::print_usage(std::ostream &out) const {
}
void Options::Device::print_device_info(std::ostream &out) const {
int num_devices;
cudaDeviceProp props;
cudaError_t result;
result = cudaGetDeviceCount(&num_devices);
if (result != cudaSuccess) {
throw std::runtime_error("cudaGetNumDevices() failed");
}
out << "Device Name,SM,CUDA Device ID,Phy Device ID" << std::endl;
@@ -165,14 +211,28 @@ void Options::Device::print_device_info(std::ostream &out) const {
void Options::Device::print_options(std::ostream &out, int indent) const {
out
<< indent_str(indent) << "device: " << device << "\n"
<< indent_str(indent) << "clock: " << int(double(properties.clockRate) / 1000.0) << "\n"
<< indent_str(indent) << "compute-capability: " << compute_capability() << "\n";
<< indent_str(indent) << "devices: ";
for (int device : devices) {
out << device << ',';
}
out
<< "\n"
<< indent_str(indent) << "clock: " << int(double(properties[0].clockRate) / 1000.0) << "\n"
<< indent_str(indent) << "compute-capability: " << compute_capability(0) << "\n";
}
/// Returns the device ID from a device index
int Options::Device::device_id(size_t device_index) const {
if (device_index > devices.size()) {
throw std::runtime_error("Out of bounds device index: " +
std::to_string(device_index));
}
return devices.at(device_index);
}
/// Returns the compute capability of the listed device (e.g. 61, 60, 70, 75)
int Options::Device::compute_capability() const {
return properties.major * 10 + properties.minor;
int Options::Device::compute_capability(int device_index) const {
return properties[device_index].major * 10 + properties[device_index].minor;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
@@ -207,10 +267,10 @@ Options::Initialization::Initialization(cutlass::CommandLine const &cmdline) {
else {
// profiler chosen data distribution (allowed to change based on numeric types)
fix_data_distribution = false;
// set uniform data distribution with range [-4, 4]
// set uniform data distribution with range [-4, 4]
data_distribution.set_uniform(-4, 4, 0);
}
}
@@ -248,10 +308,10 @@ void Options::Initialization::get_distribution(
};
// Initalize pnz values to a default value of 100%
dist.gaussian.pnz = 100.0;
dist.gaussian.pnzA = 100.0;
dist.gaussian.pnzB = 100.0;
dist.gaussian.pnzC = 100.0;
dist.gaussian.pnz = 1.0;
dist.gaussian.pnzA = 1.0;
dist.gaussian.pnzB = 1.0;
dist.gaussian.pnzC = 1.0;
using KeyValueVector = std::vector<std::pair<std::string, std::string> >;
@@ -335,7 +395,7 @@ Options::Library::Library(cutlass::CommandLine const &cmdline) {
std::string mode = "default";
cmdline.get_cmd_line_argument("library-algo-mode", mode);
algorithm_mode = from_string<AlgorithmMode>(mode);
}
}
if (cmdline.check_cmd_line_flag("library-algos")) {
@@ -353,7 +413,7 @@ Options::Library::Library(cutlass::CommandLine const &cmdline) {
}
else {
int algo;
std::stringstream ss;
std::stringstream ss;
ss << token;
ss >> algo;
@@ -396,12 +456,12 @@ void Options::Library::print_options(std::ostream &out, int indent) const {
Options::Profiling::Profiling(cutlass::CommandLine const &cmdline) {
cmdline.get_cmd_line_argument("workspace-count", workspace_count, 0);
cmdline.get_cmd_line_argument("workspace-count", workspace_count, 0);
cmdline.get_cmd_line_argument("warmup-iterations", warmup_iterations, 10);
cmdline.get_cmd_line_argument("profiling-iterations", iterations, 100);
cmdline.get_cmd_line_argument("sleep-duration", sleep_duration, 50);
cmdline.get_cmd_line_argument("profiling-enabled", enabled, true);
if (cmdline.check_cmd_line_flag("providers")) {
std::vector<std::string> tokens;
@@ -416,7 +476,7 @@ Options::Profiling::Profiling(cutlass::CommandLine const &cmdline) {
else {
providers.push_back(library::Provider::kCUTLASS);
providers.push_back(library::Provider::kCUBLAS);
providers.push_back(library::Provider::kCUDNN);
providers.push_back(library::Provider::kCUDNN);
}
}
@@ -480,7 +540,7 @@ size_t Options::Profiling::index(library::Provider provider) const {
/////////////////////////////////////////////////////////////////////////////////////////////////
Options::Verification::Verification(cutlass::CommandLine const &cmdline) {
cmdline.get_cmd_line_argument("verification-enabled", enabled, true);
if (enabled) {
cmdline.get_cmd_line_argument("verification-required", required, false);
@@ -500,7 +560,7 @@ Options::Verification::Verification(cutlass::CommandLine const &cmdline) {
}
if (cmdline.check_cmd_line_flag("verification-providers")) {
std::vector<std::string> tokens;
cmdline.get_cmd_line_arguments("verification-providers", tokens);
@@ -516,7 +576,7 @@ Options::Verification::Verification(cutlass::CommandLine const &cmdline) {
else {
providers.push_back(library::Provider::kCUBLAS);
providers.push_back(library::Provider::kReferenceDevice);
providers.push_back(library::Provider::kCUDNN);
providers.push_back(library::Provider::kCUDNN);
}
}
@@ -583,11 +643,11 @@ size_t Options::Verification::index(library::Provider provider) const {
/////////////////////////////////////////////////////////////////////////////////////////////////
Options::Report::Report(cutlass::CommandLine const &cmdline) {
cmdline.get_cmd_line_argument("append", append, false);
cmdline.get_cmd_line_argument("output", output_path);
cmdline.get_cmd_line_argument("junit-output", junit_output_path);
if (cmdline.check_cmd_line_flag("tags")) {
cmdline.get_cmd_line_argument_pairs("tags", pivot_tags);
}
@@ -687,11 +747,11 @@ Options::Options(cutlass::CommandLine const &cmdline):
device(cmdline),
initialization(cmdline),
library(cmdline),
profiling(cmdline),
verification(cmdline),
profiling(cmdline),
verification(cmdline),
report(cmdline),
about(cmdline) {
if (cmdline.check_cmd_line_flag("mode")) {
std::string token;
cmdline.get_cmd_line_argument("mode", token);