/* * Copyright (c) Advanced Micro Devices, Inc., or its affiliates. * * SPDX-License-Identifier: MIT */ #include constexpr int WIDTH = 16; constexpr int HEIGHT = 16; constexpr int NUM = WIDTH * HEIGHT; constexpr int THREADS_PER_BLOCK_X = 8; constexpr int THREADS_PER_BLOCK_Y = 8; template __global__ void vectoradd_float(T* a, const T* bm, int width, int height) { int x = blockDim.x * blockIdx.x + threadIdx.x; int y = blockDim.y * blockIdx.y + threadIdx.y; int i = y * width + x; if (i < (width * height)) { a[i] = __ldg(&bm[i]); } } int2 make_vector2(int a) { return make_int2(a, a); } char2 make_vector2(signed char a) { return make_char2(a, a); } char4 make_vector4(signed char a) { return make_char4(a, a, a, a); } short2 make_vector2(short a) { return make_short2(a, a); } ushort2 make_vector2(unsigned short a) { return make_ushort2(a, a); } short4 make_vector4(short a) { return make_short4(a, a, a, a); } int4 make_vector4(int a) { return make_int4(a, a, a, a); } uint2 make_vector2(unsigned int a) { return make_uint2(a, a); } uint4 make_vector4(unsigned int a) { return make_uint4(a, a, a, a); } float2 make_vector2(float a) { return make_float2(a, a); } float4 make_vector4(float a) { return make_float4(a, a, a, a); } uchar2 make_vector2(unsigned char a) { return make_uchar2(a, a); } uchar4 make_vector4(unsigned char a) { return make_uchar4(a, a, a, a); } double2 make_vector2(double a) { return make_double2(a, a); } template int dataTypesRun() { T* hostA; T* hostB; T* deviceA; T* deviceB; int i; int errors; hostA = (T*)malloc(NUM * sizeof(T)); hostB = (T*)malloc(NUM * sizeof(T)); // initialize the input data for (i = 0; i < NUM; i++) { hostB[i] = (U)i; } HIP_CHECK(hipMalloc((void**)&deviceA, NUM * sizeof(T))); HIP_CHECK(hipMalloc((void**)&deviceB, NUM * sizeof(T))); HIP_CHECK(hipMemcpy(deviceB, hostB, NUM * sizeof(T), hipMemcpyHostToDevice)); hipLaunchKernelGGL(vectoradd_float, dim3(WIDTH / THREADS_PER_BLOCK_X, HEIGHT / THREADS_PER_BLOCK_Y), dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, deviceA, static_cast(deviceB), WIDTH, HEIGHT); HIP_CHECK(hipGetLastError()); HIP_CHECK(hipMemcpy(hostA, deviceA, NUM * sizeof(T), hipMemcpyDeviceToHost)); // verify the results errors = 0; for (i = 0; i < NUM; i++) { if (hostA[i] != (hostB[i])) { errors++; } } HIP_CHECK(hipFree(deviceA)); HIP_CHECK(hipFree(deviceB)); free(hostA); free(hostB); return errors; } template int dataTypesRun2() { T* hostA; T* hostB; T* deviceA; T* deviceB; int i; int errors; hostA = (T*)malloc(NUM * sizeof(T)); hostB = (T*)malloc(NUM * sizeof(T)); // initialize the input data for (i = 0; i < NUM; i++) { hostB[i] = make_vector2((U)i); } HIP_CHECK(hipMalloc((void**)&deviceA, NUM * sizeof(T))); HIP_CHECK(hipMalloc((void**)&deviceB, NUM * sizeof(T))); HIP_CHECK(hipMemcpy(deviceB, hostB, NUM * sizeof(T), hipMemcpyHostToDevice)); hipLaunchKernelGGL(vectoradd_float, dim3(WIDTH / THREADS_PER_BLOCK_X, HEIGHT / THREADS_PER_BLOCK_Y), dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, deviceA, static_cast(deviceB), WIDTH, HEIGHT); HIP_CHECK(hipGetLastError()); HIP_CHECK(hipMemcpy(hostA, deviceA, NUM * sizeof(T), hipMemcpyDeviceToHost)); // verify the results errors = 0; for (i = 0; i < NUM; i++) { if (hostA[i].x != (hostB[i].x) && hostA[i].y != (hostB[i].y)) { errors++; } } HIP_CHECK(hipFree(deviceA)); HIP_CHECK(hipFree(deviceB)); free(hostA); free(hostB); return errors; } template int dataTypesRun4() { T* hostA; T* hostB; T* deviceA; T* deviceB; int i; int errors; hostA = (T*)malloc(NUM * sizeof(T)); hostB = (T*)malloc(NUM * sizeof(T)); // initialize the input data for (i = 0; i < NUM; i++) { hostB[i] = make_vector4((U)i); } HIP_CHECK(hipMalloc((void**)&deviceA, NUM * sizeof(T))); HIP_CHECK(hipMalloc((void**)&deviceB, NUM * sizeof(T))); HIP_CHECK(hipMemcpy(deviceB, hostB, NUM * sizeof(T), hipMemcpyHostToDevice)); hipLaunchKernelGGL(vectoradd_float, dim3(WIDTH / THREADS_PER_BLOCK_X, HEIGHT / THREADS_PER_BLOCK_Y), dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0, 0, deviceA, static_cast(deviceB), WIDTH, HEIGHT); HIP_CHECK(hipGetLastError()); HIP_CHECK(hipMemcpy(hostA, deviceA, NUM * sizeof(T), hipMemcpyDeviceToHost)); // verify the results errors = 0; for (i = 0; i < NUM; i++) { if (hostA[i].x != (hostB[i].x) && hostA[i].y != (hostB[i].y) && hostA[i].z != (hostB[i].z) && hostA[i].w != (hostB[i].w)) { errors++; } } HIP_CHECK(hipFree(deviceA)); HIP_CHECK(hipFree(deviceB)); free(hostA); free(hostB); return errors; } HIP_TEST_CASE(Unit_ldg) { using namespace std; int errors; errors = dataTypesRun() | dataTypesRun() | dataTypesRun() | dataTypesRun() | dataTypesRun() | dataTypesRun() | dataTypesRun() | dataTypesRun() | dataTypesRun() | dataTypesRun() | dataTypesRun() | dataTypesRun() | dataTypesRun(); REQUIRE(errors == 0); errors = dataTypesRun2() | dataTypesRun2() | dataTypesRun2() | dataTypesRun2() | dataTypesRun2() | dataTypesRun2() | dataTypesRun2() | dataTypesRun2(); REQUIRE(errors == 0); errors = dataTypesRun4() | dataTypesRun4() | dataTypesRun4() | dataTypesRun4() | dataTypesRun4() | dataTypesRun4(); REQUIRE(errors == 0); }