aboutsummaryrefslogtreecommitdiff
path: root/libgomp
diff options
context:
space:
mode:
authorJulian Brown <julian@codesourcery.com>2019-11-20 17:53:31 +0000
committerJulian Brown <julian@codesourcery.com>2019-11-20 17:53:31 +0000
commita52ee1727738e17b4ad70b681b388c03619cf879 (patch)
treef0c07d7c1a154a3c4799f63986997bc0d7e1d559 /libgomp
parent9a095c09255c4e650fed9f5e904877f2f1d87f85 (diff)
Fix host-to-device copies from rodata for AMD GCN
libgomp/ * plugin/plugin-gcn.c (hsa_memory_copy_wrapper): New. (copy_data, GOMP_OFFLOAD_host2dev): Use above function. (GOMP_OFFLOAD_dev2host, GOMP_OFFLOAD_dev2dev): Check hsa_memory_copy return code. Reviewed-by: Andrew Stubbs <ams@codesourcery.com> git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@278516 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgomp')
-rw-r--r--libgomp/ChangeLog7
-rw-r--r--libgomp/plugin/plugin-gcn.c38
2 files changed, 41 insertions, 4 deletions
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 9d4a34c90a3..eb51462bb3f 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,5 +1,12 @@
2019-11-20 Julian Brown <julian@codesourcery.com>
+ * plugin/plugin-gcn.c (hsa_memory_copy_wrapper): New.
+ (copy_data, GOMP_OFFLOAD_host2dev): Use above function.
+ (GOMP_OFFLOAD_dev2host, GOMP_OFFLOAD_dev2dev): Check hsa_memory_copy
+ return code.
+
+2019-11-20 Julian Brown <julian@codesourcery.com>
+
PR libgomp/92511
* oacc-mem.c (present_create_copy): Fix device pointer return value in
diff --git a/libgomp/plugin/plugin-gcn.c b/libgomp/plugin/plugin-gcn.c
index 583916759a5..392a0eeca95 100644
--- a/libgomp/plugin/plugin-gcn.c
+++ b/libgomp/plugin/plugin-gcn.c
@@ -2940,6 +2940,32 @@ maybe_init_omp_async (struct agent_info *agent)
= GOMP_OFFLOAD_openacc_async_construct (agent->device_id);
}
+/* A wrapper that works around an issue in the HSA runtime with host-to-device
+ copies from read-only pages. */
+
+static void
+hsa_memory_copy_wrapper (void *dst, const void *src, size_t len)
+{
+ hsa_status_t status = hsa_fns.hsa_memory_copy_fn (dst, src, len);
+
+ if (status == HSA_STATUS_SUCCESS)
+ return;
+
+ /* It appears that the copy fails if the source data is in a read-only page.
+ We can't detect that easily, so try copying the data to a temporary buffer
+ and doing the copy again if we got an error above. */
+
+ GCN_WARNING ("Read-only data transfer bug workaround triggered for "
+ "[%p:+%d]\n", (void *) src, (int) len);
+
+ void *src_copy = malloc (len);
+ memcpy (src_copy, src, len);
+ status = hsa_fns.hsa_memory_copy_fn (dst, (const void *) src_copy, len);
+ free (src_copy);
+ if (status != HSA_STATUS_SUCCESS)
+ GOMP_PLUGIN_error ("memory copy failed");
+}
+
/* Copy data to or from a device. This is intended for use as an async
callback event. */
@@ -2950,7 +2976,7 @@ copy_data (void *data_)
GCN_DEBUG ("Async thread %d:%d: Copying %zu bytes from (%p) to (%p)\n",
data->aq->agent->device_id, data->aq->id, data->len, data->src,
data->dst);
- hsa_fns.hsa_memory_copy_fn (data->dst, data->src, data->len);
+ hsa_memory_copy_wrapper (data->dst, data->src, data->len);
if (data->free_src)
free ((void *) data->src);
free (data);
@@ -3643,7 +3669,9 @@ GOMP_OFFLOAD_dev2host (int device, void *dst, const void *src, size_t n)
{
GCN_DEBUG ("Copying %zu bytes from device %d (%p) to host (%p)\n", n, device,
src, dst);
- hsa_fns.hsa_memory_copy_fn (dst, src, n);
+ hsa_status_t status = hsa_fns.hsa_memory_copy_fn (dst, src, n);
+ if (status != HSA_STATUS_SUCCESS)
+ GOMP_PLUGIN_error ("memory copy failed");
return true;
}
@@ -3654,7 +3682,7 @@ GOMP_OFFLOAD_host2dev (int device, void *dst, const void *src, size_t n)
{
GCN_DEBUG ("Copying %zu bytes from host (%p) to device %d (%p)\n", n, src,
device, dst);
- hsa_fns.hsa_memory_copy_fn (dst, src, n);
+ hsa_memory_copy_wrapper (dst, src, n);
return true;
}
@@ -3675,7 +3703,9 @@ GOMP_OFFLOAD_dev2dev (int device, void *dst, const void *src, size_t n)
GCN_DEBUG ("Copying %zu bytes from device %d (%p) to device %d (%p)\n", n,
device, src, device, dst);
- hsa_fns.hsa_memory_copy_fn (dst, src, n);
+ hsa_status_t status = hsa_fns.hsa_memory_copy_fn (dst, src, n);
+ if (status != HSA_STATUS_SUCCESS)
+ GOMP_PLUGIN_error ("memory copy failed");
return true;
}