annotate libgomp/target.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1 /* Copyright (C) 2013-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
2 Contributed by Jakub Jelinek <jakub@redhat.com>.
kono
parents:
diff changeset
3
kono
parents:
diff changeset
4 This file is part of the GNU Offloading and Multi Processing Library
kono
parents:
diff changeset
5 (libgomp).
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 Libgomp is free software; you can redistribute it and/or modify it
kono
parents:
diff changeset
8 under the terms of the GNU General Public License as published by
kono
parents:
diff changeset
9 the Free Software Foundation; either version 3, or (at your option)
kono
parents:
diff changeset
10 any later version.
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
kono
parents:
diff changeset
14 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
kono
parents:
diff changeset
15 more details.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 Under Section 7 of GPL version 3, you are granted additional
kono
parents:
diff changeset
18 permissions described in the GCC Runtime Library Exception, version
kono
parents:
diff changeset
19 3.1, as published by the Free Software Foundation.
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21 You should have received a copy of the GNU General Public License and
kono
parents:
diff changeset
22 a copy of the GCC Runtime Library Exception along with this program;
kono
parents:
diff changeset
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
kono
parents:
diff changeset
24 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 /* This file contains the support of offloading. */
kono
parents:
diff changeset
27
kono
parents:
diff changeset
28 #include "libgomp.h"
kono
parents:
diff changeset
29 #include "oacc-plugin.h"
kono
parents:
diff changeset
30 #include "oacc-int.h"
kono
parents:
diff changeset
31 #include "gomp-constants.h"
kono
parents:
diff changeset
32 #include <limits.h>
kono
parents:
diff changeset
33 #include <stdbool.h>
kono
parents:
diff changeset
34 #include <stdlib.h>
kono
parents:
diff changeset
35 #ifdef HAVE_INTTYPES_H
kono
parents:
diff changeset
36 # include <inttypes.h> /* For PRIu64. */
kono
parents:
diff changeset
37 #endif
kono
parents:
diff changeset
38 #include <string.h>
kono
parents:
diff changeset
39 #include <assert.h>
kono
parents:
diff changeset
40 #include <errno.h>
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 #ifdef PLUGIN_SUPPORT
kono
parents:
diff changeset
43 #include <dlfcn.h>
kono
parents:
diff changeset
44 #include "plugin-suffix.h"
kono
parents:
diff changeset
45 #endif
kono
parents:
diff changeset
46
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
47 #define FIELD_TGT_EMPTY (~(size_t) 0)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
48
111
kono
parents:
diff changeset
49 static void gomp_target_init (void);
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51 /* The whole initialization code for offloading plugins is only run one. */
kono
parents:
diff changeset
52 static pthread_once_t gomp_is_initialized = PTHREAD_ONCE_INIT;
kono
parents:
diff changeset
53
kono
parents:
diff changeset
54 /* Mutex for offload image registration. */
kono
parents:
diff changeset
55 static gomp_mutex_t register_lock;
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 /* This structure describes an offload image.
kono
parents:
diff changeset
58 It contains type of the target device, pointer to host table descriptor, and
kono
parents:
diff changeset
59 pointer to target data. */
kono
parents:
diff changeset
60 struct offload_image_descr {
kono
parents:
diff changeset
61 unsigned version;
kono
parents:
diff changeset
62 enum offload_target_type type;
kono
parents:
diff changeset
63 const void *host_table;
kono
parents:
diff changeset
64 const void *target_data;
kono
parents:
diff changeset
65 };
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 /* Array of descriptors of offload images. */
kono
parents:
diff changeset
68 static struct offload_image_descr *offload_images;
kono
parents:
diff changeset
69
kono
parents:
diff changeset
70 /* Total number of offload images. */
kono
parents:
diff changeset
71 static int num_offload_images;
kono
parents:
diff changeset
72
kono
parents:
diff changeset
73 /* Array of descriptors for all available devices. */
kono
parents:
diff changeset
74 static struct gomp_device_descr *devices;
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 /* Total number of available devices. */
kono
parents:
diff changeset
77 static int num_devices;
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 /* Number of GOMP_OFFLOAD_CAP_OPENMP_400 devices. */
kono
parents:
diff changeset
80 static int num_devices_openmp;
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 /* Similar to gomp_realloc, but release register_lock before gomp_fatal. */
kono
parents:
diff changeset
83
kono
parents:
diff changeset
84 static void *
kono
parents:
diff changeset
85 gomp_realloc_unlock (void *old, size_t size)
kono
parents:
diff changeset
86 {
kono
parents:
diff changeset
87 void *ret = realloc (old, size);
kono
parents:
diff changeset
88 if (ret == NULL)
kono
parents:
diff changeset
89 {
kono
parents:
diff changeset
90 gomp_mutex_unlock (&register_lock);
kono
parents:
diff changeset
91 gomp_fatal ("Out of memory allocating %lu bytes", (unsigned long) size);
kono
parents:
diff changeset
92 }
kono
parents:
diff changeset
93 return ret;
kono
parents:
diff changeset
94 }
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 attribute_hidden void
kono
parents:
diff changeset
97 gomp_init_targets_once (void)
kono
parents:
diff changeset
98 {
kono
parents:
diff changeset
99 (void) pthread_once (&gomp_is_initialized, gomp_target_init);
kono
parents:
diff changeset
100 }
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 attribute_hidden int
kono
parents:
diff changeset
103 gomp_get_num_devices (void)
kono
parents:
diff changeset
104 {
kono
parents:
diff changeset
105 gomp_init_targets_once ();
kono
parents:
diff changeset
106 return num_devices_openmp;
kono
parents:
diff changeset
107 }
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 static struct gomp_device_descr *
kono
parents:
diff changeset
110 resolve_device (int device_id)
kono
parents:
diff changeset
111 {
kono
parents:
diff changeset
112 if (device_id == GOMP_DEVICE_ICV)
kono
parents:
diff changeset
113 {
kono
parents:
diff changeset
114 struct gomp_task_icv *icv = gomp_icv (false);
kono
parents:
diff changeset
115 device_id = icv->default_device_var;
kono
parents:
diff changeset
116 }
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 if (device_id < 0 || device_id >= gomp_get_num_devices ())
kono
parents:
diff changeset
119 return NULL;
kono
parents:
diff changeset
120
kono
parents:
diff changeset
121 gomp_mutex_lock (&devices[device_id].lock);
kono
parents:
diff changeset
122 if (devices[device_id].state == GOMP_DEVICE_UNINITIALIZED)
kono
parents:
diff changeset
123 gomp_init_device (&devices[device_id]);
kono
parents:
diff changeset
124 else if (devices[device_id].state == GOMP_DEVICE_FINALIZED)
kono
parents:
diff changeset
125 {
kono
parents:
diff changeset
126 gomp_mutex_unlock (&devices[device_id].lock);
kono
parents:
diff changeset
127 return NULL;
kono
parents:
diff changeset
128 }
kono
parents:
diff changeset
129 gomp_mutex_unlock (&devices[device_id].lock);
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 return &devices[device_id];
kono
parents:
diff changeset
132 }
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134
kono
parents:
diff changeset
135 static inline splay_tree_key
kono
parents:
diff changeset
136 gomp_map_lookup (splay_tree mem_map, splay_tree_key key)
kono
parents:
diff changeset
137 {
kono
parents:
diff changeset
138 if (key->host_start != key->host_end)
kono
parents:
diff changeset
139 return splay_tree_lookup (mem_map, key);
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 key->host_end++;
kono
parents:
diff changeset
142 splay_tree_key n = splay_tree_lookup (mem_map, key);
kono
parents:
diff changeset
143 key->host_end--;
kono
parents:
diff changeset
144 if (n)
kono
parents:
diff changeset
145 return n;
kono
parents:
diff changeset
146 key->host_start--;
kono
parents:
diff changeset
147 n = splay_tree_lookup (mem_map, key);
kono
parents:
diff changeset
148 key->host_start++;
kono
parents:
diff changeset
149 if (n)
kono
parents:
diff changeset
150 return n;
kono
parents:
diff changeset
151 return splay_tree_lookup (mem_map, key);
kono
parents:
diff changeset
152 }
kono
parents:
diff changeset
153
kono
parents:
diff changeset
154 static inline splay_tree_key
kono
parents:
diff changeset
155 gomp_map_0len_lookup (splay_tree mem_map, splay_tree_key key)
kono
parents:
diff changeset
156 {
kono
parents:
diff changeset
157 if (key->host_start != key->host_end)
kono
parents:
diff changeset
158 return splay_tree_lookup (mem_map, key);
kono
parents:
diff changeset
159
kono
parents:
diff changeset
160 key->host_end++;
kono
parents:
diff changeset
161 splay_tree_key n = splay_tree_lookup (mem_map, key);
kono
parents:
diff changeset
162 key->host_end--;
kono
parents:
diff changeset
163 return n;
kono
parents:
diff changeset
164 }
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 static inline void
kono
parents:
diff changeset
167 gomp_device_copy (struct gomp_device_descr *devicep,
kono
parents:
diff changeset
168 bool (*copy_func) (int, void *, const void *, size_t),
kono
parents:
diff changeset
169 const char *dst, void *dstaddr,
kono
parents:
diff changeset
170 const char *src, const void *srcaddr,
kono
parents:
diff changeset
171 size_t size)
kono
parents:
diff changeset
172 {
kono
parents:
diff changeset
173 if (!copy_func (devicep->target_id, dstaddr, srcaddr, size))
kono
parents:
diff changeset
174 {
kono
parents:
diff changeset
175 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
176 gomp_fatal ("Copying of %s object [%p..%p) to %s object [%p..%p) failed",
kono
parents:
diff changeset
177 src, srcaddr, srcaddr + size, dst, dstaddr, dstaddr + size);
kono
parents:
diff changeset
178 }
kono
parents:
diff changeset
179 }
kono
parents:
diff changeset
180
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
181 static inline void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
182 goacc_device_copy_async (struct gomp_device_descr *devicep,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
183 bool (*copy_func) (int, void *, const void *, size_t,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
184 struct goacc_asyncqueue *),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
185 const char *dst, void *dstaddr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
186 const char *src, const void *srcaddr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
187 size_t size, struct goacc_asyncqueue *aq)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
188 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
189 if (!copy_func (devicep->target_id, dstaddr, srcaddr, size, aq))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
190 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
191 gomp_mutex_unlock (&devicep->lock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
192 gomp_fatal ("Copying of %s object [%p..%p) to %s object [%p..%p) failed",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
193 src, srcaddr, srcaddr + size, dst, dstaddr, dstaddr + size);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
194 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
195 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
196
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
197 /* Infrastructure for coalescing adjacent or nearly adjacent (in device addresses)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
198 host to device memory transfers. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
199
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
200 struct gomp_coalesce_chunk
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
201 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
202 /* The starting and ending point of a coalesced chunk of memory. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
203 size_t start, end;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
204 };
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
205
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
206 struct gomp_coalesce_buf
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
207 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
208 /* Buffer into which gomp_copy_host2dev will memcpy data and from which
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
209 it will be copied to the device. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
210 void *buf;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
211 struct target_mem_desc *tgt;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
212 /* Array with offsets, chunks[i].start is the starting offset and
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
213 chunks[i].end ending offset relative to tgt->tgt_start device address
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
214 of chunks which are to be copied to buf and later copied to device. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
215 struct gomp_coalesce_chunk *chunks;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
216 /* Number of chunks in chunks array, or -1 if coalesce buffering should not
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
217 be performed. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
218 long chunk_cnt;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
219 /* During construction of chunks array, how many memory regions are within
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
220 the last chunk. If there is just one memory region for a chunk, we copy
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
221 it directly to device rather than going through buf. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
222 long use_cnt;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
223 };
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
224
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
225 /* Maximum size of memory region considered for coalescing. Larger copies
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
226 are performed directly. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
227 #define MAX_COALESCE_BUF_SIZE (32 * 1024)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
228
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
229 /* Maximum size of a gap in between regions to consider them being copied
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
230 within the same chunk. All the device offsets considered are within
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
231 newly allocated device memory, so it isn't fatal if we copy some padding
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
232 in between from host to device. The gaps come either from alignment
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
233 padding or from memory regions which are not supposed to be copied from
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
234 host to device (e.g. map(alloc:), map(from:) etc.). */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
235 #define MAX_COALESCE_BUF_GAP (4 * 1024)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
236
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
237 /* Add region with device tgt_start relative offset and length to CBUF. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
238
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
239 static inline void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
240 gomp_coalesce_buf_add (struct gomp_coalesce_buf *cbuf, size_t start, size_t len)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
241 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
242 if (len > MAX_COALESCE_BUF_SIZE || len == 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
243 return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
244 if (cbuf->chunk_cnt)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
245 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
246 if (cbuf->chunk_cnt < 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
247 return;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
248 if (start < cbuf->chunks[cbuf->chunk_cnt - 1].end)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
249 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
250 cbuf->chunk_cnt = -1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
251 return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
252 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
253 if (start < cbuf->chunks[cbuf->chunk_cnt - 1].end + MAX_COALESCE_BUF_GAP)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
254 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
255 cbuf->chunks[cbuf->chunk_cnt - 1].end = start + len;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
256 cbuf->use_cnt++;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
257 return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
258 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
259 /* If the last chunk is only used by one mapping, discard it,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
260 as it will be one host to device copy anyway and
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
261 memcpying it around will only waste cycles. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
262 if (cbuf->use_cnt == 1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
263 cbuf->chunk_cnt--;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
264 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
265 cbuf->chunks[cbuf->chunk_cnt].start = start;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
266 cbuf->chunks[cbuf->chunk_cnt].end = start + len;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
267 cbuf->chunk_cnt++;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
268 cbuf->use_cnt = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
269 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
270
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
271 /* Return true for mapping kinds which need to copy data from the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
272 host to device for regions that weren't previously mapped. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
273
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
274 static inline bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
275 gomp_to_device_kind_p (int kind)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
276 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
277 switch (kind)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
278 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
279 case GOMP_MAP_ALLOC:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
280 case GOMP_MAP_FROM:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
281 case GOMP_MAP_FORCE_ALLOC:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
282 case GOMP_MAP_FORCE_FROM:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
283 case GOMP_MAP_ALWAYS_FROM:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
284 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
285 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
286 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
287 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
288 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
289
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
290 attribute_hidden void
111
kono
parents:
diff changeset
291 gomp_copy_host2dev (struct gomp_device_descr *devicep,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
292 struct goacc_asyncqueue *aq,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
293 void *d, const void *h, size_t sz,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
294 struct gomp_coalesce_buf *cbuf)
111
kono
parents:
diff changeset
295 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
296 if (cbuf)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
297 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
298 uintptr_t doff = (uintptr_t) d - cbuf->tgt->tgt_start;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
299 if (doff < cbuf->chunks[cbuf->chunk_cnt - 1].end)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
300 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
301 long first = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
302 long last = cbuf->chunk_cnt - 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
303 while (first <= last)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
304 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
305 long middle = (first + last) >> 1;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
306 if (cbuf->chunks[middle].end <= doff)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
307 first = middle + 1;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
308 else if (cbuf->chunks[middle].start <= doff)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
309 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
310 if (doff + sz > cbuf->chunks[middle].end)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
311 gomp_fatal ("internal libgomp cbuf error");
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
312 memcpy ((char *) cbuf->buf + (doff - cbuf->chunks[0].start),
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
313 h, sz);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
314 return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
315 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
316 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
317 last = middle - 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
318 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
319 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
320 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
321 if (__builtin_expect (aq != NULL, 0))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
322 goacc_device_copy_async (devicep, devicep->openacc.async.host2dev_func,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
323 "dev", d, "host", h, sz, aq);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
324 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
325 gomp_device_copy (devicep, devicep->host2dev_func, "dev", d, "host", h, sz);
111
kono
parents:
diff changeset
326 }
kono
parents:
diff changeset
327
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
328 attribute_hidden void
111
kono
parents:
diff changeset
329 gomp_copy_dev2host (struct gomp_device_descr *devicep,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
330 struct goacc_asyncqueue *aq,
111
kono
parents:
diff changeset
331 void *h, const void *d, size_t sz)
kono
parents:
diff changeset
332 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
333 if (__builtin_expect (aq != NULL, 0))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
334 goacc_device_copy_async (devicep, devicep->openacc.async.dev2host_func,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
335 "host", h, "dev", d, sz, aq);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
336 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
337 gomp_device_copy (devicep, devicep->dev2host_func, "host", h, "dev", d, sz);
111
kono
parents:
diff changeset
338 }
kono
parents:
diff changeset
339
kono
parents:
diff changeset
340 static void
kono
parents:
diff changeset
341 gomp_free_device_memory (struct gomp_device_descr *devicep, void *devptr)
kono
parents:
diff changeset
342 {
kono
parents:
diff changeset
343 if (!devicep->free_func (devicep->target_id, devptr))
kono
parents:
diff changeset
344 {
kono
parents:
diff changeset
345 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
346 gomp_fatal ("error in freeing device memory block at %p", devptr);
kono
parents:
diff changeset
347 }
kono
parents:
diff changeset
348 }
kono
parents:
diff changeset
349
kono
parents:
diff changeset
350 /* Handle the case where gomp_map_lookup, splay_tree_lookup or
kono
parents:
diff changeset
351 gomp_map_0len_lookup found oldn for newn.
kono
parents:
diff changeset
352 Helper function of gomp_map_vars. */
kono
parents:
diff changeset
353
kono
parents:
diff changeset
354 static inline void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
355 gomp_map_vars_existing (struct gomp_device_descr *devicep,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
356 struct goacc_asyncqueue *aq, splay_tree_key oldn,
111
kono
parents:
diff changeset
357 splay_tree_key newn, struct target_var_desc *tgt_var,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
358 unsigned char kind, struct gomp_coalesce_buf *cbuf)
111
kono
parents:
diff changeset
359 {
kono
parents:
diff changeset
360 tgt_var->key = oldn;
kono
parents:
diff changeset
361 tgt_var->copy_from = GOMP_MAP_COPY_FROM_P (kind);
kono
parents:
diff changeset
362 tgt_var->always_copy_from = GOMP_MAP_ALWAYS_FROM_P (kind);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
363 tgt_var->do_detach = kind == GOMP_MAP_ATTACH;
111
kono
parents:
diff changeset
364 tgt_var->offset = newn->host_start - oldn->host_start;
kono
parents:
diff changeset
365 tgt_var->length = newn->host_end - newn->host_start;
kono
parents:
diff changeset
366
kono
parents:
diff changeset
367 if ((kind & GOMP_MAP_FLAG_FORCE)
kono
parents:
diff changeset
368 || oldn->host_start > newn->host_start
kono
parents:
diff changeset
369 || oldn->host_end < newn->host_end)
kono
parents:
diff changeset
370 {
kono
parents:
diff changeset
371 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
372 gomp_fatal ("Trying to map into device [%p..%p) object when "
kono
parents:
diff changeset
373 "[%p..%p) is already mapped",
kono
parents:
diff changeset
374 (void *) newn->host_start, (void *) newn->host_end,
kono
parents:
diff changeset
375 (void *) oldn->host_start, (void *) oldn->host_end);
kono
parents:
diff changeset
376 }
kono
parents:
diff changeset
377
kono
parents:
diff changeset
378 if (GOMP_MAP_ALWAYS_TO_P (kind))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
379 gomp_copy_host2dev (devicep, aq,
111
kono
parents:
diff changeset
380 (void *) (oldn->tgt->tgt_start + oldn->tgt_offset
kono
parents:
diff changeset
381 + newn->host_start - oldn->host_start),
kono
parents:
diff changeset
382 (void *) newn->host_start,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
383 newn->host_end - newn->host_start, cbuf);
111
kono
parents:
diff changeset
384
kono
parents:
diff changeset
385 if (oldn->refcount != REFCOUNT_INFINITY)
kono
parents:
diff changeset
386 oldn->refcount++;
kono
parents:
diff changeset
387 }
kono
parents:
diff changeset
388
kono
parents:
diff changeset
389 static int
kono
parents:
diff changeset
390 get_kind (bool short_mapkind, void *kinds, int idx)
kono
parents:
diff changeset
391 {
kono
parents:
diff changeset
392 return short_mapkind ? ((unsigned short *) kinds)[idx]
kono
parents:
diff changeset
393 : ((unsigned char *) kinds)[idx];
kono
parents:
diff changeset
394 }
kono
parents:
diff changeset
395
kono
parents:
diff changeset
396 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
397 gomp_map_pointer (struct target_mem_desc *tgt, struct goacc_asyncqueue *aq,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
398 uintptr_t host_ptr, uintptr_t target_offset, uintptr_t bias,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
399 struct gomp_coalesce_buf *cbuf)
111
kono
parents:
diff changeset
400 {
kono
parents:
diff changeset
401 struct gomp_device_descr *devicep = tgt->device_descr;
kono
parents:
diff changeset
402 struct splay_tree_s *mem_map = &devicep->mem_map;
kono
parents:
diff changeset
403 struct splay_tree_key_s cur_node;
kono
parents:
diff changeset
404
kono
parents:
diff changeset
405 cur_node.host_start = host_ptr;
kono
parents:
diff changeset
406 if (cur_node.host_start == (uintptr_t) NULL)
kono
parents:
diff changeset
407 {
kono
parents:
diff changeset
408 cur_node.tgt_offset = (uintptr_t) NULL;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
409 gomp_copy_host2dev (devicep, aq,
111
kono
parents:
diff changeset
410 (void *) (tgt->tgt_start + target_offset),
kono
parents:
diff changeset
411 (void *) &cur_node.tgt_offset,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
412 sizeof (void *), cbuf);
111
kono
parents:
diff changeset
413 return;
kono
parents:
diff changeset
414 }
kono
parents:
diff changeset
415 /* Add bias to the pointer value. */
kono
parents:
diff changeset
416 cur_node.host_start += bias;
kono
parents:
diff changeset
417 cur_node.host_end = cur_node.host_start;
kono
parents:
diff changeset
418 splay_tree_key n = gomp_map_lookup (mem_map, &cur_node);
kono
parents:
diff changeset
419 if (n == NULL)
kono
parents:
diff changeset
420 {
kono
parents:
diff changeset
421 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
422 gomp_fatal ("Pointer target of array section wasn't mapped");
kono
parents:
diff changeset
423 }
kono
parents:
diff changeset
424 cur_node.host_start -= n->host_start;
kono
parents:
diff changeset
425 cur_node.tgt_offset
kono
parents:
diff changeset
426 = n->tgt->tgt_start + n->tgt_offset + cur_node.host_start;
kono
parents:
diff changeset
427 /* At this point tgt_offset is target address of the
kono
parents:
diff changeset
428 array section. Now subtract bias to get what we want
kono
parents:
diff changeset
429 to initialize the pointer with. */
kono
parents:
diff changeset
430 cur_node.tgt_offset -= bias;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
431 gomp_copy_host2dev (devicep, aq, (void *) (tgt->tgt_start + target_offset),
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
432 (void *) &cur_node.tgt_offset, sizeof (void *), cbuf);
111
kono
parents:
diff changeset
433 }
kono
parents:
diff changeset
434
kono
parents:
diff changeset
435 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
436 gomp_map_fields_existing (struct target_mem_desc *tgt,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
437 struct goacc_asyncqueue *aq, splay_tree_key n,
111
kono
parents:
diff changeset
438 size_t first, size_t i, void **hostaddrs,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
439 size_t *sizes, void *kinds,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
440 struct gomp_coalesce_buf *cbuf)
111
kono
parents:
diff changeset
441 {
kono
parents:
diff changeset
442 struct gomp_device_descr *devicep = tgt->device_descr;
kono
parents:
diff changeset
443 struct splay_tree_s *mem_map = &devicep->mem_map;
kono
parents:
diff changeset
444 struct splay_tree_key_s cur_node;
kono
parents:
diff changeset
445 int kind;
kono
parents:
diff changeset
446 const bool short_mapkind = true;
kono
parents:
diff changeset
447 const int typemask = short_mapkind ? 0xff : 0x7;
kono
parents:
diff changeset
448
kono
parents:
diff changeset
449 cur_node.host_start = (uintptr_t) hostaddrs[i];
kono
parents:
diff changeset
450 cur_node.host_end = cur_node.host_start + sizes[i];
kono
parents:
diff changeset
451 splay_tree_key n2 = splay_tree_lookup (mem_map, &cur_node);
kono
parents:
diff changeset
452 kind = get_kind (short_mapkind, kinds, i);
kono
parents:
diff changeset
453 if (n2
kono
parents:
diff changeset
454 && n2->tgt == n->tgt
kono
parents:
diff changeset
455 && n2->host_start - n->host_start == n2->tgt_offset - n->tgt_offset)
kono
parents:
diff changeset
456 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
457 gomp_map_vars_existing (devicep, aq, n2, &cur_node,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
458 &tgt->list[i], kind & typemask, cbuf);
111
kono
parents:
diff changeset
459 return;
kono
parents:
diff changeset
460 }
kono
parents:
diff changeset
461 if (sizes[i] == 0)
kono
parents:
diff changeset
462 {
kono
parents:
diff changeset
463 if (cur_node.host_start > (uintptr_t) hostaddrs[first - 1])
kono
parents:
diff changeset
464 {
kono
parents:
diff changeset
465 cur_node.host_start--;
kono
parents:
diff changeset
466 n2 = splay_tree_lookup (mem_map, &cur_node);
kono
parents:
diff changeset
467 cur_node.host_start++;
kono
parents:
diff changeset
468 if (n2
kono
parents:
diff changeset
469 && n2->tgt == n->tgt
kono
parents:
diff changeset
470 && n2->host_start - n->host_start
kono
parents:
diff changeset
471 == n2->tgt_offset - n->tgt_offset)
kono
parents:
diff changeset
472 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
473 gomp_map_vars_existing (devicep, aq, n2, &cur_node,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
474 &tgt->list[i], kind & typemask, cbuf);
111
kono
parents:
diff changeset
475 return;
kono
parents:
diff changeset
476 }
kono
parents:
diff changeset
477 }
kono
parents:
diff changeset
478 cur_node.host_end++;
kono
parents:
diff changeset
479 n2 = splay_tree_lookup (mem_map, &cur_node);
kono
parents:
diff changeset
480 cur_node.host_end--;
kono
parents:
diff changeset
481 if (n2
kono
parents:
diff changeset
482 && n2->tgt == n->tgt
kono
parents:
diff changeset
483 && n2->host_start - n->host_start == n2->tgt_offset - n->tgt_offset)
kono
parents:
diff changeset
484 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
485 gomp_map_vars_existing (devicep, aq, n2, &cur_node, &tgt->list[i],
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
486 kind & typemask, cbuf);
111
kono
parents:
diff changeset
487 return;
kono
parents:
diff changeset
488 }
kono
parents:
diff changeset
489 }
kono
parents:
diff changeset
490 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
491 gomp_fatal ("Trying to map into device [%p..%p) structure element when "
kono
parents:
diff changeset
492 "other mapped elements from the same structure weren't mapped "
kono
parents:
diff changeset
493 "together with it", (void *) cur_node.host_start,
kono
parents:
diff changeset
494 (void *) cur_node.host_end);
kono
parents:
diff changeset
495 }
kono
parents:
diff changeset
496
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
497 attribute_hidden void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
498 gomp_attach_pointer (struct gomp_device_descr *devicep,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
499 struct goacc_asyncqueue *aq, splay_tree mem_map,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
500 splay_tree_key n, uintptr_t attach_to, size_t bias,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
501 struct gomp_coalesce_buf *cbufp)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
502 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
503 struct splay_tree_key_s s;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
504 size_t size, idx;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
505
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
506 if (n == NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
507 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
508 gomp_mutex_unlock (&devicep->lock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
509 gomp_fatal ("enclosing struct not mapped for attach");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
510 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
511
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
512 size = (n->host_end - n->host_start + sizeof (void *) - 1) / sizeof (void *);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
513 /* We might have a pointer in a packed struct: however we cannot have more
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
514 than one such pointer in each pointer-sized portion of the struct, so
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
515 this is safe. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
516 idx = (attach_to - n->host_start) / sizeof (void *);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
517
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
518 if (!n->aux)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
519 n->aux = gomp_malloc_cleared (sizeof (struct splay_tree_aux));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
520
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
521 if (!n->aux->attach_count)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
522 n->aux->attach_count
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
523 = gomp_malloc_cleared (sizeof (*n->aux->attach_count) * size);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
524
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
525 if (n->aux->attach_count[idx] < UINTPTR_MAX)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
526 n->aux->attach_count[idx]++;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
527 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
528 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
529 gomp_mutex_unlock (&devicep->lock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
530 gomp_fatal ("attach count overflow");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
531 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
532
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
533 if (n->aux->attach_count[idx] == 1)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
534 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
535 uintptr_t devptr = n->tgt->tgt_start + n->tgt_offset + attach_to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
536 - n->host_start;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
537 uintptr_t target = (uintptr_t) *(void **) attach_to;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
538 splay_tree_key tn;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
539 uintptr_t data;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
540
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
541 if ((void *) target == NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
542 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
543 gomp_mutex_unlock (&devicep->lock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
544 gomp_fatal ("attempt to attach null pointer");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
545 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
546
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
547 s.host_start = target + bias;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
548 s.host_end = s.host_start + 1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
549 tn = splay_tree_lookup (mem_map, &s);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
550
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
551 if (!tn)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
552 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
553 gomp_mutex_unlock (&devicep->lock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
554 gomp_fatal ("pointer target not mapped for attach");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
555 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
556
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
557 data = tn->tgt->tgt_start + tn->tgt_offset + target - tn->host_start;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
558
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
559 gomp_debug (1,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
560 "%s: attaching host %p, target %p (struct base %p) to %p\n",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
561 __FUNCTION__, (void *) attach_to, (void *) devptr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
562 (void *) (n->tgt->tgt_start + n->tgt_offset), (void *) data);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
563
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
564 gomp_copy_host2dev (devicep, aq, (void *) devptr, (void *) &data,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
565 sizeof (void *), cbufp);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
566 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
567 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
568 gomp_debug (1, "%s: attach count for %p -> %u\n", __FUNCTION__,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
569 (void *) attach_to, (int) n->aux->attach_count[idx]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
570 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
571
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
572 attribute_hidden void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
573 gomp_detach_pointer (struct gomp_device_descr *devicep,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
574 struct goacc_asyncqueue *aq, splay_tree_key n,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
575 uintptr_t detach_from, bool finalize,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
576 struct gomp_coalesce_buf *cbufp)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
577 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
578 size_t idx;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
579
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
580 if (n == NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
581 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
582 gomp_mutex_unlock (&devicep->lock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
583 gomp_fatal ("enclosing struct not mapped for detach");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
584 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
585
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
586 idx = (detach_from - n->host_start) / sizeof (void *);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
587
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
588 if (!n->aux || !n->aux->attach_count)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
589 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
590 gomp_mutex_unlock (&devicep->lock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
591 gomp_fatal ("no attachment counters for struct");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
592 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
593
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
594 if (finalize)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
595 n->aux->attach_count[idx] = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
596
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
597 if (n->aux->attach_count[idx] == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
598 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
599 gomp_mutex_unlock (&devicep->lock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
600 gomp_fatal ("attach count underflow");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
601 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
602 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
603 n->aux->attach_count[idx]--;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
604
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
605 if (n->aux->attach_count[idx] == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
606 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
607 uintptr_t devptr = n->tgt->tgt_start + n->tgt_offset + detach_from
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
608 - n->host_start;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
609 uintptr_t target = (uintptr_t) *(void **) detach_from;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
610
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
611 gomp_debug (1,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
612 "%s: detaching host %p, target %p (struct base %p) to %p\n",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
613 __FUNCTION__, (void *) detach_from, (void *) devptr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
614 (void *) (n->tgt->tgt_start + n->tgt_offset),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
615 (void *) target);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
616
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
617 gomp_copy_host2dev (devicep, aq, (void *) devptr, (void *) &target,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
618 sizeof (void *), cbufp);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
619 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
620 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
621 gomp_debug (1, "%s: attach count for %p -> %u\n", __FUNCTION__,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
622 (void *) detach_from, (int) n->aux->attach_count[idx]);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
623 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
624
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
625 attribute_hidden uintptr_t
111
kono
parents:
diff changeset
626 gomp_map_val (struct target_mem_desc *tgt, void **hostaddrs, size_t i)
kono
parents:
diff changeset
627 {
kono
parents:
diff changeset
628 if (tgt->list[i].key != NULL)
kono
parents:
diff changeset
629 return tgt->list[i].key->tgt->tgt_start
kono
parents:
diff changeset
630 + tgt->list[i].key->tgt_offset
kono
parents:
diff changeset
631 + tgt->list[i].offset;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
632
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
633 switch (tgt->list[i].offset)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
634 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
635 case OFFSET_INLINED:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
636 return (uintptr_t) hostaddrs[i];
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
637
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
638 case OFFSET_POINTER:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
639 return 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
640
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
641 case OFFSET_STRUCT:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
642 return tgt->list[i + 1].key->tgt->tgt_start
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
643 + tgt->list[i + 1].key->tgt_offset
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
644 + tgt->list[i + 1].offset
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
645 + (uintptr_t) hostaddrs[i]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
646 - (uintptr_t) hostaddrs[i + 1];
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
647
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
648 default:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
649 return tgt->tgt_start + tgt->list[i].offset;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
650 }
111
kono
parents:
diff changeset
651 }
kono
parents:
diff changeset
652
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
653 static inline __attribute__((always_inline)) struct target_mem_desc *
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
654 gomp_map_vars_internal (struct gomp_device_descr *devicep,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
655 struct goacc_asyncqueue *aq, size_t mapnum,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
656 void **hostaddrs, void **devaddrs, size_t *sizes,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
657 void *kinds, bool short_mapkind,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
658 enum gomp_map_vars_kind pragma_kind)
111
kono
parents:
diff changeset
659 {
kono
parents:
diff changeset
660 size_t i, tgt_align, tgt_size, not_found_cnt = 0;
kono
parents:
diff changeset
661 bool has_firstprivate = false;
kono
parents:
diff changeset
662 const int rshift = short_mapkind ? 8 : 3;
kono
parents:
diff changeset
663 const int typemask = short_mapkind ? 0xff : 0x7;
kono
parents:
diff changeset
664 struct splay_tree_s *mem_map = &devicep->mem_map;
kono
parents:
diff changeset
665 struct splay_tree_key_s cur_node;
kono
parents:
diff changeset
666 struct target_mem_desc *tgt
kono
parents:
diff changeset
667 = gomp_malloc (sizeof (*tgt) + sizeof (tgt->list[0]) * mapnum);
kono
parents:
diff changeset
668 tgt->list_count = mapnum;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
669 tgt->refcount = (pragma_kind == GOMP_MAP_VARS_ENTER_DATA
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
670 || pragma_kind == GOMP_MAP_VARS_OPENACC_ENTER_DATA) ? 0 : 1;
111
kono
parents:
diff changeset
671 tgt->device_descr = devicep;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
672 tgt->prev = NULL;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
673 struct gomp_coalesce_buf cbuf, *cbufp = NULL;
111
kono
parents:
diff changeset
674
kono
parents:
diff changeset
675 if (mapnum == 0)
kono
parents:
diff changeset
676 {
kono
parents:
diff changeset
677 tgt->tgt_start = 0;
kono
parents:
diff changeset
678 tgt->tgt_end = 0;
kono
parents:
diff changeset
679 return tgt;
kono
parents:
diff changeset
680 }
kono
parents:
diff changeset
681
kono
parents:
diff changeset
682 tgt_align = sizeof (void *);
kono
parents:
diff changeset
683 tgt_size = 0;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
684 cbuf.chunks = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
685 cbuf.chunk_cnt = -1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
686 cbuf.use_cnt = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
687 cbuf.buf = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
688 if (mapnum > 1 || pragma_kind == GOMP_MAP_VARS_TARGET)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
689 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
690 size_t chunks_size = (mapnum + 1) * sizeof (struct gomp_coalesce_chunk);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
691 cbuf.chunks = (struct gomp_coalesce_chunk *) gomp_alloca (chunks_size);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
692 cbuf.chunk_cnt = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
693 }
111
kono
parents:
diff changeset
694 if (pragma_kind == GOMP_MAP_VARS_TARGET)
kono
parents:
diff changeset
695 {
kono
parents:
diff changeset
696 size_t align = 4 * sizeof (void *);
kono
parents:
diff changeset
697 tgt_align = align;
kono
parents:
diff changeset
698 tgt_size = mapnum * sizeof (void *);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
699 cbuf.chunk_cnt = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
700 cbuf.use_cnt = 1 + (mapnum > 1);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
701 cbuf.chunks[0].start = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
702 cbuf.chunks[0].end = tgt_size;
111
kono
parents:
diff changeset
703 }
kono
parents:
diff changeset
704
kono
parents:
diff changeset
705 gomp_mutex_lock (&devicep->lock);
kono
parents:
diff changeset
706 if (devicep->state == GOMP_DEVICE_FINALIZED)
kono
parents:
diff changeset
707 {
kono
parents:
diff changeset
708 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
709 free (tgt);
kono
parents:
diff changeset
710 return NULL;
kono
parents:
diff changeset
711 }
kono
parents:
diff changeset
712
kono
parents:
diff changeset
713 for (i = 0; i < mapnum; i++)
kono
parents:
diff changeset
714 {
kono
parents:
diff changeset
715 int kind = get_kind (short_mapkind, kinds, i);
kono
parents:
diff changeset
716 if (hostaddrs[i] == NULL
kono
parents:
diff changeset
717 || (kind & typemask) == GOMP_MAP_FIRSTPRIVATE_INT)
kono
parents:
diff changeset
718 {
kono
parents:
diff changeset
719 tgt->list[i].key = NULL;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
720 tgt->list[i].offset = OFFSET_INLINED;
111
kono
parents:
diff changeset
721 continue;
kono
parents:
diff changeset
722 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
723 else if ((kind & typemask) == GOMP_MAP_USE_DEVICE_PTR
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
724 || (kind & typemask) == GOMP_MAP_USE_DEVICE_PTR_IF_PRESENT)
111
kono
parents:
diff changeset
725 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
726 tgt->list[i].key = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
727 if (!not_found_cnt)
111
kono
parents:
diff changeset
728 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
729 /* In OpenMP < 5.0 and OpenACC the mapping has to be done
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
730 on a separate construct prior to using use_device_{addr,ptr}.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
731 In OpenMP 5.0, map directives need to be ordered by the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
732 middle-end before the use_device_* clauses. If
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
733 !not_found_cnt, all mappings requested (if any) are already
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
734 mapped, so use_device_{addr,ptr} can be resolved right away.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
735 Otherwise, if not_found_cnt, gomp_map_lookup might fail
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
736 now but would succeed after performing the mappings in the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
737 following loop. We can't defer this always to the second
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
738 loop, because it is not even invoked when !not_found_cnt
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
739 after the first loop. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
740 cur_node.host_start = (uintptr_t) hostaddrs[i];
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
741 cur_node.host_end = cur_node.host_start;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
742 splay_tree_key n = gomp_map_lookup (mem_map, &cur_node);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
743 if (n != NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
744 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
745 cur_node.host_start -= n->host_start;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
746 hostaddrs[i]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
747 = (void *) (n->tgt->tgt_start + n->tgt_offset
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
748 + cur_node.host_start);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
749 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
750 else if ((kind & typemask) == GOMP_MAP_USE_DEVICE_PTR)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
751 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
752 gomp_mutex_unlock (&devicep->lock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
753 gomp_fatal ("use_device_ptr pointer wasn't mapped");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
754 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
755 else if ((kind & typemask) == GOMP_MAP_USE_DEVICE_PTR_IF_PRESENT)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
756 /* If not present, continue using the host address. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
757 ;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
758 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
759 __builtin_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
760 tgt->list[i].offset = OFFSET_INLINED;
111
kono
parents:
diff changeset
761 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
762 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
763 tgt->list[i].offset = 0;
111
kono
parents:
diff changeset
764 continue;
kono
parents:
diff changeset
765 }
kono
parents:
diff changeset
766 else if ((kind & typemask) == GOMP_MAP_STRUCT)
kono
parents:
diff changeset
767 {
kono
parents:
diff changeset
768 size_t first = i + 1;
kono
parents:
diff changeset
769 size_t last = i + sizes[i];
kono
parents:
diff changeset
770 cur_node.host_start = (uintptr_t) hostaddrs[i];
kono
parents:
diff changeset
771 cur_node.host_end = (uintptr_t) hostaddrs[last]
kono
parents:
diff changeset
772 + sizes[last];
kono
parents:
diff changeset
773 tgt->list[i].key = NULL;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
774 tgt->list[i].offset = OFFSET_STRUCT;
111
kono
parents:
diff changeset
775 splay_tree_key n = splay_tree_lookup (mem_map, &cur_node);
kono
parents:
diff changeset
776 if (n == NULL)
kono
parents:
diff changeset
777 {
kono
parents:
diff changeset
778 size_t align = (size_t) 1 << (kind >> rshift);
kono
parents:
diff changeset
779 if (tgt_align < align)
kono
parents:
diff changeset
780 tgt_align = align;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
781 tgt_size -= (uintptr_t) hostaddrs[first] - cur_node.host_start;
111
kono
parents:
diff changeset
782 tgt_size = (tgt_size + align - 1) & ~(align - 1);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
783 tgt_size += cur_node.host_end - cur_node.host_start;
111
kono
parents:
diff changeset
784 not_found_cnt += last - i;
kono
parents:
diff changeset
785 for (i = first; i <= last; i++)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
786 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
787 tgt->list[i].key = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
788 if (gomp_to_device_kind_p (get_kind (short_mapkind, kinds, i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
789 & typemask))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
790 gomp_coalesce_buf_add (&cbuf,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
791 tgt_size - cur_node.host_end
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
792 + (uintptr_t) hostaddrs[i],
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
793 sizes[i]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
794 }
111
kono
parents:
diff changeset
795 i--;
kono
parents:
diff changeset
796 continue;
kono
parents:
diff changeset
797 }
kono
parents:
diff changeset
798 for (i = first; i <= last; i++)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
799 gomp_map_fields_existing (tgt, aq, n, first, i, hostaddrs,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
800 sizes, kinds, NULL);
111
kono
parents:
diff changeset
801 i--;
kono
parents:
diff changeset
802 continue;
kono
parents:
diff changeset
803 }
kono
parents:
diff changeset
804 else if ((kind & typemask) == GOMP_MAP_ALWAYS_POINTER)
kono
parents:
diff changeset
805 {
kono
parents:
diff changeset
806 tgt->list[i].key = NULL;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
807 tgt->list[i].offset = OFFSET_POINTER;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
808 has_firstprivate = true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
809 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
810 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
811 else if ((kind & typemask) == GOMP_MAP_ATTACH)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
812 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
813 tgt->list[i].key = NULL;
111
kono
parents:
diff changeset
814 has_firstprivate = true;
kono
parents:
diff changeset
815 continue;
kono
parents:
diff changeset
816 }
kono
parents:
diff changeset
817 cur_node.host_start = (uintptr_t) hostaddrs[i];
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
818 if (!GOMP_MAP_POINTER_P (kind & typemask)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
819 && (kind & typemask) != GOMP_MAP_ATTACH)
111
kono
parents:
diff changeset
820 cur_node.host_end = cur_node.host_start + sizes[i];
kono
parents:
diff changeset
821 else
kono
parents:
diff changeset
822 cur_node.host_end = cur_node.host_start + sizeof (void *);
kono
parents:
diff changeset
823 if ((kind & typemask) == GOMP_MAP_FIRSTPRIVATE)
kono
parents:
diff changeset
824 {
kono
parents:
diff changeset
825 tgt->list[i].key = NULL;
kono
parents:
diff changeset
826
kono
parents:
diff changeset
827 size_t align = (size_t) 1 << (kind >> rshift);
kono
parents:
diff changeset
828 if (tgt_align < align)
kono
parents:
diff changeset
829 tgt_align = align;
kono
parents:
diff changeset
830 tgt_size = (tgt_size + align - 1) & ~(align - 1);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
831 gomp_coalesce_buf_add (&cbuf, tgt_size,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
832 cur_node.host_end - cur_node.host_start);
111
kono
parents:
diff changeset
833 tgt_size += cur_node.host_end - cur_node.host_start;
kono
parents:
diff changeset
834 has_firstprivate = true;
kono
parents:
diff changeset
835 continue;
kono
parents:
diff changeset
836 }
kono
parents:
diff changeset
837 splay_tree_key n;
kono
parents:
diff changeset
838 if ((kind & typemask) == GOMP_MAP_ZERO_LEN_ARRAY_SECTION)
kono
parents:
diff changeset
839 {
kono
parents:
diff changeset
840 n = gomp_map_0len_lookup (mem_map, &cur_node);
kono
parents:
diff changeset
841 if (!n)
kono
parents:
diff changeset
842 {
kono
parents:
diff changeset
843 tgt->list[i].key = NULL;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
844 tgt->list[i].offset = OFFSET_POINTER;
111
kono
parents:
diff changeset
845 continue;
kono
parents:
diff changeset
846 }
kono
parents:
diff changeset
847 }
kono
parents:
diff changeset
848 else
kono
parents:
diff changeset
849 n = splay_tree_lookup (mem_map, &cur_node);
kono
parents:
diff changeset
850 if (n && n->refcount != REFCOUNT_LINK)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
851 gomp_map_vars_existing (devicep, aq, n, &cur_node, &tgt->list[i],
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
852 kind & typemask, NULL);
111
kono
parents:
diff changeset
853 else
kono
parents:
diff changeset
854 {
kono
parents:
diff changeset
855 tgt->list[i].key = NULL;
kono
parents:
diff changeset
856
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
857 if ((kind & typemask) == GOMP_MAP_IF_PRESENT)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
858 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
859 /* Not present, hence, skip entry - including its MAP_POINTER,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
860 when existing. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
861 tgt->list[i].offset = OFFSET_POINTER;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
862 if (i + 1 < mapnum
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
863 && ((typemask & get_kind (short_mapkind, kinds, i + 1))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
864 == GOMP_MAP_POINTER))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
865 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
866 ++i;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
867 tgt->list[i].key = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
868 tgt->list[i].offset = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
869 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
870 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
871 }
111
kono
parents:
diff changeset
872 size_t align = (size_t) 1 << (kind >> rshift);
kono
parents:
diff changeset
873 not_found_cnt++;
kono
parents:
diff changeset
874 if (tgt_align < align)
kono
parents:
diff changeset
875 tgt_align = align;
kono
parents:
diff changeset
876 tgt_size = (tgt_size + align - 1) & ~(align - 1);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
877 if (gomp_to_device_kind_p (kind & typemask))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
878 gomp_coalesce_buf_add (&cbuf, tgt_size,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
879 cur_node.host_end - cur_node.host_start);
111
kono
parents:
diff changeset
880 tgt_size += cur_node.host_end - cur_node.host_start;
kono
parents:
diff changeset
881 if ((kind & typemask) == GOMP_MAP_TO_PSET)
kono
parents:
diff changeset
882 {
kono
parents:
diff changeset
883 size_t j;
kono
parents:
diff changeset
884 for (j = i + 1; j < mapnum; j++)
kono
parents:
diff changeset
885 if (!GOMP_MAP_POINTER_P (get_kind (short_mapkind, kinds, j)
kono
parents:
diff changeset
886 & typemask))
kono
parents:
diff changeset
887 break;
kono
parents:
diff changeset
888 else if ((uintptr_t) hostaddrs[j] < cur_node.host_start
kono
parents:
diff changeset
889 || ((uintptr_t) hostaddrs[j] + sizeof (void *)
kono
parents:
diff changeset
890 > cur_node.host_end))
kono
parents:
diff changeset
891 break;
kono
parents:
diff changeset
892 else
kono
parents:
diff changeset
893 {
kono
parents:
diff changeset
894 tgt->list[j].key = NULL;
kono
parents:
diff changeset
895 i++;
kono
parents:
diff changeset
896 }
kono
parents:
diff changeset
897 }
kono
parents:
diff changeset
898 }
kono
parents:
diff changeset
899 }
kono
parents:
diff changeset
900
kono
parents:
diff changeset
901 if (devaddrs)
kono
parents:
diff changeset
902 {
kono
parents:
diff changeset
903 if (mapnum != 1)
kono
parents:
diff changeset
904 {
kono
parents:
diff changeset
905 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
906 gomp_fatal ("unexpected aggregation");
kono
parents:
diff changeset
907 }
kono
parents:
diff changeset
908 tgt->to_free = devaddrs[0];
kono
parents:
diff changeset
909 tgt->tgt_start = (uintptr_t) tgt->to_free;
kono
parents:
diff changeset
910 tgt->tgt_end = tgt->tgt_start + sizes[0];
kono
parents:
diff changeset
911 }
kono
parents:
diff changeset
912 else if (not_found_cnt || pragma_kind == GOMP_MAP_VARS_TARGET)
kono
parents:
diff changeset
913 {
kono
parents:
diff changeset
914 /* Allocate tgt_align aligned tgt_size block of memory. */
kono
parents:
diff changeset
915 /* FIXME: Perhaps change interface to allocate properly aligned
kono
parents:
diff changeset
916 memory. */
kono
parents:
diff changeset
917 tgt->to_free = devicep->alloc_func (devicep->target_id,
kono
parents:
diff changeset
918 tgt_size + tgt_align - 1);
kono
parents:
diff changeset
919 if (!tgt->to_free)
kono
parents:
diff changeset
920 {
kono
parents:
diff changeset
921 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
922 gomp_fatal ("device memory allocation fail");
kono
parents:
diff changeset
923 }
kono
parents:
diff changeset
924
kono
parents:
diff changeset
925 tgt->tgt_start = (uintptr_t) tgt->to_free;
kono
parents:
diff changeset
926 tgt->tgt_start = (tgt->tgt_start + tgt_align - 1) & ~(tgt_align - 1);
kono
parents:
diff changeset
927 tgt->tgt_end = tgt->tgt_start + tgt_size;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
928
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
929 if (cbuf.use_cnt == 1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
930 cbuf.chunk_cnt--;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
931 if (cbuf.chunk_cnt > 0)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
932 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
933 cbuf.buf
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
934 = malloc (cbuf.chunks[cbuf.chunk_cnt - 1].end - cbuf.chunks[0].start);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
935 if (cbuf.buf)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
936 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
937 cbuf.tgt = tgt;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
938 cbufp = &cbuf;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
939 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
940 }
111
kono
parents:
diff changeset
941 }
kono
parents:
diff changeset
942 else
kono
parents:
diff changeset
943 {
kono
parents:
diff changeset
944 tgt->to_free = NULL;
kono
parents:
diff changeset
945 tgt->tgt_start = 0;
kono
parents:
diff changeset
946 tgt->tgt_end = 0;
kono
parents:
diff changeset
947 }
kono
parents:
diff changeset
948
kono
parents:
diff changeset
949 tgt_size = 0;
kono
parents:
diff changeset
950 if (pragma_kind == GOMP_MAP_VARS_TARGET)
kono
parents:
diff changeset
951 tgt_size = mapnum * sizeof (void *);
kono
parents:
diff changeset
952
kono
parents:
diff changeset
953 tgt->array = NULL;
kono
parents:
diff changeset
954 if (not_found_cnt || has_firstprivate)
kono
parents:
diff changeset
955 {
kono
parents:
diff changeset
956 if (not_found_cnt)
kono
parents:
diff changeset
957 tgt->array = gomp_malloc (not_found_cnt * sizeof (*tgt->array));
kono
parents:
diff changeset
958 splay_tree_node array = tgt->array;
kono
parents:
diff changeset
959 size_t j, field_tgt_offset = 0, field_tgt_clear = ~(size_t) 0;
kono
parents:
diff changeset
960 uintptr_t field_tgt_base = 0;
kono
parents:
diff changeset
961
kono
parents:
diff changeset
962 for (i = 0; i < mapnum; i++)
kono
parents:
diff changeset
963 if (tgt->list[i].key == NULL)
kono
parents:
diff changeset
964 {
kono
parents:
diff changeset
965 int kind = get_kind (short_mapkind, kinds, i);
kono
parents:
diff changeset
966 if (hostaddrs[i] == NULL)
kono
parents:
diff changeset
967 continue;
kono
parents:
diff changeset
968 switch (kind & typemask)
kono
parents:
diff changeset
969 {
kono
parents:
diff changeset
970 size_t align, len, first, last;
kono
parents:
diff changeset
971 splay_tree_key n;
kono
parents:
diff changeset
972 case GOMP_MAP_FIRSTPRIVATE:
kono
parents:
diff changeset
973 align = (size_t) 1 << (kind >> rshift);
kono
parents:
diff changeset
974 tgt_size = (tgt_size + align - 1) & ~(align - 1);
kono
parents:
diff changeset
975 tgt->list[i].offset = tgt_size;
kono
parents:
diff changeset
976 len = sizes[i];
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
977 gomp_copy_host2dev (devicep, aq,
111
kono
parents:
diff changeset
978 (void *) (tgt->tgt_start + tgt_size),
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
979 (void *) hostaddrs[i], len, cbufp);
111
kono
parents:
diff changeset
980 tgt_size += len;
kono
parents:
diff changeset
981 continue;
kono
parents:
diff changeset
982 case GOMP_MAP_FIRSTPRIVATE_INT:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
983 case GOMP_MAP_ZERO_LEN_ARRAY_SECTION:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
984 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
985 case GOMP_MAP_USE_DEVICE_PTR_IF_PRESENT:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
986 /* The OpenACC 'host_data' construct only allows 'use_device'
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
987 "mapping" clauses, so in the first loop, 'not_found_cnt'
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
988 must always have been zero, so all OpenACC 'use_device'
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
989 clauses have already been handled. (We can only easily test
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
990 'use_device' with 'if_present' clause here.) */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
991 assert (tgt->list[i].offset == OFFSET_INLINED);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
992 /* Nevertheless, FALLTHRU to the normal handling, to keep the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
993 code conceptually simple, similar to the first loop. */
111
kono
parents:
diff changeset
994 case GOMP_MAP_USE_DEVICE_PTR:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
995 if (tgt->list[i].offset == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
996 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
997 cur_node.host_start = (uintptr_t) hostaddrs[i];
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
998 cur_node.host_end = cur_node.host_start;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
999 n = gomp_map_lookup (mem_map, &cur_node);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1000 if (n != NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1001 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1002 cur_node.host_start -= n->host_start;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1003 hostaddrs[i]
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1004 = (void *) (n->tgt->tgt_start + n->tgt_offset
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1005 + cur_node.host_start);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1006 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1007 else if ((kind & typemask) == GOMP_MAP_USE_DEVICE_PTR)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1008 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1009 gomp_mutex_unlock (&devicep->lock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1010 gomp_fatal ("use_device_ptr pointer wasn't mapped");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1011 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1012 else if ((kind & typemask)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1013 == GOMP_MAP_USE_DEVICE_PTR_IF_PRESENT)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1014 /* If not present, continue using the host address. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1015 ;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1016 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1017 __builtin_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1018 tgt->list[i].offset = OFFSET_INLINED;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1019 }
111
kono
parents:
diff changeset
1020 continue;
kono
parents:
diff changeset
1021 case GOMP_MAP_STRUCT:
kono
parents:
diff changeset
1022 first = i + 1;
kono
parents:
diff changeset
1023 last = i + sizes[i];
kono
parents:
diff changeset
1024 cur_node.host_start = (uintptr_t) hostaddrs[i];
kono
parents:
diff changeset
1025 cur_node.host_end = (uintptr_t) hostaddrs[last]
kono
parents:
diff changeset
1026 + sizes[last];
kono
parents:
diff changeset
1027 if (tgt->list[first].key != NULL)
kono
parents:
diff changeset
1028 continue;
kono
parents:
diff changeset
1029 n = splay_tree_lookup (mem_map, &cur_node);
kono
parents:
diff changeset
1030 if (n == NULL)
kono
parents:
diff changeset
1031 {
kono
parents:
diff changeset
1032 size_t align = (size_t) 1 << (kind >> rshift);
kono
parents:
diff changeset
1033 tgt_size -= (uintptr_t) hostaddrs[first]
kono
parents:
diff changeset
1034 - (uintptr_t) hostaddrs[i];
kono
parents:
diff changeset
1035 tgt_size = (tgt_size + align - 1) & ~(align - 1);
kono
parents:
diff changeset
1036 tgt_size += (uintptr_t) hostaddrs[first]
kono
parents:
diff changeset
1037 - (uintptr_t) hostaddrs[i];
kono
parents:
diff changeset
1038 field_tgt_base = (uintptr_t) hostaddrs[first];
kono
parents:
diff changeset
1039 field_tgt_offset = tgt_size;
kono
parents:
diff changeset
1040 field_tgt_clear = last;
kono
parents:
diff changeset
1041 tgt_size += cur_node.host_end
kono
parents:
diff changeset
1042 - (uintptr_t) hostaddrs[first];
kono
parents:
diff changeset
1043 continue;
kono
parents:
diff changeset
1044 }
kono
parents:
diff changeset
1045 for (i = first; i <= last; i++)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1046 gomp_map_fields_existing (tgt, aq, n, first, i, hostaddrs,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1047 sizes, kinds, cbufp);
111
kono
parents:
diff changeset
1048 i--;
kono
parents:
diff changeset
1049 continue;
kono
parents:
diff changeset
1050 case GOMP_MAP_ALWAYS_POINTER:
kono
parents:
diff changeset
1051 cur_node.host_start = (uintptr_t) hostaddrs[i];
kono
parents:
diff changeset
1052 cur_node.host_end = cur_node.host_start + sizeof (void *);
kono
parents:
diff changeset
1053 n = splay_tree_lookup (mem_map, &cur_node);
kono
parents:
diff changeset
1054 if (n == NULL
kono
parents:
diff changeset
1055 || n->host_start > cur_node.host_start
kono
parents:
diff changeset
1056 || n->host_end < cur_node.host_end)
kono
parents:
diff changeset
1057 {
kono
parents:
diff changeset
1058 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1059 gomp_fatal ("always pointer not mapped");
kono
parents:
diff changeset
1060 }
kono
parents:
diff changeset
1061 if ((get_kind (short_mapkind, kinds, i - 1) & typemask)
kono
parents:
diff changeset
1062 != GOMP_MAP_ALWAYS_POINTER)
kono
parents:
diff changeset
1063 cur_node.tgt_offset = gomp_map_val (tgt, hostaddrs, i - 1);
kono
parents:
diff changeset
1064 if (cur_node.tgt_offset)
kono
parents:
diff changeset
1065 cur_node.tgt_offset -= sizes[i];
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1066 gomp_copy_host2dev (devicep, aq,
111
kono
parents:
diff changeset
1067 (void *) (n->tgt->tgt_start
kono
parents:
diff changeset
1068 + n->tgt_offset
kono
parents:
diff changeset
1069 + cur_node.host_start
kono
parents:
diff changeset
1070 - n->host_start),
kono
parents:
diff changeset
1071 (void *) &cur_node.tgt_offset,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1072 sizeof (void *), cbufp);
111
kono
parents:
diff changeset
1073 cur_node.tgt_offset = n->tgt->tgt_start + n->tgt_offset
kono
parents:
diff changeset
1074 + cur_node.host_start - n->host_start;
kono
parents:
diff changeset
1075 continue;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1076 case GOMP_MAP_IF_PRESENT:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1077 /* Not present - otherwise handled above. Skip over its
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1078 MAP_POINTER as well. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1079 if (i + 1 < mapnum
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1080 && ((typemask & get_kind (short_mapkind, kinds, i + 1))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1081 == GOMP_MAP_POINTER))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1082 ++i;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1083 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1084 case GOMP_MAP_ATTACH:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1085 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1086 cur_node.host_start = (uintptr_t) hostaddrs[i];
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1087 cur_node.host_end = cur_node.host_start + sizeof (void *);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1088 splay_tree_key n = splay_tree_lookup (mem_map, &cur_node);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1089 if (n != NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1090 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1091 tgt->list[i].key = n;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1092 tgt->list[i].offset = cur_node.host_start - n->host_start;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1093 tgt->list[i].length = n->host_end - n->host_start;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1094 tgt->list[i].copy_from = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1095 tgt->list[i].always_copy_from = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1096 tgt->list[i].do_detach
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1097 = (pragma_kind != GOMP_MAP_VARS_OPENACC_ENTER_DATA);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1098 n->refcount++;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1099 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1100 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1101 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1102 gomp_mutex_unlock (&devicep->lock);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1103 gomp_fatal ("outer struct not mapped for attach");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1104 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1105 gomp_attach_pointer (devicep, aq, mem_map, n,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1106 (uintptr_t) hostaddrs[i], sizes[i],
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1107 cbufp);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1108 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1109 }
111
kono
parents:
diff changeset
1110 default:
kono
parents:
diff changeset
1111 break;
kono
parents:
diff changeset
1112 }
kono
parents:
diff changeset
1113 splay_tree_key k = &array->key;
kono
parents:
diff changeset
1114 k->host_start = (uintptr_t) hostaddrs[i];
kono
parents:
diff changeset
1115 if (!GOMP_MAP_POINTER_P (kind & typemask))
kono
parents:
diff changeset
1116 k->host_end = k->host_start + sizes[i];
kono
parents:
diff changeset
1117 else
kono
parents:
diff changeset
1118 k->host_end = k->host_start + sizeof (void *);
kono
parents:
diff changeset
1119 splay_tree_key n = splay_tree_lookup (mem_map, k);
kono
parents:
diff changeset
1120 if (n && n->refcount != REFCOUNT_LINK)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1121 gomp_map_vars_existing (devicep, aq, n, k, &tgt->list[i],
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1122 kind & typemask, cbufp);
111
kono
parents:
diff changeset
1123 else
kono
parents:
diff changeset
1124 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1125 k->aux = NULL;
111
kono
parents:
diff changeset
1126 if (n && n->refcount == REFCOUNT_LINK)
kono
parents:
diff changeset
1127 {
kono
parents:
diff changeset
1128 /* Replace target address of the pointer with target address
kono
parents:
diff changeset
1129 of mapped object in the splay tree. */
kono
parents:
diff changeset
1130 splay_tree_remove (mem_map, n);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1131 k->aux
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1132 = gomp_malloc_cleared (sizeof (struct splay_tree_aux));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1133 k->aux->link_key = n;
111
kono
parents:
diff changeset
1134 }
kono
parents:
diff changeset
1135 size_t align = (size_t) 1 << (kind >> rshift);
kono
parents:
diff changeset
1136 tgt->list[i].key = k;
kono
parents:
diff changeset
1137 k->tgt = tgt;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1138 if (field_tgt_clear != FIELD_TGT_EMPTY)
111
kono
parents:
diff changeset
1139 {
kono
parents:
diff changeset
1140 k->tgt_offset = k->host_start - field_tgt_base
kono
parents:
diff changeset
1141 + field_tgt_offset;
kono
parents:
diff changeset
1142 if (i == field_tgt_clear)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1143 field_tgt_clear = FIELD_TGT_EMPTY;
111
kono
parents:
diff changeset
1144 }
kono
parents:
diff changeset
1145 else
kono
parents:
diff changeset
1146 {
kono
parents:
diff changeset
1147 tgt_size = (tgt_size + align - 1) & ~(align - 1);
kono
parents:
diff changeset
1148 k->tgt_offset = tgt_size;
kono
parents:
diff changeset
1149 tgt_size += k->host_end - k->host_start;
kono
parents:
diff changeset
1150 }
kono
parents:
diff changeset
1151 tgt->list[i].copy_from = GOMP_MAP_COPY_FROM_P (kind & typemask);
kono
parents:
diff changeset
1152 tgt->list[i].always_copy_from
kono
parents:
diff changeset
1153 = GOMP_MAP_ALWAYS_FROM_P (kind & typemask);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1154 tgt->list[i].do_detach = false;
111
kono
parents:
diff changeset
1155 tgt->list[i].offset = 0;
kono
parents:
diff changeset
1156 tgt->list[i].length = k->host_end - k->host_start;
kono
parents:
diff changeset
1157 k->refcount = 1;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1158 k->virtual_refcount = 0;
111
kono
parents:
diff changeset
1159 tgt->refcount++;
kono
parents:
diff changeset
1160 array->left = NULL;
kono
parents:
diff changeset
1161 array->right = NULL;
kono
parents:
diff changeset
1162 splay_tree_insert (mem_map, array);
kono
parents:
diff changeset
1163 switch (kind & typemask)
kono
parents:
diff changeset
1164 {
kono
parents:
diff changeset
1165 case GOMP_MAP_ALLOC:
kono
parents:
diff changeset
1166 case GOMP_MAP_FROM:
kono
parents:
diff changeset
1167 case GOMP_MAP_FORCE_ALLOC:
kono
parents:
diff changeset
1168 case GOMP_MAP_FORCE_FROM:
kono
parents:
diff changeset
1169 case GOMP_MAP_ALWAYS_FROM:
kono
parents:
diff changeset
1170 break;
kono
parents:
diff changeset
1171 case GOMP_MAP_TO:
kono
parents:
diff changeset
1172 case GOMP_MAP_TOFROM:
kono
parents:
diff changeset
1173 case GOMP_MAP_FORCE_TO:
kono
parents:
diff changeset
1174 case GOMP_MAP_FORCE_TOFROM:
kono
parents:
diff changeset
1175 case GOMP_MAP_ALWAYS_TO:
kono
parents:
diff changeset
1176 case GOMP_MAP_ALWAYS_TOFROM:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1177 gomp_copy_host2dev (devicep, aq,
111
kono
parents:
diff changeset
1178 (void *) (tgt->tgt_start
kono
parents:
diff changeset
1179 + k->tgt_offset),
kono
parents:
diff changeset
1180 (void *) k->host_start,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1181 k->host_end - k->host_start, cbufp);
111
kono
parents:
diff changeset
1182 break;
kono
parents:
diff changeset
1183 case GOMP_MAP_POINTER:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1184 gomp_map_pointer (tgt, aq,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1185 (uintptr_t) *(void **) k->host_start,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1186 k->tgt_offset, sizes[i], cbufp);
111
kono
parents:
diff changeset
1187 break;
kono
parents:
diff changeset
1188 case GOMP_MAP_TO_PSET:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1189 gomp_copy_host2dev (devicep, aq,
111
kono
parents:
diff changeset
1190 (void *) (tgt->tgt_start
kono
parents:
diff changeset
1191 + k->tgt_offset),
kono
parents:
diff changeset
1192 (void *) k->host_start,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1193 k->host_end - k->host_start, cbufp);
111
kono
parents:
diff changeset
1194
kono
parents:
diff changeset
1195 for (j = i + 1; j < mapnum; j++)
kono
parents:
diff changeset
1196 if (!GOMP_MAP_POINTER_P (get_kind (short_mapkind, kinds,
kono
parents:
diff changeset
1197 j)
kono
parents:
diff changeset
1198 & typemask))
kono
parents:
diff changeset
1199 break;
kono
parents:
diff changeset
1200 else if ((uintptr_t) hostaddrs[j] < k->host_start
kono
parents:
diff changeset
1201 || ((uintptr_t) hostaddrs[j] + sizeof (void *)
kono
parents:
diff changeset
1202 > k->host_end))
kono
parents:
diff changeset
1203 break;
kono
parents:
diff changeset
1204 else
kono
parents:
diff changeset
1205 {
kono
parents:
diff changeset
1206 tgt->list[j].key = k;
kono
parents:
diff changeset
1207 tgt->list[j].copy_from = false;
kono
parents:
diff changeset
1208 tgt->list[j].always_copy_from = false;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1209 tgt->list[j].do_detach = false;
111
kono
parents:
diff changeset
1210 if (k->refcount != REFCOUNT_INFINITY)
kono
parents:
diff changeset
1211 k->refcount++;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1212 gomp_map_pointer (tgt, aq,
111
kono
parents:
diff changeset
1213 (uintptr_t) *(void **) hostaddrs[j],
kono
parents:
diff changeset
1214 k->tgt_offset
kono
parents:
diff changeset
1215 + ((uintptr_t) hostaddrs[j]
kono
parents:
diff changeset
1216 - k->host_start),
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1217 sizes[j], cbufp);
111
kono
parents:
diff changeset
1218 i++;
kono
parents:
diff changeset
1219 }
kono
parents:
diff changeset
1220 break;
kono
parents:
diff changeset
1221 case GOMP_MAP_FORCE_PRESENT:
kono
parents:
diff changeset
1222 {
kono
parents:
diff changeset
1223 /* We already looked up the memory region above and it
kono
parents:
diff changeset
1224 was missing. */
kono
parents:
diff changeset
1225 size_t size = k->host_end - k->host_start;
kono
parents:
diff changeset
1226 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1227 #ifdef HAVE_INTTYPES_H
kono
parents:
diff changeset
1228 gomp_fatal ("present clause: !acc_is_present (%p, "
kono
parents:
diff changeset
1229 "%"PRIu64" (0x%"PRIx64"))",
kono
parents:
diff changeset
1230 (void *) k->host_start,
kono
parents:
diff changeset
1231 (uint64_t) size, (uint64_t) size);
kono
parents:
diff changeset
1232 #else
kono
parents:
diff changeset
1233 gomp_fatal ("present clause: !acc_is_present (%p, "
kono
parents:
diff changeset
1234 "%lu (0x%lx))", (void *) k->host_start,
kono
parents:
diff changeset
1235 (unsigned long) size, (unsigned long) size);
kono
parents:
diff changeset
1236 #endif
kono
parents:
diff changeset
1237 }
kono
parents:
diff changeset
1238 break;
kono
parents:
diff changeset
1239 case GOMP_MAP_FORCE_DEVICEPTR:
kono
parents:
diff changeset
1240 assert (k->host_end - k->host_start == sizeof (void *));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1241 gomp_copy_host2dev (devicep, aq,
111
kono
parents:
diff changeset
1242 (void *) (tgt->tgt_start
kono
parents:
diff changeset
1243 + k->tgt_offset),
kono
parents:
diff changeset
1244 (void *) k->host_start,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1245 sizeof (void *), cbufp);
111
kono
parents:
diff changeset
1246 break;
kono
parents:
diff changeset
1247 default:
kono
parents:
diff changeset
1248 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1249 gomp_fatal ("%s: unhandled kind 0x%.2x", __FUNCTION__,
kono
parents:
diff changeset
1250 kind);
kono
parents:
diff changeset
1251 }
kono
parents:
diff changeset
1252
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1253 if (k->aux && k->aux->link_key)
111
kono
parents:
diff changeset
1254 {
kono
parents:
diff changeset
1255 /* Set link pointer on target to the device address of the
kono
parents:
diff changeset
1256 mapped object. */
kono
parents:
diff changeset
1257 void *tgt_addr = (void *) (tgt->tgt_start + k->tgt_offset);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1258 /* We intentionally do not use coalescing here, as it's not
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1259 data allocated by the current call to this function. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1260 gomp_copy_host2dev (devicep, aq, (void *) n->tgt_offset,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1261 &tgt_addr, sizeof (void *), NULL);
111
kono
parents:
diff changeset
1262 }
kono
parents:
diff changeset
1263 array++;
kono
parents:
diff changeset
1264 }
kono
parents:
diff changeset
1265 }
kono
parents:
diff changeset
1266 }
kono
parents:
diff changeset
1267
kono
parents:
diff changeset
1268 if (pragma_kind == GOMP_MAP_VARS_TARGET)
kono
parents:
diff changeset
1269 {
kono
parents:
diff changeset
1270 for (i = 0; i < mapnum; i++)
kono
parents:
diff changeset
1271 {
kono
parents:
diff changeset
1272 cur_node.tgt_offset = gomp_map_val (tgt, hostaddrs, i);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1273 gomp_copy_host2dev (devicep, aq,
111
kono
parents:
diff changeset
1274 (void *) (tgt->tgt_start + i * sizeof (void *)),
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1275 (void *) &cur_node.tgt_offset, sizeof (void *),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1276 cbufp);
111
kono
parents:
diff changeset
1277 }
kono
parents:
diff changeset
1278 }
kono
parents:
diff changeset
1279
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1280 if (cbufp)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1281 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1282 long c = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1283 for (c = 0; c < cbuf.chunk_cnt; ++c)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1284 gomp_copy_host2dev (devicep, aq,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1285 (void *) (tgt->tgt_start + cbuf.chunks[c].start),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1286 (char *) cbuf.buf + (cbuf.chunks[c].start
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1287 - cbuf.chunks[0].start),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1288 cbuf.chunks[c].end - cbuf.chunks[c].start, NULL);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1289 free (cbuf.buf);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1290 cbuf.buf = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1291 cbufp = NULL;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1292 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1293
111
kono
parents:
diff changeset
1294 /* If the variable from "omp target enter data" map-list was already mapped,
kono
parents:
diff changeset
1295 tgt is not needed. Otherwise tgt will be freed by gomp_unmap_vars or
kono
parents:
diff changeset
1296 gomp_exit_data. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1297 if ((pragma_kind == GOMP_MAP_VARS_ENTER_DATA
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1298 || pragma_kind == GOMP_MAP_VARS_OPENACC_ENTER_DATA)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1299 && tgt->refcount == 0)
111
kono
parents:
diff changeset
1300 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1301 /* If we're about to discard a target_mem_desc with no "structural"
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1302 references (tgt->refcount == 0), any splay keys linked in the tgt's
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1303 list must have their virtual refcount incremented to represent that
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1304 "lost" reference in order to implement the semantics of the OpenACC
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1305 "present increment" operation properly. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1306 if (pragma_kind == GOMP_MAP_VARS_OPENACC_ENTER_DATA)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1307 for (i = 0; i < tgt->list_count; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1308 if (tgt->list[i].key)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1309 tgt->list[i].key->virtual_refcount++;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1310
111
kono
parents:
diff changeset
1311 free (tgt);
kono
parents:
diff changeset
1312 tgt = NULL;
kono
parents:
diff changeset
1313 }
kono
parents:
diff changeset
1314
kono
parents:
diff changeset
1315 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1316 return tgt;
kono
parents:
diff changeset
1317 }
kono
parents:
diff changeset
1318
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1319 attribute_hidden struct target_mem_desc *
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1320 gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1321 void **hostaddrs, void **devaddrs, size_t *sizes, void *kinds,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1322 bool short_mapkind, enum gomp_map_vars_kind pragma_kind)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1323 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1324 return gomp_map_vars_internal (devicep, NULL, mapnum, hostaddrs, devaddrs,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1325 sizes, kinds, short_mapkind, pragma_kind);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1326 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1327
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1328 attribute_hidden struct target_mem_desc *
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1329 gomp_map_vars_async (struct gomp_device_descr *devicep,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1330 struct goacc_asyncqueue *aq, size_t mapnum,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1331 void **hostaddrs, void **devaddrs, size_t *sizes,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1332 void *kinds, bool short_mapkind,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1333 enum gomp_map_vars_kind pragma_kind)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1334 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1335 return gomp_map_vars_internal (devicep, aq, mapnum, hostaddrs, devaddrs,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1336 sizes, kinds, short_mapkind, pragma_kind);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1337 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1338
111
kono
parents:
diff changeset
1339 static void
kono
parents:
diff changeset
1340 gomp_unmap_tgt (struct target_mem_desc *tgt)
kono
parents:
diff changeset
1341 {
kono
parents:
diff changeset
1342 /* Deallocate on target the tgt->tgt_start .. tgt->tgt_end region. */
kono
parents:
diff changeset
1343 if (tgt->tgt_end)
kono
parents:
diff changeset
1344 gomp_free_device_memory (tgt->device_descr, tgt->to_free);
kono
parents:
diff changeset
1345
kono
parents:
diff changeset
1346 free (tgt->array);
kono
parents:
diff changeset
1347 free (tgt);
kono
parents:
diff changeset
1348 }
kono
parents:
diff changeset
1349
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1350 static bool
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1351 gomp_unref_tgt (void *ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1352 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1353 bool is_tgt_unmapped = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1354
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1355 struct target_mem_desc *tgt = (struct target_mem_desc *) ptr;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1356
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1357 if (tgt->refcount > 1)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1358 tgt->refcount--;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1359 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1360 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1361 gomp_unmap_tgt (tgt);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1362 is_tgt_unmapped = true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1363 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1364
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1365 return is_tgt_unmapped;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1366 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1367
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1368 static void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1369 gomp_unref_tgt_void (void *ptr)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1370 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1371 (void) gomp_unref_tgt (ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1372 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1373
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1374 static inline __attribute__((always_inline)) bool
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1375 gomp_remove_var_internal (struct gomp_device_descr *devicep, splay_tree_key k,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1376 struct goacc_asyncqueue *aq)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1377 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1378 bool is_tgt_unmapped = false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1379 splay_tree_remove (&devicep->mem_map, k);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1380 if (k->aux)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1381 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1382 if (k->aux->link_key)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1383 splay_tree_insert (&devicep->mem_map,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1384 (splay_tree_node) k->aux->link_key);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1385 if (k->aux->attach_count)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1386 free (k->aux->attach_count);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1387 free (k->aux);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1388 k->aux = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1389 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1390 if (aq)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1391 devicep->openacc.async.queue_callback_func (aq, gomp_unref_tgt_void,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1392 (void *) k->tgt);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1393 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1394 is_tgt_unmapped = gomp_unref_tgt ((void *) k->tgt);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1395 return is_tgt_unmapped;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1396 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1397
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1398 attribute_hidden bool
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1399 gomp_remove_var (struct gomp_device_descr *devicep, splay_tree_key k)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1400 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1401 return gomp_remove_var_internal (devicep, k, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1402 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1403
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1404 /* Remove a variable asynchronously. This actually removes the variable
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1405 mapping immediately, but retains the linked target_mem_desc until the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1406 asynchronous operation has completed (as it may still refer to target
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1407 memory). The device lock must be held before entry, and remains locked on
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1408 exit. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1409
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1410 attribute_hidden void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1411 gomp_remove_var_async (struct gomp_device_descr *devicep, splay_tree_key k,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1412 struct goacc_asyncqueue *aq)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1413 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1414 (void) gomp_remove_var_internal (devicep, k, aq);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1415 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1416
111
kono
parents:
diff changeset
1417 /* Unmap variables described by TGT. If DO_COPYFROM is true, copy relevant
kono
parents:
diff changeset
1418 variables back from device to host: if it is false, it is assumed that this
kono
parents:
diff changeset
1419 has been done already. */
kono
parents:
diff changeset
1420
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1421 static inline __attribute__((always_inline)) void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1422 gomp_unmap_vars_internal (struct target_mem_desc *tgt, bool do_copyfrom,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1423 struct goacc_asyncqueue *aq)
111
kono
parents:
diff changeset
1424 {
kono
parents:
diff changeset
1425 struct gomp_device_descr *devicep = tgt->device_descr;
kono
parents:
diff changeset
1426
kono
parents:
diff changeset
1427 if (tgt->list_count == 0)
kono
parents:
diff changeset
1428 {
kono
parents:
diff changeset
1429 free (tgt);
kono
parents:
diff changeset
1430 return;
kono
parents:
diff changeset
1431 }
kono
parents:
diff changeset
1432
kono
parents:
diff changeset
1433 gomp_mutex_lock (&devicep->lock);
kono
parents:
diff changeset
1434 if (devicep->state == GOMP_DEVICE_FINALIZED)
kono
parents:
diff changeset
1435 {
kono
parents:
diff changeset
1436 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1437 free (tgt->array);
kono
parents:
diff changeset
1438 free (tgt);
kono
parents:
diff changeset
1439 return;
kono
parents:
diff changeset
1440 }
kono
parents:
diff changeset
1441
kono
parents:
diff changeset
1442 size_t i;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1443
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1444 /* We must perform detachments before any copies back to the host. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1445 for (i = 0; i < tgt->list_count; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1446 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1447 splay_tree_key k = tgt->list[i].key;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1448
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1449 if (k != NULL && tgt->list[i].do_detach)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1450 gomp_detach_pointer (devicep, aq, k, tgt->list[i].key->host_start
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1451 + tgt->list[i].offset,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1452 k->refcount == 1, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1453 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1454
111
kono
parents:
diff changeset
1455 for (i = 0; i < tgt->list_count; i++)
kono
parents:
diff changeset
1456 {
kono
parents:
diff changeset
1457 splay_tree_key k = tgt->list[i].key;
kono
parents:
diff changeset
1458 if (k == NULL)
kono
parents:
diff changeset
1459 continue;
kono
parents:
diff changeset
1460
kono
parents:
diff changeset
1461 bool do_unmap = false;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1462 if (k->tgt == tgt
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1463 && k->virtual_refcount > 0
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1464 && k->refcount != REFCOUNT_INFINITY)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1465 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1466 k->virtual_refcount--;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1467 k->refcount--;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1468 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1469 else if (k->refcount > 1 && k->refcount != REFCOUNT_INFINITY)
111
kono
parents:
diff changeset
1470 k->refcount--;
kono
parents:
diff changeset
1471 else if (k->refcount == 1)
kono
parents:
diff changeset
1472 {
kono
parents:
diff changeset
1473 k->refcount--;
kono
parents:
diff changeset
1474 do_unmap = true;
kono
parents:
diff changeset
1475 }
kono
parents:
diff changeset
1476
kono
parents:
diff changeset
1477 if ((do_unmap && do_copyfrom && tgt->list[i].copy_from)
kono
parents:
diff changeset
1478 || tgt->list[i].always_copy_from)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1479 gomp_copy_dev2host (devicep, aq,
111
kono
parents:
diff changeset
1480 (void *) (k->host_start + tgt->list[i].offset),
kono
parents:
diff changeset
1481 (void *) (k->tgt->tgt_start + k->tgt_offset
kono
parents:
diff changeset
1482 + tgt->list[i].offset),
kono
parents:
diff changeset
1483 tgt->list[i].length);
kono
parents:
diff changeset
1484 if (do_unmap)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1485 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1486 struct target_mem_desc *k_tgt = k->tgt;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1487 bool is_tgt_unmapped = gomp_remove_var (devicep, k);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1488 /* It would be bad if TGT got unmapped while we're still iterating
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1489 over its LIST_COUNT, and also expect to use it in the following
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1490 code. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1491 assert (!is_tgt_unmapped
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1492 || k_tgt != tgt);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1493 }
111
kono
parents:
diff changeset
1494 }
kono
parents:
diff changeset
1495
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1496 if (aq)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1497 devicep->openacc.async.queue_callback_func (aq, gomp_unref_tgt_void,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1498 (void *) tgt);
111
kono
parents:
diff changeset
1499 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1500 gomp_unref_tgt ((void *) tgt);
111
kono
parents:
diff changeset
1501
kono
parents:
diff changeset
1502 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1503 }
kono
parents:
diff changeset
1504
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1505 attribute_hidden void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1506 gomp_unmap_vars (struct target_mem_desc *tgt, bool do_copyfrom)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1507 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1508 gomp_unmap_vars_internal (tgt, do_copyfrom, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1509 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1510
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1511 attribute_hidden void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1512 gomp_unmap_vars_async (struct target_mem_desc *tgt, bool do_copyfrom,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1513 struct goacc_asyncqueue *aq)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1514 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1515 gomp_unmap_vars_internal (tgt, do_copyfrom, aq);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1516 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1517
111
kono
parents:
diff changeset
1518 static void
kono
parents:
diff changeset
1519 gomp_update (struct gomp_device_descr *devicep, size_t mapnum, void **hostaddrs,
kono
parents:
diff changeset
1520 size_t *sizes, void *kinds, bool short_mapkind)
kono
parents:
diff changeset
1521 {
kono
parents:
diff changeset
1522 size_t i;
kono
parents:
diff changeset
1523 struct splay_tree_key_s cur_node;
kono
parents:
diff changeset
1524 const int typemask = short_mapkind ? 0xff : 0x7;
kono
parents:
diff changeset
1525
kono
parents:
diff changeset
1526 if (!devicep)
kono
parents:
diff changeset
1527 return;
kono
parents:
diff changeset
1528
kono
parents:
diff changeset
1529 if (mapnum == 0)
kono
parents:
diff changeset
1530 return;
kono
parents:
diff changeset
1531
kono
parents:
diff changeset
1532 gomp_mutex_lock (&devicep->lock);
kono
parents:
diff changeset
1533 if (devicep->state == GOMP_DEVICE_FINALIZED)
kono
parents:
diff changeset
1534 {
kono
parents:
diff changeset
1535 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1536 return;
kono
parents:
diff changeset
1537 }
kono
parents:
diff changeset
1538
kono
parents:
diff changeset
1539 for (i = 0; i < mapnum; i++)
kono
parents:
diff changeset
1540 if (sizes[i])
kono
parents:
diff changeset
1541 {
kono
parents:
diff changeset
1542 cur_node.host_start = (uintptr_t) hostaddrs[i];
kono
parents:
diff changeset
1543 cur_node.host_end = cur_node.host_start + sizes[i];
kono
parents:
diff changeset
1544 splay_tree_key n = splay_tree_lookup (&devicep->mem_map, &cur_node);
kono
parents:
diff changeset
1545 if (n)
kono
parents:
diff changeset
1546 {
kono
parents:
diff changeset
1547 int kind = get_kind (short_mapkind, kinds, i);
kono
parents:
diff changeset
1548 if (n->host_start > cur_node.host_start
kono
parents:
diff changeset
1549 || n->host_end < cur_node.host_end)
kono
parents:
diff changeset
1550 {
kono
parents:
diff changeset
1551 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1552 gomp_fatal ("Trying to update [%p..%p) object when "
kono
parents:
diff changeset
1553 "only [%p..%p) is mapped",
kono
parents:
diff changeset
1554 (void *) cur_node.host_start,
kono
parents:
diff changeset
1555 (void *) cur_node.host_end,
kono
parents:
diff changeset
1556 (void *) n->host_start,
kono
parents:
diff changeset
1557 (void *) n->host_end);
kono
parents:
diff changeset
1558 }
kono
parents:
diff changeset
1559
kono
parents:
diff changeset
1560
kono
parents:
diff changeset
1561 void *hostaddr = (void *) cur_node.host_start;
kono
parents:
diff changeset
1562 void *devaddr = (void *) (n->tgt->tgt_start + n->tgt_offset
kono
parents:
diff changeset
1563 + cur_node.host_start - n->host_start);
kono
parents:
diff changeset
1564 size_t size = cur_node.host_end - cur_node.host_start;
kono
parents:
diff changeset
1565
kono
parents:
diff changeset
1566 if (GOMP_MAP_COPY_TO_P (kind & typemask))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1567 gomp_copy_host2dev (devicep, NULL, devaddr, hostaddr, size,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1568 NULL);
111
kono
parents:
diff changeset
1569 if (GOMP_MAP_COPY_FROM_P (kind & typemask))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1570 gomp_copy_dev2host (devicep, NULL, hostaddr, devaddr, size);
111
kono
parents:
diff changeset
1571 }
kono
parents:
diff changeset
1572 }
kono
parents:
diff changeset
1573 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1574 }
kono
parents:
diff changeset
1575
kono
parents:
diff changeset
1576 /* Load image pointed by TARGET_DATA to the device, specified by DEVICEP.
kono
parents:
diff changeset
1577 And insert to splay tree the mapping between addresses from HOST_TABLE and
kono
parents:
diff changeset
1578 from loaded target image. We rely in the host and device compiler
kono
parents:
diff changeset
1579 emitting variable and functions in the same order. */
kono
parents:
diff changeset
1580
kono
parents:
diff changeset
1581 static void
kono
parents:
diff changeset
1582 gomp_load_image_to_device (struct gomp_device_descr *devicep, unsigned version,
kono
parents:
diff changeset
1583 const void *host_table, const void *target_data,
kono
parents:
diff changeset
1584 bool is_register_lock)
kono
parents:
diff changeset
1585 {
kono
parents:
diff changeset
1586 void **host_func_table = ((void ***) host_table)[0];
kono
parents:
diff changeset
1587 void **host_funcs_end = ((void ***) host_table)[1];
kono
parents:
diff changeset
1588 void **host_var_table = ((void ***) host_table)[2];
kono
parents:
diff changeset
1589 void **host_vars_end = ((void ***) host_table)[3];
kono
parents:
diff changeset
1590
kono
parents:
diff changeset
1591 /* The func table contains only addresses, the var table contains addresses
kono
parents:
diff changeset
1592 and corresponding sizes. */
kono
parents:
diff changeset
1593 int num_funcs = host_funcs_end - host_func_table;
kono
parents:
diff changeset
1594 int num_vars = (host_vars_end - host_var_table) / 2;
kono
parents:
diff changeset
1595
kono
parents:
diff changeset
1596 /* Load image to device and get target addresses for the image. */
kono
parents:
diff changeset
1597 struct addr_pair *target_table = NULL;
kono
parents:
diff changeset
1598 int i, num_target_entries;
kono
parents:
diff changeset
1599
kono
parents:
diff changeset
1600 num_target_entries
kono
parents:
diff changeset
1601 = devicep->load_image_func (devicep->target_id, version,
kono
parents:
diff changeset
1602 target_data, &target_table);
kono
parents:
diff changeset
1603
kono
parents:
diff changeset
1604 if (num_target_entries != num_funcs + num_vars)
kono
parents:
diff changeset
1605 {
kono
parents:
diff changeset
1606 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1607 if (is_register_lock)
kono
parents:
diff changeset
1608 gomp_mutex_unlock (&register_lock);
kono
parents:
diff changeset
1609 gomp_fatal ("Cannot map target functions or variables"
kono
parents:
diff changeset
1610 " (expected %u, have %u)", num_funcs + num_vars,
kono
parents:
diff changeset
1611 num_target_entries);
kono
parents:
diff changeset
1612 }
kono
parents:
diff changeset
1613
kono
parents:
diff changeset
1614 /* Insert host-target address mapping into splay tree. */
kono
parents:
diff changeset
1615 struct target_mem_desc *tgt = gomp_malloc (sizeof (*tgt));
kono
parents:
diff changeset
1616 tgt->array = gomp_malloc ((num_funcs + num_vars) * sizeof (*tgt->array));
kono
parents:
diff changeset
1617 tgt->refcount = REFCOUNT_INFINITY;
kono
parents:
diff changeset
1618 tgt->tgt_start = 0;
kono
parents:
diff changeset
1619 tgt->tgt_end = 0;
kono
parents:
diff changeset
1620 tgt->to_free = NULL;
kono
parents:
diff changeset
1621 tgt->prev = NULL;
kono
parents:
diff changeset
1622 tgt->list_count = 0;
kono
parents:
diff changeset
1623 tgt->device_descr = devicep;
kono
parents:
diff changeset
1624 splay_tree_node array = tgt->array;
kono
parents:
diff changeset
1625
kono
parents:
diff changeset
1626 for (i = 0; i < num_funcs; i++)
kono
parents:
diff changeset
1627 {
kono
parents:
diff changeset
1628 splay_tree_key k = &array->key;
kono
parents:
diff changeset
1629 k->host_start = (uintptr_t) host_func_table[i];
kono
parents:
diff changeset
1630 k->host_end = k->host_start + 1;
kono
parents:
diff changeset
1631 k->tgt = tgt;
kono
parents:
diff changeset
1632 k->tgt_offset = target_table[i].start;
kono
parents:
diff changeset
1633 k->refcount = REFCOUNT_INFINITY;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1634 k->virtual_refcount = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1635 k->aux = NULL;
111
kono
parents:
diff changeset
1636 array->left = NULL;
kono
parents:
diff changeset
1637 array->right = NULL;
kono
parents:
diff changeset
1638 splay_tree_insert (&devicep->mem_map, array);
kono
parents:
diff changeset
1639 array++;
kono
parents:
diff changeset
1640 }
kono
parents:
diff changeset
1641
kono
parents:
diff changeset
1642 /* Most significant bit of the size in host and target tables marks
kono
parents:
diff changeset
1643 "omp declare target link" variables. */
kono
parents:
diff changeset
1644 const uintptr_t link_bit = 1ULL << (sizeof (uintptr_t) * __CHAR_BIT__ - 1);
kono
parents:
diff changeset
1645 const uintptr_t size_mask = ~link_bit;
kono
parents:
diff changeset
1646
kono
parents:
diff changeset
1647 for (i = 0; i < num_vars; i++)
kono
parents:
diff changeset
1648 {
kono
parents:
diff changeset
1649 struct addr_pair *target_var = &target_table[num_funcs + i];
kono
parents:
diff changeset
1650 uintptr_t target_size = target_var->end - target_var->start;
kono
parents:
diff changeset
1651
kono
parents:
diff changeset
1652 if ((uintptr_t) host_var_table[i * 2 + 1] != target_size)
kono
parents:
diff changeset
1653 {
kono
parents:
diff changeset
1654 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1655 if (is_register_lock)
kono
parents:
diff changeset
1656 gomp_mutex_unlock (&register_lock);
kono
parents:
diff changeset
1657 gomp_fatal ("Cannot map target variables (size mismatch)");
kono
parents:
diff changeset
1658 }
kono
parents:
diff changeset
1659
kono
parents:
diff changeset
1660 splay_tree_key k = &array->key;
kono
parents:
diff changeset
1661 k->host_start = (uintptr_t) host_var_table[i * 2];
kono
parents:
diff changeset
1662 k->host_end
kono
parents:
diff changeset
1663 = k->host_start + (size_mask & (uintptr_t) host_var_table[i * 2 + 1]);
kono
parents:
diff changeset
1664 k->tgt = tgt;
kono
parents:
diff changeset
1665 k->tgt_offset = target_var->start;
kono
parents:
diff changeset
1666 k->refcount = target_size & link_bit ? REFCOUNT_LINK : REFCOUNT_INFINITY;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1667 k->virtual_refcount = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1668 k->aux = NULL;
111
kono
parents:
diff changeset
1669 array->left = NULL;
kono
parents:
diff changeset
1670 array->right = NULL;
kono
parents:
diff changeset
1671 splay_tree_insert (&devicep->mem_map, array);
kono
parents:
diff changeset
1672 array++;
kono
parents:
diff changeset
1673 }
kono
parents:
diff changeset
1674
kono
parents:
diff changeset
1675 free (target_table);
kono
parents:
diff changeset
1676 }
kono
parents:
diff changeset
1677
kono
parents:
diff changeset
1678 /* Unload the mappings described by target_data from device DEVICE_P.
kono
parents:
diff changeset
1679 The device must be locked. */
kono
parents:
diff changeset
1680
kono
parents:
diff changeset
1681 static void
kono
parents:
diff changeset
1682 gomp_unload_image_from_device (struct gomp_device_descr *devicep,
kono
parents:
diff changeset
1683 unsigned version,
kono
parents:
diff changeset
1684 const void *host_table, const void *target_data)
kono
parents:
diff changeset
1685 {
kono
parents:
diff changeset
1686 void **host_func_table = ((void ***) host_table)[0];
kono
parents:
diff changeset
1687 void **host_funcs_end = ((void ***) host_table)[1];
kono
parents:
diff changeset
1688 void **host_var_table = ((void ***) host_table)[2];
kono
parents:
diff changeset
1689 void **host_vars_end = ((void ***) host_table)[3];
kono
parents:
diff changeset
1690
kono
parents:
diff changeset
1691 /* The func table contains only addresses, the var table contains addresses
kono
parents:
diff changeset
1692 and corresponding sizes. */
kono
parents:
diff changeset
1693 int num_funcs = host_funcs_end - host_func_table;
kono
parents:
diff changeset
1694 int num_vars = (host_vars_end - host_var_table) / 2;
kono
parents:
diff changeset
1695
kono
parents:
diff changeset
1696 struct splay_tree_key_s k;
kono
parents:
diff changeset
1697 splay_tree_key node = NULL;
kono
parents:
diff changeset
1698
kono
parents:
diff changeset
1699 /* Find mapping at start of node array */
kono
parents:
diff changeset
1700 if (num_funcs || num_vars)
kono
parents:
diff changeset
1701 {
kono
parents:
diff changeset
1702 k.host_start = (num_funcs ? (uintptr_t) host_func_table[0]
kono
parents:
diff changeset
1703 : (uintptr_t) host_var_table[0]);
kono
parents:
diff changeset
1704 k.host_end = k.host_start + 1;
kono
parents:
diff changeset
1705 node = splay_tree_lookup (&devicep->mem_map, &k);
kono
parents:
diff changeset
1706 }
kono
parents:
diff changeset
1707
kono
parents:
diff changeset
1708 if (!devicep->unload_image_func (devicep->target_id, version, target_data))
kono
parents:
diff changeset
1709 {
kono
parents:
diff changeset
1710 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1711 gomp_fatal ("image unload fail");
kono
parents:
diff changeset
1712 }
kono
parents:
diff changeset
1713
kono
parents:
diff changeset
1714 /* Remove mappings from splay tree. */
kono
parents:
diff changeset
1715 int i;
kono
parents:
diff changeset
1716 for (i = 0; i < num_funcs; i++)
kono
parents:
diff changeset
1717 {
kono
parents:
diff changeset
1718 k.host_start = (uintptr_t) host_func_table[i];
kono
parents:
diff changeset
1719 k.host_end = k.host_start + 1;
kono
parents:
diff changeset
1720 splay_tree_remove (&devicep->mem_map, &k);
kono
parents:
diff changeset
1721 }
kono
parents:
diff changeset
1722
kono
parents:
diff changeset
1723 /* Most significant bit of the size in host and target tables marks
kono
parents:
diff changeset
1724 "omp declare target link" variables. */
kono
parents:
diff changeset
1725 const uintptr_t link_bit = 1ULL << (sizeof (uintptr_t) * __CHAR_BIT__ - 1);
kono
parents:
diff changeset
1726 const uintptr_t size_mask = ~link_bit;
kono
parents:
diff changeset
1727 bool is_tgt_unmapped = false;
kono
parents:
diff changeset
1728
kono
parents:
diff changeset
1729 for (i = 0; i < num_vars; i++)
kono
parents:
diff changeset
1730 {
kono
parents:
diff changeset
1731 k.host_start = (uintptr_t) host_var_table[i * 2];
kono
parents:
diff changeset
1732 k.host_end
kono
parents:
diff changeset
1733 = k.host_start + (size_mask & (uintptr_t) host_var_table[i * 2 + 1]);
kono
parents:
diff changeset
1734
kono
parents:
diff changeset
1735 if (!(link_bit & (uintptr_t) host_var_table[i * 2 + 1]))
kono
parents:
diff changeset
1736 splay_tree_remove (&devicep->mem_map, &k);
kono
parents:
diff changeset
1737 else
kono
parents:
diff changeset
1738 {
kono
parents:
diff changeset
1739 splay_tree_key n = splay_tree_lookup (&devicep->mem_map, &k);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1740 is_tgt_unmapped = gomp_remove_var (devicep, n);
111
kono
parents:
diff changeset
1741 }
kono
parents:
diff changeset
1742 }
kono
parents:
diff changeset
1743
kono
parents:
diff changeset
1744 if (node && !is_tgt_unmapped)
kono
parents:
diff changeset
1745 {
kono
parents:
diff changeset
1746 free (node->tgt);
kono
parents:
diff changeset
1747 free (node);
kono
parents:
diff changeset
1748 }
kono
parents:
diff changeset
1749 }
kono
parents:
diff changeset
1750
kono
parents:
diff changeset
1751 /* This function should be called from every offload image while loading.
kono
parents:
diff changeset
1752 It gets the descriptor of the host func and var tables HOST_TABLE, TYPE of
kono
parents:
diff changeset
1753 the target, and TARGET_DATA needed by target plugin. */
kono
parents:
diff changeset
1754
kono
parents:
diff changeset
1755 void
kono
parents:
diff changeset
1756 GOMP_offload_register_ver (unsigned version, const void *host_table,
kono
parents:
diff changeset
1757 int target_type, const void *target_data)
kono
parents:
diff changeset
1758 {
kono
parents:
diff changeset
1759 int i;
kono
parents:
diff changeset
1760
kono
parents:
diff changeset
1761 if (GOMP_VERSION_LIB (version) > GOMP_VERSION)
kono
parents:
diff changeset
1762 gomp_fatal ("Library too old for offload (version %u < %u)",
kono
parents:
diff changeset
1763 GOMP_VERSION, GOMP_VERSION_LIB (version));
kono
parents:
diff changeset
1764
kono
parents:
diff changeset
1765 gomp_mutex_lock (&register_lock);
kono
parents:
diff changeset
1766
kono
parents:
diff changeset
1767 /* Load image to all initialized devices. */
kono
parents:
diff changeset
1768 for (i = 0; i < num_devices; i++)
kono
parents:
diff changeset
1769 {
kono
parents:
diff changeset
1770 struct gomp_device_descr *devicep = &devices[i];
kono
parents:
diff changeset
1771 gomp_mutex_lock (&devicep->lock);
kono
parents:
diff changeset
1772 if (devicep->type == target_type
kono
parents:
diff changeset
1773 && devicep->state == GOMP_DEVICE_INITIALIZED)
kono
parents:
diff changeset
1774 gomp_load_image_to_device (devicep, version,
kono
parents:
diff changeset
1775 host_table, target_data, true);
kono
parents:
diff changeset
1776 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1777 }
kono
parents:
diff changeset
1778
kono
parents:
diff changeset
1779 /* Insert image to array of pending images. */
kono
parents:
diff changeset
1780 offload_images
kono
parents:
diff changeset
1781 = gomp_realloc_unlock (offload_images,
kono
parents:
diff changeset
1782 (num_offload_images + 1)
kono
parents:
diff changeset
1783 * sizeof (struct offload_image_descr));
kono
parents:
diff changeset
1784 offload_images[num_offload_images].version = version;
kono
parents:
diff changeset
1785 offload_images[num_offload_images].type = target_type;
kono
parents:
diff changeset
1786 offload_images[num_offload_images].host_table = host_table;
kono
parents:
diff changeset
1787 offload_images[num_offload_images].target_data = target_data;
kono
parents:
diff changeset
1788
kono
parents:
diff changeset
1789 num_offload_images++;
kono
parents:
diff changeset
1790 gomp_mutex_unlock (&register_lock);
kono
parents:
diff changeset
1791 }
kono
parents:
diff changeset
1792
kono
parents:
diff changeset
1793 void
kono
parents:
diff changeset
1794 GOMP_offload_register (const void *host_table, int target_type,
kono
parents:
diff changeset
1795 const void *target_data)
kono
parents:
diff changeset
1796 {
kono
parents:
diff changeset
1797 GOMP_offload_register_ver (0, host_table, target_type, target_data);
kono
parents:
diff changeset
1798 }
kono
parents:
diff changeset
1799
kono
parents:
diff changeset
1800 /* This function should be called from every offload image while unloading.
kono
parents:
diff changeset
1801 It gets the descriptor of the host func and var tables HOST_TABLE, TYPE of
kono
parents:
diff changeset
1802 the target, and TARGET_DATA needed by target plugin. */
kono
parents:
diff changeset
1803
kono
parents:
diff changeset
1804 void
kono
parents:
diff changeset
1805 GOMP_offload_unregister_ver (unsigned version, const void *host_table,
kono
parents:
diff changeset
1806 int target_type, const void *target_data)
kono
parents:
diff changeset
1807 {
kono
parents:
diff changeset
1808 int i;
kono
parents:
diff changeset
1809
kono
parents:
diff changeset
1810 gomp_mutex_lock (&register_lock);
kono
parents:
diff changeset
1811
kono
parents:
diff changeset
1812 /* Unload image from all initialized devices. */
kono
parents:
diff changeset
1813 for (i = 0; i < num_devices; i++)
kono
parents:
diff changeset
1814 {
kono
parents:
diff changeset
1815 struct gomp_device_descr *devicep = &devices[i];
kono
parents:
diff changeset
1816 gomp_mutex_lock (&devicep->lock);
kono
parents:
diff changeset
1817 if (devicep->type == target_type
kono
parents:
diff changeset
1818 && devicep->state == GOMP_DEVICE_INITIALIZED)
kono
parents:
diff changeset
1819 gomp_unload_image_from_device (devicep, version,
kono
parents:
diff changeset
1820 host_table, target_data);
kono
parents:
diff changeset
1821 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1822 }
kono
parents:
diff changeset
1823
kono
parents:
diff changeset
1824 /* Remove image from array of pending images. */
kono
parents:
diff changeset
1825 for (i = 0; i < num_offload_images; i++)
kono
parents:
diff changeset
1826 if (offload_images[i].target_data == target_data)
kono
parents:
diff changeset
1827 {
kono
parents:
diff changeset
1828 offload_images[i] = offload_images[--num_offload_images];
kono
parents:
diff changeset
1829 break;
kono
parents:
diff changeset
1830 }
kono
parents:
diff changeset
1831
kono
parents:
diff changeset
1832 gomp_mutex_unlock (&register_lock);
kono
parents:
diff changeset
1833 }
kono
parents:
diff changeset
1834
kono
parents:
diff changeset
1835 void
kono
parents:
diff changeset
1836 GOMP_offload_unregister (const void *host_table, int target_type,
kono
parents:
diff changeset
1837 const void *target_data)
kono
parents:
diff changeset
1838 {
kono
parents:
diff changeset
1839 GOMP_offload_unregister_ver (0, host_table, target_type, target_data);
kono
parents:
diff changeset
1840 }
kono
parents:
diff changeset
1841
kono
parents:
diff changeset
1842 /* This function initializes the target device, specified by DEVICEP. DEVICEP
kono
parents:
diff changeset
1843 must be locked on entry, and remains locked on return. */
kono
parents:
diff changeset
1844
kono
parents:
diff changeset
1845 attribute_hidden void
kono
parents:
diff changeset
1846 gomp_init_device (struct gomp_device_descr *devicep)
kono
parents:
diff changeset
1847 {
kono
parents:
diff changeset
1848 int i;
kono
parents:
diff changeset
1849 if (!devicep->init_device_func (devicep->target_id))
kono
parents:
diff changeset
1850 {
kono
parents:
diff changeset
1851 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1852 gomp_fatal ("device initialization failed");
kono
parents:
diff changeset
1853 }
kono
parents:
diff changeset
1854
kono
parents:
diff changeset
1855 /* Load to device all images registered by the moment. */
kono
parents:
diff changeset
1856 for (i = 0; i < num_offload_images; i++)
kono
parents:
diff changeset
1857 {
kono
parents:
diff changeset
1858 struct offload_image_descr *image = &offload_images[i];
kono
parents:
diff changeset
1859 if (image->type == devicep->type)
kono
parents:
diff changeset
1860 gomp_load_image_to_device (devicep, image->version,
kono
parents:
diff changeset
1861 image->host_table, image->target_data,
kono
parents:
diff changeset
1862 false);
kono
parents:
diff changeset
1863 }
kono
parents:
diff changeset
1864
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1865 /* Initialize OpenACC asynchronous queues. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1866 goacc_init_asyncqueues (devicep);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1867
111
kono
parents:
diff changeset
1868 devicep->state = GOMP_DEVICE_INITIALIZED;
kono
parents:
diff changeset
1869 }
kono
parents:
diff changeset
1870
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1871 /* This function finalizes the target device, specified by DEVICEP. DEVICEP
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1872 must be locked on entry, and remains locked on return. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1873
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1874 attribute_hidden bool
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1875 gomp_fini_device (struct gomp_device_descr *devicep)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1876 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1877 bool ret = goacc_fini_asyncqueues (devicep);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1878 ret &= devicep->fini_device_func (devicep->target_id);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1879 devicep->state = GOMP_DEVICE_FINALIZED;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1880 return ret;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1881 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1882
111
kono
parents:
diff changeset
1883 attribute_hidden void
kono
parents:
diff changeset
1884 gomp_unload_device (struct gomp_device_descr *devicep)
kono
parents:
diff changeset
1885 {
kono
parents:
diff changeset
1886 if (devicep->state == GOMP_DEVICE_INITIALIZED)
kono
parents:
diff changeset
1887 {
kono
parents:
diff changeset
1888 unsigned i;
kono
parents:
diff changeset
1889
kono
parents:
diff changeset
1890 /* Unload from device all images registered at the moment. */
kono
parents:
diff changeset
1891 for (i = 0; i < num_offload_images; i++)
kono
parents:
diff changeset
1892 {
kono
parents:
diff changeset
1893 struct offload_image_descr *image = &offload_images[i];
kono
parents:
diff changeset
1894 if (image->type == devicep->type)
kono
parents:
diff changeset
1895 gomp_unload_image_from_device (devicep, image->version,
kono
parents:
diff changeset
1896 image->host_table,
kono
parents:
diff changeset
1897 image->target_data);
kono
parents:
diff changeset
1898 }
kono
parents:
diff changeset
1899 }
kono
parents:
diff changeset
1900 }
kono
parents:
diff changeset
1901
kono
parents:
diff changeset
1902 /* Host fallback for GOMP_target{,_ext} routines. */
kono
parents:
diff changeset
1903
kono
parents:
diff changeset
1904 static void
kono
parents:
diff changeset
1905 gomp_target_fallback (void (*fn) (void *), void **hostaddrs)
kono
parents:
diff changeset
1906 {
kono
parents:
diff changeset
1907 struct gomp_thread old_thr, *thr = gomp_thread ();
kono
parents:
diff changeset
1908 old_thr = *thr;
kono
parents:
diff changeset
1909 memset (thr, '\0', sizeof (*thr));
kono
parents:
diff changeset
1910 if (gomp_places_list)
kono
parents:
diff changeset
1911 {
kono
parents:
diff changeset
1912 thr->place = old_thr.place;
kono
parents:
diff changeset
1913 thr->ts.place_partition_len = gomp_places_list_len;
kono
parents:
diff changeset
1914 }
kono
parents:
diff changeset
1915 fn (hostaddrs);
kono
parents:
diff changeset
1916 gomp_free_thread (thr);
kono
parents:
diff changeset
1917 *thr = old_thr;
kono
parents:
diff changeset
1918 }
kono
parents:
diff changeset
1919
kono
parents:
diff changeset
1920 /* Calculate alignment and size requirements of a private copy of data shared
kono
parents:
diff changeset
1921 as GOMP_MAP_FIRSTPRIVATE and store them to TGT_ALIGN and TGT_SIZE. */
kono
parents:
diff changeset
1922
kono
parents:
diff changeset
1923 static inline void
kono
parents:
diff changeset
1924 calculate_firstprivate_requirements (size_t mapnum, size_t *sizes,
kono
parents:
diff changeset
1925 unsigned short *kinds, size_t *tgt_align,
kono
parents:
diff changeset
1926 size_t *tgt_size)
kono
parents:
diff changeset
1927 {
kono
parents:
diff changeset
1928 size_t i;
kono
parents:
diff changeset
1929 for (i = 0; i < mapnum; i++)
kono
parents:
diff changeset
1930 if ((kinds[i] & 0xff) == GOMP_MAP_FIRSTPRIVATE)
kono
parents:
diff changeset
1931 {
kono
parents:
diff changeset
1932 size_t align = (size_t) 1 << (kinds[i] >> 8);
kono
parents:
diff changeset
1933 if (*tgt_align < align)
kono
parents:
diff changeset
1934 *tgt_align = align;
kono
parents:
diff changeset
1935 *tgt_size = (*tgt_size + align - 1) & ~(align - 1);
kono
parents:
diff changeset
1936 *tgt_size += sizes[i];
kono
parents:
diff changeset
1937 }
kono
parents:
diff changeset
1938 }
kono
parents:
diff changeset
1939
kono
parents:
diff changeset
1940 /* Copy data shared as GOMP_MAP_FIRSTPRIVATE to DST. */
kono
parents:
diff changeset
1941
kono
parents:
diff changeset
1942 static inline void
kono
parents:
diff changeset
1943 copy_firstprivate_data (char *tgt, size_t mapnum, void **hostaddrs,
kono
parents:
diff changeset
1944 size_t *sizes, unsigned short *kinds, size_t tgt_align,
kono
parents:
diff changeset
1945 size_t tgt_size)
kono
parents:
diff changeset
1946 {
kono
parents:
diff changeset
1947 uintptr_t al = (uintptr_t) tgt & (tgt_align - 1);
kono
parents:
diff changeset
1948 if (al)
kono
parents:
diff changeset
1949 tgt += tgt_align - al;
kono
parents:
diff changeset
1950 tgt_size = 0;
kono
parents:
diff changeset
1951 size_t i;
kono
parents:
diff changeset
1952 for (i = 0; i < mapnum; i++)
kono
parents:
diff changeset
1953 if ((kinds[i] & 0xff) == GOMP_MAP_FIRSTPRIVATE)
kono
parents:
diff changeset
1954 {
kono
parents:
diff changeset
1955 size_t align = (size_t) 1 << (kinds[i] >> 8);
kono
parents:
diff changeset
1956 tgt_size = (tgt_size + align - 1) & ~(align - 1);
kono
parents:
diff changeset
1957 memcpy (tgt + tgt_size, hostaddrs[i], sizes[i]);
kono
parents:
diff changeset
1958 hostaddrs[i] = tgt + tgt_size;
kono
parents:
diff changeset
1959 tgt_size = tgt_size + sizes[i];
kono
parents:
diff changeset
1960 }
kono
parents:
diff changeset
1961 }
kono
parents:
diff changeset
1962
kono
parents:
diff changeset
1963 /* Helper function of GOMP_target{,_ext} routines. */
kono
parents:
diff changeset
1964
kono
parents:
diff changeset
1965 static void *
kono
parents:
diff changeset
1966 gomp_get_target_fn_addr (struct gomp_device_descr *devicep,
kono
parents:
diff changeset
1967 void (*host_fn) (void *))
kono
parents:
diff changeset
1968 {
kono
parents:
diff changeset
1969 if (devicep->capabilities & GOMP_OFFLOAD_CAP_NATIVE_EXEC)
kono
parents:
diff changeset
1970 return (void *) host_fn;
kono
parents:
diff changeset
1971 else
kono
parents:
diff changeset
1972 {
kono
parents:
diff changeset
1973 gomp_mutex_lock (&devicep->lock);
kono
parents:
diff changeset
1974 if (devicep->state == GOMP_DEVICE_FINALIZED)
kono
parents:
diff changeset
1975 {
kono
parents:
diff changeset
1976 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1977 return NULL;
kono
parents:
diff changeset
1978 }
kono
parents:
diff changeset
1979
kono
parents:
diff changeset
1980 struct splay_tree_key_s k;
kono
parents:
diff changeset
1981 k.host_start = (uintptr_t) host_fn;
kono
parents:
diff changeset
1982 k.host_end = k.host_start + 1;
kono
parents:
diff changeset
1983 splay_tree_key tgt_fn = splay_tree_lookup (&devicep->mem_map, &k);
kono
parents:
diff changeset
1984 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
1985 if (tgt_fn == NULL)
kono
parents:
diff changeset
1986 return NULL;
kono
parents:
diff changeset
1987
kono
parents:
diff changeset
1988 return (void *) tgt_fn->tgt_offset;
kono
parents:
diff changeset
1989 }
kono
parents:
diff changeset
1990 }
kono
parents:
diff changeset
1991
kono
parents:
diff changeset
1992 /* Called when encountering a target directive. If DEVICE
kono
parents:
diff changeset
1993 is GOMP_DEVICE_ICV, it means use device-var ICV. If it is
kono
parents:
diff changeset
1994 GOMP_DEVICE_HOST_FALLBACK (or any value
kono
parents:
diff changeset
1995 larger than last available hw device), use host fallback.
kono
parents:
diff changeset
1996 FN is address of host code, UNUSED is part of the current ABI, but
kono
parents:
diff changeset
1997 we're not actually using it. HOSTADDRS, SIZES and KINDS are arrays
kono
parents:
diff changeset
1998 with MAPNUM entries, with addresses of the host objects,
kono
parents:
diff changeset
1999 sizes of the host objects (resp. for pointer kind pointer bias
kono
parents:
diff changeset
2000 and assumed sizeof (void *) size) and kinds. */
kono
parents:
diff changeset
2001
kono
parents:
diff changeset
2002 void
kono
parents:
diff changeset
2003 GOMP_target (int device, void (*fn) (void *), const void *unused,
kono
parents:
diff changeset
2004 size_t mapnum, void **hostaddrs, size_t *sizes,
kono
parents:
diff changeset
2005 unsigned char *kinds)
kono
parents:
diff changeset
2006 {
kono
parents:
diff changeset
2007 struct gomp_device_descr *devicep = resolve_device (device);
kono
parents:
diff changeset
2008
kono
parents:
diff changeset
2009 void *fn_addr;
kono
parents:
diff changeset
2010 if (devicep == NULL
kono
parents:
diff changeset
2011 || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2012 /* All shared memory devices should use the GOMP_target_ext function. */
kono
parents:
diff changeset
2013 || devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM
kono
parents:
diff changeset
2014 || !(fn_addr = gomp_get_target_fn_addr (devicep, fn)))
kono
parents:
diff changeset
2015 return gomp_target_fallback (fn, hostaddrs);
kono
parents:
diff changeset
2016
kono
parents:
diff changeset
2017 struct target_mem_desc *tgt_vars
kono
parents:
diff changeset
2018 = gomp_map_vars (devicep, mapnum, hostaddrs, NULL, sizes, kinds, false,
kono
parents:
diff changeset
2019 GOMP_MAP_VARS_TARGET);
kono
parents:
diff changeset
2020 devicep->run_func (devicep->target_id, fn_addr, (void *) tgt_vars->tgt_start,
kono
parents:
diff changeset
2021 NULL);
kono
parents:
diff changeset
2022 gomp_unmap_vars (tgt_vars, true);
kono
parents:
diff changeset
2023 }
kono
parents:
diff changeset
2024
kono
parents:
diff changeset
2025 /* Like GOMP_target, but KINDS is 16-bit, UNUSED is no longer present,
kono
parents:
diff changeset
2026 and several arguments have been added:
kono
parents:
diff changeset
2027 FLAGS is a bitmask, see GOMP_TARGET_FLAG_* in gomp-constants.h.
kono
parents:
diff changeset
2028 DEPEND is array of dependencies, see GOMP_task for details.
kono
parents:
diff changeset
2029
kono
parents:
diff changeset
2030 ARGS is a pointer to an array consisting of a variable number of both
kono
parents:
diff changeset
2031 device-independent and device-specific arguments, which can take one two
kono
parents:
diff changeset
2032 elements where the first specifies for which device it is intended, the type
kono
parents:
diff changeset
2033 and optionally also the value. If the value is not present in the first
kono
parents:
diff changeset
2034 one, the whole second element the actual value. The last element of the
kono
parents:
diff changeset
2035 array is a single NULL. Among the device independent can be for example
kono
parents:
diff changeset
2036 NUM_TEAMS and THREAD_LIMIT.
kono
parents:
diff changeset
2037
kono
parents:
diff changeset
2038 NUM_TEAMS is positive if GOMP_teams will be called in the body with
kono
parents:
diff changeset
2039 that value, or 1 if teams construct is not present, or 0, if
kono
parents:
diff changeset
2040 teams construct does not have num_teams clause and so the choice is
kono
parents:
diff changeset
2041 implementation defined, and -1 if it can't be determined on the host
kono
parents:
diff changeset
2042 what value will GOMP_teams have on the device.
kono
parents:
diff changeset
2043 THREAD_LIMIT similarly is positive if GOMP_teams will be called in the
kono
parents:
diff changeset
2044 body with that value, or 0, if teams construct does not have thread_limit
kono
parents:
diff changeset
2045 clause or the teams construct is not present, or -1 if it can't be
kono
parents:
diff changeset
2046 determined on the host what value will GOMP_teams have on the device. */
kono
parents:
diff changeset
2047
kono
parents:
diff changeset
2048 void
kono
parents:
diff changeset
2049 GOMP_target_ext (int device, void (*fn) (void *), size_t mapnum,
kono
parents:
diff changeset
2050 void **hostaddrs, size_t *sizes, unsigned short *kinds,
kono
parents:
diff changeset
2051 unsigned int flags, void **depend, void **args)
kono
parents:
diff changeset
2052 {
kono
parents:
diff changeset
2053 struct gomp_device_descr *devicep = resolve_device (device);
kono
parents:
diff changeset
2054 size_t tgt_align = 0, tgt_size = 0;
kono
parents:
diff changeset
2055 bool fpc_done = false;
kono
parents:
diff changeset
2056
kono
parents:
diff changeset
2057 if (flags & GOMP_TARGET_FLAG_NOWAIT)
kono
parents:
diff changeset
2058 {
kono
parents:
diff changeset
2059 struct gomp_thread *thr = gomp_thread ();
kono
parents:
diff changeset
2060 /* Create a team if we don't have any around, as nowait
kono
parents:
diff changeset
2061 target tasks make sense to run asynchronously even when
kono
parents:
diff changeset
2062 outside of any parallel. */
kono
parents:
diff changeset
2063 if (__builtin_expect (thr->ts.team == NULL, 0))
kono
parents:
diff changeset
2064 {
kono
parents:
diff changeset
2065 struct gomp_team *team = gomp_new_team (1);
kono
parents:
diff changeset
2066 struct gomp_task *task = thr->task;
kono
parents:
diff changeset
2067 struct gomp_task_icv *icv = task ? &task->icv : &gomp_global_icv;
kono
parents:
diff changeset
2068 team->prev_ts = thr->ts;
kono
parents:
diff changeset
2069 thr->ts.team = team;
kono
parents:
diff changeset
2070 thr->ts.team_id = 0;
kono
parents:
diff changeset
2071 thr->ts.work_share = &team->work_shares[0];
kono
parents:
diff changeset
2072 thr->ts.last_work_share = NULL;
kono
parents:
diff changeset
2073 #ifdef HAVE_SYNC_BUILTINS
kono
parents:
diff changeset
2074 thr->ts.single_count = 0;
kono
parents:
diff changeset
2075 #endif
kono
parents:
diff changeset
2076 thr->ts.static_trip = 0;
kono
parents:
diff changeset
2077 thr->task = &team->implicit_task[0];
kono
parents:
diff changeset
2078 gomp_init_task (thr->task, NULL, icv);
kono
parents:
diff changeset
2079 if (task)
kono
parents:
diff changeset
2080 {
kono
parents:
diff changeset
2081 thr->task = task;
kono
parents:
diff changeset
2082 gomp_end_task ();
kono
parents:
diff changeset
2083 free (task);
kono
parents:
diff changeset
2084 thr->task = &team->implicit_task[0];
kono
parents:
diff changeset
2085 }
kono
parents:
diff changeset
2086 else
kono
parents:
diff changeset
2087 pthread_setspecific (gomp_thread_destructor, thr);
kono
parents:
diff changeset
2088 }
kono
parents:
diff changeset
2089 if (thr->ts.team
kono
parents:
diff changeset
2090 && !thr->task->final_task)
kono
parents:
diff changeset
2091 {
kono
parents:
diff changeset
2092 gomp_create_target_task (devicep, fn, mapnum, hostaddrs,
kono
parents:
diff changeset
2093 sizes, kinds, flags, depend, args,
kono
parents:
diff changeset
2094 GOMP_TARGET_TASK_BEFORE_MAP);
kono
parents:
diff changeset
2095 return;
kono
parents:
diff changeset
2096 }
kono
parents:
diff changeset
2097 }
kono
parents:
diff changeset
2098
kono
parents:
diff changeset
2099 /* If there are depend clauses, but nowait is not present
kono
parents:
diff changeset
2100 (or we are in a final task), block the parent task until the
kono
parents:
diff changeset
2101 dependencies are resolved and then just continue with the rest
kono
parents:
diff changeset
2102 of the function as if it is a merged task. */
kono
parents:
diff changeset
2103 if (depend != NULL)
kono
parents:
diff changeset
2104 {
kono
parents:
diff changeset
2105 struct gomp_thread *thr = gomp_thread ();
kono
parents:
diff changeset
2106 if (thr->task && thr->task->depend_hash)
kono
parents:
diff changeset
2107 {
kono
parents:
diff changeset
2108 /* If we might need to wait, copy firstprivate now. */
kono
parents:
diff changeset
2109 calculate_firstprivate_requirements (mapnum, sizes, kinds,
kono
parents:
diff changeset
2110 &tgt_align, &tgt_size);
kono
parents:
diff changeset
2111 if (tgt_align)
kono
parents:
diff changeset
2112 {
kono
parents:
diff changeset
2113 char *tgt = gomp_alloca (tgt_size + tgt_align - 1);
kono
parents:
diff changeset
2114 copy_firstprivate_data (tgt, mapnum, hostaddrs, sizes, kinds,
kono
parents:
diff changeset
2115 tgt_align, tgt_size);
kono
parents:
diff changeset
2116 }
kono
parents:
diff changeset
2117 fpc_done = true;
kono
parents:
diff changeset
2118 gomp_task_maybe_wait_for_dependencies (depend);
kono
parents:
diff changeset
2119 }
kono
parents:
diff changeset
2120 }
kono
parents:
diff changeset
2121
kono
parents:
diff changeset
2122 void *fn_addr;
kono
parents:
diff changeset
2123 if (devicep == NULL
kono
parents:
diff changeset
2124 || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2125 || !(fn_addr = gomp_get_target_fn_addr (devicep, fn))
kono
parents:
diff changeset
2126 || (devicep->can_run_func && !devicep->can_run_func (fn_addr)))
kono
parents:
diff changeset
2127 {
kono
parents:
diff changeset
2128 if (!fpc_done)
kono
parents:
diff changeset
2129 {
kono
parents:
diff changeset
2130 calculate_firstprivate_requirements (mapnum, sizes, kinds,
kono
parents:
diff changeset
2131 &tgt_align, &tgt_size);
kono
parents:
diff changeset
2132 if (tgt_align)
kono
parents:
diff changeset
2133 {
kono
parents:
diff changeset
2134 char *tgt = gomp_alloca (tgt_size + tgt_align - 1);
kono
parents:
diff changeset
2135 copy_firstprivate_data (tgt, mapnum, hostaddrs, sizes, kinds,
kono
parents:
diff changeset
2136 tgt_align, tgt_size);
kono
parents:
diff changeset
2137 }
kono
parents:
diff changeset
2138 }
kono
parents:
diff changeset
2139 gomp_target_fallback (fn, hostaddrs);
kono
parents:
diff changeset
2140 return;
kono
parents:
diff changeset
2141 }
kono
parents:
diff changeset
2142
kono
parents:
diff changeset
2143 struct target_mem_desc *tgt_vars;
kono
parents:
diff changeset
2144 if (devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
2145 {
kono
parents:
diff changeset
2146 if (!fpc_done)
kono
parents:
diff changeset
2147 {
kono
parents:
diff changeset
2148 calculate_firstprivate_requirements (mapnum, sizes, kinds,
kono
parents:
diff changeset
2149 &tgt_align, &tgt_size);
kono
parents:
diff changeset
2150 if (tgt_align)
kono
parents:
diff changeset
2151 {
kono
parents:
diff changeset
2152 char *tgt = gomp_alloca (tgt_size + tgt_align - 1);
kono
parents:
diff changeset
2153 copy_firstprivate_data (tgt, mapnum, hostaddrs, sizes, kinds,
kono
parents:
diff changeset
2154 tgt_align, tgt_size);
kono
parents:
diff changeset
2155 }
kono
parents:
diff changeset
2156 }
kono
parents:
diff changeset
2157 tgt_vars = NULL;
kono
parents:
diff changeset
2158 }
kono
parents:
diff changeset
2159 else
kono
parents:
diff changeset
2160 tgt_vars = gomp_map_vars (devicep, mapnum, hostaddrs, NULL, sizes, kinds,
kono
parents:
diff changeset
2161 true, GOMP_MAP_VARS_TARGET);
kono
parents:
diff changeset
2162 devicep->run_func (devicep->target_id, fn_addr,
kono
parents:
diff changeset
2163 tgt_vars ? (void *) tgt_vars->tgt_start : hostaddrs,
kono
parents:
diff changeset
2164 args);
kono
parents:
diff changeset
2165 if (tgt_vars)
kono
parents:
diff changeset
2166 gomp_unmap_vars (tgt_vars, true);
kono
parents:
diff changeset
2167 }
kono
parents:
diff changeset
2168
kono
parents:
diff changeset
2169 /* Host fallback for GOMP_target_data{,_ext} routines. */
kono
parents:
diff changeset
2170
kono
parents:
diff changeset
2171 static void
kono
parents:
diff changeset
2172 gomp_target_data_fallback (void)
kono
parents:
diff changeset
2173 {
kono
parents:
diff changeset
2174 struct gomp_task_icv *icv = gomp_icv (false);
kono
parents:
diff changeset
2175 if (icv->target_data)
kono
parents:
diff changeset
2176 {
kono
parents:
diff changeset
2177 /* Even when doing a host fallback, if there are any active
kono
parents:
diff changeset
2178 #pragma omp target data constructs, need to remember the
kono
parents:
diff changeset
2179 new #pragma omp target data, otherwise GOMP_target_end_data
kono
parents:
diff changeset
2180 would get out of sync. */
kono
parents:
diff changeset
2181 struct target_mem_desc *tgt
kono
parents:
diff changeset
2182 = gomp_map_vars (NULL, 0, NULL, NULL, NULL, NULL, false,
kono
parents:
diff changeset
2183 GOMP_MAP_VARS_DATA);
kono
parents:
diff changeset
2184 tgt->prev = icv->target_data;
kono
parents:
diff changeset
2185 icv->target_data = tgt;
kono
parents:
diff changeset
2186 }
kono
parents:
diff changeset
2187 }
kono
parents:
diff changeset
2188
kono
parents:
diff changeset
2189 void
kono
parents:
diff changeset
2190 GOMP_target_data (int device, const void *unused, size_t mapnum,
kono
parents:
diff changeset
2191 void **hostaddrs, size_t *sizes, unsigned char *kinds)
kono
parents:
diff changeset
2192 {
kono
parents:
diff changeset
2193 struct gomp_device_descr *devicep = resolve_device (device);
kono
parents:
diff changeset
2194
kono
parents:
diff changeset
2195 if (devicep == NULL
kono
parents:
diff changeset
2196 || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2197 || (devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM))
kono
parents:
diff changeset
2198 return gomp_target_data_fallback ();
kono
parents:
diff changeset
2199
kono
parents:
diff changeset
2200 struct target_mem_desc *tgt
kono
parents:
diff changeset
2201 = gomp_map_vars (devicep, mapnum, hostaddrs, NULL, sizes, kinds, false,
kono
parents:
diff changeset
2202 GOMP_MAP_VARS_DATA);
kono
parents:
diff changeset
2203 struct gomp_task_icv *icv = gomp_icv (true);
kono
parents:
diff changeset
2204 tgt->prev = icv->target_data;
kono
parents:
diff changeset
2205 icv->target_data = tgt;
kono
parents:
diff changeset
2206 }
kono
parents:
diff changeset
2207
kono
parents:
diff changeset
2208 void
kono
parents:
diff changeset
2209 GOMP_target_data_ext (int device, size_t mapnum, void **hostaddrs,
kono
parents:
diff changeset
2210 size_t *sizes, unsigned short *kinds)
kono
parents:
diff changeset
2211 {
kono
parents:
diff changeset
2212 struct gomp_device_descr *devicep = resolve_device (device);
kono
parents:
diff changeset
2213
kono
parents:
diff changeset
2214 if (devicep == NULL
kono
parents:
diff changeset
2215 || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2216 || devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
2217 return gomp_target_data_fallback ();
kono
parents:
diff changeset
2218
kono
parents:
diff changeset
2219 struct target_mem_desc *tgt
kono
parents:
diff changeset
2220 = gomp_map_vars (devicep, mapnum, hostaddrs, NULL, sizes, kinds, true,
kono
parents:
diff changeset
2221 GOMP_MAP_VARS_DATA);
kono
parents:
diff changeset
2222 struct gomp_task_icv *icv = gomp_icv (true);
kono
parents:
diff changeset
2223 tgt->prev = icv->target_data;
kono
parents:
diff changeset
2224 icv->target_data = tgt;
kono
parents:
diff changeset
2225 }
kono
parents:
diff changeset
2226
kono
parents:
diff changeset
2227 void
kono
parents:
diff changeset
2228 GOMP_target_end_data (void)
kono
parents:
diff changeset
2229 {
kono
parents:
diff changeset
2230 struct gomp_task_icv *icv = gomp_icv (false);
kono
parents:
diff changeset
2231 if (icv->target_data)
kono
parents:
diff changeset
2232 {
kono
parents:
diff changeset
2233 struct target_mem_desc *tgt = icv->target_data;
kono
parents:
diff changeset
2234 icv->target_data = tgt->prev;
kono
parents:
diff changeset
2235 gomp_unmap_vars (tgt, true);
kono
parents:
diff changeset
2236 }
kono
parents:
diff changeset
2237 }
kono
parents:
diff changeset
2238
kono
parents:
diff changeset
2239 void
kono
parents:
diff changeset
2240 GOMP_target_update (int device, const void *unused, size_t mapnum,
kono
parents:
diff changeset
2241 void **hostaddrs, size_t *sizes, unsigned char *kinds)
kono
parents:
diff changeset
2242 {
kono
parents:
diff changeset
2243 struct gomp_device_descr *devicep = resolve_device (device);
kono
parents:
diff changeset
2244
kono
parents:
diff changeset
2245 if (devicep == NULL
kono
parents:
diff changeset
2246 || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2247 || devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
2248 return;
kono
parents:
diff changeset
2249
kono
parents:
diff changeset
2250 gomp_update (devicep, mapnum, hostaddrs, sizes, kinds, false);
kono
parents:
diff changeset
2251 }
kono
parents:
diff changeset
2252
kono
parents:
diff changeset
2253 void
kono
parents:
diff changeset
2254 GOMP_target_update_ext (int device, size_t mapnum, void **hostaddrs,
kono
parents:
diff changeset
2255 size_t *sizes, unsigned short *kinds,
kono
parents:
diff changeset
2256 unsigned int flags, void **depend)
kono
parents:
diff changeset
2257 {
kono
parents:
diff changeset
2258 struct gomp_device_descr *devicep = resolve_device (device);
kono
parents:
diff changeset
2259
kono
parents:
diff changeset
2260 /* If there are depend clauses, but nowait is not present,
kono
parents:
diff changeset
2261 block the parent task until the dependencies are resolved
kono
parents:
diff changeset
2262 and then just continue with the rest of the function as if it
kono
parents:
diff changeset
2263 is a merged task. Until we are able to schedule task during
kono
parents:
diff changeset
2264 variable mapping or unmapping, ignore nowait if depend clauses
kono
parents:
diff changeset
2265 are not present. */
kono
parents:
diff changeset
2266 if (depend != NULL)
kono
parents:
diff changeset
2267 {
kono
parents:
diff changeset
2268 struct gomp_thread *thr = gomp_thread ();
kono
parents:
diff changeset
2269 if (thr->task && thr->task->depend_hash)
kono
parents:
diff changeset
2270 {
kono
parents:
diff changeset
2271 if ((flags & GOMP_TARGET_FLAG_NOWAIT)
kono
parents:
diff changeset
2272 && thr->ts.team
kono
parents:
diff changeset
2273 && !thr->task->final_task)
kono
parents:
diff changeset
2274 {
kono
parents:
diff changeset
2275 if (gomp_create_target_task (devicep, (void (*) (void *)) NULL,
kono
parents:
diff changeset
2276 mapnum, hostaddrs, sizes, kinds,
kono
parents:
diff changeset
2277 flags | GOMP_TARGET_FLAG_UPDATE,
kono
parents:
diff changeset
2278 depend, NULL, GOMP_TARGET_TASK_DATA))
kono
parents:
diff changeset
2279 return;
kono
parents:
diff changeset
2280 }
kono
parents:
diff changeset
2281 else
kono
parents:
diff changeset
2282 {
kono
parents:
diff changeset
2283 struct gomp_team *team = thr->ts.team;
kono
parents:
diff changeset
2284 /* If parallel or taskgroup has been cancelled, don't start new
kono
parents:
diff changeset
2285 tasks. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2286 if (__builtin_expect (gomp_cancel_var, 0) && team)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2287 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2288 if (gomp_team_barrier_cancelled (&team->barrier))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2289 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2290 if (thr->task->taskgroup)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2291 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2292 if (thr->task->taskgroup->cancelled)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2293 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2294 if (thr->task->taskgroup->workshare
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2295 && thr->task->taskgroup->prev
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2296 && thr->task->taskgroup->prev->cancelled)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2297 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2298 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2299 }
111
kono
parents:
diff changeset
2300
kono
parents:
diff changeset
2301 gomp_task_maybe_wait_for_dependencies (depend);
kono
parents:
diff changeset
2302 }
kono
parents:
diff changeset
2303 }
kono
parents:
diff changeset
2304 }
kono
parents:
diff changeset
2305
kono
parents:
diff changeset
2306 if (devicep == NULL
kono
parents:
diff changeset
2307 || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2308 || devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
2309 return;
kono
parents:
diff changeset
2310
kono
parents:
diff changeset
2311 struct gomp_thread *thr = gomp_thread ();
kono
parents:
diff changeset
2312 struct gomp_team *team = thr->ts.team;
kono
parents:
diff changeset
2313 /* If parallel or taskgroup has been cancelled, don't start new tasks. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2314 if (__builtin_expect (gomp_cancel_var, 0) && team)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2315 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2316 if (gomp_team_barrier_cancelled (&team->barrier))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2317 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2318 if (thr->task->taskgroup)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2319 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2320 if (thr->task->taskgroup->cancelled)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2321 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2322 if (thr->task->taskgroup->workshare
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2323 && thr->task->taskgroup->prev
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2324 && thr->task->taskgroup->prev->cancelled)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2325 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2326 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2327 }
111
kono
parents:
diff changeset
2328
kono
parents:
diff changeset
2329 gomp_update (devicep, mapnum, hostaddrs, sizes, kinds, true);
kono
parents:
diff changeset
2330 }
kono
parents:
diff changeset
2331
kono
parents:
diff changeset
2332 static void
kono
parents:
diff changeset
2333 gomp_exit_data (struct gomp_device_descr *devicep, size_t mapnum,
kono
parents:
diff changeset
2334 void **hostaddrs, size_t *sizes, unsigned short *kinds)
kono
parents:
diff changeset
2335 {
kono
parents:
diff changeset
2336 const int typemask = 0xff;
kono
parents:
diff changeset
2337 size_t i;
kono
parents:
diff changeset
2338 gomp_mutex_lock (&devicep->lock);
kono
parents:
diff changeset
2339 if (devicep->state == GOMP_DEVICE_FINALIZED)
kono
parents:
diff changeset
2340 {
kono
parents:
diff changeset
2341 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
2342 return;
kono
parents:
diff changeset
2343 }
kono
parents:
diff changeset
2344
kono
parents:
diff changeset
2345 for (i = 0; i < mapnum; i++)
kono
parents:
diff changeset
2346 {
kono
parents:
diff changeset
2347 struct splay_tree_key_s cur_node;
kono
parents:
diff changeset
2348 unsigned char kind = kinds[i] & typemask;
kono
parents:
diff changeset
2349 switch (kind)
kono
parents:
diff changeset
2350 {
kono
parents:
diff changeset
2351 case GOMP_MAP_FROM:
kono
parents:
diff changeset
2352 case GOMP_MAP_ALWAYS_FROM:
kono
parents:
diff changeset
2353 case GOMP_MAP_DELETE:
kono
parents:
diff changeset
2354 case GOMP_MAP_RELEASE:
kono
parents:
diff changeset
2355 case GOMP_MAP_ZERO_LEN_ARRAY_SECTION:
kono
parents:
diff changeset
2356 case GOMP_MAP_DELETE_ZERO_LEN_ARRAY_SECTION:
kono
parents:
diff changeset
2357 cur_node.host_start = (uintptr_t) hostaddrs[i];
kono
parents:
diff changeset
2358 cur_node.host_end = cur_node.host_start + sizes[i];
kono
parents:
diff changeset
2359 splay_tree_key k = (kind == GOMP_MAP_DELETE_ZERO_LEN_ARRAY_SECTION
kono
parents:
diff changeset
2360 || kind == GOMP_MAP_ZERO_LEN_ARRAY_SECTION)
kono
parents:
diff changeset
2361 ? gomp_map_0len_lookup (&devicep->mem_map, &cur_node)
kono
parents:
diff changeset
2362 : splay_tree_lookup (&devicep->mem_map, &cur_node);
kono
parents:
diff changeset
2363 if (!k)
kono
parents:
diff changeset
2364 continue;
kono
parents:
diff changeset
2365
kono
parents:
diff changeset
2366 if (k->refcount > 0 && k->refcount != REFCOUNT_INFINITY)
kono
parents:
diff changeset
2367 k->refcount--;
kono
parents:
diff changeset
2368 if ((kind == GOMP_MAP_DELETE
kono
parents:
diff changeset
2369 || kind == GOMP_MAP_DELETE_ZERO_LEN_ARRAY_SECTION)
kono
parents:
diff changeset
2370 && k->refcount != REFCOUNT_INFINITY)
kono
parents:
diff changeset
2371 k->refcount = 0;
kono
parents:
diff changeset
2372
kono
parents:
diff changeset
2373 if ((kind == GOMP_MAP_FROM && k->refcount == 0)
kono
parents:
diff changeset
2374 || kind == GOMP_MAP_ALWAYS_FROM)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2375 gomp_copy_dev2host (devicep, NULL, (void *) cur_node.host_start,
111
kono
parents:
diff changeset
2376 (void *) (k->tgt->tgt_start + k->tgt_offset
kono
parents:
diff changeset
2377 + cur_node.host_start
kono
parents:
diff changeset
2378 - k->host_start),
kono
parents:
diff changeset
2379 cur_node.host_end - cur_node.host_start);
kono
parents:
diff changeset
2380 if (k->refcount == 0)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2381 gomp_remove_var (devicep, k);
111
kono
parents:
diff changeset
2382
kono
parents:
diff changeset
2383 break;
kono
parents:
diff changeset
2384 default:
kono
parents:
diff changeset
2385 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
2386 gomp_fatal ("GOMP_target_enter_exit_data unhandled kind 0x%.2x",
kono
parents:
diff changeset
2387 kind);
kono
parents:
diff changeset
2388 }
kono
parents:
diff changeset
2389 }
kono
parents:
diff changeset
2390
kono
parents:
diff changeset
2391 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
2392 }
kono
parents:
diff changeset
2393
kono
parents:
diff changeset
2394 void
kono
parents:
diff changeset
2395 GOMP_target_enter_exit_data (int device, size_t mapnum, void **hostaddrs,
kono
parents:
diff changeset
2396 size_t *sizes, unsigned short *kinds,
kono
parents:
diff changeset
2397 unsigned int flags, void **depend)
kono
parents:
diff changeset
2398 {
kono
parents:
diff changeset
2399 struct gomp_device_descr *devicep = resolve_device (device);
kono
parents:
diff changeset
2400
kono
parents:
diff changeset
2401 /* If there are depend clauses, but nowait is not present,
kono
parents:
diff changeset
2402 block the parent task until the dependencies are resolved
kono
parents:
diff changeset
2403 and then just continue with the rest of the function as if it
kono
parents:
diff changeset
2404 is a merged task. Until we are able to schedule task during
kono
parents:
diff changeset
2405 variable mapping or unmapping, ignore nowait if depend clauses
kono
parents:
diff changeset
2406 are not present. */
kono
parents:
diff changeset
2407 if (depend != NULL)
kono
parents:
diff changeset
2408 {
kono
parents:
diff changeset
2409 struct gomp_thread *thr = gomp_thread ();
kono
parents:
diff changeset
2410 if (thr->task && thr->task->depend_hash)
kono
parents:
diff changeset
2411 {
kono
parents:
diff changeset
2412 if ((flags & GOMP_TARGET_FLAG_NOWAIT)
kono
parents:
diff changeset
2413 && thr->ts.team
kono
parents:
diff changeset
2414 && !thr->task->final_task)
kono
parents:
diff changeset
2415 {
kono
parents:
diff changeset
2416 if (gomp_create_target_task (devicep, (void (*) (void *)) NULL,
kono
parents:
diff changeset
2417 mapnum, hostaddrs, sizes, kinds,
kono
parents:
diff changeset
2418 flags, depend, NULL,
kono
parents:
diff changeset
2419 GOMP_TARGET_TASK_DATA))
kono
parents:
diff changeset
2420 return;
kono
parents:
diff changeset
2421 }
kono
parents:
diff changeset
2422 else
kono
parents:
diff changeset
2423 {
kono
parents:
diff changeset
2424 struct gomp_team *team = thr->ts.team;
kono
parents:
diff changeset
2425 /* If parallel or taskgroup has been cancelled, don't start new
kono
parents:
diff changeset
2426 tasks. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2427 if (__builtin_expect (gomp_cancel_var, 0) && team)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2428 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2429 if (gomp_team_barrier_cancelled (&team->barrier))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2430 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2431 if (thr->task->taskgroup)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2432 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2433 if (thr->task->taskgroup->cancelled)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2434 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2435 if (thr->task->taskgroup->workshare
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2436 && thr->task->taskgroup->prev
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2437 && thr->task->taskgroup->prev->cancelled)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2438 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2439 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2440 }
111
kono
parents:
diff changeset
2441
kono
parents:
diff changeset
2442 gomp_task_maybe_wait_for_dependencies (depend);
kono
parents:
diff changeset
2443 }
kono
parents:
diff changeset
2444 }
kono
parents:
diff changeset
2445 }
kono
parents:
diff changeset
2446
kono
parents:
diff changeset
2447 if (devicep == NULL
kono
parents:
diff changeset
2448 || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2449 || devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
2450 return;
kono
parents:
diff changeset
2451
kono
parents:
diff changeset
2452 struct gomp_thread *thr = gomp_thread ();
kono
parents:
diff changeset
2453 struct gomp_team *team = thr->ts.team;
kono
parents:
diff changeset
2454 /* If parallel or taskgroup has been cancelled, don't start new tasks. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2455 if (__builtin_expect (gomp_cancel_var, 0) && team)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2456 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2457 if (gomp_team_barrier_cancelled (&team->barrier))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2458 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2459 if (thr->task->taskgroup)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2460 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2461 if (thr->task->taskgroup->cancelled)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2462 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2463 if (thr->task->taskgroup->workshare
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2464 && thr->task->taskgroup->prev
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2465 && thr->task->taskgroup->prev->cancelled)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2466 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2467 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2468 }
111
kono
parents:
diff changeset
2469
kono
parents:
diff changeset
2470 size_t i;
kono
parents:
diff changeset
2471 if ((flags & GOMP_TARGET_FLAG_EXIT_DATA) == 0)
kono
parents:
diff changeset
2472 for (i = 0; i < mapnum; i++)
kono
parents:
diff changeset
2473 if ((kinds[i] & 0xff) == GOMP_MAP_STRUCT)
kono
parents:
diff changeset
2474 {
kono
parents:
diff changeset
2475 gomp_map_vars (devicep, sizes[i] + 1, &hostaddrs[i], NULL, &sizes[i],
kono
parents:
diff changeset
2476 &kinds[i], true, GOMP_MAP_VARS_ENTER_DATA);
kono
parents:
diff changeset
2477 i += sizes[i];
kono
parents:
diff changeset
2478 }
kono
parents:
diff changeset
2479 else
kono
parents:
diff changeset
2480 gomp_map_vars (devicep, 1, &hostaddrs[i], NULL, &sizes[i], &kinds[i],
kono
parents:
diff changeset
2481 true, GOMP_MAP_VARS_ENTER_DATA);
kono
parents:
diff changeset
2482 else
kono
parents:
diff changeset
2483 gomp_exit_data (devicep, mapnum, hostaddrs, sizes, kinds);
kono
parents:
diff changeset
2484 }
kono
parents:
diff changeset
2485
kono
parents:
diff changeset
2486 bool
kono
parents:
diff changeset
2487 gomp_target_task_fn (void *data)
kono
parents:
diff changeset
2488 {
kono
parents:
diff changeset
2489 struct gomp_target_task *ttask = (struct gomp_target_task *) data;
kono
parents:
diff changeset
2490 struct gomp_device_descr *devicep = ttask->devicep;
kono
parents:
diff changeset
2491
kono
parents:
diff changeset
2492 if (ttask->fn != NULL)
kono
parents:
diff changeset
2493 {
kono
parents:
diff changeset
2494 void *fn_addr;
kono
parents:
diff changeset
2495 if (devicep == NULL
kono
parents:
diff changeset
2496 || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2497 || !(fn_addr = gomp_get_target_fn_addr (devicep, ttask->fn))
kono
parents:
diff changeset
2498 || (devicep->can_run_func && !devicep->can_run_func (fn_addr)))
kono
parents:
diff changeset
2499 {
kono
parents:
diff changeset
2500 ttask->state = GOMP_TARGET_TASK_FALLBACK;
kono
parents:
diff changeset
2501 gomp_target_fallback (ttask->fn, ttask->hostaddrs);
kono
parents:
diff changeset
2502 return false;
kono
parents:
diff changeset
2503 }
kono
parents:
diff changeset
2504
kono
parents:
diff changeset
2505 if (ttask->state == GOMP_TARGET_TASK_FINISHED)
kono
parents:
diff changeset
2506 {
kono
parents:
diff changeset
2507 if (ttask->tgt)
kono
parents:
diff changeset
2508 gomp_unmap_vars (ttask->tgt, true);
kono
parents:
diff changeset
2509 return false;
kono
parents:
diff changeset
2510 }
kono
parents:
diff changeset
2511
kono
parents:
diff changeset
2512 void *actual_arguments;
kono
parents:
diff changeset
2513 if (devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
2514 {
kono
parents:
diff changeset
2515 ttask->tgt = NULL;
kono
parents:
diff changeset
2516 actual_arguments = ttask->hostaddrs;
kono
parents:
diff changeset
2517 }
kono
parents:
diff changeset
2518 else
kono
parents:
diff changeset
2519 {
kono
parents:
diff changeset
2520 ttask->tgt = gomp_map_vars (devicep, ttask->mapnum, ttask->hostaddrs,
kono
parents:
diff changeset
2521 NULL, ttask->sizes, ttask->kinds, true,
kono
parents:
diff changeset
2522 GOMP_MAP_VARS_TARGET);
kono
parents:
diff changeset
2523 actual_arguments = (void *) ttask->tgt->tgt_start;
kono
parents:
diff changeset
2524 }
kono
parents:
diff changeset
2525 ttask->state = GOMP_TARGET_TASK_READY_TO_RUN;
kono
parents:
diff changeset
2526
kono
parents:
diff changeset
2527 devicep->async_run_func (devicep->target_id, fn_addr, actual_arguments,
kono
parents:
diff changeset
2528 ttask->args, (void *) ttask);
kono
parents:
diff changeset
2529 return true;
kono
parents:
diff changeset
2530 }
kono
parents:
diff changeset
2531 else if (devicep == NULL
kono
parents:
diff changeset
2532 || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2533 || devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
2534 return false;
kono
parents:
diff changeset
2535
kono
parents:
diff changeset
2536 size_t i;
kono
parents:
diff changeset
2537 if (ttask->flags & GOMP_TARGET_FLAG_UPDATE)
kono
parents:
diff changeset
2538 gomp_update (devicep, ttask->mapnum, ttask->hostaddrs, ttask->sizes,
kono
parents:
diff changeset
2539 ttask->kinds, true);
kono
parents:
diff changeset
2540 else if ((ttask->flags & GOMP_TARGET_FLAG_EXIT_DATA) == 0)
kono
parents:
diff changeset
2541 for (i = 0; i < ttask->mapnum; i++)
kono
parents:
diff changeset
2542 if ((ttask->kinds[i] & 0xff) == GOMP_MAP_STRUCT)
kono
parents:
diff changeset
2543 {
kono
parents:
diff changeset
2544 gomp_map_vars (devicep, ttask->sizes[i] + 1, &ttask->hostaddrs[i],
kono
parents:
diff changeset
2545 NULL, &ttask->sizes[i], &ttask->kinds[i], true,
kono
parents:
diff changeset
2546 GOMP_MAP_VARS_ENTER_DATA);
kono
parents:
diff changeset
2547 i += ttask->sizes[i];
kono
parents:
diff changeset
2548 }
kono
parents:
diff changeset
2549 else
kono
parents:
diff changeset
2550 gomp_map_vars (devicep, 1, &ttask->hostaddrs[i], NULL, &ttask->sizes[i],
kono
parents:
diff changeset
2551 &ttask->kinds[i], true, GOMP_MAP_VARS_ENTER_DATA);
kono
parents:
diff changeset
2552 else
kono
parents:
diff changeset
2553 gomp_exit_data (devicep, ttask->mapnum, ttask->hostaddrs, ttask->sizes,
kono
parents:
diff changeset
2554 ttask->kinds);
kono
parents:
diff changeset
2555 return false;
kono
parents:
diff changeset
2556 }
kono
parents:
diff changeset
2557
kono
parents:
diff changeset
2558 void
kono
parents:
diff changeset
2559 GOMP_teams (unsigned int num_teams, unsigned int thread_limit)
kono
parents:
diff changeset
2560 {
kono
parents:
diff changeset
2561 if (thread_limit)
kono
parents:
diff changeset
2562 {
kono
parents:
diff changeset
2563 struct gomp_task_icv *icv = gomp_icv (true);
kono
parents:
diff changeset
2564 icv->thread_limit_var
kono
parents:
diff changeset
2565 = thread_limit > INT_MAX ? UINT_MAX : thread_limit;
kono
parents:
diff changeset
2566 }
kono
parents:
diff changeset
2567 (void) num_teams;
kono
parents:
diff changeset
2568 }
kono
parents:
diff changeset
2569
kono
parents:
diff changeset
2570 void *
kono
parents:
diff changeset
2571 omp_target_alloc (size_t size, int device_num)
kono
parents:
diff changeset
2572 {
kono
parents:
diff changeset
2573 if (device_num == GOMP_DEVICE_HOST_FALLBACK)
kono
parents:
diff changeset
2574 return malloc (size);
kono
parents:
diff changeset
2575
kono
parents:
diff changeset
2576 if (device_num < 0)
kono
parents:
diff changeset
2577 return NULL;
kono
parents:
diff changeset
2578
kono
parents:
diff changeset
2579 struct gomp_device_descr *devicep = resolve_device (device_num);
kono
parents:
diff changeset
2580 if (devicep == NULL)
kono
parents:
diff changeset
2581 return NULL;
kono
parents:
diff changeset
2582
kono
parents:
diff changeset
2583 if (!(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2584 || devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
2585 return malloc (size);
kono
parents:
diff changeset
2586
kono
parents:
diff changeset
2587 gomp_mutex_lock (&devicep->lock);
kono
parents:
diff changeset
2588 void *ret = devicep->alloc_func (devicep->target_id, size);
kono
parents:
diff changeset
2589 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
2590 return ret;
kono
parents:
diff changeset
2591 }
kono
parents:
diff changeset
2592
kono
parents:
diff changeset
2593 void
kono
parents:
diff changeset
2594 omp_target_free (void *device_ptr, int device_num)
kono
parents:
diff changeset
2595 {
kono
parents:
diff changeset
2596 if (device_ptr == NULL)
kono
parents:
diff changeset
2597 return;
kono
parents:
diff changeset
2598
kono
parents:
diff changeset
2599 if (device_num == GOMP_DEVICE_HOST_FALLBACK)
kono
parents:
diff changeset
2600 {
kono
parents:
diff changeset
2601 free (device_ptr);
kono
parents:
diff changeset
2602 return;
kono
parents:
diff changeset
2603 }
kono
parents:
diff changeset
2604
kono
parents:
diff changeset
2605 if (device_num < 0)
kono
parents:
diff changeset
2606 return;
kono
parents:
diff changeset
2607
kono
parents:
diff changeset
2608 struct gomp_device_descr *devicep = resolve_device (device_num);
kono
parents:
diff changeset
2609 if (devicep == NULL)
kono
parents:
diff changeset
2610 return;
kono
parents:
diff changeset
2611
kono
parents:
diff changeset
2612 if (!(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2613 || devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
2614 {
kono
parents:
diff changeset
2615 free (device_ptr);
kono
parents:
diff changeset
2616 return;
kono
parents:
diff changeset
2617 }
kono
parents:
diff changeset
2618
kono
parents:
diff changeset
2619 gomp_mutex_lock (&devicep->lock);
kono
parents:
diff changeset
2620 gomp_free_device_memory (devicep, device_ptr);
kono
parents:
diff changeset
2621 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
2622 }
kono
parents:
diff changeset
2623
kono
parents:
diff changeset
2624 int
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2625 omp_target_is_present (const void *ptr, int device_num)
111
kono
parents:
diff changeset
2626 {
kono
parents:
diff changeset
2627 if (ptr == NULL)
kono
parents:
diff changeset
2628 return 1;
kono
parents:
diff changeset
2629
kono
parents:
diff changeset
2630 if (device_num == GOMP_DEVICE_HOST_FALLBACK)
kono
parents:
diff changeset
2631 return 1;
kono
parents:
diff changeset
2632
kono
parents:
diff changeset
2633 if (device_num < 0)
kono
parents:
diff changeset
2634 return 0;
kono
parents:
diff changeset
2635
kono
parents:
diff changeset
2636 struct gomp_device_descr *devicep = resolve_device (device_num);
kono
parents:
diff changeset
2637 if (devicep == NULL)
kono
parents:
diff changeset
2638 return 0;
kono
parents:
diff changeset
2639
kono
parents:
diff changeset
2640 if (!(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2641 || devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
2642 return 1;
kono
parents:
diff changeset
2643
kono
parents:
diff changeset
2644 gomp_mutex_lock (&devicep->lock);
kono
parents:
diff changeset
2645 struct splay_tree_s *mem_map = &devicep->mem_map;
kono
parents:
diff changeset
2646 struct splay_tree_key_s cur_node;
kono
parents:
diff changeset
2647
kono
parents:
diff changeset
2648 cur_node.host_start = (uintptr_t) ptr;
kono
parents:
diff changeset
2649 cur_node.host_end = cur_node.host_start;
kono
parents:
diff changeset
2650 splay_tree_key n = gomp_map_0len_lookup (mem_map, &cur_node);
kono
parents:
diff changeset
2651 int ret = n != NULL;
kono
parents:
diff changeset
2652 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
2653 return ret;
kono
parents:
diff changeset
2654 }
kono
parents:
diff changeset
2655
kono
parents:
diff changeset
2656 int
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2657 omp_target_memcpy (void *dst, const void *src, size_t length,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2658 size_t dst_offset, size_t src_offset, int dst_device_num,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2659 int src_device_num)
111
kono
parents:
diff changeset
2660 {
kono
parents:
diff changeset
2661 struct gomp_device_descr *dst_devicep = NULL, *src_devicep = NULL;
kono
parents:
diff changeset
2662 bool ret;
kono
parents:
diff changeset
2663
kono
parents:
diff changeset
2664 if (dst_device_num != GOMP_DEVICE_HOST_FALLBACK)
kono
parents:
diff changeset
2665 {
kono
parents:
diff changeset
2666 if (dst_device_num < 0)
kono
parents:
diff changeset
2667 return EINVAL;
kono
parents:
diff changeset
2668
kono
parents:
diff changeset
2669 dst_devicep = resolve_device (dst_device_num);
kono
parents:
diff changeset
2670 if (dst_devicep == NULL)
kono
parents:
diff changeset
2671 return EINVAL;
kono
parents:
diff changeset
2672
kono
parents:
diff changeset
2673 if (!(dst_devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2674 || dst_devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
2675 dst_devicep = NULL;
kono
parents:
diff changeset
2676 }
kono
parents:
diff changeset
2677 if (src_device_num != GOMP_DEVICE_HOST_FALLBACK)
kono
parents:
diff changeset
2678 {
kono
parents:
diff changeset
2679 if (src_device_num < 0)
kono
parents:
diff changeset
2680 return EINVAL;
kono
parents:
diff changeset
2681
kono
parents:
diff changeset
2682 src_devicep = resolve_device (src_device_num);
kono
parents:
diff changeset
2683 if (src_devicep == NULL)
kono
parents:
diff changeset
2684 return EINVAL;
kono
parents:
diff changeset
2685
kono
parents:
diff changeset
2686 if (!(src_devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2687 || src_devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
2688 src_devicep = NULL;
kono
parents:
diff changeset
2689 }
kono
parents:
diff changeset
2690 if (src_devicep == NULL && dst_devicep == NULL)
kono
parents:
diff changeset
2691 {
kono
parents:
diff changeset
2692 memcpy ((char *) dst + dst_offset, (char *) src + src_offset, length);
kono
parents:
diff changeset
2693 return 0;
kono
parents:
diff changeset
2694 }
kono
parents:
diff changeset
2695 if (src_devicep == NULL)
kono
parents:
diff changeset
2696 {
kono
parents:
diff changeset
2697 gomp_mutex_lock (&dst_devicep->lock);
kono
parents:
diff changeset
2698 ret = dst_devicep->host2dev_func (dst_devicep->target_id,
kono
parents:
diff changeset
2699 (char *) dst + dst_offset,
kono
parents:
diff changeset
2700 (char *) src + src_offset, length);
kono
parents:
diff changeset
2701 gomp_mutex_unlock (&dst_devicep->lock);
kono
parents:
diff changeset
2702 return (ret ? 0 : EINVAL);
kono
parents:
diff changeset
2703 }
kono
parents:
diff changeset
2704 if (dst_devicep == NULL)
kono
parents:
diff changeset
2705 {
kono
parents:
diff changeset
2706 gomp_mutex_lock (&src_devicep->lock);
kono
parents:
diff changeset
2707 ret = src_devicep->dev2host_func (src_devicep->target_id,
kono
parents:
diff changeset
2708 (char *) dst + dst_offset,
kono
parents:
diff changeset
2709 (char *) src + src_offset, length);
kono
parents:
diff changeset
2710 gomp_mutex_unlock (&src_devicep->lock);
kono
parents:
diff changeset
2711 return (ret ? 0 : EINVAL);
kono
parents:
diff changeset
2712 }
kono
parents:
diff changeset
2713 if (src_devicep == dst_devicep)
kono
parents:
diff changeset
2714 {
kono
parents:
diff changeset
2715 gomp_mutex_lock (&src_devicep->lock);
kono
parents:
diff changeset
2716 ret = src_devicep->dev2dev_func (src_devicep->target_id,
kono
parents:
diff changeset
2717 (char *) dst + dst_offset,
kono
parents:
diff changeset
2718 (char *) src + src_offset, length);
kono
parents:
diff changeset
2719 gomp_mutex_unlock (&src_devicep->lock);
kono
parents:
diff changeset
2720 return (ret ? 0 : EINVAL);
kono
parents:
diff changeset
2721 }
kono
parents:
diff changeset
2722 return EINVAL;
kono
parents:
diff changeset
2723 }
kono
parents:
diff changeset
2724
kono
parents:
diff changeset
2725 static int
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2726 omp_target_memcpy_rect_worker (void *dst, const void *src, size_t element_size,
111
kono
parents:
diff changeset
2727 int num_dims, const size_t *volume,
kono
parents:
diff changeset
2728 const size_t *dst_offsets,
kono
parents:
diff changeset
2729 const size_t *src_offsets,
kono
parents:
diff changeset
2730 const size_t *dst_dimensions,
kono
parents:
diff changeset
2731 const size_t *src_dimensions,
kono
parents:
diff changeset
2732 struct gomp_device_descr *dst_devicep,
kono
parents:
diff changeset
2733 struct gomp_device_descr *src_devicep)
kono
parents:
diff changeset
2734 {
kono
parents:
diff changeset
2735 size_t dst_slice = element_size;
kono
parents:
diff changeset
2736 size_t src_slice = element_size;
kono
parents:
diff changeset
2737 size_t j, dst_off, src_off, length;
kono
parents:
diff changeset
2738 int i, ret;
kono
parents:
diff changeset
2739
kono
parents:
diff changeset
2740 if (num_dims == 1)
kono
parents:
diff changeset
2741 {
kono
parents:
diff changeset
2742 if (__builtin_mul_overflow (element_size, volume[0], &length)
kono
parents:
diff changeset
2743 || __builtin_mul_overflow (element_size, dst_offsets[0], &dst_off)
kono
parents:
diff changeset
2744 || __builtin_mul_overflow (element_size, src_offsets[0], &src_off))
kono
parents:
diff changeset
2745 return EINVAL;
kono
parents:
diff changeset
2746 if (dst_devicep == NULL && src_devicep == NULL)
kono
parents:
diff changeset
2747 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2748 memcpy ((char *) dst + dst_off, (const char *) src + src_off,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2749 length);
111
kono
parents:
diff changeset
2750 ret = 1;
kono
parents:
diff changeset
2751 }
kono
parents:
diff changeset
2752 else if (src_devicep == NULL)
kono
parents:
diff changeset
2753 ret = dst_devicep->host2dev_func (dst_devicep->target_id,
kono
parents:
diff changeset
2754 (char *) dst + dst_off,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2755 (const char *) src + src_off,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2756 length);
111
kono
parents:
diff changeset
2757 else if (dst_devicep == NULL)
kono
parents:
diff changeset
2758 ret = src_devicep->dev2host_func (src_devicep->target_id,
kono
parents:
diff changeset
2759 (char *) dst + dst_off,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2760 (const char *) src + src_off,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2761 length);
111
kono
parents:
diff changeset
2762 else if (src_devicep == dst_devicep)
kono
parents:
diff changeset
2763 ret = src_devicep->dev2dev_func (src_devicep->target_id,
kono
parents:
diff changeset
2764 (char *) dst + dst_off,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2765 (const char *) src + src_off,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2766 length);
111
kono
parents:
diff changeset
2767 else
kono
parents:
diff changeset
2768 ret = 0;
kono
parents:
diff changeset
2769 return ret ? 0 : EINVAL;
kono
parents:
diff changeset
2770 }
kono
parents:
diff changeset
2771
kono
parents:
diff changeset
2772 /* FIXME: it would be nice to have some plugin function to handle
kono
parents:
diff changeset
2773 num_dims == 2 and num_dims == 3 more efficiently. Larger ones can
kono
parents:
diff changeset
2774 be handled in the generic recursion below, and for host-host it
kono
parents:
diff changeset
2775 should be used even for any num_dims >= 2. */
kono
parents:
diff changeset
2776
kono
parents:
diff changeset
2777 for (i = 1; i < num_dims; i++)
kono
parents:
diff changeset
2778 if (__builtin_mul_overflow (dst_slice, dst_dimensions[i], &dst_slice)
kono
parents:
diff changeset
2779 || __builtin_mul_overflow (src_slice, src_dimensions[i], &src_slice))
kono
parents:
diff changeset
2780 return EINVAL;
kono
parents:
diff changeset
2781 if (__builtin_mul_overflow (dst_slice, dst_offsets[0], &dst_off)
kono
parents:
diff changeset
2782 || __builtin_mul_overflow (src_slice, src_offsets[0], &src_off))
kono
parents:
diff changeset
2783 return EINVAL;
kono
parents:
diff changeset
2784 for (j = 0; j < volume[0]; j++)
kono
parents:
diff changeset
2785 {
kono
parents:
diff changeset
2786 ret = omp_target_memcpy_rect_worker ((char *) dst + dst_off,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2787 (const char *) src + src_off,
111
kono
parents:
diff changeset
2788 element_size, num_dims - 1,
kono
parents:
diff changeset
2789 volume + 1, dst_offsets + 1,
kono
parents:
diff changeset
2790 src_offsets + 1, dst_dimensions + 1,
kono
parents:
diff changeset
2791 src_dimensions + 1, dst_devicep,
kono
parents:
diff changeset
2792 src_devicep);
kono
parents:
diff changeset
2793 if (ret)
kono
parents:
diff changeset
2794 return ret;
kono
parents:
diff changeset
2795 dst_off += dst_slice;
kono
parents:
diff changeset
2796 src_off += src_slice;
kono
parents:
diff changeset
2797 }
kono
parents:
diff changeset
2798 return 0;
kono
parents:
diff changeset
2799 }
kono
parents:
diff changeset
2800
kono
parents:
diff changeset
2801 int
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2802 omp_target_memcpy_rect (void *dst, const void *src, size_t element_size,
111
kono
parents:
diff changeset
2803 int num_dims, const size_t *volume,
kono
parents:
diff changeset
2804 const size_t *dst_offsets,
kono
parents:
diff changeset
2805 const size_t *src_offsets,
kono
parents:
diff changeset
2806 const size_t *dst_dimensions,
kono
parents:
diff changeset
2807 const size_t *src_dimensions,
kono
parents:
diff changeset
2808 int dst_device_num, int src_device_num)
kono
parents:
diff changeset
2809 {
kono
parents:
diff changeset
2810 struct gomp_device_descr *dst_devicep = NULL, *src_devicep = NULL;
kono
parents:
diff changeset
2811
kono
parents:
diff changeset
2812 if (!dst && !src)
kono
parents:
diff changeset
2813 return INT_MAX;
kono
parents:
diff changeset
2814
kono
parents:
diff changeset
2815 if (dst_device_num != GOMP_DEVICE_HOST_FALLBACK)
kono
parents:
diff changeset
2816 {
kono
parents:
diff changeset
2817 if (dst_device_num < 0)
kono
parents:
diff changeset
2818 return EINVAL;
kono
parents:
diff changeset
2819
kono
parents:
diff changeset
2820 dst_devicep = resolve_device (dst_device_num);
kono
parents:
diff changeset
2821 if (dst_devicep == NULL)
kono
parents:
diff changeset
2822 return EINVAL;
kono
parents:
diff changeset
2823
kono
parents:
diff changeset
2824 if (!(dst_devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2825 || dst_devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
2826 dst_devicep = NULL;
kono
parents:
diff changeset
2827 }
kono
parents:
diff changeset
2828 if (src_device_num != GOMP_DEVICE_HOST_FALLBACK)
kono
parents:
diff changeset
2829 {
kono
parents:
diff changeset
2830 if (src_device_num < 0)
kono
parents:
diff changeset
2831 return EINVAL;
kono
parents:
diff changeset
2832
kono
parents:
diff changeset
2833 src_devicep = resolve_device (src_device_num);
kono
parents:
diff changeset
2834 if (src_devicep == NULL)
kono
parents:
diff changeset
2835 return EINVAL;
kono
parents:
diff changeset
2836
kono
parents:
diff changeset
2837 if (!(src_devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2838 || src_devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
2839 src_devicep = NULL;
kono
parents:
diff changeset
2840 }
kono
parents:
diff changeset
2841
kono
parents:
diff changeset
2842 if (src_devicep != NULL && dst_devicep != NULL && src_devicep != dst_devicep)
kono
parents:
diff changeset
2843 return EINVAL;
kono
parents:
diff changeset
2844
kono
parents:
diff changeset
2845 if (src_devicep)
kono
parents:
diff changeset
2846 gomp_mutex_lock (&src_devicep->lock);
kono
parents:
diff changeset
2847 else if (dst_devicep)
kono
parents:
diff changeset
2848 gomp_mutex_lock (&dst_devicep->lock);
kono
parents:
diff changeset
2849 int ret = omp_target_memcpy_rect_worker (dst, src, element_size, num_dims,
kono
parents:
diff changeset
2850 volume, dst_offsets, src_offsets,
kono
parents:
diff changeset
2851 dst_dimensions, src_dimensions,
kono
parents:
diff changeset
2852 dst_devicep, src_devicep);
kono
parents:
diff changeset
2853 if (src_devicep)
kono
parents:
diff changeset
2854 gomp_mutex_unlock (&src_devicep->lock);
kono
parents:
diff changeset
2855 else if (dst_devicep)
kono
parents:
diff changeset
2856 gomp_mutex_unlock (&dst_devicep->lock);
kono
parents:
diff changeset
2857 return ret;
kono
parents:
diff changeset
2858 }
kono
parents:
diff changeset
2859
kono
parents:
diff changeset
2860 int
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2861 omp_target_associate_ptr (const void *host_ptr, const void *device_ptr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2862 size_t size, size_t device_offset, int device_num)
111
kono
parents:
diff changeset
2863 {
kono
parents:
diff changeset
2864 if (device_num == GOMP_DEVICE_HOST_FALLBACK)
kono
parents:
diff changeset
2865 return EINVAL;
kono
parents:
diff changeset
2866
kono
parents:
diff changeset
2867 if (device_num < 0)
kono
parents:
diff changeset
2868 return EINVAL;
kono
parents:
diff changeset
2869
kono
parents:
diff changeset
2870 struct gomp_device_descr *devicep = resolve_device (device_num);
kono
parents:
diff changeset
2871 if (devicep == NULL)
kono
parents:
diff changeset
2872 return EINVAL;
kono
parents:
diff changeset
2873
kono
parents:
diff changeset
2874 if (!(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
2875 || devicep->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
kono
parents:
diff changeset
2876 return EINVAL;
kono
parents:
diff changeset
2877
kono
parents:
diff changeset
2878 gomp_mutex_lock (&devicep->lock);
kono
parents:
diff changeset
2879
kono
parents:
diff changeset
2880 struct splay_tree_s *mem_map = &devicep->mem_map;
kono
parents:
diff changeset
2881 struct splay_tree_key_s cur_node;
kono
parents:
diff changeset
2882 int ret = EINVAL;
kono
parents:
diff changeset
2883
kono
parents:
diff changeset
2884 cur_node.host_start = (uintptr_t) host_ptr;
kono
parents:
diff changeset
2885 cur_node.host_end = cur_node.host_start + size;
kono
parents:
diff changeset
2886 splay_tree_key n = gomp_map_lookup (mem_map, &cur_node);
kono
parents:
diff changeset
2887 if (n)
kono
parents:
diff changeset
2888 {
kono
parents:
diff changeset
2889 if (n->tgt->tgt_start + n->tgt_offset
kono
parents:
diff changeset
2890 == (uintptr_t) device_ptr + device_offset
kono
parents:
diff changeset
2891 && n->host_start <= cur_node.host_start
kono
parents:
diff changeset
2892 && n->host_end >= cur_node.host_end)
kono
parents:
diff changeset
2893 ret = 0;
kono
parents:
diff changeset
2894 }
kono
parents:
diff changeset
2895 else
kono
parents:
diff changeset
2896 {
kono
parents:
diff changeset
2897 struct target_mem_desc *tgt = gomp_malloc (sizeof (*tgt));
kono
parents:
diff changeset
2898 tgt->array = gomp_malloc (sizeof (*tgt->array));
kono
parents:
diff changeset
2899 tgt->refcount = 1;
kono
parents:
diff changeset
2900 tgt->tgt_start = 0;
kono
parents:
diff changeset
2901 tgt->tgt_end = 0;
kono
parents:
diff changeset
2902 tgt->to_free = NULL;
kono
parents:
diff changeset
2903 tgt->prev = NULL;
kono
parents:
diff changeset
2904 tgt->list_count = 0;
kono
parents:
diff changeset
2905 tgt->device_descr = devicep;
kono
parents:
diff changeset
2906 splay_tree_node array = tgt->array;
kono
parents:
diff changeset
2907 splay_tree_key k = &array->key;
kono
parents:
diff changeset
2908 k->host_start = cur_node.host_start;
kono
parents:
diff changeset
2909 k->host_end = cur_node.host_end;
kono
parents:
diff changeset
2910 k->tgt = tgt;
kono
parents:
diff changeset
2911 k->tgt_offset = (uintptr_t) device_ptr + device_offset;
kono
parents:
diff changeset
2912 k->refcount = REFCOUNT_INFINITY;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2913 k->virtual_refcount = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2914 k->aux = NULL;
111
kono
parents:
diff changeset
2915 array->left = NULL;
kono
parents:
diff changeset
2916 array->right = NULL;
kono
parents:
diff changeset
2917 splay_tree_insert (&devicep->mem_map, array);
kono
parents:
diff changeset
2918 ret = 0;
kono
parents:
diff changeset
2919 }
kono
parents:
diff changeset
2920 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
2921 return ret;
kono
parents:
diff changeset
2922 }
kono
parents:
diff changeset
2923
kono
parents:
diff changeset
2924 int
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2925 omp_target_disassociate_ptr (const void *ptr, int device_num)
111
kono
parents:
diff changeset
2926 {
kono
parents:
diff changeset
2927 if (device_num == GOMP_DEVICE_HOST_FALLBACK)
kono
parents:
diff changeset
2928 return EINVAL;
kono
parents:
diff changeset
2929
kono
parents:
diff changeset
2930 if (device_num < 0)
kono
parents:
diff changeset
2931 return EINVAL;
kono
parents:
diff changeset
2932
kono
parents:
diff changeset
2933 struct gomp_device_descr *devicep = resolve_device (device_num);
kono
parents:
diff changeset
2934 if (devicep == NULL)
kono
parents:
diff changeset
2935 return EINVAL;
kono
parents:
diff changeset
2936
kono
parents:
diff changeset
2937 if (!(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400))
kono
parents:
diff changeset
2938 return EINVAL;
kono
parents:
diff changeset
2939
kono
parents:
diff changeset
2940 gomp_mutex_lock (&devicep->lock);
kono
parents:
diff changeset
2941
kono
parents:
diff changeset
2942 struct splay_tree_s *mem_map = &devicep->mem_map;
kono
parents:
diff changeset
2943 struct splay_tree_key_s cur_node;
kono
parents:
diff changeset
2944 int ret = EINVAL;
kono
parents:
diff changeset
2945
kono
parents:
diff changeset
2946 cur_node.host_start = (uintptr_t) ptr;
kono
parents:
diff changeset
2947 cur_node.host_end = cur_node.host_start;
kono
parents:
diff changeset
2948 splay_tree_key n = gomp_map_lookup (mem_map, &cur_node);
kono
parents:
diff changeset
2949 if (n
kono
parents:
diff changeset
2950 && n->host_start == cur_node.host_start
kono
parents:
diff changeset
2951 && n->refcount == REFCOUNT_INFINITY
kono
parents:
diff changeset
2952 && n->tgt->tgt_start == 0
kono
parents:
diff changeset
2953 && n->tgt->to_free == NULL
kono
parents:
diff changeset
2954 && n->tgt->refcount == 1
kono
parents:
diff changeset
2955 && n->tgt->list_count == 0)
kono
parents:
diff changeset
2956 {
kono
parents:
diff changeset
2957 splay_tree_remove (&devicep->mem_map, n);
kono
parents:
diff changeset
2958 gomp_unmap_tgt (n->tgt);
kono
parents:
diff changeset
2959 ret = 0;
kono
parents:
diff changeset
2960 }
kono
parents:
diff changeset
2961
kono
parents:
diff changeset
2962 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
2963 return ret;
kono
parents:
diff changeset
2964 }
kono
parents:
diff changeset
2965
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2966 int
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2967 omp_pause_resource (omp_pause_resource_t kind, int device_num)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2968 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2969 (void) kind;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2970 if (device_num == GOMP_DEVICE_HOST_FALLBACK)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2971 return gomp_pause_host ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2972 if (device_num < 0 || device_num >= gomp_get_num_devices ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2973 return -1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2974 /* Do nothing for target devices for now. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2975 return 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2976 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2977
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2978 int
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2979 omp_pause_resource_all (omp_pause_resource_t kind)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2980 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2981 (void) kind;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2982 if (gomp_pause_host ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2983 return -1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2984 /* Do nothing for target devices for now. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2985 return 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2986 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2987
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2988 ialias (omp_pause_resource)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2989 ialias (omp_pause_resource_all)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2990
111
kono
parents:
diff changeset
2991 #ifdef PLUGIN_SUPPORT
kono
parents:
diff changeset
2992
kono
parents:
diff changeset
2993 /* This function tries to load a plugin for DEVICE. Name of plugin is passed
kono
parents:
diff changeset
2994 in PLUGIN_NAME.
kono
parents:
diff changeset
2995 The handles of the found functions are stored in the corresponding fields
kono
parents:
diff changeset
2996 of DEVICE. The function returns TRUE on success and FALSE otherwise. */
kono
parents:
diff changeset
2997
kono
parents:
diff changeset
2998 static bool
kono
parents:
diff changeset
2999 gomp_load_plugin_for_device (struct gomp_device_descr *device,
kono
parents:
diff changeset
3000 const char *plugin_name)
kono
parents:
diff changeset
3001 {
kono
parents:
diff changeset
3002 const char *err = NULL, *last_missing = NULL;
kono
parents:
diff changeset
3003
kono
parents:
diff changeset
3004 void *plugin_handle = dlopen (plugin_name, RTLD_LAZY);
kono
parents:
diff changeset
3005 if (!plugin_handle)
kono
parents:
diff changeset
3006 goto dl_fail;
kono
parents:
diff changeset
3007
kono
parents:
diff changeset
3008 /* Check if all required functions are available in the plugin and store
kono
parents:
diff changeset
3009 their handlers. None of the symbols can legitimately be NULL,
kono
parents:
diff changeset
3010 so we don't need to check dlerror all the time. */
kono
parents:
diff changeset
3011 #define DLSYM(f) \
kono
parents:
diff changeset
3012 if (!(device->f##_func = dlsym (plugin_handle, "GOMP_OFFLOAD_" #f))) \
kono
parents:
diff changeset
3013 goto dl_fail
kono
parents:
diff changeset
3014 /* Similar, but missing functions are not an error. Return false if
kono
parents:
diff changeset
3015 failed, true otherwise. */
kono
parents:
diff changeset
3016 #define DLSYM_OPT(f, n) \
kono
parents:
diff changeset
3017 ((device->f##_func = dlsym (plugin_handle, "GOMP_OFFLOAD_" #n)) \
kono
parents:
diff changeset
3018 || (last_missing = #n, 0))
kono
parents:
diff changeset
3019
kono
parents:
diff changeset
3020 DLSYM (version);
kono
parents:
diff changeset
3021 if (device->version_func () != GOMP_VERSION)
kono
parents:
diff changeset
3022 {
kono
parents:
diff changeset
3023 err = "plugin version mismatch";
kono
parents:
diff changeset
3024 goto fail;
kono
parents:
diff changeset
3025 }
kono
parents:
diff changeset
3026
kono
parents:
diff changeset
3027 DLSYM (get_name);
kono
parents:
diff changeset
3028 DLSYM (get_caps);
kono
parents:
diff changeset
3029 DLSYM (get_type);
kono
parents:
diff changeset
3030 DLSYM (get_num_devices);
kono
parents:
diff changeset
3031 DLSYM (init_device);
kono
parents:
diff changeset
3032 DLSYM (fini_device);
kono
parents:
diff changeset
3033 DLSYM (load_image);
kono
parents:
diff changeset
3034 DLSYM (unload_image);
kono
parents:
diff changeset
3035 DLSYM (alloc);
kono
parents:
diff changeset
3036 DLSYM (free);
kono
parents:
diff changeset
3037 DLSYM (dev2host);
kono
parents:
diff changeset
3038 DLSYM (host2dev);
kono
parents:
diff changeset
3039 device->capabilities = device->get_caps_func ();
kono
parents:
diff changeset
3040 if (device->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
3041 {
kono
parents:
diff changeset
3042 DLSYM (run);
kono
parents:
diff changeset
3043 DLSYM (async_run);
kono
parents:
diff changeset
3044 DLSYM_OPT (can_run, can_run);
kono
parents:
diff changeset
3045 DLSYM (dev2dev);
kono
parents:
diff changeset
3046 }
kono
parents:
diff changeset
3047 if (device->capabilities & GOMP_OFFLOAD_CAP_OPENACC_200)
kono
parents:
diff changeset
3048 {
kono
parents:
diff changeset
3049 if (!DLSYM_OPT (openacc.exec, openacc_exec)
kono
parents:
diff changeset
3050 || !DLSYM_OPT (openacc.create_thread_data,
kono
parents:
diff changeset
3051 openacc_create_thread_data)
kono
parents:
diff changeset
3052 || !DLSYM_OPT (openacc.destroy_thread_data,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3053 openacc_destroy_thread_data)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3054 || !DLSYM_OPT (openacc.async.construct, openacc_async_construct)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3055 || !DLSYM_OPT (openacc.async.destruct, openacc_async_destruct)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3056 || !DLSYM_OPT (openacc.async.test, openacc_async_test)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3057 || !DLSYM_OPT (openacc.async.synchronize, openacc_async_synchronize)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3058 || !DLSYM_OPT (openacc.async.serialize, openacc_async_serialize)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3059 || !DLSYM_OPT (openacc.async.queue_callback,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3060 openacc_async_queue_callback)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3061 || !DLSYM_OPT (openacc.async.exec, openacc_async_exec)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3062 || !DLSYM_OPT (openacc.async.dev2host, openacc_async_dev2host)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3063 || !DLSYM_OPT (openacc.async.host2dev, openacc_async_host2dev)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3064 || !DLSYM_OPT (openacc.get_property, openacc_get_property))
111
kono
parents:
diff changeset
3065 {
kono
parents:
diff changeset
3066 /* Require all the OpenACC handlers if we have
kono
parents:
diff changeset
3067 GOMP_OFFLOAD_CAP_OPENACC_200. */
kono
parents:
diff changeset
3068 err = "plugin missing OpenACC handler function";
kono
parents:
diff changeset
3069 goto fail;
kono
parents:
diff changeset
3070 }
kono
parents:
diff changeset
3071
kono
parents:
diff changeset
3072 unsigned cuda = 0;
kono
parents:
diff changeset
3073 cuda += DLSYM_OPT (openacc.cuda.get_current_device,
kono
parents:
diff changeset
3074 openacc_cuda_get_current_device);
kono
parents:
diff changeset
3075 cuda += DLSYM_OPT (openacc.cuda.get_current_context,
kono
parents:
diff changeset
3076 openacc_cuda_get_current_context);
kono
parents:
diff changeset
3077 cuda += DLSYM_OPT (openacc.cuda.get_stream, openacc_cuda_get_stream);
kono
parents:
diff changeset
3078 cuda += DLSYM_OPT (openacc.cuda.set_stream, openacc_cuda_set_stream);
kono
parents:
diff changeset
3079 if (cuda && cuda != 4)
kono
parents:
diff changeset
3080 {
kono
parents:
diff changeset
3081 /* Make sure all the CUDA functions are there if any of them are. */
kono
parents:
diff changeset
3082 err = "plugin missing OpenACC CUDA handler function";
kono
parents:
diff changeset
3083 goto fail;
kono
parents:
diff changeset
3084 }
kono
parents:
diff changeset
3085 }
kono
parents:
diff changeset
3086 #undef DLSYM
kono
parents:
diff changeset
3087 #undef DLSYM_OPT
kono
parents:
diff changeset
3088
kono
parents:
diff changeset
3089 return 1;
kono
parents:
diff changeset
3090
kono
parents:
diff changeset
3091 dl_fail:
kono
parents:
diff changeset
3092 err = dlerror ();
kono
parents:
diff changeset
3093 fail:
kono
parents:
diff changeset
3094 gomp_error ("while loading %s: %s", plugin_name, err);
kono
parents:
diff changeset
3095 if (last_missing)
kono
parents:
diff changeset
3096 gomp_error ("missing function was %s", last_missing);
kono
parents:
diff changeset
3097 if (plugin_handle)
kono
parents:
diff changeset
3098 dlclose (plugin_handle);
kono
parents:
diff changeset
3099
kono
parents:
diff changeset
3100 return 0;
kono
parents:
diff changeset
3101 }
kono
parents:
diff changeset
3102
kono
parents:
diff changeset
3103 /* This function finalizes all initialized devices. */
kono
parents:
diff changeset
3104
kono
parents:
diff changeset
3105 static void
kono
parents:
diff changeset
3106 gomp_target_fini (void)
kono
parents:
diff changeset
3107 {
kono
parents:
diff changeset
3108 int i;
kono
parents:
diff changeset
3109 for (i = 0; i < num_devices; i++)
kono
parents:
diff changeset
3110 {
kono
parents:
diff changeset
3111 bool ret = true;
kono
parents:
diff changeset
3112 struct gomp_device_descr *devicep = &devices[i];
kono
parents:
diff changeset
3113 gomp_mutex_lock (&devicep->lock);
kono
parents:
diff changeset
3114 if (devicep->state == GOMP_DEVICE_INITIALIZED)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3115 ret = gomp_fini_device (devicep);
111
kono
parents:
diff changeset
3116 gomp_mutex_unlock (&devicep->lock);
kono
parents:
diff changeset
3117 if (!ret)
kono
parents:
diff changeset
3118 gomp_fatal ("device finalization failed");
kono
parents:
diff changeset
3119 }
kono
parents:
diff changeset
3120 }
kono
parents:
diff changeset
3121
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3122 /* This function initializes the runtime for offloading.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3123 It parses the list of offload plugins, and tries to load these.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3124 On return, the variables NUM_DEVICES and NUM_DEVICES_OPENMP
111
kono
parents:
diff changeset
3125 will be set, and the array DEVICES initialized, containing descriptors for
kono
parents:
diff changeset
3126 corresponding devices, first the GOMP_OFFLOAD_CAP_OPENMP_400 ones, follows
kono
parents:
diff changeset
3127 by the others. */
kono
parents:
diff changeset
3128
kono
parents:
diff changeset
3129 static void
kono
parents:
diff changeset
3130 gomp_target_init (void)
kono
parents:
diff changeset
3131 {
kono
parents:
diff changeset
3132 const char *prefix ="libgomp-plugin-";
kono
parents:
diff changeset
3133 const char *suffix = SONAME_SUFFIX (1);
kono
parents:
diff changeset
3134 const char *cur, *next;
kono
parents:
diff changeset
3135 char *plugin_name;
kono
parents:
diff changeset
3136 int i, new_num_devices;
kono
parents:
diff changeset
3137
kono
parents:
diff changeset
3138 num_devices = 0;
kono
parents:
diff changeset
3139 devices = NULL;
kono
parents:
diff changeset
3140
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3141 cur = OFFLOAD_PLUGINS;
111
kono
parents:
diff changeset
3142 if (*cur)
kono
parents:
diff changeset
3143 do
kono
parents:
diff changeset
3144 {
kono
parents:
diff changeset
3145 struct gomp_device_descr current_device;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3146 size_t prefix_len, suffix_len, cur_len;
111
kono
parents:
diff changeset
3147
kono
parents:
diff changeset
3148 next = strchr (cur, ',');
kono
parents:
diff changeset
3149
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3150 prefix_len = strlen (prefix);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3151 cur_len = next ? next - cur : strlen (cur);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3152 suffix_len = strlen (suffix);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3153
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3154 plugin_name = (char *) malloc (prefix_len + cur_len + suffix_len + 1);
111
kono
parents:
diff changeset
3155 if (!plugin_name)
kono
parents:
diff changeset
3156 {
kono
parents:
diff changeset
3157 num_devices = 0;
kono
parents:
diff changeset
3158 break;
kono
parents:
diff changeset
3159 }
kono
parents:
diff changeset
3160
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3161 memcpy (plugin_name, prefix, prefix_len);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3162 memcpy (plugin_name + prefix_len, cur, cur_len);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3163 memcpy (plugin_name + prefix_len + cur_len, suffix, suffix_len + 1);
111
kono
parents:
diff changeset
3164
kono
parents:
diff changeset
3165 if (gomp_load_plugin_for_device (&current_device, plugin_name))
kono
parents:
diff changeset
3166 {
kono
parents:
diff changeset
3167 new_num_devices = current_device.get_num_devices_func ();
kono
parents:
diff changeset
3168 if (new_num_devices >= 1)
kono
parents:
diff changeset
3169 {
kono
parents:
diff changeset
3170 /* Augment DEVICES and NUM_DEVICES. */
kono
parents:
diff changeset
3171
kono
parents:
diff changeset
3172 devices = realloc (devices, (num_devices + new_num_devices)
kono
parents:
diff changeset
3173 * sizeof (struct gomp_device_descr));
kono
parents:
diff changeset
3174 if (!devices)
kono
parents:
diff changeset
3175 {
kono
parents:
diff changeset
3176 num_devices = 0;
kono
parents:
diff changeset
3177 free (plugin_name);
kono
parents:
diff changeset
3178 break;
kono
parents:
diff changeset
3179 }
kono
parents:
diff changeset
3180
kono
parents:
diff changeset
3181 current_device.name = current_device.get_name_func ();
kono
parents:
diff changeset
3182 /* current_device.capabilities has already been set. */
kono
parents:
diff changeset
3183 current_device.type = current_device.get_type_func ();
kono
parents:
diff changeset
3184 current_device.mem_map.root = NULL;
kono
parents:
diff changeset
3185 current_device.state = GOMP_DEVICE_UNINITIALIZED;
kono
parents:
diff changeset
3186 for (i = 0; i < new_num_devices; i++)
kono
parents:
diff changeset
3187 {
kono
parents:
diff changeset
3188 current_device.target_id = i;
kono
parents:
diff changeset
3189 devices[num_devices] = current_device;
kono
parents:
diff changeset
3190 gomp_mutex_init (&devices[num_devices].lock);
kono
parents:
diff changeset
3191 num_devices++;
kono
parents:
diff changeset
3192 }
kono
parents:
diff changeset
3193 }
kono
parents:
diff changeset
3194 }
kono
parents:
diff changeset
3195
kono
parents:
diff changeset
3196 free (plugin_name);
kono
parents:
diff changeset
3197 cur = next + 1;
kono
parents:
diff changeset
3198 }
kono
parents:
diff changeset
3199 while (next);
kono
parents:
diff changeset
3200
kono
parents:
diff changeset
3201 /* In DEVICES, sort the GOMP_OFFLOAD_CAP_OPENMP_400 ones first, and set
kono
parents:
diff changeset
3202 NUM_DEVICES_OPENMP. */
kono
parents:
diff changeset
3203 struct gomp_device_descr *devices_s
kono
parents:
diff changeset
3204 = malloc (num_devices * sizeof (struct gomp_device_descr));
kono
parents:
diff changeset
3205 if (!devices_s)
kono
parents:
diff changeset
3206 {
kono
parents:
diff changeset
3207 num_devices = 0;
kono
parents:
diff changeset
3208 free (devices);
kono
parents:
diff changeset
3209 devices = NULL;
kono
parents:
diff changeset
3210 }
kono
parents:
diff changeset
3211 num_devices_openmp = 0;
kono
parents:
diff changeset
3212 for (i = 0; i < num_devices; i++)
kono
parents:
diff changeset
3213 if (devices[i].capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
kono
parents:
diff changeset
3214 devices_s[num_devices_openmp++] = devices[i];
kono
parents:
diff changeset
3215 int num_devices_after_openmp = num_devices_openmp;
kono
parents:
diff changeset
3216 for (i = 0; i < num_devices; i++)
kono
parents:
diff changeset
3217 if (!(devices[i].capabilities & GOMP_OFFLOAD_CAP_OPENMP_400))
kono
parents:
diff changeset
3218 devices_s[num_devices_after_openmp++] = devices[i];
kono
parents:
diff changeset
3219 free (devices);
kono
parents:
diff changeset
3220 devices = devices_s;
kono
parents:
diff changeset
3221
kono
parents:
diff changeset
3222 for (i = 0; i < num_devices; i++)
kono
parents:
diff changeset
3223 {
kono
parents:
diff changeset
3224 /* The 'devices' array can be moved (by the realloc call) until we have
kono
parents:
diff changeset
3225 found all the plugins, so registering with the OpenACC runtime (which
kono
parents:
diff changeset
3226 takes a copy of the pointer argument) must be delayed until now. */
kono
parents:
diff changeset
3227 if (devices[i].capabilities & GOMP_OFFLOAD_CAP_OPENACC_200)
kono
parents:
diff changeset
3228 goacc_register (&devices[i]);
kono
parents:
diff changeset
3229 }
kono
parents:
diff changeset
3230
kono
parents:
diff changeset
3231 if (atexit (gomp_target_fini) != 0)
kono
parents:
diff changeset
3232 gomp_fatal ("atexit failed");
kono
parents:
diff changeset
3233 }
kono
parents:
diff changeset
3234
kono
parents:
diff changeset
3235 #else /* PLUGIN_SUPPORT */
kono
parents:
diff changeset
3236 /* If dlfcn.h is unavailable we always fallback to host execution.
kono
parents:
diff changeset
3237 GOMP_target* routines are just stubs for this case. */
kono
parents:
diff changeset
3238 static void
kono
parents:
diff changeset
3239 gomp_target_init (void)
kono
parents:
diff changeset
3240 {
kono
parents:
diff changeset
3241 }
kono
parents:
diff changeset
3242 #endif /* PLUGIN_SUPPORT */