annotate libgomp/target.c @ 138:fc828634a951

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