LCOV - code coverage report
Current view: top level - src/offload - offload_library.c (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:85b8a9b) Lines: 58.3 % 24 14
Test Date: 2026-06-14 06:48:14 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 <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        20652 : 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        20652 : }
      67              : 
      68              : /*******************************************************************************
      69              :  * \brief Returns the number of available devices.
      70              :  * \author Ole Schuett
      71              :  ******************************************************************************/
      72        10328 : int offload_get_device_count(void) {
      73        10328 :   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        10328 :   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      1954514 : void offload_activate_chosen_device(void) {
     101      1954514 :   if (chosen_device_id < 0) {
     102      1954514 :     return;
     103              :   }
     104              : #if defined(__OFFLOAD_CUDA)
     105              :   OFFLOAD_CHECK(cudaSetDevice(chosen_device_id));
     106              : #elif defined(__OFFLOAD_HIP)
     107              :   OFFLOAD_CHECK(hipSetDevice(chosen_device_id));
     108              : #elif defined(__OFFLOAD_OPENCL)
     109              :   OFFLOAD_CHECK(libxstream_device_set_active(chosen_device_id));
     110              : #endif
     111              : }
     112              : 
     113              : /*******************************************************************************
     114              :  * \brief Starts a timing range.
     115              :  * \author Ole Schuett
     116              :  ******************************************************************************/
     117   1930427051 : void offload_timeset(const char *message) {
     118              : #if defined(__OFFLOAD_PROFILING)
     119              : #if defined(__OFFLOAD_CUDA)
     120              :   // colors are picked based on a (very simple) hash value of the message
     121              :   int hash = 0;
     122              :   for (size_t i = 0; i < strlen(message); i++) {
     123              :     hash += i * message[i] * message[i];
     124              :   }
     125              :   nvtxEventAttributes_t eventAttrib = {0};
     126              :   eventAttrib.version = NVTX_VERSION;
     127              :   eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
     128              :   eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
     129              :   eventAttrib.message.ascii = message;
     130              :   eventAttrib.colorType = NVTX_COLOR_ARGB;
     131              :   eventAttrib.color = colormap[hash % 14];
     132              :   eventAttrib.payloadType = NVTX_PAYLOAD_TYPE_INT64;
     133              :   eventAttrib.payload.llValue = 123;
     134              :   eventAttrib.category = 42;
     135              :   nvtxRangePushEx(&eventAttrib);
     136              : #elif defined(__OFFLOAD_HIP) && defined(__HIP_PLATFORM_AMD__)
     137              :   roctxRangePushA(message);
     138              : #endif
     139              : #endif
     140   1930427051 :   (void)message; // mark argument as used
     141   1930427051 : }
     142              : 
     143              : /*******************************************************************************
     144              :  * \brief Ends a timing range.
     145              :  * \author Ole Schuett
     146              :  ******************************************************************************/
     147   1930427051 : void offload_timestop(void) {
     148              : #if defined(__OFFLOAD_PROFILING)
     149              : #if defined(__OFFLOAD_CUDA)
     150              :   nvtxRangePop();
     151              : #elif defined(__OFFLOAD_HIP) && defined(__HIP_PLATFORM_AMD__)
     152              :   roctxRangePop();
     153              : #endif
     154              : #endif
     155   1930427051 : }
     156              : 
     157              : /*******************************************************************************
     158              :  * \brief Gets free and total device memory.
     159              :  * \author Ole Schuett
     160              :  ******************************************************************************/
     161            0 : void offload_mem_info(size_t *free, size_t *total) {
     162              : #if defined(__OFFLOAD_CUDA)
     163              :   OFFLOAD_CHECK(cudaMemGetInfo(free, total));
     164              : #elif defined(__OFFLOAD_HIP)
     165              :   OFFLOAD_CHECK(hipMemGetInfo(free, total));
     166              : #elif defined(__OFFLOAD_OPENCL)
     167              :   OFFLOAD_CHECK(libxstream_mem_info(free, total));
     168              : #else
     169            0 :   *free = *total = 0;
     170              : #endif
     171            0 : }
     172              : 
     173            0 : int offload_host_malloc(void **ptr__, const size_t size__) {
     174              : #if defined(__OFFLOAD)
     175              :   if (chosen_device_id >= 0) {
     176              :     offloadMallocHost(ptr__, size__); /* checked */
     177              :     return offloadSuccess;
     178              :   }
     179              : #endif
     180            0 :   *ptr__ = malloc(size__);
     181            0 :   return EXIT_SUCCESS;
     182              : }
     183              : 
     184            0 : int offload_host_free(void *ptr__) {
     185              : #if defined(__OFFLOAD)
     186              :   if (chosen_device_id >= 0) {
     187              :     offloadFreeHost(ptr__); /* checked */
     188              :     return offloadSuccess;
     189              :   }
     190              : #endif
     191            0 :   free(ptr__);
     192            0 :   return EXIT_SUCCESS;
     193              : }
     194              : 
     195              : // EOF
        

Generated by: LCOV version 2.0-1