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_buffer.h"
8 : #include "offload_library.h"
9 : #include "offload_mempool.h"
10 : #include "offload_runtime.h"
11 :
12 : #include <assert.h>
13 : #include <stdio.h>
14 : #include <stdlib.h>
15 :
16 : #if 1
17 : #define OFFLOAD_BUFFER_MEMPOOL
18 : #endif
19 :
20 : /*******************************************************************************
21 : * \brief Internal routine to deallocate given buffer.
22 : * \author Hans Pabst
23 : ******************************************************************************/
24 304497 : static void offload_free_buffer_internal(offload_buffer *buffer) {
25 304497 : assert(NULL != buffer);
26 : #if defined(OFFLOAD_BUFFER_MEMPOOL)
27 304497 : if (NULL != buffer->host_buffer &&
28 303995 : buffer->host_buffer != buffer->device_buffer) {
29 303995 : offload_mempool_host_free(buffer->host_buffer);
30 : }
31 304497 : if (NULL != buffer->device_buffer) {
32 303995 : offload_mempool_device_free(buffer->device_buffer);
33 : }
34 : #elif defined(__OFFLOAD)
35 : if (NULL != buffer->host_buffer &&
36 : buffer->host_buffer != buffer->device_buffer) {
37 : offloadFreeHost(buffer->host_buffer);
38 : }
39 : if (NULL != buffer->device_buffer) {
40 : offloadFree(buffer->device_buffer);
41 : }
42 : #else
43 : free(buffer->host_buffer);
44 : assert(NULL == buffer->device_buffer);
45 : #endif
46 304497 : }
47 :
48 : /*******************************************************************************
49 : * \brief Allocates a buffer (NULL or valid) with the given number of elements.
50 : * \author Ole Schuett and Hans Pabst
51 : ******************************************************************************/
52 317397 : void offload_create_buffer(const int length, offload_buffer **buffer) {
53 317397 : const size_t requested_size = sizeof(double) * length;
54 :
55 317397 : if (*buffer != NULL) {
56 13088 : if (0 == requested_size) {
57 88 : offload_free_buffer_internal(*buffer);
58 88 : (*buffer)->size = 0;
59 88 : (*buffer)->host_buffer = NULL;
60 88 : (*buffer)->device_buffer = NULL;
61 88 : return;
62 13000 : } else if (requested_size <= (*buffer)->size) {
63 : return; // reuse existing buffer
64 : } else {
65 100 : offload_free_buffer_internal(*buffer);
66 : }
67 : } else {
68 304309 : (*buffer) = malloc(sizeof(offload_buffer));
69 304309 : assert(NULL != *buffer);
70 : }
71 :
72 304409 : (*buffer)->size = requested_size;
73 304409 : (*buffer)->host_buffer = NULL;
74 304409 : (*buffer)->device_buffer = NULL;
75 304409 : if (0 == requested_size) {
76 : return;
77 : }
78 : #if defined(OFFLOAD_BUFFER_MEMPOOL)
79 : #if !defined(__OFFLOAD_UNIFIED_MEMORY)
80 303995 : (*buffer)->host_buffer = offload_mempool_host_malloc(requested_size);
81 : #endif
82 303995 : (*buffer)->device_buffer = offload_mempool_device_malloc(requested_size);
83 : #elif defined(__OFFLOAD)
84 : offload_activate_chosen_device();
85 : #if !defined(__OFFLOAD_UNIFIED_MEMORY)
86 : offloadMallocHost((void **)&(*buffer)->host_buffer, requested_size);
87 : #endif
88 : offloadMalloc((void **)&(*buffer)->device_buffer, requested_size);
89 : #else
90 : (*buffer)->host_buffer = malloc(requested_size);
91 : (*buffer)->device_buffer = NULL;
92 : #endif
93 303995 : if (NULL == (*buffer)->host_buffer) { /* unified memory */
94 0 : (*buffer)->host_buffer = (*buffer)->device_buffer;
95 : }
96 : }
97 :
98 : /*******************************************************************************
99 : * \brief Deallocate given buffer.
100 : * \author Ole Schuett
101 : ******************************************************************************/
102 304309 : void offload_free_buffer(offload_buffer *buffer) {
103 304309 : if (NULL != buffer) {
104 304309 : offload_free_buffer_internal(buffer);
105 304309 : free(buffer);
106 : }
107 304309 : }
108 :
109 : /*******************************************************************************
110 : * \brief Returns a pointer to the host buffer (Fortran API).
111 : * \author Ole Schuett
112 : ******************************************************************************/
113 316482 : double *offload_get_buffer_host_pointer(offload_buffer *buffer) {
114 316482 : assert(NULL != buffer);
115 316482 : return buffer->host_buffer;
116 : }
117 :
118 : // EOF
|