root/ompi/mpi/c/type_create_f90_real.c

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

DEFINITIONS

This source file includes following definitions.
  1. MPI_Type_create_f90_real

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2015 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) 2006-2009 Sun Microsystems, Inc.  All rights reserved.
  14  * Copyright (c) 2008-2018 Cisco Systems, Inc.  All rights reserved
  15  * Copyright (c) 2013      Los Alamos National Security, LLC.  All rights
  16  *                         reserved.
  17  * Copyright (c) 2015      Research Organization for Information Science
  18  *                         and Technology (RIST). All rights reserved.
  19  * Copyright (c) 2017      IBM Corporation.  All rights reserved.
  20  * Copyright (c) 2018      Amazon.com, Inc. or its affiliates.  All Rights reserved.
  21  * Copyright (c) 2018      FUJITSU LIMITED.  All rights reserved.
  22  * $COPYRIGHT$
  23  *
  24  * Additional copyrights may follow
  25  *
  26  * $HEADER$
  27  */
  28 
  29 #include "ompi_config.h"
  30 
  31 #include <float.h>
  32 
  33 #include "opal/util/printf.h"
  34 
  35 #include "ompi/mpi/c/bindings.h"
  36 #include "ompi/runtime/params.h"
  37 #include "ompi/communicator/communicator.h"
  38 #include "ompi/errhandler/errhandler.h"
  39 
  40 #if OMPI_BUILD_MPI_PROFILING
  41 #if OPAL_HAVE_WEAK_SYMBOLS
  42 #pragma weak MPI_Type_create_f90_real = PMPI_Type_create_f90_real
  43 #endif
  44 #define MPI_Type_create_f90_real PMPI_Type_create_f90_real
  45 #endif
  46 
  47 static const char FUNC_NAME[] = "MPI_Type_create_f90_real";
  48 
  49 
  50 int MPI_Type_create_f90_real(int p, int r, MPI_Datatype *newtype)
  51 {
  52     uint64_t key;
  53     int p_key, r_key;
  54     int sflt_dig = 3, sflt_max_10_exp = +5, sflt_min_10_exp = -4;
  55 
  56     OPAL_CR_NOOP_PROGRESS();
  57 
  58     if (MPI_PARAM_CHECK) {
  59         OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
  60 
  61         /* Note: These functions accept negative integers for the p and r
  62          * arguments.  This is because for the SELECTED_REAL_KIND,
  63          * negative numbers are equivalent to zero values.  See section
  64          * 13.14.95 of the Fortran 95 standard. */
  65 
  66         if ((MPI_UNDEFINED == p && MPI_UNDEFINED == r)) {
  67             return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME);
  68         }
  69     }
  70 
  71     /* if the user does not care about p or r set them to 0 so the
  72      * test associate with them will always succeed.
  73      */
  74     p_key = p;
  75     r_key = r;
  76     if( MPI_UNDEFINED == p ) p_key = 0;
  77     if( MPI_UNDEFINED == r ) r_key = 0;
  78 
  79     /**
  80      * With respect to the MPI standard, MPI-2.0 Sect. 10.2.5, MPI_TYPE_CREATE_F90_xxxx,
  81      * page 295, line 47 we handle this nicely by caching the values in a hash table.
  82      * However, as the value of might not always make sense, a little bit of optimization
  83      * might be a good idea. Therefore, first we try to see if we can handle the value
  84      * with some kind of default value, and if it's the case then we look into the
  85      * cache.
  86      */
  87 
  88     if     ( (LDBL_DIG < p) || (LDBL_MAX_10_EXP < r) || (-LDBL_MIN_10_EXP < r) ) *newtype = &ompi_mpi_datatype_null.dt;
  89     else if( (DBL_DIG  < p) || (DBL_MAX_10_EXP  < r) || (-DBL_MIN_10_EXP  < r) ) *newtype = &ompi_mpi_long_double.dt;
  90     else if( (FLT_DIG  < p) || (FLT_MAX_10_EXP  < r) || (-FLT_MIN_10_EXP  < r) ) *newtype = &ompi_mpi_double.dt;
  91     else if( ! OMPI_HAVE_FORTRAN_REAL2 ||
  92              (sflt_dig < p) || (sflt_max_10_exp < r) || (-sflt_min_10_exp < r) ) *newtype = &ompi_mpi_float.dt;
  93     else                                                                         *newtype = &ompi_mpi_real2.dt;
  94 
  95     if( *newtype != &ompi_mpi_datatype_null.dt ) {
  96         ompi_datatype_t* datatype;
  97         const int* a_i[2] = {&p, &r};
  98         int rc;
  99 
 100         key = (((uint64_t)p_key) << 32) | ((uint64_t)r_key);
 101         if( OPAL_SUCCESS == opal_hash_table_get_value_uint64( &ompi_mpi_f90_real_hashtable,
 102                                                               key, (void**)newtype ) ) {
 103             return MPI_SUCCESS;
 104         }
 105         /* Create the duplicate type corresponding to selected type, then
 106          * set the argument to be a COMBINER with the correct value of r
 107          * and add it to the hash table. */
 108         if (OMPI_SUCCESS != ompi_datatype_duplicate( *newtype, &datatype)) {
 109             OMPI_ERRHANDLER_RETURN (MPI_ERR_INTERN, MPI_COMM_WORLD,
 110                                     MPI_ERR_INTERN, FUNC_NAME );
 111         }
 112         /* Make sure the user is not allowed to free this datatype as specified
 113          * in the MPI standard.
 114          */
 115         datatype->super.flags |= OMPI_DATATYPE_FLAG_PREDEFINED;
 116         /* Mark the datatype as a special F90 convenience type */
 117         // Specifically using opal_snprintf() here (instead of
 118         // snprintf()) so that over-eager compilers do not warn us
 119         // that we may be truncating the output.  We *know* that the
 120         // output may be truncated, and it's ok.
 121         opal_snprintf(datatype->name, sizeof(datatype->name),
 122                       "COMBINER %s", (*newtype)->name);
 123 
 124         ompi_datatype_set_args( datatype, 2, a_i, 0, NULL, 0, NULL, MPI_COMBINER_F90_REAL );
 125 
 126         rc = opal_hash_table_set_value_uint64( &ompi_mpi_f90_real_hashtable, key, datatype );
 127         if (OMPI_SUCCESS != rc) {
 128             return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, rc, FUNC_NAME);
 129         }
 130         *newtype = datatype;
 131         return MPI_SUCCESS;
 132     }
 133 
 134     return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME);
 135 }

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