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-2008 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) 2018 Amazon.com, Inc. or its affiliates. All Rights reserved.
20 * $COPYRIGHT$
21 *
22 * Additional copyrights may follow
23 *
24 * $HEADER$
25 */
26
27 #include "ompi_config.h"
28
29 #include "opal/util/printf.h"
30
31 #include "ompi/mpi/c/bindings.h"
32 #include "ompi/runtime/params.h"
33 #include "ompi/communicator/communicator.h"
34 #include "ompi/errhandler/errhandler.h"
35
36 #if OMPI_BUILD_MPI_PROFILING
37 #if OPAL_HAVE_WEAK_SYMBOLS
38 #pragma weak MPI_Type_create_f90_integer = PMPI_Type_create_f90_integer
39 #endif
40 #define MPI_Type_create_f90_integer PMPI_Type_create_f90_integer
41 #endif
42
43 static const char FUNC_NAME[] = "MPI_Type_create_f90_integer";
44
45
46 int MPI_Type_create_f90_integer(int r, MPI_Datatype *newtype)
47
48 {
49 OPAL_CR_NOOP_PROGRESS();
50
51 if (MPI_PARAM_CHECK) {
52 OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
53
54 /* Note: These functions accept negative integers for the p and r
55 * arguments. This is because for the SELECTED_INTEGER_KIND,
56 * negative numbers are equivalent to zero values. See section
57 * 13.14.95 of the Fortran 95 standard. */
58 }
59
60 /**
61 * With respect to the MPI standard, MPI-2.0 Sect. 10.2.5, MPI_TYPE_CREATE_F90_xxxx,
62 * page 295, line 47 we handle this nicely by caching the values in a hash table.
63 * However, as the value of might not always make sense, a little bit of optimization
64 * might be a good idea. Therefore, first we try to see if we can handle the value
65 * with some kind of default value, and if it's the case then we look into the
66 * cache.
67 */
68
69 if (r > 38) *newtype = &ompi_mpi_datatype_null.dt;
70 #if OMPI_HAVE_FORTRAN_INTEGER16
71 else if (r > 18) *newtype = &ompi_mpi_long_long_int.dt;
72 #else
73 else if (r > 18) *newtype = &ompi_mpi_datatype_null.dt;
74 #endif /* OMPI_HAVE_F90_INTEGER16 */
75 #if SIZEOF_LONG > SIZEOF_INT
76 else if (r > 9) *newtype = &ompi_mpi_long.dt;
77 #else
78 #if SIZEOF_LONG_LONG > SIZEOF_INT
79 else if (r > 9) *newtype = &ompi_mpi_long_long_int.dt;
80 #else
81 else if (r > 9) *newtype = &ompi_mpi_datatype_null.dt;
82 #endif /* SIZEOF_LONG_LONG > SIZEOF_INT */
83 #endif /* SIZEOF_LONG > SIZEOF_INT */
84 else if (r > 4) *newtype = &ompi_mpi_int.dt;
85 else if (r > 2) *newtype = &ompi_mpi_short.dt;
86 else *newtype = &ompi_mpi_byte.dt;
87
88 if( *newtype != &ompi_mpi_datatype_null.dt ) {
89 ompi_datatype_t* datatype;
90 const int* a_i[1];
91 int rc;
92
93 if( OPAL_SUCCESS == opal_hash_table_get_value_uint32( &ompi_mpi_f90_integer_hashtable,
94 r, (void**)newtype ) ) {
95 return MPI_SUCCESS;
96 }
97 /* Create the duplicate type corresponding to selected type, then
98 * set the argument to be a COMBINER with the correct value of r
99 * and add it to the hash table. */
100 if (OMPI_SUCCESS != ompi_datatype_duplicate( *newtype, &datatype)) {
101 OMPI_ERRHANDLER_RETURN (MPI_ERR_INTERN, MPI_COMM_WORLD,
102 MPI_ERR_INTERN, FUNC_NAME );
103 }
104 /* Make sure the user is not allowed to free this datatype as specified
105 * in the MPI standard.
106 */
107 datatype->super.flags |= OMPI_DATATYPE_FLAG_PREDEFINED;
108 /* Mark the datatype as a special F90 convenience type */
109 // Specifically using opal_snprintf() here (instead of
110 // snprintf()) so that over-eager compilers do not warn us
111 // that we may be truncating the output. We *know* that the
112 // output may be truncated, and that's ok.
113 opal_snprintf(datatype->name, sizeof(datatype->name),
114 "COMBINER %s", (*newtype)->name);
115
116 a_i[0] = &r;
117 ompi_datatype_set_args( datatype, 1, a_i, 0, NULL, 0, NULL, MPI_COMBINER_F90_INTEGER );
118
119 rc = opal_hash_table_set_value_uint32( &ompi_mpi_f90_integer_hashtable, r, datatype );
120 if (OMPI_SUCCESS != rc) {
121 return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, rc, FUNC_NAME);
122 }
123 *newtype = datatype;
124 return MPI_SUCCESS;
125 }
126
127 return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME);
128 }