annotate libgomp/oacc-mem.c @ 118:fd00160c1b76

ifdef TARGET_64BIT
author mir3636
date Tue, 27 Feb 2018 15:01:35 +0900
parents 04ced10e8804
children 84e7813d76e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* OpenACC Runtime initialization routines
kono
parents:
diff changeset
2
kono
parents:
diff changeset
3 Copyright (C) 2013-2017 Free Software Foundation, Inc.
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 Contributed by Mentor Embedded.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 This file is part of the GNU Offloading and Multi Processing Library
kono
parents:
diff changeset
8 (libgomp).
kono
parents:
diff changeset
9
kono
parents:
diff changeset
10 Libgomp is free software; you can redistribute it and/or modify it
kono
parents:
diff changeset
11 under the terms of the GNU General Public License as published by
kono
parents:
diff changeset
12 the Free Software Foundation; either version 3, or (at your option)
kono
parents:
diff changeset
13 any later version.
kono
parents:
diff changeset
14
kono
parents:
diff changeset
15 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
kono
parents:
diff changeset
17 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
kono
parents:
diff changeset
18 more details.
kono
parents:
diff changeset
19
kono
parents:
diff changeset
20 Under Section 7 of GPL version 3, you are granted additional
kono
parents:
diff changeset
21 permissions described in the GCC Runtime Library Exception, version
kono
parents:
diff changeset
22 3.1, as published by the Free Software Foundation.
kono
parents:
diff changeset
23
kono
parents:
diff changeset
24 You should have received a copy of the GNU General Public License and
kono
parents:
diff changeset
25 a copy of the GCC Runtime Library Exception along with this program;
kono
parents:
diff changeset
26 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
kono
parents:
diff changeset
27 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
28
kono
parents:
diff changeset
29 #include "openacc.h"
kono
parents:
diff changeset
30 #include "config.h"
kono
parents:
diff changeset
31 #include "libgomp.h"
kono
parents:
diff changeset
32 #include "gomp-constants.h"
kono
parents:
diff changeset
33 #include "oacc-int.h"
kono
parents:
diff changeset
34 #include <stdint.h>
kono
parents:
diff changeset
35 #include <string.h>
kono
parents:
diff changeset
36 #include <assert.h>
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 /* Return block containing [H->S), or NULL if not contained. The device lock
kono
parents:
diff changeset
39 for DEV must be locked on entry, and remains locked on exit. */
kono
parents:
diff changeset
40
kono
parents:
diff changeset
41 static splay_tree_key
kono
parents:
diff changeset
42 lookup_host (struct gomp_device_descr *dev, void *h, size_t s)
kono
parents:
diff changeset
43 {
kono
parents:
diff changeset
44 struct splay_tree_key_s node;
kono
parents:
diff changeset
45 splay_tree_key key;
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 node.host_start = (uintptr_t) h;
kono
parents:
diff changeset
48 node.host_end = (uintptr_t) h + s;
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 key = splay_tree_lookup (&dev->mem_map, &node);
kono
parents:
diff changeset
51
kono
parents:
diff changeset
52 return key;
kono
parents:
diff changeset
53 }
kono
parents:
diff changeset
54
kono
parents:
diff changeset
55 /* Return block containing [D->S), or NULL if not contained.
kono
parents:
diff changeset
56 The list isn't ordered by device address, so we have to iterate
kono
parents:
diff changeset
57 over the whole array. This is not expected to be a common
kono
parents:
diff changeset
58 operation. The device lock associated with TGT must be locked on entry, and
kono
parents:
diff changeset
59 remains locked on exit. */
kono
parents:
diff changeset
60
kono
parents:
diff changeset
61 static splay_tree_key
kono
parents:
diff changeset
62 lookup_dev (struct target_mem_desc *tgt, void *d, size_t s)
kono
parents:
diff changeset
63 {
kono
parents:
diff changeset
64 int i;
kono
parents:
diff changeset
65 struct target_mem_desc *t;
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 if (!tgt)
kono
parents:
diff changeset
68 return NULL;
kono
parents:
diff changeset
69
kono
parents:
diff changeset
70 for (t = tgt; t != NULL; t = t->prev)
kono
parents:
diff changeset
71 {
kono
parents:
diff changeset
72 if (t->tgt_start <= (uintptr_t) d && t->tgt_end >= (uintptr_t) d + s)
kono
parents:
diff changeset
73 break;
kono
parents:
diff changeset
74 }
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 if (!t)
kono
parents:
diff changeset
77 return NULL;
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 for (i = 0; i < t->list_count; i++)
kono
parents:
diff changeset
80 {
kono
parents:
diff changeset
81 void * offset;
kono
parents:
diff changeset
82
kono
parents:
diff changeset
83 splay_tree_key k = &t->array[i].key;
kono
parents:
diff changeset
84 offset = d - t->tgt_start + k->tgt_offset;
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 if (k->host_start + offset <= (void *) k->host_end)
kono
parents:
diff changeset
87 return k;
kono
parents:
diff changeset
88 }
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 return NULL;
kono
parents:
diff changeset
91 }
kono
parents:
diff changeset
92
kono
parents:
diff changeset
93 /* OpenACC is silent on how memory exhaustion is indicated. We return
kono
parents:
diff changeset
94 NULL. */
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 void *
kono
parents:
diff changeset
97 acc_malloc (size_t s)
kono
parents:
diff changeset
98 {
kono
parents:
diff changeset
99 if (!s)
kono
parents:
diff changeset
100 return NULL;
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 goacc_lazy_initialize ();
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 struct goacc_thread *thr = goacc_thread ();
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 assert (thr->dev);
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
109 return malloc (s);
kono
parents:
diff changeset
110
kono
parents:
diff changeset
111 return thr->dev->alloc_func (thr->dev->target_id, s);
kono
parents:
diff changeset
112 }
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 /* OpenACC 2.0a (3.2.16) doesn't specify what to do in the event
kono
parents:
diff changeset
115 the device address is mapped. We choose to check if it mapped,
kono
parents:
diff changeset
116 and if it is, to unmap it. */
kono
parents:
diff changeset
117 void
kono
parents:
diff changeset
118 acc_free (void *d)
kono
parents:
diff changeset
119 {
kono
parents:
diff changeset
120 splay_tree_key k;
kono
parents:
diff changeset
121
kono
parents:
diff changeset
122 if (!d)
kono
parents:
diff changeset
123 return;
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 struct goacc_thread *thr = goacc_thread ();
kono
parents:
diff changeset
126
kono
parents:
diff changeset
127 assert (thr && thr->dev);
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 struct gomp_device_descr *acc_dev = thr->dev;
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
132 return free (d);
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 gomp_mutex_lock (&acc_dev->lock);
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 /* We don't have to call lazy open here, as the ptr value must have
kono
parents:
diff changeset
137 been returned by acc_malloc. It's not permitted to pass NULL in
kono
parents:
diff changeset
138 (unless you got that null from acc_malloc). */
kono
parents:
diff changeset
139 if ((k = lookup_dev (acc_dev->openacc.data_environ, d, 1)))
kono
parents:
diff changeset
140 {
kono
parents:
diff changeset
141 void *offset;
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 offset = d - k->tgt->tgt_start + k->tgt_offset;
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
146
kono
parents:
diff changeset
147 acc_unmap_data ((void *)(k->host_start + offset));
kono
parents:
diff changeset
148 }
kono
parents:
diff changeset
149 else
kono
parents:
diff changeset
150 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
151
kono
parents:
diff changeset
152 if (!acc_dev->free_func (acc_dev->target_id, d))
kono
parents:
diff changeset
153 gomp_fatal ("error in freeing device memory in %s", __FUNCTION__);
kono
parents:
diff changeset
154 }
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156 void
kono
parents:
diff changeset
157 acc_memcpy_to_device (void *d, void *h, size_t s)
kono
parents:
diff changeset
158 {
kono
parents:
diff changeset
159 /* No need to call lazy open here, as the device pointer must have
kono
parents:
diff changeset
160 been obtained from a routine that did that. */
kono
parents:
diff changeset
161 struct goacc_thread *thr = goacc_thread ();
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 assert (thr && thr->dev);
kono
parents:
diff changeset
164
kono
parents:
diff changeset
165 if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
166 {
kono
parents:
diff changeset
167 memmove (d, h, s);
kono
parents:
diff changeset
168 return;
kono
parents:
diff changeset
169 }
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 if (!thr->dev->host2dev_func (thr->dev->target_id, d, h, s))
kono
parents:
diff changeset
172 gomp_fatal ("error in %s", __FUNCTION__);
kono
parents:
diff changeset
173 }
kono
parents:
diff changeset
174
kono
parents:
diff changeset
175 void
kono
parents:
diff changeset
176 acc_memcpy_from_device (void *h, void *d, size_t s)
kono
parents:
diff changeset
177 {
kono
parents:
diff changeset
178 /* No need to call lazy open here, as the device pointer must have
kono
parents:
diff changeset
179 been obtained from a routine that did that. */
kono
parents:
diff changeset
180 struct goacc_thread *thr = goacc_thread ();
kono
parents:
diff changeset
181
kono
parents:
diff changeset
182 assert (thr && thr->dev);
kono
parents:
diff changeset
183
kono
parents:
diff changeset
184 if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
185 {
kono
parents:
diff changeset
186 memmove (h, d, s);
kono
parents:
diff changeset
187 return;
kono
parents:
diff changeset
188 }
kono
parents:
diff changeset
189
kono
parents:
diff changeset
190 if (!thr->dev->dev2host_func (thr->dev->target_id, h, d, s))
kono
parents:
diff changeset
191 gomp_fatal ("error in %s", __FUNCTION__);
kono
parents:
diff changeset
192 }
kono
parents:
diff changeset
193
kono
parents:
diff changeset
194 /* Return the device pointer that corresponds to host data H. Or NULL
kono
parents:
diff changeset
195 if no mapping. */
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 void *
kono
parents:
diff changeset
198 acc_deviceptr (void *h)
kono
parents:
diff changeset
199 {
kono
parents:
diff changeset
200 splay_tree_key n;
kono
parents:
diff changeset
201 void *d;
kono
parents:
diff changeset
202 void *offset;
kono
parents:
diff changeset
203
kono
parents:
diff changeset
204 goacc_lazy_initialize ();
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 struct goacc_thread *thr = goacc_thread ();
kono
parents:
diff changeset
207 struct gomp_device_descr *dev = thr->dev;
kono
parents:
diff changeset
208
kono
parents:
diff changeset
209 if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
210 return h;
kono
parents:
diff changeset
211
kono
parents:
diff changeset
212 gomp_mutex_lock (&dev->lock);
kono
parents:
diff changeset
213
kono
parents:
diff changeset
214 n = lookup_host (dev, h, 1);
kono
parents:
diff changeset
215
kono
parents:
diff changeset
216 if (!n)
kono
parents:
diff changeset
217 {
kono
parents:
diff changeset
218 gomp_mutex_unlock (&dev->lock);
kono
parents:
diff changeset
219 return NULL;
kono
parents:
diff changeset
220 }
kono
parents:
diff changeset
221
kono
parents:
diff changeset
222 offset = h - n->host_start;
kono
parents:
diff changeset
223
kono
parents:
diff changeset
224 d = n->tgt->tgt_start + n->tgt_offset + offset;
kono
parents:
diff changeset
225
kono
parents:
diff changeset
226 gomp_mutex_unlock (&dev->lock);
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228 return d;
kono
parents:
diff changeset
229 }
kono
parents:
diff changeset
230
kono
parents:
diff changeset
231 /* Return the host pointer that corresponds to device data D. Or NULL
kono
parents:
diff changeset
232 if no mapping. */
kono
parents:
diff changeset
233
kono
parents:
diff changeset
234 void *
kono
parents:
diff changeset
235 acc_hostptr (void *d)
kono
parents:
diff changeset
236 {
kono
parents:
diff changeset
237 splay_tree_key n;
kono
parents:
diff changeset
238 void *h;
kono
parents:
diff changeset
239 void *offset;
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 goacc_lazy_initialize ();
kono
parents:
diff changeset
242
kono
parents:
diff changeset
243 struct goacc_thread *thr = goacc_thread ();
kono
parents:
diff changeset
244 struct gomp_device_descr *acc_dev = thr->dev;
kono
parents:
diff changeset
245
kono
parents:
diff changeset
246 if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
247 return d;
kono
parents:
diff changeset
248
kono
parents:
diff changeset
249 gomp_mutex_lock (&acc_dev->lock);
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 n = lookup_dev (acc_dev->openacc.data_environ, d, 1);
kono
parents:
diff changeset
252
kono
parents:
diff changeset
253 if (!n)
kono
parents:
diff changeset
254 {
kono
parents:
diff changeset
255 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
256 return NULL;
kono
parents:
diff changeset
257 }
kono
parents:
diff changeset
258
kono
parents:
diff changeset
259 offset = d - n->tgt->tgt_start + n->tgt_offset;
kono
parents:
diff changeset
260
kono
parents:
diff changeset
261 h = n->host_start + offset;
kono
parents:
diff changeset
262
kono
parents:
diff changeset
263 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
264
kono
parents:
diff changeset
265 return h;
kono
parents:
diff changeset
266 }
kono
parents:
diff changeset
267
kono
parents:
diff changeset
268 /* Return 1 if host data [H,+S] is present on the device. */
kono
parents:
diff changeset
269
kono
parents:
diff changeset
270 int
kono
parents:
diff changeset
271 acc_is_present (void *h, size_t s)
kono
parents:
diff changeset
272 {
kono
parents:
diff changeset
273 splay_tree_key n;
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 if (!s || !h)
kono
parents:
diff changeset
276 return 0;
kono
parents:
diff changeset
277
kono
parents:
diff changeset
278 goacc_lazy_initialize ();
kono
parents:
diff changeset
279
kono
parents:
diff changeset
280 struct goacc_thread *thr = goacc_thread ();
kono
parents:
diff changeset
281 struct gomp_device_descr *acc_dev = thr->dev;
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
284 return h != NULL;
kono
parents:
diff changeset
285
kono
parents:
diff changeset
286 gomp_mutex_lock (&acc_dev->lock);
kono
parents:
diff changeset
287
kono
parents:
diff changeset
288 n = lookup_host (acc_dev, h, s);
kono
parents:
diff changeset
289
kono
parents:
diff changeset
290 if (n && ((uintptr_t)h < n->host_start
kono
parents:
diff changeset
291 || (uintptr_t)h + s > n->host_end
kono
parents:
diff changeset
292 || s > n->host_end - n->host_start))
kono
parents:
diff changeset
293 n = NULL;
kono
parents:
diff changeset
294
kono
parents:
diff changeset
295 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
296
kono
parents:
diff changeset
297 return n != NULL;
kono
parents:
diff changeset
298 }
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 /* Create a mapping for host [H,+S] -> device [D,+S] */
kono
parents:
diff changeset
301
kono
parents:
diff changeset
302 void
kono
parents:
diff changeset
303 acc_map_data (void *h, void *d, size_t s)
kono
parents:
diff changeset
304 {
kono
parents:
diff changeset
305 struct target_mem_desc *tgt = NULL;
kono
parents:
diff changeset
306 size_t mapnum = 1;
kono
parents:
diff changeset
307 void *hostaddrs = h;
kono
parents:
diff changeset
308 void *devaddrs = d;
kono
parents:
diff changeset
309 size_t sizes = s;
kono
parents:
diff changeset
310 unsigned short kinds = GOMP_MAP_ALLOC;
kono
parents:
diff changeset
311
kono
parents:
diff changeset
312 goacc_lazy_initialize ();
kono
parents:
diff changeset
313
kono
parents:
diff changeset
314 struct goacc_thread *thr = goacc_thread ();
kono
parents:
diff changeset
315 struct gomp_device_descr *acc_dev = thr->dev;
kono
parents:
diff changeset
316
kono
parents:
diff changeset
317 if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
318 {
kono
parents:
diff changeset
319 if (d != h)
kono
parents:
diff changeset
320 gomp_fatal ("cannot map data on shared-memory system");
kono
parents:
diff changeset
321 }
kono
parents:
diff changeset
322 else
kono
parents:
diff changeset
323 {
kono
parents:
diff changeset
324 struct goacc_thread *thr = goacc_thread ();
kono
parents:
diff changeset
325
kono
parents:
diff changeset
326 if (!d || !h || !s)
kono
parents:
diff changeset
327 gomp_fatal ("[%p,+%d]->[%p,+%d] is a bad map",
kono
parents:
diff changeset
328 (void *)h, (int)s, (void *)d, (int)s);
kono
parents:
diff changeset
329
kono
parents:
diff changeset
330 gomp_mutex_lock (&acc_dev->lock);
kono
parents:
diff changeset
331
kono
parents:
diff changeset
332 if (lookup_host (acc_dev, h, s))
kono
parents:
diff changeset
333 {
kono
parents:
diff changeset
334 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
335 gomp_fatal ("host address [%p, +%d] is already mapped", (void *)h,
kono
parents:
diff changeset
336 (int)s);
kono
parents:
diff changeset
337 }
kono
parents:
diff changeset
338
kono
parents:
diff changeset
339 if (lookup_dev (thr->dev->openacc.data_environ, d, s))
kono
parents:
diff changeset
340 {
kono
parents:
diff changeset
341 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
342 gomp_fatal ("device address [%p, +%d] is already mapped", (void *)d,
kono
parents:
diff changeset
343 (int)s);
kono
parents:
diff changeset
344 }
kono
parents:
diff changeset
345
kono
parents:
diff changeset
346 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
347
kono
parents:
diff changeset
348 tgt = gomp_map_vars (acc_dev, mapnum, &hostaddrs, &devaddrs, &sizes,
kono
parents:
diff changeset
349 &kinds, true, GOMP_MAP_VARS_OPENACC);
kono
parents:
diff changeset
350 }
kono
parents:
diff changeset
351
kono
parents:
diff changeset
352 gomp_mutex_lock (&acc_dev->lock);
kono
parents:
diff changeset
353 tgt->prev = acc_dev->openacc.data_environ;
kono
parents:
diff changeset
354 acc_dev->openacc.data_environ = tgt;
kono
parents:
diff changeset
355 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
356 }
kono
parents:
diff changeset
357
kono
parents:
diff changeset
358 void
kono
parents:
diff changeset
359 acc_unmap_data (void *h)
kono
parents:
diff changeset
360 {
kono
parents:
diff changeset
361 struct goacc_thread *thr = goacc_thread ();
kono
parents:
diff changeset
362 struct gomp_device_descr *acc_dev = thr->dev;
kono
parents:
diff changeset
363
kono
parents:
diff changeset
364 /* No need to call lazy open, as the address must have been mapped. */
kono
parents:
diff changeset
365
kono
parents:
diff changeset
366 /* This is a no-op on shared-memory targets. */
kono
parents:
diff changeset
367 if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
368 return;
kono
parents:
diff changeset
369
kono
parents:
diff changeset
370 size_t host_size;
kono
parents:
diff changeset
371
kono
parents:
diff changeset
372 gomp_mutex_lock (&acc_dev->lock);
kono
parents:
diff changeset
373
kono
parents:
diff changeset
374 splay_tree_key n = lookup_host (acc_dev, h, 1);
kono
parents:
diff changeset
375 struct target_mem_desc *t;
kono
parents:
diff changeset
376
kono
parents:
diff changeset
377 if (!n)
kono
parents:
diff changeset
378 {
kono
parents:
diff changeset
379 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
380 gomp_fatal ("%p is not a mapped block", (void *)h);
kono
parents:
diff changeset
381 }
kono
parents:
diff changeset
382
kono
parents:
diff changeset
383 host_size = n->host_end - n->host_start;
kono
parents:
diff changeset
384
kono
parents:
diff changeset
385 if (n->host_start != (uintptr_t) h)
kono
parents:
diff changeset
386 {
kono
parents:
diff changeset
387 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
388 gomp_fatal ("[%p,%d] surrounds %p",
kono
parents:
diff changeset
389 (void *) n->host_start, (int) host_size, (void *) h);
kono
parents:
diff changeset
390 }
kono
parents:
diff changeset
391
kono
parents:
diff changeset
392 t = n->tgt;
kono
parents:
diff changeset
393
kono
parents:
diff changeset
394 if (t->refcount == 2)
kono
parents:
diff changeset
395 {
kono
parents:
diff changeset
396 struct target_mem_desc *tp;
kono
parents:
diff changeset
397
kono
parents:
diff changeset
398 /* This is the last reference, so pull the descriptor off the
kono
parents:
diff changeset
399 chain. This avoids gomp_unmap_vars via gomp_unmap_tgt from
kono
parents:
diff changeset
400 freeing the device memory. */
kono
parents:
diff changeset
401 t->tgt_end = 0;
kono
parents:
diff changeset
402 t->to_free = 0;
kono
parents:
diff changeset
403
kono
parents:
diff changeset
404 for (tp = NULL, t = acc_dev->openacc.data_environ; t != NULL;
kono
parents:
diff changeset
405 tp = t, t = t->prev)
kono
parents:
diff changeset
406 if (n->tgt == t)
kono
parents:
diff changeset
407 {
kono
parents:
diff changeset
408 if (tp)
kono
parents:
diff changeset
409 tp->prev = t->prev;
kono
parents:
diff changeset
410 else
kono
parents:
diff changeset
411 acc_dev->openacc.data_environ = t->prev;
kono
parents:
diff changeset
412
kono
parents:
diff changeset
413 break;
kono
parents:
diff changeset
414 }
kono
parents:
diff changeset
415 }
kono
parents:
diff changeset
416
kono
parents:
diff changeset
417 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
418
kono
parents:
diff changeset
419 gomp_unmap_vars (t, true);
kono
parents:
diff changeset
420 }
kono
parents:
diff changeset
421
kono
parents:
diff changeset
422 #define FLAG_PRESENT (1 << 0)
kono
parents:
diff changeset
423 #define FLAG_CREATE (1 << 1)
kono
parents:
diff changeset
424 #define FLAG_COPY (1 << 2)
kono
parents:
diff changeset
425
kono
parents:
diff changeset
426 static void *
kono
parents:
diff changeset
427 present_create_copy (unsigned f, void *h, size_t s)
kono
parents:
diff changeset
428 {
kono
parents:
diff changeset
429 void *d;
kono
parents:
diff changeset
430 splay_tree_key n;
kono
parents:
diff changeset
431
kono
parents:
diff changeset
432 if (!h || !s)
kono
parents:
diff changeset
433 gomp_fatal ("[%p,+%d] is a bad range", (void *)h, (int)s);
kono
parents:
diff changeset
434
kono
parents:
diff changeset
435 goacc_lazy_initialize ();
kono
parents:
diff changeset
436
kono
parents:
diff changeset
437 struct goacc_thread *thr = goacc_thread ();
kono
parents:
diff changeset
438 struct gomp_device_descr *acc_dev = thr->dev;
kono
parents:
diff changeset
439
kono
parents:
diff changeset
440 if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
441 return h;
kono
parents:
diff changeset
442
kono
parents:
diff changeset
443 gomp_mutex_lock (&acc_dev->lock);
kono
parents:
diff changeset
444
kono
parents:
diff changeset
445 n = lookup_host (acc_dev, h, s);
kono
parents:
diff changeset
446 if (n)
kono
parents:
diff changeset
447 {
kono
parents:
diff changeset
448 /* Present. */
kono
parents:
diff changeset
449 d = (void *) (n->tgt->tgt_start + n->tgt_offset);
kono
parents:
diff changeset
450
kono
parents:
diff changeset
451 if (!(f & FLAG_PRESENT))
kono
parents:
diff changeset
452 {
kono
parents:
diff changeset
453 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
454 gomp_fatal ("[%p,+%d] already mapped to [%p,+%d]",
kono
parents:
diff changeset
455 (void *)h, (int)s, (void *)d, (int)s);
kono
parents:
diff changeset
456 }
kono
parents:
diff changeset
457 if ((h + s) > (void *)n->host_end)
kono
parents:
diff changeset
458 {
kono
parents:
diff changeset
459 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
460 gomp_fatal ("[%p,+%d] not mapped", (void *)h, (int)s);
kono
parents:
diff changeset
461 }
kono
parents:
diff changeset
462
kono
parents:
diff changeset
463 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
464 }
kono
parents:
diff changeset
465 else if (!(f & FLAG_CREATE))
kono
parents:
diff changeset
466 {
kono
parents:
diff changeset
467 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
468 gomp_fatal ("[%p,+%d] not mapped", (void *)h, (int)s);
kono
parents:
diff changeset
469 }
kono
parents:
diff changeset
470 else
kono
parents:
diff changeset
471 {
kono
parents:
diff changeset
472 struct target_mem_desc *tgt;
kono
parents:
diff changeset
473 size_t mapnum = 1;
kono
parents:
diff changeset
474 unsigned short kinds;
kono
parents:
diff changeset
475 void *hostaddrs = h;
kono
parents:
diff changeset
476
kono
parents:
diff changeset
477 if (f & FLAG_COPY)
kono
parents:
diff changeset
478 kinds = GOMP_MAP_TO;
kono
parents:
diff changeset
479 else
kono
parents:
diff changeset
480 kinds = GOMP_MAP_ALLOC;
kono
parents:
diff changeset
481
kono
parents:
diff changeset
482 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
483
kono
parents:
diff changeset
484 tgt = gomp_map_vars (acc_dev, mapnum, &hostaddrs, NULL, &s, &kinds, true,
kono
parents:
diff changeset
485 GOMP_MAP_VARS_OPENACC);
kono
parents:
diff changeset
486
kono
parents:
diff changeset
487 gomp_mutex_lock (&acc_dev->lock);
kono
parents:
diff changeset
488
kono
parents:
diff changeset
489 d = tgt->to_free;
kono
parents:
diff changeset
490 tgt->prev = acc_dev->openacc.data_environ;
kono
parents:
diff changeset
491 acc_dev->openacc.data_environ = tgt;
kono
parents:
diff changeset
492
kono
parents:
diff changeset
493 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
494 }
kono
parents:
diff changeset
495
kono
parents:
diff changeset
496 return d;
kono
parents:
diff changeset
497 }
kono
parents:
diff changeset
498
kono
parents:
diff changeset
499 void *
kono
parents:
diff changeset
500 acc_create (void *h, size_t s)
kono
parents:
diff changeset
501 {
kono
parents:
diff changeset
502 return present_create_copy (FLAG_CREATE, h, s);
kono
parents:
diff changeset
503 }
kono
parents:
diff changeset
504
kono
parents:
diff changeset
505 void *
kono
parents:
diff changeset
506 acc_copyin (void *h, size_t s)
kono
parents:
diff changeset
507 {
kono
parents:
diff changeset
508 return present_create_copy (FLAG_CREATE | FLAG_COPY, h, s);
kono
parents:
diff changeset
509 }
kono
parents:
diff changeset
510
kono
parents:
diff changeset
511 void *
kono
parents:
diff changeset
512 acc_present_or_create (void *h, size_t s)
kono
parents:
diff changeset
513 {
kono
parents:
diff changeset
514 return present_create_copy (FLAG_PRESENT | FLAG_CREATE, h, s);
kono
parents:
diff changeset
515 }
kono
parents:
diff changeset
516
kono
parents:
diff changeset
517 /* acc_pcreate is acc_present_or_create by a different name. */
kono
parents:
diff changeset
518 #ifdef HAVE_ATTRIBUTE_ALIAS
kono
parents:
diff changeset
519 strong_alias (acc_present_or_create, acc_pcreate)
kono
parents:
diff changeset
520 #else
kono
parents:
diff changeset
521 void *
kono
parents:
diff changeset
522 acc_pcreate (void *h, size_t s)
kono
parents:
diff changeset
523 {
kono
parents:
diff changeset
524 return acc_present_or_create (h, s);
kono
parents:
diff changeset
525 }
kono
parents:
diff changeset
526 #endif
kono
parents:
diff changeset
527
kono
parents:
diff changeset
528 void *
kono
parents:
diff changeset
529 acc_present_or_copyin (void *h, size_t s)
kono
parents:
diff changeset
530 {
kono
parents:
diff changeset
531 return present_create_copy (FLAG_PRESENT | FLAG_CREATE | FLAG_COPY, h, s);
kono
parents:
diff changeset
532 }
kono
parents:
diff changeset
533
kono
parents:
diff changeset
534 /* acc_pcopyin is acc_present_or_copyin by a different name. */
kono
parents:
diff changeset
535 #ifdef HAVE_ATTRIBUTE_ALIAS
kono
parents:
diff changeset
536 strong_alias (acc_present_or_copyin, acc_pcopyin)
kono
parents:
diff changeset
537 #else
kono
parents:
diff changeset
538 void *
kono
parents:
diff changeset
539 acc_pcopyin (void *h, size_t s)
kono
parents:
diff changeset
540 {
kono
parents:
diff changeset
541 return acc_present_or_copyin (h, s);
kono
parents:
diff changeset
542 }
kono
parents:
diff changeset
543 #endif
kono
parents:
diff changeset
544
kono
parents:
diff changeset
545 #define FLAG_COPYOUT (1 << 0)
kono
parents:
diff changeset
546
kono
parents:
diff changeset
547 static void
kono
parents:
diff changeset
548 delete_copyout (unsigned f, void *h, size_t s, const char *libfnname)
kono
parents:
diff changeset
549 {
kono
parents:
diff changeset
550 size_t host_size;
kono
parents:
diff changeset
551 splay_tree_key n;
kono
parents:
diff changeset
552 void *d;
kono
parents:
diff changeset
553 struct goacc_thread *thr = goacc_thread ();
kono
parents:
diff changeset
554 struct gomp_device_descr *acc_dev = thr->dev;
kono
parents:
diff changeset
555
kono
parents:
diff changeset
556 if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
557 return;
kono
parents:
diff changeset
558
kono
parents:
diff changeset
559 gomp_mutex_lock (&acc_dev->lock);
kono
parents:
diff changeset
560
kono
parents:
diff changeset
561 n = lookup_host (acc_dev, h, s);
kono
parents:
diff changeset
562
kono
parents:
diff changeset
563 /* No need to call lazy open, as the data must already have been
kono
parents:
diff changeset
564 mapped. */
kono
parents:
diff changeset
565
kono
parents:
diff changeset
566 if (!n)
kono
parents:
diff changeset
567 {
kono
parents:
diff changeset
568 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
569 gomp_fatal ("[%p,%d] is not mapped", (void *)h, (int)s);
kono
parents:
diff changeset
570 }
kono
parents:
diff changeset
571
kono
parents:
diff changeset
572 d = (void *) (n->tgt->tgt_start + n->tgt_offset
kono
parents:
diff changeset
573 + (uintptr_t) h - n->host_start);
kono
parents:
diff changeset
574
kono
parents:
diff changeset
575 host_size = n->host_end - n->host_start;
kono
parents:
diff changeset
576
kono
parents:
diff changeset
577 if (n->host_start != (uintptr_t) h || host_size != s)
kono
parents:
diff changeset
578 {
kono
parents:
diff changeset
579 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
580 gomp_fatal ("[%p,%d] surrounds2 [%p,+%d]",
kono
parents:
diff changeset
581 (void *) n->host_start, (int) host_size, (void *) h, (int) s);
kono
parents:
diff changeset
582 }
kono
parents:
diff changeset
583
kono
parents:
diff changeset
584 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
585
kono
parents:
diff changeset
586 if (f & FLAG_COPYOUT)
kono
parents:
diff changeset
587 acc_dev->dev2host_func (acc_dev->target_id, h, d, s);
kono
parents:
diff changeset
588
kono
parents:
diff changeset
589 acc_unmap_data (h);
kono
parents:
diff changeset
590
kono
parents:
diff changeset
591 if (!acc_dev->free_func (acc_dev->target_id, d))
kono
parents:
diff changeset
592 gomp_fatal ("error in freeing device memory in %s", libfnname);
kono
parents:
diff changeset
593 }
kono
parents:
diff changeset
594
kono
parents:
diff changeset
595 void
kono
parents:
diff changeset
596 acc_delete (void *h , size_t s)
kono
parents:
diff changeset
597 {
kono
parents:
diff changeset
598 delete_copyout (0, h, s, __FUNCTION__);
kono
parents:
diff changeset
599 }
kono
parents:
diff changeset
600
kono
parents:
diff changeset
601 void
kono
parents:
diff changeset
602 acc_copyout (void *h, size_t s)
kono
parents:
diff changeset
603 {
kono
parents:
diff changeset
604 delete_copyout (FLAG_COPYOUT, h, s, __FUNCTION__);
kono
parents:
diff changeset
605 }
kono
parents:
diff changeset
606
kono
parents:
diff changeset
607 static void
kono
parents:
diff changeset
608 update_dev_host (int is_dev, void *h, size_t s)
kono
parents:
diff changeset
609 {
kono
parents:
diff changeset
610 splay_tree_key n;
kono
parents:
diff changeset
611 void *d;
kono
parents:
diff changeset
612
kono
parents:
diff changeset
613 goacc_lazy_initialize ();
kono
parents:
diff changeset
614
kono
parents:
diff changeset
615 struct goacc_thread *thr = goacc_thread ();
kono
parents:
diff changeset
616 struct gomp_device_descr *acc_dev = thr->dev;
kono
parents:
diff changeset
617
kono
parents:
diff changeset
618 if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
619 return;
kono
parents:
diff changeset
620
kono
parents:
diff changeset
621 gomp_mutex_lock (&acc_dev->lock);
kono
parents:
diff changeset
622
kono
parents:
diff changeset
623 n = lookup_host (acc_dev, h, s);
kono
parents:
diff changeset
624
kono
parents:
diff changeset
625 if (!n)
kono
parents:
diff changeset
626 {
kono
parents:
diff changeset
627 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
628 gomp_fatal ("[%p,%d] is not mapped", h, (int)s);
kono
parents:
diff changeset
629 }
kono
parents:
diff changeset
630
kono
parents:
diff changeset
631 d = (void *) (n->tgt->tgt_start + n->tgt_offset
kono
parents:
diff changeset
632 + (uintptr_t) h - n->host_start);
kono
parents:
diff changeset
633
kono
parents:
diff changeset
634 if (is_dev)
kono
parents:
diff changeset
635 acc_dev->host2dev_func (acc_dev->target_id, d, h, s);
kono
parents:
diff changeset
636 else
kono
parents:
diff changeset
637 acc_dev->dev2host_func (acc_dev->target_id, h, d, s);
kono
parents:
diff changeset
638
kono
parents:
diff changeset
639 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
640 }
kono
parents:
diff changeset
641
kono
parents:
diff changeset
642 void
kono
parents:
diff changeset
643 acc_update_device (void *h, size_t s)
kono
parents:
diff changeset
644 {
kono
parents:
diff changeset
645 update_dev_host (1, h, s);
kono
parents:
diff changeset
646 }
kono
parents:
diff changeset
647
kono
parents:
diff changeset
648 void
kono
parents:
diff changeset
649 acc_update_self (void *h, size_t s)
kono
parents:
diff changeset
650 {
kono
parents:
diff changeset
651 update_dev_host (0, h, s);
kono
parents:
diff changeset
652 }
kono
parents:
diff changeset
653
kono
parents:
diff changeset
654 void
kono
parents:
diff changeset
655 gomp_acc_insert_pointer (size_t mapnum, void **hostaddrs, size_t *sizes,
kono
parents:
diff changeset
656 void *kinds)
kono
parents:
diff changeset
657 {
kono
parents:
diff changeset
658 struct target_mem_desc *tgt;
kono
parents:
diff changeset
659 struct goacc_thread *thr = goacc_thread ();
kono
parents:
diff changeset
660 struct gomp_device_descr *acc_dev = thr->dev;
kono
parents:
diff changeset
661
kono
parents:
diff changeset
662 gomp_debug (0, " %s: prepare mappings\n", __FUNCTION__);
kono
parents:
diff changeset
663 tgt = gomp_map_vars (acc_dev, mapnum, hostaddrs,
kono
parents:
diff changeset
664 NULL, sizes, kinds, true, GOMP_MAP_VARS_OPENACC);
kono
parents:
diff changeset
665 gomp_debug (0, " %s: mappings prepared\n", __FUNCTION__);
kono
parents:
diff changeset
666
kono
parents:
diff changeset
667 gomp_mutex_lock (&acc_dev->lock);
kono
parents:
diff changeset
668 tgt->prev = acc_dev->openacc.data_environ;
kono
parents:
diff changeset
669 acc_dev->openacc.data_environ = tgt;
kono
parents:
diff changeset
670 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
671 }
kono
parents:
diff changeset
672
kono
parents:
diff changeset
673 void
kono
parents:
diff changeset
674 gomp_acc_remove_pointer (void *h, bool force_copyfrom, int async, int mapnum)
kono
parents:
diff changeset
675 {
kono
parents:
diff changeset
676 struct goacc_thread *thr = goacc_thread ();
kono
parents:
diff changeset
677 struct gomp_device_descr *acc_dev = thr->dev;
kono
parents:
diff changeset
678 splay_tree_key n;
kono
parents:
diff changeset
679 struct target_mem_desc *t;
kono
parents:
diff changeset
680 int minrefs = (mapnum == 1) ? 2 : 3;
kono
parents:
diff changeset
681
kono
parents:
diff changeset
682 gomp_mutex_lock (&acc_dev->lock);
kono
parents:
diff changeset
683
kono
parents:
diff changeset
684 n = lookup_host (acc_dev, h, 1);
kono
parents:
diff changeset
685
kono
parents:
diff changeset
686 if (!n)
kono
parents:
diff changeset
687 {
kono
parents:
diff changeset
688 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
689 gomp_fatal ("%p is not a mapped block", (void *)h);
kono
parents:
diff changeset
690 }
kono
parents:
diff changeset
691
kono
parents:
diff changeset
692 gomp_debug (0, " %s: restore mappings\n", __FUNCTION__);
kono
parents:
diff changeset
693
kono
parents:
diff changeset
694 t = n->tgt;
kono
parents:
diff changeset
695
kono
parents:
diff changeset
696 struct target_mem_desc *tp;
kono
parents:
diff changeset
697
kono
parents:
diff changeset
698 if (t->refcount == minrefs)
kono
parents:
diff changeset
699 {
kono
parents:
diff changeset
700 /* This is the last reference, so pull the descriptor off the
kono
parents:
diff changeset
701 chain. This avoids gomp_unmap_vars via gomp_unmap_tgt from
kono
parents:
diff changeset
702 freeing the device memory. */
kono
parents:
diff changeset
703 t->tgt_end = 0;
kono
parents:
diff changeset
704 t->to_free = 0;
kono
parents:
diff changeset
705
kono
parents:
diff changeset
706 for (tp = NULL, t = acc_dev->openacc.data_environ; t != NULL;
kono
parents:
diff changeset
707 tp = t, t = t->prev)
kono
parents:
diff changeset
708 {
kono
parents:
diff changeset
709 if (n->tgt == t)
kono
parents:
diff changeset
710 {
kono
parents:
diff changeset
711 if (tp)
kono
parents:
diff changeset
712 tp->prev = t->prev;
kono
parents:
diff changeset
713 else
kono
parents:
diff changeset
714 acc_dev->openacc.data_environ = t->prev;
kono
parents:
diff changeset
715 break;
kono
parents:
diff changeset
716 }
kono
parents:
diff changeset
717 }
kono
parents:
diff changeset
718 }
kono
parents:
diff changeset
719
kono
parents:
diff changeset
720 if (force_copyfrom)
kono
parents:
diff changeset
721 t->list[0].copy_from = 1;
kono
parents:
diff changeset
722
kono
parents:
diff changeset
723 gomp_mutex_unlock (&acc_dev->lock);
kono
parents:
diff changeset
724
kono
parents:
diff changeset
725 /* If running synchronously, unmap immediately. */
kono
parents:
diff changeset
726 if (async < acc_async_noval)
kono
parents:
diff changeset
727 gomp_unmap_vars (t, true);
kono
parents:
diff changeset
728 else
kono
parents:
diff changeset
729 t->device_descr->openacc.register_async_cleanup_func (t, async);
kono
parents:
diff changeset
730
kono
parents:
diff changeset
731 gomp_debug (0, " %s: mappings restored\n", __FUNCTION__);
kono
parents:
diff changeset
732 }