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:
co-authored by
yuzhai
Haicheng Wu
parent
0837a2a00a
commit
cc3c29a81a
+122
-62
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user