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