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
|