diff options
Diffstat (limited to 'liboffloadmic/runtime/offload_table.cpp')
-rw-r--r-- | liboffloadmic/runtime/offload_table.cpp | 124 |
1 files changed, 123 insertions, 1 deletions
diff --git a/liboffloadmic/runtime/offload_table.cpp b/liboffloadmic/runtime/offload_table.cpp index f3c5100..09c4d20 100644 --- a/liboffloadmic/runtime/offload_table.cpp +++ b/liboffloadmic/runtime/offload_table.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 @@ -31,6 +31,16 @@ #include "offload_table.h" #include "offload_common.h" +// Offload Library versioning +// We initialize version to OFFLOAD_VERSION_16 +// 15.0 application downgrades this to 1500 for MYO to use the older version. +// 15.0 pragma works without needing version-specific code. +// 16.0-U2 added a call from ofldbegin.cpp to set the version explicitly. +// Pre-16.0-U2 application will find pre-initialized version number as 1600. +// Post 16.0-U2 application will set its own version explicitly. +int offload_version = OFFLOAD_VERSION_16; +int offload_version_count = 0; + #if !HOST_LIBRARY // Predefined offload entries extern void omp_set_num_threads_lrb(void*); @@ -55,6 +65,12 @@ extern void omp_set_nest_lock_lrb(void*); extern void omp_unset_nest_lock_lrb(void*); extern void omp_test_nest_lock_lrb(void*); +// OpenMP 4.5 APIs +extern void omp_target_alloc_target(void*); +extern void omp_target_free_target(void*); +extern void omp_target_memcpy_target(void*); +extern void omp_target_memcpy_rect_target(void*); + // Predefined entries on the target side static FuncTable::Entry predefined_entries[] = { "omp_set_num_threads_target", @@ -98,6 +114,15 @@ static FuncTable::Entry predefined_entries[] = { "omp_test_nest_lock_target", (void*) &omp_test_nest_lock_lrb, + "omp_target_alloc_target", + (void*) &omp_target_alloc_target, + "omp_target_free_target", + (void*) &omp_target_free_target, + "omp_target_memcpy_target", + (void*) &omp_target_memcpy_target, + "omp_target_memcpy_rect_target", + (void*) &omp_target_memcpy_rect_target, + (const char*) -1, (void*) -1 }; @@ -113,6 +138,28 @@ FuncList __offload_entries(&predefined_table); FuncList __offload_entries; #endif // !HOST_LIBRARY +extern "C" { + +// Set library version +void __offload_set_version(int v) +{ + offload_version_count++; + if (offload_version_count == 1) + { + offload_version = v; + } + else + { + // Mix of versions is not supported + if (v != offload_version) + { + LIBOFFLOAD_ERROR(c_mixed_versions); + exit(1); + } + } +} + +} // extern "C" // Function table. No predefined entries. FuncList __offload_funcs; @@ -296,6 +343,62 @@ void VarList::table_patch_names(void *buf, int64_t nelems) } } +#if HOST_LIBRARY +// 16.0 and earlier compilers used the following VarTable +struct OldVarTable { + const char* name; + void* addr; + // uint64_t var_alloc_type missing in 16.0 and earlier + uint64_t size; +}; + +static void convert_OldVarTable_to_NewVarTable(VarList::Node *vt_start) +{ + int table_size = 0; + char * new_var_table; + OldVarTable *old_var_table; + + OFFLOAD_DEBUG_TRACE(2, + "Converting old var table to new var table to support backward compatiblity\n"); + + // Calculate size of memory to be malloced + old_var_table = (OldVarTable *) vt_start->table.entries; + while (old_var_table->name != (const char*) -1) { + table_size++; + old_var_table++; + } + + if (table_size != 0) { + // Add 1 to table_size for end of table signature + VarTable::Entry *new_var_table = + new VarTable::Entry[table_size+1]; + + if (new_var_table == NULL) + LIBOFFLOAD_ERROR(c_malloc); + + old_var_table = (OldVarTable *) vt_start->table.entries; + + // Update VarList with new table + vt_start->table.entries = new_var_table; + + // Fix up the new table value from old table + for (int i=0; i< table_size; i++) { + new_var_table->name = old_var_table->name; + new_var_table->addr = old_var_table->addr; + new_var_table->size = old_var_table->size; + // Assign value of 0 for the missing field. + // Implying it is neither IMPLICIT or LINK variable as + // they were not supported in earlier compilers + new_var_table->var_alloc_type = 0; + old_var_table++; + new_var_table++; + } + new_var_table->name = (const char *)-1; + } + +} +#endif //HOST_LIBRARY + // Adds given list element to the global lookup table list extern "C" void __offload_register_tables( FuncList::Node *entry_table, @@ -311,6 +414,17 @@ extern "C" void __offload_register_tables( __offload_funcs.add_table(func_table); OFFLOAD_DEBUG_TRACE(2, "Registering var table %p\n", var_table); + + // Compiler earlier than 17.0 used a different var_table. + // Convert the old table to new var_table format. + // Only the host table for LINUX has changed. +#ifndef TARGET_WINNT +#if HOST_LIBRARY + if (offload_version < OFFLOAD_VERSION_17) { + convert_OldVarTable_to_NewVarTable(var_table); + } +#endif +#endif __offload_vars.add_table(var_table); } @@ -329,6 +443,14 @@ extern "C" void __offload_unregister_tables( __offload_funcs.remove_table(func_table); OFFLOAD_DEBUG_TRACE(2, "Unregistering var table %p\n", var_table); +#ifndef TARGET_WINNT +#if HOST_LIBRARY + if (offload_version < OFFLOAD_VERSION_17) { + // Free the malloced var_table created for backward compatiblity + delete var_table->table.entries; + } +#endif +#endif __offload_vars.remove_table(var_table); } |