2024-01-03 19:19:35 +08:00
|
|
|
/* Copyright (C) 2020-2024 Free Software Foundation, Inc.
|
2020-05-19 20:02:04 +08:00
|
|
|
Contributed by Jakub Jelinek <jakub@redhat.com>.
|
|
|
|
|
|
|
|
This file is part of the GNU Offloading and Multi Processing Library
|
|
|
|
(libgomp).
|
|
|
|
|
|
|
|
Libgomp is free software; you can redistribute it and/or modify it
|
|
|
|
under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 3, or (at your option)
|
|
|
|
any later version.
|
|
|
|
|
|
|
|
Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
|
|
more details.
|
|
|
|
|
|
|
|
Under Section 7 of GPL version 3, you are granted additional
|
|
|
|
permissions described in the GCC Runtime Library Exception, version
|
|
|
|
3.1, as published by the Free Software Foundation.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License and
|
|
|
|
a copy of the GCC Runtime Library Exception along with this program;
|
|
|
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
|
|
|
|
/* This file contains wrappers for the system allocation routines. Most
|
|
|
|
places in the OpenMP API do not make any provision for failure, so in
|
|
|
|
general we cannot allow memory allocation to fail. */
|
|
|
|
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#include "libgomp.h"
|
|
|
|
#include <stdlib.h>
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
#include <string.h>
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#if defined(LIBGOMP_USE_MEMKIND) || defined(LIBGOMP_USE_LIBNUMA)
|
2022-06-09 16:14:42 +08:00
|
|
|
#include <dlfcn.h>
|
|
|
|
#endif
|
2020-05-19 20:02:04 +08:00
|
|
|
|
OpenMP/Fortran: Implement omp allocators/allocate for ptr/allocatables
This commit adds -fopenmp-allocators which enables support for
'omp allocators' and 'omp allocate' that are associated with a Fortran
allocate-stmt. If such a construct is encountered, an error is shown,
unless the -fopenmp-allocators flag is present.
With -fopenmp -fopenmp-allocators, those constructs get turned into
GOMP_alloc allocations, while -fopenmp-allocators (also without -fopenmp)
ensures deallocation and reallocation (via intrinsic assignments) are
properly directed to GOMP_free/omp_realloc - while normal Fortran
allocations are processed by free/realloc.
In order to distinguish a 'malloc'ed from a 'GOMP_alloc'ed memory, the
version field of the Fortran array discriptor is (mis)used: 0 indicates
the normal Fortran allocation while 1 denotes GOMP_alloc. For scalars,
there is record keeping in libgomp: GOMP_add_alloc(ptr) will add the
pointer address to a splay_tree while GOMP_is_alloc(ptr) will return
true it was previously added but also removes it from the list.
Besides Fortran FE work, BUILT_IN_GOMP_REALLOC is no part of
omp-builtins.def and libgomp gains the mentioned two new function.
gcc/ChangeLog:
* builtin-types.def (BT_FN_PTR_PTR_SIZE_PTRMODE_PTRMODE): New.
* omp-builtins.def (BUILT_IN_GOMP_REALLOC): New.
* builtins.cc (builtin_fnspec): Handle it.
* gimple-ssa-warn-access.cc (fndecl_alloc_p,
matching_alloc_calls_p): Likewise.
* gimple.cc (nonfreeing_call_p): Likewise.
* predict.cc (expr_expected_value_1): Likewise.
* tree-ssa-ccp.cc (evaluate_stmt): Likewise.
* tree.cc (fndecl_dealloc_argno): Likewise.
gcc/fortran/ChangeLog:
* dump-parse-tree.cc (show_omp_node): Handle EXEC_OMP_ALLOCATE
and EXEC_OMP_ALLOCATORS.
* f95-lang.cc (ATTR_ALLOC_WARN_UNUSED_RESULT_SIZE_2_NOTHROW_LIST):
Add 'ECF_LEAF | ECF_MALLOC' to existing 'ECF_NOTHROW'.
(ATTR_ALLOC_WARN_UNUSED_RESULT_SIZE_2_NOTHROW_LEAF_LIST): Define.
* gfortran.h (gfc_omp_clauses): Add contained_in_target_construct.
* invoke.texi (-fopenacc, -fopenmp): Update based on C version.
(-fopenmp-simd): New, based on C version.
(-fopenmp-allocators): New.
* lang.opt (fopenmp-allocators): Add.
* openmp.cc (resolve_omp_clauses): For allocators/allocate directive,
add target and no dynamic_allocators diagnostic and more invalid
diagnostic.
* parse.cc (decode_omp_directive): Set contains_teams_construct.
* trans-array.h (gfc_array_allocate): Update prototype.
(gfc_conv_descriptor_version): New prototype.
* trans-decl.cc (gfc_init_default_dt): Fix comment.
* trans-array.cc (gfc_conv_descriptor_version): New.
(gfc_array_allocate): Support GOMP_alloc allocation.
(gfc_alloc_allocatable_for_assignment, structure_alloc_comps):
Handle GOMP_free/omp_realloc as needed.
* trans-expr.cc (gfc_conv_procedure_call): Likewise.
(alloc_scalar_allocatable_for_assignment): Likewise.
* trans-intrinsic.cc (conv_intrinsic_move_alloc): Likewise.
* trans-openmp.cc (gfc_trans_omp_allocators,
gfc_trans_omp_directive): Handle allocators/allocate directive.
(gfc_omp_call_add_alloc, gfc_omp_call_is_alloc): New.
* trans-stmt.h (gfc_trans_allocate): Update prototype.
* trans-stmt.cc (gfc_trans_allocate): Support GOMP_alloc.
* trans-types.cc (gfc_get_dtype_rank_type): Set version field.
* trans.cc (gfc_allocate_using_malloc, gfc_allocate_allocatable):
Update to handle GOMP_alloc.
(gfc_deallocate_with_status, gfc_deallocate_scalar_with_status):
Handle GOMP_free.
(trans_code): Update call.
* trans.h (gfc_allocate_allocatable, gfc_allocate_using_malloc):
Update prototype.
(gfc_omp_call_add_alloc, gfc_omp_call_is_alloc): New prototype.
* types.def (BT_FN_PTR_PTR_SIZE_PTRMODE_PTRMODE): New.
libgomp/ChangeLog:
* allocator.c (struct fort_alloc_splay_tree_key_s,
fort_alloc_splay_compare, GOMP_add_alloc, GOMP_is_alloc): New.
* libgomp.h: Define splay_tree_static for 'reverse' splay tree.
* libgomp.map (GOMP_5.1.2): New; add GOMP_add_alloc and
GOMP_is_alloc; move GOMP_target_map_indirect_ptr from ...
(GOMP_5.1.1): ... here.
* libgomp.texi (Impl. Status, Memory management): Update for
allocators/allocate directives.
* splay-tree.c: Handle splay_tree_static define to declare all
functions as static.
(splay_tree_lookup_node): New.
* splay-tree.h: Handle splay_tree_decl_only define.
(splay_tree_lookup_node): New prototype.
* target.c: Define splay_tree_static for 'reverse'.
* testsuite/libgomp.fortran/allocators-1.f90: New test.
* testsuite/libgomp.fortran/allocators-2.f90: New test.
* testsuite/libgomp.fortran/allocators-3.f90: New test.
* testsuite/libgomp.fortran/allocators-4.f90: New test.
* testsuite/libgomp.fortran/allocators-5.f90: New test.
gcc/testsuite/ChangeLog:
* gfortran.dg/gomp/allocate-14.f90: Add coarray and
not-listed tests.
* gfortran.dg/gomp/allocate-5.f90: Remove sorry dg-message.
* gfortran.dg/bind_c_array_params_2.f90: Update expected
dump for dtype '.version=0'.
* gfortran.dg/gomp/allocate-16.f90: New test.
* gfortran.dg/gomp/allocators-3.f90: New test.
* gfortran.dg/gomp/allocators-4.f90: New test.
2023-12-08 22:18:25 +08:00
|
|
|
/* Keeping track whether a Fortran scalar allocatable/pointer has been
|
|
|
|
allocated via 'omp allocators'/'omp allocate'. */
|
|
|
|
|
|
|
|
struct fort_alloc_splay_tree_key_s {
|
|
|
|
void *ptr;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct fort_alloc_splay_tree_node_s *fort_alloc_splay_tree_node;
|
|
|
|
typedef struct fort_alloc_splay_tree_s *fort_alloc_splay_tree;
|
|
|
|
typedef struct fort_alloc_splay_tree_key_s *fort_alloc_splay_tree_key;
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
fort_alloc_splay_compare (fort_alloc_splay_tree_key x, fort_alloc_splay_tree_key y)
|
|
|
|
{
|
|
|
|
if (x->ptr < y->ptr)
|
|
|
|
return -1;
|
|
|
|
if (x->ptr > y->ptr)
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#define splay_tree_prefix fort_alloc
|
|
|
|
#define splay_tree_static
|
|
|
|
#include "splay-tree.h"
|
|
|
|
|
|
|
|
#define splay_tree_prefix fort_alloc
|
|
|
|
#define splay_tree_static
|
|
|
|
#define splay_tree_c
|
|
|
|
#include "splay-tree.h"
|
|
|
|
|
|
|
|
static struct fort_alloc_splay_tree_s fort_alloc_scalars;
|
|
|
|
|
|
|
|
/* Add pointer as being alloced by GOMP_alloc. */
|
|
|
|
void
|
|
|
|
GOMP_add_alloc (void *ptr)
|
|
|
|
{
|
|
|
|
if (ptr == NULL)
|
|
|
|
return;
|
|
|
|
fort_alloc_splay_tree_node item;
|
|
|
|
item = gomp_malloc (sizeof (struct splay_tree_node_s));
|
|
|
|
item->key.ptr = ptr;
|
|
|
|
item->left = NULL;
|
|
|
|
item->right = NULL;
|
|
|
|
fort_alloc_splay_tree_insert (&fort_alloc_scalars, item);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remove pointer, either called by FREE or by REALLOC,
|
|
|
|
either of them can change the allocation status. */
|
|
|
|
bool
|
|
|
|
GOMP_is_alloc (void *ptr)
|
|
|
|
{
|
|
|
|
struct fort_alloc_splay_tree_key_s needle;
|
|
|
|
fort_alloc_splay_tree_node n;
|
|
|
|
needle.ptr = ptr;
|
|
|
|
n = fort_alloc_splay_tree_lookup_node (&fort_alloc_scalars, &needle);
|
|
|
|
if (n)
|
|
|
|
{
|
|
|
|
fort_alloc_splay_tree_remove (&fort_alloc_scalars, &n->key);
|
|
|
|
free (n);
|
|
|
|
}
|
|
|
|
return n != NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-05-19 20:02:04 +08:00
|
|
|
#define omp_max_predefined_alloc omp_thread_mem_alloc
|
2024-06-12 19:09:33 +08:00
|
|
|
#define ompx_gnu_min_predefined_alloc ompx_gnu_pinned_mem_alloc
|
|
|
|
#define ompx_gnu_max_predefined_alloc ompx_gnu_pinned_mem_alloc
|
2020-05-19 20:02:04 +08:00
|
|
|
|
OpenMP: Allocate directive for static vars, clean up
For the 'allocate' directive, remove the sorry for static variables and
just keep using normal memory, but honor the requested alignment and set
a DECL_ATTRIBUTE in case a target may want to make use of this later on.
The documentation is updated accordingly.
The C diagnostic to check for predefined allocators (req. for static vars)
failed to accept GCC's ompx_gnu_... allocator, now fixed. (Fortran was
already okay; but both now use new common #defined value for checking.)
And while Fortran common block variables are still rejected, the check
has been improved as before the sorry diagnostic did not work for
common blocks in modules.
Finally, for 'allocate' clause on the target/task/taskloop directives,
there is now a warning for omp_thread_mem_alloc (i.e. predefined allocator
with access = thread), which is undefined behavior according to the
OpenMP specification.
And, last, testing showed that var decl + static_assert sets TREE_USED
but does not produce a statement list in C, which did run into an assert
in gimplify. This special case is now also handled.
gcc/c/ChangeLog:
* c-parser.cc (c_parser_omp_allocate): Set alignment for alignof;
accept static variables and fix predef allocator check.
gcc/fortran/ChangeLog:
* openmp.cc (is_predefined_allocator): Use gomp-constants.h consts.
* trans-common.cc (translate_common): Reject OpenMP allocate directives.
* trans-decl.cc (gfc_finish_var_decl): Handle allocate directive
for static variables.
(gfc_trans_deferred_vars): Update for the latter.
gcc/ChangeLog:
* gimplify.cc (gimplify_bind_expr): Fix corner case for OpenMP
allocate directive.
(gimplify_scan_omp_clauses): Warn if omp_thread_mem_alloc is used
as allocator with the target/task/taskloop directive.
include/ChangeLog:
* gomp-constants.h (GOMP_OMP_PREDEF_ALLOC_MAX,
GOMP_OMPX_PREDEF_ALLOC_MIN, GOMP_OMPX_PREDEF_ALLOC_MAX,
GOMP_OMP_PREDEF_ALLOC_THREADS): New defines.
libgomp/ChangeLog:
* allocator.c: Add static asserts for news
GOMP_OMP{,X}_PREDEF_ALLOC_{MIN,MAX} range values.
* libgomp.texi (OpenMP Impl. Status): Allocate directive for
static vars is now supported. Refer to PR for allocate clause.
(Memory allocation): Update for static vars; minor word tweaking.
gcc/testsuite/ChangeLog:
* c-c++-common/gomp/allocate-9.c: Update for removed sorry.
* gfortran.dg/gomp/allocate-15.f90: Likewise.
* gfortran.dg/gomp/allocate-pinned-1.f90: Likewise.
* gfortran.dg/gomp/allocate-4.f90: Likewise; add dg-error for
previously missing diagnostic.
* c-c++-common/gomp/allocate-18.c: New test.
* c-c++-common/gomp/allocate-19.c: New test.
* gfortran.dg/gomp/allocate-clause.f90: New test.
* gfortran.dg/gomp/allocate-static-2.f90: New test.
* gfortran.dg/gomp/allocate-static.f90: New test.
2024-10-07 16:45:14 +08:00
|
|
|
_Static_assert (GOMP_OMP_PREDEF_ALLOC_MAX == omp_thread_mem_alloc,
|
|
|
|
"GOMP_OMP_PREDEF_ALLOC_MAX == omp_thread_mem_alloc");
|
|
|
|
_Static_assert (GOMP_OMPX_PREDEF_ALLOC_MIN == ompx_gnu_min_predefined_alloc,
|
|
|
|
"GOMP_OMP_PREDEF_ALLOC_MAX == omp_thread_mem_alloc");
|
|
|
|
_Static_assert (GOMP_OMPX_PREDEF_ALLOC_MAX == ompx_gnu_max_predefined_alloc,
|
|
|
|
"GOMP_OMP_PREDEF_ALLOC_MAX == omp_thread_mem_alloc");
|
|
|
|
_Static_assert (GOMP_OMP_PREDEF_ALLOC_THREADS == omp_thread_mem_alloc,
|
|
|
|
"GOMP_OMP_PREDEF_ALLOC_THREADS == omp_thread_mem_alloc");
|
|
|
|
|
2021-12-04 01:46:41 +08:00
|
|
|
/* These macros may be overridden in config/<target>/allocator.c.
|
2022-01-04 20:22:01 +08:00
|
|
|
The defaults (no override) are to return NULL for pinned memory requests
|
|
|
|
and pass through to the regular OS calls otherwise.
|
2021-12-04 01:46:41 +08:00
|
|
|
The following definitions (ab)use comma operators to avoid unused
|
|
|
|
variable errors. */
|
|
|
|
#ifndef MEMSPACE_ALLOC
|
2022-01-04 20:22:01 +08:00
|
|
|
#define MEMSPACE_ALLOC(MEMSPACE, SIZE, PIN) \
|
|
|
|
(PIN ? NULL : malloc (((void)(MEMSPACE), (SIZE))))
|
2021-12-04 01:46:41 +08:00
|
|
|
#endif
|
|
|
|
#ifndef MEMSPACE_CALLOC
|
2022-01-04 20:22:01 +08:00
|
|
|
#define MEMSPACE_CALLOC(MEMSPACE, SIZE, PIN) \
|
|
|
|
(PIN ? NULL : calloc (1, (((void)(MEMSPACE), (SIZE)))))
|
2021-12-04 01:46:41 +08:00
|
|
|
#endif
|
|
|
|
#ifndef MEMSPACE_REALLOC
|
2022-01-04 20:22:01 +08:00
|
|
|
#define MEMSPACE_REALLOC(MEMSPACE, ADDR, OLDSIZE, SIZE, OLDPIN, PIN) \
|
|
|
|
((PIN) || (OLDPIN) ? NULL \
|
|
|
|
: realloc (ADDR, (((void)(MEMSPACE), (void)(OLDSIZE), (SIZE)))))
|
2021-12-04 01:46:41 +08:00
|
|
|
#endif
|
|
|
|
#ifndef MEMSPACE_FREE
|
2022-01-04 20:22:01 +08:00
|
|
|
#define MEMSPACE_FREE(MEMSPACE, ADDR, SIZE, PIN) \
|
|
|
|
if (PIN) free (((void)(MEMSPACE), (void)(SIZE), (ADDR)))
|
2021-12-04 01:46:41 +08:00
|
|
|
#endif
|
2022-01-27 21:48:50 +08:00
|
|
|
#ifndef MEMSPACE_VALIDATE
|
2022-01-04 20:22:01 +08:00
|
|
|
#define MEMSPACE_VALIDATE(MEMSPACE, ACCESS, PIN) \
|
|
|
|
(PIN ? 0 : ((void)(MEMSPACE), (void)(ACCESS), 1))
|
2022-01-27 21:48:50 +08:00
|
|
|
#endif
|
2021-12-04 01:46:41 +08:00
|
|
|
|
|
|
|
/* Map the predefined allocators to the correct memory space.
|
|
|
|
The index to this table is the omp_allocator_handle_t enum value.
|
|
|
|
When the user calls omp_alloc with a predefined allocator this
|
|
|
|
table determines what memory they get. */
|
2024-06-12 19:09:33 +08:00
|
|
|
static const omp_memspace_handle_t predefined_omp_alloc_mapping[] = {
|
2021-12-04 01:46:41 +08:00
|
|
|
omp_default_mem_space, /* omp_null_allocator doesn't actually use this. */
|
|
|
|
omp_default_mem_space, /* omp_default_mem_alloc. */
|
|
|
|
omp_large_cap_mem_space, /* omp_large_cap_mem_alloc. */
|
|
|
|
omp_const_mem_space, /* omp_const_mem_alloc. */
|
|
|
|
omp_high_bw_mem_space, /* omp_high_bw_mem_alloc. */
|
|
|
|
omp_low_lat_mem_space, /* omp_low_lat_mem_alloc. */
|
|
|
|
omp_low_lat_mem_space, /* omp_cgroup_mem_alloc (implementation defined). */
|
|
|
|
omp_low_lat_mem_space, /* omp_pteam_mem_alloc (implementation defined). */
|
|
|
|
omp_low_lat_mem_space, /* omp_thread_mem_alloc (implementation defined). */
|
|
|
|
};
|
2024-06-12 19:09:33 +08:00
|
|
|
static const omp_memspace_handle_t predefined_ompx_gnu_alloc_mapping[] = {
|
|
|
|
omp_default_mem_space, /* ompx_gnu_pinned_mem_alloc. */
|
|
|
|
};
|
2021-12-04 01:46:41 +08:00
|
|
|
|
|
|
|
#define ARRAY_SIZE(A) (sizeof (A) / sizeof ((A)[0]))
|
2024-06-12 19:09:33 +08:00
|
|
|
_Static_assert (ARRAY_SIZE (predefined_omp_alloc_mapping)
|
2021-12-04 01:46:41 +08:00
|
|
|
== omp_max_predefined_alloc + 1,
|
2024-06-12 19:09:33 +08:00
|
|
|
"predefined_omp_alloc_mapping must match omp_memspace_handle_t");
|
|
|
|
_Static_assert (ARRAY_SIZE (predefined_ompx_gnu_alloc_mapping)
|
|
|
|
== (ompx_gnu_max_predefined_alloc
|
|
|
|
- ompx_gnu_min_predefined_alloc) + 1,
|
|
|
|
"predefined_ompx_gnu_alloc_mapping must match"
|
|
|
|
" omp_memspace_handle_t");
|
|
|
|
|
|
|
|
static inline bool
|
|
|
|
predefined_allocator_p (omp_allocator_handle_t allocator)
|
|
|
|
{
|
|
|
|
return allocator <= ompx_gnu_max_predefined_alloc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline omp_memspace_handle_t
|
|
|
|
predefined_alloc_mapping (omp_allocator_handle_t allocator)
|
|
|
|
{
|
|
|
|
if (allocator <= omp_max_predefined_alloc)
|
|
|
|
return predefined_omp_alloc_mapping[allocator];
|
|
|
|
else if (allocator >= ompx_gnu_min_predefined_alloc
|
|
|
|
&& allocator <= ompx_gnu_max_predefined_alloc)
|
|
|
|
{
|
|
|
|
int index = allocator - ompx_gnu_min_predefined_alloc;
|
|
|
|
return predefined_ompx_gnu_alloc_mapping[index];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
/* This should never happen. */
|
|
|
|
return omp_default_mem_space;
|
|
|
|
}
|
2021-12-04 01:46:41 +08:00
|
|
|
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
enum gomp_numa_memkind_kind
|
2022-06-09 16:14:42 +08:00
|
|
|
{
|
|
|
|
GOMP_MEMKIND_NONE = 0,
|
|
|
|
#define GOMP_MEMKIND_KINDS \
|
|
|
|
GOMP_MEMKIND_KIND (HBW_INTERLEAVE), \
|
|
|
|
GOMP_MEMKIND_KIND (HBW_PREFERRED), \
|
|
|
|
GOMP_MEMKIND_KIND (DAX_KMEM_ALL), \
|
|
|
|
GOMP_MEMKIND_KIND (DAX_KMEM), \
|
|
|
|
GOMP_MEMKIND_KIND (INTERLEAVE), \
|
|
|
|
GOMP_MEMKIND_KIND (DEFAULT)
|
|
|
|
#define GOMP_MEMKIND_KIND(kind) GOMP_MEMKIND_##kind
|
|
|
|
GOMP_MEMKIND_KINDS,
|
|
|
|
#undef GOMP_MEMKIND_KIND
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
GOMP_MEMKIND_COUNT,
|
|
|
|
GOMP_MEMKIND_LIBNUMA = GOMP_MEMKIND_COUNT
|
2022-06-09 16:14:42 +08:00
|
|
|
};
|
|
|
|
|
2020-05-19 20:02:04 +08:00
|
|
|
struct omp_allocator_data
|
|
|
|
{
|
|
|
|
omp_memspace_handle_t memspace;
|
|
|
|
omp_uintptr_t alignment;
|
|
|
|
omp_uintptr_t pool_size;
|
|
|
|
omp_uintptr_t used_pool_size;
|
|
|
|
omp_allocator_handle_t fb_data;
|
|
|
|
unsigned int sync_hint : 8;
|
|
|
|
unsigned int access : 8;
|
|
|
|
unsigned int fallback : 8;
|
|
|
|
unsigned int pinned : 1;
|
|
|
|
unsigned int partition : 7;
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#if defined(LIBGOMP_USE_MEMKIND) || defined(LIBGOMP_USE_LIBNUMA)
|
2022-06-09 16:14:42 +08:00
|
|
|
unsigned int memkind : 8;
|
|
|
|
#endif
|
2020-05-19 20:02:04 +08:00
|
|
|
#ifndef HAVE_SYNC_BUILTINS
|
|
|
|
gomp_mutex_t lock;
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
struct omp_mem_header
|
|
|
|
{
|
|
|
|
void *ptr;
|
|
|
|
size_t size;
|
|
|
|
omp_allocator_handle_t allocator;
|
|
|
|
void *pad;
|
|
|
|
};
|
|
|
|
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
struct gomp_libnuma_data
|
|
|
|
{
|
|
|
|
void *numa_handle;
|
|
|
|
void *(*numa_alloc_local) (size_t);
|
|
|
|
void *(*numa_realloc) (void *, size_t, size_t);
|
|
|
|
void (*numa_free) (void *, size_t);
|
|
|
|
};
|
|
|
|
|
2022-06-09 16:14:42 +08:00
|
|
|
struct gomp_memkind_data
|
|
|
|
{
|
|
|
|
void *memkind_handle;
|
|
|
|
void *(*memkind_malloc) (void *, size_t);
|
|
|
|
void *(*memkind_calloc) (void *, size_t, size_t);
|
|
|
|
void *(*memkind_realloc) (void *, void *, size_t);
|
|
|
|
void (*memkind_free) (void *, void *);
|
|
|
|
int (*memkind_check_available) (void *);
|
|
|
|
void **kinds[GOMP_MEMKIND_COUNT];
|
|
|
|
};
|
|
|
|
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#ifdef LIBGOMP_USE_LIBNUMA
|
|
|
|
static struct gomp_libnuma_data *libnuma_data;
|
|
|
|
static pthread_once_t libnuma_data_once = PTHREAD_ONCE_INIT;
|
|
|
|
|
|
|
|
static void
|
|
|
|
gomp_init_libnuma (void)
|
|
|
|
{
|
|
|
|
void *handle = dlopen ("libnuma.so.1", RTLD_LAZY);
|
|
|
|
struct gomp_libnuma_data *data;
|
|
|
|
|
|
|
|
data = calloc (1, sizeof (struct gomp_libnuma_data));
|
|
|
|
if (data == NULL)
|
|
|
|
{
|
|
|
|
if (handle)
|
|
|
|
dlclose (handle);
|
|
|
|
return;
|
|
|
|
}
|
2023-08-17 21:20:55 +08:00
|
|
|
if (handle)
|
|
|
|
{
|
|
|
|
int (*numa_available) (void);
|
|
|
|
numa_available
|
|
|
|
= (__typeof (numa_available)) dlsym (handle, "numa_available");
|
|
|
|
if (!numa_available || numa_available () != 0)
|
|
|
|
{
|
|
|
|
dlclose (handle);
|
|
|
|
handle = NULL;
|
|
|
|
}
|
|
|
|
}
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
if (!handle)
|
|
|
|
{
|
|
|
|
__atomic_store_n (&libnuma_data, data, MEMMODEL_RELEASE);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
data->numa_handle = handle;
|
|
|
|
data->numa_alloc_local
|
|
|
|
= (__typeof (data->numa_alloc_local)) dlsym (handle, "numa_alloc_local");
|
|
|
|
data->numa_realloc
|
|
|
|
= (__typeof (data->numa_realloc)) dlsym (handle, "numa_realloc");
|
|
|
|
data->numa_free
|
|
|
|
= (__typeof (data->numa_free)) dlsym (handle, "numa_free");
|
|
|
|
__atomic_store_n (&libnuma_data, data, MEMMODEL_RELEASE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct gomp_libnuma_data *
|
|
|
|
gomp_get_libnuma (void)
|
|
|
|
{
|
|
|
|
struct gomp_libnuma_data *data
|
|
|
|
= __atomic_load_n (&libnuma_data, MEMMODEL_ACQUIRE);
|
|
|
|
if (data)
|
|
|
|
return data;
|
|
|
|
pthread_once (&libnuma_data_once, gomp_init_libnuma);
|
|
|
|
return __atomic_load_n (&libnuma_data, MEMMODEL_ACQUIRE);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2022-06-09 16:14:42 +08:00
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
static struct gomp_memkind_data *memkind_data;
|
|
|
|
static pthread_once_t memkind_data_once = PTHREAD_ONCE_INIT;
|
|
|
|
|
|
|
|
static void
|
|
|
|
gomp_init_memkind (void)
|
|
|
|
{
|
2022-06-11 03:19:51 +08:00
|
|
|
void *handle = dlopen ("libmemkind.so.0", RTLD_LAZY);
|
2022-06-09 16:14:42 +08:00
|
|
|
struct gomp_memkind_data *data;
|
|
|
|
int i;
|
|
|
|
static const char *kinds[] = {
|
|
|
|
NULL,
|
|
|
|
#define GOMP_MEMKIND_KIND(kind) "MEMKIND_" #kind
|
|
|
|
GOMP_MEMKIND_KINDS
|
|
|
|
#undef GOMP_MEMKIND_KIND
|
|
|
|
};
|
|
|
|
|
|
|
|
data = calloc (1, sizeof (struct gomp_memkind_data));
|
|
|
|
if (data == NULL)
|
|
|
|
{
|
|
|
|
if (handle)
|
|
|
|
dlclose (handle);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!handle)
|
|
|
|
{
|
|
|
|
__atomic_store_n (&memkind_data, data, MEMMODEL_RELEASE);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
data->memkind_handle = handle;
|
|
|
|
data->memkind_malloc
|
|
|
|
= (__typeof (data->memkind_malloc)) dlsym (handle, "memkind_malloc");
|
|
|
|
data->memkind_calloc
|
|
|
|
= (__typeof (data->memkind_calloc)) dlsym (handle, "memkind_calloc");
|
|
|
|
data->memkind_realloc
|
|
|
|
= (__typeof (data->memkind_realloc)) dlsym (handle, "memkind_realloc");
|
|
|
|
data->memkind_free
|
|
|
|
= (__typeof (data->memkind_free)) dlsym (handle, "memkind_free");
|
|
|
|
data->memkind_check_available
|
|
|
|
= (__typeof (data->memkind_check_available))
|
|
|
|
dlsym (handle, "memkind_check_available");
|
|
|
|
if (data->memkind_malloc
|
|
|
|
&& data->memkind_calloc
|
|
|
|
&& data->memkind_realloc
|
|
|
|
&& data->memkind_free
|
|
|
|
&& data->memkind_check_available)
|
|
|
|
for (i = 1; i < GOMP_MEMKIND_COUNT; ++i)
|
|
|
|
{
|
|
|
|
data->kinds[i] = (void **) dlsym (handle, kinds[i]);
|
|
|
|
if (data->kinds[i] && data->memkind_check_available (*data->kinds[i]))
|
|
|
|
data->kinds[i] = NULL;
|
|
|
|
}
|
|
|
|
__atomic_store_n (&memkind_data, data, MEMMODEL_RELEASE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct gomp_memkind_data *
|
|
|
|
gomp_get_memkind (void)
|
|
|
|
{
|
|
|
|
struct gomp_memkind_data *data
|
|
|
|
= __atomic_load_n (&memkind_data, MEMMODEL_ACQUIRE);
|
|
|
|
if (data)
|
|
|
|
return data;
|
|
|
|
pthread_once (&memkind_data_once, gomp_init_memkind);
|
|
|
|
return __atomic_load_n (&memkind_data, MEMMODEL_ACQUIRE);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-05-19 20:02:04 +08:00
|
|
|
omp_allocator_handle_t
|
|
|
|
omp_init_allocator (omp_memspace_handle_t memspace, int ntraits,
|
|
|
|
const omp_alloctrait_t traits[])
|
|
|
|
{
|
|
|
|
struct omp_allocator_data data
|
|
|
|
= { memspace, 1, ~(uintptr_t) 0, 0, 0, omp_atv_contended, omp_atv_all,
|
2022-06-09 16:14:42 +08:00
|
|
|
omp_atv_default_mem_fb, omp_atv_false, omp_atv_environment,
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#if defined(LIBGOMP_USE_MEMKIND) || defined(LIBGOMP_USE_LIBNUMA)
|
2022-06-09 16:14:42 +08:00
|
|
|
GOMP_MEMKIND_NONE
|
|
|
|
#endif
|
|
|
|
};
|
2020-05-19 20:02:04 +08:00
|
|
|
struct omp_allocator_data *ret;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (memspace > omp_low_lat_mem_space)
|
|
|
|
return omp_null_allocator;
|
|
|
|
for (i = 0; i < ntraits; i++)
|
|
|
|
switch (traits[i].key)
|
|
|
|
{
|
|
|
|
case omp_atk_sync_hint:
|
|
|
|
switch (traits[i].value)
|
|
|
|
{
|
|
|
|
case omp_atv_default:
|
|
|
|
data.sync_hint = omp_atv_contended;
|
|
|
|
break;
|
|
|
|
case omp_atv_contended:
|
|
|
|
case omp_atv_uncontended:
|
2021-10-11 19:34:51 +08:00
|
|
|
case omp_atv_serialized:
|
2020-05-19 20:02:04 +08:00
|
|
|
case omp_atv_private:
|
|
|
|
data.sync_hint = traits[i].value;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return omp_null_allocator;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case omp_atk_alignment:
|
2020-07-09 17:29:30 +08:00
|
|
|
if (traits[i].value == omp_atv_default)
|
|
|
|
{
|
|
|
|
data.alignment = 1;
|
|
|
|
break;
|
|
|
|
}
|
2020-05-19 20:02:04 +08:00
|
|
|
if ((traits[i].value & (traits[i].value - 1)) != 0
|
|
|
|
|| !traits[i].value)
|
|
|
|
return omp_null_allocator;
|
|
|
|
data.alignment = traits[i].value;
|
|
|
|
break;
|
|
|
|
case omp_atk_access:
|
|
|
|
switch (traits[i].value)
|
|
|
|
{
|
|
|
|
case omp_atv_default:
|
|
|
|
data.access = omp_atv_all;
|
|
|
|
break;
|
|
|
|
case omp_atv_all:
|
|
|
|
case omp_atv_cgroup:
|
|
|
|
case omp_atv_pteam:
|
|
|
|
case omp_atv_thread:
|
|
|
|
data.access = traits[i].value;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return omp_null_allocator;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case omp_atk_pool_size:
|
2020-07-09 17:29:30 +08:00
|
|
|
if (traits[i].value == omp_atv_default)
|
|
|
|
data.pool_size = ~(uintptr_t) 0;
|
|
|
|
else
|
|
|
|
data.pool_size = traits[i].value;
|
2020-05-19 20:02:04 +08:00
|
|
|
break;
|
|
|
|
case omp_atk_fallback:
|
|
|
|
switch (traits[i].value)
|
|
|
|
{
|
|
|
|
case omp_atv_default:
|
|
|
|
data.fallback = omp_atv_default_mem_fb;
|
|
|
|
break;
|
|
|
|
case omp_atv_default_mem_fb:
|
|
|
|
case omp_atv_null_fb:
|
|
|
|
case omp_atv_abort_fb:
|
|
|
|
case omp_atv_allocator_fb:
|
|
|
|
data.fallback = traits[i].value;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return omp_null_allocator;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case omp_atk_fb_data:
|
|
|
|
data.fb_data = traits[i].value;
|
|
|
|
break;
|
|
|
|
case omp_atk_pinned:
|
|
|
|
switch (traits[i].value)
|
|
|
|
{
|
|
|
|
case omp_atv_default:
|
|
|
|
case omp_atv_false:
|
|
|
|
data.pinned = omp_atv_false;
|
|
|
|
break;
|
|
|
|
case omp_atv_true:
|
|
|
|
data.pinned = omp_atv_true;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return omp_null_allocator;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case omp_atk_partition:
|
|
|
|
switch (traits[i].value)
|
|
|
|
{
|
|
|
|
case omp_atv_default:
|
|
|
|
data.partition = omp_atv_environment;
|
|
|
|
break;
|
|
|
|
case omp_atv_environment:
|
|
|
|
case omp_atv_nearest:
|
|
|
|
case omp_atv_blocked:
|
|
|
|
case omp_atv_interleaved:
|
|
|
|
data.partition = traits[i].value;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return omp_null_allocator;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return omp_null_allocator;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data.alignment < sizeof (void *))
|
|
|
|
data.alignment = sizeof (void *);
|
|
|
|
|
2022-06-09 16:14:42 +08:00
|
|
|
switch (memspace)
|
|
|
|
{
|
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
case omp_high_bw_mem_space:
|
2022-06-09 16:14:42 +08:00
|
|
|
struct gomp_memkind_data *memkind_data;
|
|
|
|
memkind_data = gomp_get_memkind ();
|
|
|
|
if (data.partition == omp_atv_interleaved
|
|
|
|
&& memkind_data->kinds[GOMP_MEMKIND_HBW_INTERLEAVE])
|
|
|
|
{
|
|
|
|
data.memkind = GOMP_MEMKIND_HBW_INTERLEAVE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (memkind_data->kinds[GOMP_MEMKIND_HBW_PREFERRED])
|
|
|
|
{
|
|
|
|
data.memkind = GOMP_MEMKIND_HBW_PREFERRED;
|
|
|
|
break;
|
|
|
|
}
|
2023-07-11 22:11:35 +08:00
|
|
|
break;
|
2022-06-09 16:14:42 +08:00
|
|
|
case omp_large_cap_mem_space:
|
|
|
|
memkind_data = gomp_get_memkind ();
|
|
|
|
if (memkind_data->kinds[GOMP_MEMKIND_DAX_KMEM_ALL])
|
|
|
|
data.memkind = GOMP_MEMKIND_DAX_KMEM_ALL;
|
|
|
|
else if (memkind_data->kinds[GOMP_MEMKIND_DAX_KMEM])
|
|
|
|
data.memkind = GOMP_MEMKIND_DAX_KMEM;
|
|
|
|
break;
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#endif
|
2022-06-09 16:14:42 +08:00
|
|
|
default:
|
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
if (data.partition == omp_atv_interleaved)
|
|
|
|
{
|
|
|
|
memkind_data = gomp_get_memkind ();
|
|
|
|
if (memkind_data->kinds[GOMP_MEMKIND_INTERLEAVE])
|
|
|
|
data.memkind = GOMP_MEMKIND_INTERLEAVE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#ifdef LIBGOMP_USE_LIBNUMA
|
|
|
|
if (data.memkind == GOMP_MEMKIND_NONE && data.partition == omp_atv_nearest)
|
|
|
|
{
|
|
|
|
libnuma_data = gomp_get_libnuma ();
|
2023-07-14 15:14:37 +08:00
|
|
|
if (libnuma_data->numa_alloc_local != NULL)
|
|
|
|
data.memkind = GOMP_MEMKIND_LIBNUMA;
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2022-01-27 21:48:50 +08:00
|
|
|
/* Reject unsupported memory spaces. */
|
2022-01-04 20:22:01 +08:00
|
|
|
if (!MEMSPACE_VALIDATE (data.memspace, data.access, data.pinned))
|
2022-01-27 21:48:50 +08:00
|
|
|
return omp_null_allocator;
|
|
|
|
|
2020-05-19 20:02:04 +08:00
|
|
|
ret = gomp_malloc (sizeof (struct omp_allocator_data));
|
|
|
|
*ret = data;
|
|
|
|
#ifndef HAVE_SYNC_BUILTINS
|
|
|
|
gomp_mutex_init (&ret->lock);
|
|
|
|
#endif
|
|
|
|
return (omp_allocator_handle_t) ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
omp_destroy_allocator (omp_allocator_handle_t allocator)
|
|
|
|
{
|
|
|
|
if (allocator != omp_null_allocator)
|
|
|
|
{
|
|
|
|
#ifndef HAVE_SYNC_BUILTINS
|
|
|
|
gomp_mutex_destroy (&((struct omp_allocator_data *) allocator)->lock);
|
|
|
|
#endif
|
|
|
|
free ((void *) allocator);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-15 14:33:20 +08:00
|
|
|
ialias (omp_init_allocator)
|
|
|
|
ialias (omp_destroy_allocator)
|
|
|
|
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
void *
|
openmp: Implement allocate clause in omp lowering.
For now, task/taskloop constructs aren't handled and C/C++ array reductions
and reductions with task or inscan modifiers need further work.
Instead of calling omp_alloc/omp_free (where the former doesn't have
alignment argument and omp_aligned_alloc is 5.1 only feature), this calls
GOMP_alloc/GOMP_free, so that the library can fail if it would fall back
into NULL (exception is zero length allocations).
2020-11-12 Jakub Jelinek <jakub@redhat.com>
gcc/
* builtin-types.def (BT_FN_PTR_SIZE_SIZE_PTRMODE): New function type.
* omp-builtins.def (BUILT_IN_GOACC_DECLARE): Move earlier.
(BUILT_IN_GOMP_ALLOC, BUILT_IN_GOMP_FREE): New builtins.
* gimplify.c (gimplify_scan_omp_clauses): Force allocator into a
decl if it is not NULL, INTEGER_CST or decl.
(gimplify_adjust_omp_clauses): Clear GOVD_EXPLICIT on explicit clauses
which are being removed. Remove allocate clauses for variables not seen
if they are private, firstprivate or linear too. Call
omp_notice_variable on the allocator otherwise.
(gimplify_omp_for): Handle iterator vars mentioned in allocate clauses
similarly to non-is_gimple_reg iterators.
* omp-low.c (struct omp_context): Add allocate_map field.
(delete_omp_context): Delete it.
(scan_sharing_clauses): Fill it from allocate clauses. Remove it
if mentioned also in shared clause.
(lower_private_allocate): New function.
(lower_rec_input_clauses): Handle allocate clause for privatized
variables, except for task/taskloop, C/C++ array reductions for now
and task/inscan variables.
(lower_send_shared_vars): Don't consider variables in allocate_map
as shared.
* omp-expand.c (expand_omp_for_generic, expand_omp_for_static_nochunk,
expand_omp_for_static_chunk): Use expand_omp_build_assign instead of
gimple_build_assign + gsi_insert_after.
* builtins.c (builtin_fnspec): Handle BUILTIN_GOMP_ALLOC and
BUILTIN_GOMP_FREE.
* tree-ssa-ccp.c (evaluate_stmt): Handle BUILTIN_GOMP_ALLOC.
* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Handle
BUILTIN_GOMP_ALLOC.
(mark_all_reaching_defs_necessary_1): Handle BUILTIN_GOMP_ALLOC
and BUILTIN_GOMP_FREE.
(propagate_necessity): Likewise.
gcc/fortran/
* f95-lang.c (ATTR_ALLOC_WARN_UNUSED_RESULT_SIZE_2_NOTHROW_LIST):
Define.
(gfc_init_builtin_functions): Add alloc_size and warn_unused_result
attributes to __builtin_GOMP_alloc.
* types.def (BT_PTRMODE): New primitive type.
(BT_FN_VOID_PTR_PTRMODE, BT_FN_PTR_SIZE_SIZE_PTRMODE): New function
types.
libgomp/
* libgomp.map (GOMP_alloc, GOMP_free): Export at GOMP_5.0.1.
* omp.h.in (omp_alloc): Add malloc and alloc_size attributes.
* libgomp_g.h (GOMP_alloc, GOMP_free): Declare.
* allocator.c (omp_aligned_alloc): New for now static function,
add alignment argument and handle it.
(omp_alloc): Reimplement using omp_aligned_alloc.
(GOMP_alloc, GOMP_free): New functions.
(omp_free): Add ialias.
* testsuite/libgomp.c-c++-common/allocate-1.c: New test.
* testsuite/libgomp.c++/allocate-1.C: New test.
2020-11-13 04:38:04 +08:00
|
|
|
omp_aligned_alloc (size_t alignment, size_t size,
|
|
|
|
omp_allocator_handle_t allocator)
|
2020-05-19 20:02:04 +08:00
|
|
|
{
|
|
|
|
struct omp_allocator_data *allocator_data;
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
size_t new_size, new_alignment;
|
2020-05-19 20:02:04 +08:00
|
|
|
void *ptr, *ret;
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#if defined(LIBGOMP_USE_MEMKIND) || defined(LIBGOMP_USE_LIBNUMA)
|
|
|
|
enum gomp_numa_memkind_kind memkind;
|
2022-06-09 16:14:42 +08:00
|
|
|
#endif
|
2020-05-19 20:02:04 +08:00
|
|
|
|
2020-05-30 20:02:56 +08:00
|
|
|
if (__builtin_expect (size == 0, 0))
|
|
|
|
return NULL;
|
|
|
|
|
2020-05-19 20:02:04 +08:00
|
|
|
retry:
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
new_alignment = alignment;
|
2020-05-19 20:02:04 +08:00
|
|
|
if (allocator == omp_null_allocator)
|
|
|
|
{
|
|
|
|
struct gomp_thread *thr = gomp_thread ();
|
|
|
|
if (thr->ts.def_allocator == omp_null_allocator)
|
|
|
|
thr->ts.def_allocator = gomp_def_allocator;
|
|
|
|
allocator = (omp_allocator_handle_t) thr->ts.def_allocator;
|
|
|
|
}
|
|
|
|
|
2024-06-12 19:09:33 +08:00
|
|
|
if (!predefined_allocator_p (allocator))
|
2020-05-19 20:02:04 +08:00
|
|
|
{
|
|
|
|
allocator_data = (struct omp_allocator_data *) allocator;
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
if (new_alignment < allocator_data->alignment)
|
|
|
|
new_alignment = allocator_data->alignment;
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#if defined(LIBGOMP_USE_MEMKIND) || defined(LIBGOMP_USE_LIBNUMA)
|
2022-06-09 16:14:42 +08:00
|
|
|
memkind = allocator_data->memkind;
|
|
|
|
#endif
|
2020-05-19 20:02:04 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allocator_data = NULL;
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
if (new_alignment < sizeof (void *))
|
|
|
|
new_alignment = sizeof (void *);
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#if defined(LIBGOMP_USE_MEMKIND) || defined(LIBGOMP_USE_LIBNUMA)
|
2022-06-09 16:14:42 +08:00
|
|
|
memkind = GOMP_MEMKIND_NONE;
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#endif
|
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
2022-06-09 16:14:42 +08:00
|
|
|
if (allocator == omp_high_bw_mem_alloc)
|
|
|
|
memkind = GOMP_MEMKIND_HBW_PREFERRED;
|
|
|
|
else if (allocator == omp_large_cap_mem_alloc)
|
|
|
|
memkind = GOMP_MEMKIND_DAX_KMEM_ALL;
|
|
|
|
if (memkind)
|
|
|
|
{
|
|
|
|
struct gomp_memkind_data *memkind_data = gomp_get_memkind ();
|
|
|
|
if (!memkind_data->kinds[memkind])
|
|
|
|
memkind = GOMP_MEMKIND_NONE;
|
|
|
|
}
|
|
|
|
#endif
|
2020-05-19 20:02:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
new_size = sizeof (struct omp_mem_header);
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
if (new_alignment > sizeof (void *))
|
|
|
|
new_size += new_alignment - sizeof (void *);
|
2020-05-19 20:02:04 +08:00
|
|
|
if (__builtin_add_overflow (size, new_size, &new_size))
|
|
|
|
goto fail;
|
2022-01-27 21:48:50 +08:00
|
|
|
#ifdef OMP_LOW_LAT_MEM_ALLOC_INVALID
|
|
|
|
if (allocator == omp_low_lat_mem_alloc)
|
|
|
|
goto fail;
|
|
|
|
#endif
|
2020-05-19 20:02:04 +08:00
|
|
|
|
|
|
|
if (__builtin_expect (allocator_data
|
|
|
|
&& allocator_data->pool_size < ~(uintptr_t) 0, 0))
|
|
|
|
{
|
|
|
|
uintptr_t used_pool_size;
|
|
|
|
if (new_size > allocator_data->pool_size)
|
|
|
|
goto fail;
|
|
|
|
#ifdef HAVE_SYNC_BUILTINS
|
|
|
|
used_pool_size = __atomic_load_n (&allocator_data->used_pool_size,
|
|
|
|
MEMMODEL_RELAXED);
|
|
|
|
do
|
|
|
|
{
|
|
|
|
uintptr_t new_pool_size;
|
|
|
|
if (__builtin_add_overflow (used_pool_size, new_size,
|
|
|
|
&new_pool_size)
|
|
|
|
|| new_pool_size > allocator_data->pool_size)
|
|
|
|
goto fail;
|
|
|
|
if (__atomic_compare_exchange_n (&allocator_data->used_pool_size,
|
|
|
|
&used_pool_size, new_pool_size,
|
|
|
|
true, MEMMODEL_RELAXED,
|
|
|
|
MEMMODEL_RELAXED))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
while (1);
|
|
|
|
#else
|
|
|
|
gomp_mutex_lock (&allocator_data->lock);
|
|
|
|
if (__builtin_add_overflow (allocator_data->used_pool_size, new_size,
|
|
|
|
&used_pool_size)
|
|
|
|
|| used_pool_size > allocator_data->pool_size)
|
|
|
|
{
|
|
|
|
gomp_mutex_unlock (&allocator_data->lock);
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
allocator_data->used_pool_size = used_pool_size;
|
|
|
|
gomp_mutex_unlock (&allocator_data->lock);
|
|
|
|
#endif
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#ifdef LIBGOMP_USE_LIBNUMA
|
|
|
|
if (memkind == GOMP_MEMKIND_LIBNUMA)
|
|
|
|
ptr = libnuma_data->numa_alloc_local (new_size);
|
|
|
|
# ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
else
|
|
|
|
# endif
|
|
|
|
#endif
|
2022-06-09 16:14:42 +08:00
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
if (memkind)
|
|
|
|
{
|
|
|
|
struct gomp_memkind_data *memkind_data = gomp_get_memkind ();
|
|
|
|
void *kind = *memkind_data->kinds[memkind];
|
|
|
|
ptr = memkind_data->memkind_malloc (kind, new_size);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
2022-01-04 20:22:01 +08:00
|
|
|
ptr = MEMSPACE_ALLOC (allocator_data->memspace, new_size,
|
|
|
|
allocator_data->pinned);
|
2020-05-19 20:02:04 +08:00
|
|
|
if (ptr == NULL)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_SYNC_BUILTINS
|
|
|
|
__atomic_add_fetch (&allocator_data->used_pool_size, -new_size,
|
|
|
|
MEMMODEL_RELAXED);
|
|
|
|
#else
|
|
|
|
gomp_mutex_lock (&allocator_data->lock);
|
|
|
|
allocator_data->used_pool_size -= new_size;
|
|
|
|
gomp_mutex_unlock (&allocator_data->lock);
|
|
|
|
#endif
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#ifdef LIBGOMP_USE_LIBNUMA
|
|
|
|
if (memkind == GOMP_MEMKIND_LIBNUMA)
|
|
|
|
ptr = libnuma_data->numa_alloc_local (new_size);
|
|
|
|
# ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
else
|
|
|
|
# endif
|
|
|
|
#endif
|
2022-06-09 16:14:42 +08:00
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
if (memkind)
|
|
|
|
{
|
|
|
|
struct gomp_memkind_data *memkind_data = gomp_get_memkind ();
|
|
|
|
void *kind = *memkind_data->kinds[memkind];
|
|
|
|
ptr = memkind_data->memkind_malloc (kind, new_size);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
2021-12-04 01:46:41 +08:00
|
|
|
{
|
|
|
|
omp_memspace_handle_t memspace;
|
|
|
|
memspace = (allocator_data
|
|
|
|
? allocator_data->memspace
|
2024-06-12 19:09:33 +08:00
|
|
|
: predefined_alloc_mapping (allocator));
|
|
|
|
int pinned = (allocator_data
|
|
|
|
? allocator_data->pinned
|
|
|
|
: allocator == ompx_gnu_pinned_mem_alloc);
|
|
|
|
ptr = MEMSPACE_ALLOC (memspace, new_size, pinned);
|
2021-12-04 01:46:41 +08:00
|
|
|
}
|
2020-05-19 20:02:04 +08:00
|
|
|
if (ptr == NULL)
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
if (new_alignment > sizeof (void *))
|
2020-05-19 20:02:04 +08:00
|
|
|
ret = (void *) (((uintptr_t) ptr
|
|
|
|
+ sizeof (struct omp_mem_header)
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
+ new_alignment - sizeof (void *))
|
|
|
|
& ~(new_alignment - 1));
|
2020-05-19 20:02:04 +08:00
|
|
|
else
|
|
|
|
ret = (char *) ptr + sizeof (struct omp_mem_header);
|
|
|
|
((struct omp_mem_header *) ret)[-1].ptr = ptr;
|
|
|
|
((struct omp_mem_header *) ret)[-1].size = new_size;
|
|
|
|
((struct omp_mem_header *) ret)[-1].allocator = allocator;
|
|
|
|
return ret;
|
|
|
|
|
2021-12-04 01:46:41 +08:00
|
|
|
fail:;
|
|
|
|
int fallback = (allocator_data
|
|
|
|
? allocator_data->fallback
|
2024-06-12 19:09:33 +08:00
|
|
|
: (allocator == omp_default_mem_alloc
|
|
|
|
|| allocator == ompx_gnu_pinned_mem_alloc)
|
2021-12-04 01:46:41 +08:00
|
|
|
? omp_atv_null_fb
|
|
|
|
: omp_atv_default_mem_fb);
|
|
|
|
switch (fallback)
|
2020-05-19 20:02:04 +08:00
|
|
|
{
|
2021-12-04 01:46:41 +08:00
|
|
|
case omp_atv_default_mem_fb:
|
|
|
|
allocator = omp_default_mem_alloc;
|
|
|
|
goto retry;
|
|
|
|
case omp_atv_null_fb:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
case omp_atv_abort_fb:
|
|
|
|
gomp_fatal ("Out of memory allocating %lu bytes",
|
|
|
|
(unsigned long) size);
|
|
|
|
case omp_atv_allocator_fb:
|
|
|
|
allocator = allocator_data->fb_data;
|
|
|
|
goto retry;
|
2020-05-19 20:02:04 +08:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
ialias (omp_aligned_alloc)
|
|
|
|
|
openmp: Implement allocate clause in omp lowering.
For now, task/taskloop constructs aren't handled and C/C++ array reductions
and reductions with task or inscan modifiers need further work.
Instead of calling omp_alloc/omp_free (where the former doesn't have
alignment argument and omp_aligned_alloc is 5.1 only feature), this calls
GOMP_alloc/GOMP_free, so that the library can fail if it would fall back
into NULL (exception is zero length allocations).
2020-11-12 Jakub Jelinek <jakub@redhat.com>
gcc/
* builtin-types.def (BT_FN_PTR_SIZE_SIZE_PTRMODE): New function type.
* omp-builtins.def (BUILT_IN_GOACC_DECLARE): Move earlier.
(BUILT_IN_GOMP_ALLOC, BUILT_IN_GOMP_FREE): New builtins.
* gimplify.c (gimplify_scan_omp_clauses): Force allocator into a
decl if it is not NULL, INTEGER_CST or decl.
(gimplify_adjust_omp_clauses): Clear GOVD_EXPLICIT on explicit clauses
which are being removed. Remove allocate clauses for variables not seen
if they are private, firstprivate or linear too. Call
omp_notice_variable on the allocator otherwise.
(gimplify_omp_for): Handle iterator vars mentioned in allocate clauses
similarly to non-is_gimple_reg iterators.
* omp-low.c (struct omp_context): Add allocate_map field.
(delete_omp_context): Delete it.
(scan_sharing_clauses): Fill it from allocate clauses. Remove it
if mentioned also in shared clause.
(lower_private_allocate): New function.
(lower_rec_input_clauses): Handle allocate clause for privatized
variables, except for task/taskloop, C/C++ array reductions for now
and task/inscan variables.
(lower_send_shared_vars): Don't consider variables in allocate_map
as shared.
* omp-expand.c (expand_omp_for_generic, expand_omp_for_static_nochunk,
expand_omp_for_static_chunk): Use expand_omp_build_assign instead of
gimple_build_assign + gsi_insert_after.
* builtins.c (builtin_fnspec): Handle BUILTIN_GOMP_ALLOC and
BUILTIN_GOMP_FREE.
* tree-ssa-ccp.c (evaluate_stmt): Handle BUILTIN_GOMP_ALLOC.
* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Handle
BUILTIN_GOMP_ALLOC.
(mark_all_reaching_defs_necessary_1): Handle BUILTIN_GOMP_ALLOC
and BUILTIN_GOMP_FREE.
(propagate_necessity): Likewise.
gcc/fortran/
* f95-lang.c (ATTR_ALLOC_WARN_UNUSED_RESULT_SIZE_2_NOTHROW_LIST):
Define.
(gfc_init_builtin_functions): Add alloc_size and warn_unused_result
attributes to __builtin_GOMP_alloc.
* types.def (BT_PTRMODE): New primitive type.
(BT_FN_VOID_PTR_PTRMODE, BT_FN_PTR_SIZE_SIZE_PTRMODE): New function
types.
libgomp/
* libgomp.map (GOMP_alloc, GOMP_free): Export at GOMP_5.0.1.
* omp.h.in (omp_alloc): Add malloc and alloc_size attributes.
* libgomp_g.h (GOMP_alloc, GOMP_free): Declare.
* allocator.c (omp_aligned_alloc): New for now static function,
add alignment argument and handle it.
(omp_alloc): Reimplement using omp_aligned_alloc.
(GOMP_alloc, GOMP_free): New functions.
(omp_free): Add ialias.
* testsuite/libgomp.c-c++-common/allocate-1.c: New test.
* testsuite/libgomp.c++/allocate-1.C: New test.
2020-11-13 04:38:04 +08:00
|
|
|
void *
|
|
|
|
omp_alloc (size_t size, omp_allocator_handle_t allocator)
|
|
|
|
{
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
return ialias_call (omp_aligned_alloc) (1, size, allocator);
|
openmp: Implement allocate clause in omp lowering.
For now, task/taskloop constructs aren't handled and C/C++ array reductions
and reductions with task or inscan modifiers need further work.
Instead of calling omp_alloc/omp_free (where the former doesn't have
alignment argument and omp_aligned_alloc is 5.1 only feature), this calls
GOMP_alloc/GOMP_free, so that the library can fail if it would fall back
into NULL (exception is zero length allocations).
2020-11-12 Jakub Jelinek <jakub@redhat.com>
gcc/
* builtin-types.def (BT_FN_PTR_SIZE_SIZE_PTRMODE): New function type.
* omp-builtins.def (BUILT_IN_GOACC_DECLARE): Move earlier.
(BUILT_IN_GOMP_ALLOC, BUILT_IN_GOMP_FREE): New builtins.
* gimplify.c (gimplify_scan_omp_clauses): Force allocator into a
decl if it is not NULL, INTEGER_CST or decl.
(gimplify_adjust_omp_clauses): Clear GOVD_EXPLICIT on explicit clauses
which are being removed. Remove allocate clauses for variables not seen
if they are private, firstprivate or linear too. Call
omp_notice_variable on the allocator otherwise.
(gimplify_omp_for): Handle iterator vars mentioned in allocate clauses
similarly to non-is_gimple_reg iterators.
* omp-low.c (struct omp_context): Add allocate_map field.
(delete_omp_context): Delete it.
(scan_sharing_clauses): Fill it from allocate clauses. Remove it
if mentioned also in shared clause.
(lower_private_allocate): New function.
(lower_rec_input_clauses): Handle allocate clause for privatized
variables, except for task/taskloop, C/C++ array reductions for now
and task/inscan variables.
(lower_send_shared_vars): Don't consider variables in allocate_map
as shared.
* omp-expand.c (expand_omp_for_generic, expand_omp_for_static_nochunk,
expand_omp_for_static_chunk): Use expand_omp_build_assign instead of
gimple_build_assign + gsi_insert_after.
* builtins.c (builtin_fnspec): Handle BUILTIN_GOMP_ALLOC and
BUILTIN_GOMP_FREE.
* tree-ssa-ccp.c (evaluate_stmt): Handle BUILTIN_GOMP_ALLOC.
* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Handle
BUILTIN_GOMP_ALLOC.
(mark_all_reaching_defs_necessary_1): Handle BUILTIN_GOMP_ALLOC
and BUILTIN_GOMP_FREE.
(propagate_necessity): Likewise.
gcc/fortran/
* f95-lang.c (ATTR_ALLOC_WARN_UNUSED_RESULT_SIZE_2_NOTHROW_LIST):
Define.
(gfc_init_builtin_functions): Add alloc_size and warn_unused_result
attributes to __builtin_GOMP_alloc.
* types.def (BT_PTRMODE): New primitive type.
(BT_FN_VOID_PTR_PTRMODE, BT_FN_PTR_SIZE_SIZE_PTRMODE): New function
types.
libgomp/
* libgomp.map (GOMP_alloc, GOMP_free): Export at GOMP_5.0.1.
* omp.h.in (omp_alloc): Add malloc and alloc_size attributes.
* libgomp_g.h (GOMP_alloc, GOMP_free): Declare.
* allocator.c (omp_aligned_alloc): New for now static function,
add alignment argument and handle it.
(omp_alloc): Reimplement using omp_aligned_alloc.
(GOMP_alloc, GOMP_free): New functions.
(omp_free): Add ialias.
* testsuite/libgomp.c-c++-common/allocate-1.c: New test.
* testsuite/libgomp.c++/allocate-1.C: New test.
2020-11-13 04:38:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Like omp_aligned_alloc, but apply on top of that:
|
|
|
|
"For allocations that arise from this ... the null_fb value of the
|
|
|
|
fallback allocator trait behaves as if the abort_fb had been specified." */
|
|
|
|
|
|
|
|
void *
|
|
|
|
GOMP_alloc (size_t alignment, size_t size, uintptr_t allocator)
|
|
|
|
{
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
void *ret
|
|
|
|
= ialias_call (omp_aligned_alloc) (alignment, size,
|
|
|
|
(omp_allocator_handle_t) allocator);
|
openmp: Implement allocate clause in omp lowering.
For now, task/taskloop constructs aren't handled and C/C++ array reductions
and reductions with task or inscan modifiers need further work.
Instead of calling omp_alloc/omp_free (where the former doesn't have
alignment argument and omp_aligned_alloc is 5.1 only feature), this calls
GOMP_alloc/GOMP_free, so that the library can fail if it would fall back
into NULL (exception is zero length allocations).
2020-11-12 Jakub Jelinek <jakub@redhat.com>
gcc/
* builtin-types.def (BT_FN_PTR_SIZE_SIZE_PTRMODE): New function type.
* omp-builtins.def (BUILT_IN_GOACC_DECLARE): Move earlier.
(BUILT_IN_GOMP_ALLOC, BUILT_IN_GOMP_FREE): New builtins.
* gimplify.c (gimplify_scan_omp_clauses): Force allocator into a
decl if it is not NULL, INTEGER_CST or decl.
(gimplify_adjust_omp_clauses): Clear GOVD_EXPLICIT on explicit clauses
which are being removed. Remove allocate clauses for variables not seen
if they are private, firstprivate or linear too. Call
omp_notice_variable on the allocator otherwise.
(gimplify_omp_for): Handle iterator vars mentioned in allocate clauses
similarly to non-is_gimple_reg iterators.
* omp-low.c (struct omp_context): Add allocate_map field.
(delete_omp_context): Delete it.
(scan_sharing_clauses): Fill it from allocate clauses. Remove it
if mentioned also in shared clause.
(lower_private_allocate): New function.
(lower_rec_input_clauses): Handle allocate clause for privatized
variables, except for task/taskloop, C/C++ array reductions for now
and task/inscan variables.
(lower_send_shared_vars): Don't consider variables in allocate_map
as shared.
* omp-expand.c (expand_omp_for_generic, expand_omp_for_static_nochunk,
expand_omp_for_static_chunk): Use expand_omp_build_assign instead of
gimple_build_assign + gsi_insert_after.
* builtins.c (builtin_fnspec): Handle BUILTIN_GOMP_ALLOC and
BUILTIN_GOMP_FREE.
* tree-ssa-ccp.c (evaluate_stmt): Handle BUILTIN_GOMP_ALLOC.
* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Handle
BUILTIN_GOMP_ALLOC.
(mark_all_reaching_defs_necessary_1): Handle BUILTIN_GOMP_ALLOC
and BUILTIN_GOMP_FREE.
(propagate_necessity): Likewise.
gcc/fortran/
* f95-lang.c (ATTR_ALLOC_WARN_UNUSED_RESULT_SIZE_2_NOTHROW_LIST):
Define.
(gfc_init_builtin_functions): Add alloc_size and warn_unused_result
attributes to __builtin_GOMP_alloc.
* types.def (BT_PTRMODE): New primitive type.
(BT_FN_VOID_PTR_PTRMODE, BT_FN_PTR_SIZE_SIZE_PTRMODE): New function
types.
libgomp/
* libgomp.map (GOMP_alloc, GOMP_free): Export at GOMP_5.0.1.
* omp.h.in (omp_alloc): Add malloc and alloc_size attributes.
* libgomp_g.h (GOMP_alloc, GOMP_free): Declare.
* allocator.c (omp_aligned_alloc): New for now static function,
add alignment argument and handle it.
(omp_alloc): Reimplement using omp_aligned_alloc.
(GOMP_alloc, GOMP_free): New functions.
(omp_free): Add ialias.
* testsuite/libgomp.c-c++-common/allocate-1.c: New test.
* testsuite/libgomp.c++/allocate-1.C: New test.
2020-11-13 04:38:04 +08:00
|
|
|
if (__builtin_expect (ret == NULL, 0) && size)
|
|
|
|
gomp_fatal ("Out of memory allocating %lu bytes",
|
|
|
|
(unsigned long) size);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-05-19 20:02:04 +08:00
|
|
|
void
|
|
|
|
omp_free (void *ptr, omp_allocator_handle_t allocator)
|
|
|
|
{
|
|
|
|
struct omp_mem_header *data;
|
2021-12-04 01:46:41 +08:00
|
|
|
omp_memspace_handle_t memspace = omp_default_mem_space;
|
2022-01-04 20:22:01 +08:00
|
|
|
int pinned = false;
|
2020-05-19 20:02:04 +08:00
|
|
|
|
|
|
|
if (ptr == NULL)
|
|
|
|
return;
|
|
|
|
(void) allocator;
|
|
|
|
data = &((struct omp_mem_header *) ptr)[-1];
|
2024-06-12 19:09:33 +08:00
|
|
|
if (!predefined_allocator_p (data->allocator))
|
2020-05-19 20:02:04 +08:00
|
|
|
{
|
|
|
|
struct omp_allocator_data *allocator_data
|
|
|
|
= (struct omp_allocator_data *) (data->allocator);
|
|
|
|
if (allocator_data->pool_size < ~(uintptr_t) 0)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_SYNC_BUILTINS
|
|
|
|
__atomic_add_fetch (&allocator_data->used_pool_size, -data->size,
|
|
|
|
MEMMODEL_RELAXED);
|
|
|
|
#else
|
|
|
|
gomp_mutex_lock (&allocator_data->lock);
|
2020-06-02 17:55:42 +08:00
|
|
|
allocator_data->used_pool_size -= data->size;
|
2020-05-19 20:02:04 +08:00
|
|
|
gomp_mutex_unlock (&allocator_data->lock);
|
|
|
|
#endif
|
|
|
|
}
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#ifdef LIBGOMP_USE_LIBNUMA
|
|
|
|
if (allocator_data->memkind == GOMP_MEMKIND_LIBNUMA)
|
|
|
|
{
|
|
|
|
libnuma_data->numa_free (data->ptr, data->size);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
# ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
else
|
|
|
|
# endif
|
|
|
|
#endif
|
2022-06-09 16:14:42 +08:00
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
if (allocator_data->memkind)
|
|
|
|
{
|
|
|
|
struct gomp_memkind_data *memkind_data = gomp_get_memkind ();
|
|
|
|
void *kind = *memkind_data->kinds[allocator_data->memkind];
|
|
|
|
memkind_data->memkind_free (kind, data->ptr);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
2021-12-04 01:46:41 +08:00
|
|
|
|
|
|
|
memspace = allocator_data->memspace;
|
2022-01-04 20:22:01 +08:00
|
|
|
pinned = allocator_data->pinned;
|
2020-05-19 20:02:04 +08:00
|
|
|
}
|
2022-06-09 16:14:42 +08:00
|
|
|
else
|
|
|
|
{
|
2021-12-04 01:46:41 +08:00
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
enum gomp_numa_memkind_kind memkind = GOMP_MEMKIND_NONE;
|
2022-06-09 16:14:42 +08:00
|
|
|
if (data->allocator == omp_high_bw_mem_alloc)
|
|
|
|
memkind = GOMP_MEMKIND_HBW_PREFERRED;
|
|
|
|
else if (data->allocator == omp_large_cap_mem_alloc)
|
|
|
|
memkind = GOMP_MEMKIND_DAX_KMEM_ALL;
|
|
|
|
if (memkind)
|
|
|
|
{
|
|
|
|
struct gomp_memkind_data *memkind_data = gomp_get_memkind ();
|
|
|
|
if (memkind_data->kinds[memkind])
|
|
|
|
{
|
|
|
|
void *kind = *memkind_data->kinds[memkind];
|
|
|
|
memkind_data->memkind_free (kind, data->ptr);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2021-12-04 01:46:41 +08:00
|
|
|
|
2024-06-12 19:09:33 +08:00
|
|
|
memspace = predefined_alloc_mapping (data->allocator);
|
|
|
|
pinned = (data->allocator == ompx_gnu_pinned_mem_alloc);
|
2021-12-04 01:46:41 +08:00
|
|
|
}
|
|
|
|
|
2022-01-04 20:22:01 +08:00
|
|
|
MEMSPACE_FREE (memspace, data->ptr, data->size, pinned);
|
2020-05-19 20:02:04 +08:00
|
|
|
}
|
openmp: Implement allocate clause in omp lowering.
For now, task/taskloop constructs aren't handled and C/C++ array reductions
and reductions with task or inscan modifiers need further work.
Instead of calling omp_alloc/omp_free (where the former doesn't have
alignment argument and omp_aligned_alloc is 5.1 only feature), this calls
GOMP_alloc/GOMP_free, so that the library can fail if it would fall back
into NULL (exception is zero length allocations).
2020-11-12 Jakub Jelinek <jakub@redhat.com>
gcc/
* builtin-types.def (BT_FN_PTR_SIZE_SIZE_PTRMODE): New function type.
* omp-builtins.def (BUILT_IN_GOACC_DECLARE): Move earlier.
(BUILT_IN_GOMP_ALLOC, BUILT_IN_GOMP_FREE): New builtins.
* gimplify.c (gimplify_scan_omp_clauses): Force allocator into a
decl if it is not NULL, INTEGER_CST or decl.
(gimplify_adjust_omp_clauses): Clear GOVD_EXPLICIT on explicit clauses
which are being removed. Remove allocate clauses for variables not seen
if they are private, firstprivate or linear too. Call
omp_notice_variable on the allocator otherwise.
(gimplify_omp_for): Handle iterator vars mentioned in allocate clauses
similarly to non-is_gimple_reg iterators.
* omp-low.c (struct omp_context): Add allocate_map field.
(delete_omp_context): Delete it.
(scan_sharing_clauses): Fill it from allocate clauses. Remove it
if mentioned also in shared clause.
(lower_private_allocate): New function.
(lower_rec_input_clauses): Handle allocate clause for privatized
variables, except for task/taskloop, C/C++ array reductions for now
and task/inscan variables.
(lower_send_shared_vars): Don't consider variables in allocate_map
as shared.
* omp-expand.c (expand_omp_for_generic, expand_omp_for_static_nochunk,
expand_omp_for_static_chunk): Use expand_omp_build_assign instead of
gimple_build_assign + gsi_insert_after.
* builtins.c (builtin_fnspec): Handle BUILTIN_GOMP_ALLOC and
BUILTIN_GOMP_FREE.
* tree-ssa-ccp.c (evaluate_stmt): Handle BUILTIN_GOMP_ALLOC.
* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Handle
BUILTIN_GOMP_ALLOC.
(mark_all_reaching_defs_necessary_1): Handle BUILTIN_GOMP_ALLOC
and BUILTIN_GOMP_FREE.
(propagate_necessity): Likewise.
gcc/fortran/
* f95-lang.c (ATTR_ALLOC_WARN_UNUSED_RESULT_SIZE_2_NOTHROW_LIST):
Define.
(gfc_init_builtin_functions): Add alloc_size and warn_unused_result
attributes to __builtin_GOMP_alloc.
* types.def (BT_PTRMODE): New primitive type.
(BT_FN_VOID_PTR_PTRMODE, BT_FN_PTR_SIZE_SIZE_PTRMODE): New function
types.
libgomp/
* libgomp.map (GOMP_alloc, GOMP_free): Export at GOMP_5.0.1.
* omp.h.in (omp_alloc): Add malloc and alloc_size attributes.
* libgomp_g.h (GOMP_alloc, GOMP_free): Declare.
* allocator.c (omp_aligned_alloc): New for now static function,
add alignment argument and handle it.
(omp_alloc): Reimplement using omp_aligned_alloc.
(GOMP_alloc, GOMP_free): New functions.
(omp_free): Add ialias.
* testsuite/libgomp.c-c++-common/allocate-1.c: New test.
* testsuite/libgomp.c++/allocate-1.C: New test.
2020-11-13 04:38:04 +08:00
|
|
|
|
|
|
|
ialias (omp_free)
|
|
|
|
|
|
|
|
void
|
|
|
|
GOMP_free (void *ptr, uintptr_t allocator)
|
|
|
|
{
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
return ialias_call (omp_free) (ptr, (omp_allocator_handle_t) allocator);
|
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
|
|
|
omp_aligned_calloc (size_t alignment, size_t nmemb, size_t size,
|
|
|
|
omp_allocator_handle_t allocator)
|
|
|
|
{
|
|
|
|
struct omp_allocator_data *allocator_data;
|
|
|
|
size_t new_size, size_temp, new_alignment;
|
|
|
|
void *ptr, *ret;
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#if defined(LIBGOMP_USE_MEMKIND) || defined(LIBGOMP_USE_LIBNUMA)
|
|
|
|
enum gomp_numa_memkind_kind memkind;
|
2022-06-09 16:14:42 +08:00
|
|
|
#endif
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
|
|
|
|
if (__builtin_expect (size == 0 || nmemb == 0, 0))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
retry:
|
|
|
|
new_alignment = alignment;
|
|
|
|
if (allocator == omp_null_allocator)
|
|
|
|
{
|
|
|
|
struct gomp_thread *thr = gomp_thread ();
|
|
|
|
if (thr->ts.def_allocator == omp_null_allocator)
|
|
|
|
thr->ts.def_allocator = gomp_def_allocator;
|
|
|
|
allocator = (omp_allocator_handle_t) thr->ts.def_allocator;
|
|
|
|
}
|
|
|
|
|
2024-06-12 19:09:33 +08:00
|
|
|
if (!predefined_allocator_p (allocator))
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
{
|
|
|
|
allocator_data = (struct omp_allocator_data *) allocator;
|
|
|
|
if (new_alignment < allocator_data->alignment)
|
|
|
|
new_alignment = allocator_data->alignment;
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#if defined(LIBGOMP_USE_MEMKIND) || defined(LIBGOMP_USE_LIBNUMA)
|
2022-06-09 16:14:42 +08:00
|
|
|
memkind = allocator_data->memkind;
|
|
|
|
#endif
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allocator_data = NULL;
|
|
|
|
if (new_alignment < sizeof (void *))
|
|
|
|
new_alignment = sizeof (void *);
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#if defined(LIBGOMP_USE_MEMKIND) || defined(LIBGOMP_USE_LIBNUMA)
|
2022-06-09 16:14:42 +08:00
|
|
|
memkind = GOMP_MEMKIND_NONE;
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#endif
|
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
2022-06-09 16:14:42 +08:00
|
|
|
if (allocator == omp_high_bw_mem_alloc)
|
|
|
|
memkind = GOMP_MEMKIND_HBW_PREFERRED;
|
|
|
|
else if (allocator == omp_large_cap_mem_alloc)
|
|
|
|
memkind = GOMP_MEMKIND_DAX_KMEM_ALL;
|
|
|
|
if (memkind)
|
|
|
|
{
|
|
|
|
struct gomp_memkind_data *memkind_data = gomp_get_memkind ();
|
|
|
|
if (!memkind_data->kinds[memkind])
|
|
|
|
memkind = GOMP_MEMKIND_NONE;
|
|
|
|
}
|
|
|
|
#endif
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
new_size = sizeof (struct omp_mem_header);
|
|
|
|
if (new_alignment > sizeof (void *))
|
|
|
|
new_size += new_alignment - sizeof (void *);
|
|
|
|
if (__builtin_mul_overflow (size, nmemb, &size_temp))
|
|
|
|
goto fail;
|
|
|
|
if (__builtin_add_overflow (size_temp, new_size, &new_size))
|
|
|
|
goto fail;
|
2022-01-27 21:48:50 +08:00
|
|
|
#ifdef OMP_LOW_LAT_MEM_ALLOC_INVALID
|
|
|
|
if (allocator == omp_low_lat_mem_alloc)
|
|
|
|
goto fail;
|
|
|
|
#endif
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
|
|
|
|
if (__builtin_expect (allocator_data
|
|
|
|
&& allocator_data->pool_size < ~(uintptr_t) 0, 0))
|
|
|
|
{
|
|
|
|
uintptr_t used_pool_size;
|
|
|
|
if (new_size > allocator_data->pool_size)
|
|
|
|
goto fail;
|
|
|
|
#ifdef HAVE_SYNC_BUILTINS
|
|
|
|
used_pool_size = __atomic_load_n (&allocator_data->used_pool_size,
|
|
|
|
MEMMODEL_RELAXED);
|
|
|
|
do
|
|
|
|
{
|
|
|
|
uintptr_t new_pool_size;
|
|
|
|
if (__builtin_add_overflow (used_pool_size, new_size,
|
|
|
|
&new_pool_size)
|
|
|
|
|| new_pool_size > allocator_data->pool_size)
|
|
|
|
goto fail;
|
|
|
|
if (__atomic_compare_exchange_n (&allocator_data->used_pool_size,
|
|
|
|
&used_pool_size, new_pool_size,
|
|
|
|
true, MEMMODEL_RELAXED,
|
|
|
|
MEMMODEL_RELAXED))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
while (1);
|
|
|
|
#else
|
|
|
|
gomp_mutex_lock (&allocator_data->lock);
|
|
|
|
if (__builtin_add_overflow (allocator_data->used_pool_size, new_size,
|
|
|
|
&used_pool_size)
|
|
|
|
|| used_pool_size > allocator_data->pool_size)
|
|
|
|
{
|
|
|
|
gomp_mutex_unlock (&allocator_data->lock);
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
allocator_data->used_pool_size = used_pool_size;
|
|
|
|
gomp_mutex_unlock (&allocator_data->lock);
|
|
|
|
#endif
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#ifdef LIBGOMP_USE_LIBNUMA
|
|
|
|
if (memkind == GOMP_MEMKIND_LIBNUMA)
|
|
|
|
/* numa_alloc_local uses mmap with MAP_ANONYMOUS, returning
|
|
|
|
memory that is initialized to zero. */
|
|
|
|
ptr = libnuma_data->numa_alloc_local (new_size);
|
|
|
|
# ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
else
|
|
|
|
# endif
|
|
|
|
#endif
|
2022-06-09 16:14:42 +08:00
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
if (memkind)
|
|
|
|
{
|
|
|
|
struct gomp_memkind_data *memkind_data = gomp_get_memkind ();
|
|
|
|
void *kind = *memkind_data->kinds[memkind];
|
|
|
|
ptr = memkind_data->memkind_calloc (kind, 1, new_size);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
2022-01-04 20:22:01 +08:00
|
|
|
ptr = MEMSPACE_CALLOC (allocator_data->memspace, new_size,
|
|
|
|
allocator_data->pinned);
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
if (ptr == NULL)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_SYNC_BUILTINS
|
|
|
|
__atomic_add_fetch (&allocator_data->used_pool_size, -new_size,
|
|
|
|
MEMMODEL_RELAXED);
|
|
|
|
#else
|
|
|
|
gomp_mutex_lock (&allocator_data->lock);
|
|
|
|
allocator_data->used_pool_size -= new_size;
|
|
|
|
gomp_mutex_unlock (&allocator_data->lock);
|
|
|
|
#endif
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#ifdef LIBGOMP_USE_LIBNUMA
|
|
|
|
if (memkind == GOMP_MEMKIND_LIBNUMA)
|
|
|
|
/* numa_alloc_local uses mmap with MAP_ANONYMOUS, returning
|
|
|
|
memory that is initialized to zero. */
|
|
|
|
ptr = libnuma_data->numa_alloc_local (new_size);
|
|
|
|
# ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
else
|
|
|
|
# endif
|
|
|
|
#endif
|
2022-06-09 16:14:42 +08:00
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
if (memkind)
|
|
|
|
{
|
|
|
|
struct gomp_memkind_data *memkind_data = gomp_get_memkind ();
|
|
|
|
void *kind = *memkind_data->kinds[memkind];
|
|
|
|
ptr = memkind_data->memkind_calloc (kind, 1, new_size);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
2021-12-04 01:46:41 +08:00
|
|
|
{
|
|
|
|
omp_memspace_handle_t memspace;
|
|
|
|
memspace = (allocator_data
|
|
|
|
? allocator_data->memspace
|
2024-06-12 19:09:33 +08:00
|
|
|
: predefined_alloc_mapping (allocator));
|
|
|
|
int pinned = (allocator_data
|
|
|
|
? allocator_data->pinned
|
|
|
|
: allocator == ompx_gnu_pinned_mem_alloc);
|
|
|
|
ptr = MEMSPACE_CALLOC (memspace, new_size, pinned);
|
2021-12-04 01:46:41 +08:00
|
|
|
}
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
if (ptr == NULL)
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (new_alignment > sizeof (void *))
|
|
|
|
ret = (void *) (((uintptr_t) ptr
|
|
|
|
+ sizeof (struct omp_mem_header)
|
|
|
|
+ new_alignment - sizeof (void *))
|
|
|
|
& ~(new_alignment - 1));
|
|
|
|
else
|
|
|
|
ret = (char *) ptr + sizeof (struct omp_mem_header);
|
|
|
|
((struct omp_mem_header *) ret)[-1].ptr = ptr;
|
|
|
|
((struct omp_mem_header *) ret)[-1].size = new_size;
|
|
|
|
((struct omp_mem_header *) ret)[-1].allocator = allocator;
|
|
|
|
return ret;
|
|
|
|
|
2021-12-04 01:46:41 +08:00
|
|
|
fail:;
|
|
|
|
int fallback = (allocator_data
|
|
|
|
? allocator_data->fallback
|
2024-06-12 19:09:33 +08:00
|
|
|
: (allocator == omp_default_mem_alloc
|
|
|
|
|| allocator == ompx_gnu_pinned_mem_alloc)
|
2021-12-04 01:46:41 +08:00
|
|
|
? omp_atv_null_fb
|
|
|
|
: omp_atv_default_mem_fb);
|
|
|
|
switch (fallback)
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
{
|
2021-12-04 01:46:41 +08:00
|
|
|
case omp_atv_default_mem_fb:
|
|
|
|
allocator = omp_default_mem_alloc;
|
|
|
|
goto retry;
|
|
|
|
case omp_atv_null_fb:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
case omp_atv_abort_fb:
|
|
|
|
gomp_fatal ("Out of memory allocating %lu bytes",
|
|
|
|
(unsigned long) (size * nmemb));
|
|
|
|
case omp_atv_allocator_fb:
|
|
|
|
allocator = allocator_data->fb_data;
|
|
|
|
goto retry;
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ialias (omp_aligned_calloc)
|
|
|
|
|
|
|
|
void *
|
|
|
|
omp_calloc (size_t nmemb, size_t size, omp_allocator_handle_t allocator)
|
|
|
|
{
|
|
|
|
return ialias_call (omp_aligned_calloc) (1, nmemb, size, allocator);
|
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
|
|
|
omp_realloc (void *ptr, size_t size, omp_allocator_handle_t allocator,
|
|
|
|
omp_allocator_handle_t free_allocator)
|
|
|
|
{
|
|
|
|
struct omp_allocator_data *allocator_data, *free_allocator_data;
|
|
|
|
size_t new_size, old_size, new_alignment, old_alignment;
|
|
|
|
void *new_ptr, *ret;
|
|
|
|
struct omp_mem_header *data;
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#if defined(LIBGOMP_USE_MEMKIND) || defined(LIBGOMP_USE_LIBNUMA)
|
|
|
|
enum gomp_numa_memkind_kind memkind, free_memkind;
|
2022-06-09 16:14:42 +08:00
|
|
|
#endif
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
|
|
|
|
if (__builtin_expect (ptr == NULL, 0))
|
|
|
|
return ialias_call (omp_aligned_alloc) (1, size, allocator);
|
|
|
|
|
|
|
|
if (__builtin_expect (size == 0, 0))
|
|
|
|
{
|
|
|
|
ialias_call (omp_free) (ptr, free_allocator);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
data = &((struct omp_mem_header *) ptr)[-1];
|
|
|
|
free_allocator = data->allocator;
|
|
|
|
|
|
|
|
retry:
|
|
|
|
new_alignment = sizeof (void *);
|
|
|
|
if (allocator == omp_null_allocator)
|
|
|
|
allocator = free_allocator;
|
|
|
|
|
2024-06-12 19:09:33 +08:00
|
|
|
if (!predefined_allocator_p (allocator))
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
{
|
|
|
|
allocator_data = (struct omp_allocator_data *) allocator;
|
|
|
|
if (new_alignment < allocator_data->alignment)
|
|
|
|
new_alignment = allocator_data->alignment;
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#if defined(LIBGOMP_USE_MEMKIND) || defined(LIBGOMP_USE_LIBNUMA)
|
2022-06-09 16:14:42 +08:00
|
|
|
memkind = allocator_data->memkind;
|
|
|
|
#endif
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
}
|
|
|
|
else
|
2022-06-09 16:14:42 +08:00
|
|
|
{
|
|
|
|
allocator_data = NULL;
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#if defined(LIBGOMP_USE_MEMKIND) || defined(LIBGOMP_USE_LIBNUMA)
|
2022-06-09 16:14:42 +08:00
|
|
|
memkind = GOMP_MEMKIND_NONE;
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#endif
|
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
2022-06-09 16:14:42 +08:00
|
|
|
if (allocator == omp_high_bw_mem_alloc)
|
|
|
|
memkind = GOMP_MEMKIND_HBW_PREFERRED;
|
|
|
|
else if (allocator == omp_large_cap_mem_alloc)
|
|
|
|
memkind = GOMP_MEMKIND_DAX_KMEM_ALL;
|
|
|
|
if (memkind)
|
|
|
|
{
|
|
|
|
struct gomp_memkind_data *memkind_data = gomp_get_memkind ();
|
|
|
|
if (!memkind_data->kinds[memkind])
|
|
|
|
memkind = GOMP_MEMKIND_NONE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
2024-06-12 19:09:33 +08:00
|
|
|
if (!predefined_allocator_p (free_allocator))
|
2022-06-09 16:14:42 +08:00
|
|
|
{
|
|
|
|
free_allocator_data = (struct omp_allocator_data *) free_allocator;
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#if defined(LIBGOMP_USE_MEMKIND) || defined(LIBGOMP_USE_LIBNUMA)
|
2022-06-09 16:14:42 +08:00
|
|
|
free_memkind = free_allocator_data->memkind;
|
|
|
|
#endif
|
|
|
|
}
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
else
|
2022-06-09 16:14:42 +08:00
|
|
|
{
|
|
|
|
free_allocator_data = NULL;
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#if defined(LIBGOMP_USE_MEMKIND) || defined(LIBGOMP_USE_LIBNUMA)
|
2022-06-09 16:14:42 +08:00
|
|
|
free_memkind = GOMP_MEMKIND_NONE;
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#endif
|
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
2022-06-09 16:14:42 +08:00
|
|
|
if (free_allocator == omp_high_bw_mem_alloc)
|
|
|
|
free_memkind = GOMP_MEMKIND_HBW_PREFERRED;
|
|
|
|
else if (free_allocator == omp_large_cap_mem_alloc)
|
|
|
|
free_memkind = GOMP_MEMKIND_DAX_KMEM_ALL;
|
|
|
|
if (free_memkind)
|
|
|
|
{
|
|
|
|
struct gomp_memkind_data *memkind_data = gomp_get_memkind ();
|
|
|
|
if (!memkind_data->kinds[free_memkind])
|
|
|
|
free_memkind = GOMP_MEMKIND_NONE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
old_alignment = (uintptr_t) ptr - (uintptr_t) (data->ptr);
|
|
|
|
|
|
|
|
new_size = sizeof (struct omp_mem_header);
|
|
|
|
if (new_alignment > sizeof (void *))
|
|
|
|
new_size += new_alignment - sizeof (void *);
|
|
|
|
if (__builtin_add_overflow (size, new_size, &new_size))
|
|
|
|
goto fail;
|
|
|
|
old_size = data->size;
|
2022-01-27 21:48:50 +08:00
|
|
|
#ifdef OMP_LOW_LAT_MEM_ALLOC_INVALID
|
|
|
|
if (allocator == omp_low_lat_mem_alloc)
|
|
|
|
goto fail;
|
|
|
|
#endif
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
|
|
|
|
if (__builtin_expect (allocator_data
|
|
|
|
&& allocator_data->pool_size < ~(uintptr_t) 0, 0))
|
|
|
|
{
|
|
|
|
uintptr_t used_pool_size;
|
|
|
|
size_t prev_size = 0;
|
|
|
|
/* Check if we can use realloc. Don't use it if extra alignment
|
|
|
|
was used previously or newly, because realloc might return a pointer
|
|
|
|
with different alignment and then we'd need to memmove the data
|
|
|
|
again. */
|
|
|
|
if (free_allocator_data
|
|
|
|
&& free_allocator_data == allocator_data
|
|
|
|
&& new_alignment == sizeof (void *)
|
|
|
|
&& old_alignment == sizeof (struct omp_mem_header))
|
|
|
|
prev_size = old_size;
|
|
|
|
if (new_size > prev_size
|
|
|
|
&& new_size - prev_size > allocator_data->pool_size)
|
|
|
|
goto fail;
|
|
|
|
#ifdef HAVE_SYNC_BUILTINS
|
|
|
|
used_pool_size = __atomic_load_n (&allocator_data->used_pool_size,
|
|
|
|
MEMMODEL_RELAXED);
|
|
|
|
do
|
|
|
|
{
|
|
|
|
uintptr_t new_pool_size;
|
|
|
|
if (new_size > prev_size)
|
|
|
|
{
|
|
|
|
if (__builtin_add_overflow (used_pool_size, new_size - prev_size,
|
|
|
|
&new_pool_size)
|
|
|
|
|| new_pool_size > allocator_data->pool_size)
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
new_pool_size = used_pool_size + new_size - prev_size;
|
|
|
|
if (__atomic_compare_exchange_n (&allocator_data->used_pool_size,
|
|
|
|
&used_pool_size, new_pool_size,
|
|
|
|
true, MEMMODEL_RELAXED,
|
|
|
|
MEMMODEL_RELAXED))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
while (1);
|
|
|
|
#else
|
|
|
|
gomp_mutex_lock (&allocator_data->lock);
|
|
|
|
if (new_size > prev_size)
|
|
|
|
{
|
|
|
|
if (__builtin_add_overflow (allocator_data->used_pool_size,
|
|
|
|
new_size - prev_size,
|
|
|
|
&used_pool_size)
|
|
|
|
|| used_pool_size > allocator_data->pool_size)
|
|
|
|
{
|
|
|
|
gomp_mutex_unlock (&allocator_data->lock);
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
used_pool_size = (allocator_data->used_pool_size
|
|
|
|
+ new_size - prev_size);
|
|
|
|
allocator_data->used_pool_size = used_pool_size;
|
|
|
|
gomp_mutex_unlock (&allocator_data->lock);
|
2022-06-09 16:14:42 +08:00
|
|
|
#endif
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#ifdef LIBGOMP_USE_LIBNUMA
|
|
|
|
if (memkind == GOMP_MEMKIND_LIBNUMA)
|
|
|
|
{
|
|
|
|
if (prev_size)
|
|
|
|
new_ptr = libnuma_data->numa_realloc (data->ptr, data->size,
|
|
|
|
new_size);
|
|
|
|
else
|
|
|
|
new_ptr = libnuma_data->numa_alloc_local (new_size);
|
|
|
|
}
|
|
|
|
# ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
else
|
|
|
|
# endif
|
|
|
|
#endif
|
2022-06-09 16:14:42 +08:00
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
if (memkind)
|
|
|
|
{
|
|
|
|
struct gomp_memkind_data *memkind_data = gomp_get_memkind ();
|
|
|
|
void *kind = *memkind_data->kinds[memkind];
|
|
|
|
if (prev_size)
|
|
|
|
new_ptr = memkind_data->memkind_realloc (kind, data->ptr,
|
|
|
|
new_size);
|
|
|
|
else
|
|
|
|
new_ptr = memkind_data->memkind_malloc (kind, new_size);
|
|
|
|
}
|
|
|
|
else
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
#endif
|
|
|
|
if (prev_size)
|
2024-06-12 19:09:33 +08:00
|
|
|
{
|
|
|
|
int was_pinned = (free_allocator_data
|
|
|
|
? free_allocator_data->pinned
|
|
|
|
: free_allocator == ompx_gnu_pinned_mem_alloc);
|
|
|
|
new_ptr = MEMSPACE_REALLOC (allocator_data->memspace, data->ptr,
|
|
|
|
data->size, new_size, was_pinned,
|
|
|
|
allocator_data->pinned);
|
|
|
|
}
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
else
|
2022-01-04 20:22:01 +08:00
|
|
|
new_ptr = MEMSPACE_ALLOC (allocator_data->memspace, new_size,
|
|
|
|
allocator_data->pinned);
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
if (new_ptr == NULL)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_SYNC_BUILTINS
|
|
|
|
__atomic_add_fetch (&allocator_data->used_pool_size,
|
|
|
|
prev_size - new_size,
|
|
|
|
MEMMODEL_RELAXED);
|
|
|
|
#else
|
|
|
|
gomp_mutex_lock (&allocator_data->lock);
|
|
|
|
allocator_data->used_pool_size -= new_size - prev_size;
|
|
|
|
gomp_mutex_unlock (&allocator_data->lock);
|
|
|
|
#endif
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
else if (prev_size)
|
|
|
|
{
|
|
|
|
ret = (char *) new_ptr + sizeof (struct omp_mem_header);
|
|
|
|
((struct omp_mem_header *) ret)[-1].ptr = new_ptr;
|
|
|
|
((struct omp_mem_header *) ret)[-1].size = new_size;
|
|
|
|
((struct omp_mem_header *) ret)[-1].allocator = allocator;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (new_alignment == sizeof (void *)
|
|
|
|
&& old_alignment == sizeof (struct omp_mem_header)
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#if defined(LIBGOMP_USE_MEMKIND) || defined(LIBGOMP_USE_LIBNUMA)
|
2022-06-09 16:14:42 +08:00
|
|
|
&& memkind == free_memkind
|
|
|
|
#endif
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
&& (free_allocator_data == NULL
|
|
|
|
|| free_allocator_data->pool_size == ~(uintptr_t) 0))
|
|
|
|
{
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#ifdef LIBGOMP_USE_LIBNUMA
|
|
|
|
if (memkind == GOMP_MEMKIND_LIBNUMA)
|
|
|
|
new_ptr = libnuma_data->numa_realloc (data->ptr, data->size, new_size);
|
|
|
|
# ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
else
|
|
|
|
# endif
|
|
|
|
#endif
|
2022-06-09 16:14:42 +08:00
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
if (memkind)
|
|
|
|
{
|
|
|
|
struct gomp_memkind_data *memkind_data = gomp_get_memkind ();
|
|
|
|
void *kind = *memkind_data->kinds[memkind];
|
|
|
|
new_ptr = memkind_data->memkind_realloc (kind, data->ptr,
|
|
|
|
new_size);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
2021-12-04 01:46:41 +08:00
|
|
|
{
|
|
|
|
omp_memspace_handle_t memspace;
|
|
|
|
memspace = (allocator_data
|
|
|
|
? allocator_data->memspace
|
2024-06-12 19:09:33 +08:00
|
|
|
: predefined_alloc_mapping (allocator));
|
|
|
|
int was_pinned = (free_allocator_data
|
|
|
|
? free_allocator_data->pinned
|
|
|
|
: free_allocator == ompx_gnu_pinned_mem_alloc);
|
|
|
|
int pinned = (allocator_data
|
|
|
|
? allocator_data->pinned
|
|
|
|
: allocator == ompx_gnu_pinned_mem_alloc);
|
2022-01-04 20:22:01 +08:00
|
|
|
new_ptr = MEMSPACE_REALLOC (memspace, data->ptr, data->size, new_size,
|
2024-06-12 19:09:33 +08:00
|
|
|
was_pinned, pinned);
|
2021-12-04 01:46:41 +08:00
|
|
|
}
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
if (new_ptr == NULL)
|
|
|
|
goto fail;
|
2022-01-04 20:22:01 +08:00
|
|
|
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
ret = (char *) new_ptr + sizeof (struct omp_mem_header);
|
|
|
|
((struct omp_mem_header *) ret)[-1].ptr = new_ptr;
|
|
|
|
((struct omp_mem_header *) ret)[-1].size = new_size;
|
|
|
|
((struct omp_mem_header *) ret)[-1].allocator = allocator;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#ifdef LIBGOMP_USE_LIBNUMA
|
|
|
|
if (memkind == GOMP_MEMKIND_LIBNUMA)
|
|
|
|
new_ptr = libnuma_data->numa_alloc_local (new_size);
|
|
|
|
# ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
else
|
|
|
|
# endif
|
|
|
|
#endif
|
2022-06-09 16:14:42 +08:00
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
if (memkind)
|
|
|
|
{
|
|
|
|
struct gomp_memkind_data *memkind_data = gomp_get_memkind ();
|
|
|
|
void *kind = *memkind_data->kinds[memkind];
|
|
|
|
new_ptr = memkind_data->memkind_malloc (kind, new_size);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
2021-12-04 01:46:41 +08:00
|
|
|
{
|
|
|
|
omp_memspace_handle_t memspace;
|
|
|
|
memspace = (allocator_data
|
|
|
|
? allocator_data->memspace
|
2024-06-12 19:09:33 +08:00
|
|
|
: predefined_alloc_mapping (allocator));
|
|
|
|
int pinned = (allocator_data
|
|
|
|
? allocator_data->pinned
|
|
|
|
: allocator == ompx_gnu_pinned_mem_alloc);
|
|
|
|
new_ptr = MEMSPACE_ALLOC (memspace, new_size, pinned);
|
2021-12-04 01:46:41 +08:00
|
|
|
}
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
if (new_ptr == NULL)
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (new_alignment > sizeof (void *))
|
|
|
|
ret = (void *) (((uintptr_t) new_ptr
|
|
|
|
+ sizeof (struct omp_mem_header)
|
|
|
|
+ new_alignment - sizeof (void *))
|
|
|
|
& ~(new_alignment - 1));
|
|
|
|
else
|
|
|
|
ret = (char *) new_ptr + sizeof (struct omp_mem_header);
|
|
|
|
((struct omp_mem_header *) ret)[-1].ptr = new_ptr;
|
|
|
|
((struct omp_mem_header *) ret)[-1].size = new_size;
|
|
|
|
((struct omp_mem_header *) ret)[-1].allocator = allocator;
|
|
|
|
if (old_size - old_alignment < size)
|
|
|
|
size = old_size - old_alignment;
|
|
|
|
memcpy (ret, ptr, size);
|
|
|
|
if (__builtin_expect (free_allocator_data
|
|
|
|
&& free_allocator_data->pool_size < ~(uintptr_t) 0, 0))
|
|
|
|
{
|
|
|
|
#ifdef HAVE_SYNC_BUILTINS
|
|
|
|
__atomic_add_fetch (&free_allocator_data->used_pool_size, -data->size,
|
|
|
|
MEMMODEL_RELAXED);
|
|
|
|
#else
|
|
|
|
gomp_mutex_lock (&free_allocator_data->lock);
|
|
|
|
free_allocator_data->used_pool_size -= data->size;
|
|
|
|
gomp_mutex_unlock (&free_allocator_data->lock);
|
|
|
|
#endif
|
|
|
|
}
|
libgomp: Use libnuma for OpenMP's partition=nearest allocation trait
As with the memkind library, it is only used when found at runtime;
it does not need to be present when building GCC.
The included testcase does not check whether the memory has been placed
on the nearest node as the Linux kernel memory handling too often ignores
that hint, using a different node for the allocation. However, when
running with 'numactl --preferred=<node> ./executable', it is clearly
visible that the feature works by comparing malloc/default vs. nearest
placement (using get_mempolicy to obtain the node for a mem addr).
libgomp/ChangeLog:
* allocator.c: Add ifdef for LIBGOMP_USE_LIBNUMA.
(enum gomp_numa_memkind_kind): Renamed from gomp_memkind_kind;
add GOMP_MEMKIND_LIBNUMA.
(struct gomp_libnuma_data, gomp_init_libnuma, gomp_get_libnuma): New.
(omp_init_allocator): Handle partition=nearest with libnuma if avail.
(omp_aligned_alloc, omp_free, omp_aligned_calloc, omp_realloc): Add
numa_alloc_local (+ memset), numa_free, and numa_realloc calls as
needed.
* config/linux/allocator.c (LIBGOMP_USE_LIBNUMA): Define
* libgomp.texi: Fix a typo; use 'fi' instead of its ligature char.
(Memory allocation): Renamed from 'Memory allocation with libmemkind';
updated for libnuma usage.
* testsuite/libgomp.c-c++-common/alloc-11.c: New test.
* testsuite/libgomp.c-c++-common/alloc-12.c: New test.
2023-07-12 19:50:21 +08:00
|
|
|
#ifdef LIBGOMP_USE_LIBNUMA
|
|
|
|
if (free_memkind == GOMP_MEMKIND_LIBNUMA)
|
|
|
|
{
|
|
|
|
libnuma_data->numa_free (data->ptr, data->size);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
# ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
else
|
|
|
|
# endif
|
|
|
|
#endif
|
2022-06-09 16:14:42 +08:00
|
|
|
#ifdef LIBGOMP_USE_MEMKIND
|
|
|
|
if (free_memkind)
|
|
|
|
{
|
|
|
|
struct gomp_memkind_data *memkind_data = gomp_get_memkind ();
|
|
|
|
void *kind = *memkind_data->kinds[free_memkind];
|
|
|
|
memkind_data->memkind_free (kind, data->ptr);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#endif
|
2021-12-04 01:46:41 +08:00
|
|
|
{
|
|
|
|
omp_memspace_handle_t was_memspace;
|
|
|
|
was_memspace = (free_allocator_data
|
|
|
|
? free_allocator_data->memspace
|
2024-06-12 19:09:33 +08:00
|
|
|
: predefined_alloc_mapping (free_allocator));
|
|
|
|
int was_pinned = (free_allocator_data
|
|
|
|
? free_allocator_data->pinned
|
|
|
|
: free_allocator == ompx_gnu_pinned_mem_alloc);
|
2022-01-04 20:22:01 +08:00
|
|
|
MEMSPACE_FREE (was_memspace, data->ptr, data->size, was_pinned);
|
2021-12-04 01:46:41 +08:00
|
|
|
}
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
return ret;
|
|
|
|
|
2021-12-04 01:46:41 +08:00
|
|
|
fail:;
|
|
|
|
int fallback = (allocator_data
|
|
|
|
? allocator_data->fallback
|
2024-06-12 19:09:33 +08:00
|
|
|
: (allocator == omp_default_mem_alloc
|
|
|
|
|| allocator == ompx_gnu_pinned_mem_alloc)
|
2021-12-04 01:46:41 +08:00
|
|
|
? omp_atv_null_fb
|
|
|
|
: omp_atv_default_mem_fb);
|
|
|
|
switch (fallback)
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
{
|
2021-12-04 01:46:41 +08:00
|
|
|
case omp_atv_default_mem_fb:
|
|
|
|
allocator = omp_default_mem_alloc;
|
|
|
|
goto retry;
|
|
|
|
case omp_atv_null_fb:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
case omp_atv_abort_fb:
|
|
|
|
gomp_fatal ("Out of memory allocating %lu bytes",
|
|
|
|
(unsigned long) size);
|
|
|
|
case omp_atv_allocator_fb:
|
|
|
|
allocator = allocator_data->fb_data;
|
|
|
|
goto retry;
|
openmp: Add omp_aligned_{,c}alloc and omp_{c,re}alloc
This patch adds new OpenMP 5.1 allocator entrypoints and in addition to that
fixes an omp_alloc bug which is hard to test for - if the first allocator
fails but has a larger alignment trait and has a fallback allocator, either
the default behavior or a user fallback, then the extra alignment will be used
even in the fallback allocation, rather than just starting with whatever
alignment has been requested (in GOMP_alloc or the minimum one in omp_alloc).
Jonathan's comment on IRC this morning made me realize that I should add
alloc_align attributes to 2 of the prototypes and I still need to add testsuite
coverage for omp_realloc, will do that in a follow-up.
2021-09-30 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_aligned_alloc, omp_calloc, omp_aligned_calloc,
omp_realloc): New prototypes.
(omp_alloc): Move after omp_free prototype, add __malloc__ (omp_free)
attribute.
* allocator.c: Include string.h.
(omp_aligned_alloc): No longer static, add ialias. Add new_alignment
variable and use it instead of alignment so that when retrying the old
alignment is used again. Don't retry if new alignment is the same
as old alignment, unless allocator had pool size.
(omp_alloc, GOMP_alloc, GOMP_free): Use ialias_call.
(omp_aligned_calloc, omp_calloc, omp_realloc): New functions.
* libgomp.map (OMP_5.0.2): Export omp_aligned_alloc, omp_calloc,
omp_aligned_calloc and omp_realloc.
* testsuite/libgomp.c-c++-common/alloc-4.c (main): Add
omp_aligned_alloc, omp_calloc and omp_aligned_calloc tests.
* testsuite/libgomp.c-c++-common/alloc-5.c: New test.
* testsuite/libgomp.c-c++-common/alloc-6.c: New test.
* testsuite/libgomp.c-c++-common/alloc-7.c: New test.
* testsuite/libgomp.c-c++-common/alloc-8.c: New test.
2021-09-30 15:30:18 +08:00
|
|
|
}
|
|
|
|
return NULL;
|
openmp: Implement allocate clause in omp lowering.
For now, task/taskloop constructs aren't handled and C/C++ array reductions
and reductions with task or inscan modifiers need further work.
Instead of calling omp_alloc/omp_free (where the former doesn't have
alignment argument and omp_aligned_alloc is 5.1 only feature), this calls
GOMP_alloc/GOMP_free, so that the library can fail if it would fall back
into NULL (exception is zero length allocations).
2020-11-12 Jakub Jelinek <jakub@redhat.com>
gcc/
* builtin-types.def (BT_FN_PTR_SIZE_SIZE_PTRMODE): New function type.
* omp-builtins.def (BUILT_IN_GOACC_DECLARE): Move earlier.
(BUILT_IN_GOMP_ALLOC, BUILT_IN_GOMP_FREE): New builtins.
* gimplify.c (gimplify_scan_omp_clauses): Force allocator into a
decl if it is not NULL, INTEGER_CST or decl.
(gimplify_adjust_omp_clauses): Clear GOVD_EXPLICIT on explicit clauses
which are being removed. Remove allocate clauses for variables not seen
if they are private, firstprivate or linear too. Call
omp_notice_variable on the allocator otherwise.
(gimplify_omp_for): Handle iterator vars mentioned in allocate clauses
similarly to non-is_gimple_reg iterators.
* omp-low.c (struct omp_context): Add allocate_map field.
(delete_omp_context): Delete it.
(scan_sharing_clauses): Fill it from allocate clauses. Remove it
if mentioned also in shared clause.
(lower_private_allocate): New function.
(lower_rec_input_clauses): Handle allocate clause for privatized
variables, except for task/taskloop, C/C++ array reductions for now
and task/inscan variables.
(lower_send_shared_vars): Don't consider variables in allocate_map
as shared.
* omp-expand.c (expand_omp_for_generic, expand_omp_for_static_nochunk,
expand_omp_for_static_chunk): Use expand_omp_build_assign instead of
gimple_build_assign + gsi_insert_after.
* builtins.c (builtin_fnspec): Handle BUILTIN_GOMP_ALLOC and
BUILTIN_GOMP_FREE.
* tree-ssa-ccp.c (evaluate_stmt): Handle BUILTIN_GOMP_ALLOC.
* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Handle
BUILTIN_GOMP_ALLOC.
(mark_all_reaching_defs_necessary_1): Handle BUILTIN_GOMP_ALLOC
and BUILTIN_GOMP_FREE.
(propagate_necessity): Likewise.
gcc/fortran/
* f95-lang.c (ATTR_ALLOC_WARN_UNUSED_RESULT_SIZE_2_NOTHROW_LIST):
Define.
(gfc_init_builtin_functions): Add alloc_size and warn_unused_result
attributes to __builtin_GOMP_alloc.
* types.def (BT_PTRMODE): New primitive type.
(BT_FN_VOID_PTR_PTRMODE, BT_FN_PTR_SIZE_SIZE_PTRMODE): New function
types.
libgomp/
* libgomp.map (GOMP_alloc, GOMP_free): Export at GOMP_5.0.1.
* omp.h.in (omp_alloc): Add malloc and alloc_size attributes.
* libgomp_g.h (GOMP_alloc, GOMP_free): Declare.
* allocator.c (omp_aligned_alloc): New for now static function,
add alignment argument and handle it.
(omp_alloc): Reimplement using omp_aligned_alloc.
(GOMP_alloc, GOMP_free): New functions.
(omp_free): Add ialias.
* testsuite/libgomp.c-c++-common/allocate-1.c: New test.
* testsuite/libgomp.c++/allocate-1.C: New test.
2020-11-13 04:38:04 +08:00
|
|
|
}
|