It turns out that Fortran has some specific rules about copying
strings. Here's one: no matter how much of the string you copy, the destination string must be space-padded for the entire remaining area. Specifically, even if you call MPI_INFO_GET and tell MPI to only copy a max of N characters of the value into the result string, if the Fortran string is M characters (where M > N), MPI must space-pad the remaining (M-N) characters to be spaces. So you're supposed to obey the argument to MPI_INFO_GET... sorta. Precedents: * http://www.ibiblio.org/pub/languages/fortran/ch2-13.html * LAM/MPI * Sun CT MPI This commit was SVN r11412.
Этот коммит содержится в:
родитель
4f75dfd353
Коммит
17d313f6e1
@ -82,8 +82,6 @@ void mpi_error_string_f(MPI_Fint *errorcode, char *string,
|
||||
));
|
||||
if (MPI_SUCCESS == OMPI_FINT_2_INT(*ierr)) {
|
||||
OMPI_SINGLE_INT_2_FINT(resultlen);
|
||||
string_len = (string_len < MPI_MAX_ERROR_STRING) ?
|
||||
string_len : MPI_MAX_ERROR_STRING;
|
||||
if (OMPI_SUCCESS != (ret = ompi_fortran_string_c2f(c_string, string,
|
||||
string_len))) {
|
||||
c_err = OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, ret, FUNC_NAME);
|
||||
|
@ -74,6 +74,6 @@ void mpi_file_get_view_f(MPI_Fint *fh, MPI_Offset *disp,
|
||||
*disp = (MPI_Fint) c_disp;
|
||||
*etype = MPI_Type_c2f(c_etype);
|
||||
*filetype = MPI_Type_c2f(c_filetype);
|
||||
ompi_fortran_string_c2f(c_datarep, datarep, MPI_MAX_DATAREP_STRING);
|
||||
ompi_fortran_string_c2f(c_datarep, datarep, datarep_len);
|
||||
}
|
||||
}
|
||||
|
@ -80,8 +80,8 @@ void mpi_get_processor_name_f(char *name, MPI_Fint *resultlen, MPI_Fint *ierr,
|
||||
if (MPI_SUCCESS == OMPI_FINT_2_INT(*ierr)) {
|
||||
OMPI_SINGLE_INT_2_FINT(resultlen);
|
||||
|
||||
name_len = (name_len < OMPI_FINT_2_INT(*resultlen)) ?
|
||||
name_len : OMPI_FINT_2_INT(*resultlen);
|
||||
/* Use the full length of the Fortran string, not *resultlen.
|
||||
See comment in ompi/mpi/f77/strings.c. */
|
||||
if (OMPI_SUCCESS != (ret = ompi_fortran_string_c2f(c_name, name,
|
||||
name_len))) {
|
||||
c_err = OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, ret, FUNC_NAME);
|
||||
|
@ -91,8 +91,8 @@ void mpi_info_get_f(MPI_Fint *info, char *key, MPI_Fint *valuelen,
|
||||
if (MPI_SUCCESS == OMPI_FINT_2_INT(*ierr)) {
|
||||
OMPI_SINGLE_INT_2_LOGICAL(flag);
|
||||
|
||||
value_len = (value_len < OMPI_FINT_2_INT(*valuelen)) ?
|
||||
value_len : OMPI_FINT_2_INT(*valuelen);
|
||||
/* Use the full length of the Fortran string, not *valuelen.
|
||||
See comment in ompi/mpi/f77/strings.c. */
|
||||
if (OMPI_SUCCESS != (ret = ompi_fortran_string_c2f(c_value, value,
|
||||
value_len))) {
|
||||
c_err = OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, ret, FUNC_NAME);
|
||||
|
@ -81,7 +81,6 @@ void mpi_info_get_nthkey_f(MPI_Fint *info, MPI_Fint *n, char *key,
|
||||
OMPI_FINT_2_INT(*n),
|
||||
c_key));
|
||||
|
||||
key_len = (key_len < MPI_MAX_INFO_KEY) ? key_len : MPI_MAX_INFO_KEY;
|
||||
if (OMPI_SUCCESS != (ret = ompi_fortran_string_c2f(c_key, key, key_len))) {
|
||||
c_err = OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, ret, FUNC_NAME);
|
||||
*ierr = OMPI_INT_2_FINT(c_err);
|
||||
|
@ -71,7 +71,18 @@ int ompi_fortran_string_f2c(char *fstr, int len, char **cstr)
|
||||
|
||||
|
||||
/*
|
||||
* copy a C string into a Fortran string
|
||||
* Copy a C string into a Fortran string. Note that when Fortran
|
||||
* copies strings, even if it operates on subsets of the strings, it
|
||||
* is expected to zero out the rest of the string with spaces. Hence,
|
||||
* when calling this function, the "len" parameter should be the
|
||||
* compiler-passed length of the entire string, even if you're copying
|
||||
* over less than the full string. Specifically:
|
||||
*
|
||||
* http://www.ibiblio.org/pub/languages/fortran/ch2-13.html
|
||||
*
|
||||
* "Whole operations 'using' only 'part' of it, e.g. assignment of a
|
||||
* shorter string, or reading a shorter record, automatically pads the
|
||||
* rest of the string with blanks."
|
||||
*/
|
||||
int ompi_fortran_string_c2f(char *cstr, char *fstr, int len)
|
||||
{
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user