(git:39fe4c4)
Loading...
Searching...
No Matches
offload_library.c
Go to the documentation of this file.
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
32static int chosen_device_id = -1;
33
34const 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 ******************************************************************************/
53void 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}
67
68/*******************************************************************************
69 * \brief Returns the number of available devices.
70 * \author Ole Schuett
71 ******************************************************************************/
73 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 return count;
82}
83
84/*******************************************************************************
85 * \brief Selects the chosen device to be used.
86 * \author Ole Schuett
87 ******************************************************************************/
88void 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 ******************************************************************************/
95
96/*******************************************************************************
97 * \brief Activates the device selected via offload_set_chosen_device()
98 * \author Ole Schuett
99 ******************************************************************************/
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}
111
112/*******************************************************************************
113 * \brief Starts a timing range.
114 * \author Ole Schuett
115 ******************************************************************************/
116void 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 (void)message; // mark argument as used
140}
141
142/*******************************************************************************
143 * \brief Ends a timing range.
144 * \author Ole Schuett
145 ******************************************************************************/
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}
155
156/*******************************************************************************
157 * \brief Gets free and total device memory.
158 * \author Ole Schuett
159 ******************************************************************************/
160void 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 *free = *total = 0;
169#endif
170}
171
172/*******************************************************************************
173 * \brief Allocate pinned memory (or simple malloc when there is no gpu)
174 ******************************************************************************/
175int offload_host_malloc(void **ptr__, const size_t size__) {
176#if defined(__OFFLOAD)
177 offloadMallocHost(ptr__, size__); /* checked */
178 return offloadSuccess;
179#else
180 *ptr__ = malloc(size__);
181 return EXIT_SUCCESS;
182#endif
183}
184
185/*******************************************************************************
186 * \brief free pinned memory (or simple free when there is no gpu)
187 ******************************************************************************/
188int offload_host_free(void *ptr__) {
189#if defined(__OFFLOAD)
190 offloadFreeHost(ptr__); /* checked */
191 return offloadSuccess;
192#else
193 free(ptr__);
194 return EXIT_SUCCESS;
195#endif
196}
197
198// EOF
static unsigned int hash(const dbm_task_t task)
Private hash function based on Szudzik's elegant pairing. Using unsigned int to return a positive num...
static void const int const int i
const uint32_t colormap[]
int offload_get_device_count(void)
Returns the number of available devices.
void offload_activate_chosen_device(void)
Activates the device selected via offload_set_chosen_device()
int offload_host_free(void *ptr__)
free pinned memory (or simple free when there is no gpu)
static int chosen_device_id
void offload_timestop(void)
Ends a timing range.
int offload_get_chosen_device(void)
Returns the chosen device.
void offload_init(void)
Initialize runtime.
int offload_host_malloc(void **ptr__, const size_t size__)
Allocate pinned memory (or simple malloc when there is no gpu)