SWDEV-470698 - fix formatting, add format check workflow (#657)

This commit is contained in:
Danylo Lytovchenko
2025-08-20 16:28:06 +02:00
committato da GitHub
parent 5840940caa
commit f7338717ae
1574 ha cambiato i file con 162972 aggiunte e 199346 eliminazioni
@@ -26,85 +26,85 @@ THE SOFTWARE.
#include "hip_helper.h"
__global__ void bit_extract_kernel(uint32_t* C_d, const uint32_t* A_d, size_t N) {
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
size_t stride = blockDim.x * gridDim.x;
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
size_t stride = blockDim.x * gridDim.x;
for (size_t i = offset; i < N; i += stride) {
for (size_t i = offset; i < N; i += stride) {
#ifdef __HIP_PLATFORM_AMD__
C_d[i] = __bitextract_u32(A_d[i], 8, 4);
C_d[i] = __bitextract_u32(A_d[i], 8, 4);
#else /* defined __HIP_PLATFORM_NVIDIA__ or other path */
C_d[i] = ((A_d[i] & 0xf00) >> 8);
C_d[i] = ((A_d[i] & 0xf00) >> 8);
#endif
}
}
}
int main(int argc, char* argv[]) {
uint32_t *A_d, *C_d;
uint32_t *A_h, *C_h;
size_t N = 1000000;
size_t Nbytes = N * sizeof(uint32_t);
uint32_t *A_d, *C_d;
uint32_t *A_h, *C_h;
size_t N = 1000000;
size_t Nbytes = N * sizeof(uint32_t);
#ifdef __HIP_ENABLE_PCH
// Verify hip_pch.o
const char* pch = nullptr;
unsigned int size = 0;
__hipGetPCH(&pch, &size);
printf("pch size: %u\n", size);
if (size == 0) {
printf("__hipGetPCH failed!\n");
return -1;
} else {
printf("__hipGetPCH succeeded!\n");
}
// Verify hip_pch.o
const char* pch = nullptr;
unsigned int size = 0;
__hipGetPCH(&pch, &size);
printf("pch size: %u\n", size);
if (size == 0) {
printf("__hipGetPCH failed!\n");
return -1;
} else {
printf("__hipGetPCH succeeded!\n");
}
#endif
int deviceId;
checkHipErrors(hipGetDevice(&deviceId));
hipDeviceProp_t props;
checkHipErrors(hipGetDeviceProperties(&props, deviceId));
printf("info: running on device #%d %s\n", deviceId, props.name);
int deviceId;
checkHipErrors(hipGetDevice(&deviceId));
hipDeviceProp_t props;
checkHipErrors(hipGetDeviceProperties(&props, deviceId));
printf("info: running on device #%d %s\n", deviceId, props.name);
printf("info: allocate host mem (%6.2f MB)\n", 2 * Nbytes / 1024.0 / 1024.0);
A_h = (uint32_t*)malloc(Nbytes);
checkHipErrors(A_h == 0 ? hipErrorOutOfMemory : hipSuccess);
C_h = (uint32_t*)malloc(Nbytes);
checkHipErrors(C_h == 0 ? hipErrorOutOfMemory : hipSuccess);
printf("info: allocate host mem (%6.2f MB)\n", 2 * Nbytes / 1024.0 / 1024.0);
A_h = (uint32_t*)malloc(Nbytes);
checkHipErrors(A_h == 0 ? hipErrorOutOfMemory : hipSuccess);
C_h = (uint32_t*)malloc(Nbytes);
checkHipErrors(C_h == 0 ? hipErrorOutOfMemory : hipSuccess);
for (size_t i = 0; i < N; i++) {
A_h[i] = i;
for (size_t i = 0; i < N; i++) {
A_h[i] = i;
}
printf("info: allocate device mem (%6.2f MB)\n", 2 * Nbytes / 1024.0 / 1024.0);
checkHipErrors(hipMalloc(&A_d, Nbytes));
checkHipErrors(hipMalloc(&C_d, Nbytes));
printf("info: copy Host2Device\n");
checkHipErrors(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
printf("info: launch 'bit_extract_kernel' \n");
const unsigned blocks = 512;
const unsigned threadsPerBlock = 256;
hipLaunchKernelGGL(bit_extract_kernel, dim3(blocks), dim3(threadsPerBlock), 0, 0, C_d, A_d, N);
printf("info: copy Device2Host\n");
checkHipErrors(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
printf("info: check result\n");
for (size_t i = 0; i < N; i++) {
unsigned Agold = ((A_h[i] & 0xf00) >> 8);
if (C_h[i] != Agold) {
fprintf(stderr, "mismatch detected.\n");
printf("%zu: %08x =? %08x (Ain=%08x)\n", i, C_h[i], Agold, A_h[i]);
checkHipErrors(hipErrorUnknown);
}
}
printf("info: allocate device mem (%6.2f MB)\n", 2 * Nbytes / 1024.0 / 1024.0);
checkHipErrors(hipMalloc(&A_d, Nbytes));
checkHipErrors(hipMalloc(&C_d, Nbytes));
checkHipErrors(hipFree(A_d));
checkHipErrors(hipFree(C_d));
free(A_h);
free(C_h);
printf("info: copy Host2Device\n");
checkHipErrors(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
printf("info: launch 'bit_extract_kernel' \n");
const unsigned blocks = 512;
const unsigned threadsPerBlock = 256;
hipLaunchKernelGGL(bit_extract_kernel, dim3(blocks), dim3(threadsPerBlock), 0, 0, C_d, A_d, N);
printf("info: copy Device2Host\n");
checkHipErrors(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
printf("info: check result\n");
for (size_t i = 0; i < N; i++) {
unsigned Agold = ((A_h[i] & 0xf00) >> 8);
if (C_h[i] != Agold) {
fprintf(stderr, "mismatch detected.\n");
printf("%zu: %08x =? %08x (Ain=%08x)\n", i, C_h[i], Agold, A_h[i]);
checkHipErrors(hipErrorUnknown);
}
}
checkHipErrors(hipFree(A_d));
checkHipErrors(hipFree(C_d));
free(A_h);
free(C_h);
printf("PASSED!\n");
printf("PASSED!\n");
}
@@ -36,7 +36,7 @@ static constexpr auto NUM_BLOCKS{32};
using namespace std;
static constexpr auto saxpy{
R"(
R"(
#include "test_header.h"
#include "test_header1.h"
extern "C"
@@ -50,8 +50,7 @@ void saxpy(real a, realptr x, realptr y, realptr out, size_t n)
}
)"};
int main()
{
int main() {
hipDeviceProp_t props;
int device = 0;
checkHipErrors(hipSetDevice(device));
@@ -62,11 +61,11 @@ int main()
auto pos = agentTarget.find(':');
if (pos != std::string::npos) {
postFix = agentTarget.substr(pos); // Features
postFix = agentTarget.substr(pos); // Features
agentTarget.resize(pos);
}
if (!getGenericTarget(agentTarget, genericTarget)) {
cout << props.gcnArchName <<" has no generic target support. Skipped!" << endl;
cout << props.gcnArchName << " has no generic target support. Skipped!" << endl;
return 0;
}
if (agentTarget.find("gfx906") != std::string::npos) {
@@ -86,16 +85,20 @@ int main()
vector<const char*> header_sources;
header_names.push_back("test_header.h");
header_names.push_back("test_header1.h");
header_sources.push_back("#ifndef HIPRTC_TEST_HEADER_H\n#define HIPRTC_TEST_HEADER_H\ntypedef float real;\n#endif //HIPRTC_TEST_HEADER_H\n");
header_sources.push_back("#ifndef HIPRTC_TEST_HEADER1_H\n#define HIPRTC_TEST_HEADER1_H\ntypedef float* realptr;\n#endif //HIPRTC_TEST_HEADER1_H\n");
hiprtcCreateProgram(&prog, // prog
saxpy, // buffer
"saxpy.cu", // name
num_headers, // numHeaders
&header_sources[0], // headers
&header_names[0]); // includeNames
header_sources.push_back(
"#ifndef HIPRTC_TEST_HEADER_H\n#define HIPRTC_TEST_HEADER_H\ntypedef float real;\n#endif "
"//HIPRTC_TEST_HEADER_H\n");
header_sources.push_back(
"#ifndef HIPRTC_TEST_HEADER1_H\n#define HIPRTC_TEST_HEADER1_H\ntypedef float* "
"realptr;\n#endif //HIPRTC_TEST_HEADER1_H\n");
hiprtcCreateProgram(&prog, // prog
saxpy, // buffer
"saxpy.cu", // name
num_headers, // numHeaders
&header_sources[0], // headers
&header_names[0]); // includeNames
string offload {"--offload-arch="};
string offload{"--offload-arch="};
offload += genericTarget.c_str();
/*
* offload must be one of following:
@@ -108,17 +111,17 @@ int main()
*
* */
const char* options[] = {offload.c_str(), "-mcode-object-version=6", "-w"};
hiprtcResult compileResult {
hiprtcCompileProgram(prog, sizeof(options) / sizeof(options[0]), options) };
hiprtcResult compileResult{
hiprtcCompileProgram(prog, sizeof(options) / sizeof(options[0]), options)};
size_t logSize;
hiprtcGetProgramLogSize(prog, &logSize);
if (logSize) {
string log(logSize, '\0');
hiprtcGetProgramLog(prog, &log[0]);
string log(logSize, '\0');
hiprtcGetProgramLog(prog, &log[0]);
cout << log << '\n';
cout << log << '\n';
}
if (compileResult != HIPRTC_SUCCESS) {
@@ -148,43 +151,42 @@ int main()
unique_ptr<float[]> hOut{new float[n]};
for (size_t i = 0; i < n; ++i) {
hX[i] = static_cast<float>(i);
hY[i] = static_cast<float>(i * 2);
hX[i] = static_cast<float>(i);
hY[i] = static_cast<float>(i * 2);
}
hipDeviceptr_t dX, dY, dOut;
checkHipErrors(hipMalloc((void **)&dX, bufferSize));
checkHipErrors(hipMalloc((void **)&dY, bufferSize));
checkHipErrors(hipMalloc((void **)&dOut, bufferSize));
checkHipErrors(hipMalloc((void**)&dX, bufferSize));
checkHipErrors(hipMalloc((void**)&dY, bufferSize));
checkHipErrors(hipMalloc((void**)&dOut, bufferSize));
checkHipErrors(hipMemcpyHtoD(dX, hX.get(), bufferSize));
checkHipErrors(hipMemcpyHtoD(dY, hY.get(), bufferSize));
struct {
float a_;
hipDeviceptr_t b_;
hipDeviceptr_t c_;
hipDeviceptr_t d_;
size_t e_;
float a_;
hipDeviceptr_t b_;
hipDeviceptr_t c_;
hipDeviceptr_t d_;
size_t e_;
} args{a, dX, dY, dOut, n};
auto size = sizeof(args);
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args,
HIP_LAUNCH_PARAM_BUFFER_SIZE, &size,
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size,
HIP_LAUNCH_PARAM_END};
checkHipErrors(hipModuleLaunchKernel(kernel, NUM_BLOCKS, 1, 1, NUM_THREADS, 1, 1,
0, nullptr, nullptr, config));
checkHipErrors(hipModuleLaunchKernel(kernel, NUM_BLOCKS, 1, 1, NUM_THREADS, 1, 1, 0, nullptr,
nullptr, config));
checkHipErrors(hipMemcpyDtoH(hOut.get(), dOut, bufferSize));
for (size_t i = 0; i < n; ++i) {
if (fabs(a * hX[i] + hY[i] - hOut[i]) > fabs(hOut[i])* 1e-6) {
cout << "Validation failed." << endl;
}
if (fabs(a * hX[i] + hY[i] - hOut[i]) > fabs(hOut[i]) * 1e-6) {
cout << "Validation failed." << endl;
}
}
checkHipErrors(hipFree((void *)dX));
checkHipErrors(hipFree((void *)dY));
checkHipErrors(hipFree((void *)dOut));
checkHipErrors(hipFree((void*)dX));
checkHipErrors(hipFree((void*)dY));
checkHipErrors(hipFree((void*)dOut));
checkHipErrors(hipModuleUnload(module));
@@ -28,8 +28,7 @@ THE SOFTWARE.
/*
* Square each element in the array A and write to array C.
*/
template <typename T>
__global__ void vector_square(T* C_d, const T* A_d, size_t N) {
template <typename T> __global__ void vector_square(T* C_d, const T* A_d, size_t N) {
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
size_t stride = blockDim.x * gridDim.x;
@@ -33,56 +33,56 @@ THE SOFTWARE.
#define kernel_name "hello_world"
int main() {
float *A, *B;
hipDeviceptr_t Ad, Bd;
A = new float[LEN];
B = new float[LEN];
float *A, *B;
hipDeviceptr_t Ad, Bd;
A = new float[LEN];
B = new float[LEN];
for (uint32_t i = 0; i < LEN; i++) {
A[i] = i * 1.0f;
B[i] = 0.0f;
for (uint32_t i = 0; i < LEN; i++) {
A[i] = i * 1.0f;
B[i] = 0.0f;
}
hipInit(0);
hipDevice_t device;
hipCtx_t context;
checkHipErrors(hipDeviceGet(&device, 0));
checkHipErrors(hipCtxCreate(&context, 0, device));
checkHipErrors(hipMalloc((void**)&Ad, SIZE));
checkHipErrors(hipMalloc((void**)&Bd, SIZE));
checkHipErrors(hipMemcpyHtoD(Ad, A, SIZE));
checkHipErrors(hipMemcpyHtoD(Bd, B, SIZE));
hipModule_t Module;
hipFunction_t Function;
checkHipErrors(hipModuleLoad(&Module, fileName));
checkHipErrors(hipModuleGetFunction(&Function, Module, kernel_name));
void* args[2] = {&Ad, &Bd};
checkHipErrors(hipModuleLaunchKernel(Function, 1, 1, 1, LEN, 1, 1, 0, 0, args, nullptr));
checkHipErrors(hipMemcpyDtoH(B, Bd, SIZE));
int mismatchCount = 0;
for (uint32_t i = 0; i < LEN; i++) {
if (A[i] != B[i]) {
mismatchCount++;
std::cout << "error: mismatch " << A[i] << " != " << B[i] << std::endl;
}
}
hipInit(0);
hipDevice_t device;
hipCtx_t context;
checkHipErrors(hipDeviceGet(&device, 0));
checkHipErrors(hipCtxCreate(&context, 0, device));
if (mismatchCount == 0) {
std::cout << "PASSED!\n";
} else {
std::cout << "FAILED!\n";
};
checkHipErrors(hipMalloc((void**)&Ad, SIZE));
checkHipErrors(hipMalloc((void**)&Bd, SIZE));
checkHipErrors(hipMemcpyHtoD(Ad, A, SIZE));
checkHipErrors(hipMemcpyHtoD(Bd, B, SIZE));
hipModule_t Module;
hipFunction_t Function;
checkHipErrors(hipModuleLoad(&Module, fileName));
checkHipErrors(hipModuleGetFunction(&Function, Module, kernel_name));
void* args[2] = {&Ad, &Bd};
checkHipErrors(hipModuleLaunchKernel(Function, 1, 1, 1, LEN, 1, 1, 0, 0, args, nullptr));
checkHipErrors(hipMemcpyDtoH(B, Bd, SIZE));
int mismatchCount = 0;
for (uint32_t i = 0; i < LEN; i++) {
if (A[i] != B[i]) {
mismatchCount++;
std::cout << "error: mismatch " << A[i] << " != " << B[i] << std::endl;
}
}
if (mismatchCount == 0) {
std::cout << "PASSED!\n";
} else {
std::cout << "FAILED!\n";
};
checkHipErrors(hipFree(Ad));
checkHipErrors(hipFree(Bd));
delete[] A;
delete[] B;
checkHipErrors(hipCtxDestroy(context));
return 0;
checkHipErrors(hipFree(Ad));
checkHipErrors(hipFree(Bd));
delete[] A;
delete[] B;
checkHipErrors(hipCtxDestroy(context));
return 0;
}
@@ -38,69 +38,69 @@ THE SOFTWARE.
#define kernel_name "hello_world"
int main() {
float *A, *B;
hipDeviceptr_t Ad, Bd;
A = new float[LEN];
B = new float[LEN];
float *A, *B;
hipDeviceptr_t Ad, Bd;
A = new float[LEN];
B = new float[LEN];
for (uint32_t i = 0; i < LEN; i++) {
A[i] = i * 1.0f;
B[i] = 0.0f;
for (uint32_t i = 0; i < LEN; i++) {
A[i] = i * 1.0f;
B[i] = 0.0f;
}
hipInit(0);
hipDevice_t device;
hipCtx_t context;
checkHipErrors(hipDeviceGet(&device, 0));
checkHipErrors(hipCtxCreate(&context, 0, device));
checkHipErrors(hipMalloc((void**)&Ad, SIZE));
checkHipErrors(hipMalloc((void**)&Bd, SIZE));
checkHipErrors(hipMemcpyHtoD(Ad, A, SIZE));
checkHipErrors(hipMemcpyHtoD(Bd, B, SIZE));
hipModule_t Module;
hipFunction_t Function;
checkHipErrors(hipModuleLoad(&Module, fileName));
checkHipErrors(hipModuleGetFunction(&Function, Module, kernel_name));
struct {
void* _Ad;
void* _Bd;
} args;
args._Ad = Ad;
args._Bd = Bd;
size_t size = sizeof(args);
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size,
HIP_LAUNCH_PARAM_END};
checkHipErrors(
hipExtModuleLaunchKernel(Function, LEN, 1, 1, LEN, 1, 1, 0, 0, NULL, (void**)&config, 0));
checkHipErrors(hipMemcpyDtoH(B, Bd, SIZE));
int mismatchCount = 0;
for (uint32_t i = 0; i < LEN; i++) {
if (A[i] != B[i]) {
mismatchCount++;
std::cout << "error: mismatch " << A[i] << " != " << B[i] << std::endl;
}
}
hipInit(0);
hipDevice_t device;
hipCtx_t context;
checkHipErrors(hipDeviceGet(&device, 0));
checkHipErrors(hipCtxCreate(&context, 0, device));
if (mismatchCount == 0) {
std::cout << "PASSED!\n";
} else {
std::cout << "FAILED!\n";
};
checkHipErrors(hipMalloc((void**)&Ad, SIZE));
checkHipErrors(hipMalloc((void**)&Bd, SIZE));
checkHipErrors(hipMemcpyHtoD(Ad, A, SIZE));
checkHipErrors(hipMemcpyHtoD(Bd, B, SIZE));
hipModule_t Module;
hipFunction_t Function;
checkHipErrors(hipModuleLoad(&Module, fileName));
checkHipErrors(hipModuleGetFunction(&Function, Module, kernel_name));
struct {
void* _Ad;
void* _Bd;
} args;
args._Ad = Ad;
args._Bd = Bd;
size_t size = sizeof(args);
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size,
HIP_LAUNCH_PARAM_END};
checkHipErrors(
hipExtModuleLaunchKernel(Function, LEN, 1, 1, LEN, 1, 1, 0, 0, NULL, (void**)&config, 0));
checkHipErrors(hipMemcpyDtoH(B, Bd, SIZE));
int mismatchCount = 0;
for (uint32_t i = 0; i < LEN; i++) {
if (A[i] != B[i]) {
mismatchCount++;
std::cout << "error: mismatch " << A[i] << " != " << B[i] << std::endl;
}
}
if (mismatchCount == 0) {
std::cout << "PASSED!\n";
} else {
std::cout << "FAILED!\n";
};
checkHipErrors(hipFree(Ad));
checkHipErrors(hipFree(Bd));
delete[] A;
delete[] B;
checkHipErrors(hipCtxDestroy(context));
return 0;
checkHipErrors(hipFree(Ad));
checkHipErrors(hipFree(Bd));
delete[] A;
delete[] B;
checkHipErrors(hipCtxDestroy(context));
return 0;
}
@@ -35,67 +35,67 @@ THE SOFTWARE.
#define kernel_name "hello_world"
int main() {
float *A, *B;
hipDeviceptr_t Ad, Bd;
A = new float[LEN];
B = new float[LEN];
float *A, *B;
hipDeviceptr_t Ad, Bd;
A = new float[LEN];
B = new float[LEN];
for (uint32_t i = 0; i < LEN; i++) {
A[i] = i * 1.0f;
B[i] = 0.0f;
for (uint32_t i = 0; i < LEN; i++) {
A[i] = i * 1.0f;
B[i] = 0.0f;
}
hipInit(0);
hipDevice_t device;
hipCtx_t context;
checkHipErrors(hipDeviceGet(&device, 0));
checkHipErrors(hipCtxCreate(&context, 0, device));
checkHipErrors(hipMalloc((void**)&Ad, SIZE));
checkHipErrors(hipMalloc((void**)&Bd, SIZE));
checkHipErrors(hipMemcpyHtoD(Ad, A, SIZE));
checkHipErrors(hipMemcpyHtoD(Bd, B, SIZE));
hipModule_t Module;
hipFunction_t Function;
checkHipErrors(hipModuleLoad(&Module, fileName));
checkHipErrors(hipModuleGetFunction(&Function, Module, kernel_name));
struct {
void* _Ad;
void* _Bd;
} args;
args._Ad = (void*)Ad;
args._Bd = (void*)Bd;
size_t size = sizeof(args);
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size,
HIP_LAUNCH_PARAM_END};
checkHipErrors(hipModuleLaunchKernel(Function, 1, 1, 1, LEN, 1, 1, 0, 0, NULL, (void**)&config));
checkHipErrors(hipMemcpyDtoH(B, Bd, SIZE));
int mismatchCount = 0;
for (uint32_t i = 0; i < LEN; i++) {
if (A[i] != B[i]) {
mismatchCount++;
std::cout << "error: mismatch " << A[i] << " != " << B[i] << std::endl;
}
}
hipInit(0);
hipDevice_t device;
hipCtx_t context;
checkHipErrors(hipDeviceGet(&device, 0));
checkHipErrors(hipCtxCreate(&context, 0, device));
if (mismatchCount == 0) {
std::cout << "PASSED!\n";
} else {
std::cout << "FAILED!\n";
};
checkHipErrors(hipMalloc((void**)&Ad, SIZE));
checkHipErrors(hipMalloc((void**)&Bd, SIZE));
checkHipErrors(hipMemcpyHtoD(Ad, A, SIZE));
checkHipErrors(hipMemcpyHtoD(Bd, B, SIZE));
hipModule_t Module;
hipFunction_t Function;
checkHipErrors(hipModuleLoad(&Module, fileName));
checkHipErrors(hipModuleGetFunction(&Function, Module, kernel_name));
struct {
void* _Ad;
void* _Bd;
} args;
args._Ad = (void*) Ad;
args._Bd = (void*) Bd;
size_t size = sizeof(args);
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size,
HIP_LAUNCH_PARAM_END};
checkHipErrors(hipModuleLaunchKernel(Function, 1, 1, 1, LEN, 1, 1, 0, 0, NULL, (void**)&config));
checkHipErrors(hipMemcpyDtoH(B, Bd, SIZE));
int mismatchCount = 0;
for (uint32_t i = 0; i < LEN; i++) {
if (A[i] != B[i]) {
mismatchCount++;
std::cout << "error: mismatch " << A[i] << " != " << B[i] << std::endl;
}
}
if (mismatchCount == 0) {
std::cout << "PASSED!\n";
} else {
std::cout << "FAILED!\n";
};
checkHipErrors(hipFree(Ad));
hipFree(Bd);
delete[] A;
delete[] B;
checkHipErrors(hipCtxDestroy(context));
return 0;
checkHipErrors(hipFree(Ad));
hipFree(Bd);
delete[] A;
delete[] B;
checkHipErrors(hipCtxDestroy(context));
return 0;
}
@@ -23,6 +23,6 @@ THE SOFTWARE.
#include "hip/hip_runtime.h"
extern "C" __global__ void hello_world(float* a, float* b) {
int tx = threadIdx.x;
b[tx] = a[tx];
int tx = threadIdx.x;
b[tx] = a[tx];
}
@@ -31,131 +31,136 @@ THE SOFTWARE.
#define SIZE LEN * sizeof(float)
#define fileName "vcpy_kernel.code"
#define checkHipErrors(cmd) \
{ \
hipError_t status = cmd; \
if (status != hipSuccess) { \
std::cout << "error: #" << status << " (" << hipGetErrorString(status) \
<< ") at line:" << __LINE__ << ": " << #cmd << std::endl; \
abort(); \
} \
}
#define checkHipErrors(cmd) \
{ \
hipError_t status = cmd; \
if (status != hipSuccess) { \
std::cout << "error: #" << status << " (" << hipGetErrorString(status) \
<< ") at line:" << __LINE__ << ": " << #cmd << std::endl; \
abort(); \
} \
}
int main() {
float *A, *B;
float *Ad, *Bd;
A = new float[LEN];
B = new float[LEN];
float *A, *B;
float *Ad, *Bd;
A = new float[LEN];
B = new float[LEN];
for (uint32_t i = 0; i < LEN; i++) {
A[i] = i * 1.0f;
B[i] = 0.0f;
}
for (uint32_t i = 0; i < LEN; i++) {
A[i] = i * 1.0f;
B[i] = 0.0f;
}
hipInit(0);
hipDevice_t device;
hipCtx_t context;
hipDeviceGet(&device, 0);
hipCtxCreate(&context, 0, device);
hipInit(0);
hipDevice_t device;
hipCtx_t context;
hipDeviceGet(&device, 0);
hipCtxCreate(&context, 0, device);
hipMalloc((void**)&Ad, SIZE);
hipMalloc((void**)&Bd, SIZE);
hipMalloc((void**)&Ad, SIZE);
hipMalloc((void**)&Bd, SIZE);
hipMemcpyHtoD(hipDeviceptr_t(Ad), A, SIZE);
hipMemcpyHtoD((hipDeviceptr_t)(Bd), B, SIZE);
hipModule_t Module;
checkHipErrors(hipModuleLoad(&Module, fileName));
hipMemcpyHtoD(hipDeviceptr_t(Ad), A, SIZE);
hipMemcpyHtoD((hipDeviceptr_t)(Bd), B, SIZE);
hipModule_t Module;
checkHipErrors(hipModuleLoad(&Module, fileName));
float myDeviceGlobal_h = 42.0;
float* deviceGlobal;
size_t deviceGlobalSize;
checkHipErrors(hipModuleGetGlobal((void**)&deviceGlobal, &deviceGlobalSize, Module, "myDeviceGlobal"));
checkHipErrors(hipMemcpyHtoD(hipDeviceptr_t(deviceGlobal), &myDeviceGlobal_h, deviceGlobalSize));
float myDeviceGlobal_h = 42.0;
float* deviceGlobal;
size_t deviceGlobalSize;
checkHipErrors(
hipModuleGetGlobal((void**)&deviceGlobal, &deviceGlobalSize, Module, "myDeviceGlobal"));
checkHipErrors(hipMemcpyHtoD(hipDeviceptr_t(deviceGlobal), &myDeviceGlobal_h, deviceGlobalSize));
#define ARRAY_SIZE 16
float myDeviceGlobalArray_h[ARRAY_SIZE];
float *myDeviceGlobalArray;
size_t myDeviceGlobalArraySize;
checkHipErrors(hipModuleGetGlobal((void**)&myDeviceGlobalArray, &myDeviceGlobalArraySize, Module, "myDeviceGlobalArray"));
for (int i = 0; i < ARRAY_SIZE; i++) {
myDeviceGlobalArray_h[i] = i * 1000.0f;
}
checkHipErrors(hipMemcpyHtoD(hipDeviceptr_t(myDeviceGlobalArray), &myDeviceGlobalArray_h, myDeviceGlobalArraySize));
float myDeviceGlobalArray_h[ARRAY_SIZE];
float* myDeviceGlobalArray;
size_t myDeviceGlobalArraySize;
checkHipErrors(hipModuleGetGlobal((void**)&myDeviceGlobalArray, &myDeviceGlobalArraySize, Module,
"myDeviceGlobalArray"));
for (int i = 0; i < ARRAY_SIZE; i++) {
myDeviceGlobalArray_h[i] = i * 1000.0f;
}
checkHipErrors(hipMemcpyHtoD(hipDeviceptr_t(myDeviceGlobalArray), &myDeviceGlobalArray_h,
myDeviceGlobalArraySize));
struct {
void* _Ad;
void* _Bd;
} args;
struct {
void* _Ad;
void* _Bd;
} args;
args._Ad = (void*) Ad;
args._Bd = (void*) Bd;
args._Ad = (void*)Ad;
args._Bd = (void*)Bd;
size_t size = sizeof(args);
size_t size = sizeof(args);
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size,
HIP_LAUNCH_PARAM_END};
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size,
HIP_LAUNCH_PARAM_END};
{
hipFunction_t Function;
checkHipErrors(hipModuleGetFunction(&Function, Module, "hello_world"));
checkHipErrors(hipModuleLaunchKernel(Function, 1, 1, 1, LEN, 1, 1, 0, 0, NULL, (void**)&config));
{
hipFunction_t Function;
checkHipErrors(hipModuleGetFunction(&Function, Module, "hello_world"));
checkHipErrors(
hipModuleLaunchKernel(Function, 1, 1, 1, LEN, 1, 1, 0, 0, NULL, (void**)&config));
hipMemcpyDtoH(B, Bd, SIZE);
hipMemcpyDtoH(B, Bd, SIZE);
int mismatchCount = 0;
for (uint32_t i = 0; i < LEN; i++) {
if (A[i] != B[i]) {
mismatchCount++;
std::cout << "error: mismatch " << A[i] << " != " << B[i] << std::endl;
if (mismatchCount >= 10) {
break;
}
}
int mismatchCount = 0;
for (uint32_t i = 0; i < LEN; i++) {
if (A[i] != B[i]) {
mismatchCount++;
std::cout << "error: mismatch " << A[i] << " != " << B[i] << std::endl;
if (mismatchCount >= 10) {
break;
}
if (mismatchCount == 0) {
std::cout << "PASSED!\n";
} else {
std::cout << "FAILED!\n";
};
}
}
{
hipFunction_t Function;
checkHipErrors(hipModuleGetFunction(&Function, Module, "test_globals"));
int val =-1;
checkHipErrors(hipFuncGetAttribute(&val, HIP_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES,Function));
printf("Shared Size Bytes = %d\n",val);
checkHipErrors(hipFuncGetAttribute(&val, HIP_FUNC_ATTRIBUTE_NUM_REGS, Function));
printf("Num Regs = %d\n",val);
checkHipErrors(hipModuleLaunchKernel(Function, 1, 1, 1, LEN, 1, 1, 0, 0, NULL, (void**)&config));
if (mismatchCount == 0) {
std::cout << "PASSED!\n";
} else {
std::cout << "FAILED!\n";
};
}
hipMemcpyDtoH(B, Bd, SIZE);
{
hipFunction_t Function;
checkHipErrors(hipModuleGetFunction(&Function, Module, "test_globals"));
int val = -1;
checkHipErrors(hipFuncGetAttribute(&val, HIP_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES, Function));
printf("Shared Size Bytes = %d\n", val);
checkHipErrors(hipFuncGetAttribute(&val, HIP_FUNC_ATTRIBUTE_NUM_REGS, Function));
printf("Num Regs = %d\n", val);
checkHipErrors(
hipModuleLaunchKernel(Function, 1, 1, 1, LEN, 1, 1, 0, 0, NULL, (void**)&config));
int mismatchCount = 0;
for (uint32_t i = 0; i < LEN; i++) {
float expected = A[i] + myDeviceGlobal_h + myDeviceGlobalArray_h[i % 16];
if (expected != B[i]) {
mismatchCount++;
std::cout << "error: mismatch " << expected << " != " << B[i] << std::endl;
if (mismatchCount >= 10) {
break;
}
}
hipMemcpyDtoH(B, Bd, SIZE);
int mismatchCount = 0;
for (uint32_t i = 0; i < LEN; i++) {
float expected = A[i] + myDeviceGlobal_h + myDeviceGlobalArray_h[i % 16];
if (expected != B[i]) {
mismatchCount++;
std::cout << "error: mismatch " << expected << " != " << B[i] << std::endl;
if (mismatchCount >= 10) {
break;
}
if (mismatchCount == 0) {
std::cout << "PASSED!\n";
} else {
std::cout << "FAILED!\n";
};
}
}
hipFree(Ad);
hipFree(Bd);
delete[] A;
delete[] B;
hipCtxDestroy(context);
return 0;
if (mismatchCount == 0) {
std::cout << "PASSED!\n";
} else {
std::cout << "FAILED!\n";
};
}
hipFree(Ad);
hipFree(Bd);
delete[] A;
delete[] B;
hipCtxDestroy(context);
return 0;
}
@@ -28,11 +28,11 @@ __device__ float myDeviceGlobal;
__device__ float myDeviceGlobalArray[16];
extern "C" __global__ void hello_world(const float* a, float* b) {
int tx = threadIdx.x;
b[tx] = a[tx];
int tx = threadIdx.x;
b[tx] = a[tx];
}
extern "C" __global__ void test_globals(const float* a, float* b) {
int tx = threadIdx.x;
b[tx] = a[tx] + myDeviceGlobal + myDeviceGlobalArray[tx % ARRAY_SIZE];
int tx = threadIdx.x;
b[tx] = a[tx] + myDeviceGlobal + myDeviceGlobalArray[tx % ARRAY_SIZE];
}
@@ -24,79 +24,78 @@ THE SOFTWARE.
#include "hip/hip_runtime.h"
#define CHECK(cmd) \
{ \
hipError_t error = cmd; \
if (error != hipSuccess) { \
fprintf(stderr, "error: '%s'(%d) at %s:%d\n", hipGetErrorString(error), error, \
__FILE__, __LINE__); \
exit(EXIT_FAILURE); \
} \
}
{ \
hipError_t error = cmd; \
if (error != hipSuccess) { \
fprintf(stderr, "error: '%s'(%d) at %s:%d\n", hipGetErrorString(error), error, __FILE__, \
__LINE__); \
exit(EXIT_FAILURE); \
} \
}
/*
* Square each element in the array A and write to array C.
*/
template <typename T>
__global__ void vector_square(T* C_d, const T* A_d, size_t N) {
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
size_t stride = blockDim.x * gridDim.x;
template <typename T> __global__ void vector_square(T* C_d, const T* A_d, size_t N) {
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
size_t stride = blockDim.x * gridDim.x;
for (size_t i = offset; i < N; i += stride) {
C_d[i] = A_d[i] * A_d[i];
}
for (size_t i = offset; i < N; i += stride) {
C_d[i] = A_d[i] * A_d[i];
}
}
int main(int argc, char* argv[]) {
float *A_d, *C_d;
float *A_h, *C_h;
size_t N = 1000000;
size_t Nbytes = N * sizeof(float);
static int device = 0;
CHECK(hipSetDevice(device));
hipDeviceProp_t props;
CHECK(hipGetDeviceProperties(&props, device /*deviceID*/));
printf("info: running on device %s\n", props.name);
float *A_d, *C_d;
float *A_h, *C_h;
size_t N = 1000000;
size_t Nbytes = N * sizeof(float);
static int device = 0;
CHECK(hipSetDevice(device));
hipDeviceProp_t props;
CHECK(hipGetDeviceProperties(&props, device /*deviceID*/));
printf("info: running on device %s\n", props.name);
#ifdef __HIP_PLATFORM_AMD__
printf("info: architecture on AMD GPU device is: %s\n", props.gcnArchName);
printf("info: architecture on AMD GPU device is: %s\n", props.gcnArchName);
#endif
printf("info: allocate host mem (%6.2f MB)\n", 2 * Nbytes / 1024.0 / 1024.0);
A_h = (float*)malloc(Nbytes);
CHECK(A_h == 0 ? hipErrorOutOfMemory : hipSuccess);
C_h = (float*)malloc(Nbytes);
CHECK(C_h == 0 ? hipErrorOutOfMemory : hipSuccess);
// Fill with Phi + i
for (size_t i = 0; i < N; i++) {
A_h[i] = 1.618f + i;
printf("info: allocate host mem (%6.2f MB)\n", 2 * Nbytes / 1024.0 / 1024.0);
A_h = (float*)malloc(Nbytes);
CHECK(A_h == 0 ? hipErrorOutOfMemory : hipSuccess);
C_h = (float*)malloc(Nbytes);
CHECK(C_h == 0 ? hipErrorOutOfMemory : hipSuccess);
// Fill with Phi + i
for (size_t i = 0; i < N; i++) {
A_h[i] = 1.618f + i;
}
printf("info: allocate device mem (%6.2f MB)\n", 2 * Nbytes / 1024.0 / 1024.0);
CHECK(hipMalloc(&A_d, Nbytes));
CHECK(hipMalloc(&C_d, Nbytes));
printf("info: copy Host2Device\n");
CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
const unsigned blocks = 512;
const unsigned threadsPerBlock = 256;
printf("info: launch 'vector_square' kernel\n");
hipLaunchKernelGGL(vector_square, dim3(blocks), dim3(threadsPerBlock), 0, 0, C_d, A_d, N);
printf("info: copy Device2Host\n");
CHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
printf("info: check result\n");
for (size_t i = 0; i < N; i++) {
if (C_h[i] != A_h[i] * A_h[i]) {
CHECK(hipErrorUnknown);
}
}
printf("info: allocate device mem (%6.2f MB)\n", 2 * Nbytes / 1024.0 / 1024.0);
CHECK(hipMalloc(&A_d, Nbytes));
CHECK(hipMalloc(&C_d, Nbytes));
CHECK(hipFree(A_d));
CHECK(hipFree(C_d));
free(A_h);
free(C_h);
printf("info: copy Host2Device\n");
CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
const unsigned blocks = 512;
const unsigned threadsPerBlock = 256;
printf("info: launch 'vector_square' kernel\n");
hipLaunchKernelGGL(vector_square, dim3(blocks), dim3(threadsPerBlock), 0, 0, C_d, A_d, N);
printf("info: copy Device2Host\n");
CHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
printf("info: check result\n");
for (size_t i = 0; i < N; i++) {
if (C_h[i] != A_h[i] * A_h[i]) {
CHECK(hipErrorUnknown);
}
}
CHECK(hipFree(A_d));
CHECK(hipFree(C_d));
free(A_h);
free(C_h);
printf("PASSED!\n");
printf("PASSED!\n");
}
@@ -39,154 +39,155 @@ THE SOFTWARE.
#define TIMING_RUN_COUNT 100
#define TOTAL_RUN_COUNT WARMUP_RUN_COUNT + TIMING_RUN_COUNT
#define FILENAME "test_kernel.code"
#define failed(...) \
abort();
#define failed(...) abort();
__global__ void EmptyKernel() {}
// Helper to print various timing metrics
void print_timing(std::string test, std::array<float, TOTAL_RUN_COUNT> &results, int batch = 1)
{
void print_timing(std::string test, std::array<float, TOTAL_RUN_COUNT>& results, int batch = 1) {
float total_us = 0.0f, mean_us = 0.0f, stddev_us = 0.0f;
float total_us = 0.0f, mean_us = 0.0f, stddev_us = 0.0f;
// remove top outliers due to nature of variability across large number of multi-threaded runs
std::sort(results.begin(), results.end(), std::greater<float>());
auto start_iter = std::next(results.begin(), WARMUP_RUN_COUNT);
auto end_iter = results.end();
// remove top outliers due to nature of variability across large number of multi-threaded runs
std::sort(results.begin(), results.end(), std::greater<float>());
auto start_iter = std::next(results.begin(), WARMUP_RUN_COUNT);
auto end_iter = results.end();
// mean
std::for_each(start_iter, end_iter,
[&](const float& run_ms) { total_us += (run_ms * 1000) / batch; });
mean_us = total_us / TIMING_RUN_COUNT;
// mean
std::for_each(start_iter, end_iter, [&](const float &run_ms) {
total_us += (run_ms * 1000) / batch;
});
mean_us = total_us / TIMING_RUN_COUNT;
// stddev
total_us = 0;
std::for_each(start_iter, end_iter, [&](const float& run_ms) {
float dev_us = ((run_ms * 1000) / batch) - mean_us;
total_us += dev_us * dev_us;
});
stddev_us = sqrt(total_us / TIMING_RUN_COUNT);
// stddev
total_us = 0;
std::for_each(start_iter, end_iter, [&](const float &run_ms) {
float dev_us = ((run_ms * 1000) / batch) - mean_us;
total_us += dev_us * dev_us;
});
stddev_us = sqrt(total_us / TIMING_RUN_COUNT);
printf("\n %s: %.1f us, std: %.1f us\n", test.c_str(), mean_us, stddev_us);
printf("\n %s: %.1f us, std: %.1f us\n", test.c_str(), mean_us, stddev_us);
}
// Measure time taken to enqueue a kernel on the GPU using hipModuleLaunchKernel
void hipModuleLaunchKernel_enqueue_rate(const std::vector<char>& buffer, std::atomic_int* shared, int max_threads)
{
//resources necessary for this thread
hipStream_t stream;
checkHipErrors(hipStreamCreate(&stream));
hipModule_t module;
hipFunction_t function;
void hipModuleLaunchKernel_enqueue_rate(const std::vector<char>& buffer, std::atomic_int* shared,
int max_threads) {
// resources necessary for this thread
hipStream_t stream;
checkHipErrors(hipStreamCreate(&stream));
hipModule_t module;
hipFunction_t function;
checkHipErrors(hipModuleLoadData(&module, &buffer[0]));
checkHipErrors(hipModuleGetFunction(&function, module, "test"));
checkHipErrors(hipModuleLoadData(&module, &buffer[0]));
checkHipErrors(hipModuleGetFunction(&function, module, "test"));
void* kernel_params = nullptr;
std::array<float, TOTAL_RUN_COUNT> results;
void* kernel_params = nullptr;
std::array<float, TOTAL_RUN_COUNT> results;
//synchronize all threads, before running
int tid = shared->fetch_add(1, std::memory_order_release);
while (max_threads != shared->load(std::memory_order_acquire)) {}
// synchronize all threads, before running
int tid = shared->fetch_add(1, std::memory_order_release);
while (max_threads != shared->load(std::memory_order_acquire)) {
}
for (auto i = 0; i < TOTAL_RUN_COUNT; ++i) {
auto start = std::chrono::high_resolution_clock::now();
checkHipErrors(hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, stream, &kernel_params, nullptr));
auto stop = std::chrono::high_resolution_clock::now();
results[i] = std::chrono::duration<double, std::milli>(stop - start).count();
}
for (auto i = 0; i < TOTAL_RUN_COUNT; ++i) {
auto start = std::chrono::high_resolution_clock::now();
checkHipErrors(
hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, stream, &kernel_params, nullptr));
auto stop = std::chrono::high_resolution_clock::now();
results[i] = std::chrono::duration<double, std::milli>(stop - start).count();
}
checkHipErrors(hipModuleUnload(module));
print_timing("Thread ID : " + std::to_string(tid) + " , " + "hipModuleLaunchKernel enqueue rate", results);
checkHipErrors(hipStreamSynchronize(stream));
checkHipErrors(hipStreamDestroy(stream));
checkHipErrors(hipModuleUnload(module));
print_timing("Thread ID : " + std::to_string(tid) + " , " + "hipModuleLaunchKernel enqueue rate",
results);
checkHipErrors(hipStreamSynchronize(stream));
checkHipErrors(hipStreamDestroy(stream));
}
// Measure time taken to enqueue a kernel on the GPU using hipLaunchKernelGGL
void hipLaunchKernelGGL_enqueue_rate(const std::vector<char>& buffer, std::atomic_int* shared, int max_threads)
{
//resources necessary for this thread
hipStream_t stream;
checkHipErrors(hipStreamCreate(&stream));
std::array<float, TOTAL_RUN_COUNT> results;
void hipLaunchKernelGGL_enqueue_rate(const std::vector<char>& buffer, std::atomic_int* shared,
int max_threads) {
// resources necessary for this thread
hipStream_t stream;
checkHipErrors(hipStreamCreate(&stream));
std::array<float, TOTAL_RUN_COUNT> results;
//synchronize all threads, before running
int tid = shared->fetch_add(1, std::memory_order_release);
while (max_threads != shared->load(std::memory_order_acquire)) {}
// synchronize all threads, before running
int tid = shared->fetch_add(1, std::memory_order_release);
while (max_threads != shared->load(std::memory_order_acquire)) {
}
for (auto i = 0; i < TOTAL_RUN_COUNT; ++i) {
auto start = std::chrono::high_resolution_clock::now();
hipLaunchKernelGGL((EmptyKernel), dim3(NUM_GROUPS), dim3(GROUP_SIZE), 0, stream);
auto stop = std::chrono::high_resolution_clock::now();
results[i] = std::chrono::duration<double, std::milli>(stop - start).count();
}
print_timing("Thread ID : " + std::to_string(tid) + " , " + "hipLaunchKernelGGL enqueue rate", results);
checkHipErrors(hipStreamSynchronize(stream));
checkHipErrors(hipStreamDestroy(stream));
for (auto i = 0; i < TOTAL_RUN_COUNT; ++i) {
auto start = std::chrono::high_resolution_clock::now();
hipLaunchKernelGGL((EmptyKernel), dim3(NUM_GROUPS), dim3(GROUP_SIZE), 0, stream);
auto stop = std::chrono::high_resolution_clock::now();
results[i] = std::chrono::duration<double, std::milli>(stop - start).count();
}
print_timing("Thread ID : " + std::to_string(tid) + " , " + "hipLaunchKernelGGL enqueue rate",
results);
checkHipErrors(hipStreamSynchronize(stream));
checkHipErrors(hipStreamDestroy(stream));
}
// Simple thread pool
struct thread_pool {
thread_pool(int total_threads) : max_threads(total_threads) {
std::ifstream file(FILENAME, std::ios::binary | std::ios::ate);
std::streamsize fsize = file.tellg();
file.seekg(0, std::ios::beg);
thread_pool(int total_threads) : max_threads(total_threads) {
std::ifstream file(FILENAME, std::ios::binary | std::ios::ate);
std::streamsize fsize = file.tellg();
file.seekg(0, std::ios::beg);
buffer.resize(fsize);
if (!file.read(buffer.data(), fsize)) {
failed("could not open code object '%s'\n", FILENAME);
}
file.close();
buffer.resize(fsize);
if (!file.read(buffer.data(), fsize)) {
failed("could not open code object '%s'\n", FILENAME);
}
void start(std::function<void(const std::vector<char>&, std::atomic_int*, int)> f) {
for (int i = 0; i < max_threads; ++i) {
threads.push_back(std::async(std::launch::async, f, std::ref(buffer), &shared, max_threads));
}
file.close();
}
void start(std::function<void(const std::vector<char>&, std::atomic_int*, int)> f) {
for (int i = 0; i < max_threads; ++i) {
threads.push_back(std::async(std::launch::async, f, std::ref(buffer), &shared, max_threads));
}
void finish() {
for (auto&&thread : threads) {
thread.get();
}
threads.clear();
shared = 0;
}
void finish() {
for (auto&& thread : threads) {
thread.get();
}
~thread_pool() {
finish();
}
private:
std::atomic_int shared {0};
std::vector<char> buffer;
std::vector<std::future<void>> threads;
int max_threads = 1;
threads.clear();
shared = 0;
}
~thread_pool() { finish(); }
private:
std::atomic_int shared{0};
std::vector<char> buffer;
std::vector<std::future<void>> threads;
int max_threads = 1;
};
int main(int argc, char* argv[])
{
if (argc != 3) {
std::cerr << "Run test as 'hipDispatchEnqueueRateMT <num_threads> <0-hipModuleLaunchKernel /1-hipLaunchKernelGGL>'\n";
return -1;
}
int max_threads = atoi(argv[1]);
int run_module_test = atoi(argv[2]);
if(max_threads < 1 || run_module_test < 0 || run_module_test > 1) {
std::cerr << "Invalid Input.\n";
std::cerr << "Run test as 'hipDispatchEnqueueRateMT <num_threads> <0-hipModuleLaunchKernel /1-hipLaunchKernelGGL>'\n";
return -1;
}
thread_pool task(max_threads);
int main(int argc, char* argv[]) {
if (argc != 3) {
std::cerr << "Run test as 'hipDispatchEnqueueRateMT <num_threads> <0-hipModuleLaunchKernel "
"/1-hipLaunchKernelGGL>'\n";
return -1;
}
int max_threads = atoi(argv[1]);
int run_module_test = atoi(argv[2]);
if (max_threads < 1 || run_module_test < 0 || run_module_test > 1) {
std::cerr << "Invalid Input.\n";
std::cerr << "Run test as 'hipDispatchEnqueueRateMT <num_threads> <0-hipModuleLaunchKernel "
"/1-hipLaunchKernelGGL>'\n";
return -1;
}
thread_pool task(max_threads);
if(run_module_test == 0) {
task.start(hipModuleLaunchKernel_enqueue_rate);
task.finish();
} else {
task.start(hipLaunchKernelGGL_enqueue_rate);
task.finish();
}
if (run_module_test == 0) {
task.start(hipModuleLaunchKernel_enqueue_rate);
task.finish();
} else {
task.start(hipLaunchKernelGGL_enqueue_rate);
task.finish();
}
return 0;
return 0;
}
@@ -36,107 +36,105 @@ THE SOFTWARE.
#define FILE_NAME "test_kernel.code"
#define KERNEL_NAME "test"
__global__ void EmptyKernel() { }
__global__ void EmptyKernel() {}
void print_timing(std::string test, const std::array<float, TOTAL_RUN_COUNT> &results, int batch = 1) {
void print_timing(std::string test, const std::array<float, TOTAL_RUN_COUNT>& results,
int batch = 1) {
float total_us = 0.0f, mean_us = 0.0f, stddev_us = 0.0f;
float total_us = 0.0f, mean_us = 0.0f, stddev_us = 0.0f;
// skip warm-up runs
auto start_iter = std::next(results.begin(), WARMUP_RUN_COUNT);
auto end_iter = results.end();
// skip warm-up runs
auto start_iter = std::next(results.begin(), WARMUP_RUN_COUNT);
auto end_iter = results.end();
// mean
std::for_each(start_iter, end_iter,
[&](const float& run_ms) { total_us += (run_ms * 1000) / batch; });
mean_us = total_us / TIMING_RUN_COUNT;
// mean
std::for_each(start_iter, end_iter, [&](const float &run_ms) {
total_us += (run_ms * 1000) / batch;
});
mean_us = total_us / TIMING_RUN_COUNT;
// stddev
total_us = 0;
std::for_each(start_iter, end_iter, [&](const float& run_ms) {
float dev_us = ((run_ms * 1000) / batch) - mean_us;
total_us += dev_us * dev_us;
});
stddev_us = sqrt(total_us / TIMING_RUN_COUNT);
// stddev
total_us = 0;
std::for_each(start_iter, end_iter, [&](const float &run_ms) {
float dev_us = ((run_ms * 1000) / batch) - mean_us;
total_us += dev_us * dev_us;
});
stddev_us = sqrt(total_us / TIMING_RUN_COUNT);
// display
printf("\n %s: %.1f us, std: %.1f us\n", test.c_str(), mean_us, stddev_us);
// display
printf("\n %s: %.1f us, std: %.1f us\n", test.c_str(), mean_us, stddev_us);
}
int main() {
hipStream_t stream0 = 0;
hipDevice_t device;
checkHipErrors(hipDeviceGet(&device, 0));
hipCtx_t context;
checkHipErrors(hipCtxCreate(&context, 0, device));
hipModule_t module;
hipFunction_t function;
checkHipErrors(hipModuleLoad(&module, FILE_NAME));
checkHipErrors(hipModuleGetFunction(&function, module, KERNEL_NAME));
void* params = nullptr;
hipStream_t stream0 = 0;
hipDevice_t device;
checkHipErrors(hipDeviceGet(&device, 0));
hipCtx_t context;
checkHipErrors(hipCtxCreate(&context, 0, device));
hipModule_t module;
hipFunction_t function;
checkHipErrors(hipModuleLoad(&module, FILE_NAME));
checkHipErrors(hipModuleGetFunction(&function, module, KERNEL_NAME));
void* params = nullptr;
std::array<float, TOTAL_RUN_COUNT> results;
hipEvent_t start, stop;
checkHipErrors(hipEventCreate(&start));
checkHipErrors(hipEventCreate(&stop));
std::array<float, TOTAL_RUN_COUNT> results;
hipEvent_t start, stop;
checkHipErrors(hipEventCreate(&start));
checkHipErrors(hipEventCreate(&stop));
/************************************************************************************/
/* HIP kernel launch enqueue rate: */
/* Measure time taken to enqueue a kernel on the GPU */
/************************************************************************************/
/************************************************************************************/
/* HIP kernel launch enqueue rate: */
/* Measure time taken to enqueue a kernel on the GPU */
/************************************************************************************/
// Timing hipModuleLaunchKernel
for (auto i = 0; i < TOTAL_RUN_COUNT; ++i) {
auto start = std::chrono::high_resolution_clock::now();
checkHipErrors(hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, 0, &params, nullptr));
auto stop = std::chrono::high_resolution_clock::now();
results[i] = std::chrono::duration<float, std::milli>(stop - start).count();
// Timing hipModuleLaunchKernel
for (auto i = 0; i < TOTAL_RUN_COUNT; ++i) {
auto start = std::chrono::high_resolution_clock::now();
checkHipErrors(hipModuleLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, 0, &params, nullptr));
auto stop = std::chrono::high_resolution_clock::now();
results[i] = std::chrono::duration<float, std::milli>(stop - start).count();
}
print_timing("hipModuleLaunchKernel enqueue rate", results);
// Timing hipLaunchKernelGGL
for (auto i = 0; i < TOTAL_RUN_COUNT; ++i) {
auto start = std::chrono::high_resolution_clock::now();
hipLaunchKernelGGL((EmptyKernel), dim3(NUM_GROUPS), dim3(GROUP_SIZE), 0, stream0);
auto stop = std::chrono::high_resolution_clock::now();
results[i] = std::chrono::duration<float, std::milli>(stop - start).count();
}
print_timing("hipLaunchKernelGGL enqueue rate", results);
/***********************************************************************************/
/* Single dispatch execution latency using HIP events: */
/* Measures latency to start & finish executing a kernel with GPU-scope visibility */
/***********************************************************************************/
// Timing around the dispatch
for (auto i = 0; i < TOTAL_RUN_COUNT; ++i) {
checkHipErrors(hipEventRecord(start, 0));
hipLaunchKernelGGL((EmptyKernel), dim3(NUM_GROUPS), dim3(GROUP_SIZE), 0, stream0);
checkHipErrors(hipEventRecord(stop, 0));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&results[i], start, stop));
}
print_timing("Timing around single dispatch latency", results);
/*********************************************************************************/
/* Batch dispatch execution latency using HIP events: */
/* Measures latency to start & finish executing each dispatch in a batch */
/*********************************************************************************/
for (auto i = 0; i < TOTAL_RUN_COUNT; ++i) {
checkHipErrors(hipEventRecord(start, 0));
for (int j = 0; j < BATCH_SIZE; j++) {
hipLaunchKernelGGL((EmptyKernel), dim3(NUM_GROUPS), dim3(GROUP_SIZE), 0, stream0);
}
print_timing("hipModuleLaunchKernel enqueue rate", results);
checkHipErrors(hipEventRecord(stop, 0));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&results[i], start, stop));
}
print_timing("Batch dispatch latency", results, BATCH_SIZE);
// Timing hipLaunchKernelGGL
for (auto i = 0; i < TOTAL_RUN_COUNT; ++i) {
auto start = std::chrono::high_resolution_clock::now();
hipLaunchKernelGGL((EmptyKernel), dim3(NUM_GROUPS), dim3(GROUP_SIZE), 0, stream0);
auto stop = std::chrono::high_resolution_clock::now();
results[i] = std::chrono::duration<float, std::milli>(stop - start).count();
}
print_timing("hipLaunchKernelGGL enqueue rate", results);
/***********************************************************************************/
/* Single dispatch execution latency using HIP events: */
/* Measures latency to start & finish executing a kernel with GPU-scope visibility */
/***********************************************************************************/
//Timing around the dispatch
for (auto i = 0; i < TOTAL_RUN_COUNT; ++i) {
checkHipErrors(hipEventRecord(start, 0));
hipLaunchKernelGGL((EmptyKernel), dim3(NUM_GROUPS), dim3(GROUP_SIZE), 0, stream0);
checkHipErrors(hipEventRecord(stop, 0));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&results[i], start, stop));
}
print_timing("Timing around single dispatch latency", results);
/*********************************************************************************/
/* Batch dispatch execution latency using HIP events: */
/* Measures latency to start & finish executing each dispatch in a batch */
/*********************************************************************************/
for (auto i = 0; i < TOTAL_RUN_COUNT; ++i) {
checkHipErrors(hipEventRecord(start, 0));
for (int j = 0; j < BATCH_SIZE; j++) {
hipLaunchKernelGGL((EmptyKernel), dim3(NUM_GROUPS), dim3(GROUP_SIZE), 0, stream0);
}
checkHipErrors(hipEventRecord(stop, 0));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&results[i], start, stop));
}
print_timing("Batch dispatch latency", results, BATCH_SIZE);
checkHipErrors(hipEventDestroy(start));
checkHipErrors(hipEventDestroy(stop));
checkHipErrors(hipCtxDestroy(context));
checkHipErrors(hipEventDestroy(start));
checkHipErrors(hipEventDestroy(stop));
checkHipErrors(hipCtxDestroy(context));
}
@@ -19,6 +19,4 @@ THE SOFTWARE.
#include "hip/hip_runtime.h"
extern "C" __global__ void test() {
}
extern "C" __global__ void test() {}
@@ -36,7 +36,7 @@ THE SOFTWARE.
void printCompilerInfo() {
#ifdef __NVCC__
printf("compiler: nvcc\n");
printf("compiler: nvcc\n");
#endif
}
@@ -44,157 +44,157 @@ double bytesToKB(size_t s) { return (double)s / (1024.0); }
double bytesToGB(size_t s) { return (double)s / (1024.0 * 1024.0 * 1024.0); }
#define printLimit(w1, limit, units) \
{ \
size_t val; \
cudaDeviceGetLimit(&val, limit); \
std::cout << setw(w1) << #limit ": " << val << " " << units << std::endl; \
}
{ \
size_t val; \
cudaDeviceGetLimit(&val, limit); \
std::cout << setw(w1) << #limit ": " << val << " " << units << std::endl; \
}
void printDeviceProp(int deviceId) {
using namespace std;
const int w1 = 34;
using namespace std;
const int w1 = 34;
cout << left;
cout << left;
cout << setw(w1)
<< "--------------------------------------------------------------------------------"
<< endl;
cout << setw(w1) << "device#" << deviceId << endl;
cout << setw(w1)
<< "--------------------------------------------------------------------------------"
<< endl;
cout << setw(w1) << "device#" << deviceId << endl;
hipDeviceProp_t props = {0};
checkHipErrors(hipGetDeviceProperties(&props, deviceId));
hipDeviceProp_t props = {0};
checkHipErrors(hipGetDeviceProperties(&props, deviceId));
cout << setw(w1) << "Name: " << props.name << endl;
cout << setw(w1) << "pciBusID: " << props.pciBusID << endl;
cout << setw(w1) << "pciDeviceID: " << props.pciDeviceID << endl;
cout << setw(w1) << "pciDomainID: " << props.pciDomainID << endl;
cout << setw(w1) << "multiProcessorCount: " << props.multiProcessorCount << endl;
cout << setw(w1) << "maxThreadsPerMultiProcessor: " << props.maxThreadsPerMultiProcessor
<< endl;
cout << setw(w1) << "isMultiGpuBoard: " << props.isMultiGpuBoard << endl;
cout << setw(w1) << "clockRate: " << (float)props.clockRate / 1000.0 << " Mhz" << endl;
cout << setw(w1) << "memoryClockRate: " << (float)props.memoryClockRate / 1000.0 << " Mhz"
<< endl;
cout << setw(w1) << "memoryBusWidth: " << props.memoryBusWidth << endl;
cout << setw(w1) << "totalGlobalMem: " << fixed << setprecision(2)
<< bytesToGB(props.totalGlobalMem) << " GB" << endl;
cout << setw(w1) << "totalConstMem: " << props.totalConstMem << endl;
cout << setw(w1) << "sharedMemPerBlock: " << (float)props.sharedMemPerBlock / 1024.0 << " KB"
<< endl;
cout << setw(w1) << "canMapHostMemory: " << props.canMapHostMemory << endl;
cout << setw(w1) << "regsPerBlock: " << props.regsPerBlock << endl;
cout << setw(w1) << "warpSize: " << props.warpSize << endl;
cout << setw(w1) << "l2CacheSize: " << props.l2CacheSize << endl;
cout << setw(w1) << "computeMode: " << props.computeMode << endl;
cout << setw(w1) << "maxThreadsPerBlock: " << props.maxThreadsPerBlock << endl;
cout << setw(w1) << "maxThreadsDim.x: " << props.maxThreadsDim[0] << endl;
cout << setw(w1) << "maxThreadsDim.y: " << props.maxThreadsDim[1] << endl;
cout << setw(w1) << "maxThreadsDim.z: " << props.maxThreadsDim[2] << endl;
cout << setw(w1) << "maxGridSize.x: " << props.maxGridSize[0] << endl;
cout << setw(w1) << "maxGridSize.y: " << props.maxGridSize[1] << endl;
cout << setw(w1) << "maxGridSize.z: " << props.maxGridSize[2] << endl;
cout << setw(w1) << "major: " << props.major << endl;
cout << setw(w1) << "minor: " << props.minor << endl;
cout << setw(w1) << "concurrentKernels: " << props.concurrentKernels << endl;
cout << setw(w1) << "cooperativeLaunch: " << props.cooperativeLaunch << endl;
cout << setw(w1) << "cooperativeMultiDeviceLaunch: " << props.cooperativeMultiDeviceLaunch << endl;
cout << setw(w1) << "isIntegrated: " << props.integrated << endl;
cout << setw(w1) << "maxTexture1D: " << props.maxTexture1D << endl;
cout << setw(w1) << "maxTexture2D.width: " << props.maxTexture2D[0] << endl;
cout << setw(w1) << "maxTexture2D.height: " << props.maxTexture2D[1] << endl;
cout << setw(w1) << "maxTexture3D.width: " << props.maxTexture3D[0] << endl;
cout << setw(w1) << "maxTexture3D.height: " << props.maxTexture3D[1] << endl;
cout << setw(w1) << "maxTexture3D.depth: " << props.maxTexture3D[2] << endl;
cout << setw(w1) << "hostNativeAtomicSupported: " << props.hostNativeAtomicSupported << endl;
cout << setw(w1) << "Name: " << props.name << endl;
cout << setw(w1) << "pciBusID: " << props.pciBusID << endl;
cout << setw(w1) << "pciDeviceID: " << props.pciDeviceID << endl;
cout << setw(w1) << "pciDomainID: " << props.pciDomainID << endl;
cout << setw(w1) << "multiProcessorCount: " << props.multiProcessorCount << endl;
cout << setw(w1) << "maxThreadsPerMultiProcessor: " << props.maxThreadsPerMultiProcessor << endl;
cout << setw(w1) << "isMultiGpuBoard: " << props.isMultiGpuBoard << endl;
cout << setw(w1) << "clockRate: " << (float)props.clockRate / 1000.0 << " Mhz" << endl;
cout << setw(w1) << "memoryClockRate: " << (float)props.memoryClockRate / 1000.0 << " Mhz"
<< endl;
cout << setw(w1) << "memoryBusWidth: " << props.memoryBusWidth << endl;
cout << setw(w1) << "totalGlobalMem: " << fixed << setprecision(2)
<< bytesToGB(props.totalGlobalMem) << " GB" << endl;
cout << setw(w1) << "totalConstMem: " << props.totalConstMem << endl;
cout << setw(w1) << "sharedMemPerBlock: " << (float)props.sharedMemPerBlock / 1024.0 << " KB"
<< endl;
cout << setw(w1) << "canMapHostMemory: " << props.canMapHostMemory << endl;
cout << setw(w1) << "regsPerBlock: " << props.regsPerBlock << endl;
cout << setw(w1) << "warpSize: " << props.warpSize << endl;
cout << setw(w1) << "l2CacheSize: " << props.l2CacheSize << endl;
cout << setw(w1) << "computeMode: " << props.computeMode << endl;
cout << setw(w1) << "maxThreadsPerBlock: " << props.maxThreadsPerBlock << endl;
cout << setw(w1) << "maxThreadsDim.x: " << props.maxThreadsDim[0] << endl;
cout << setw(w1) << "maxThreadsDim.y: " << props.maxThreadsDim[1] << endl;
cout << setw(w1) << "maxThreadsDim.z: " << props.maxThreadsDim[2] << endl;
cout << setw(w1) << "maxGridSize.x: " << props.maxGridSize[0] << endl;
cout << setw(w1) << "maxGridSize.y: " << props.maxGridSize[1] << endl;
cout << setw(w1) << "maxGridSize.z: " << props.maxGridSize[2] << endl;
cout << setw(w1) << "major: " << props.major << endl;
cout << setw(w1) << "minor: " << props.minor << endl;
cout << setw(w1) << "concurrentKernels: " << props.concurrentKernels << endl;
cout << setw(w1) << "cooperativeLaunch: " << props.cooperativeLaunch << endl;
cout << setw(w1) << "cooperativeMultiDeviceLaunch: " << props.cooperativeMultiDeviceLaunch
<< endl;
cout << setw(w1) << "isIntegrated: " << props.integrated << endl;
cout << setw(w1) << "maxTexture1D: " << props.maxTexture1D << endl;
cout << setw(w1) << "maxTexture2D.width: " << props.maxTexture2D[0] << endl;
cout << setw(w1) << "maxTexture2D.height: " << props.maxTexture2D[1] << endl;
cout << setw(w1) << "maxTexture3D.width: " << props.maxTexture3D[0] << endl;
cout << setw(w1) << "maxTexture3D.height: " << props.maxTexture3D[1] << endl;
cout << setw(w1) << "maxTexture3D.depth: " << props.maxTexture3D[2] << endl;
cout << setw(w1) << "hostNativeAtomicSupported: " << props.hostNativeAtomicSupported << endl;
#ifdef __HIP_PLATFORM_AMD__
cout << setw(w1) << "isLargeBar: " << props.isLargeBar << endl;
cout << setw(w1) << "asicRevision: " << props.asicRevision << endl;
cout << setw(w1) << "maxSharedMemoryPerMultiProcessor: " << fixed << setprecision(2)
<< bytesToKB(props.maxSharedMemoryPerMultiProcessor) << " KB" << endl;
cout << setw(w1) << "clockInstructionRate: " << (float)props.clockInstructionRate / 1000.0
<< " Mhz" << endl;
cout << setw(w1) << "arch.hasGlobalInt32Atomics: " << props.arch.hasGlobalInt32Atomics << endl;
cout << setw(w1) << "arch.hasGlobalFloatAtomicExch: " << props.arch.hasGlobalFloatAtomicExch
<< endl;
cout << setw(w1) << "arch.hasSharedInt32Atomics: " << props.arch.hasSharedInt32Atomics << endl;
cout << setw(w1) << "arch.hasSharedFloatAtomicExch: " << props.arch.hasSharedFloatAtomicExch
<< endl;
cout << setw(w1) << "arch.hasFloatAtomicAdd: " << props.arch.hasFloatAtomicAdd << endl;
cout << setw(w1) << "arch.hasGlobalInt64Atomics: " << props.arch.hasGlobalInt64Atomics << endl;
cout << setw(w1) << "arch.hasSharedInt64Atomics: " << props.arch.hasSharedInt64Atomics << endl;
cout << setw(w1) << "arch.hasDoubles: " << props.arch.hasDoubles << endl;
cout << setw(w1) << "arch.hasWarpVote: " << props.arch.hasWarpVote << endl;
cout << setw(w1) << "arch.hasWarpBallot: " << props.arch.hasWarpBallot << endl;
cout << setw(w1) << "arch.hasWarpShuffle: " << props.arch.hasWarpShuffle << endl;
cout << setw(w1) << "arch.hasFunnelShift: " << props.arch.hasFunnelShift << endl;
cout << setw(w1) << "arch.hasThreadFenceSystem: " << props.arch.hasThreadFenceSystem << endl;
cout << setw(w1) << "arch.hasSyncThreadsExt: " << props.arch.hasSyncThreadsExt << endl;
cout << setw(w1) << "arch.hasSurfaceFuncs: " << props.arch.hasSurfaceFuncs << endl;
cout << setw(w1) << "arch.has3dGrid: " << props.arch.has3dGrid << endl;
cout << setw(w1) << "arch.hasDynamicParallelism: " << props.arch.hasDynamicParallelism << endl;
cout << setw(w1) << "gcnArchName: " << props.gcnArchName << endl;
cout << setw(w1) << "isLargeBar: " << props.isLargeBar << endl;
cout << setw(w1) << "asicRevision: " << props.asicRevision << endl;
cout << setw(w1) << "maxSharedMemoryPerMultiProcessor: " << fixed << setprecision(2)
<< bytesToKB(props.maxSharedMemoryPerMultiProcessor) << " KB" << endl;
cout << setw(w1) << "clockInstructionRate: " << (float)props.clockInstructionRate / 1000.0
<< " Mhz" << endl;
cout << setw(w1) << "arch.hasGlobalInt32Atomics: " << props.arch.hasGlobalInt32Atomics << endl;
cout << setw(w1) << "arch.hasGlobalFloatAtomicExch: " << props.arch.hasGlobalFloatAtomicExch
<< endl;
cout << setw(w1) << "arch.hasSharedInt32Atomics: " << props.arch.hasSharedInt32Atomics << endl;
cout << setw(w1) << "arch.hasSharedFloatAtomicExch: " << props.arch.hasSharedFloatAtomicExch
<< endl;
cout << setw(w1) << "arch.hasFloatAtomicAdd: " << props.arch.hasFloatAtomicAdd << endl;
cout << setw(w1) << "arch.hasGlobalInt64Atomics: " << props.arch.hasGlobalInt64Atomics << endl;
cout << setw(w1) << "arch.hasSharedInt64Atomics: " << props.arch.hasSharedInt64Atomics << endl;
cout << setw(w1) << "arch.hasDoubles: " << props.arch.hasDoubles << endl;
cout << setw(w1) << "arch.hasWarpVote: " << props.arch.hasWarpVote << endl;
cout << setw(w1) << "arch.hasWarpBallot: " << props.arch.hasWarpBallot << endl;
cout << setw(w1) << "arch.hasWarpShuffle: " << props.arch.hasWarpShuffle << endl;
cout << setw(w1) << "arch.hasFunnelShift: " << props.arch.hasFunnelShift << endl;
cout << setw(w1) << "arch.hasThreadFenceSystem: " << props.arch.hasThreadFenceSystem << endl;
cout << setw(w1) << "arch.hasSyncThreadsExt: " << props.arch.hasSyncThreadsExt << endl;
cout << setw(w1) << "arch.hasSurfaceFuncs: " << props.arch.hasSurfaceFuncs << endl;
cout << setw(w1) << "arch.has3dGrid: " << props.arch.has3dGrid << endl;
cout << setw(w1) << "arch.hasDynamicParallelism: " << props.arch.hasDynamicParallelism << endl;
cout << setw(w1) << "gcnArchName: " << props.gcnArchName << endl;
#endif
int deviceCnt;
checkHipErrors(hipGetDeviceCount(&deviceCnt));
cout << setw(w1) << "peers: ";
for (int i = 0; i < deviceCnt; i++) {
int isPeer;
checkHipErrors(hipDeviceCanAccessPeer(&isPeer, i, deviceId));
if (isPeer) {
cout << "device#" << i << " ";
}
int deviceCnt;
checkHipErrors(hipGetDeviceCount(&deviceCnt));
cout << setw(w1) << "peers: ";
for (int i = 0; i < deviceCnt; i++) {
int isPeer;
checkHipErrors(hipDeviceCanAccessPeer(&isPeer, i, deviceId));
if (isPeer) {
cout << "device#" << i << " ";
}
cout << endl;
cout << setw(w1) << "non-peers: ";
for (int i = 0; i < deviceCnt; i++) {
int isPeer;
checkHipErrors(hipDeviceCanAccessPeer(&isPeer, i, deviceId));
if (!isPeer) {
cout << "device#" << i << " ";
}
}
cout << endl;
cout << setw(w1) << "non-peers: ";
for (int i = 0; i < deviceCnt; i++) {
int isPeer;
checkHipErrors(hipDeviceCanAccessPeer(&isPeer, i, deviceId));
if (!isPeer) {
cout << "device#" << i << " ";
}
cout << endl;
}
cout << endl;
#ifdef __HIP_PLATFORM_NVIDIA__
// Limits:
cout << endl;
printLimit(w1, cudaLimitStackSize, "bytes/thread");
printLimit(w1, cudaLimitPrintfFifoSize, "bytes/device");
printLimit(w1, cudaLimitMallocHeapSize, "bytes/device");
printLimit(w1, cudaLimitDevRuntimeSyncDepth, "grids");
printLimit(w1, cudaLimitDevRuntimePendingLaunchCount, "launches");
// Limits:
cout << endl;
printLimit(w1, cudaLimitStackSize, "bytes/thread");
printLimit(w1, cudaLimitPrintfFifoSize, "bytes/device");
printLimit(w1, cudaLimitMallocHeapSize, "bytes/device");
printLimit(w1, cudaLimitDevRuntimeSyncDepth, "grids");
printLimit(w1, cudaLimitDevRuntimePendingLaunchCount, "launches");
#endif
cout << endl;
cout << endl;
size_t free, total;
checkHipErrors(hipMemGetInfo(&free, &total));
size_t free, total;
checkHipErrors(hipMemGetInfo(&free, &total));
cout << fixed << setprecision(2);
cout << setw(w1) << "memInfo.total: " << bytesToGB(total) << " GB" << endl;
cout << setw(w1) << "memInfo.free: " << bytesToGB(free) << " GB (" << setprecision(0)
<< (float)free / total * 100.0 << "%)" << endl;
cout << fixed << setprecision(2);
cout << setw(w1) << "memInfo.total: " << bytesToGB(total) << " GB" << endl;
cout << setw(w1) << "memInfo.free: " << bytesToGB(free) << " GB (" << setprecision(0)
<< (float)free / total * 100.0 << "%)" << endl;
}
int main(int argc, char* argv[]) {
using namespace std;
using namespace std;
cout << endl;
cout << endl;
printCompilerInfo();
printCompilerInfo();
int deviceCnt;
int deviceCnt;
checkHipErrors(hipGetDeviceCount(&deviceCnt));
checkHipErrors(hipGetDeviceCount(&deviceCnt));
for (int i = 0; i < deviceCnt; i++) {
checkHipErrors(hipSetDevice(i));
printDeviceProp(i);
}
for (int i = 0; i < deviceCnt; i++) {
checkHipErrors(hipSetDevice(i));
printDeviceProp(i);
}
std::cout << std::endl;
std::cout << std::endl;
}
@@ -38,86 +38,87 @@ THE SOFTWARE.
// Device (Kernel) function, it must be void
__global__ void matrixTranspose(float* out, float* in, const int width) {
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
out[y * width + x] = in[x * width + y];
out[y * width + x] = in[x * width + y];
}
// CPU implementation of matrix transpose
void matrixTransposeCPUReference(float* output, float* input, const unsigned int width) {
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
}
}
int main() {
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
std::cout << "Device name " << devProp.name << std::endl;
std::cout << "Device name " << devProp.name << std::endl;
int i;
int errors;
int i;
int errors;
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// Lauching kernel from host
hipLaunchKernelGGL(
matrixTranspose, dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, gpuTransposeMatrix, gpuMatrix, WIDTH);
// Memory transfer from device to host
checkHipErrors(
hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("PASSED!\n");
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
// Lauching kernel from host
hipLaunchKernelGGL(matrixTranspose, dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, gpuTransposeMatrix,
gpuMatrix, WIDTH);
// Memory transfer from device to host
checkHipErrors(hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("PASSED!\n");
}
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
return errors;
return errors;
}
@@ -36,128 +36,129 @@ THE SOFTWARE.
// Device (Kernel) function, it must be void
__global__ void matrixTranspose(float* out, float* in, const int width) {
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
asm volatile("v_mov_b32_e32 %0, %1" : "=v"(out[x * width + y]) : "v"(in[y * width + x]));
asm volatile("v_mov_b32_e32 %0, %1" : "=v"(out[x * width + y]) : "v"(in[y * width + x]));
}
// CPU implementation of matrix transpose
void matrixTransposeCPUReference(float* output, float* input, const unsigned int width) {
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
}
}
int main() {
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
std::cout << "Device name " << devProp.name << std::endl;
std::cout << "Device name " << devProp.name << std::endl;
hipEvent_t start, stop;
checkHipErrors(hipEventCreate(&start));
checkHipErrors(hipEventCreate(&stop));
float eventMs = 1.0f;
hipEvent_t start, stop;
checkHipErrors(hipEventCreate(&start));
checkHipErrors(hipEventCreate(&stop));
float eventMs = 1.0f;
int i;
int errors;
int i;
int errors;
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// Record the start event
checkHipErrors(hipEventRecord(start, NULL));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// Record the stop event
checkHipErrors(hipEventRecord(stop, NULL));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&eventMs, start, stop));
printf("hipMemcpyHostToDevice time taken = %6.3fms\n", eventMs);
// Record the start event
checkHipErrors(hipEventRecord(start, NULL));
// Lauching kernel from host
hipLaunchKernelGGL(
matrixTranspose, dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, gpuTransposeMatrix, gpuMatrix, WIDTH);
// Record the stop event
checkHipErrors(hipEventRecord(stop, NULL));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&eventMs, start, stop));
printf("kernel Execution time = %6.3fms\n", eventMs);
// Record the start event
checkHipErrors(hipEventRecord(start, NULL));
// Memory transfer from device to host
checkHipErrors(
hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// Record the stop event
checkHipErrors(hipEventRecord(stop, NULL));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&eventMs, start, stop));
checkHipErrors(hipEventDestroy(start));
checkHipErrors(hipEventDestroy(stop));
printf("hipMemcpyDeviceToHost time taken = %6.3fms\n", eventMs);
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
printf("gpu%f cpu %f \n", TransposeMatrix[i], cpuTransposeMatrix[i]);
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("PASSED!\n");
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// Record the start event
checkHipErrors(hipEventRecord(start, NULL));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// Record the stop event
checkHipErrors(hipEventRecord(stop, NULL));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&eventMs, start, stop));
printf("hipMemcpyHostToDevice time taken = %6.3fms\n", eventMs);
// Record the start event
checkHipErrors(hipEventRecord(start, NULL));
// Lauching kernel from host
hipLaunchKernelGGL(matrixTranspose, dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, gpuTransposeMatrix,
gpuMatrix, WIDTH);
// Record the stop event
checkHipErrors(hipEventRecord(stop, NULL));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&eventMs, start, stop));
printf("kernel Execution time = %6.3fms\n", eventMs);
// Record the start event
checkHipErrors(hipEventRecord(start, NULL));
// Memory transfer from device to host
checkHipErrors(hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// Record the stop event
checkHipErrors(hipEventRecord(stop, NULL));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&eventMs, start, stop));
checkHipErrors(hipEventDestroy(start));
checkHipErrors(hipEventDestroy(stop));
printf("hipMemcpyDeviceToHost time taken = %6.3fms\n", eventMs);
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
printf("gpu%f cpu %f \n", TransposeMatrix[i], cpuTransposeMatrix[i]);
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("PASSED!\n");
}
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
return errors;
return errors;
}
@@ -21,66 +21,74 @@ THE SOFTWARE.
*/
#include "hip/hip_runtime.h"
extern "C" __global__ void tex2dKernelChar(char* outputData,hipTextureObject_t texObj, int width, int height) {
extern "C" __global__ void tex2dKernelChar(char* outputData, hipTextureObject_t texObj, int width,
int height) {
#if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outputData[y * width + x] = tex2D<char>(texObj, x, y);
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outputData[y * width + x] = tex2D<char>(texObj, x, y);
#endif
}
extern "C" __global__ void tex2dKernelShort(short* outputData,hipTextureObject_t texObj, int width, int height) {
extern "C" __global__ void tex2dKernelShort(short* outputData, hipTextureObject_t texObj, int width,
int height) {
#if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outputData[y * width + x] = tex2D<short>(texObj, x, y);
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outputData[y * width + x] = tex2D<short>(texObj, x, y);
#endif
}
extern "C" __global__ void tex2dKernelInt(int* outputData,hipTextureObject_t texObj ,int width, int height) {
extern "C" __global__ void tex2dKernelInt(int* outputData, hipTextureObject_t texObj, int width,
int height) {
#if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outputData[y * width + x] = tex2D<int>(texObj, x, y);
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outputData[y * width + x] = tex2D<int>(texObj, x, y);
#endif
}
extern "C" __global__ void tex2dKernelFloat(float* outputData,hipTextureObject_t texObj, int width, int height) {
extern "C" __global__ void tex2dKernelFloat(float* outputData, hipTextureObject_t texObj, int width,
int height) {
#if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outputData[y * width + x] = tex2D<float>(texObj, x, y);
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outputData[y * width + x] = tex2D<float>(texObj, x, y);
#endif
}
extern "C" __global__ void tex2dKernelChar4(char4* outputData,hipTextureObject_t texObj, int width, int height) {
extern "C" __global__ void tex2dKernelChar4(char4* outputData, hipTextureObject_t texObj, int width,
int height) {
#if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outputData[y * width + x] = tex2D<char4>(texObj, x, y);
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outputData[y * width + x] = tex2D<char4>(texObj, x, y);
#endif
}
extern "C" __global__ void tex2dKernelShort4(short4* outputData,hipTextureObject_t texObj, int width, int height) {
extern "C" __global__ void tex2dKernelShort4(short4* outputData, hipTextureObject_t texObj,
int width, int height) {
#if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outputData[y * width + x] = tex2D<short4>(texObj, x, y);
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outputData[y * width + x] = tex2D<short4>(texObj, x, y);
#endif
}
extern "C" __global__ void tex2dKernelInt4(int4* outputData,hipTextureObject_t texObj, int width, int height) {
extern "C" __global__ void tex2dKernelInt4(int4* outputData, hipTextureObject_t texObj, int width,
int height) {
#if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outputData[y * width + x] = tex2D<int4>(texObj, x, y);
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outputData[y * width + x] = tex2D<int4>(texObj, x, y);
#endif
}
extern "C" __global__ void tex2dKernelFloat4(float4* outputData,hipTextureObject_t texObj, int width, int height) {
extern "C" __global__ void tex2dKernelFloat4(float4* outputData, hipTextureObject_t texObj,
int width, int height) {
#if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outputData[y * width + x] = tex2D<float4>(texObj, x, y);
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
outputData[y * width + x] = tex2D<float4>(texObj, x, y);
#endif
}
@@ -30,8 +30,7 @@ THE SOFTWARE.
bool testResult = true;
template<typename T,
typename std::enable_if<std::is_arithmetic<T>::value>::type *t = nullptr>
template <typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type* t = nullptr>
static inline hipArray_Format getArrayFormat() {
if (std::is_same<char, T>::value) {
return HIP_AD_FORMAT_SIGNED_INT8;
@@ -45,97 +44,81 @@ static inline hipArray_Format getArrayFormat() {
return HIP_AD_FORMAT_HALF;
}
template<typename T,
typename std::enable_if<!std::is_arithmetic<T>::value>::type *t = nullptr>
template <typename T, typename std::enable_if<!std::is_arithmetic<T>::value>::type* t = nullptr>
static inline hipArray_Format getArrayFormat() {
return getArrayFormat<decltype(T::x)>();
}
template<typename T>
static inline constexpr int rank() {
template <typename T> static inline constexpr int rank() {
return sizeof(T) / sizeof(decltype(T::x));
}
#ifdef __HIP_PLATFORM_NVIDIA__
template <typename T,
typename std::enable_if<std::is_same<T, int4>::value ||
std::is_same<T, short4>::value ||
std::is_same<T, char4>::value ||
std::is_same<T, float4>::value>::type *t = nullptr>
static inline bool operator!=(const T& a, const T& b)
{
return (a.x != b.x) || (a.y != b.y) || (a.z != b.z) || (a.w != b.w);
typename std::enable_if<std::is_same<T, int4>::value || std::is_same<T, short4>::value ||
std::is_same<T, char4>::value ||
std::is_same<T, float4>::value>::type* t = nullptr>
static inline bool operator!=(const T& a, const T& b) {
return (a.x != b.x) || (a.y != b.y) || (a.z != b.z) || (a.w != b.w);
}
#endif
template<typename T>
static inline T getRandom() {
template <typename T> static inline T getRandom() {
double r = 0;
if (std::is_signed < T > ::value) {
if (std::is_signed<T>::value) {
r = (std::rand() - RAND_MAX / 2.0) / (RAND_MAX / 2.0 + 1.);
} else {
r = std::rand() / (RAND_MAX + 1.);
}
return static_cast<T>(std::numeric_limits < T > ::max() * r);
return static_cast<T>(std::numeric_limits<T>::max() * r);
}
template<typename T,
typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
template <typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
static inline constexpr int getChannels() {
return 1;
}
template<typename T,
typename std::enable_if<!std::is_arithmetic<T>::value>::type *t = nullptr,
typename std::enable_if<rank<T>() != 0>::type *r = nullptr>
template <typename T, typename std::enable_if<!std::is_arithmetic<T>::value>::type* t = nullptr,
typename std::enable_if<rank<T>() != 0>::type* r = nullptr>
static inline constexpr int getChannels() {
return rank<T>();
}
template<typename T,
typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
static inline void printDiff(const int &i, const int &j, const T &expected,
const T &output) {
std::cout << "Difference [" << i << " " << j << "]: " << expected << " - "
<< output << "\n";
template <typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
static inline void printDiff(const int& i, const int& j, const T& expected, const T& output) {
std::cout << "Difference [" << i << " " << j << "]: " << expected << " - " << output << "\n";
}
template<typename T,
typename std::enable_if<!std::is_arithmetic<T>::value>::type* = nullptr,
typename std::enable_if<rank<T>() == 4>::type* = nullptr>
static inline void printDiff(const int &i, const int &j, const T &expected,
const T &output) {
std::cout << "Difference [" << i << " " << j << "]: " << expected.x << ","
<< expected.y << "," << expected.z << "," << expected.w << " - "
<< output.x << "," << output.y << "," << output.z << "," << output.w
<< "\n";
template <typename T, typename std::enable_if<!std::is_arithmetic<T>::value>::type* = nullptr,
typename std::enable_if<rank<T>() == 4>::type* = nullptr>
static inline void printDiff(const int& i, const int& j, const T& expected, const T& output) {
std::cout << "Difference [" << i << " " << j << "]: " << expected.x << "," << expected.y << ","
<< expected.z << "," << expected.w << " - " << output.x << "," << output.y << ","
<< output.z << "," << output.w << "\n";
}
template<typename T,
typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
static inline void initVal(T &val) {
template <typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
static inline void initVal(T& val) {
val = getRandom<T>();
}
template<typename T,
typename std::enable_if<!std::is_arithmetic<T>::value>::type* = nullptr,
typename std::enable_if<rank<T>() == 4>::type* = nullptr>
static inline void initVal(T &val) {
template <typename T, typename std::enable_if<!std::is_arithmetic<T>::value>::type* = nullptr,
typename std::enable_if<rank<T>() == 4>::type* = nullptr>
static inline void initVal(T& val) {
val.x = getRandom<decltype(T::x)>();
val.y = getRandom<decltype(T::x)>();
val.z = getRandom<decltype(T::x)>();
val.w = getRandom<decltype(T::x)>();
}
template<typename T>
bool runTest(hipModule_t &module, const char *refName, const char *funcName) {
template <typename T> bool runTest(hipModule_t& module, const char* refName, const char* funcName) {
hipArray_Format format = getArrayFormat<T>();
int channels = getChannels<T>();
unsigned int width = 256;
unsigned int height = 256;
unsigned int size = width * height * sizeof(T);
T *hData = (T*) malloc(size);
T* hData = (T*)malloc(size);
memset(hData, 0, size);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -149,8 +132,8 @@ bool runTest(hipModule_t &module, const char *refName, const char *funcName) {
const size_t spitch = width * sizeof(T);
checkHipErrors(hipMemcpy2DToArray(array, 0, 0, hData, spitch, width * sizeof(T),
height, hipMemcpyHostToDevice));
checkHipErrors(hipMemcpy2DToArray(array, 0, 0, hData, spitch, width * sizeof(T), height,
hipMemcpyHostToDevice));
hipResourceDesc resDesc;
memset(&resDesc, 0, sizeof(resDesc));
@@ -168,24 +151,24 @@ bool runTest(hipModule_t &module, const char *refName, const char *funcName) {
hipTextureObject_t texObj;
checkHipErrors(hipCreateTextureObject(&texObj, &resDesc, &texDesc, nullptr));
T *dData = NULL;
checkHipErrors(hipMalloc((void** )&dData, size));
T* dData = NULL;
checkHipErrors(hipMalloc((void**)&dData, size));
struct {
void *_Ad;
void* _Ad;
hipTextureObject_t _texObj;
unsigned int _Bd;
unsigned int _Cd;
} args;
args._Ad = (void*) dData;
args._Ad = (void*)dData;
args._texObj = texObj;
args._Bd = width;
args._Cd = height;
size_t sizeTemp = sizeof(args);
void *config[] = { HIP_LAUNCH_PARAM_BUFFER_POINTER, &args,
HIP_LAUNCH_PARAM_BUFFER_SIZE, &sizeTemp, HIP_LAUNCH_PARAM_END };
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, HIP_LAUNCH_PARAM_BUFFER_SIZE, &sizeTemp,
HIP_LAUNCH_PARAM_END};
hipFunction_t Function;
checkHipErrors(hipModuleGetFunction(&Function, module, funcName));
@@ -193,11 +176,10 @@ bool runTest(hipModule_t &module, const char *refName, const char *funcName) {
int temp1 = width / 16;
int temp2 = height / 16;
checkHipErrors(
hipModuleLaunchKernel(Function, 16, 16, 1, temp1, temp2, 1, 0, 0, NULL,
(void** )&config));
hipModuleLaunchKernel(Function, 16, 16, 1, temp1, temp2, 1, 0, 0, NULL, (void**)&config));
checkHipErrors(hipDeviceSynchronize());
T *hOutputData = (T*) malloc(size);
T* hOutputData = (T*)malloc(size);
memset(hOutputData, 0, size);
checkHipErrors(hipMemcpy(hOutputData, dData, size, hipMemcpyDeviceToHost));
@@ -220,10 +202,9 @@ bool runTest(hipModule_t &module, const char *refName, const char *funcName) {
}
inline bool isImageSupported() {
int imageSupport = 1;
int imageSupport = 1;
#ifdef __HIP_PLATFORM_AMD__
checkHipErrors(hipDeviceGetAttribute(&imageSupport, hipDeviceAttributeImageSupport,
0));
checkHipErrors(hipDeviceGetAttribute(&imageSupport, hipDeviceAttributeImageSupport, 0));
#endif
return imageSupport != 0;
}
@@ -38,86 +38,87 @@ THE SOFTWARE.
// Device (Kernel) function, it must be void
__global__ void matrixTranspose(float* out, float* in, const int width) {
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
out[y * width + x] = in[x * width + y];
out[y * width + x] = in[x * width + y];
}
// CPU implementation of matrix transpose
void matrixTransposeCPUReference(float* output, float* input, const unsigned int width) {
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
}
}
int main() {
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
std::cout << "Device name " << devProp.name << std::endl;
std::cout << "Device name " << devProp.name << std::endl;
int i;
int errors;
int i;
int errors;
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// Lauching kernel from host
hipLaunchKernelGGL(
matrixTranspose, dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, gpuTransposeMatrix, gpuMatrix, WIDTH);
// Memory transfer from device to host
checkHipErrors(
hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("PASSED!\n");
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
// Lauching kernel from host
hipLaunchKernelGGL(matrixTranspose, dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, gpuTransposeMatrix,
gpuMatrix, WIDTH);
// Memory transfer from device to host
checkHipErrors(hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("PASSED!\n");
}
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
return errors;
return errors;
}
@@ -23,153 +23,153 @@ THE SOFTWARE.
#define NUM 1000000
// Device (Kernel) function
__global__ void multiply(float* C, float* A, float* B, int N){
__global__ void multiply(float* C, float* A, float* B, int N) {
int tx = blockDim.x * blockIdx.x + threadIdx.x;
int tx = blockDim.x*blockIdx.x+threadIdx.x;
if (tx < N){
C[tx] = A[tx] * B[tx];
}
if (tx < N) {
C[tx] = A[tx] * B[tx];
}
}
// CPU implementation
void multiplyCPU(float* C, float* A, float* B, int N){
for(unsigned int i=0; i<N; i++){
C[i] = A[i] * B[i];
}
void multiplyCPU(float* C, float* A, float* B, int N) {
for (unsigned int i = 0; i < N; i++) {
C[i] = A[i] * B[i];
}
}
void launchKernel(float* C, float* A, float* B, bool manual){
void launchKernel(float* C, float* A, float* B, bool manual) {
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
hipEvent_t start, stop;
checkHipErrors(hipEventCreate(&start));
checkHipErrors(hipEventCreate(&stop));
float eventMs = 1.0f;
const unsigned threadsperblock = 32;
const unsigned blocks = (NUM / threadsperblock) + 1;
hipEvent_t start, stop;
checkHipErrors(hipEventCreate(&start));
checkHipErrors(hipEventCreate(&stop));
float eventMs = 1.0f;
const unsigned threadsperblock = 32;
const unsigned blocks = (NUM/threadsperblock)+1;
int mingridSize = 0;
int gridSize = 0;
int blockSize = 0;
int mingridSize = 0;
int gridSize = 0;
int blockSize = 0;
if (manual) {
blockSize = threadsperblock;
gridSize = blocks;
std::cout << std::endl << "Manual Configuration with block size " << blockSize << std::endl;
} else {
checkHipErrors(hipOccupancyMaxPotentialBlockSize(&mingridSize, &blockSize, multiply, 0, 0));
std::cout << std::endl
<< "Automatic Configuation based on hipOccupancyMaxPotentialBlockSize " << std::endl;
std::cout << "Suggested blocksize is " << blockSize << ", Minimum gridsize is " << mingridSize
<< std::endl;
gridSize = (NUM / blockSize) + 1;
}
if (manual){
blockSize = threadsperblock;
gridSize = blocks;
std::cout << std::endl << "Manual Configuration with block size " << blockSize << std::endl;
}
else{
checkHipErrors(hipOccupancyMaxPotentialBlockSize(&mingridSize, &blockSize, multiply, 0, 0));
std::cout << std::endl << "Automatic Configuation based on hipOccupancyMaxPotentialBlockSize " << std::endl;
std::cout << "Suggested blocksize is " << blockSize << ", Minimum gridsize is " << mingridSize << std::endl;
gridSize = (NUM/blockSize)+1;
}
// Record the start event
checkHipErrors(hipEventRecord(start, NULL));
// Record the start event
checkHipErrors(hipEventRecord(start, NULL));
// Launching the Kernel from Host
hipLaunchKernelGGL(multiply, dim3(gridSize), dim3(blockSize), 0, 0, C, A, B, NUM);
// Launching the Kernel from Host
hipLaunchKernelGGL(multiply, dim3(gridSize), dim3(blockSize), 0, 0, C, A, B, NUM);
// Record the stop event
checkHipErrors(hipEventRecord(stop, NULL));
checkHipErrors(hipEventSynchronize(stop));
// Record the stop event
checkHipErrors(hipEventRecord(stop, NULL));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&eventMs, start, stop));
printf("kernel Execution time = %6.3fms\n", eventMs);
checkHipErrors(hipEventElapsedTime(&eventMs, start, stop));
printf("kernel Execution time = %6.3fms\n", eventMs);
checkHipErrors(hipEventDestroy(start));
checkHipErrors(hipEventDestroy(stop));
checkHipErrors(hipEventDestroy(start));
checkHipErrors(hipEventDestroy(stop));
// Calculate Occupancy
int numBlock = 0;
checkHipErrors(hipOccupancyMaxActiveBlocksPerMultiprocessor(&numBlock, multiply, blockSize, 0));
//Calculate Occupancy
int numBlock = 0;
checkHipErrors(hipOccupancyMaxActiveBlocksPerMultiprocessor(&numBlock, multiply, blockSize, 0));
if(devProp.maxThreadsPerMultiProcessor){
std::cout << "Theoretical Occupancy is " << (double)numBlock* blockSize/devProp.maxThreadsPerMultiProcessor * 100 << "%" << std::endl;
}
if (devProp.maxThreadsPerMultiProcessor) {
std::cout << "Theoretical Occupancy is "
<< (double)numBlock * blockSize / devProp.maxThreadsPerMultiProcessor * 100 << "%"
<< std::endl;
}
}
int main() {
float *A, *B, *C0, *C1, *cpuC;
float *Ad, *Bd, *C0d, *C1d;
int errors=0;
int i;
float *A, *B, *C0, *C1, *cpuC;
float *Ad, *Bd, *C0d, *C1d;
int errors = 0;
int i;
// initialize the input data
A = (float *)malloc(NUM * sizeof(float));
B = (float *)malloc(NUM * sizeof(float));
C0 = (float *)malloc(NUM * sizeof(float));
C1 = (float *)malloc(NUM * sizeof(float));
cpuC = (float *)malloc(NUM * sizeof(float));
// initialize the input data
A = (float*)malloc(NUM * sizeof(float));
B = (float*)malloc(NUM * sizeof(float));
C0 = (float*)malloc(NUM * sizeof(float));
C1 = (float*)malloc(NUM * sizeof(float));
cpuC = (float*)malloc(NUM * sizeof(float));
for(i=0; i< NUM; i++){
A[i] = i;
B[i] = i;
}
for (i = 0; i < NUM; i++) {
A[i] = i;
B[i] = i;
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&Ad, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&Bd, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&C0d, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&C1d, NUM * sizeof(float)));
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&Ad, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&Bd, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&C0d, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&C1d, NUM * sizeof(float)));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(Ad,A,NUM * sizeof(float), hipMemcpyHostToDevice));
checkHipErrors(hipMemcpy(Bd,B,NUM * sizeof(float), hipMemcpyHostToDevice));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(Ad, A, NUM * sizeof(float), hipMemcpyHostToDevice));
checkHipErrors(hipMemcpy(Bd, B, NUM * sizeof(float), hipMemcpyHostToDevice));
//Kernel launch with manual/default block size
launchKernel(C0d, Ad, Bd, 1);
// Kernel launch with manual/default block size
launchKernel(C0d, Ad, Bd, 1);
//Kernel launch with the block size suggested by hipOccupancyMaxPotentialBlockSize
launchKernel(C1d, Ad, Bd, 0);
// Kernel launch with the block size suggested by hipOccupancyMaxPotentialBlockSize
launchKernel(C1d, Ad, Bd, 0);
// Memory transfer from device to host
checkHipErrors(hipMemcpy(C0,C0d, NUM * sizeof(float), hipMemcpyDeviceToHost));
checkHipErrors(hipMemcpy(C1,C1d, NUM * sizeof(float), hipMemcpyDeviceToHost));
// Memory transfer from device to host
checkHipErrors(hipMemcpy(C0, C0d, NUM * sizeof(float), hipMemcpyDeviceToHost));
checkHipErrors(hipMemcpy(C1, C1d, NUM * sizeof(float), hipMemcpyDeviceToHost));
// CPU computation
multiplyCPU(cpuC, A, B, NUM);
// CPU computation
multiplyCPU(cpuC, A, B, NUM);
//verify the results
double eps = 1.0E-6;
// verify the results
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(C0[i] - cpuC[i]) > eps) {
errors++;
}
}
for (i = 0; i < NUM; i++) {
if (std::abs(C0[i] - cpuC[i]) > eps) {
errors++;
}
}
if (errors != 0){
printf("\nManual Test FAILED: %d errors\n", errors);
errors=0;
} else {
printf("\nManual Test PASSED!\n");
}
if (errors != 0) {
printf("\nManual Test FAILED: %d errors\n", errors);
errors = 0;
} else {
printf("\nManual Test PASSED!\n");
}
for (i = 0; i < NUM; i++) {
if (std::abs(C1[i] - cpuC[i]) > eps) {
errors++;
}
}
for (i = 0; i < NUM; i++) {
if (std::abs(C1[i] - cpuC[i]) > eps) {
errors++;
}
}
if (errors != 0){
printf("\n Automatic Test FAILED: %d errors\n", errors);
} else {
printf("\nAutomatic Test PASSED!\n");
}
if (errors != 0) {
printf("\n Automatic Test FAILED: %d errors\n", errors);
} else {
printf("\nAutomatic Test PASSED!\n");
}
checkHipErrors(hipFree(Ad));
checkHipErrors(hipFree(Bd));
checkHipErrors(hipFree(C0d));
checkHipErrors(hipFree(C1d));
checkHipErrors(hipFree(Ad));
checkHipErrors(hipFree(Bd));
checkHipErrors(hipFree(C0d));
checkHipErrors(hipFree(C1d));
free(A);
free(B);
free(C0);
free(C1);
free(cpuC);
return 0;
free(A);
free(B);
free(C0);
free(C1);
free(cpuC);
return 0;
}
@@ -21,10 +21,10 @@ THE SOFTWARE.
#include <iostream>
#include "hip_helper.h"
#define THREADS_PER_BLOCK 64
#define BLOCKS_PER_GRID 4
#define SIZE (BLOCKS_PER_GRID * THREADS_PER_BLOCK)
#define NOT_SUPPORTED -99 // dummy number indicates unsupported operation
#define THREADS_PER_BLOCK 64
#define BLOCKS_PER_GRID 4
#define SIZE (BLOCKS_PER_GRID * THREADS_PER_BLOCK)
#define NOT_SUPPORTED -99 // dummy number indicates unsupported operation
// Using __gfx*__ macro one can have GPU architecture specific code flow
// For example: If below kernel runs on gfx908 it will increment 'in' by 'value' and store into
@@ -22,7 +22,4 @@
#include <hip/hip_runtime.h>
__device__ int square_me(int A) {
return A*A;
}
__device__ int square_me(int A) { return A * A; }
@@ -38,40 +38,39 @@
extern __device__ int square_me(int);
__global__ void square_and_save(int* A, int* B) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
B[tid] = square_me(A[tid]);
int tid = threadIdx.x + blockIdx.x * blockDim.x;
B[tid] = square_me(A[tid]);
}
void run_test2() {
int *A_h, *B_h, *A_d, *B_d;
A_h = new int[LEN];
B_h = new int[LEN];
for (unsigned i = 0; i < LEN; i++) {
A_h[i] = i;
B_h[i] = 0;
}
size_t valbytes = LEN*sizeof(int);
int *A_h, *B_h, *A_d, *B_d;
A_h = new int[LEN];
B_h = new int[LEN];
for (unsigned i = 0; i < LEN; i++) {
A_h[i] = i;
B_h[i] = 0;
}
size_t valbytes = LEN * sizeof(int);
HIP_ASSERT(hipMalloc((void**)&A_d, valbytes));
HIP_ASSERT(hipMalloc((void**)&B_d, valbytes));
HIP_ASSERT(hipMalloc((void**)&A_d, valbytes));
HIP_ASSERT(hipMalloc((void**)&B_d, valbytes));
HIP_ASSERT(hipMemcpy(A_d, A_h, valbytes, hipMemcpyHostToDevice));
hipLaunchKernelGGL(square_and_save, dim3(LEN/64), dim3(64),
0, 0, A_d, B_d);
HIP_ASSERT(hipMemcpy(B_h, B_d, valbytes, hipMemcpyDeviceToHost));
HIP_ASSERT(hipMemcpy(A_d, A_h, valbytes, hipMemcpyHostToDevice));
hipLaunchKernelGGL(square_and_save, dim3(LEN / 64), dim3(64), 0, 0, A_d, B_d);
HIP_ASSERT(hipMemcpy(B_h, B_d, valbytes, hipMemcpyDeviceToHost));
for (unsigned i = 0; i < LEN; i++) {
assert(A_h[i]*A_h[i] == B_h[i]);
}
for (unsigned i = 0; i < LEN; i++) {
assert(A_h[i] * A_h[i] == B_h[i]);
}
HIP_ASSERT(hipFree(A_d));
HIP_ASSERT(hipFree(B_d));
delete [] A_h;
delete [] B_h;
std::cout << "Test Passed!\n";
HIP_ASSERT(hipFree(A_d));
HIP_ASSERT(hipFree(B_d));
delete[] A_h;
delete[] B_h;
std::cout << "Test Passed!\n";
}
int main(){
int main() {
// Run test that generates static lib with ar
run_test2();
}
@@ -22,7 +22,7 @@
extern void run_test1();
int main(){
int main() {
// Run test that generates static lib with -emit-static-lib
run_test1();
}
@@ -26,69 +26,64 @@ THE SOFTWARE.
*
* Square each element in the array A and write to array C.
*/
template <typename T>
__global__ void
vector_square(T *C_d, T *A_d, size_t N)
{
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
size_t stride = blockDim.x * gridDim.x ;
template <typename T> __global__ void vector_square(T* C_d, T* A_d, size_t N) {
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
size_t stride = blockDim.x * gridDim.x;
for (size_t i=offset; i<N; i+=stride) {
C_d[i] = A_d[i] * A_d[i];
}
for (size_t i = offset; i < N; i += stride) {
C_d[i] = A_d[i] * A_d[i];
}
}
int main(int argc, char *argv[])
{
float *A_d, *C_d;
float *A_h, *C_h;
size_t N = 1000000;
size_t Nbytes = N * sizeof(float);
int main(int argc, char* argv[]) {
float *A_d, *C_d;
float *A_h, *C_h;
size_t N = 1000000;
size_t Nbytes = N * sizeof(float);
hipDeviceProp_t props;
checkHipErrors(hipGetDeviceProperties(&props, 0/*deviceID*/));
printf ("info: running on device %s\n", props.name);
hipDeviceProp_t props;
checkHipErrors(hipGetDeviceProperties(&props, 0 /*deviceID*/));
printf("info: running on device %s\n", props.name);
printf ("info: allocate host mem (%6.2f MB)\n", 2*Nbytes/1024.0/1024.0);
A_h = (float*)malloc(Nbytes);
checkHipErrors(A_h == 0 ? hipErrorMemoryAllocation : hipSuccess );
C_h = (float*)malloc(Nbytes);
checkHipErrors(C_h == 0 ? hipErrorMemoryAllocation : hipSuccess );
// Fill with Phi + i
for (size_t i=0; i<N; i++)
{
A_h[i] = 1.618f + i;
printf("info: allocate host mem (%6.2f MB)\n", 2 * Nbytes / 1024.0 / 1024.0);
A_h = (float*)malloc(Nbytes);
checkHipErrors(A_h == 0 ? hipErrorMemoryAllocation : hipSuccess);
C_h = (float*)malloc(Nbytes);
checkHipErrors(C_h == 0 ? hipErrorMemoryAllocation : hipSuccess);
// Fill with Phi + i
for (size_t i = 0; i < N; i++) {
A_h[i] = 1.618f + i;
}
printf("info: allocate device mem (%6.2f MB)\n", 2 * Nbytes / 1024.0 / 1024.0);
checkHipErrors(hipMalloc(&A_d, Nbytes));
checkHipErrors(hipMalloc(&C_d, Nbytes));
printf("info: copy Host2Device\n");
checkHipErrors(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
const unsigned blocks = 512;
const unsigned threadsPerBlock = 256;
printf("info: launch 'vector_square' kernel\n");
vector_square<<<blocks, threadsPerBlock>>>(C_d, A_d, N);
printf("info: copy Device2Host\n");
checkHipErrors(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
printf("info: checkHipErrors result\n");
for (size_t i = 0; i < N; i++) {
if (C_h[i] != A_h[i] * A_h[i]) {
checkHipErrors(hipErrorUnknown);
}
}
printf ("info: allocate device mem (%6.2f MB)\n", 2*Nbytes/1024.0/1024.0);
checkHipErrors(hipMalloc(&A_d, Nbytes));
checkHipErrors(hipMalloc(&C_d, Nbytes));
checkHipErrors(hipFree(A_d));
checkHipErrors(hipFree(C_d));
free(A_h);
free(C_h);
printf ("info: copy Host2Device\n");
checkHipErrors ( hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
const unsigned blocks = 512;
const unsigned threadsPerBlock = 256;
printf ("info: launch 'vector_square' kernel\n");
vector_square <<<blocks, threadsPerBlock>>> (C_d, A_d, N);
printf ("info: copy Device2Host\n");
checkHipErrors ( hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
printf ("info: checkHipErrors result\n");
for (size_t i=0; i<N; i++) {
if (C_h[i] != A_h[i] * A_h[i]) {
checkHipErrors(hipErrorUnknown);
}
}
checkHipErrors(hipFree(A_d));
checkHipErrors(hipFree(C_d));
free(A_h);
free(C_h);
printf ("PASSED!\n");
printf("PASSED!\n");
}
@@ -26,67 +26,62 @@ THE SOFTWARE.
*
* Square each element in the array A and write to array C.
*/
template <typename T>
__global__ void
vector_square(T *C_d, T *A_d, size_t N)
{
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
size_t stride = blockDim.x * gridDim.x ;
template <typename T> __global__ void vector_square(T* C_d, T* A_d, size_t N) {
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
size_t stride = blockDim.x * gridDim.x;
for (size_t i=offset; i<N; i+=stride) {
C_d[i] = A_d[i] * A_d[i];
}
for (size_t i = offset; i < N; i += stride) {
C_d[i] = A_d[i] * A_d[i];
}
}
int main(int argc, char *argv[])
{
float *A_d, *C_d;
float *A_h, *C_h;
size_t N = 1000000;
size_t Nbytes = N * sizeof(float);
int main(int argc, char* argv[]) {
float *A_d, *C_d;
float *A_h, *C_h;
size_t N = 1000000;
size_t Nbytes = N * sizeof(float);
hipDeviceProp_t props;
checkHipErrors(hipGetDeviceProperties(&props, 0/*deviceID*/));
printf ("info: running on device %s\n", props.name);
hipDeviceProp_t props;
checkHipErrors(hipGetDeviceProperties(&props, 0 /*deviceID*/));
printf("info: running on device %s\n", props.name);
printf ("info: allocate host mem (%6.2f MB)\n", 2*Nbytes/1024.0/1024.0);
A_h = (float*)malloc(Nbytes);
checkHipErrors(A_h == 0 ? hipErrorMemoryAllocation : hipSuccess );
C_h = (float*)malloc(Nbytes);
checkHipErrors(C_h == 0 ? hipErrorMemoryAllocation : hipSuccess );
// Fill with Phi + i
for (size_t i=0; i<N; i++)
{
A_h[i] = 1.618f + i;
printf("info: allocate host mem (%6.2f MB)\n", 2 * Nbytes / 1024.0 / 1024.0);
A_h = (float*)malloc(Nbytes);
checkHipErrors(A_h == 0 ? hipErrorMemoryAllocation : hipSuccess);
C_h = (float*)malloc(Nbytes);
checkHipErrors(C_h == 0 ? hipErrorMemoryAllocation : hipSuccess);
// Fill with Phi + i
for (size_t i = 0; i < N; i++) {
A_h[i] = 1.618f + i;
}
printf("info: allocate device mem (%6.2f MB)\n", 2 * Nbytes / 1024.0 / 1024.0);
checkHipErrors(hipMalloc(&A_d, Nbytes));
checkHipErrors(hipMalloc(&C_d, Nbytes));
printf("info: copy Host2Device\n");
checkHipErrors(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
const unsigned blocks = 512;
const unsigned threadsPerBlock = 256;
printf("info: launch 'vector_square' kernel\n");
vector_square<<<blocks, threadsPerBlock>>>(C_d, A_d, N);
printf("info: copy Device2Host\n");
checkHipErrors(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
printf("info: checkHipErrors result\n");
for (size_t i = 0; i < N; i++) {
if (C_h[i] != A_h[i] * A_h[i]) {
checkHipErrors(hipErrorUnknown);
}
printf ("info: allocate device mem (%6.2f MB)\n", 2*Nbytes/1024.0/1024.0);
checkHipErrors(hipMalloc(&A_d, Nbytes));
checkHipErrors(hipMalloc(&C_d, Nbytes));
printf ("info: copy Host2Device\n");
checkHipErrors ( hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
const unsigned blocks = 512;
const unsigned threadsPerBlock = 256;
printf ("info: launch 'vector_square' kernel\n");
vector_square <<<blocks, threadsPerBlock>>> (C_d, A_d, N);
printf ("info: copy Device2Host\n");
checkHipErrors ( hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
printf ("info: checkHipErrors result\n");
for (size_t i=0; i<N; i++) {
if (C_h[i] != A_h[i] * A_h[i]) {
checkHipErrors(hipErrorUnknown);
}
}
checkHipErrors(hipFree(A_d));
checkHipErrors(hipFree(C_d));
free(A_h);
free(C_h);
printf ("PASSED!\n");
}
checkHipErrors(hipFree(A_d));
checkHipErrors(hipFree(C_d));
free(A_h);
free(C_h);
printf("PASSED!\n");
}
@@ -27,67 +27,62 @@ THE SOFTWARE.
/*
* Square each element in the array A and write to array C.
*/
template <typename T>
__global__ void
vector_square(T *C_d, T *A_d, size_t N)
{
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
size_t stride = blockDim.x * gridDim.x ;
template <typename T> __global__ void vector_square(T* C_d, T* A_d, size_t N) {
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
size_t stride = blockDim.x * gridDim.x;
for (size_t i=offset; i<N; i+=stride) {
C_d[i] = A_d[i] * A_d[i];
}
for (size_t i = offset; i < N; i += stride) {
C_d[i] = A_d[i] * A_d[i];
}
}
int main(int argc, char *argv[])
{
float *A_d, *C_d;
float *A_h, *C_h;
size_t N = 1000000;
size_t Nbytes = N * sizeof(float);
int main(int argc, char* argv[]) {
float *A_d, *C_d;
float *A_h, *C_h;
size_t N = 1000000;
size_t Nbytes = N * sizeof(float);
hipDeviceProp_t props;
checkHipErrors(hipGetDeviceProperties(&props, 0/*deviceID*/));
printf ("info: running on device %s\n", props.name);
hipDeviceProp_t props;
checkHipErrors(hipGetDeviceProperties(&props, 0 /*deviceID*/));
printf("info: running on device %s\n", props.name);
printf ("info: allocate host mem (%6.2f MB)\n", 2*Nbytes/1024.0/1024.0);
A_h = (float*)malloc(Nbytes);
checkHipErrors(A_h == 0 ? hipErrorOutOfMemory : hipSuccess );
C_h = (float*)malloc(Nbytes);
checkHipErrors(C_h == 0 ? hipErrorOutOfMemory : hipSuccess );
// Fill with Phi + i
for (size_t i=0; i<N; i++)
{
A_h[i] = 1.618f + i;
printf("info: allocate host mem (%6.2f MB)\n", 2 * Nbytes / 1024.0 / 1024.0);
A_h = (float*)malloc(Nbytes);
checkHipErrors(A_h == 0 ? hipErrorOutOfMemory : hipSuccess);
C_h = (float*)malloc(Nbytes);
checkHipErrors(C_h == 0 ? hipErrorOutOfMemory : hipSuccess);
// Fill with Phi + i
for (size_t i = 0; i < N; i++) {
A_h[i] = 1.618f + i;
}
printf("info: allocate device mem (%6.2f MB)\n", 2 * Nbytes / 1024.0 / 1024.0);
checkHipErrors(hipMalloc(&A_d, Nbytes));
checkHipErrors(hipMalloc(&C_d, Nbytes));
printf("info: copy Host2Device\n");
checkHipErrors(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
const unsigned blocks = 512;
const unsigned threadsPerBlock = 256;
printf("info: launch 'vector_square' kernel\n");
hipLaunchKernelGGL(vector_square, dim3(blocks), dim3(threadsPerBlock), 0, 0, C_d, A_d, N);
printf("info: copy Device2Host\n");
checkHipErrors(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
printf("info: checkHipErrors result\n");
for (size_t i = 0; i < N; i++) {
if (C_h[i] != A_h[i] * A_h[i]) {
checkHipErrors(hipErrorUnknown);
}
printf ("info: allocate device mem (%6.2f MB)\n", 2*Nbytes/1024.0/1024.0);
checkHipErrors(hipMalloc(&A_d, Nbytes));
checkHipErrors(hipMalloc(&C_d, Nbytes));
printf ("info: copy Host2Device\n");
checkHipErrors ( hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
const unsigned blocks = 512;
const unsigned threadsPerBlock = 256;
printf ("info: launch 'vector_square' kernel\n");
hipLaunchKernelGGL(vector_square, dim3(blocks), dim3(threadsPerBlock), 0, 0, C_d, A_d, N);
printf ("info: copy Device2Host\n");
checkHipErrors ( hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
printf ("info: checkHipErrors result\n");
for (size_t i=0; i<N; i++) {
if (C_h[i] != A_h[i] * A_h[i]) {
checkHipErrors(hipErrorUnknown);
}
}
checkHipErrors(hipFree(A_d));
checkHipErrors(hipFree(C_d));
free(A_h);
free(C_h);
printf ("PASSED!\n");
}
checkHipErrors(hipFree(A_d));
checkHipErrors(hipFree(C_d));
free(A_h);
free(C_h);
printf("PASSED!\n");
}
@@ -37,86 +37,87 @@ THE SOFTWARE.
// Device (Kernel) function, it must be void
__global__ void matrixTranspose(float* out, float* in, const int width) {
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
out[y * width + x] = in[x * width + y];
out[y * width + x] = in[x * width + y];
}
// CPU implementation of matrix transpose
void matrixTransposeCPUReference(float* output, float* input, const unsigned int width) {
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
}
}
int main() {
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
std::cout << "Device name " << devProp.name << std::endl;
std::cout << "Device name " << devProp.name << std::endl;
int i;
int errors;
int i;
int errors;
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// Lauching kernel from host
hipLaunchKernelGGL(
matrixTranspose, dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, gpuTransposeMatrix, gpuMatrix, WIDTH);
// Memory transfer from device to host
checkHipErrors(
hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("PASSED!\n");
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
// Lauching kernel from host
hipLaunchKernelGGL(matrixTranspose, dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, gpuTransposeMatrix,
gpuMatrix, WIDTH);
// Memory transfer from device to host
checkHipErrors(hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("PASSED!\n");
}
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
return errors;
return errors;
}
@@ -36,127 +36,128 @@ THE SOFTWARE.
// Device (Kernel) function, it must be void
__global__ void matrixTranspose(float* out, float* in, const int width) {
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
out[y * width + x] = in[x * width + y];
out[y * width + x] = in[x * width + y];
}
// CPU implementation of matrix transpose
void matrixTransposeCPUReference(float* output, float* input, const unsigned int width) {
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
}
}
int main() {
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
std::cout << "Device name " << devProp.name << std::endl;
std::cout << "Device name " << devProp.name << std::endl;
hipEvent_t start, stop;
checkHipErrors(hipEventCreate(&start));
checkHipErrors(hipEventCreate(&stop));
float eventMs = 1.0f;
hipEvent_t start, stop;
checkHipErrors(hipEventCreate(&start));
checkHipErrors(hipEventCreate(&stop));
float eventMs = 1.0f;
int i;
int errors;
int i;
int errors;
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// Record the start event
checkHipErrors(hipEventRecord(start, NULL));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// Record the stop event
checkHipErrors(hipEventRecord(stop, NULL));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&eventMs, start, stop));
printf("hipMemcpyHostToDevice time taken = %6.3fms\n", eventMs);
// Record the start event
checkHipErrors(hipEventRecord(start, NULL));
// Lauching kernel from host
hipLaunchKernelGGL(
matrixTranspose, dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, gpuTransposeMatrix, gpuMatrix, WIDTH);
// Record the stop event
checkHipErrors(hipEventRecord(stop, NULL));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&eventMs, start, stop));
printf("kernel Execution time = %6.3fms\n", eventMs);
// Record the start event
checkHipErrors(hipEventRecord(start, NULL));
// Memory transfer from device to host
checkHipErrors(
hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// Record the stop event
checkHipErrors(hipEventRecord(stop, NULL));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&eventMs, start, stop));
printf("hipMemcpyDeviceToHost time taken = %6.3fms\n", eventMs);
checkHipErrors(hipEventDestroy(start));
checkHipErrors(hipEventDestroy(stop));
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("PASSED!\n");
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// Record the start event
checkHipErrors(hipEventRecord(start, NULL));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// Record the stop event
checkHipErrors(hipEventRecord(stop, NULL));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&eventMs, start, stop));
printf("hipMemcpyHostToDevice time taken = %6.3fms\n", eventMs);
// Record the start event
checkHipErrors(hipEventRecord(start, NULL));
// Lauching kernel from host
hipLaunchKernelGGL(matrixTranspose, dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, gpuTransposeMatrix,
gpuMatrix, WIDTH);
// Record the stop event
checkHipErrors(hipEventRecord(stop, NULL));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&eventMs, start, stop));
printf("kernel Execution time = %6.3fms\n", eventMs);
// Record the start event
checkHipErrors(hipEventRecord(start, NULL));
// Memory transfer from device to host
checkHipErrors(hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// Record the stop event
checkHipErrors(hipEventRecord(stop, NULL));
checkHipErrors(hipEventSynchronize(stop));
checkHipErrors(hipEventElapsedTime(&eventMs, start, stop));
printf("hipMemcpyDeviceToHost time taken = %6.3fms\n", eventMs);
checkHipErrors(hipEventDestroy(start));
checkHipErrors(hipEventDestroy(stop));
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("PASSED!\n");
}
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
return errors;
return errors;
}
@@ -27,67 +27,62 @@ THE SOFTWARE.
/*
* Square each element in the array A and write to array C.
*/
template <typename T>
__global__ void
vector_square(T *C_d, T *A_d, size_t N)
{
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
size_t stride = blockDim.x * gridDim.x ;
template <typename T> __global__ void vector_square(T* C_d, T* A_d, size_t N) {
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
size_t stride = blockDim.x * gridDim.x;
for (size_t i=offset; i<N; i+=stride) {
C_d[i] = A_d[i] * A_d[i];
}
for (size_t i = offset; i < N; i += stride) {
C_d[i] = A_d[i] * A_d[i];
}
}
int main(int argc, char *argv[])
{
float *A_d, *C_d;
float *A_h, *C_h;
size_t N = 1000000;
size_t Nbytes = N * sizeof(float);
int main(int argc, char* argv[]) {
float *A_d, *C_d;
float *A_h, *C_h;
size_t N = 1000000;
size_t Nbytes = N * sizeof(float);
hipDeviceProp_t props;
checkHipErrors(hipGetDeviceProperties(&props, 0/*deviceID*/));
printf ("info: running on device %s\n", props.name);
hipDeviceProp_t props;
checkHipErrors(hipGetDeviceProperties(&props, 0 /*deviceID*/));
printf("info: running on device %s\n", props.name);
printf ("info: allocate host mem (%6.2f MB)\n", 2*Nbytes/1024.0/1024.0);
A_h = (float*)malloc(Nbytes);
checkHipErrors(A_h == 0 ? hipErrorOutOfMemory : hipSuccess );
C_h = (float*)malloc(Nbytes);
checkHipErrors(C_h == 0 ? hipErrorOutOfMemory : hipSuccess );
// Fill with Phi + i
for (size_t i=0; i<N; i++)
{
A_h[i] = 1.618f + i;
printf("info: allocate host mem (%6.2f MB)\n", 2 * Nbytes / 1024.0 / 1024.0);
A_h = (float*)malloc(Nbytes);
checkHipErrors(A_h == 0 ? hipErrorOutOfMemory : hipSuccess);
C_h = (float*)malloc(Nbytes);
checkHipErrors(C_h == 0 ? hipErrorOutOfMemory : hipSuccess);
// Fill with Phi + i
for (size_t i = 0; i < N; i++) {
A_h[i] = 1.618f + i;
}
printf("info: allocate device mem (%6.2f MB)\n", 2 * Nbytes / 1024.0 / 1024.0);
checkHipErrors(hipMalloc(&A_d, Nbytes));
checkHipErrors(hipMalloc(&C_d, Nbytes));
printf("info: copy Host2Device\n");
checkHipErrors(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
const unsigned blocks = 512;
const unsigned threadsPerBlock = 256;
printf("info: launch 'vector_square' kernel\n");
hipLaunchKernelGGL(vector_square, dim3(blocks), dim3(threadsPerBlock), 0, 0, C_d, A_d, N);
printf("info: copy Device2Host\n");
checkHipErrors(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
printf("info: check result\n");
for (size_t i = 0; i < N; i++) {
if (C_h[i] != A_h[i] * A_h[i]) {
checkHipErrors(hipErrorUnknown);
}
printf ("info: allocate device mem (%6.2f MB)\n", 2*Nbytes/1024.0/1024.0);
checkHipErrors(hipMalloc(&A_d, Nbytes));
checkHipErrors(hipMalloc(&C_d, Nbytes));
printf ("info: copy Host2Device\n");
checkHipErrors ( hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
const unsigned blocks = 512;
const unsigned threadsPerBlock = 256;
printf ("info: launch 'vector_square' kernel\n");
hipLaunchKernelGGL(vector_square, dim3(blocks), dim3(threadsPerBlock), 0, 0, C_d, A_d, N);
printf ("info: copy Device2Host\n");
checkHipErrors ( hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
printf ("info: check result\n");
for (size_t i=0; i<N; i++) {
if (C_h[i] != A_h[i] * A_h[i]) {
checkHipErrors(hipErrorUnknown);
}
}
checkHipErrors(hipFree(A_d));
checkHipErrors(hipFree(C_d));
free(A_h);
free(C_h);
printf ("PASSED!\n");
}
checkHipErrors(hipFree(A_d));
checkHipErrors(hipFree(C_d));
free(A_h);
free(C_h);
printf("PASSED!\n");
}
@@ -35,7 +35,7 @@ static constexpr auto NUM_THREADS{128};
static constexpr auto NUM_BLOCKS{32};
static constexpr auto saxpy{
R"(
R"(
#include "test_header.h"
#include "test_header1.h"
extern "C"
@@ -49,109 +49,111 @@ void saxpy(real a, realptr x, realptr y, realptr out, size_t n)
}
)"};
int main()
{
using namespace std;
int main() {
using namespace std;
hiprtcProgram prog;
int num_headers = 2;
vector<const char*> header_names;
vector<const char*> header_sources;
header_names.push_back("test_header.h");
header_names.push_back("test_header1.h");
header_sources.push_back("#ifndef HIPRTC_TEST_HEADER_H\n#define HIPRTC_TEST_HEADER_H\ntypedef float real;\n#endif //HIPRTC_TEST_HEADER_H\n");
header_sources.push_back("#ifndef HIPRTC_TEST_HEADER1_H\n#define HIPRTC_TEST_HEADER1_H\ntypedef float* realptr;\n#endif //HIPRTC_TEST_HEADER1_H\n");
hiprtcCreateProgram(&prog, // prog
saxpy, // buffer
"saxpy.cu", // name
num_headers, // numHeaders
&header_sources[0], // headers
&header_names[0]); // includeNames
hiprtcProgram prog;
int num_headers = 2;
vector<const char*> header_names;
vector<const char*> header_sources;
header_names.push_back("test_header.h");
header_names.push_back("test_header1.h");
header_sources.push_back(
"#ifndef HIPRTC_TEST_HEADER_H\n#define HIPRTC_TEST_HEADER_H\ntypedef float real;\n#endif "
"//HIPRTC_TEST_HEADER_H\n");
header_sources.push_back(
"#ifndef HIPRTC_TEST_HEADER1_H\n#define HIPRTC_TEST_HEADER1_H\ntypedef float* "
"realptr;\n#endif //HIPRTC_TEST_HEADER1_H\n");
hiprtcCreateProgram(&prog, // prog
saxpy, // buffer
"saxpy.cu", // name
num_headers, // numHeaders
&header_sources[0], // headers
&header_names[0]); // includeNames
hipDeviceProp_t props;
int device = 0;
checkHipErrors(hipGetDeviceProperties(&props, device));
hipDeviceProp_t props;
int device = 0;
checkHipErrors(hipGetDeviceProperties(&props, device));
const char* options[] = {};
const char* options[] = {};
hiprtcResult compileResult{hiprtcCompileProgram(prog, 0, options)};
hiprtcResult compileResult{hiprtcCompileProgram(prog, 0, options)};
size_t logSize;
hiprtcGetProgramLogSize(prog, &logSize);
size_t logSize;
hiprtcGetProgramLogSize(prog, &logSize);
if (logSize) {
string log(logSize, '\0');
hiprtcGetProgramLog(prog, &log[0]);
if (logSize) {
string log(logSize, '\0');
hiprtcGetProgramLog(prog, &log[0]);
cout << log << '\n';
cout << log << '\n';
}
if (compileResult != HIPRTC_SUCCESS) {
cout << "Compilation failed." << endl;
}
size_t codeSize;
hiprtcGetCodeSize(prog, &codeSize);
vector<char> code(codeSize);
hiprtcGetCode(prog, code.data());
hiprtcDestroyProgram(&prog);
hipModule_t module;
hipFunction_t kernel;
checkHipErrors(hipModuleLoadData(&module, code.data()));
checkHipErrors(hipModuleGetFunction(&kernel, module, "saxpy"));
size_t n = NUM_THREADS * NUM_BLOCKS;
size_t bufferSize = n * sizeof(float);
float a = 5.1f;
unique_ptr<float[]> hX{new float[n]};
unique_ptr<float[]> hY{new float[n]};
unique_ptr<float[]> hOut{new float[n]};
for (size_t i = 0; i < n; ++i) {
hX[i] = static_cast<float>(i);
hY[i] = static_cast<float>(i * 2);
}
hipDeviceptr_t dX, dY, dOut;
checkHipErrors(hipMalloc((void**)&dX, bufferSize));
checkHipErrors(hipMalloc((void**)&dY, bufferSize));
checkHipErrors(hipMalloc((void**)&dOut, bufferSize));
checkHipErrors(hipMemcpyHtoD(dX, hX.get(), bufferSize));
checkHipErrors(hipMemcpyHtoD(dY, hY.get(), bufferSize));
struct {
float a_;
hipDeviceptr_t b_;
hipDeviceptr_t c_;
hipDeviceptr_t d_;
size_t e_;
} args{a, dX, dY, dOut, n};
auto size = sizeof(args);
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, HIP_LAUNCH_PARAM_BUFFER_SIZE, &size,
HIP_LAUNCH_PARAM_END};
checkHipErrors(hipModuleLaunchKernel(kernel, NUM_BLOCKS, 1, 1, NUM_THREADS, 1, 1, 0, nullptr,
nullptr, config));
checkHipErrors(hipMemcpyDtoH(hOut.get(), dOut, bufferSize));
for (size_t i = 0; i < n; ++i) {
if (fabs(a * hX[i] + hY[i] - hOut[i]) > fabs(hOut[i]) * 1e-6) {
cout << "Validation failed." << endl;
}
}
if (compileResult != HIPRTC_SUCCESS) {
cout << "Compilation failed." << endl;
}
checkHipErrors(hipFree((void*)dX));
checkHipErrors(hipFree((void*)dY));
checkHipErrors(hipFree((void*)dOut));
size_t codeSize;
hiprtcGetCodeSize(prog, &codeSize);
checkHipErrors(hipModuleUnload(module));
vector<char> code(codeSize);
hiprtcGetCode(prog, code.data());
hiprtcDestroyProgram(&prog);
hipModule_t module;
hipFunction_t kernel;
checkHipErrors(hipModuleLoadData(&module, code.data()));
checkHipErrors(hipModuleGetFunction(&kernel, module, "saxpy"));
size_t n = NUM_THREADS * NUM_BLOCKS;
size_t bufferSize = n * sizeof(float);
float a = 5.1f;
unique_ptr<float[]> hX{new float[n]};
unique_ptr<float[]> hY{new float[n]};
unique_ptr<float[]> hOut{new float[n]};
for (size_t i = 0; i < n; ++i) {
hX[i] = static_cast<float>(i);
hY[i] = static_cast<float>(i * 2);
}
hipDeviceptr_t dX, dY, dOut;
checkHipErrors(hipMalloc((void **)&dX, bufferSize));
checkHipErrors(hipMalloc((void **)&dY, bufferSize));
checkHipErrors(hipMalloc((void **)&dOut, bufferSize));
checkHipErrors(hipMemcpyHtoD(dX, hX.get(), bufferSize));
checkHipErrors(hipMemcpyHtoD(dY, hY.get(), bufferSize));
struct {
float a_;
hipDeviceptr_t b_;
hipDeviceptr_t c_;
hipDeviceptr_t d_;
size_t e_;
} args{a, dX, dY, dOut, n};
auto size = sizeof(args);
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args,
HIP_LAUNCH_PARAM_BUFFER_SIZE, &size,
HIP_LAUNCH_PARAM_END};
checkHipErrors(hipModuleLaunchKernel(kernel, NUM_BLOCKS, 1, 1, NUM_THREADS, 1, 1,
0, nullptr, nullptr, config));
checkHipErrors(hipMemcpyDtoH(hOut.get(), dOut, bufferSize));
for (size_t i = 0; i < n; ++i) {
if (fabs(a * hX[i] + hY[i] - hOut[i]) > fabs(hOut[i])* 1e-6) {
cout << "Validation failed." << endl;
}
}
checkHipErrors(hipFree((void *)dX));
checkHipErrors(hipFree((void *)dY));
checkHipErrors(hipFree((void *)dOut));
checkHipErrors(hipModuleUnload(module));
cout << "SAXPY test completed" << endl;
cout << "SAXPY test completed" << endl;
}
@@ -36,93 +36,94 @@ THE SOFTWARE.
// Device (Kernel) function, it must be void
__global__ void matrixTranspose(float* out, float* in, const int width) {
__shared__ float sharedMem[WIDTH * WIDTH];
__shared__ float sharedMem[WIDTH * WIDTH];
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
sharedMem[y * width + x] = in[x * width + y];
sharedMem[y * width + x] = in[x * width + y];
__syncthreads();
__syncthreads();
out[y * width + x] = sharedMem[y * width + x];
out[y * width + x] = sharedMem[y * width + x];
}
// CPU implementation of matrix transpose
void matrixTransposeCPUReference(float* output, float* input, const unsigned int width) {
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
}
}
int main() {
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
std::cout << "Device name " << devProp.name << std::endl;
std::cout << "Device name " << devProp.name << std::endl;
int i;
int errors;
int i;
int errors;
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// Lauching kernel from host
hipLaunchKernelGGL(
matrixTranspose, dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, gpuTransposeMatrix, gpuMatrix, WIDTH);
// Memory transfer from device to host
checkHipErrors(
hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
printf("%d cpu: %f gpu %f\n", i, cpuTransposeMatrix[i], TransposeMatrix[i]);
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("PASSED!\n");
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
// Lauching kernel from host
hipLaunchKernelGGL(matrixTranspose, dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, gpuTransposeMatrix,
gpuMatrix, WIDTH);
// Memory transfer from device to host
checkHipErrors(hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
printf("%d cpu: %f gpu %f\n", i, cpuTransposeMatrix[i], TransposeMatrix[i]);
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("PASSED!\n");
}
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
return errors;
return errors;
}
@@ -36,89 +36,90 @@ THE SOFTWARE.
// Device (Kernel) function, it must be void
__global__ void matrixTranspose(float* out, float* in, const int width) {
int x = blockDim.x * blockIdx.x + threadIdx.x;
int x = blockDim.x * blockIdx.x + threadIdx.x;
float val = in[x];
float val = in[x];
for (int i = 0; i < width; i++) {
for (int j = 0; j < width; j++) out[i * width + j] = __shfl(val, j * width + i);
}
for (int i = 0; i < width; i++) {
for (int j = 0; j < width; j++) out[i * width + j] = __shfl(val, j * width + i);
}
}
// CPU implementation of matrix transpose
void matrixTransposeCPUReference(float* output, float* input, const unsigned int width) {
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
}
}
int main() {
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
std::cout << "Device name " << devProp.name << std::endl;
std::cout << "Device name " << devProp.name << std::endl;
int i;
int errors;
int i;
int errors;
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// Lauching kernel from host
hipLaunchKernelGGL(matrixTranspose, dim3(1), dim3(THREADS_PER_BLOCK_X * THREADS_PER_BLOCK_Y), 0,
0, gpuTransposeMatrix, gpuMatrix, WIDTH);
// Memory transfer from device to host
checkHipErrors(
hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
printf("%d cpu: %f gpu %f\n", i, cpuTransposeMatrix[i], TransposeMatrix[i]);
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("PASSED!\n");
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
// Lauching kernel from host
hipLaunchKernelGGL(matrixTranspose, dim3(1), dim3(THREADS_PER_BLOCK_X * THREADS_PER_BLOCK_Y), 0, 0,
gpuTransposeMatrix, gpuMatrix, WIDTH);
// Memory transfer from device to host
checkHipErrors(hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
printf("%d cpu: %f gpu %f\n", i, cpuTransposeMatrix[i], TransposeMatrix[i]);
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("PASSED!\n");
}
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
return errors;
return errors;
}
@@ -37,87 +37,88 @@ THE SOFTWARE.
// Device (Kernel) function, it must be void
__global__ void matrixTranspose(float* out, float* in, const int width) {
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
float val = in[y * width + x];
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
float val = in[y * width + x];
out[x * width + y] = __shfl(val, y * width + x);
out[x * width + y] = __shfl(val, y * width + x);
}
// CPU implementation of matrix transpose
void matrixTransposeCPUReference(float* output, float* input, const unsigned int width) {
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
}
}
int main() {
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
std::cout << "Device name " << devProp.name << std::endl;
std::cout << "Device name " << devProp.name << std::endl;
int i;
int errors;
int i;
int errors;
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// Lauching kernel from host
hipLaunchKernelGGL(matrixTranspose, dim3(1), dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0,
gpuTransposeMatrix, gpuMatrix, WIDTH);
// Memory transfer from device to host
checkHipErrors(
hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
printf("%d cpu: %f gpu %f\n", i, cpuTransposeMatrix[i], TransposeMatrix[i]);
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("PASSED!\n");
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
// Lauching kernel from host
hipLaunchKernelGGL(matrixTranspose, dim3(1), dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0,
gpuTransposeMatrix, gpuMatrix, WIDTH);
// Memory transfer from device to host
checkHipErrors(hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
printf("%d cpu: %f gpu %f\n", i, cpuTransposeMatrix[i], TransposeMatrix[i]);
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("PASSED!\n");
}
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
return errors;
return errors;
}
@@ -36,93 +36,95 @@ THE SOFTWARE.
// Device (Kernel) function, it must be void
__global__ void matrixTranspose(float* out, float* in, const int width) {
extern __shared__ float sharedMem[];
extern __shared__ float sharedMem[];
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
sharedMem[y * width + x] = in[x * width + y];
sharedMem[y * width + x] = in[x * width + y];
__syncthreads();
__syncthreads();
out[y * width + x] = sharedMem[y * width + x];
out[y * width + x] = sharedMem[y * width + x];
}
// CPU implementation of matrix transpose
void matrixTransposeCPUReference(float* output, float* input, const unsigned int width) {
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
for (unsigned int j = 0; j < width; j++) {
for (unsigned int i = 0; i < width; i++) {
output[i * width + j] = input[j * width + i];
}
}
}
int main() {
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* Matrix;
float* TransposeMatrix;
float* cpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
float* gpuMatrix;
float* gpuTransposeMatrix;
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
std::cout << "Device name " << devProp.name << std::endl;
std::cout << "Device name " << devProp.name << std::endl;
int i;
int errors;
int i;
int errors;
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
Matrix = (float*)malloc(NUM * sizeof(float));
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
// initialize the input data
for (i = 0; i < NUM; i++) {
Matrix[i] = (float)i * 10.0f;
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// Lauching kernel from host
hipLaunchKernelGGL(matrixTranspose,
dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), sizeof(float) * WIDTH * WIDTH,
0, gpuTransposeMatrix, gpuMatrix, WIDTH);
// Memory transfer from device to host
checkHipErrors(
hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
printf("%d cpu: %f gpu %f\n", i, cpuTransposeMatrix[i], TransposeMatrix[i]);
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("dynamic_shared PASSED!\n");
}
// allocate the memory on the device side
checkHipErrors(hipMalloc((void**)&gpuMatrix, NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float)));
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// Memory transfer from host to device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
// Lauching kernel from host
hipLaunchKernelGGL(matrixTranspose, dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), sizeof(float) * WIDTH * WIDTH,
0, gpuTransposeMatrix, gpuMatrix, WIDTH);
// Memory transfer from device to host
checkHipErrors(hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost));
// CPU MatrixTranspose computation
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
// verify the results
errors = 0;
double eps = 1.0E-6;
for (i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
printf("%d cpu: %f gpu %f\n", i, cpuTransposeMatrix[i], TransposeMatrix[i]);
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("dynamic_shared PASSED!\n");
}
// free the resources on device side
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuTransposeMatrix));
// free the resources on host side
free(Matrix);
free(TransposeMatrix);
free(cpuTransposeMatrix);
return errors;
return errors;
}
@@ -34,106 +34,105 @@ THE SOFTWARE.
using namespace std;
__global__ void matrixTranspose_static_shared(float* out, float* in,
const int width) {
__shared__ float sharedMem[WIDTH * WIDTH];
__global__ void matrixTranspose_static_shared(float* out, float* in, const int width) {
__shared__ float sharedMem[WIDTH * WIDTH];
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
sharedMem[y * width + x] = in[x * width + y];
sharedMem[y * width + x] = in[x * width + y];
__syncthreads();
__syncthreads();
out[y * width + x] = sharedMem[y * width + x];
out[y * width + x] = sharedMem[y * width + x];
}
__global__ void matrixTranspose_dynamic_shared(float* out, float* in,
const int width) {
extern __shared__ float sharedMem[];
__global__ void matrixTranspose_dynamic_shared(float* out, float* in, const int width) {
extern __shared__ float sharedMem[];
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
sharedMem[y * width + x] = in[x * width + y];
sharedMem[y * width + x] = in[x * width + y];
__syncthreads();
__syncthreads();
out[y * width + x] = sharedMem[y * width + x];
out[y * width + x] = sharedMem[y * width + x];
}
void MultipleStream(float** data, float* randArray, float** gpuTransposeMatrix,
float** TransposeMatrix, int width) {
const int num_streams = 2;
hipStream_t streams[num_streams];
const int num_streams = 2;
hipStream_t streams[num_streams];
for (int i = 0; i < num_streams; i++) checkHipErrors(hipStreamCreate(&streams[i]));
for (int i = 0; i < num_streams; i++) checkHipErrors(hipStreamCreate(&streams[i]));
for (int i = 0; i < num_streams; i++) {
checkHipErrors(hipMalloc((void**)&data[i], NUM * sizeof(float)));
checkHipErrors(hipMemcpyAsync(data[i], randArray, NUM * sizeof(float), hipMemcpyHostToDevice, streams[i]));
}
for (int i = 0; i < num_streams; i++) {
checkHipErrors(hipMalloc((void**)&data[i], NUM * sizeof(float)));
checkHipErrors(
hipMemcpyAsync(data[i], randArray, NUM * sizeof(float), hipMemcpyHostToDevice, streams[i]));
}
hipLaunchKernelGGL(matrixTranspose_static_shared,
dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, streams[0],
gpuTransposeMatrix[0], data[0], width);
hipLaunchKernelGGL(matrixTranspose_static_shared,
dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, streams[0],
gpuTransposeMatrix[0], data[0], width);
hipLaunchKernelGGL(matrixTranspose_dynamic_shared,
dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), sizeof(float) * WIDTH * WIDTH,
streams[1], gpuTransposeMatrix[1], data[1], width);
hipLaunchKernelGGL(matrixTranspose_dynamic_shared,
dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), sizeof(float) * WIDTH * WIDTH,
streams[1], gpuTransposeMatrix[1], data[1], width);
for (int i = 0; i < num_streams; i++)
checkHipErrors(hipMemcpyAsync(TransposeMatrix[i], gpuTransposeMatrix[i], NUM * sizeof(float),
hipMemcpyDeviceToHost, streams[i]));
for (int i = 0; i < num_streams; i++)
checkHipErrors(hipMemcpyAsync(TransposeMatrix[i], gpuTransposeMatrix[i], NUM * sizeof(float),
hipMemcpyDeviceToHost, streams[i]));
}
int main() {
checkHipErrors(hipSetDevice(0));
checkHipErrors(hipSetDevice(0));
float *data[2], *TransposeMatrix[2], *gpuTransposeMatrix[2], *randArray;
float *data[2], *TransposeMatrix[2], *gpuTransposeMatrix[2], *randArray;
int width = WIDTH;
int width = WIDTH;
randArray = (float*)malloc(NUM * sizeof(float));
randArray = (float*)malloc(NUM * sizeof(float));
TransposeMatrix[0] = (float*)malloc(NUM * sizeof(float));
TransposeMatrix[1] = (float*)malloc(NUM * sizeof(float));
TransposeMatrix[0] = (float*)malloc(NUM * sizeof(float));
TransposeMatrix[1] = (float*)malloc(NUM * sizeof(float));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix[0], NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix[1], NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix[0], NUM * sizeof(float)));
checkHipErrors(hipMalloc((void**)&gpuTransposeMatrix[1], NUM * sizeof(float)));
for (int i = 0; i < NUM; i++) {
randArray[i] = (float)i * 1.0f;
for (int i = 0; i < NUM; i++) {
randArray[i] = (float)i * 1.0f;
}
MultipleStream(data, randArray, gpuTransposeMatrix, TransposeMatrix, width);
checkHipErrors(hipDeviceSynchronize());
// verify the results
int errors = 0;
double eps = 1.0E-6;
for (int i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[0][i] - TransposeMatrix[1][i]) > eps) {
printf("%d stream0: %f stream1 %f\n", i, TransposeMatrix[0][i], TransposeMatrix[1][i]);
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("stream PASSED!\n");
}
MultipleStream(data, randArray, gpuTransposeMatrix, TransposeMatrix, width);
free(randArray);
for (int i = 0; i < 2; i++) {
checkHipErrors(hipFree(data[i]));
checkHipErrors(hipFree(gpuTransposeMatrix[i]));
free(TransposeMatrix[i]);
}
checkHipErrors(hipDeviceSynchronize());
// verify the results
int errors = 0;
double eps = 1.0E-6;
for (int i = 0; i < NUM; i++) {
if (std::abs(TransposeMatrix[0][i] - TransposeMatrix[1][i]) > eps) {
printf("%d stream0: %f stream1 %f\n", i, TransposeMatrix[0][i], TransposeMatrix[1][i]);
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("stream PASSED!\n");
}
free(randArray);
for (int i = 0; i < 2; i++) {
checkHipErrors(hipFree(data[i]));
checkHipErrors(hipFree(gpuTransposeMatrix[i]));
free(TransposeMatrix[i]);
}
checkHipErrors(hipDeviceReset());
return 0;
checkHipErrors(hipDeviceReset());
return 0;
}
@@ -34,193 +34,188 @@ using namespace std;
#define KRED "\x1B[31m"
#define failed(...) \
printf("%serror: ", KRED); \
printf(__VA_ARGS__); \
printf("\n"); \
printf("error: TEST FAILED\n%s", KNRM); \
abort();
printf("%serror: ", KRED); \
printf(__VA_ARGS__); \
printf("\n"); \
printf("error: TEST FAILED\n%s", KNRM); \
abort();
#define HIPCHECK(error) \
{ \
hipError_t localError = error; \
if ((localError != hipSuccess)&& (localError != hipErrorPeerAccessAlreadyEnabled)&& \
(localError != hipErrorPeerAccessNotEnabled )) { \
printf("%serror: '%s'(%d) from %s at %s:%d%s\n", KRED, hipGetErrorString(localError), \
localError, #error, __FILE__, __LINE__, KNRM); \
failed("API returned error code."); \
} \
}
{ \
hipError_t localError = error; \
if ((localError != hipSuccess) && (localError != hipErrorPeerAccessAlreadyEnabled) && \
(localError != hipErrorPeerAccessNotEnabled)) { \
printf("%serror: '%s'(%d) from %s at %s:%d%s\n", KRED, hipGetErrorString(localError), \
localError, #error, __FILE__, __LINE__, KNRM); \
failed("API returned error code."); \
} \
}
void checkPeer2PeerSupport() {
int gpuCount;
int canAccessPeer;
int gpuCount;
int canAccessPeer;
HIPCHECK(hipGetDeviceCount(&gpuCount));
HIPCHECK(hipGetDeviceCount(&gpuCount));
for (int currentGpu = 0; currentGpu < gpuCount; currentGpu++) {
HIPCHECK(hipSetDevice(currentGpu));
for (int currentGpu = 0; currentGpu < gpuCount; currentGpu++) {
HIPCHECK(hipSetDevice(currentGpu));
for (int peerGpu = 0; peerGpu < currentGpu; peerGpu++) {
if (currentGpu != peerGpu) {
HIPCHECK(hipDeviceCanAccessPeer(&canAccessPeer, currentGpu, peerGpu));
printf("currentGpu#%d canAccessPeer: peerGpu#%d=%d\n", currentGpu, peerGpu,
canAccessPeer);
}
for (int peerGpu = 0; peerGpu < currentGpu; peerGpu++) {
if (currentGpu != peerGpu) {
HIPCHECK(hipDeviceCanAccessPeer(&canAccessPeer, currentGpu, peerGpu));
printf("currentGpu#%d canAccessPeer: peerGpu#%d=%d\n", currentGpu, peerGpu, canAccessPeer);
}
HIPCHECK(hipSetDevice(peerGpu));
HIPCHECK(hipDeviceReset());
}
HIPCHECK(hipSetDevice(currentGpu));
HIPCHECK(hipDeviceReset());
HIPCHECK(hipSetDevice(peerGpu));
HIPCHECK(hipDeviceReset());
}
HIPCHECK(hipSetDevice(currentGpu));
HIPCHECK(hipDeviceReset());
}
}
void enablePeer2Peer(int currentGpu, int peerGpu) {
int canAccessPeer;
int canAccessPeer;
// Must be on a multi-gpu system:
assert(currentGpu != peerGpu);
// Must be on a multi-gpu system:
assert(currentGpu != peerGpu);
HIPCHECK(hipSetDevice(currentGpu));
hipDeviceCanAccessPeer(&canAccessPeer, currentGpu, peerGpu);
HIPCHECK(hipSetDevice(currentGpu));
hipDeviceCanAccessPeer(&canAccessPeer, currentGpu, peerGpu);
if (canAccessPeer == 1) {
HIPCHECK(hipDeviceEnablePeerAccess(peerGpu, 0));
} else
printf("peer2peer transfer not possible between the selected gpu devices");
if (canAccessPeer == 1) {
HIPCHECK(hipDeviceEnablePeerAccess(peerGpu, 0));
} else
printf("peer2peer transfer not possible between the selected gpu devices");
}
void disablePeer2Peer(int currentGpu, int peerGpu) {
int canAccessPeer;
int canAccessPeer;
// Must be on a multi-gpu system:
assert(currentGpu != peerGpu);
// Must be on a multi-gpu system:
assert(currentGpu != peerGpu);
HIPCHECK(hipSetDevice(currentGpu));
hipDeviceCanAccessPeer(&canAccessPeer, currentGpu, peerGpu);
HIPCHECK(hipSetDevice(currentGpu));
hipDeviceCanAccessPeer(&canAccessPeer, currentGpu, peerGpu);
if (canAccessPeer == 1) {
HIPCHECK(hipDeviceDisablePeerAccess(peerGpu));
} else
printf("peer2peer disable not required");
if (canAccessPeer == 1) {
HIPCHECK(hipDeviceDisablePeerAccess(peerGpu));
} else
printf("peer2peer disable not required");
}
__global__ void matrixTranspose_static_shared(float* out, float* in,
const int width) {
__shared__ float sharedMem[WIDTH * WIDTH];
__global__ void matrixTranspose_static_shared(float* out, float* in, const int width) {
__shared__ float sharedMem[WIDTH * WIDTH];
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
sharedMem[y * width + x] = in[x * width + y];
sharedMem[y * width + x] = in[x * width + y];
__syncthreads();
__syncthreads();
out[y * width + x] = sharedMem[y * width + x];
out[y * width + x] = sharedMem[y * width + x];
}
__global__ void matrixTranspose_dynamic_shared(float* out, float* in,
const int width) {
extern __shared__ float sharedMem[];
__global__ void matrixTranspose_dynamic_shared(float* out, float* in, const int width) {
extern __shared__ float sharedMem[];
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
int x = blockDim.x * blockIdx.x + threadIdx.x;
int y = blockDim.y * blockIdx.y + threadIdx.y;
sharedMem[y * width + x] = in[x * width + y];
sharedMem[y * width + x] = in[x * width + y];
__syncthreads();
__syncthreads();
out[y * width + x] = sharedMem[y * width + x];
out[y * width + x] = sharedMem[y * width + x];
}
int main() {
checkPeer2PeerSupport();
checkPeer2PeerSupport();
int gpuCount;
int currentGpu, peerGpu;
int gpuCount;
int currentGpu, peerGpu;
HIPCHECK(hipGetDeviceCount(&gpuCount));
if (gpuCount < 2) {
printf("Peer2Peer application requires atleast 2 gpu devices");
return 0;
}
currentGpu = 0;
peerGpu = (currentGpu + 1);
printf("currentGpu=%d peerGpu=%d (Total no. of gpu = %d)\n", currentGpu, peerGpu, gpuCount);
float *data[2], *TransposeMatrix[2], *gpuTransposeMatrix[2], *randArray;
int width = WIDTH;
randArray = (float*)malloc(NUM * sizeof(float));
for (int i = 0; i < NUM; i++) {
randArray[i] = (float)i * 1.0f;
}
enablePeer2Peer(currentGpu, peerGpu);
HIPCHECK(hipSetDevice(currentGpu));
TransposeMatrix[0] = (float*)malloc(NUM * sizeof(float));
hipMalloc((void**)&gpuTransposeMatrix[0], NUM * sizeof(float));
hipMalloc((void**)&data[0], NUM * sizeof(float));
hipMemcpy(data[0], randArray, NUM * sizeof(float), hipMemcpyHostToDevice);
hipLaunchKernelGGL(matrixTranspose_static_shared,
dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, gpuTransposeMatrix[0],
data[0], width);
HIPCHECK(hipDeviceSynchronize());
HIPCHECK(hipSetDevice(peerGpu));
TransposeMatrix[1] = (float*)malloc(NUM * sizeof(float));
hipMalloc((void**)&gpuTransposeMatrix[1], NUM * sizeof(float));
hipMalloc((void**)&data[1], NUM * sizeof(float));
hipMemcpy(data[1], gpuTransposeMatrix[0], NUM * sizeof(float), hipMemcpyDeviceToDevice);
hipLaunchKernelGGL(matrixTranspose_dynamic_shared,
dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), sizeof(float) * WIDTH * WIDTH,
0, gpuTransposeMatrix[1], data[1], width);
hipMemcpy(TransposeMatrix[1], gpuTransposeMatrix[1], NUM * sizeof(float),
hipMemcpyDeviceToHost);
hipDeviceSynchronize();
disablePeer2Peer(currentGpu, peerGpu);
// verify the results
int errors = 0;
double eps = 1.0E-6;
for (int i = 0; i < NUM; i++) {
if (std::abs(randArray[i] - TransposeMatrix[1][i]) > eps) {
printf("%d cpu: %f gpu peered data %f\n", i, randArray[i], TransposeMatrix[1][i]);
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("Peer2Peer PASSED!\n");
}
free(randArray);
for (int i = 0; i < 2; i++) {
hipFree(data[i]);
hipFree(gpuTransposeMatrix[i]);
free(TransposeMatrix[i]);
}
HIPCHECK(hipSetDevice(peerGpu));
HIPCHECK(hipDeviceReset());
HIPCHECK(hipSetDevice(currentGpu));
HIPCHECK(hipDeviceReset());
HIPCHECK(hipGetDeviceCount(&gpuCount));
if (gpuCount < 2) {
printf("Peer2Peer application requires atleast 2 gpu devices");
return 0;
}
currentGpu = 0;
peerGpu = (currentGpu + 1);
printf("currentGpu=%d peerGpu=%d (Total no. of gpu = %d)\n", currentGpu, peerGpu, gpuCount);
float *data[2], *TransposeMatrix[2], *gpuTransposeMatrix[2], *randArray;
int width = WIDTH;
randArray = (float*)malloc(NUM * sizeof(float));
for (int i = 0; i < NUM; i++) {
randArray[i] = (float)i * 1.0f;
}
enablePeer2Peer(currentGpu, peerGpu);
HIPCHECK(hipSetDevice(currentGpu));
TransposeMatrix[0] = (float*)malloc(NUM * sizeof(float));
hipMalloc((void**)&gpuTransposeMatrix[0], NUM * sizeof(float));
hipMalloc((void**)&data[0], NUM * sizeof(float));
hipMemcpy(data[0], randArray, NUM * sizeof(float), hipMemcpyHostToDevice);
hipLaunchKernelGGL(
matrixTranspose_static_shared, dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, gpuTransposeMatrix[0], data[0], width);
HIPCHECK(hipDeviceSynchronize());
HIPCHECK(hipSetDevice(peerGpu));
TransposeMatrix[1] = (float*)malloc(NUM * sizeof(float));
hipMalloc((void**)&gpuTransposeMatrix[1], NUM * sizeof(float));
hipMalloc((void**)&data[1], NUM * sizeof(float));
hipMemcpy(data[1], gpuTransposeMatrix[0], NUM * sizeof(float), hipMemcpyDeviceToDevice);
hipLaunchKernelGGL(matrixTranspose_dynamic_shared,
dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y),
dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), sizeof(float) * WIDTH * WIDTH,
0, gpuTransposeMatrix[1], data[1], width);
hipMemcpy(TransposeMatrix[1], gpuTransposeMatrix[1], NUM * sizeof(float), hipMemcpyDeviceToHost);
hipDeviceSynchronize();
disablePeer2Peer(currentGpu, peerGpu);
// verify the results
int errors = 0;
double eps = 1.0E-6;
for (int i = 0; i < NUM; i++) {
if (std::abs(randArray[i] - TransposeMatrix[1][i]) > eps) {
printf("%d cpu: %f gpu peered data %f\n", i, randArray[i], TransposeMatrix[1][i]);
errors++;
}
}
if (errors != 0) {
printf("FAILED: %d errors\n", errors);
} else {
printf("Peer2Peer PASSED!\n");
}
free(randArray);
for (int i = 0; i < 2; i++) {
hipFree(data[i]);
hipFree(gpuTransposeMatrix[i]);
free(TransposeMatrix[i]);
}
HIPCHECK(hipSetDevice(peerGpu));
HIPCHECK(hipDeviceReset());
HIPCHECK(hipSetDevice(currentGpu));
HIPCHECK(hipDeviceReset());
return 0;
}
@@ -35,89 +35,90 @@ THE SOFTWARE.
// CPU function - basically scan each row and save the output in array
void matrixRowSum(int* input, int* output, int width) {
for (int i = 0; i < width; i++) {
for (int j = 0; j < width; j++) {
output[i] += input[i * width + j];
}
for (int i = 0; i < width; i++) {
for (int j = 0; j < width; j++) {
output[i] += input[i * width + j];
}
}
}
// Device (kernel) function
__global__ void gpuMatrixRowSum(int* input, int* output, int width) {
int index = blockDim.x * blockIdx.x + threadIdx.x;
int index = blockDim.x * blockIdx.x + threadIdx.x;
#pragma unroll
for (int i = 0; i < width; i++) {
output[index] += input[index * width + i];
}
for (int i = 0; i < width; i++) {
output[index] += input[index * width + i];
}
}
int main() {
int* Matrix;
int* sumMatrix;
int* cpuSumMatrix;
int* Matrix;
int* sumMatrix;
int* cpuSumMatrix;
int* gpuMatrix;
int* gpuSumMatrix;
int* gpuMatrix;
int* gpuSumMatrix;
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
hipDeviceProp_t devProp;
checkHipErrors(hipGetDeviceProperties(&devProp, 0));
std::cout << "Device name " << devProp.name << std::endl;
std::cout << "Device name " << devProp.name << std::endl;
Matrix = (int*)malloc(sizeof(int) * SIZE);
sumMatrix = (int*)malloc(sizeof(int) * LENGTH);
cpuSumMatrix = (int*)malloc(sizeof(int) * LENGTH);
Matrix = (int*)malloc(sizeof(int) * SIZE);
sumMatrix = (int*)malloc(sizeof(int) * LENGTH);
cpuSumMatrix = (int*)malloc(sizeof(int) * LENGTH);
for (int i = 0; i < SIZE; i++) {
Matrix[i] = i * 2;
for (int i = 0; i < SIZE; i++) {
Matrix[i] = i * 2;
}
for (int i = 0; i < LENGTH; i++) {
cpuSumMatrix[i] = 0;
}
// Allocated Device Memory
checkHipErrors(hipMalloc((void**)&gpuMatrix, SIZE * sizeof(int)));
checkHipErrors(hipMalloc((void**)&gpuSumMatrix, LENGTH * sizeof(int)));
// Memory Copy to Device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, SIZE * sizeof(int), hipMemcpyHostToDevice));
checkHipErrors(
hipMemcpy(gpuSumMatrix, cpuSumMatrix, LENGTH * sizeof(float), hipMemcpyHostToDevice));
// Launch device kernels
hipLaunchKernelGGL(gpuMatrixRowSum, dim3(BLOCKS_PER_GRID), dim3(THREADS_PER_BLOCK), 0, 0,
gpuMatrix, gpuSumMatrix, LENGTH);
// Memory copy back to device
checkHipErrors(hipMemcpy(sumMatrix, gpuSumMatrix, LENGTH * sizeof(int), hipMemcpyDeviceToHost));
// Cpu implementation
matrixRowSum(Matrix, cpuSumMatrix, LENGTH);
// verify the results
int errors = 0;
for (int i = 0; i < LENGTH; i++) {
if (sumMatrix[i] != cpuSumMatrix[i]) {
printf("%d - cpu: %d gpu: %d\n", i, sumMatrix[i], cpuSumMatrix[i]);
errors++;
}
}
for (int i = 0; i < LENGTH; i++) {
cpuSumMatrix[i] = 0;
}
if (errors == 0) {
printf("PASSED\n");
} else {
printf("FAILED with %d errors\n", errors);
}
// Allocated Device Memory
checkHipErrors(hipMalloc((void**)&gpuMatrix, SIZE * sizeof(int)));
checkHipErrors(hipMalloc((void**)&gpuSumMatrix, LENGTH * sizeof(int)));
// GPU Free
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuSumMatrix));
// Memory Copy to Device
checkHipErrors(hipMemcpy(gpuMatrix, Matrix, SIZE * sizeof(int), hipMemcpyHostToDevice));
checkHipErrors(hipMemcpy(gpuSumMatrix, cpuSumMatrix, LENGTH * sizeof(float), hipMemcpyHostToDevice));
// CPU Free
free(Matrix);
free(sumMatrix);
free(cpuSumMatrix);
// Launch device kernels
hipLaunchKernelGGL(gpuMatrixRowSum, dim3(BLOCKS_PER_GRID), dim3(THREADS_PER_BLOCK), 0, 0,
gpuMatrix, gpuSumMatrix, LENGTH);
// Memory copy back to device
checkHipErrors(hipMemcpy(sumMatrix, gpuSumMatrix, LENGTH * sizeof(int), hipMemcpyDeviceToHost));
// Cpu implementation
matrixRowSum(Matrix, cpuSumMatrix, LENGTH);
// verify the results
int errors = 0;
for (int i = 0; i < LENGTH; i++) {
if (sumMatrix[i] != cpuSumMatrix[i]) {
printf("%d - cpu: %d gpu: %d\n", i, sumMatrix[i], cpuSumMatrix[i]);
errors++;
}
}
if (errors == 0) {
printf("PASSED\n");
} else {
printf("FAILED with %d errors\n", errors);
}
// GPU Free
checkHipErrors(hipFree(gpuMatrix));
checkHipErrors(hipFree(gpuSumMatrix));
// CPU Free
free(Matrix);
free(sumMatrix);
free(cpuSumMatrix);
return errors;
return errors;
}
@@ -25,9 +25,9 @@ THE SOFTWARE.
#ifndef checkHipErrors
#define checkHipErrors(err) __checkHipErrors(err, __FILE__, __LINE__)
inline void __checkHipErrors(hipError_t err, const char *file, const int line) {
inline void __checkHipErrors(hipError_t err, const char* file, const int line) {
if (HIP_SUCCESS != err) {
const char *errorStr = hipGetErrorString(err);
const char* errorStr = hipGetErrorString(err);
fprintf(stderr,
"checkHipErrors() HIP API error = %04d \"%s\" from file <%s>, "
"line %i.\n",