1/* OpenACC Runtime Library: acc_device_host.
2
3   Copyright (C) 2013-2020 Free Software Foundation, Inc.
4
5   Contributed by Mentor Embedded.
6
7   This file is part of the GNU Offloading and Multi Processing Library
8   (libgomp).
9
10   Libgomp is free software; you can redistribute it and/or modify it
11   under the terms of the GNU General Public License as published by
12   the Free Software Foundation; either version 3, or (at your option)
13   any later version.
14
15   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
16   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18   more details.
19
20   Under Section 7 of GPL version 3, you are granted additional
21   permissions described in the GCC Runtime Library Exception, version
22   3.1, as published by the Free Software Foundation.
23
24   You should have received a copy of the GNU General Public License and
25   a copy of the GCC Runtime Library Exception along with this program;
26   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
27   <http://www.gnu.org/licenses/>.  */
28
29#include "libgomp.h"
30#include "oacc-int.h"
31#include "gomp-constants.h"
32
33#include <stdbool.h>
34#include <stddef.h>
35
36static struct gomp_device_descr host_dispatch;
37
38static const char *
39host_get_name (void)
40{
41  return host_dispatch.name;
42}
43
44static unsigned int
45host_get_caps (void)
46{
47  return host_dispatch.capabilities;
48}
49
50static int
51host_get_type (void)
52{
53  return host_dispatch.type;
54}
55
56static int
57host_get_num_devices (void)
58{
59  return 1;
60}
61
62static bool
63host_init_device (int n __attribute__ ((unused)))
64{
65  return true;
66}
67
68static bool
69host_fini_device (int n __attribute__ ((unused)))
70{
71  return true;
72}
73
74static unsigned
75host_version (void)
76{
77  return GOMP_VERSION;
78}
79
80static int
81host_load_image (int n __attribute__ ((unused)),
82		 unsigned v __attribute__ ((unused)),
83		 const void *t __attribute__ ((unused)),
84		 struct addr_pair **r __attribute__ ((unused)))
85{
86  return 0;
87}
88
89static bool
90host_unload_image (int n __attribute__ ((unused)),
91		   unsigned v __attribute__ ((unused)),
92		   const void *t __attribute__ ((unused)))
93{
94  return true;
95}
96
97static void *
98host_alloc (int n __attribute__ ((unused)), size_t s)
99{
100  return gomp_malloc (s);
101}
102
103static bool
104host_free (int n __attribute__ ((unused)), void *p)
105{
106  free (p);
107  return true;
108}
109
110static bool
111host_dev2host (int n __attribute__ ((unused)),
112	       void *h __attribute__ ((unused)),
113	       const void *d __attribute__ ((unused)),
114	       size_t s __attribute__ ((unused)))
115{
116  return true;
117}
118
119static bool
120host_host2dev (int n __attribute__ ((unused)),
121	       void *d __attribute__ ((unused)),
122	       const void *h __attribute__ ((unused)),
123	       size_t s __attribute__ ((unused)))
124{
125  return true;
126}
127
128static void
129host_run (int n __attribute__ ((unused)), void *fn_ptr, void *vars,
130	  void **args __attribute__((unused)))
131{
132  void (*fn)(void *) = (void (*)(void *)) fn_ptr;
133
134  fn (vars);
135}
136
137static void
138host_openacc_exec (void (*fn) (void *),
139		   size_t mapnum __attribute__ ((unused)),
140		   void **hostaddrs,
141		   void **devaddrs __attribute__ ((unused)),
142		   unsigned *dims __attribute__ ((unused)),
143		   void *targ_mem_desc __attribute__ ((unused)))
144{
145  fn (hostaddrs);
146}
147
148static void
149host_openacc_async_exec (void (*fn) (void *),
150			 size_t mapnum __attribute__ ((unused)),
151			 void **hostaddrs,
152			 void **devaddrs __attribute__ ((unused)),
153			 unsigned *dims __attribute__ ((unused)),
154			 void *targ_mem_desc __attribute__ ((unused)),
155			 struct goacc_asyncqueue *aq __attribute__ ((unused)))
156{
157  fn (hostaddrs);
158}
159
160static int
161host_openacc_async_test (struct goacc_asyncqueue *aq __attribute__ ((unused)))
162{
163  return 1;
164}
165
166static bool
167host_openacc_async_synchronize (struct goacc_asyncqueue *aq
168				__attribute__ ((unused)))
169{
170  return true;
171}
172
173static bool
174host_openacc_async_serialize (struct goacc_asyncqueue *aq1
175			      __attribute__ ((unused)),
176			      struct goacc_asyncqueue *aq2
177			      __attribute__ ((unused)))
178{
179  return true;
180}
181
182static bool
183host_openacc_async_host2dev (int ord __attribute__ ((unused)),
184			     void *dst __attribute__ ((unused)),
185			     const void *src __attribute__ ((unused)),
186			     size_t n __attribute__ ((unused)),
187			     struct goacc_asyncqueue *aq
188			     __attribute__ ((unused)))
189{
190  return true;
191}
192
193static bool
194host_openacc_async_dev2host (int ord __attribute__ ((unused)),
195			     void *dst __attribute__ ((unused)),
196			     const void *src __attribute__ ((unused)),
197			     size_t n __attribute__ ((unused)),
198			     struct goacc_asyncqueue *aq
199			     __attribute__ ((unused)))
200{
201  return true;
202}
203
204static void
205host_openacc_async_queue_callback (struct goacc_asyncqueue *aq
206				   __attribute__ ((unused)),
207				   void (*callback_fn)(void *)
208				   __attribute__ ((unused)),
209				   void *userptr __attribute__ ((unused)))
210{
211}
212
213static struct goacc_asyncqueue *
214host_openacc_async_construct (int device __attribute__((unused)))
215{
216  /* Non-NULL 0xffff... value as opaque dummy.  */
217  return (struct goacc_asyncqueue *) -1;
218}
219
220static bool
221host_openacc_async_destruct (struct goacc_asyncqueue *aq
222			     __attribute__ ((unused)))
223{
224  return true;
225}
226
227static union goacc_property_value
228host_openacc_get_property (int n, enum goacc_property prop)
229{
230  union goacc_property_value nullval = { .val = 0 };
231
232  if (n >= host_get_num_devices ())
233    return nullval;
234
235  switch (prop)
236    {
237    case GOACC_PROPERTY_NAME:
238      return (union goacc_property_value) { .ptr = "GOMP" };
239    case GOACC_PROPERTY_VENDOR:
240      return (union goacc_property_value) { .ptr = "GNU" };
241    case GOACC_PROPERTY_DRIVER:
242      return (union goacc_property_value) { .ptr = VERSION };
243    case GOACC_PROPERTY_MEMORY:
244    case GOACC_PROPERTY_FREE_MEMORY:
245    default:
246      return nullval;
247    }
248}
249
250static void *
251host_openacc_create_thread_data (int ord __attribute__ ((unused)))
252{
253  return NULL;
254}
255
256static void
257host_openacc_destroy_thread_data (void *tls_data __attribute__ ((unused)))
258{
259}
260
261static struct gomp_device_descr host_dispatch =
262  {
263    .name = "host",
264    .capabilities = (GOMP_OFFLOAD_CAP_SHARED_MEM
265		     | GOMP_OFFLOAD_CAP_NATIVE_EXEC
266		     | GOMP_OFFLOAD_CAP_OPENACC_200),
267    .target_id = 0,
268    .type = OFFLOAD_TARGET_TYPE_HOST,
269
270    .get_name_func = host_get_name,
271    .get_caps_func = host_get_caps,
272    .get_type_func = host_get_type,
273    .get_num_devices_func = host_get_num_devices,
274    .init_device_func = host_init_device,
275    .fini_device_func = host_fini_device,
276    .version_func = host_version,
277    .load_image_func = host_load_image,
278    .unload_image_func = host_unload_image,
279    .alloc_func = host_alloc,
280    .free_func = host_free,
281    .dev2host_func = host_dev2host,
282    .host2dev_func = host_host2dev,
283    .run_func = host_run,
284
285    .mem_map = { NULL },
286    /* .lock initialized in goacc_host_init.  */
287    .state = GOMP_DEVICE_UNINITIALIZED,
288
289    .openacc = {
290      .exec_func = host_openacc_exec,
291
292      .create_thread_data_func = host_openacc_create_thread_data,
293      .destroy_thread_data_func = host_openacc_destroy_thread_data,
294
295      .async = {
296	.construct_func = host_openacc_async_construct,
297	.destruct_func = host_openacc_async_destruct,
298	.test_func = host_openacc_async_test,
299	.synchronize_func = host_openacc_async_synchronize,
300	.serialize_func = host_openacc_async_serialize,
301	.queue_callback_func = host_openacc_async_queue_callback,
302	.exec_func = host_openacc_async_exec,
303	.dev2host_func = host_openacc_async_dev2host,
304	.host2dev_func = host_openacc_async_host2dev,
305      },
306
307      .get_property_func = host_openacc_get_property,
308
309      .cuda = {
310	.get_current_device_func = NULL,
311	.get_current_context_func = NULL,
312	.get_stream_func = NULL,
313	.set_stream_func = NULL,
314      }
315    }
316  };
317
318/* Initialize and register this device type.  */
319void
320goacc_host_init (void)
321{
322  gomp_mutex_init (&host_dispatch.lock);
323  goacc_register (&host_dispatch);
324}
325