@@ -220,7 +220,7 @@ cublasGemmExDispatcher::cublasGemmExDispatcher(
|
||||
|
||||
// cuBLAS introduces a separate cublasComputeType enumerant to more precisely describe
|
||||
// internal numerical data types used in the computation.
|
||||
#if (__CUDA_VER_MAJOR__ >= 11)
|
||||
#if (__CUDACC_VER_MAJOR__ >= 11)
|
||||
library::OpcodeClassID const & opcode_class =
|
||||
op_desc.tile_description.math_instruction.opcode_class;
|
||||
|
||||
@@ -253,7 +253,7 @@ cublasGemmExDispatcher::cublasGemmExDispatcher(
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // __CUDA_VER_MAJOR__ >= 11
|
||||
#endif // __CUDACC_VER_MAJOR__ >= 11
|
||||
|
||||
if (!good) {
|
||||
status = Status::kErrorNotSupported;
|
||||
@@ -286,7 +286,7 @@ cublasStatus_t cublasGemmExDispatcher::operator()(cublasHandle_t handle) {
|
||||
int(configuration.ldc),
|
||||
arguments.batch_stride_C,
|
||||
configuration.batch_count,
|
||||
#if (__CUDA_VER_MAJOR__ >= 11)
|
||||
#if (__CUDACC_VER_MAJOR__ >= 11)
|
||||
compute_type,
|
||||
#else
|
||||
compute_data_type,
|
||||
@@ -313,7 +313,7 @@ cublasStatus_t cublasGemmExDispatcher::operator()(cublasHandle_t handle) {
|
||||
arguments.D,
|
||||
data_type_C,
|
||||
int(configuration.ldc),
|
||||
#if (__CUDA_VER_MAJOR__ >= 11)
|
||||
#if (__CUDACC_VER_MAJOR__ >= 11)
|
||||
compute_type,
|
||||
#else
|
||||
compute_data_type,
|
||||
@@ -187,7 +187,7 @@ struct cublasGemmExDispatcher {
|
||||
cudaDataType_t data_type_C;
|
||||
cudaDataType_t compute_data_type;
|
||||
|
||||
#if (__CUDA_VER_MAJOR__ >= 11)
|
||||
#if (__CUDACC_VER_MAJOR__ >= 11)
|
||||
cublasComputeType_t compute_type;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -254,6 +254,10 @@ int64_t GemmOperationProfiler::GemmProblem::flops(library::GemmDescription const
|
||||
flops_ *= 4;
|
||||
break;
|
||||
|
||||
case library::MathOperationID::kMultiplyAddComplexFastF32:
|
||||
flops_ *= 4;
|
||||
break;
|
||||
|
||||
case library::MathOperationID::kMultiplyAddGaussianComplex:
|
||||
flops_ *= 3;
|
||||
break;
|
||||
|
||||
@@ -260,6 +260,9 @@ int OperationProfiler::profile_all(
|
||||
auto min_cc = operation->description().tile_description.minimum_compute_capability;
|
||||
auto max_cc = operation->description().tile_description.maximum_compute_capability;
|
||||
|
||||
// Clear named allocations
|
||||
device_context.free();
|
||||
|
||||
// Execute compatible cutlass operations if they satisfy the current device's compute capability
|
||||
if (operation->description().kind == kind_ &&
|
||||
operation->description().provider == library::Provider::kCUTLASS &&
|
||||
@@ -301,9 +304,12 @@ int OperationProfiler::profile_all(
|
||||
problem);
|
||||
|
||||
if (status == Status::kErrorInternal) {
|
||||
// Stop profiling if there was an internal error
|
||||
internal_error = true;
|
||||
break;
|
||||
|
||||
// If there was an internal error, consume the CUDA error and move to the next operation.
|
||||
(void)cudaGetLastError();
|
||||
|
||||
report.append_results(results_);
|
||||
continue;
|
||||
}
|
||||
else if (status != Status::kSuccess) {
|
||||
// If the workspace could not be initialized for any other reason, continue to
|
||||
@@ -322,9 +328,12 @@ int OperationProfiler::profile_all(
|
||||
problem);
|
||||
|
||||
if (status == Status::kErrorInternal) {
|
||||
// Stop profiling if there was an internal error
|
||||
internal_error = true;
|
||||
break;
|
||||
|
||||
// If there was an internal error, consume the CUDA error and move to the next operation.
|
||||
(void)cudaGetLastError();
|
||||
|
||||
report.append_results(results_);
|
||||
continue;
|
||||
}
|
||||
else if (status != Status::kSuccess) {
|
||||
// If the workspace could not be initialized for any other reason, continue to
|
||||
@@ -383,9 +392,6 @@ int OperationProfiler::profile_all(
|
||||
problem);
|
||||
}
|
||||
|
||||
// Clear named allocations
|
||||
device_context.free();
|
||||
|
||||
report.append_results(results_);
|
||||
results_.clear();
|
||||
}
|
||||
|
||||
@@ -577,6 +577,8 @@ Options::Report::Report(cutlass::CommandLine const &cmdline) {
|
||||
cmdline.get_cmd_line_argument("report-not-run", report_not_run, false);
|
||||
|
||||
cmdline.get_cmd_line_argument("verbose", verbose, true);
|
||||
|
||||
cmdline.get_cmd_line_argument("sort-results", sort_results, false);
|
||||
}
|
||||
|
||||
void Options::Report::print_usage(std::ostream &out) const {
|
||||
@@ -602,7 +604,10 @@ void Options::Report::print_usage(std::ostream &out) const {
|
||||
<< " column. Useful for generating pivot tables.\n\n"
|
||||
|
||||
<< " --verbose=<bool> "
|
||||
<< " Prints human-readable text to stdout. If false, nothing is written to stdout.\n\n";
|
||||
<< " Prints human-readable text to stdout. If false, nothing is written to stdout.\n\n"
|
||||
|
||||
<< " --sort-results=<bool> "
|
||||
<< " Sorts results (by flops-per-byte).\n\n";
|
||||
}
|
||||
|
||||
void Options::Report::print_options(std::ostream &out, int indent) const {
|
||||
|
||||
@@ -231,6 +231,9 @@ public:
|
||||
/// Prints human-readable text to stdout. If false, nothing is written to stdout
|
||||
bool verbose;
|
||||
|
||||
/// Sort results by (currently by flops-per-byte)
|
||||
bool sort_results;
|
||||
|
||||
//
|
||||
// Methods
|
||||
//
|
||||
|
||||
@@ -154,6 +154,22 @@ void PerformanceReport::append_result(PerformanceResult result) {
|
||||
}
|
||||
}
|
||||
|
||||
void PerformanceReport::sort_results(PerformanceResultVector &results) {
|
||||
|
||||
struct FlopsPerByteCompare
|
||||
{
|
||||
bool operator()(const PerformanceResult &a, const PerformanceResult &b)
|
||||
{
|
||||
double a_flops_per_byte = double(a.flops) / double(a.bytes);
|
||||
double b_flops_per_byte = double(b.flops) / double(b.bytes);
|
||||
|
||||
return (a_flops_per_byte < b_flops_per_byte);
|
||||
}
|
||||
};
|
||||
|
||||
std::stable_sort(results.begin(), results.end(), FlopsPerByteCompare());
|
||||
}
|
||||
|
||||
void PerformanceReport::append_results(PerformanceResultVector const &results) {
|
||||
|
||||
if (options_.report.verbose) {
|
||||
@@ -173,12 +189,16 @@ PerformanceReport::~PerformanceReport() {
|
||||
//
|
||||
if (options_.report.verbose && !concatenated_results_.empty()) {
|
||||
|
||||
if (options_.report.sort_results) {
|
||||
sort_results(concatenated_results_);
|
||||
}
|
||||
|
||||
std::cout << "\n\n";
|
||||
std::cout << "=============================\n\n";
|
||||
std::cout << "CSV Results:\n\n";
|
||||
|
||||
print_csv_header_(std::cout) << std::endl;
|
||||
|
||||
|
||||
for (auto const &result : concatenated_results_) {
|
||||
print_result_csv_(std::cout, result) << "\n";
|
||||
}
|
||||
@@ -273,7 +293,8 @@ std::ostream & PerformanceReport::print_result_pretty_(
|
||||
|
||||
out
|
||||
<< " Bytes: " << result.bytes << " bytes\n"
|
||||
<< " FLOPs: " << result.flops << " flops\n\n";
|
||||
<< " FLOPs: " << result.flops << " flops\n"
|
||||
<< " FLOPs/Byte: " << (result.flops / result.bytes) << "\n\n";
|
||||
|
||||
if (result.good()) {
|
||||
|
||||
@@ -309,6 +330,7 @@ std::ostream & PerformanceReport::print_csv_header_(
|
||||
out
|
||||
<< ",Bytes"
|
||||
<< ",Flops"
|
||||
<< ",Flops/Byte"
|
||||
<< ",Runtime"
|
||||
<< ",GB/s"
|
||||
<< ",GFLOPs"
|
||||
@@ -345,6 +367,7 @@ std::ostream & PerformanceReport::print_result_csv_(
|
||||
out
|
||||
<< "," << result.bytes
|
||||
<< "," << result.flops
|
||||
<< "," << result.flops / result.bytes
|
||||
<< "," << result.runtime;
|
||||
|
||||
if (result.good()) {
|
||||
|
||||
@@ -86,6 +86,7 @@ public:
|
||||
|
||||
void next_problem();
|
||||
void append_result(PerformanceResult result);
|
||||
void sort_results(PerformanceResultVector &results);
|
||||
void append_results(PerformanceResultVector const &results);
|
||||
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user