From 824197f886f01bcaab7aaf2866e2d909ab716da5 Mon Sep 17 00:00:00 2001 From: Howard Pritchard <howardp@lanl.gov> Date: Thu, 22 Mar 2018 03:55:18 -0600 Subject: [PATCH] mpool/memkind: refactor to use the current API The mpool/memkind component was using a deprecated "partitions" API. This commit refactors the memkind component to make use of the supported public API. The public API uses 3 parameters to specify a mpool "kind": - a memkind type (which for now is just default or HBM) - a memkind policy - a memkind_bits (partly to specify pagesize) The MCA parameters were changed to reflect these memkind parameters. Add a make check test for sanity checking of the memkind component. Signed-off-by: Howard Pritchard <howardp@lanl.gov> --- configure.ac | 1 + opal/mca/mpool/memkind/configure.m4 | 7 +- opal/mca/mpool/memkind/mpool_memkind.h | 31 ++- .../mpool/memkind/mpool_memkind_component.c | 259 +++++++++++++----- opal/mca/mpool/memkind/mpool_memkind_module.c | 15 +- test/Makefile.am | 2 +- test/mpool/Makefile.am | 21 ++ test/mpool/mpool_memkind.c | 160 +++++++++++ 8 files changed, 413 insertions(+), 83 deletions(-) create mode 100644 test/mpool/Makefile.am create mode 100644 test/mpool/mpool_memkind.c diff --git a/configure.ac b/configure.ac index 64eab61b8f..35f4d4f1d7 100644 --- a/configure.ac +++ b/configure.ac @@ -1422,6 +1422,7 @@ AC_CONFIG_FILES([ test/datatype/Makefile test/dss/Makefile test/class/Makefile + test/mpool/Makefile test/support/Makefile test/threads/Makefile test/util/Makefile diff --git a/opal/mca/mpool/memkind/configure.m4 b/opal/mca/mpool/memkind/configure.m4 index bc6e5a3286..95541fe100 100644 --- a/opal/mca/mpool/memkind/configure.m4 +++ b/opal/mca/mpool/memkind/configure.m4 @@ -1,6 +1,6 @@ # -*- shell-script -*- # -# Copyright (c) 2013-2014 Los Alamos National Security, LLC. All rights +# Copyright (c) 2013-2018 Los Alamos National Security, LLC. All rights # reserved. # $COPYRIGHT$ # @@ -24,7 +24,10 @@ AC_DEFUN([MCA_opal_mpool_memkind_CONFIG],[ opal_check_memkind_dir=$with_memkind fi - OPAL_CHECK_PACKAGE([mpool_memkind], [memkind.h], [memkind], [memkind_malloc], [ -lnuma], + # + # memkind_create_kind was introduced with memkind v1.4.0 release + # + OPAL_CHECK_PACKAGE([mpool_memkind], [memkind.h], [memkind], [memkind_create_kind], [ -lnuma], [$opal_check_memkind_dir], [], [opal_mpool_memkind_happy="yes"], []) if test "$opal_mpool_memkind_happy" != "yes" -a -n "$with_memkind" ; then diff --git a/opal/mca/mpool/memkind/mpool_memkind.h b/opal/mca/mpool/memkind/mpool_memkind.h index afc0b6d8b7..2ac6c29107 100644 --- a/opal/mca/mpool/memkind/mpool_memkind.h +++ b/opal/mca/mpool/memkind/mpool_memkind.h @@ -12,7 +12,7 @@ * All rights reserved. * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2010-2015 Los Alamos National Security, LLC. All rights + * Copyright (c) 2010-2018 Los Alamos National Security, LLC. All rights * reserved. * $COPYRIGHT$ * @@ -38,32 +38,49 @@ BEGIN_C_DECLS static const int mca_mpool_memkind_default_pagesize = 4096; + struct mca_mpool_memkind_module_t { mca_mpool_base_module_t super; memkind_t kind; + memkind_memtype_t type; + memkind_policy_t policy; + memkind_bits_t memkind_bits; int page_size; }; + typedef struct mca_mpool_memkind_module_t mca_mpool_memkind_module_t; +struct mca_mpool_memkind_module_le_t { + opal_list_item_t super; + mca_mpool_memkind_module_t module; +}; +typedef struct mca_mpool_memkind_module_le_t mca_mpool_memkind_module_le_t; + +OBJ_CLASS_DECLARATION(mca_mpool_memkind_module_le_t); + struct mca_mpool_memkind_component_t { mca_mpool_base_component_t super; int hbw; int pagesize; int bind; - int default_partition; + memkind_memtype_t default_type; + memkind_policy_t default_policy; + memkind_bits_t default_memkind_bits; + memkind_t default_kind; int priority; - char *memkind_file; int output; - mca_mpool_memkind_module_t modules[MEMKIND_NUM_BASE_KIND]; + opal_list_t module_list; }; + typedef struct mca_mpool_memkind_component_t mca_mpool_memkind_component_t; OPAL_MODULE_DECLSPEC extern mca_mpool_memkind_component_t mca_mpool_memkind_component; -/* +/** * Initializes the mpool module. -*/ + */ + +void mca_mpool_memkind_module_init(mca_mpool_memkind_module_t *mpool); -void mca_mpool_memkind_module_init(mca_mpool_memkind_module_t *mpool, int partition); /** * Allocate block of high bandwidth memory. diff --git a/opal/mca/mpool/memkind/mpool_memkind_component.c b/opal/mca/mpool/memkind/mpool_memkind_component.c index d438d0599f..41145d039c 100644 --- a/opal/mca/mpool/memkind/mpool_memkind_component.c +++ b/opal/mca/mpool/memkind/mpool_memkind_component.c @@ -12,7 +12,7 @@ * All rights reserved. * Copyright (c) 2007-2009 Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2008-2009 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2010-2016 Los Alamos National Security, LLC. All rights + * Copyright (c) 2010-2018 Los Alamos National Security, LLC. All rights * reserved. * Copyright (c) 2014 NVIDIA Corporation. All rights reserved. * Copyright (c) 2017 Research Organization for Information Science @@ -35,6 +35,7 @@ #include <memkind.h> #include "opal/mca/base/base.h" #include "opal/mca/allocator/base/base.h" +#include "opal/mca/mpool/base/base.h" #include "opal/util/argv.h" #include "mpool_memkind.h" @@ -77,22 +78,42 @@ mca_mpool_memkind_component_t mca_mpool_memkind_component = { } }; -static mca_base_var_enum_value_t memory_kinds[] = { - {.value = MEMKIND_PARTITION_DEFAULT, .string = "memkind_default"}, - {.value = MEMKIND_PARTITION_HBW, .string = "memkind_hbw"}, - {.value = MEMKIND_PARTITION_HBW_HUGETLB, .string = "memkind_hwb_hugetlb"}, - {.value = MEMKIND_PARTITION_HBW_PREFERRED, .string = "memkind_hbw_preferred"}, - {.value = MEMKIND_PARTITION_HBW_PREFERRED_HUGETLB, .string = "memkind_hbw_preferred_hugetlb"}, - {.value = MEMKIND_PARTITION_HUGETLB, .string = "memkind_hugetlb"}, - {.value = MEMKIND_PARTITION_HBW_GBTLB, .string = "memkind_hbw_gbtlb"}, - {.value = MEMKIND_PARTITION_HBW_PREFERRED_GBTLB, .string = "memkind_hbw_preferred_gbtlb"}, - {.value = MEMKIND_PARTITION_GBTLB, .string = "memkind_gbtlb"}, - {.value = MEMKIND_PARTITION_HBW_INTERLEAVE, .string = "memkind_hbw_interleave"}, - {.value = MEMKIND_PARTITION_INTERLEAVE, .string = "memkind_interleave"}, +static void mca_mpool_memkind_module_le_destroy(mca_mpool_memkind_module_le_t *elem) +{ + if (NULL != elem->module.kind) { + memkind_destroy_kind(elem->module.kind); + } +} + +OBJ_CLASS_INSTANCE(mca_mpool_memkind_module_le_t, + opal_list_item_t, + NULL, + mca_mpool_memkind_module_le_destroy); + +static mca_base_var_enum_value_t memory_types[] = { + {.value = MEMKIND_MEMTYPE_DEFAULT, .string = "memkind_default"}, + {.value = MEMKIND_MEMTYPE_HIGH_BANDWIDTH, .string = "memkind_hbw"}, {.string = NULL}, }; -static mca_base_var_enum_t *mca_mpool_memkind_enum = NULL; +static mca_base_var_enum_value_t memory_policy[] = { + {.value = MEMKIND_POLICY_BIND_LOCAL, .string = "mempolicy_bind_local"}, + {.value = MEMKIND_POLICY_BIND_ALL, .string = "mempolicy_bind_all"}, + {.value = MEMKIND_POLICY_PREFERRED_LOCAL, .string = "mempolicy_perferred_local"}, + {.value = MEMKIND_POLICY_INTERLEAVE_LOCAL, .string = "mempolicy_interleave_local"}, + {.value = MEMKIND_POLICY_INTERLEAVE_ALL, .string = "mempolicy_interleave_all"}, + {.string = NULL}, +}; + +static mca_base_var_enum_value_t memory_kind_bits[] = { + {.value = 0, .string = "memkind_mask_page_size_4KB"}, + {.value = MEMKIND_MASK_PAGE_SIZE_2MB, .string = "memkind_mask_page_size_2MB"}, + {.string = NULL}, +}; + +static mca_base_var_enum_t *mca_mpool_memkind_policy_enum = NULL; +static mca_base_var_enum_t *mca_mpool_memkind_type_enum = NULL; +static mca_base_var_enum_t *mca_mpool_memkind_kind_bits_enum = NULL; static int opal_mpool_memkind_verbose; static int mca_mpool_memkind_register(void) @@ -100,18 +121,51 @@ static int mca_mpool_memkind_register(void) int rc; /* register MEMKIND component parameters */ - mca_mpool_memkind_component.default_partition = memory_kinds[0].value; - rc = mca_base_var_enum_create ("memkind partition types", memory_kinds, &mca_mpool_memkind_enum); + mca_mpool_memkind_component.default_type = memory_types[0].value; + + rc = mca_base_var_enum_create ("memkind memory types", memory_types, + &mca_mpool_memkind_type_enum); if (OPAL_SUCCESS != rc) { return rc; } (void) mca_base_component_var_register(&mca_mpool_memkind_component.super.mpool_version, - "default_partition", "Default memkind partition to use", - MCA_BASE_VAR_TYPE_INT, mca_mpool_memkind_enum, 0, 0, + "default_type", "Default memkind type to use", + MCA_BASE_VAR_TYPE_INT, mca_mpool_memkind_type_enum, 0, 0, OPAL_INFO_LVL_5, MCA_BASE_VAR_SCOPE_LOCAL, - &mca_mpool_memkind_component.default_partition); + &mca_mpool_memkind_component.default_type); + + /* + * see memkind source to understand the 2 + */ + mca_mpool_memkind_component.default_policy = memory_policy[2].value; + + rc = mca_base_var_enum_create ("memkind memory policy", memory_policy, + &mca_mpool_memkind_policy_enum); + if (OPAL_SUCCESS != rc) { + return rc; + } + + (void) mca_base_component_var_register(&mca_mpool_memkind_component.super.mpool_version, + "default_policy", "Default memkind policy to use", + MCA_BASE_VAR_TYPE_INT, mca_mpool_memkind_policy_enum, 0, 0, + OPAL_INFO_LVL_5, MCA_BASE_VAR_SCOPE_LOCAL, + &mca_mpool_memkind_component.default_policy); + + mca_mpool_memkind_component.default_memkind_bits = memory_kind_bits[0].value; + + rc = mca_base_var_enum_create ("memkind memory bits", memory_kind_bits, + &mca_mpool_memkind_kind_bits_enum); + if (OPAL_SUCCESS != rc) { + return rc; + } + + (void) mca_base_component_var_register(&mca_mpool_memkind_component.super.mpool_version, + "default_bits", "Default memkind bits to use", + MCA_BASE_VAR_TYPE_INT, mca_mpool_memkind_kind_bits_enum, 0, 0, + OPAL_INFO_LVL_5, MCA_BASE_VAR_SCOPE_LOCAL, + &mca_mpool_memkind_component.default_memkind_bits); mca_mpool_memkind_component.priority = 10; (void) mca_base_component_var_register(&mca_mpool_memkind_component.super.mpool_version, @@ -135,8 +189,8 @@ static int mca_mpool_memkind_register(void) */ static int mca_mpool_memkind_open (void) { - memkind_t default_kind; int rc; + mca_mpool_memkind_module_le_t *item = NULL; if (opal_mpool_memkind_verbose != 0) { mca_mpool_memkind_component.output = opal_output_open(NULL); @@ -144,27 +198,36 @@ static int mca_mpool_memkind_open (void) mca_mpool_memkind_component.output = -1; } - rc = memkind_get_kind_by_partition (mca_mpool_memkind_component.default_partition, - &default_kind); - if (0 != rc) { + OBJ_CONSTRUCT(&mca_mpool_memkind_component.module_list, opal_list_t); + + rc = memkind_create_kind(mca_mpool_memkind_component.default_type, + mca_mpool_memkind_component.default_policy, + mca_mpool_memkind_component.default_memkind_bits, + &mca_mpool_memkind_component.default_kind); + if (MEMKIND_SUCCESS != rc) { + opal_output_verbose (MCA_BASE_VERBOSE_WARN, opal_mpool_base_framework.framework_output, + "memkind_create_kind default returned %d", rc); return OPAL_ERR_NOT_AVAILABLE; } - if (memkind_check_available (default_kind)) { - char *kind_string; + item = OBJ_NEW(mca_mpool_memkind_module_le_t); - mca_mpool_memkind_enum->string_from_value (mca_mpool_memkind_enum, - mca_mpool_memkind_component.default_partition, - &kind_string); - opal_output_verbose (MCA_BASE_VERBOSE_WARN, mca_mpool_memkind_component.output, - "default kind %s not available", kind_string); - free (kind_string); - return OPAL_ERR_NOT_AVAILABLE; + item->module.type = mca_mpool_memkind_component.default_type; + item->module.policy = mca_mpool_memkind_component.default_policy; + item->module.memkind_bits = mca_mpool_memkind_component.default_memkind_bits; + item->module.kind = mca_mpool_memkind_component.default_kind; + /* + * ufff, magic mask - see memkind.h in the memkind package + */ + if (MEMKIND_MASK_PAGE_SIZE_2MB == (item->module.memkind_bits & 0x7F)) { + item->module.page_size = 2097152; + } else { + item->module.page_size = 4096; } - for (int i = 0 ; i < MEMKIND_NUM_BASE_KIND ; ++i) { - mca_mpool_memkind_module_init (mca_mpool_memkind_component.modules + i, i); - } + opal_list_append(&mca_mpool_memkind_component.module_list, + (opal_list_item_t *)item); + return OPAL_SUCCESS; } @@ -174,9 +237,21 @@ static int mca_mpool_memkind_close(void) opal_output_close (mca_mpool_memkind_component.output); mca_mpool_memkind_component.output = -1; - if (mca_mpool_memkind_enum) { - OBJ_RELEASE(mca_mpool_memkind_enum); - mca_mpool_memkind_enum = NULL; + OBJ_DESTRUCT(&mca_mpool_memkind_component.module_list); + + if (mca_mpool_memkind_policy_enum) { + OBJ_RELEASE(mca_mpool_memkind_policy_enum); + mca_mpool_memkind_policy_enum = NULL; + } + + if (mca_mpool_memkind_type_enum) { + OBJ_RELEASE(mca_mpool_memkind_type_enum); + mca_mpool_memkind_type_enum = NULL; + } + + if (mca_mpool_memkind_kind_bits_enum) { + OBJ_RELEASE(mca_mpool_memkind_kind_bits_enum); + mca_mpool_memkind_kind_bits_enum = NULL; } return OPAL_SUCCESS; @@ -186,12 +261,15 @@ static int mca_mpool_memkind_query (const char *hints, int *priority_out, mca_mpool_base_module_t **module) { int my_priority = mca_mpool_memkind_component.priority; - char **hint_array, *partition_name; - int partition = -1, rc; - - if (module) { - *module = &mca_mpool_memkind_component.modules[mca_mpool_memkind_component.default_partition].super; - } + char **hint_array; + char *tmp, *key, *value = NULL; + int rc; + memkind_memtype_t type = mca_mpool_memkind_component.default_type; + memkind_policy_t policy = mca_mpool_memkind_component.default_policy; + memkind_bits_t memkind_bits = mca_mpool_memkind_component.default_memkind_bits; + mca_mpool_memkind_module_le_t *item = NULL; + mca_mpool_base_module_t *found_module = NULL; + memkind_t kind; if (NULL == hints) { if (priority_out) { @@ -209,7 +287,6 @@ static int mca_mpool_memkind_query (const char *hints, int *priority_out, } for (int i = 0 ; hint_array[i] ; ++i) { - char *tmp, *key, *value; key = hint_array[i]; tmp = strchr (key, '='); @@ -218,6 +295,11 @@ static int mca_mpool_memkind_query (const char *hints, int *priority_out, value = tmp + 1; } + /* + * TODO: may want to emit a warning + */ + if (value == NULL) break; + if (0 == strcasecmp (key, "mpool")) { if (0 == strcasecmp (value, "memkind")) { /* specifically selected */ @@ -229,37 +311,90 @@ static int mca_mpool_memkind_query (const char *hints, int *priority_out, } return OPAL_SUCCESS; } - } else if (0 == strcasecmp (key, "partition")) { - rc = mca_mpool_memkind_enum->value_from_string (mca_mpool_memkind_enum, - value, &partition); + } else if (0 == strcasecmp (key, "policy")) { + + rc = mca_mpool_memkind_policy_enum->value_from_string (mca_mpool_memkind_policy_enum, + value, (int *)&policy); if (OPAL_SUCCESS != rc) { - opal_output_verbose (MCA_BASE_VERBOSE_WARN, mca_mpool_memkind_component.output, - "invalid partition %s specified", value); + opal_output_verbose (MCA_BASE_VERBOSE_WARN, opal_mpool_base_framework.framework_output, + "invalid memkind policy %s specified", value); } - partition_name = value; + } else if (0 == strcasecmp (key, "type")) { + + rc = mca_mpool_memkind_type_enum->value_from_string (mca_mpool_memkind_type_enum, + value, (int *)&type); + if (OPAL_SUCCESS != rc) { + opal_output_verbose (MCA_BASE_VERBOSE_WARN, opal_mpool_base_framework.framework_output, + "invalid memkind type %s specified", value); + } + + } else if (0 == strcasecmp (key, "kind_bits")) { + + rc = mca_mpool_memkind_kind_bits_enum->value_from_string (mca_mpool_memkind_kind_bits_enum, + value, (int *)&memkind_bits); + if (OPAL_SUCCESS != rc) { + opal_output_verbose (MCA_BASE_VERBOSE_WARN, opal_mpool_base_framework.framework_output, + "invalid memkind kind_bits %s specified", value); + } } } - if (-1 != partition) { - memkind_t kind; + /* + * now look for an existing module with matching policy, type, memkind bits + */ - my_priority = 0; + OPAL_LIST_FOREACH(item, &mca_mpool_memkind_component.module_list, + mca_mpool_memkind_module_le_t) { + if ((item->module.type == type) && + (item->module.policy == policy) && + (item->module.memkind_bits = memkind_bits)) { + found_module = &item->module.super; + break; + } + } - if (!memkind_get_kind_by_partition (partition, &kind)) { - if (memkind_check_available (kind)) { - opal_output_verbose (MCA_BASE_VERBOSE_WARN, mca_mpool_memkind_component.output, - "kind %s not available", partition_name); + /* + * didn't find a matching module, try to create one + */ + + if (NULL == found_module) { + rc = memkind_create_kind(type, policy, memkind_bits, &kind); + if (MEMKIND_SUCCESS == rc) { + + item = OBJ_NEW(mca_mpool_memkind_module_le_t); + + item->module.type = type; + item->module.policy = policy; + item->module.memkind_bits = memkind_bits; + item->module.kind = kind; + + if (MEMKIND_MASK_PAGE_SIZE_2MB == item->module.memkind_bits) { + item->module.page_size = 2097152; } else { - my_priority = 100; + item->module.page_size = 4096; } - } - if (module) { - *module = &mca_mpool_memkind_component.modules[partition].super; + mca_mpool_memkind_module_init(&item->module); + + opal_list_append(&mca_mpool_memkind_component.module_list, + (opal_list_item_t *)item); + found_module = &item->module.super; + + } else { + opal_output_verbose (MCA_BASE_VERBOSE_WARN, opal_mpool_base_framework.framework_output, + "memkind_create_kind returned %d", rc); + if (priority_out) { + *priority_out = 0; + } + return OPAL_SUCCESS; } } + if ((found_module) && (NULL != module)) { + *module = found_module; + } + opal_argv_free (hint_array); if (priority_out) { diff --git a/opal/mca/mpool/memkind/mpool_memkind_module.c b/opal/mca/mpool/memkind/mpool_memkind_module.c index c61d379e3b..d53f80a27d 100644 --- a/opal/mca/mpool/memkind/mpool_memkind_module.c +++ b/opal/mca/mpool/memkind/mpool_memkind_module.c @@ -11,7 +11,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2009-2018 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2011-2015 Los Alamos National Security, LLC. All rights + * Copyright (c) 2011-2018 Los Alamos National Security, LLC. All rights * reserved. * Copyright (c) 2011-2014 NVIDIA Corporation. All rights reserved. * $COPYRIGHT$ @@ -23,32 +23,25 @@ #include "opal_config.h" #include <string.h> -#include "opal/mca/mpool/memkind/mpool_memkind.h" +#include "mpool_memkind.h" #ifdef HAVE_UNISTD_H #include <unistd.h> #endif #include "opal/mca/mpool/base/base.h" -size_t partition_page_sizes[MEMKIND_NUM_BASE_KIND] = { - 4096, 4096, 2097152, 4096, 2097152, 2097152, - 1073741824, 1073741824, 1073741824, 4096, 4096, -}; - /* * Initializes the mpool module. */ -void mca_mpool_memkind_module_init(mca_mpool_memkind_module_t *mpool, int partition) + +void mca_mpool_memkind_module_init(mca_mpool_memkind_module_t *mpool) { mpool->super.mpool_component = &mca_mpool_memkind_component.super; mpool->super.mpool_alloc = mca_mpool_memkind_alloc; mpool->super.mpool_realloc = mca_mpool_memkind_realloc; mpool->super.mpool_free = mca_mpool_memkind_free; mpool->super.flags = MCA_MPOOL_FLAGS_MPI_ALLOC_MEM; - memkind_get_kind_by_partition (partition, &mpool->kind); - mpool->page_size = partition_page_sizes[partition]; } - void* mca_mpool_memkind_alloc( mca_mpool_base_module_t* mpool, size_t size, diff --git a/test/Makefile.am b/test/Makefile.am index 4ed2525484..9982b94530 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -22,7 +22,7 @@ # # support needs to be first for dependencies -SUBDIRS = support asm class threads datatype util dss +SUBDIRS = support asm class threads datatype util dss mpool if PROJECT_OMPI SUBDIRS += monitoring endif diff --git a/test/mpool/Makefile.am b/test/mpool/Makefile.am new file mode 100644 index 0000000000..620ed8c9a5 --- /dev/null +++ b/test/mpool/Makefile.am @@ -0,0 +1,21 @@ +# Copyright (c) 2018 Los Alamos National Security, LLC. All rights reserved. +# +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +TESTS = mpool_memkind + +check_PROGRAMS = $(TESTS) $(MPI_CHECKS) + +mpool_memkind_SOURCES = mpool_memkind.c + +LDFLAGS = $(OPAL_PKG_CONFIG_LDFLAGS) +LDADD = $(top_builddir)/opal/lib@OPAL_LIB_PREFIX@open-pal.la + +distclean: + rm -rf *.dSYM .deps .libs *.log *.o *.trs $(check_PROGRAMS) Makefile + diff --git a/test/mpool/mpool_memkind.c b/test/mpool/mpool_memkind.c new file mode 100644 index 0000000000..bae81fd3b5 --- /dev/null +++ b/test/mpool/mpool_memkind.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana + * University Research and Technology + * Corporation. All rights reserved. + * Copyright (c) 2004-2005 The University of Tennessee and The University + * of Tennessee Research Foundation. All rights + * reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 2016 Research Organization for Information Science + * and Technology (RIST). All rights reserved. + * Copyright (c) 2018 Los Alamos National Security, LLC. All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +/* + * only do this test if we have built with memkind support + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "opal_config.h" +#ifdef HAVE_MEMKIND_H +#include "opal/constants.h" +#include "opal/mca/mpool/mpool.h" +#include "opal/include/opal/frameworks.h" +#include "opal/runtime/opal.h" + +#define SIZE (2 * 1024 * 1024) + +const char *memory_types[] = { + "memkind_default", + "memkind_hbw", + NULL +}; + +const char *memory_policy[] = { + "mempolicy_bind_local", + "mempolicy_bind_all", + "mempolicy_perferred_local", + "mempolicy_interleave_local", + "mempolicy_interleave_all", + NULL +}; + +const char *memory_kind_bits[] = { + "memkind_mask_page_size_4KB", + "memkind_mask_page_size_2MB", + NULL +}; + +int main (int argc, char* argv[]) +{ + int ret = 0; + void *ptr = NULL; + char *error = NULL; + char **mp_ptr = NULL; + char **mt_ptr = NULL; + char **mk_ptr = NULL; + const char mpool_hints[] = "mpool=memkind"; + char hints[1024]; + + opal_init_util(&argc, &argv); + + if (opal_frameworks == NULL){ + error = "opal frameworks is NULL"; + goto error; + } + + if (OPAL_SUCCESS != (ret = mca_base_framework_open(&opal_allocator_base_framework, 0))) { + error = "mca_allocator_base_open() failed"; + goto error; + } + + if (OPAL_SUCCESS != (ret = mca_base_framework_open(&opal_mpool_base_framework, 0))) { + error = "mca_mpool_base_open() failed"; + goto error; + } + + /* + * first try basic allocation + */ + + ptr = mca_mpool_base_alloc(SIZE, NULL, mpool_hints); + if (NULL == ptr) { + error = "mca_mpool_base_alloc() failed"; + goto error; + } + + if (OPAL_SUCCESS != mca_mpool_base_free(ptr)) { + error = "mca_mpool_base_free() failed"; + goto error; + } + + /* + * now try policies + */ + + mp_ptr = (char **)memory_policy; + while (NULL != *mp_ptr) { + + mt_ptr = (char **)memory_types; + while (NULL != *mt_ptr) { + + mk_ptr = (char **)memory_kind_bits; + while (NULL != *mk_ptr) { + snprintf(hints, sizeof(hints), "%s,policy=%s,type=%s,kind=%s", + mpool_hints, *mp_ptr, *mt_ptr, *mk_ptr); + ptr = mca_mpool_base_alloc(SIZE, NULL, hints); + if (NULL == ptr) { + error = "mca_mpool_base_alloc() failed"; + goto error; + } + + if (OPAL_SUCCESS != mca_mpool_base_free(ptr)) { + error = "mca_mpool_base_free() failed"; + goto error; + } + mk_ptr++; + } + mt_ptr++; + } + mp_ptr++; + } + + if (OPAL_SUCCESS != (ret = mca_base_framework_close(&opal_mpool_base_framework))) { + error = "mca_mpool_base_close() failed"; + goto error; + } + + if (OPAL_SUCCESS != (ret = mca_base_framework_close(&opal_allocator_base_framework))) { + error = "mca_mpool_base_close() failed"; + goto error; + } + + opal_finalize(); + +error: + if (NULL != error) { + fprintf(stderr, "mpool/memkind test failed %s\n", error); + ret = -1; + } else { + fprintf(stderr, "mpool/memkind test passed\n"); + } + + return ret; +} +#else +int main (int argc, char* argv[]) +{ + return 77; +} +#endif /* HAVE_MEMKIND_H */