Update bandwidth and latency calculations
- Refined bandwidth and latency calculations for improved accuracy
This commit is contained in:
@@ -58,14 +58,22 @@ Tester::Tester(TesterArguments args) : args(args) {
|
||||
_shmem_context = args.shmem_context;
|
||||
CHECK_HIP(hipGetDevice(&device_id));
|
||||
CHECK_HIP(hipGetDeviceProperties(&deviceProps, device_id));
|
||||
num_warps = (args.wg_size - 1) / deviceProps.warpSize + 1;
|
||||
wf_size = deviceProps.warpSize;
|
||||
num_warps = (args.wg_size - 1) / wf_size + 1;
|
||||
CHECK_HIP(hipStreamCreate(&stream));
|
||||
CHECK_HIP(hipEventCreate(&start_event));
|
||||
CHECK_HIP(hipEventCreate(&stop_event));
|
||||
CHECK_HIP(hipMalloc((void**)&timer, sizeof(uint64_t) * args.num_wgs));
|
||||
CHECK_HIP(hipDeviceGetAttribute(&wall_clk_rate,
|
||||
hipDeviceAttributeWallClockRate, device_id));
|
||||
num_timers = args.num_wgs;
|
||||
CHECK_HIP(hipMalloc((void**)&timer, sizeof(long long int) * num_timers));
|
||||
CHECK_HIP(hipMalloc((void**)&start_time, sizeof(long long int) * num_timers));
|
||||
CHECK_HIP(hipMalloc((void**)&end_time, sizeof(long long int) * num_timers));
|
||||
}
|
||||
|
||||
Tester::~Tester() {
|
||||
CHECK_HIP(hipFree(end_time));
|
||||
CHECK_HIP(hipFree(start_time));
|
||||
CHECK_HIP(hipFree(timer));
|
||||
CHECK_HIP(hipEventDestroy(stop_event));
|
||||
CHECK_HIP(hipEventDestroy(start_event));
|
||||
@@ -75,11 +83,6 @@ Tester::~Tester() {
|
||||
std::vector<Tester*> Tester::create(TesterArguments args) {
|
||||
int rank = args.myid;
|
||||
std::vector<Tester*> testers;
|
||||
hipDeviceProp_t deviceProps;
|
||||
int device_id, numWarps;
|
||||
CHECK_HIP(hipGetDevice(&device_id));
|
||||
CHECK_HIP(hipGetDeviceProperties(&deviceProps, device_id));
|
||||
numWarps = (args.wg_size - 1) / deviceProps.warpSize + 1;
|
||||
|
||||
if (rank == 0) std::cout << "### Creating Test: ";
|
||||
|
||||
@@ -352,35 +355,23 @@ std::vector<Tester*> Tester::create(TesterArguments args) {
|
||||
testers.push_back(new ShmemPtrTester(args));
|
||||
return testers;
|
||||
case WGGetTestType:
|
||||
if (rank == 0) {
|
||||
if (args.num_wgs > 1)
|
||||
std::cout << "Tiled Blocking WG level Gets ###" << std::endl;
|
||||
else std::cout << "Blocking WG level Gets ###" << std::endl;
|
||||
}
|
||||
if (rank == 0)
|
||||
std::cout << "Blocking WG level Gets ###" << std::endl;
|
||||
testers.push_back(new ExtendedPrimitiveTester(args));
|
||||
return testers;
|
||||
case WGGetNBITestType:
|
||||
if (rank == 0) {
|
||||
if (args.num_wgs > 1)
|
||||
std::cout << "Tiled Non-Blocking WG level Gets ###" << std::endl;
|
||||
else std::cout << "Non-Blocking WG level Gets ###" << std::endl;
|
||||
}
|
||||
if (rank == 0)
|
||||
std::cout << "Non-Blocking WG level Gets ###" << std::endl;
|
||||
testers.push_back(new ExtendedPrimitiveTester(args));
|
||||
return testers;
|
||||
case WGPutTestType:
|
||||
if (rank == 0) {
|
||||
if (args.num_wgs > 1)
|
||||
std::cout << "Tiled Blocking WG level Puts ###" << std::endl;
|
||||
else std::cout << "Blocking WG level Puts ###" << std::endl;
|
||||
}
|
||||
if (rank == 0)
|
||||
std::cout << "Blocking WG level Puts ###" << std::endl;
|
||||
testers.push_back(new ExtendedPrimitiveTester(args));
|
||||
return testers;
|
||||
case WGPutNBITestType:
|
||||
if (rank == 0) {
|
||||
if (args.num_wgs > 1)
|
||||
std::cout << "Tiled Non-Blocking WG level Puts ###" << std::endl;
|
||||
else std::cout << "Non-Blocking WG level Puts ###" << std::endl;
|
||||
}
|
||||
if (rank == 0)
|
||||
std::cout << "Non-Blocking WG level Puts ###" << std::endl;
|
||||
testers.push_back(new ExtendedPrimitiveTester(args));
|
||||
return testers;
|
||||
case PutNBIMRTestType:
|
||||
@@ -389,35 +380,23 @@ std::vector<Tester*> Tester::create(TesterArguments args) {
|
||||
testers.push_back(new PrimitiveMRTester(args));
|
||||
return testers;
|
||||
case WAVEGetTestType:
|
||||
if (rank == 0) {
|
||||
if (args.num_wgs > 1 || numWarps > 1)
|
||||
std::cout << "Tiled Blocking WAVE level Gets ###" << std::endl;
|
||||
else std::cout << "Blocking WAVE level Gets ###" << std::endl;
|
||||
}
|
||||
if (rank == 0)
|
||||
std::cout << "Blocking WAVE level Gets ###" << std::endl;
|
||||
testers.push_back(new WaveLevelPrimitiveTester(args));
|
||||
return testers;
|
||||
case WAVEGetNBITestType:
|
||||
if (rank == 0) {
|
||||
if (args.num_wgs > 1 || numWarps > 1)
|
||||
std::cout << "Tiled Non-Blocking WAVE level Gets ###" << std::endl;
|
||||
else std::cout << "Non-Blocking WAVE level Gets ###" << std::endl;
|
||||
}
|
||||
if (rank == 0)
|
||||
std::cout << "Non-Blocking WAVE level Gets ###" << std::endl;
|
||||
testers.push_back(new WaveLevelPrimitiveTester(args));
|
||||
return testers;
|
||||
case WAVEPutTestType:
|
||||
if (rank == 0) {
|
||||
if (args.num_wgs > 1 || numWarps > 1)
|
||||
std::cout << "Tiled Blocking WAVE level Puts ###" << std::endl;
|
||||
else std::cout << "Blocking WAVE level Puts ###" << std::endl;
|
||||
}
|
||||
if (rank == 0)
|
||||
std::cout << "Blocking WAVE level Puts ###" << std::endl;
|
||||
testers.push_back(new WaveLevelPrimitiveTester(args));
|
||||
return testers;
|
||||
case WAVEPutNBITestType:
|
||||
if (rank == 0) {
|
||||
if (args.num_wgs > 1 || numWarps > 1)
|
||||
std::cout << "Tiled Non-Blocking WAVE level Puts ###" << std::endl;
|
||||
else std::cout << "Non-Blocking WAVE level Puts ###" << std::endl;
|
||||
}
|
||||
if (rank == 0)
|
||||
std::cout << "Non-Blocking WAVE level Puts ###" << std::endl;
|
||||
testers.push_back(new WaveLevelPrimitiveTester(args));
|
||||
return testers;
|
||||
case PutSignalTestType:
|
||||
@@ -501,11 +480,6 @@ void Tester::execute() {
|
||||
* rocshmem pes.
|
||||
*/
|
||||
if (peLaunchesKernel()) {
|
||||
/**
|
||||
* TODO:
|
||||
* Verify that this timer type is actually uint64_t on the
|
||||
* device side.
|
||||
*/
|
||||
memset(timer, 0, sizeof(uint64_t) * args.num_wgs);
|
||||
|
||||
const dim3 blockSize(args.wg_size, 1, 1);
|
||||
@@ -521,9 +495,6 @@ void Tester::execute() {
|
||||
if (err != hipSuccess) {
|
||||
printf("error = %d \n", err);
|
||||
}
|
||||
|
||||
// rocshmem_dump_stats();
|
||||
// rocshmem_reset_stats();
|
||||
}
|
||||
|
||||
barrier();
|
||||
@@ -533,32 +504,10 @@ void Tester::execute() {
|
||||
// data validation
|
||||
verifyResults(size);
|
||||
|
||||
/**
|
||||
* Adjust size for *_wg and *_wave functions
|
||||
*/
|
||||
uint64_t size_ = size;
|
||||
TestType type = (TestType)args.algorithm;
|
||||
switch (type) {
|
||||
case WAVEGetTestType:
|
||||
case WAVEGetNBITestType:
|
||||
case WAVEPutTestType:
|
||||
case WAVEPutNBITestType:
|
||||
size_ *= (args.num_wgs * num_warps);
|
||||
break;
|
||||
case WGGetTestType:
|
||||
case WGGetNBITestType:
|
||||
case WGPutTestType:
|
||||
case WGPutNBITestType:
|
||||
size_ *= args.num_wgs;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
barrier();
|
||||
|
||||
if (_type != TeamCtxInfraTestType) {
|
||||
print(size_);
|
||||
print(size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -589,30 +538,39 @@ void Tester::print(uint64_t size) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t timer_avg = timerAvgInMicroseconds();
|
||||
double latency_avg = static_cast<double>(timer_avg) / num_timed_msgs;
|
||||
/**
|
||||
* Calculate total amount of data transfered
|
||||
*/
|
||||
uint64_t total_size = size * num_timed_msgs;
|
||||
double timer_avg = timerAvgInMicroseconds();
|
||||
double latency_avg = timer_avg / num_timed_msgs;
|
||||
double avg_msg_rate = num_timed_msgs / (timer_avg / 1e6);
|
||||
|
||||
float total_kern_time_ms;
|
||||
CHECK_HIP(hipEventElapsedTime(&total_kern_time_ms, start_event, stop_event));
|
||||
float total_kern_time_s = total_kern_time_ms / 1000;
|
||||
|
||||
double time_us = gpuCyclesToMicroseconds(max_end_time - min_start_time);
|
||||
double time_s = time_us / 1e6;
|
||||
double bandwidth_avg_gbs =
|
||||
num_msgs * size * bw_factor / total_kern_time_s / pow(2, 30);
|
||||
static_cast<double>(total_size * bw_factor) / time_s / pow(2, 30);
|
||||
|
||||
int field_width = 20;
|
||||
int float_precision = 2;
|
||||
|
||||
if (_print_header) {
|
||||
printf("%-*s%*s%*s%*s",
|
||||
10, "# Size (B)",
|
||||
printf("%-*s%-*s%*s%*s%*s",
|
||||
15, "# Size (B)",
|
||||
15, "# of timed Msgs",
|
||||
field_width, "Latency (us)",
|
||||
field_width, "Bandwidth (GB/s)",
|
||||
field_width + 1, "Msg Rate (Msg/s)\n");
|
||||
_print_header = 0;
|
||||
}
|
||||
|
||||
printf("%-*lu%*.*f%*.*f%*.*f\n",
|
||||
10, size,
|
||||
printf("%-*lu%-*d%*.*f%*.*f%*.*f\n",
|
||||
15, size,
|
||||
15, num_timed_msgs,
|
||||
field_width, float_precision, latency_avg,
|
||||
field_width, float_precision, bandwidth_avg_gbs,
|
||||
field_width, float_precision, avg_msg_rate);
|
||||
@@ -634,33 +592,26 @@ void Tester::barrier() {
|
||||
flush_hdp();
|
||||
}
|
||||
|
||||
uint64_t Tester::gpuCyclesToMicroseconds(uint64_t cycles) {
|
||||
/**
|
||||
* The dGPU asm core timer runs at 27MHz. This is different from the
|
||||
* core clock returned by HIP. For an APU, this is different and might
|
||||
* need adjusting.
|
||||
*/
|
||||
uint64_t gpu_frequency_MHz = 27;
|
||||
|
||||
/**
|
||||
* hipDeviceGetAttribute(&gpu_frequency_khz,
|
||||
* hipDeviceAttributeClockRate,
|
||||
* 0);
|
||||
*/
|
||||
|
||||
return cycles / gpu_frequency_MHz;
|
||||
double Tester::gpuCyclesToMicroseconds(long long int cycles) {
|
||||
return static_cast<double>(cycles) /
|
||||
(static_cast<double>(wall_clk_rate) * 1e-3);
|
||||
}
|
||||
|
||||
uint64_t Tester::timerAvgInMicroseconds() {
|
||||
uint64_t sum = 0;
|
||||
double Tester::timerAvgInMicroseconds() {
|
||||
double sum = 0;
|
||||
min_start_time = LLONG_MAX;
|
||||
max_end_time = 0;
|
||||
|
||||
/**
|
||||
* TODO: (bpotter/avinash) Modify the calcuation for the Tiled version of
|
||||
* puts and gets at wavefront level
|
||||
*/
|
||||
for (uint64_t i = 0; i < args.num_wgs; i++) {
|
||||
for (uint32_t i = 0; i < num_timers; i++) {
|
||||
timer[i] = end_time[i] - start_time[i];
|
||||
sum += gpuCyclesToMicroseconds(timer[i]);
|
||||
min_start_time = (start_time[i] < min_start_time)
|
||||
? start_time[i]
|
||||
: min_start_time;
|
||||
max_end_time = (end_time[i] > max_end_time)
|
||||
? end_time[i]
|
||||
: max_end_time;
|
||||
}
|
||||
|
||||
return sum / args.num_wgs;
|
||||
return sum / num_timers;
|
||||
}
|
||||
|
||||
Verwijs in nieuw issue
Block a user