[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