/* Copyright (C) 2019-2024 Free Software Foundation, Inc. Copyright (C) 2019-2024 Advanced Micro Devices, Inc. All rights reserved. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #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); \ } \ } __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; /* location line */ for (size_t i = offset; i < N; i += stride) C_d[i] = __bitextract_u32(A_d[i], 8, 4); } 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); int deviceId; CHECK (hipGetDevice (&deviceId)); hipDeviceProp_t props; CHECK (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); CHECK (A_h == 0 ? hipErrorMemoryAllocation : hipSuccess); C_h = (uint32_t *) malloc (Nbytes); CHECK (C_h == 0 ? hipErrorMemoryAllocation : hipSuccess); 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); CHECK (hipMalloc (&A_d, Nbytes)); CHECK (hipMalloc (&C_d, Nbytes)); printf ("info: copy Host2Device\n"); CHECK (hipMemcpy (A_d, A_h, Nbytes, hipMemcpyHostToDevice)); printf ("info: launch 'bit_extract_kernel' \n"); const unsigned blocks = 4; const unsigned threadsPerBlock = 256; hipLaunchKernelGGL (bit_extract_kernel, 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++) { 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]); CHECK (hipErrorUnknown); } } printf ("PASSED!\n"); }