root/ompi/mca/fcoll/base/fcoll_base_file_select.c

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

DEFINITIONS

This source file includes following definitions.
  1. mca_fcoll_base_file_select
  2. mca_fcoll_base_query_table

   1 /*
   2  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   3  *                         University Research and Technology
   4  *                         Corporation.  All rights reserved.
   5  * Copyright (c) 2004-2011 The University of Tennessee and The University
   6  *                         of Tennessee Research Foundation.  All rights
   7  *                         reserved.
   8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
   9  *                         University of Stuttgart.  All rights reserved.
  10  * Copyright (c) 2004-2005 The Regents of the University of California.
  11  *                         All rights reserved.
  12  * Copyright (c) 2008-2017 University of Houston. All rights reserved.
  13  * Copyright (c) 2018      Research Organization for Information Science
  14  *                         and Technology (RIST). All rights reserved.
  15  * $COPYRIGHT$
  16  *
  17  * Additional copyrights may follow
  18  *
  19  * $HEADER$
  20  */
  21 
  22 #include "ompi_config.h"
  23 
  24 #include <string.h>
  25 
  26 #include "opal/class/opal_list.h"
  27 #include "opal/util/argv.h"
  28 #include "ompi/mca/mca.h"
  29 #include "opal/mca/base/base.h"
  30 #include "ompi/mca/fcoll/fcoll.h"
  31 #include "ompi/mca/fcoll/base/base.h"
  32 #include "ompi/mca/common/ompio/common_ompio.h"
  33 
  34 /*
  35  * This structure is needed so that we can close the modules
  36  * which are not selected but were opened. mca_base_modules_close
  37  * which does this job for us requires a opal_list_t which contains
  38  * these modules
  39  */
  40 struct queried_module_t {
  41     opal_list_item_t super;
  42     mca_fcoll_base_component_t *om_component;
  43     mca_fcoll_base_module_t *om_module;
  44 };
  45 typedef struct queried_module_t queried_module_t;
  46 static OBJ_CLASS_INSTANCE(queried_module_t, opal_list_item_t, NULL, NULL);
  47 
  48 
  49 /*
  50  * Only one fcoll module can be attached to each file.
  51  *
  52  * This module calls the query funtion on all the components that were
  53  * detected by fcoll_base_open. This function is called on a
  54  * per-file basis. This function has the following function.
  55  *
  56  * 1. Iterate over the list of available_components
  57  * 2. Call the query function on each of these components.
  58  * 3. query function returns the structure containing pointers
  59  *    to its module and its priority
  60  * 4. Select the module with the highest priority
  61  * 5. Call the init function on the selected module so that it does the
  62  *    right setup for the file
  63  * 6. Call finalize on all the other modules which returned
  64  *    their module but were unfortunate to not get selected
  65  */
  66 
  67 int mca_fcoll_base_file_select (struct ompio_file_t *file,
  68                                 mca_base_component_t *preferred)
  69 {
  70     int priority;
  71     int best_priority;
  72     opal_list_item_t *item;
  73     mca_base_component_list_item_t *cli;
  74     mca_fcoll_base_component_t *component;
  75     mca_fcoll_base_component_t *best_component;
  76     mca_fcoll_base_module_t *module;
  77     opal_list_t queried;
  78     queried_module_t *om;
  79     int err = MPI_SUCCESS;
  80 
  81     /* Check and see if a preferred component was provided. If it was
  82      provided then it should be used (if possible) */
  83     if (NULL != preferred) {
  84 
  85         /* We have a preferred component. Check if it is available
  86            and if so, whether it wants to run */
  87          opal_output_verbose(10, ompi_fcoll_base_framework.framework_output,
  88                              "fcoll:base:file_select: Checking preferred component: %s",
  89                              preferred->mca_component_name);
  90 
  91          /* query the component for its priority and get its module
  92             structure. This is necessary to proceed */
  93 
  94          component = (mca_fcoll_base_component_t *)preferred;
  95          module = component->fcollm_file_query (file, &priority);
  96          if (NULL != module &&
  97              NULL != module->fcoll_module_init) {
  98 
  99              /* this query seems to have returned something legitimate
 100               * and we can now go ahead and initialize the
 101               * file with it * but first, the functions which
 102               * are null need to be filled in */
 103 
 104              /*fill_null_pointers (module);*/
 105              file->f_fcoll = module;
 106              file->f_fcoll_component = preferred;
 107 
 108              return module->fcoll_module_init(file);
 109          }
 110             /* His preferred component is present, but is unable to
 111              * run. This is not a good sign. We should try selecting
 112              * some other component We let it fall through and select
 113              * from the list of available components
 114              */
 115      } /*end of selection for preferred component */
 116 
 117     /*
 118      * We fall till here if one of the two things happened:
 119      * 1. The preferred component was provided but for some reason was
 120      * not able to be selected
 121      * 2. No preferred component was provided
 122      *
 123      * All we need to do is to go through the list of available
 124      * components and find the one which has the highest priority and
 125      * use that for this file
 126      */
 127 
 128     best_component = NULL;
 129     best_priority = -1;
 130     OBJ_CONSTRUCT(&queried, opal_list_t);
 131 
 132     OPAL_LIST_FOREACH(cli, &ompi_fcoll_base_framework.framework_components, mca_base_component_list_item_t) {
 133        component = (mca_fcoll_base_component_t *) cli->cli_component;
 134        opal_output_verbose(10, ompi_fcoll_base_framework.framework_output,
 135                            "select: initialising %s component %s",
 136                            component->fcollm_version.mca_type_name,
 137                            component->fcollm_version.mca_component_name);
 138 
 139        /*
 140         * we can call the query function only if there is a function :-)
 141         */
 142        if (NULL == component->fcollm_file_query) {
 143           opal_output_verbose(10, ompi_fcoll_base_framework.framework_output,
 144                              "select: no query, ignoring the component");
 145        } else {
 146            /*
 147             * call the query function and see what it returns
 148             */
 149            module = component->fcollm_file_query (file, &priority);
 150 
 151            if (NULL == module ||
 152                NULL == module->fcoll_module_init) {
 153                /*
 154                 * query did not return any action which can be used
 155                 */
 156                opal_output_verbose(10, ompi_fcoll_base_framework.framework_output,
 157                                   "select: query returned failure");
 158            } else {
 159                opal_output_verbose(10, ompi_fcoll_base_framework.framework_output,
 160                                   "select: query returned priority %d",
 161                                   priority);
 162                /*
 163                 * is this the best component we have found till now?
 164                 */
 165                if (priority > best_priority) {
 166                    best_priority = priority;
 167                    best_component = component;
 168                }
 169 
 170                om = OBJ_NEW(queried_module_t);
 171                /*
 172                 * check if we have run out of space
 173                 */
 174                if (NULL == om) {
 175                    OBJ_DESTRUCT(&queried);
 176                    return OMPI_ERR_OUT_OF_RESOURCE;
 177                }
 178                om->om_component = component;
 179                om->om_module = module;
 180                opal_list_append(&queried, (opal_list_item_t *)om);
 181            } /* end else of if (NULL == module) */
 182        } /* end else of if (NULL == component->fcollm_init) */
 183     } /* end for ... end of traversal */
 184 
 185     /*
 186      * Now we have alist of components which successfully returned
 187      * their module struct.  One of these components has the best
 188      * priority. The rest have to be comm_unqueried to counter the
 189      * effects of file_query'ing them. Finalize happens only on
 190      * components which should are initialized.
 191      */
 192     if (NULL == best_component) {
 193        /*
 194         * This typically means that there was no component which was
 195         * able to run properly this time. So, we need to abort
 196         */
 197         OBJ_DESTRUCT(&queried);
 198         return OMPI_ERROR;
 199     }
 200 
 201     /*
 202      * We now have a list of components which have successfully
 203      * returned their priorities from the query. We now have to
 204      * unquery() those components which have not been selected and
 205      * init() the component which was selected
 206      */
 207     while (NULL != (item = opal_list_remove_first(&queried))) {
 208         om = (queried_module_t *) item;
 209         if (om->om_component == best_component) {
 210            /*
 211             * this is the chosen component, we have to initialise the
 212             * module of this component.
 213             *
 214             * ANJU: a component might not have all the functions
 215             * defined.  Whereever a function pointer is null in the
 216             * module structure we need to fill it in with the base
 217             * structure function pointers. This is yet to be done
 218             */
 219 
 220             /*
 221              * We don return here coz we still need to go through and
 222              * elease the other objects
 223              */
 224 
 225             /*fill_null_pointers (om->om_module);*/
 226             file->f_fcoll = om->om_module;
 227             err = om->om_module->fcoll_module_init(file);
 228             file->f_fcoll_component = (mca_base_component_t *)best_component;
 229             /*
 230             printf ("SELECTED: %s\n", best_component->fcollm_version.mca_component_name);
 231             */
 232          } else {
 233             /*
 234              * this is not the "choosen one", finalize
 235              */
 236              if (NULL != om->om_component->fcollm_file_unquery) {
 237                 /* unquery the component only if they have some clean
 238                  * up job to do. Components which are queried but do
 239                  * not actually do anything typically do not have a
 240                  * unquery. Hence this check is necessary
 241                  */
 242                  (void) om->om_component->fcollm_file_unquery(file);
 243                  opal_output_verbose(10, ompi_fcoll_base_framework.framework_output,
 244                                      "select: component %s is not selected",
 245                                      om->om_component->fcollm_version.mca_component_name);
 246                } /* end if */
 247           } /* if not best component */
 248           OBJ_RELEASE(om);
 249     } /* traversing through the entire list */
 250 
 251     opal_output_verbose(10, ompi_fcoll_base_framework.framework_output,
 252                        "select: component %s selected",
 253                         best_component->fcollm_version.mca_component_name);
 254 
 255     OBJ_DESTRUCT(&queried);
 256 
 257     return err;
 258 }
 259 
 260 int mca_fcoll_base_query_table (struct ompio_file_t *file, char *name)
 261 {
 262     if (!strcmp (name, "individual")) {
 263         if ((int)file->f_cc_size >= file->f_bytes_per_agg &&
 264             file->f_cc_size >= file->f_stripe_size) {
 265             return 1;
 266         }
 267         if ( 2 >= (int)file->f_size ){
 268             return 1;
 269         }
 270     }
 271     if (!strcmp (name, "vulcan")) {
 272         if ( (LUSTRE != file->f_fstype)) {
 273             return 1;
 274         }
 275     }
 276     if (!strcmp (name, "dynamic")) {
 277         if ((int)file->f_cc_size < file->f_bytes_per_agg &&
 278             file->f_cc_size >= file->f_stripe_size) {
 279             return 1;
 280         }
 281     }
 282     if (!strcmp (name, "dynamic_gen2")) {
 283         if ( LUSTRE == file->f_fstype ) {
 284             return 1;
 285         }
 286     }
 287     if (!strcmp (name, "two_phase")) {
 288 #if OPAL_CUDA_SUPPORT
 289         /* do not use the two_phase component with CUDA
 290            buffers, since the data sieving causes trouble 
 291            on unmanaged GPU buffers.
 292         */
 293 #else
 294         if ((int)file->f_cc_size < file->f_bytes_per_agg &&
 295             (0 == file->f_stripe_size || file->f_cc_size < file->f_stripe_size) && 
 296             (LUSTRE != file->f_fstype) ) {
 297             return 1;
 298         }
 299 #endif
 300     }
 301     return 0;
 302 }

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