(git:be2a531)
Loading...
Searching...
No Matches
offload_buffer.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_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 ******************************************************************************/
25 assert(NULL != buffer);
26#if defined(OFFLOAD_BUFFER_MEMPOOL)
27 if (NULL != buffer->host_buffer &&
28 buffer->host_buffer != buffer->device_buffer) {
30 }
31 if (NULL != 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}
47
48/*******************************************************************************
49 * \brief Allocates a buffer (NULL or valid) with the given number of elements.
50 * \author Ole Schuett and Hans Pabst
51 ******************************************************************************/
52void offload_create_buffer(const int length, offload_buffer **buffer) {
53 const size_t requested_size = sizeof(double) * length;
54
55 if (*buffer != NULL) {
56 if (0 == requested_size) {
58 (*buffer)->size = 0;
59 (*buffer)->host_buffer = NULL;
60 (*buffer)->device_buffer = NULL;
61 return;
62 } else if (requested_size <= (*buffer)->size) {
63 return; // reuse existing buffer
64 } else {
66 }
67 } else {
68 (*buffer) = malloc(sizeof(offload_buffer));
69 assert(NULL != *buffer);
70 }
71
72 (*buffer)->size = requested_size;
73 (*buffer)->host_buffer = NULL;
74 (*buffer)->device_buffer = NULL;
75 if (0 == requested_size) {
76 return;
77 }
78#if defined(OFFLOAD_BUFFER_MEMPOOL)
79#if !defined(__OFFLOAD_UNIFIED_MEMORY)
80 (*buffer)->host_buffer = offload_mempool_host_malloc(requested_size);
81#endif
82 (*buffer)->device_buffer = offload_mempool_device_malloc(requested_size);
83#elif defined(__OFFLOAD)
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 if (NULL == (*buffer)->host_buffer) { /* unified memory */
94 (*buffer)->host_buffer = (*buffer)->device_buffer;
95 }
96}
97
98/*******************************************************************************
99 * \brief Deallocate given buffer.
100 * \author Ole Schuett
101 ******************************************************************************/
103 if (NULL != buffer) {
105 free(buffer);
106 }
107}
108
109/*******************************************************************************
110 * \brief Returns a pointer to the host buffer (Fortran API).
111 * \author Ole Schuett
112 ******************************************************************************/
114 assert(NULL != buffer);
115 return buffer->host_buffer;
116}
117
118/*******************************************************************************
119 * \brief Returns a pointer to the device buffer (Fortran API).
120 * \author Samal Bibek
121 ******************************************************************************/
123 assert(NULL != buffer);
124 return buffer->device_buffer;
125}
126
127/*******************************************************************************
128 * \brief Copy data from host to device (Fortran API).
129 * \author Samal Bibek
130 ******************************************************************************/
131void offload_buffer_h2d(offload_buffer *buffer, const int length) {
132 assert(NULL != buffer);
133#if defined(__OFFLOAD)
134 if (buffer->host_buffer != NULL && buffer->device_buffer != NULL) {
135 const size_t bytes = sizeof(double) * length;
136 offloadMemcpyAsyncHtoD(buffer->device_buffer, buffer->host_buffer, bytes,
137 0);
138 }
139#else
140 (void)length; // no-op on CPU-only builds: host memory is the same store
141#endif
142}
143
144/*******************************************************************************
145 * \brief Copy data from device to host (Fortran API).
146 * \author Samal Bibek
147 ******************************************************************************/
148void offload_buffer_d2h(offload_buffer *buffer, const int length) {
149 assert(NULL != buffer);
150#if defined(__OFFLOAD)
151 if (buffer->host_buffer != NULL && buffer->device_buffer != NULL) {
152 const size_t bytes = sizeof(double) * length;
153 offloadMemcpyAsyncDtoH(buffer->host_buffer, buffer->device_buffer, bytes,
154 0);
155 }
156#else
157 (void)length; // no-op on CPU-only builds: host memory is the same store
158#endif
159}
160
161// EOF
double * offload_get_buffer_host_pointer(offload_buffer *buffer)
Returns a pointer to the host buffer (Fortran API).
void offload_buffer_h2d(offload_buffer *buffer, const int length)
Copy data from host to device (Fortran API).
void offload_free_buffer(offload_buffer *buffer)
Deallocate given buffer.
static void offload_free_buffer_internal(offload_buffer *buffer)
Internal routine to deallocate given buffer.
double * offload_get_buffer_device_pointer(offload_buffer *buffer)
Returns a pointer to the device buffer (Fortran API).
void offload_buffer_d2h(offload_buffer *buffer, const int length)
Copy data from device to host (Fortran API).
void offload_create_buffer(const int length, offload_buffer **buffer)
Allocates a buffer (NULL or valid) with the given number of elements.
void offload_activate_chosen_device(void)
Activates the device selected via offload_set_chosen_device().
void offload_mempool_host_free(const void *memory)
Internal routine for releasing memory back to the pool.
void offload_mempool_device_free(const void *memory)
Internal routine for releasing memory back to the pool.
void * offload_mempool_host_malloc(const size_t size)
Internal routine for allocating host memory from the pool.
void * offload_mempool_device_malloc(const size_t size)
Internal routine for allocating device memory from the pool.
Internal representation of a buffer.
double * device_buffer
double * host_buffer