aboutsummaryrefslogtreecommitdiff
path: root/liboffloadmic/runtime/offload_omp_target.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'liboffloadmic/runtime/offload_omp_target.cpp')
-rw-r--r--liboffloadmic/runtime/offload_omp_target.cpp178
1 files changed, 177 insertions, 1 deletions
diff --git a/liboffloadmic/runtime/offload_omp_target.cpp b/liboffloadmic/runtime/offload_omp_target.cpp
index 91baef5..2bcfef5 100644
--- a/liboffloadmic/runtime/offload_omp_target.cpp
+++ b/liboffloadmic/runtime/offload_omp_target.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2014-2015 Intel Corporation. All Rights Reserved.
+ Copyright (c) 2014-2016 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -48,6 +48,182 @@ int omp_get_num_devices() __GOMP_NOTHROW
return mic_engines_total;
}
+// OpenMP 4.5 APIs
+
+// COI supports 3-dim multiD transfers
+#define MAX_ARRAY_RANK 3
+
+DLL_LOCAL void omp_target_alloc_target(
+ void *ofld_
+)
+{
+ OFFLOAD ofld = (OFFLOAD) ofld_;
+ VarDesc vars[2] = {0};
+ size_t size;
+ void* memory;
+
+ vars[0].type.src = c_data;
+ vars[0].type.dst = c_data;
+ vars[0].direction.bits = c_parameter_in;
+ vars[0].ptr = &size;
+
+ vars[1].type.src = c_data;
+ vars[1].type.dst = c_data;
+ vars[1].direction.bits = c_parameter_out;
+ vars[1].ptr = &memory;
+
+ OFFLOAD_TARGET_ENTER(ofld, 2, vars, NULL);
+ OFFLOAD_DEBUG_TRACE(2, "omp_target_alloc(%lld)\n", size);
+ // We do not check for malloc returning NULL because the
+ // specification of this API includes the possibility of failure.
+ // The user will check the returned result
+ memory = malloc(size);
+ OFFLOAD_DEBUG_TRACE(2, "omp_target_alloc allocated at %p\n", memory);
+ OFFLOAD_TARGET_LEAVE(ofld);
+}
+
+DLL_LOCAL void omp_target_free_target(
+ void *ofld_
+)
+{
+ OFFLOAD ofld = (OFFLOAD) ofld_;
+ VarDesc vars[1] = {0};
+ void* memory;
+
+ vars[0].type.src = c_data;
+ vars[0].type.dst = c_data;
+ vars[0].direction.bits = c_parameter_in;
+ vars[0].ptr = &memory;
+
+ OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL);
+ OFFLOAD_DEBUG_TRACE(2, "omp_target_free(%p)\n", memory);
+ free(memory);
+ OFFLOAD_DEBUG_TRACE(2, "omp_target_free freed\n");
+ OFFLOAD_TARGET_LEAVE(ofld);
+}
+
+DLL_LOCAL void omp_target_memcpy_target(
+ void *ofld_
+)
+{
+ OFFLOAD ofld = (OFFLOAD) ofld_;
+ VarDesc vars[3] = {0};
+ void* dst;
+ void* src;
+ size_t length;
+
+ vars[0].type.src = c_data;
+ vars[0].type.dst = c_data;
+ vars[0].direction.bits = c_parameter_in;
+ vars[0].ptr = &dst;
+
+ vars[1].type.src = c_data;
+ vars[1].type.dst = c_data;
+ vars[1].direction.bits = c_parameter_in;
+ vars[1].ptr = &src;
+
+ vars[2].type.src = c_data;
+ vars[2].type.dst = c_data;
+ vars[2].direction.bits = c_parameter_in;
+ vars[2].ptr = &length;
+
+ OFFLOAD_TARGET_ENTER(ofld, 3, vars, NULL);
+ OFFLOAD_DEBUG_TRACE(2, "omp_target_memcpy(%p, %p, %lld)\n",
+ dst, src, length);
+ memcpy(dst, src, length);
+
+ OFFLOAD_DEBUG_TRACE(2, "omp_target_memcpy done\n");
+ OFFLOAD_TARGET_LEAVE(ofld);
+}
+
+static size_t bytesize_at_this_dimension(
+ size_t element_size,
+ int num_dims,
+ const size_t* dimensions
+)
+{
+ if (num_dims > 1) {
+ return dimensions[1] *
+ bytesize_at_this_dimension(
+ element_size, num_dims-1, dimensions+1);
+ } else {
+ return element_size;
+ }
+}
+
+static void memcpy_rect(
+ char *dst,
+ char *src,
+ size_t element_size,
+ int num_dims,
+ const size_t *volume,
+ const size_t *dst_offsets,
+ const size_t *src_offsets,
+ const size_t *dst_dimensions,
+ const size_t *src_dimensions
+)
+{
+ if (num_dims > 1) {
+ int count = volume[0];
+ int dst_index = dst_offsets[0];
+ int src_index = src_offsets[0];
+ size_t dst_element_size =
+ bytesize_at_this_dimension(element_size, num_dims, dst_dimensions);
+ size_t src_element_size =
+ bytesize_at_this_dimension(element_size, num_dims, src_dimensions);
+ for (; count>0; dst_index++, src_index++, count--) {
+ memcpy_rect(dst+dst_element_size*dst_index,
+ src+src_element_size*src_index,
+ element_size, num_dims-1, volume+1,
+ dst_offsets+1, src_offsets+1,
+ dst_dimensions+1, src_dimensions+1);
+ }
+ } else {
+ memcpy(dst+dst_offsets[0]*element_size,
+ src+src_offsets[0]*element_size,
+ element_size * volume[0]);
+ }
+}
+
+DLL_LOCAL void omp_target_memcpy_rect_target(
+ void *ofld_
+)
+{
+ OFFLOAD ofld = (OFFLOAD) ofld_;
+ VarDesc vars[1] = {0};
+ struct parameters {
+ void *dst;
+ void *src;
+ size_t element_size;
+ int num_dims;
+ size_t array_info[MAX_ARRAY_RANK*5];
+ } parameters;
+
+ vars[0].type.src = c_data;
+ vars[0].type.dst = c_data;
+ vars[0].direction.bits = c_parameter_in;
+ vars[0].ptr = &parameters;
+
+ OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL);
+ OFFLOAD_DEBUG_TRACE(2, "omp_target_memcpy_rect(%p, %p, %lld, %d)\n",
+ parameters.dst, parameters.src,
+ parameters.element_size, parameters.num_dims);
+ memcpy_rect(
+ (char*)parameters.dst, (char*)parameters.src, parameters.element_size,
+ parameters.num_dims,
+ &parameters.array_info[0],
+ &parameters.array_info[parameters.num_dims],
+ &parameters.array_info[parameters.num_dims*2],
+ &parameters.array_info[parameters.num_dims*3],
+ &parameters.array_info[parameters.num_dims*4]);
+
+ OFFLOAD_DEBUG_TRACE(2, "omp_target_memcpy_rect done\n");
+ OFFLOAD_TARGET_LEAVE(ofld);
+}
+
+// End of OpenMP 4.5 APIs
+
+
// OpenMP API wrappers
static void omp_send_int_to_host(