root/ompi/mca/pml/monitoring/pml_monitoring_component.c

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

DEFINITIONS

This source file includes following definitions.
  1. mca_pml_monitoring_add_procs
  2. mca_pml_monitoring_del_procs
  3. mca_pml_monitoring_dump
  4. mca_pml_monitoring_enable
  5. mca_pml_monitoring_component_open
  6. mca_pml_monitoring_component_init
  7. mca_pml_monitoring_component_finish
  8. mca_pml_monitoring_component_register

   1 /*
   2  * Copyright (c) 2013-2016 The University of Tennessee and The University
   3  *                         of Tennessee Research Foundation.  All rights
   4  *                         reserved.
   5  * Copyright (c) 2013-2017 Inria.  All rights reserved.
   6  * Copyright (c) 2015      Bull SAS.  All rights reserved.
   7  * Copyright (c) 2015      Research Organization for Information Science
   8  *                         and Technology (RIST). All rights reserved.
   9  * $COPYRIGHT$
  10  *
  11  * Additional copyrights may follow
  12  *
  13  * $HEADER$
  14  */
  15 
  16 #include <ompi_config.h>
  17 #include "pml_monitoring.h"
  18 #include <ompi/constants.h>
  19 #include <ompi/mca/pml/base/base.h>
  20 #include <ompi/mca/common/monitoring/common_monitoring.h>
  21 #include <opal/mca/base/mca_base_component_repository.h>
  22 
  23 static int mca_pml_monitoring_active = 0;
  24 
  25 mca_pml_base_component_t pml_selected_component = {{0}};
  26 mca_pml_base_module_t pml_selected_module = {0};
  27 
  28 mca_pml_monitoring_module_t mca_pml_monitoring_module = {
  29     mca_pml_monitoring_add_procs,
  30     mca_pml_monitoring_del_procs,
  31     mca_pml_monitoring_enable,
  32     NULL,
  33     mca_pml_monitoring_add_comm,
  34     mca_pml_monitoring_del_comm,
  35     mca_pml_monitoring_irecv_init,
  36     mca_pml_monitoring_irecv,
  37     mca_pml_monitoring_recv,
  38     mca_pml_monitoring_isend_init,
  39     mca_pml_monitoring_isend,
  40     mca_pml_monitoring_send,
  41     mca_pml_monitoring_iprobe,
  42     mca_pml_monitoring_probe,
  43     mca_pml_monitoring_start,
  44     mca_pml_monitoring_improbe,
  45     mca_pml_monitoring_mprobe,
  46     mca_pml_monitoring_imrecv,
  47     mca_pml_monitoring_mrecv,
  48     mca_pml_monitoring_dump,
  49     NULL,
  50     65535,
  51     INT_MAX
  52 };
  53 
  54 /**
  55  * This PML monitors only the processes in the MPI_COMM_WORLD. As OMPI is now lazily
  56  * adding peers on the first call to add_procs we need to check how many processes
  57  * are in the MPI_COMM_WORLD to create the storage with the right size.
  58  */
  59 int mca_pml_monitoring_add_procs(struct ompi_proc_t **procs,
  60                                  size_t nprocs)
  61 {
  62     int ret = mca_common_monitoring_add_procs(procs, nprocs);
  63     if( OMPI_SUCCESS == ret )
  64         ret = pml_selected_module.pml_add_procs(procs, nprocs);
  65     return ret;
  66 }
  67 
  68 /**
  69  * Pass the information down the PML stack.
  70  */
  71 int mca_pml_monitoring_del_procs(struct ompi_proc_t **procs,
  72                                  size_t nprocs)
  73 {
  74     return pml_selected_module.pml_del_procs(procs, nprocs);
  75 }
  76 
  77 int mca_pml_monitoring_dump(struct ompi_communicator_t* comm,
  78                             int verbose)
  79 {
  80     return pml_selected_module.pml_dump(comm, verbose);
  81 }
  82 
  83 int mca_pml_monitoring_enable(bool enable)
  84 {
  85     return pml_selected_module.pml_enable(enable);
  86 }
  87 
  88 static int mca_pml_monitoring_component_open(void)
  89 {
  90     /* CF: What if we are the only PML available ?? */
  91     if( mca_common_monitoring_enabled ) {
  92         opal_pointer_array_add(&mca_pml_base_pml,
  93                                strdup(mca_pml_monitoring_component.pmlm_version.mca_component_name));
  94     }
  95     return OMPI_SUCCESS;
  96 }
  97 
  98 static mca_pml_base_module_t*
  99 mca_pml_monitoring_component_init(int* priority,
 100                                   bool enable_progress_threads,
 101                                   bool enable_mpi_threads)
 102 {
 103     if( (OMPI_SUCCESS == mca_common_monitoring_init()) &&
 104         mca_common_monitoring_enabled ) {
 105         *priority = 0;  /* I'm up but don't select me */
 106         return &mca_pml_monitoring_module;
 107     }
 108     return NULL;
 109 }
 110 
 111 static int mca_pml_monitoring_component_finish(void)
 112 {
 113     if( !mca_common_monitoring_enabled )
 114         return OMPI_SUCCESS;
 115     if( !mca_pml_monitoring_active ) {
 116         /* The monitoring component priority is always low to guarantee that the component
 117          * is never selected. Thus, the first time component_finish is called it is right
 118          * after the selection of the best PML was done, and the perfect moment to intercept
 119          * it. At this point we remove ourselves from ompi_pml_base_framework.framework_components
 120          * so that the component never gets closed and unloaded and it's VARs are safe for
 121          * the rest of the execution.
 122          */
 123         mca_pml_base_component_t *component = NULL;
 124         mca_base_component_list_item_t *cli = NULL;
 125         OPAL_LIST_FOREACH(cli, &ompi_pml_base_framework.framework_components, mca_base_component_list_item_t) {
 126             component = (mca_pml_base_component_t *) cli->cli_component;
 127             
 128             if( component == &mca_pml_monitoring_component ) {
 129                 opal_list_remove_item(&ompi_pml_base_framework.framework_components, (opal_list_item_t*)cli);
 130                 OBJ_RELEASE(cli);
 131                 break;
 132             }
 133         }
 134         /**
 135          * We are supposed to monitor the execution. Save the winner PML component and
 136          * module, and swap it with ourselves. Increase our refcount so that we are
 137          * not dlclose.
 138          */
 139         /* Save a copy of the selected PML */
 140         pml_selected_component = mca_pml_base_selected_component;
 141         pml_selected_module = mca_pml;
 142         /* Install our interception layer */
 143         mca_pml_base_selected_component = mca_pml_monitoring_component;
 144         mca_pml = mca_pml_monitoring_module;
 145 
 146         /* Restore some of the original values: progress, flags, tags and context id */
 147         mca_pml.pml_progress = pml_selected_module.pml_progress;
 148         mca_pml.pml_max_contextid = pml_selected_module.pml_max_contextid;
 149         mca_pml.pml_max_tag = pml_selected_module.pml_max_tag;
 150         /* Add MCA_PML_BASE_FLAG_REQUIRE_WORLD flag to ensure the hashtable is properly initialized */
 151         mca_pml.pml_flags = pml_selected_module.pml_flags | MCA_PML_BASE_FLAG_REQUIRE_WORLD;
 152 
 153         mca_pml_monitoring_active = 1;
 154     } else {
 155         /**
 156          * This is the second call to component_finalize, and the component is actively
 157          * intercepting the calls to the best PML. Time to stop and cleanly finalize ourself.
 158          */
 159 
 160         /* Restore the original PML */
 161         mca_pml_base_selected_component = pml_selected_component;
 162         mca_pml = pml_selected_module;
 163         /* Redirect the close call to the original PML */
 164         pml_selected_component.pmlm_finalize();
 165 
 166         /* Free internal data structure */
 167         mca_common_monitoring_finalize();
 168 
 169         /**
 170          * We are in the compoenent code itself, we need to prevent the dlloader from
 171          * removing the code. This will result in minimal memory leaks, but it is the only
 172          * way to remove most of the references to the component (including the *vars).
 173          */
 174         mca_base_component_repository_retain_component(mca_pml_monitoring_component.pmlm_version.mca_type_name,
 175                                                        mca_pml_monitoring_component.pmlm_version.mca_component_name);
 176         /* Release all memory and be gone. */
 177         mca_base_component_close((mca_base_component_t*)&mca_pml_monitoring_component,
 178                                  ompi_pml_base_framework.framework_output);
 179     }
 180     return OMPI_SUCCESS;
 181 }
 182 
 183 static int mca_pml_monitoring_component_register(void)
 184 {
 185     mca_common_monitoring_register(&mca_pml_monitoring_component);
 186     return OMPI_SUCCESS;
 187 }
 188 
 189 mca_pml_base_component_2_0_0_t mca_pml_monitoring_component = {
 190 
 191     /* First, the mca_base_component_t struct containing meta
 192        information about the component itself */
 193 
 194     .pmlm_version = {
 195         MCA_PML_BASE_VERSION_2_0_0,
 196 
 197         .mca_component_name = "monitoring", /* MCA component name */
 198         MCA_MONITORING_MAKE_VERSION,
 199         .mca_open_component = mca_pml_monitoring_component_open,  /* component open */
 200         .mca_close_component = NULL, /* component close */
 201         .mca_register_component_params = mca_pml_monitoring_component_register
 202     },
 203     .pmlm_data = {
 204         /* The component is checkpoint ready */
 205         MCA_BASE_METADATA_PARAM_CHECKPOINT
 206     },
 207 
 208     .pmlm_init = mca_pml_monitoring_component_init,  /* component init */
 209     .pmlm_finalize = mca_pml_monitoring_component_finish   /* component finalize */
 210 };
 211 

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