1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  *   Copyright (C) 1997 University of Chicago.
4  *   See COPYRIGHT notice in top-level directory.
5  */
6 
7 #include "mpioimpl.h"
8 #include "adio_extern.h"
9 
10 #ifdef HAVE_WEAK_SYMBOLS
11 
12 #if defined(HAVE_PRAGMA_WEAK)
13 #pragma weak MPI_Register_datarep = PMPI_Register_datarep
14 #elif defined(HAVE_PRAGMA_HP_SEC_DEF)
15 #pragma _HP_SECONDARY_DEF PMPI_Register_datarep MPI_Register_datarep
16 #elif defined(HAVE_PRAGMA_CRI_DUP)
17 #pragma _CRI duplicate MPI_Register_datarep as PMPI_Register_datarep
18 /* end of weak pragmas */
19 #elif defined(HAVE_WEAK_ATTRIBUTE)
20 int MPI_Register_datarep(const char *datarep, MPI_Datarep_conversion_function *read_conversion_fn,
21 			 MPI_Datarep_conversion_function *write_conversion_fn,
22 			 MPI_Datarep_extent_function *dtype_file_extent_fn, void *extra_state) __attribute__((weak,alias("PMPI_Register_datarep")));
23 #endif
24 
25 /* Include mapping from MPI->PMPI */
26 #define MPIO_BUILD_PROFILING
27 #include "mpioprof.h"
28 #endif
29 
30 /*@
31   MPI_Register_datarep - Register functions for user-defined data
32                          representations
33 
34 Input Parameters:
35 + datarep - data representation name (string)
36 . read_conversion_fn - function invoked to convert from file representation to
37                  native representation (function)
38 . write_conversion_fn - function invoked to convert from native representation to
39                   file representation (function)
40 . dtype_file_extent_fn - function invoked to get the exted of a datatype as represented
41                   in the file (function)
42 - extra_state - pointer to extra state that is passed to each of the
43                 three functions
44 
45  Notes:
46  This function allows the user to provide routines to convert data from
47  an external representation, used within a file, and the native representation,
48  used within the CPU.  There is one predefined data representation,
49  'external32'.  Please consult the MPI-2 standard for details on this
50  function.
51 
52 .N fortran
53 
54   @*/
MPI_Register_datarep(ROMIO_CONST char * datarep,MPI_Datarep_conversion_function * read_conversion_fn,MPI_Datarep_conversion_function * write_conversion_fn,MPI_Datarep_extent_function * dtype_file_extent_fn,void * extra_state)55 int MPI_Register_datarep(ROMIO_CONST char *datarep,
56 			 MPI_Datarep_conversion_function *read_conversion_fn,
57 			 MPI_Datarep_conversion_function *write_conversion_fn,
58 			 MPI_Datarep_extent_function *dtype_file_extent_fn,
59 			 void *extra_state)
60 {
61     int error_code;
62     ADIOI_Datarep *adio_datarep;
63     static char myname[] = "MPI_REGISTER_DATAREP";
64 
65     ROMIO_THREAD_CS_ENTER();
66 
67     /* --BEGIN ERROR HANDLING-- */
68     /* check datarep name (use strlen instead of strnlen because
69        strnlen is not portable) */
70     if (datarep == NULL ||
71 	strlen(datarep) < 1 ||
72 	strlen(datarep) > MPI_MAX_DATAREP_STRING)
73     {
74 	error_code = MPIO_Err_create_code(MPI_SUCCESS,
75 					  MPIR_ERR_RECOVERABLE,
76 					  myname, __LINE__,
77 					  MPI_ERR_ARG,
78 					  "**datarepname", 0);
79 	error_code = MPIO_Err_return_file(MPI_FILE_NULL, error_code);
80 	goto fn_exit;
81     }
82     /* --END ERROR HANDLING-- */
83 
84     MPIR_MPIOInit(&error_code);
85     if (error_code != MPI_SUCCESS) goto fn_exit;
86 
87     /* --BEGIN ERROR HANDLING-- */
88     /* check datarep isn't already registered */
89     for (adio_datarep = ADIOI_Datarep_head; adio_datarep; adio_datarep = adio_datarep->next) {
90 	if (!strncmp(datarep, adio_datarep->name, MPI_MAX_DATAREP_STRING)) {
91 	    error_code = MPIO_Err_create_code(MPI_SUCCESS,
92 					      MPIR_ERR_RECOVERABLE,
93 					      myname, __LINE__,
94 					      MPI_ERR_DUP_DATAREP,
95 					      "**datarepused",
96 					      "**datarepused %s",
97 					      datarep);
98 	    error_code = MPIO_Err_return_file(MPI_FILE_NULL, error_code);
99 	    goto fn_exit;
100 	}
101     }
102 
103     /* Check Non-NULL Read and Write conversion function pointer */
104     /* Read and Write conversions are currently not supported.   */
105     if ( (read_conversion_fn != NULL) || (write_conversion_fn != NULL) )
106     {
107         error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
108                                           myname, __LINE__,
109                                           MPI_ERR_CONVERSION,
110                                           "**drconvnotsupported", 0);
111 
112 	error_code = MPIO_Err_return_file(MPI_FILE_NULL, error_code);
113 	goto fn_exit;
114     }
115 
116     /* check extent function pointer */
117     if (dtype_file_extent_fn == NULL)
118     {
119 	error_code = MPIO_Err_create_code(MPI_SUCCESS,
120 					  MPIR_ERR_RECOVERABLE,
121 					  myname, __LINE__,
122 					  MPI_ERR_ARG,
123 					  "**datarepextent", 0);
124 	error_code = MPIO_Err_return_file(MPI_FILE_NULL, error_code);
125 	goto fn_exit;
126     }
127     /* --END ERROR HANDLING-- */
128 
129     adio_datarep = ADIOI_Malloc(sizeof(ADIOI_Datarep));
130     adio_datarep->name = ADIOI_Strdup(datarep);
131     adio_datarep->state         = extra_state;
132     adio_datarep->read_conv_fn  = read_conversion_fn;
133     adio_datarep->write_conv_fn = write_conversion_fn;
134     adio_datarep->extent_fn     = dtype_file_extent_fn;
135     adio_datarep->next          = ADIOI_Datarep_head;
136 
137     ADIOI_Datarep_head = adio_datarep;
138 
139     error_code = MPI_SUCCESS;
140 
141 fn_exit:
142     ROMIO_THREAD_CS_EXIT();
143 
144     return error_code;
145 }
146