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
|