LCOV - code coverage report
Current view: top level - src/offload - offload_library.c (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:c24029e) Lines: 56.5 % 23 13
Test Date: 2026-07-04 06:36:57 Functions: 60.0 % 10 6

            Line data    Source code
       1              : /*----------------------------------------------------------------------------*/
       2              : /*  CP2K: A general program to perform molecular dynamics simulations         */
       3              : /*  Copyright 2000-2026 CP2K developers group <https://cp2k.org>              */
       4              : /*                                                                            */
       5              : /*  SPDX-License-Identifier: BSD-3-Clause                                     */
       6              : /*----------------------------------------------------------------------------*/
       7              : #include "offload_library.h"
       8              : #include "offload_runtime.h"
       9              : 
      10              : #include <assert.h>
      11              : #include <stdint.h>
      12              : #include <stdio.h>
      13              : #include <stdlib.h>
      14              : #include <string.h>
      15              : 
      16              : #if defined(__OFFLOAD_CUDA)
      17              : #include <cuda.h>
      18              : #elif defined(__OFFLOAD_HIP)
      19              : #include <hip/hip_runtime_api.h>
      20              : #elif defined(__OFFLOAD_OPENCL)
      21              : #include <libxstream/libxstream.h>
      22              : #endif
      23              : 
      24              : #if defined(__OFFLOAD_PROFILING)
      25              : #if defined(__OFFLOAD_CUDA)
      26              : #include <nvtx3/nvToolsExt.h>
      27              : #elif defined(__OFFLOAD_HIP) && defined(__HIP_PLATFORM_AMD__)
      28              : #include <roctracer/roctx.h>
      29              : #endif
      30              : #endif
      31              : 
      32              : static int chosen_device_id = -1;
      33              : 
      34              : const uint32_t colormap[] = {0xFFFFFF00,  // Yellow
      35              :                              0xFFFF00FF,  // Fuchsia
      36              :                              0xFFFF0000,  // Red
      37              :                              0xFFC0C0C0,  // Silver
      38              :                              0xFF808080,  // Gray
      39              :                              0xFF808000,  // Olive
      40              :                              0xFF800080,  // Purple
      41              :                              0xFF800000,  // Maroon
      42              :                              0xFF00FFFF,  // Aqua
      43              :                              0xFF00FF00,  // Lime
      44              :                              0xFF008080,  // Teal
      45              :                              0xFF008000,  // Green
      46              :                              0xFF0000FF,  // Blue
      47              :                              0xFF000080}; // Navy
      48              : 
      49              : /*******************************************************************************
      50              :  * \brief Initialize runtime.
      51              :  * \author Rocco Meli
      52              :  ******************************************************************************/
      53        20784 : void offload_init(void) {
      54              : #if defined(__OFFLOAD_CUDA)
      55              :   CUresult error = cuInit(0);
      56              :   if (error != CUDA_SUCCESS) {
      57              :     fprintf(stderr, "ERROR: %s %d %s %d\n", "cuInit failed with error: ", error,
      58              :             __FILE__, __LINE__);
      59              :     abort();
      60              :   }
      61              : #elif defined(__OFFLOAD_HIP)
      62              :   OFFLOAD_CHECK(hipInit(0));
      63              : #elif defined(__OFFLOAD_OPENCL)
      64              :   OFFLOAD_CHECK(libxstream_init());
      65              : #endif
      66        20784 : }
      67              : 
      68              : /*******************************************************************************
      69              :  * \brief Returns the number of available devices.
      70              :  * \author Ole Schuett
      71              :  ******************************************************************************/
      72        10394 : int offload_get_device_count(void) {
      73        10394 :   int count = 0;
      74              : #if defined(__OFFLOAD_CUDA)
      75              :   OFFLOAD_CHECK(cudaGetDeviceCount(&count));
      76              : #elif defined(__OFFLOAD_HIP)
      77              :   OFFLOAD_CHECK(hipGetDeviceCount(&count));
      78              : #elif defined(__OFFLOAD_OPENCL)
      79              :   OFFLOAD_CHECK(libxstream_device_count(&count));
      80              : #endif
      81        10394 :   return count;
      82              : }
      83              : 
      84              : /*******************************************************************************
      85              :  * \brief Selects the chosen device to be used.
      86              :  * \author Ole Schuett
      87              :  ******************************************************************************/
      88            2 : void offload_set_chosen_device(int device_id) { chosen_device_id = device_id; }
      89              : 
      90              : /*******************************************************************************
      91              :  * \brief Returns the chosen device.
      92              :  * \author Ole Schuett
      93              :  ******************************************************************************/
      94            0 : int offload_get_chosen_device(void) { return chosen_device_id; }
      95              : 
      96              : /*******************************************************************************
      97              :  * \brief Activates the device selected via offload_set_chosen_device()
      98              :  * \author Ole Schuett
      99              :  ******************************************************************************/
     100      1956070 : void offload_activate_chosen_device(void) {
     101              : #if defined(__OFFLOAD_CUDA)
     102              :   OFFLOAD_CHECK(cudaSetDevice(chosen_device_id));
     103              : #elif defined(__OFFLOAD_HIP)
     104              :   OFFLOAD_CHECK(hipSetDevice(chosen_device_id));
     105              : #elif defined(__OFFLOAD_OPENCL)
     106              :   if (chosen_device_id >= 0) {
     107              :     OFFLOAD_CHECK(libxstream_device_set_active(chosen_device_id));
     108              :   }
     109              : #endif
     110      1956070 : }
     111              : 
     112              : /*******************************************************************************
     113              :  * \brief Starts a timing range.
     114              :  * \author Ole Schuett
     115              :  ******************************************************************************/
     116   1933447131 : void offload_timeset(const char *message) {
     117              : #if defined(__OFFLOAD_PROFILING)
     118              : #if defined(__OFFLOAD_CUDA)
     119              :   // colors are picked based on a (very simple) hash value of the message
     120              :   int hash = 0;
     121              :   for (size_t i = 0; i < strlen(message); i++) {
     122              :     hash += i * message[i] * message[i];
     123              :   }
     124              :   nvtxEventAttributes_t eventAttrib = {0};
     125              :   eventAttrib.version = NVTX_VERSION;
     126              :   eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
     127              :   eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
     128              :   eventAttrib.message.ascii = message;
     129              :   eventAttrib.colorType = NVTX_COLOR_ARGB;
     130              :   eventAttrib.color = colormap[hash % 14];
     131              :   eventAttrib.payloadType = NVTX_PAYLOAD_TYPE_INT64;
     132              :   eventAttrib.payload.llValue = 123;
     133              :   eventAttrib.category = 42;
     134              :   nvtxRangePushEx(&eventAttrib);
     135              : #elif defined(__OFFLOAD_HIP) && defined(__HIP_PLATFORM_AMD__)
     136              :   roctxRangePushA(message);
     137              : #endif
     138              : #endif
     139   1933447131 :   (void)message; // mark argument as used
     140   1933447131 : }
     141              : 
     142              : /*******************************************************************************
     143              :  * \brief Ends a timing range.
     144              :  * \author Ole Schuett
     145              :  ******************************************************************************/
     146   1933447131 : void offload_timestop(void) {
     147              : #if defined(__OFFLOAD_PROFILING)
     148              : #if defined(__OFFLOAD_CUDA)
     149              :   nvtxRangePop();
     150              : #elif defined(__OFFLOAD_HIP) && defined(__HIP_PLATFORM_AMD__)
     151              :   roctxRangePop();
     152              : #endif
     153              : #endif
     154   1933447131 : }
     155              : 
     156              : /*******************************************************************************
     157              :  * \brief Gets free and total device memory.
     158              :  * \author Ole Schuett
     159              :  ******************************************************************************/
     160            0 : void offload_mem_info(size_t *free, size_t *total) {
     161              : #if defined(__OFFLOAD_CUDA)
     162              :   OFFLOAD_CHECK(cudaMemGetInfo(free, total));
     163              : #elif defined(__OFFLOAD_HIP)
     164              :   OFFLOAD_CHECK(hipMemGetInfo(free, total));
     165              : #elif defined(__OFFLOAD_OPENCL)
     166              :   OFFLOAD_CHECK(libxstream_mem_info(free, total));
     167              : #else
     168            0 :   *free = *total = 0;
     169              : #endif
     170            0 : }
     171              : 
     172              : /*******************************************************************************
     173              :  * \brief Allocate pinned memory (or simple malloc when there is no gpu)
     174              :  ******************************************************************************/
     175            0 : int offload_host_malloc(void **ptr__, const size_t size__) {
     176              : #if defined(__OFFLOAD)
     177              :   offloadMallocHost(ptr__, size__); /* checked */
     178              :   return offloadSuccess;
     179              : #else
     180            0 :   *ptr__ = malloc(size__);
     181            0 :   return EXIT_SUCCESS;
     182              : #endif
     183              : }
     184              : 
     185              : /*******************************************************************************
     186              :  * \brief free pinned memory (or simple free when there is no gpu)
     187              :  ******************************************************************************/
     188            0 : int offload_host_free(void *ptr__) {
     189              : #if defined(__OFFLOAD)
     190              :   offloadFreeHost(ptr__); /* checked */
     191              :   return offloadSuccess;
     192              : #else
     193            0 :   free(ptr__);
     194            0 :   return EXIT_SUCCESS;
     195              : #endif
     196              : }
     197              : 
     198              : // EOF
        

Generated by: LCOV version 2.0-1