[Openmp-commits] [openmp] 5439db0 - [OpenMP] Add omp_realloc implementation
Nawrin Sultana via Openmp-commits
openmp-commits at lists.llvm.org
Tue Nov 17 11:48:03 PST 2020
Author: Nawrin Sultana
Date: 2020-11-17T13:43:00-06:00
New Revision: 5439db05e74044a239c0fd37f8594b6b67dd3c02
URL: https://github.com/llvm/llvm-project/commit/5439db05e74044a239c0fd37f8594b6b67dd3c02
DIFF: https://github.com/llvm/llvm-project/commit/5439db05e74044a239c0fd37f8594b6b67dd3c02.diff
LOG: [OpenMP] Add omp_realloc implementation
This patch adds omp_realloc function implementation according to
OpenMP 5.1 specification.
Differential Revision: https://reviews.llvm.org/D90971
Added:
openmp/runtime/test/api/omp_realloc_def_fb.c
openmp/runtime/test/api/omp_realloc_null_ptr.c
openmp/runtime/test/api/omp_realloc_size_0.c
Modified:
openmp/runtime/src/dllexports
openmp/runtime/src/include/omp.h.var
openmp/runtime/src/kmp.h
openmp/runtime/src/kmp_alloc.cpp
openmp/runtime/src/kmp_csupport.cpp
openmp/runtime/src/kmp_stub.cpp
openmp/runtime/test/api/omp_calloc_def_fb.c
openmp/runtime/test/api/omp_calloc_size_0.c
openmp/runtime/tools/generate-def.pl
Removed:
################################################################################
diff --git a/openmp/runtime/src/dllexports b/openmp/runtime/src/dllexports
index 5f7447d5341d..da5a0c6e04d2 100644
--- a/openmp/runtime/src/dllexports
+++ b/openmp/runtime/src/dllexports
@@ -518,6 +518,7 @@ kmp_set_disp_num_buffers 890
__kmpc_get_default_allocator
__kmpc_alloc
__kmpc_calloc
+ __kmpc_realloc
__kmpc_free
__kmpc_init_allocator
__kmpc_destroy_allocator
@@ -536,6 +537,7 @@ kmp_set_disp_num_buffers 890
omp_fulfill_event 759
omp_display_env 733
omp_calloc 776
+ omp_realloc 777
omp_null_allocator DATA
omp_default_mem_alloc DATA
diff --git a/openmp/runtime/src/include/omp.h.var b/openmp/runtime/src/include/omp.h.var
index 440756deea52..510bfc225f89 100644
--- a/openmp/runtime/src/include/omp.h.var
+++ b/openmp/runtime/src/include/omp.h.var
@@ -324,10 +324,15 @@
# ifdef __cplusplus
extern void *__KAI_KMPC_CONVENTION omp_alloc(size_t size, omp_allocator_handle_t a = omp_null_allocator);
extern void *__KAI_KMPC_CONVENTION omp_calloc(size_t nmemb, size_t size, omp_allocator_handle_t a = omp_null_allocator);
+ extern void *__KAI_KMPC_CONVENTION omp_realloc(void *ptr, size_t size,
+ omp_allocator_handle_t allocator = omp_null_allocator,
+ omp_allocator_handle_t free_allocator = omp_null_allocator);
extern void __KAI_KMPC_CONVENTION omp_free(void * ptr, omp_allocator_handle_t a = omp_null_allocator);
# else
extern void *__KAI_KMPC_CONVENTION omp_alloc(size_t size, omp_allocator_handle_t a);
extern void *__KAI_KMPC_CONVENTION omp_calloc(size_t nmemb, size_t size, omp_allocator_handle_t a);
+ extern void *__KAI_KMPC_CONVENTION omp_realloc(void *ptr, size_t size, omp_allocator_handle_t allocator,
+ omp_allocator_handle_t free_allocator);
extern void __KAI_KMPC_CONVENTION omp_free(void *ptr, omp_allocator_handle_t a);
# endif
diff --git a/openmp/runtime/src/kmp.h b/openmp/runtime/src/kmp.h
index 5f8e6c62d209..3acee73dde4b 100644
--- a/openmp/runtime/src/kmp.h
+++ b/openmp/runtime/src/kmp.h
@@ -965,6 +965,9 @@ extern omp_allocator_handle_t __kmpc_get_default_allocator(int gtid);
extern void *__kmpc_alloc(int gtid, size_t sz, omp_allocator_handle_t al);
extern void *__kmpc_calloc(int gtid, size_t nmemb, size_t sz,
omp_allocator_handle_t al);
+extern void *__kmpc_realloc(int gtid, void *ptr, size_t sz,
+ omp_allocator_handle_t al,
+ omp_allocator_handle_t free_al);
extern void __kmpc_free(int gtid, void *ptr, omp_allocator_handle_t al);
extern void __kmp_init_memkind();
diff --git a/openmp/runtime/src/kmp_alloc.cpp b/openmp/runtime/src/kmp_alloc.cpp
index a7278674f5cf..ad5ee4d43ee6 100644
--- a/openmp/runtime/src/kmp_alloc.cpp
+++ b/openmp/runtime/src/kmp_alloc.cpp
@@ -1436,6 +1436,7 @@ omp_allocator_handle_t __kmpc_get_default_allocator(int gtid) {
typedef struct kmp_mem_desc { // Memory block descriptor
void *ptr_alloc; // Pointer returned by allocator
size_t size_a; // Size of allocated memory block (initial+descriptor+align)
+ size_t size_orig; // Original size requested
void *ptr_align; // Pointer to aligned memory, returned
kmp_allocator_t *allocator; // allocator
} kmp_mem_desc_t;
@@ -1464,6 +1465,7 @@ void *__kmpc_alloc(int gtid, size_t size, omp_allocator_handle_t allocator) {
if (allocator > kmp_max_mem_alloc && al->alignment > 0) {
align = al->alignment; // alignment requested by user
}
+ desc.size_orig = size;
desc.size_a = size + sz_desc + align;
if (__kmp_memkind_available) {
@@ -1612,6 +1614,47 @@ void *__kmpc_calloc(int gtid, size_t nmemb, size_t size,
return ptr;
}
+void *__kmpc_realloc(int gtid, void *ptr, size_t size,
+ omp_allocator_handle_t allocator,
+ omp_allocator_handle_t free_allocator) {
+ void *nptr = NULL;
+ KMP_DEBUG_ASSERT(__kmp_init_serial);
+
+ if (size == 0) {
+ if (ptr != NULL)
+ __kmpc_free(gtid, ptr, free_allocator);
+ return nptr;
+ }
+
+ KE_TRACE(25, ("__kmpc_realloc: T#%d (%p, %d, %p, %p)\n", gtid, ptr, (int)size,
+ allocator, free_allocator));
+
+ nptr = __kmpc_alloc(gtid, size, allocator);
+
+ if (nptr != NULL && ptr != NULL) {
+ kmp_mem_desc_t desc;
+ kmp_uintptr_t addr_align; // address to return to caller
+ kmp_uintptr_t addr_descr; // address of memory block descriptor
+
+ addr_align = (kmp_uintptr_t)ptr;
+ addr_descr = addr_align - sizeof(kmp_mem_desc_t);
+ desc = *((kmp_mem_desc_t *)addr_descr); // read descriptor
+
+ KMP_DEBUG_ASSERT(desc.ptr_align == ptr);
+ KMP_DEBUG_ASSERT(desc.size_orig > 0);
+ KMP_DEBUG_ASSERT(desc.size_orig < desc.size_a);
+ KMP_MEMCPY((char *)nptr, (char *)ptr,
+ (size_t)((size < desc.size_orig) ? size : desc.size_orig));
+ }
+
+ if (nptr != NULL) {
+ __kmpc_free(gtid, ptr, free_allocator);
+ }
+
+ KE_TRACE(25, ("__kmpc_realloc returns %p, T#%d\n", nptr, gtid));
+ return nptr;
+}
+
void __kmpc_free(int gtid, void *ptr, const omp_allocator_handle_t allocator) {
KE_TRACE(25, ("__kmpc_free: T#%d free(%p,%p)\n", gtid, ptr, allocator));
if (ptr == NULL)
diff --git a/openmp/runtime/src/kmp_csupport.cpp b/openmp/runtime/src/kmp_csupport.cpp
index ead7855b567d..119386c49843 100644
--- a/openmp/runtime/src/kmp_csupport.cpp
+++ b/openmp/runtime/src/kmp_csupport.cpp
@@ -4213,6 +4213,12 @@ void *omp_calloc(size_t nmemb, size_t size, omp_allocator_handle_t allocator) {
return __kmpc_calloc(__kmp_entry_gtid(), nmemb, size, allocator);
}
+void *omp_realloc(void *ptr, size_t size, omp_allocator_handle_t allocator,
+ omp_allocator_handle_t free_allocator) {
+ return __kmpc_realloc(__kmp_entry_gtid(), ptr, size, allocator,
+ free_allocator);
+}
+
void omp_free(void *ptr, omp_allocator_handle_t allocator) {
__kmpc_free(__kmp_entry_gtid(), ptr, allocator);
}
diff --git a/openmp/runtime/src/kmp_stub.cpp b/openmp/runtime/src/kmp_stub.cpp
index 058c7b488883..ac96e4a01dc2 100644
--- a/openmp/runtime/src/kmp_stub.cpp
+++ b/openmp/runtime/src/kmp_stub.cpp
@@ -371,6 +371,12 @@ void *omp_calloc(size_t nmemb, size_t size,
i;
return calloc(nmemb, size);
}
+void *omp_realloc(void *ptr, size_t size,
+ const omp_allocator_handle_t allocator,
+ const omp_allocator_handle_t free_allocator) {
+ i;
+ return realloc(ptr, size);
+}
void omp_free(void *ptr, const omp_allocator_handle_t allocator) {
i;
free(ptr);
diff --git a/openmp/runtime/test/api/omp_calloc_def_fb.c b/openmp/runtime/test/api/omp_calloc_def_fb.c
index 9d7427827ec7..e9b90fbeb603 100644
--- a/openmp/runtime/test/api/omp_calloc_def_fb.c
+++ b/openmp/runtime/test/api/omp_calloc_def_fb.c
@@ -12,7 +12,7 @@ int main() {
at[1].key = omp_atk_fallback;
at[1].value = omp_atv_default_mem_fb;
a = omp_init_allocator(omp_large_cap_mem_space, 2, at);
- printf("allocator large created: %p\n", a);
+ printf("allocator large created: %p\n", (void *)a);
#pragma omp parallel num_threads(2)
{
int i = omp_get_thread_num();
diff --git a/openmp/runtime/test/api/omp_calloc_size_0.c b/openmp/runtime/test/api/omp_calloc_size_0.c
index 6d329ce1f7a7..0902ca600ad7 100644
--- a/openmp/runtime/test/api/omp_calloc_size_0.c
+++ b/openmp/runtime/test/api/omp_calloc_size_0.c
@@ -13,7 +13,7 @@ int main()
at[1].key = omp_atk_fallback;
at[1].value = omp_atv_default_mem_fb;
a = omp_init_allocator(omp_large_cap_mem_space, 2, at);
- printf("allocator large created: %p\n", a);
+ printf("allocator large created: %p\n", (void *)a);
#pragma omp parallel num_threads(2)
{
int i = omp_get_thread_num();
diff --git a/openmp/runtime/test/api/omp_realloc_def_fb.c b/openmp/runtime/test/api/omp_realloc_def_fb.c
new file mode 100644
index 000000000000..667172cb6f4f
--- /dev/null
+++ b/openmp/runtime/test/api/omp_realloc_def_fb.c
@@ -0,0 +1,40 @@
+// RUN: %libomp-compile-and-run
+
+#include <stdio.h>
+#include <omp.h>
+
+int main() {
+ omp_alloctrait_t at[2];
+ omp_allocator_handle_t a;
+ omp_allocator_handle_t f_a;
+ void *ptr[2];
+ void *nptr[2];
+ at[0].key = omp_atk_pool_size;
+ at[0].value = 2 * 1024 * 1024;
+ at[1].key = omp_atk_fallback;
+ at[1].value = omp_atv_default_mem_fb;
+
+ a = omp_init_allocator(omp_large_cap_mem_space, 2, at);
+ f_a = omp_init_allocator(omp_default_mem_space, 2, at);
+ printf("allocator large created: %p\n", (void *)a);
+ printf("allocator default created: %p\n", (void *)f_a);
+
+ #pragma omp parallel num_threads(2)
+ {
+ int i = omp_get_thread_num();
+ ptr[i] = omp_alloc(1024 * 1024, f_a);
+ #pragma omp barrier
+ nptr[i] = omp_realloc(ptr[i], 1024 * 1024, a, f_a);
+ #pragma omp barrier
+ printf("th %d, nptr %p\n", i, nptr[i]);
+ omp_free(nptr[i], a);
+ }
+ // Both pointers should be non-NULL
+ if (nptr[0] != NULL && nptr[1] != NULL) {
+ printf("passed\n");
+ return 0;
+ } else {
+ printf("failed: pointers %p %p\n", nptr[0], nptr[1]);
+ return 1;
+ }
+}
diff --git a/openmp/runtime/test/api/omp_realloc_null_ptr.c b/openmp/runtime/test/api/omp_realloc_null_ptr.c
new file mode 100644
index 000000000000..1483e122ce18
--- /dev/null
+++ b/openmp/runtime/test/api/omp_realloc_null_ptr.c
@@ -0,0 +1,46 @@
+// RUN: %libomp-compile-and-run
+
+#include <stdio.h>
+#include <omp.h>
+
+int main()
+{
+ omp_alloctrait_t at[2];
+ omp_allocator_handle_t a;
+ omp_allocator_handle_t f_a;
+ void *ptr[2];
+ void *nptr[2];
+ at[0].key = omp_atk_pool_size;
+ at[0].value = 2*1024*1024;
+ at[1].key = omp_atk_fallback;
+ at[1].value = omp_atv_default_mem_fb;
+
+ a = omp_init_allocator(omp_large_cap_mem_space, 2, at);
+ f_a = omp_init_allocator(omp_default_mem_space, 2, at);
+ printf("allocator large created: %p\n", (void *)a);
+ printf("allocator default created: %p\n", (void *)f_a);
+
+ #pragma omp parallel num_threads(2)
+ {
+ int i = omp_get_thread_num();
+ ptr[i] = omp_alloc(0, f_a);
+ #pragma omp barrier
+ nptr[i] = omp_realloc(ptr[i], 1024 * 1024, a, f_a);
+ #pragma omp barrier
+ printf("th %d, nptr %p\n", i, nptr[i]);
+ omp_free(nptr[i], a);
+ }
+
+ // Both ptr pointers should be NULL
+ if (ptr[0] != NULL || ptr[1] != NULL) {
+ printf("failed: pointers %p %p\n", ptr[0], ptr[1]);
+ return 1;
+ }
+ // Both nptr pointers should be non-NULL
+ if (nptr[0] == NULL || nptr[1] == NULL) {
+ printf("failed: pointers %p %p\n", nptr[0], nptr[1]);
+ return 1;
+ }
+ printf("passed\n");
+ return 0;
+}
diff --git a/openmp/runtime/test/api/omp_realloc_size_0.c b/openmp/runtime/test/api/omp_realloc_size_0.c
new file mode 100644
index 000000000000..bfd027532611
--- /dev/null
+++ b/openmp/runtime/test/api/omp_realloc_size_0.c
@@ -0,0 +1,46 @@
+// RUN: %libomp-compile-and-run
+
+#include <stdio.h>
+#include <omp.h>
+
+int main()
+{
+ omp_alloctrait_t at[2];
+ omp_allocator_handle_t a;
+ omp_allocator_handle_t f_a;
+ void *ptr[2];
+ void *nptr[2];
+ at[0].key = omp_atk_pool_size;
+ at[0].value = 2*1024*1024;
+ at[1].key = omp_atk_fallback;
+ at[1].value = omp_atv_default_mem_fb;
+
+ a = omp_init_allocator(omp_large_cap_mem_space, 2, at);
+ f_a = omp_init_allocator(omp_default_mem_space, 2, at);
+ printf("allocator large created: %p\n", (void *)a);
+ printf("allocator default created: %p\n", (void *)f_a);
+
+ #pragma omp parallel num_threads(2)
+ {
+ int i = omp_get_thread_num();
+ ptr[i] = omp_alloc(1024 * 1024, f_a);
+ #pragma omp barrier
+ nptr[i] = omp_realloc(ptr[i], 0, a, f_a);
+ #pragma omp barrier
+ printf("th %d, nptr %p\n", i, nptr[i]);
+ omp_free(nptr[i], a);
+ }
+
+ // Both ptr pointers should be non-NULL
+ if (ptr[0] == NULL || ptr[1] == NULL) {
+ printf("failed: pointers %p %p\n", ptr[0], ptr[1]);
+ return 1;
+ }
+ // Both nptr pointers should be NULL
+ if (nptr[0] != NULL || nptr[1] != NULL) {
+ printf("failed: pointers %p %p\n", nptr[0], nptr[1]);
+ return 1;
+ }
+ printf("passed\n");
+ return 0;
+}
diff --git a/openmp/runtime/tools/generate-def.pl b/openmp/runtime/tools/generate-def.pl
index b245387c0fc0..771d5f0ef31a 100755
--- a/openmp/runtime/tools/generate-def.pl
+++ b/openmp/runtime/tools/generate-def.pl
@@ -108,8 +108,9 @@ (\%)
foreach my $entry ( keys( %$entries ) ) {
if ( not $entries->{ $entry }->{ obsolete } ) {
my $ordinal = $entries->{ $entry }->{ ordinal };
- # omp_alloc, omp_calloc and omp_free are C/C++ only functions, skip "1000+ordinal" for them
- if ( $entry =~ m{\A[ok]mp_} and $entry ne "omp_alloc" and $entry ne "omp_calloc" and $entry ne "omp_free" ) {
+ # omp_alloc, omp_calloc, omp_realloc and omp_free are C/C++ only functions, skip "1000+ordinal" for them
+ if ( $entry =~ m{\A[ok]mp_} and $entry ne "omp_alloc" and $entry ne "omp_calloc" and
+ $entry ne "omp_realloc" and $entry ne "omp_free" ) {
if ( not defined( $ordinal ) ) {
runtime_error(
"Bad entry \"$entry\": ordinal number is not specified."
More information about the Openmp-commits
mailing list