root/opal/mca/mpool/memkind/mpool_memkind_component.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mca_mpool_memkind_module_le_destroy
  2. mca_mpool_memkind_register
  3. mca_mpool_memkind_open
  4. mca_mpool_memkind_close
  5. mca_mpool_memkind_query

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2010 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2006 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2007-2009 Sun Microsystems, Inc.  All rights reserved.
  14  * Copyright (c) 2008-2009 Cisco Systems, Inc.  All rights reserved.
  15  * Copyright (c) 2010-2018 Los Alamos National Security, LLC. All rights
  16  *                         reserved.
  17  * Copyright (c) 2014      NVIDIA Corporation.  All rights reserved.
  18  * Copyright (c) 2017-2018 Research Organization for Information Science
  19  *                         and Technology (RIST). All rights reserved.
  20  * $COPYRIGHT$
  21  *
  22  * Additional copyrights may follow
  23  *
  24  * $HEADER$
  25  */
  26 
  27 #include "opal_config.h"
  28 #ifdef HAVE_UNISTD_H
  29 #include <unistd.h>
  30 #endif  /* HAVE_UNISTD_H*/
  31 #ifdef HAVE_STDLIB_H
  32 #include <stdlib.h>
  33 #endif  /* HAVE_STDLIB_H */
  34 #include <errno.h>
  35 #include <memkind.h>
  36 #include "opal/mca/base/base.h"
  37 #include "opal/mca/allocator/base/base.h"
  38 #include "opal/mca/mpool/base/base.h"
  39 #include "opal/util/argv.h"
  40 #include "mpool_memkind.h"
  41 
  42 
  43 /*
  44  * Local functions
  45  */
  46 
  47 static int
  48 mca_mpool_memkind_register(void);
  49 
  50 static int
  51 mca_mpool_memkind_open(void);
  52 
  53 static int
  54 mca_mpool_memkind_close(void);
  55 
  56 static int mca_mpool_memkind_query (const char *hints, int *priority,
  57                                     mca_mpool_base_module_t **module);
  58 
  59 mca_mpool_memkind_component_t mca_mpool_memkind_component = {
  60     {
  61         /* First, the mca_base_component_t struct containing meta
  62          information about the component itself */
  63         .mpool_version = {
  64             MCA_MPOOL_BASE_VERSION_3_0_0,
  65             "memkind", /* MCA component name */
  66              MCA_BASE_MAKE_VERSION(component, OPAL_MAJOR_VERSION, OPAL_MINOR_VERSION,
  67                                    OPAL_RELEASE_VERSION),
  68             .mca_open_component = mca_mpool_memkind_open,
  69             .mca_close_component = mca_mpool_memkind_close,
  70             .mca_register_component_params = mca_mpool_memkind_register
  71         },
  72         .mpool_data = {
  73             /* The component is checkpoint ready */
  74             MCA_BASE_METADATA_PARAM_CHECKPOINT
  75         },
  76 
  77         .mpool_query = mca_mpool_memkind_query,
  78     }
  79 };
  80 
  81 static void mca_mpool_memkind_module_le_destroy(mca_mpool_memkind_module_le_t *elem)
  82 {
  83     if (NULL != elem->module.kind) {
  84         memkind_destroy_kind(elem->module.kind);
  85     }
  86 }
  87 
  88 OBJ_CLASS_INSTANCE(mca_mpool_memkind_module_le_t,
  89                    opal_list_item_t,
  90                    NULL,
  91                    mca_mpool_memkind_module_le_destroy);
  92 
  93 static mca_base_var_enum_value_t memory_types[] = {
  94   {.value = MEMKIND_MEMTYPE_DEFAULT, .string = "memkind_default"},
  95   {.value = MEMKIND_MEMTYPE_HIGH_BANDWIDTH, .string = "memkind_hbw"},
  96   {.string = NULL},
  97 };
  98 
  99 static mca_base_var_enum_value_t memory_policy[] = {
 100   {.value = MEMKIND_POLICY_BIND_LOCAL, .string = "mempolicy_bind_local"},
 101   {.value = MEMKIND_POLICY_BIND_ALL, .string = "mempolicy_bind_all"},
 102   {.value = MEMKIND_POLICY_PREFERRED_LOCAL, .string = "mempolicy_perferred_local"},
 103   {.value = MEMKIND_POLICY_INTERLEAVE_LOCAL, .string = "mempolicy_interleave_local"},
 104   {.value = MEMKIND_POLICY_INTERLEAVE_ALL, .string = "mempolicy_interleave_all"},
 105   {.string = NULL},
 106 };
 107 
 108 static mca_base_var_enum_value_t memory_kind_bits[] = {
 109   {.value = 0, .string = "memkind_mask_page_size_4KB"},
 110   {.value = MEMKIND_MASK_PAGE_SIZE_2MB, .string = "memkind_mask_page_size_2MB"},
 111   {.string = NULL},
 112 };
 113 
 114 static mca_base_var_enum_t *mca_mpool_memkind_policy_enum = NULL;
 115 static mca_base_var_enum_t *mca_mpool_memkind_type_enum = NULL;
 116 static mca_base_var_enum_t *mca_mpool_memkind_kind_bits_enum = NULL;
 117 
 118 static int opal_mpool_memkind_verbose;
 119 static int mca_mpool_memkind_register(void)
 120 {
 121     int rc;
 122 
 123     /* register MEMKIND component parameters */
 124 
 125     mca_mpool_memkind_component.default_type = memory_types[0].value;
 126 
 127     rc = mca_base_var_enum_create ("memkind memory types", memory_types,
 128                                    &mca_mpool_memkind_type_enum);
 129     if (OPAL_SUCCESS != rc) {
 130         return rc;
 131     }
 132 
 133     (void) mca_base_component_var_register(&mca_mpool_memkind_component.super.mpool_version,
 134                                            "default_type", "Default memkind type to use",
 135                                            MCA_BASE_VAR_TYPE_INT, mca_mpool_memkind_type_enum, 0, 0,
 136                                            OPAL_INFO_LVL_5, MCA_BASE_VAR_SCOPE_LOCAL,
 137                                            &mca_mpool_memkind_component.default_type);
 138 
 139     /*
 140      * see memkind source to understand the 2 
 141      */
 142     mca_mpool_memkind_component.default_policy = memory_policy[2].value;
 143 
 144     rc = mca_base_var_enum_create ("memkind memory policy", memory_policy, 
 145                                    &mca_mpool_memkind_policy_enum);
 146     if (OPAL_SUCCESS != rc) {
 147         return rc;
 148     }
 149 
 150     (void) mca_base_component_var_register(&mca_mpool_memkind_component.super.mpool_version,
 151                                            "default_policy", "Default memkind policy to use",
 152                                            MCA_BASE_VAR_TYPE_INT, mca_mpool_memkind_policy_enum, 0, 0,
 153                                            OPAL_INFO_LVL_5, MCA_BASE_VAR_SCOPE_LOCAL,
 154                                            &mca_mpool_memkind_component.default_policy);
 155 
 156     mca_mpool_memkind_component.default_memkind_bits = memory_kind_bits[0].value;
 157 
 158     rc = mca_base_var_enum_create ("memkind memory bits", memory_kind_bits, 
 159                                    &mca_mpool_memkind_kind_bits_enum);
 160     if (OPAL_SUCCESS != rc) {
 161         return rc;
 162     }
 163 
 164     (void) mca_base_component_var_register(&mca_mpool_memkind_component.super.mpool_version,
 165                                            "default_bits", "Default memkind bits to use",
 166                                            MCA_BASE_VAR_TYPE_INT, mca_mpool_memkind_kind_bits_enum, 0, 0,
 167                                            OPAL_INFO_LVL_5, MCA_BASE_VAR_SCOPE_LOCAL,
 168                                            &mca_mpool_memkind_component.default_memkind_bits);
 169 
 170     mca_mpool_memkind_component.priority = 10;
 171     (void) mca_base_component_var_register(&mca_mpool_memkind_component.super.mpool_version,
 172                                            "priority", "Default priority of the memkind component",
 173                                            MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
 174                                            OPAL_INFO_LVL_5, MCA_BASE_VAR_SCOPE_LOCAL,
 175                                            &mca_mpool_memkind_component.priority);
 176 
 177     opal_mpool_memkind_verbose = 0;
 178     (void) mca_base_component_var_register(&mca_mpool_memkind_component.super.mpool_version,
 179                                            "verbose", "Verbosity of the memkind mpool component",
 180                                            MCA_BASE_VAR_TYPE_INT, &mca_base_var_enum_verbose, 0, 0,
 181                                            OPAL_INFO_LVL_9, MCA_BASE_VAR_SCOPE_LOCAL,
 182                                            &opal_mpool_memkind_verbose);
 183 
 184     return OPAL_SUCCESS;
 185 }
 186 
 187 /**
 188   * component open/close/init function
 189   */
 190 static int mca_mpool_memkind_open (void)
 191 {
 192     int rc;
 193     mca_mpool_memkind_module_le_t *item = NULL;
 194 
 195     if (opal_mpool_memkind_verbose != 0) {
 196         mca_mpool_memkind_component.output = opal_output_open(NULL);
 197     } else {
 198         mca_mpool_memkind_component.output = -1;
 199     }
 200 
 201     OBJ_CONSTRUCT(&mca_mpool_memkind_component.module_list, opal_list_t);
 202 
 203     rc = memkind_create_kind(mca_mpool_memkind_component.default_type,
 204                              mca_mpool_memkind_component.default_policy,
 205                              mca_mpool_memkind_component.default_memkind_bits,
 206                              &mca_mpool_memkind_component.default_kind);
 207     if (MEMKIND_SUCCESS != rc) {
 208         opal_output_verbose (MCA_BASE_VERBOSE_WARN, opal_mpool_base_framework.framework_output,
 209                                      "memkind_create_kind default returned %d", rc);
 210         return OPAL_ERR_NOT_AVAILABLE;
 211     }
 212 
 213     item = OBJ_NEW(mca_mpool_memkind_module_le_t);
 214 
 215     item->module.type =  mca_mpool_memkind_component.default_type;
 216     item->module.policy =  mca_mpool_memkind_component.default_policy;
 217     item->module.memkind_bits = mca_mpool_memkind_component.default_memkind_bits;
 218     item->module.kind = mca_mpool_memkind_component.default_kind;
 219     /*
 220      * ufff, magic mask - see memkind.h in the memkind package
 221      */
 222     if (MEMKIND_MASK_PAGE_SIZE_2MB == (item->module.memkind_bits & 0x7F)) {
 223         item->module.page_size = 2097152;
 224     } else {
 225         item->module.page_size = 4096;
 226     }
 227 
 228     opal_list_append(&mca_mpool_memkind_component.module_list,
 229                     (opal_list_item_t *)item);
 230  
 231 
 232     return OPAL_SUCCESS;
 233 }
 234 
 235 static int mca_mpool_memkind_close(void)
 236 {
 237     opal_output_close (mca_mpool_memkind_component.output);
 238     mca_mpool_memkind_component.output = -1;
 239 
 240     OPAL_LIST_DESTRUCT(&mca_mpool_memkind_component.module_list);
 241 
 242     if (mca_mpool_memkind_policy_enum) {
 243         OBJ_RELEASE(mca_mpool_memkind_policy_enum);
 244         mca_mpool_memkind_policy_enum = NULL;
 245     }
 246 
 247     if (mca_mpool_memkind_type_enum) {
 248         OBJ_RELEASE(mca_mpool_memkind_type_enum);
 249         mca_mpool_memkind_type_enum = NULL;
 250     }
 251 
 252     if (mca_mpool_memkind_kind_bits_enum) {
 253         OBJ_RELEASE(mca_mpool_memkind_kind_bits_enum);
 254         mca_mpool_memkind_kind_bits_enum = NULL;
 255     }
 256 
 257     return OPAL_SUCCESS;
 258 }
 259 
 260 static int mca_mpool_memkind_query (const char *hints, int *priority_out,
 261                                     mca_mpool_base_module_t **module)
 262 {
 263     int my_priority = mca_mpool_memkind_component.priority;
 264     char **hint_array;
 265     char *tmp, *key, *value = NULL;
 266     int rc;
 267     memkind_memtype_t type = mca_mpool_memkind_component.default_type;
 268     memkind_policy_t  policy = mca_mpool_memkind_component.default_policy;
 269     memkind_bits_t    memkind_bits =  mca_mpool_memkind_component.default_memkind_bits;
 270     mca_mpool_memkind_module_le_t *item = NULL;
 271     mca_mpool_base_module_t *found_module = NULL;
 272     memkind_t kind;
 273 
 274     if (NULL == hints) {
 275         if (priority_out) {
 276             *priority_out = my_priority;
 277         }
 278         return OPAL_SUCCESS;
 279     }
 280 
 281     hint_array = opal_argv_split (hints, ',');
 282     if (NULL == hint_array) {
 283         if (priority_out) {
 284             *priority_out = my_priority;
 285         }
 286         return OPAL_SUCCESS;
 287     }
 288 
 289     for (int i = 0 ; hint_array[i] ; ++i) {
 290 
 291         key = hint_array[i];
 292         tmp = strchr (key, '=');
 293         if (tmp) {
 294             *tmp = '\0';
 295             value = tmp + 1;
 296         }
 297 
 298         /*
 299          * TODO: may want to emit a warning
 300          */
 301         if (value == NULL) break;
 302 
 303         if (0 == strcasecmp (key, "mpool")) {
 304             if (0 == strcasecmp (value, "memkind")) {
 305                 /* specifically selected */
 306 
 307                 my_priority = 100;
 308             } else {
 309                 if (priority_out) {
 310                     *priority_out = 0;
 311                 }
 312                 return OPAL_SUCCESS;
 313             }
 314         } else if (0 == strcasecmp (key, "policy")) {
 315 
 316             rc = mca_mpool_memkind_policy_enum->value_from_string (mca_mpool_memkind_policy_enum,
 317                                                                    value, (int *)&policy);
 318             if (OPAL_SUCCESS != rc) {
 319                 opal_output_verbose (MCA_BASE_VERBOSE_WARN, opal_mpool_base_framework.framework_output,
 320                                      "invalid memkind policy %s specified", value);
 321             }
 322 
 323         } else if (0 == strcasecmp (key, "type")) {
 324 
 325             rc = mca_mpool_memkind_type_enum->value_from_string (mca_mpool_memkind_type_enum,
 326                                                                  value, (int *)&type);
 327             if (OPAL_SUCCESS != rc) {
 328                 opal_output_verbose (MCA_BASE_VERBOSE_WARN, opal_mpool_base_framework.framework_output,
 329                                      "invalid memkind type %s specified", value);
 330             }
 331 
 332         } else if (0 == strcasecmp (key, "kind_bits")) {
 333 
 334             rc = mca_mpool_memkind_kind_bits_enum->value_from_string (mca_mpool_memkind_kind_bits_enum,
 335                                                                       value, (int *)&memkind_bits);
 336             if (OPAL_SUCCESS != rc) {
 337                 opal_output_verbose (MCA_BASE_VERBOSE_WARN, opal_mpool_base_framework.framework_output,
 338                                      "invalid memkind kind_bits %s specified", value);
 339             }
 340         }
 341     }
 342 
 343     /*
 344      * now look for an existing module with matching policy, type, memkind bits
 345      */
 346 
 347     OPAL_LIST_FOREACH(item, &mca_mpool_memkind_component.module_list, 
 348                       mca_mpool_memkind_module_le_t) {
 349         if ((item->module.type == type) &&
 350             (item->module.policy == policy) &&
 351             (item->module.memkind_bits = memkind_bits)) {
 352                found_module = &item->module.super;
 353                break;
 354         }
 355     } 
 356 
 357     /*
 358      * didn't find a matching module, try to create one 
 359      */
 360 
 361     if (NULL == found_module) {
 362         rc = memkind_create_kind(type, policy, memkind_bits, &kind);
 363         if (MEMKIND_SUCCESS == rc) {
 364 
 365             item = OBJ_NEW(mca_mpool_memkind_module_le_t);
 366 
 367             item->module.type =  type;
 368             item->module.policy =  policy;
 369             item->module.memkind_bits = memkind_bits;
 370             item->module.kind = kind;
 371 
 372             if (MEMKIND_MASK_PAGE_SIZE_2MB == item->module.memkind_bits) {
 373                 item->module.page_size = 2097152;
 374             } else {
 375                 item->module.page_size = 4096;
 376             }
 377 
 378             mca_mpool_memkind_module_init(&item->module);
 379 
 380             opal_list_append(&mca_mpool_memkind_component.module_list,
 381                             (opal_list_item_t *)item);
 382             found_module = &item->module.super;
 383 
 384         } else {
 385             opal_output_verbose (MCA_BASE_VERBOSE_WARN, opal_mpool_base_framework.framework_output,
 386                                      "memkind_create_kind returned %d", rc);
 387             if (priority_out) {
 388                 *priority_out = 0;
 389             }
 390             return OPAL_SUCCESS;
 391         }
 392     }
 393 
 394     if ((found_module) && (NULL != module)) {
 395         *module = found_module;
 396     }
 397 
 398     opal_argv_free (hint_array);
 399 
 400     if (priority_out) {
 401         *priority_out = my_priority;
 402     }
 403 
 404     return OPAL_SUCCESS;
 405 }

/* [<][>][^][v][top][bottom][index][help] */