diff options
Diffstat (limited to 'liboffloadmic/runtime/offload_omp_target.cpp')
-rw-r--r-- | liboffloadmic/runtime/offload_omp_target.cpp | 178 |
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 = ¶meters; + + 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, + ¶meters.array_info[0], + ¶meters.array_info[parameters.num_dims], + ¶meters.array_info[parameters.num_dims*2], + ¶meters.array_info[parameters.num_dims*3], + ¶meters.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( |