forked from OSchip/llvm-project
[OpenMP] Add support for GOMP depobj
GOMP depobjs are represented as a two intptr_t array. The first element is the base address of the dependency and the second element is the flag indicating the type the depobj represents. Differential Revision: https://reviews.llvm.org/D108790
This commit is contained in:
parent
f68939d3d9
commit
258e27aae1
|
@ -23,18 +23,24 @@ enum {
|
|||
KMP_GOMP_TASK_DEPENDS_FLAG = 8
|
||||
};
|
||||
|
||||
enum {
|
||||
KMP_GOMP_DEPOBJ_IN = 1,
|
||||
KMP_GOMP_DEPOBJ_OUT = 2,
|
||||
KMP_GOMP_DEPOBJ_INOUT = 3,
|
||||
KMP_GOMP_DEPOBJ_MTXINOUTSET = 4
|
||||
};
|
||||
|
||||
// This class helps convert gomp dependency info into
|
||||
// kmp_depend_info_t structures
|
||||
class kmp_gomp_depends_info_t {
|
||||
void **depend;
|
||||
kmp_int32 num_deps;
|
||||
size_t num_out, num_mutexinout, num_in;
|
||||
size_t num_out, num_mutexinout, num_in, num_depobj;
|
||||
size_t offset;
|
||||
|
||||
public:
|
||||
kmp_gomp_depends_info_t(void **depend) : depend(depend) {
|
||||
size_t ndeps = (kmp_intptr_t)depend[0];
|
||||
size_t num_doable;
|
||||
// GOMP taskdep structure:
|
||||
// if depend[0] != 0:
|
||||
// depend = [ ndeps | nout | &out | ... | &out | &in | ... | &in ]
|
||||
|
@ -45,21 +51,17 @@ public:
|
|||
if (ndeps) {
|
||||
num_out = (kmp_intptr_t)depend[1];
|
||||
num_in = ndeps - num_out;
|
||||
num_mutexinout = 0;
|
||||
num_doable = ndeps;
|
||||
num_mutexinout = num_depobj = 0;
|
||||
offset = 2;
|
||||
} else {
|
||||
ndeps = (kmp_intptr_t)depend[1];
|
||||
num_out = (kmp_intptr_t)depend[2];
|
||||
num_mutexinout = (kmp_intptr_t)depend[3];
|
||||
num_in = (kmp_intptr_t)depend[4];
|
||||
num_doable = num_out + num_mutexinout + num_in;
|
||||
num_depobj = ndeps - num_out - num_mutexinout - num_in;
|
||||
KMP_ASSERT(num_depobj <= ndeps);
|
||||
offset = 5;
|
||||
}
|
||||
// TODO: Support gomp depobj
|
||||
if (ndeps != num_doable) {
|
||||
KMP_FATAL(GompFeatureNotSupported, "depobj");
|
||||
}
|
||||
num_deps = static_cast<kmp_int32>(ndeps);
|
||||
}
|
||||
kmp_int32 get_num_deps() const { return num_deps; }
|
||||
|
@ -67,7 +69,6 @@ public:
|
|||
kmp_depend_info_t retval;
|
||||
memset(&retval, '\0', sizeof(retval));
|
||||
KMP_ASSERT(index < (size_t)num_deps);
|
||||
retval.base_addr = (kmp_intptr_t)depend[offset + index];
|
||||
retval.len = 0;
|
||||
// Because inout and out are logically equivalent,
|
||||
// use inout and in dependency flags. GOMP does not provide a
|
||||
|
@ -75,10 +76,37 @@ public:
|
|||
if (index < num_out) {
|
||||
retval.flags.in = 1;
|
||||
retval.flags.out = 1;
|
||||
retval.base_addr = (kmp_intptr_t)depend[offset + index];
|
||||
} else if (index >= num_out && index < (num_out + num_mutexinout)) {
|
||||
retval.flags.mtx = 1;
|
||||
} else {
|
||||
retval.base_addr = (kmp_intptr_t)depend[offset + index];
|
||||
} else if (index >= (num_out + num_mutexinout) &&
|
||||
index < (num_out + num_mutexinout + num_in)) {
|
||||
retval.flags.in = 1;
|
||||
retval.base_addr = (kmp_intptr_t)depend[offset + index];
|
||||
} else {
|
||||
// depobj is a two element array (size of elements are size of pointer)
|
||||
// depobj[0] = base_addr
|
||||
// depobj[1] = type (in, out, inout, mutexinoutset, etc.)
|
||||
kmp_intptr_t *depobj = (kmp_intptr_t *)depend[offset + index];
|
||||
retval.base_addr = depobj[0];
|
||||
switch (depobj[1]) {
|
||||
case KMP_GOMP_DEPOBJ_IN:
|
||||
retval.flags.in = 1;
|
||||
break;
|
||||
case KMP_GOMP_DEPOBJ_OUT:
|
||||
retval.flags.out = 1;
|
||||
break;
|
||||
case KMP_GOMP_DEPOBJ_INOUT:
|
||||
retval.flags.in = 1;
|
||||
retval.flags.out = 1;
|
||||
break;
|
||||
case KMP_GOMP_DEPOBJ_MTXINOUTSET:
|
||||
retval.flags.mtx = 1;
|
||||
break;
|
||||
default:
|
||||
KMP_FATAL(GompFeatureNotSupported, "Unknown depobj type");
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ pythonize_bool(LIBOMP_OMPT_SUPPORT)
|
|||
pythonize_bool(LIBOMP_OMPT_OPTIONAL)
|
||||
pythonize_bool(LIBOMP_HAVE_LIBM)
|
||||
pythonize_bool(LIBOMP_HAVE_LIBATOMIC)
|
||||
pythonize_bool(OPENMP_STANDALONE_BUILD)
|
||||
|
||||
add_library(ompt-print-callback INTERFACE)
|
||||
target_include_directories(ompt-print-callback INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/ompt)
|
||||
|
|
|
@ -42,10 +42,11 @@ config.test_exec_root = config.libomp_obj_root
|
|||
config.test_format = lit.formats.ShTest()
|
||||
|
||||
# compiler flags
|
||||
config.test_flags = " -I " + config.test_source_root + \
|
||||
" -I " + config.omp_header_directory + \
|
||||
flags = " -I " + config.test_source_root + \
|
||||
" -L " + config.library_dir + \
|
||||
" " + config.test_extra_flags
|
||||
config.test_flags = " -I " + config.omp_header_directory + flags
|
||||
config.test_flags_use_compiler_omp_h = flags
|
||||
|
||||
# extra libraries
|
||||
libs = ""
|
||||
|
@ -126,6 +127,16 @@ config.substitutions.append(("%libomp-run", "%t"))
|
|||
config.substitutions.append(("%clangXX", config.test_cxx_compiler))
|
||||
config.substitutions.append(("%clang", config.test_c_compiler))
|
||||
config.substitutions.append(("%openmp_flags", config.test_openmp_flags))
|
||||
# %flags-use-compiler-omp-h allows us to use the test compiler's omp.h file which
|
||||
# may have different definitions of structures than our omp.h file.
|
||||
if config.is_standalone_build:
|
||||
config.substitutions.append(("%flags-use-compiler-omp-h",
|
||||
config.test_flags_use_compiler_omp_h))
|
||||
else:
|
||||
# If testing the runtime within an LLVM tree, then always include omp.h
|
||||
# directory associated with the new clang compiler.
|
||||
config.substitutions.append(("%flags-use-compiler-omp-h",
|
||||
config.test_flags))
|
||||
config.substitutions.append(("%flags", config.test_flags))
|
||||
config.substitutions.append(("%python", '"%s"' % (sys.executable)))
|
||||
config.substitutions.append(("%not", config.test_not))
|
||||
|
|
|
@ -16,6 +16,7 @@ config.using_hwloc = @LIBOMP_USE_HWLOC@
|
|||
config.has_ompt = @LIBOMP_OMPT_SUPPORT@ and @LIBOMP_OMPT_OPTIONAL@
|
||||
config.has_libm = @LIBOMP_HAVE_LIBM@
|
||||
config.has_libatomic = @LIBOMP_HAVE_LIBATOMIC@
|
||||
config.is_standalone_build = @OPENMP_STANDALONE_BUILD@
|
||||
|
||||
# Let the main config do the real work.
|
||||
lit_config.load_config(config, "@LIBOMP_BASE_DIR@/test/lit.cfg")
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
// RUN: %clang %openmp_flags %flags-use-compiler-omp-h %s -o %t && %libomp-run
|
||||
// UNSUPPORTED: gcc-5, gcc-6, gcc-7, gcc-8
|
||||
// UNSUPPORTED: clang-5, clang-6, clang-7, clang-8, clang-9, clang-10
|
||||
// UNSUPPORTED: icc
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <omp.h>
|
||||
#include "omp_my_sleep.h"
|
||||
|
||||
int a, b;
|
||||
|
||||
void mutexinoutset_task() {
|
||||
if (b != 0) {
|
||||
fprintf(stderr, "mutexinoutset_task: b != 0 at start of task\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
b++;
|
||||
if (b != 1) {
|
||||
fprintf(stderr, "mutexinoutset_task: b != 1\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
my_sleep(0.1);
|
||||
b--;
|
||||
if (b != 0) {
|
||||
fprintf(stderr, "mutexinoutset_task: b != 0 at end of task\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
omp_depend_t dep_a_in;
|
||||
omp_depend_t dep_a_out;
|
||||
omp_depend_t dep_a_inout;
|
||||
omp_depend_t dep_a_mutexinoutset;
|
||||
|
||||
a = 0;
|
||||
b = 0;
|
||||
|
||||
#pragma omp depobj(dep_a_in) depend(in: a)
|
||||
#pragma omp depobj(dep_a_out) depend(out: a)
|
||||
#pragma omp depobj(dep_a_inout) depend(inout: a)
|
||||
#pragma omp depobj(dep_a_mutexinoutset) depend(mutexinoutset: a)
|
||||
|
||||
#pragma omp parallel
|
||||
{
|
||||
#pragma omp single
|
||||
{
|
||||
|
||||
#pragma omp task depend(depobj: dep_a_out)
|
||||
{
|
||||
my_sleep(0.1);
|
||||
a = 10;
|
||||
}
|
||||
|
||||
#pragma omp task depend(depobj: dep_a_inout)
|
||||
{
|
||||
my_sleep(0.1);
|
||||
a++;
|
||||
}
|
||||
|
||||
#pragma omp task depend(depobj: dep_a_mutexinoutset)
|
||||
mutexinoutset_task();
|
||||
#pragma omp task depend(depobj: dep_a_mutexinoutset)
|
||||
mutexinoutset_task();
|
||||
#pragma omp task depend(depobj: dep_a_mutexinoutset)
|
||||
mutexinoutset_task();
|
||||
#pragma omp task depend(depobj: dep_a_mutexinoutset)
|
||||
mutexinoutset_task();
|
||||
#pragma omp task depend(depobj: dep_a_mutexinoutset)
|
||||
mutexinoutset_task();
|
||||
|
||||
#pragma omp task depend(depobj: dep_a_in)
|
||||
{ a += 10; }
|
||||
}
|
||||
}
|
||||
|
||||
if (a != 21) {
|
||||
fprintf(stderr, "a (%d) != 21\n", a);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#pragma omp depobj(dep_a_in) destroy
|
||||
#pragma omp depobj(dep_a_out) destroy
|
||||
#pragma omp depobj(dep_a_inout) destroy
|
||||
#pragma omp depobj(dep_a_mutexinoutset) destroy
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue