root/ompi/include/ompi/memchecker.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. memchecker_convertor_call
  2. memchecker_call
  3. memchecker_comm
  4. memchecker_request
  5. memchecker_status
  6. memchecker_datatype
  7. memchecker_message

   1 /*
   2  * Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
   3  *                         University of Stuttgart.  All rights reserved.
   4  * Copyright (c) 2010-2017 The University of Tennessee and The University
   5  *                         of Tennessee Research Foundation.  All rights
   6  *                         reserved.
   7  * Copyright (c) 2009      Oak Ridge National Labs.  All rights reserved.
   8  * Copyright (c) 2012-2013 Inria.  All rights reserved.
   9  * Copyright (c) 2014-2017 Research Organization for Information Science
  10  *                         and Technology (RIST). All rights reserved.
  11  * Copyright (c) 2014      Intel, Inc. All rights reserved.
  12  *
  13  * Copyright (c) 2016 Cisco Systems, Inc.  All rights reserved.
  14  * $COPYRIGHT$
  15  *
  16  * Additional copyrights may follow
  17  *
  18  * $HEADER$
  19  */
  20 
  21 
  22 #ifndef OMPI_MEMCHECKER_H
  23 #define OMPI_MEMCHECKER_H
  24 
  25 #include "ompi_config.h"
  26 
  27 #include "opal/datatype/opal_convertor.h"
  28 #include "opal/datatype/opal_datatype.h"
  29 #include "opal/datatype/opal_datatype_internal.h"
  30 
  31 #include "ompi/communicator/communicator.h"
  32 #include "ompi/group/group.h"
  33 #include "ompi/datatype/ompi_datatype.h"
  34 #include "ompi/request/request.h"
  35 #include "opal/mca/memchecker/base/base.h"
  36 
  37 
  38 #if OPAL_WANT_MEMCHECKER
  39 #  define MEMCHECKER(x) do {       \
  40             x;                     \
  41    } while(0)
  42 #else
  43 #  define MEMCHECKER(x)
  44 #endif /* OPAL_WANT_MEMCHECKER */
  45 
  46 
  47 static inline int memchecker_convertor_call (int (*f)(void *, size_t), opal_convertor_t* pConvertor)
  48 {
  49     if (!opal_memchecker_base_runindebugger() ||
  50         (0 == pConvertor->count) ) {
  51         return OMPI_SUCCESS;
  52     }
  53 
  54     if( OPAL_LIKELY(pConvertor->flags & CONVERTOR_NO_OP) ) {
  55         /*  We have a contiguous type. */
  56         f( (void *)pConvertor->pBaseBuf , pConvertor->local_size);
  57     } else {
  58         /* Now we got a noncontigous data. */
  59         uint32_t elem_pos = 0, i;
  60         ptrdiff_t  stack_disp  = 0;
  61         dt_elem_desc_t*  description = pConvertor->use_desc->desc;
  62         dt_elem_desc_t*  pElem       = &(description[elem_pos]);
  63         unsigned char   *source_base = pConvertor->pBaseBuf;
  64 
  65         if ( NULL != pConvertor->pDesc )
  66             stack_disp = pConvertor->pDesc->ub - pConvertor->pDesc->lb;
  67 
  68         for (i = 0; i < pConvertor->count; i++){
  69             while ( OPAL_DATATYPE_LOOP == pElem->elem.common.flags ) {
  70                 elem_pos++;
  71                 pElem = &(description[elem_pos]);
  72             }
  73 
  74             while( pElem->elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
  75                 /* now here we have a basic datatype */
  76                 f( (void *)(source_base + pElem->elem.disp), pElem->elem.count*pElem->elem.extent );
  77                 elem_pos++;       /* advance to the next data */
  78                 pElem = &(description[elem_pos]);
  79                 continue;
  80             }
  81 
  82             elem_pos = 0;
  83             pElem = &(description[elem_pos]);
  84             /* starting address of next stack. */
  85             source_base += stack_disp;
  86         }
  87     }
  88 
  89     return OMPI_SUCCESS;
  90 }
  91 
  92 
  93 /*
  94  * Set the corresponding memory area of count elements of type ty
  95  *
  96  */
  97 static inline int memchecker_call (int (*f)(void *, size_t), const void * addr,
  98                                    size_t count, struct ompi_datatype_t * datatype)
  99 {
 100     if (!opal_memchecker_base_runindebugger()) {
 101         return OMPI_SUCCESS;
 102     }
 103 
 104     if ((0 == count) || (0 == datatype->super.size)) {
 105         return OMPI_SUCCESS;
 106     }
 107 
 108     if( datatype->super.size == (size_t) (datatype->super.true_ub - datatype->super.true_lb) ) {
 109         /*  We have a contiguous type. */
 110         f( (void*)addr , datatype->super.size * count );
 111     } else {
 112         /* Now we got a noncontigous type. */
 113         uint32_t         elem_pos = 0, i;
 114         ptrdiff_t        stack_disp  = 0;
 115         dt_elem_desc_t*  description = datatype->super.opt_desc.desc;
 116         dt_elem_desc_t*  pElem       = &(description[elem_pos]);
 117         unsigned char   *source_base = (unsigned char *) addr;
 118 
 119         if ( NULL != datatype ) {
 120             stack_disp = datatype->super.ub - datatype->super.lb;
 121         }
 122 
 123         for (i = 0; i < count; i++) {
 124             while ( OPAL_DATATYPE_LOOP == pElem->elem.common.flags ) {
 125                 elem_pos++;
 126                 pElem = &(description[elem_pos]);
 127             }
 128 
 129             while( pElem->elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
 130                 /* now here we have a basic datatype */
 131                 f( (void *)(source_base + pElem->elem.disp), pElem->elem.count*pElem->elem.extent );
 132                 elem_pos++;       /* advance to the next data */
 133                 pElem = &(description[elem_pos]);
 134                 continue;
 135             }
 136 
 137             elem_pos = 0;
 138             pElem = &(description[elem_pos]);
 139             /* starting address of next stack. */
 140             source_base += stack_disp;
 141         }
 142     }
 143 
 144     return OMPI_SUCCESS;
 145 }
 146 
 147 
 148 
 149 /*
 150  * Flag: OMPI_WANT_MEMCHECKER_MPI_OBJECTS
 151  *
 152  * If set, definedness of Open MPI-internal objects is being checked.
 153  * To handle alignment, only the used members of structures are
 154  * being used -- therefore this depends on the corresponding
 155  * configure-flags.
 156  *
 157  * This is off by default, as this is rather expensive (for each member
 158  * the valgrind-magic is being inlined.
 159  * Only turn on, if You want to debug ompi-internal datastructures.
 160  */
 161 /*#define OMPI_WANT_MEMCHECKER_MPI_OBJECTS*/
 162 
 163 
 164 /*
 165  * Check every member of the communicator, whether their memory areas are defined.
 166  */
 167 #ifdef OMPI_WANT_MEMCHECKER_MPI_OBJECTS
 168 static inline int memchecker_comm(MPI_Comm comm)
 169 {
 170     if (!opal_memchecker_base_runindebugger()) {
 171         return OMPI_SUCCESS;
 172     }
 173 
 174     /*
 175      * We should not check underlying objects in this way -- either another opal/include/memchecker.h
 176      * However, let us assume, that underlying objects are initialized correctly
 177      */
 178 #if 0
 179     /* c_base */
 180     opal_memchecker_base_isdefined (&comm->c_base.obj_class, sizeof(opal_class_t *));
 181     opal_memchecker_base_isdefined ((void*)&comm->c_base.obj_reference_count, sizeof(volatile int32_t));
 182 #if OPAL_ENABLE_DEBUG
 183     opal_memchecker_base_isdefined (&comm->c_base.obj_magic_id, sizeof(opal_object_t));
 184     opal_memchecker_base_isdefined (&comm->c_base.cls_init_file_name, sizeof(const char *));
 185     opal_memchecker_base_isdefined (&comm->c_base.cls_init_lineno, sizeof(int));
 186 #endif
 187     /* c_lock */
 188     opal_memchecker_base_isdefined (&comm->c_lock.super.obj_class, sizeof(opal_class_t *));
 189     opal_memchecker_base_isdefined ((void*)&comm->c_lock.super.obj_reference_count, sizeof(volatile int32_t));
 190 #if OPAL_ENABLE_DEBUG
 191     opal_memchecker_base_isdefined (&comm->c_lock.super.obj_magic_id, sizeof(uint64_t));
 192     opal_memchecker_base_isdefined (&comm->c_lock.super.cls_init_file_name, sizeof(const char *));
 193     opal_memchecker_base_isdefined (&comm->c_lock.super.cls_init_lineno, sizeof(int));
 194 #endif
 195 /*
 196   opal_memchecker_base_isdefined (&comm->c_lock.m_lock_pthread.__m_reserved, sizeof(int));
 197   opal_memchecker_base_isdefined (&comm->c_lock.m_lock_pthread.__m_count, sizeof(int));
 198   opal_memchecker_base_isdefined (&comm->c_lock.m_lock_pthread.__m_owner, sizeof(_pthread_descr));
 199   opal_memchecker_base_isdefined (&comm->c_lock.m_lock_pthread.__m_kind, sizeof(int));
 200   opal_memchecker_base_isdefined (&comm->c_lock.m_lock_pthread.__m_lock.__status, sizeof(long int));
 201   opal_memchecker_base_isdefined (&comm->c_lock.m_lock_pthread.__m_lock.__spinlock, sizeof(int));
 202 */
 203     /*
 204      * The storage of a union has the size of the initialized member.
 205      * Here we check the whole union.
 206      */
 207     opal_memchecker_base_isdefined (&comm->c_lock.m_lock_atomic, sizeof(opal_atomic_lock_t));
 208 #endif /* 0 */
 209     opal_memchecker_base_isdefined (&comm->c_name, MPI_MAX_OBJECT_NAME);
 210     opal_memchecker_base_isdefined (&comm->c_my_rank, sizeof(int));
 211     opal_memchecker_base_isdefined (&comm->c_flags, sizeof(uint32_t));
 212     opal_memchecker_base_isdefined (&comm->c_id_available, sizeof(int));
 213     opal_memchecker_base_isdefined (&comm->c_id_start_index, sizeof(int));
 214     opal_memchecker_base_isdefined (&comm->c_local_group, sizeof(ompi_group_t *));
 215     opal_memchecker_base_isdefined (&comm->c_remote_group, sizeof(ompi_group_t *));
 216     opal_memchecker_base_isdefined (&comm->c_keyhash, sizeof(struct opal_hash_table_t *));
 217     opal_memchecker_base_isdefined (&comm->c_cube_dim, sizeof(int));
 218     opal_memchecker_base_isdefined (&comm->c_topo, sizeof(const struct mca_topo_base_module_t *));
 219     opal_memchecker_base_isdefined (&comm->c_f_to_c_index, sizeof(int));
 220 #ifdef OMPI_WANT_PERUSE
 221     opal_memchecker_base_isdefined (&comm->c_peruse_handles, sizeof(struct ompi_peruse_handle_t **));
 222 #endif
 223     opal_memchecker_base_isdefined (&comm->error_handler, sizeof(ompi_errhandler_t *));
 224     opal_memchecker_base_isdefined (&comm->errhandler_type, sizeof(ompi_errhandler_type_t));
 225     opal_memchecker_base_isdefined (&comm->c_pml_comm, sizeof(struct mca_pml_comm_t *));
 226     /* c_coll */
 227     opal_memchecker_base_isdefined (&comm->c_coll->coll_module_init, sizeof(mca_coll_base_module_init_1_0_0_fn_t));
 228     opal_memchecker_base_isdefined (&comm->c_coll->coll_module_finalize, sizeof(mca_coll_base_module_finalize_fn_t));
 229     opal_memchecker_base_isdefined (&comm->c_coll->coll_allgather, sizeof(mca_coll_base_module_allgather_fn_t));
 230     opal_memchecker_base_isdefined (&comm->c_coll->coll_allgatherv, sizeof(mca_coll_base_module_allgatherv_fn_t));
 231     opal_memchecker_base_isdefined (&comm->c_coll->coll_allreduce, sizeof(mca_coll_base_module_allreduce_fn_t));
 232     opal_memchecker_base_isdefined (&comm->c_coll->coll_alltoall, sizeof(mca_coll_base_module_alltoall_fn_t));
 233     opal_memchecker_base_isdefined (&comm->c_coll->coll_alltoallv, sizeof(mca_coll_base_module_alltoallv_fn_t));
 234     opal_memchecker_base_isdefined (&comm->c_coll->coll_alltoallw, sizeof(mca_coll_base_module_alltoallw_fn_t));
 235     opal_memchecker_base_isdefined (&comm->c_coll->coll_barrier, sizeof(mca_coll_base_module_barrier_fn_t));
 236     opal_memchecker_base_isdefined (&comm->c_coll->coll_bcast, sizeof(mca_coll_base_module_bcast_fn_t));
 237     opal_memchecker_base_isdefined (&comm->c_coll->coll_exscan, sizeof(mca_coll_base_module_exscan_fn_t));
 238     opal_memchecker_base_isdefined (&comm->c_coll->coll_gather, sizeof(mca_coll_base_module_gather_fn_t));
 239     opal_memchecker_base_isdefined (&comm->c_coll->coll_gatherv, sizeof(mca_coll_base_module_gatherv_fn_t));
 240     opal_memchecker_base_isdefined (&comm->c_coll->coll_reduce, sizeof(mca_coll_base_module_reduce_fn_t));
 241     opal_memchecker_base_isdefined (&comm->c_coll->coll_reduce_scatter, sizeof(mca_coll_base_module_reduce_scatter_fn_t));
 242     opal_memchecker_base_isdefined (&comm->c_coll->coll_scan, sizeof(mca_coll_base_module_scan_fn_t));
 243     opal_memchecker_base_isdefined (&comm->c_coll->coll_scatter, sizeof(mca_coll_base_module_scatter_fn_t));
 244     opal_memchecker_base_isdefined (&comm->c_coll->coll_scatterv, sizeof(mca_coll_base_module_scatterv_fn_t));
 245 
 246     opal_memchecker_base_isdefined (&comm->c_coll_selected_component, sizeof(const mca_coll_base_component_2_0_0_t *));
 247     opal_memchecker_base_isdefined (&comm->c_coll_selected_module, sizeof(const mca_coll_base_module_1_0_0_t *));
 248     /* Somehow, this often shows up in petsc with comm_dup'ed communicators*/
 249     /* opal_memchecker_base_isdefined (&comm->c_coll_selected_data, sizeof(struct mca_coll_base_comm_t *)); */
 250     opal_memchecker_base_isdefined (&comm->c_coll_basic_module, sizeof(const mca_coll_base_module_1_0_0_t *));
 251     opal_memchecker_base_isdefined (&comm->c_coll_basic_data, sizeof(struct mca_coll_base_comm_t *));
 252 
 253     return OMPI_SUCCESS;
 254 }
 255 #else
 256 #define memchecker_comm(comm)
 257 #endif /* OMPI_WANT_MEMCHECKER_MPI_OBJECTS */
 258 
 259 
 260 /*
 261  * Check every member of the request, whether their memory areas are defined.
 262  */
 263 #ifdef OMPI_WANT_MEMCHECKER_MPI_OBJECTS
 264 static inline int memchecker_request(MPI_Request *request)
 265 {
 266     if (!opal_memchecker_base_runindebugger()) {
 267         return OMPI_SUCCESS;
 268     }
 269 
 270 #if 0
 271     opal_memchecker_base_isdefined (&(*request)->super.super.super.obj_class, sizeof(opal_class_t *));
 272     opal_memchecker_base_isdefined ((void*)&(*request)->super.super.super.obj_reference_count, sizeof(volatile int32_t));
 273 #if OPAL_ENABLE_DEBUG
 274     opal_memchecker_base_isdefined (&(*request)->super.super.super.obj_magic_id, sizeof(uint64_t));
 275     opal_memchecker_base_isdefined (&(*request)->super.super.super.cls_init_file_name, sizeof(const char *));
 276     opal_memchecker_base_isdefined (&(*request)->super.super.super.cls_init_lineno, sizeof(int));
 277 #endif
 278 
 279     opal_memchecker_base_isdefined ((void*)&(*request)->super.super.opal_list_next, sizeof(volatile struct opal_list_item_t *));
 280     opal_memchecker_base_isdefined ((void*)&(*request)->super.super.opal_list_prev, sizeof(volatile struct opal_list_item_t *));
 281 #if OPAL_ENABLE_DEBUG
 282     opal_memchecker_base_isdefined ((void*)&(*request)->super.super.opal_list_item_refcount, sizeof(volatile int32_t));
 283     opal_memchecker_base_isdefined ((void*)&(*request)->super.super.opal_list_item_belong_to, sizeof(volatile struct opal_list_t *));
 284 #endif
 285 /*    opal_memchecker_base_isdefined (&(*request)->super.user_data, sizeof(void *)); */
 286 #endif /* 0 */
 287     opal_memchecker_base_isdefined (&(*request)->req_type, sizeof(ompi_request_type_t));
 288     /* req_status */
 289 #if 0
 290     /* We do never initialize the req_status in the creation functions,
 291      * they are just used to transport values back up....
 292      */
 293     opal_memchecker_base_isdefined (&(*request)->req_status.MPI_SOURCE, sizeof(int));
 294     opal_memchecker_base_isdefined (&(*request)->req_status.MPI_TAG, sizeof(int));
 295     opal_memchecker_base_isdefined (&(*request)->req_status.MPI_ERROR, sizeof(int));
 296     opal_memchecker_base_isdefined (&(*request)->req_status._cancelled, sizeof(int));
 297     opal_memchecker_base_isdefined (&(*request)->req_status._ucount, sizeof(size_t));
 298 #endif
 299 
 300     opal_memchecker_base_isdefined ((void*)&(*request)->req_complete, sizeof(volatile _Bool));
 301     opal_memchecker_base_isdefined ((void*)&(*request)->req_state, sizeof(volatile ompi_request_state_t));
 302     opal_memchecker_base_isdefined (&(*request)->req_persistent, sizeof(_Bool));
 303     opal_memchecker_base_isdefined (&(*request)->req_f_to_c_index, sizeof(int));
 304     opal_memchecker_base_isdefined (&(*request)->req_free, sizeof(ompi_request_free_fn_t));
 305     opal_memchecker_base_isdefined (&(*request)->req_cancel, sizeof(ompi_request_cancel_fn_t));
 306     /* req_mpi_object */
 307     opal_memchecker_base_isdefined (&(*request)->req_mpi_object.comm, sizeof(struct ompi_communicator_t *));
 308     opal_memchecker_base_isdefined (&(*request)->req_mpi_object.file, sizeof(struct ompi_file_t *));
 309     opal_memchecker_base_isdefined (&(*request)->req_mpi_object.win, sizeof(struct ompi_win_t *));
 310 
 311     return OMPI_SUCCESS;
 312 }
 313 #else
 314 #define memchecker_request(request)
 315 #endif /* OMPI_WANT_MEMCHECKER_MPI_OBJECTS */
 316 
 317 
 318 /*
 319  * Check every member of the status, whether their memory areas are defined.
 320  */
 321 #ifdef OMPI_WANT_MEMCHECKER_MPI_OBJECTS
 322 static inline int memchecker_status(MPI_Status *status)
 323 {
 324     if (!opal_memchecker_base_runindebugger()) {
 325         return OMPI_SUCCESS;
 326     }
 327 
 328     opal_memchecker_base_isdefined (&status->MPI_SOURCE, sizeof(int));
 329     opal_memchecker_base_isdefined (&status->MPI_TAG, sizeof(int));
 330     opal_memchecker_base_isdefined (&status->MPI_ERROR, sizeof(int));
 331     opal_memchecker_base_isdefined (&status->_cancelled, sizeof(int));
 332     opal_memchecker_base_isdefined (&status->_ucount, sizeof(size_t));
 333 
 334     return OMPI_SUCCESS;
 335 }
 336 #else
 337 #define memchecker_status(status)
 338 #endif /* OMPI_WANT_MEMCHECKER_MPI_OBJECTS */
 339 
 340 
 341 /*
 342  * Check every member of the datatype, whether their memory areas are defined.
 343  */
 344 #ifdef OMPI_WANT_MEMCHECKER_MPI_OBJECTS
 345 static inline int memchecker_datatype(MPI_Datatype type)
 346 {
 347     if (!opal_memchecker_base_runindebugger()) {
 348         return OMPI_SUCCESS;
 349     }
 350 
 351     /* the data description in the opal_datatype_t super class */
 352     opal_memchecker_base_isdefined (&type->super.flags, sizeof(uint16_t));
 353     opal_memchecker_base_isdefined (&type->super.id, sizeof(uint16_t));
 354     opal_memchecker_base_isdefined (&type->super.bdt_used, sizeof(uint32_t));
 355     opal_memchecker_base_isdefined (&type->super.size, sizeof(size_t));
 356     opal_memchecker_base_isdefined (&type->super.true_lb, sizeof(ptrdiff_t));
 357     opal_memchecker_base_isdefined (&type->super.true_ub, sizeof(ptrdiff_t));
 358     opal_memchecker_base_isdefined (&type->super.lb, sizeof(ptrdiff_t));
 359     opal_memchecker_base_isdefined (&type->super.ub, sizeof(ptrdiff_t));
 360     opal_memchecker_base_isdefined (&type->super.align, sizeof(uint32_t));
 361     opal_memchecker_base_isdefined (&type->super.nbElems, sizeof(uint32_t));
 362     /* name... */
 363     opal_memchecker_base_isdefined (&type->super.desc.length, sizeof(opal_datatype_count_t));
 364     opal_memchecker_base_isdefined (&type->super.desc.used, sizeof(opal_datatype_count_t));
 365     opal_memchecker_base_isdefined (&type->super.desc.desc, sizeof(dt_elem_desc_t *));
 366     opal_memchecker_base_isdefined (&type->super.opt_desc.length, sizeof(opal_datatype_count_t));
 367     opal_memchecker_base_isdefined (&type->super.opt_desc.used, sizeof(opal_datatype_count_t));
 368     opal_memchecker_base_isdefined (&type->super.opt_desc.desc, sizeof(dt_elem_desc_t *));
 369     if( NULL != type->super.ptypes )
 370         opal_memchecker_base_isdefined (&type->super.ptypes, OPAL_DATATYPE_MAX_PREDEFINED * sizeof(size_t));
 371 
 372     opal_memchecker_base_isdefined (&type->id, sizeof(int32_t));
 373     opal_memchecker_base_isdefined (&type->d_f_to_c_index, sizeof(int32_t));
 374     opal_memchecker_base_isdefined (&type->d_keyhash, sizeof(opal_hash_table_t *));
 375     opal_memchecker_base_isdefined (&type->args, sizeof(void *));
 376     opal_memchecker_base_isdefined (&type->packed_description, sizeof(void *));
 377     opal_memchecker_base_isdefined (&type->name, MPI_MAX_OBJECT_NAME * sizeof(char));
 378 
 379     return OMPI_SUCCESS;
 380 }
 381 #else
 382 #define memchecker_datatype(type)
 383 #endif /* OMPI_WANT_MEMCHECKER_MPI_OBJECTS */
 384 
 385 /*
 386  * Check every member of the message, whether their memory areas are defined.
 387  */
 388 #ifdef OMPI_WANT_MEMCHECKER_MPI_OBJECTS
 389 static inline int memchecker_message(MPI_Message *message)
 390 {
 391     if (!opal_memchecker_base_runindebugger()) {
 392         return OMPI_SUCCESS;
 393     }
 394 
 395     opal_memchecker_base_isdefined (&message->m_f_to_c_index, sizeof(int));
 396     opal_memchecker_base_isdefined (&message->comm, sizeof(ompi_communicator_t *));
 397     opal_memchecker_base_isdefined (&message->req_ptr, sizeof(void *));
 398     opal_memchecker_base_isdefined (&message->peer, sizeof(int));
 399     opal_memchecker_base_isdefined (&message->count, sizeof(sizeof_t));
 400 
 401     return OMPI_SUCCESS;
 402 }
 403 #else
 404 #define memchecker_message(message)
 405 #endif /* OMPI_WANT_MEMCHECKER_MPI_OBJECTS */
 406 
 407 
 408 #endif /* OMPI_MEMCHECKER_H */
 409 

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