1
1

mpi/fortran: fix parsing arrays of Fortran strings

MPI defines the "argv" param to Fortran MPI_COMM_SPAWN as being
terminated by a blank string.  While not precisely defined (except
through a non-binding example, Example 10.2, MPI-3.1 p382:6-29), one
can infer that the "array_of_argv" param to Fortran
MPI_COMM_SPAWN_MULTIPLE is also a set of argv, each of which are
terminated by a blank line.

The "array_of_commands" argument to Fortran MPI_COMM_SPAWN_MULTIPLE is
a little less well-defined.  It is *assumed* to be of length "count"
(another parameter to MPI_COMM_SPAWN_MULTIPLE) -- and *not* be
terminated by a blank string.  This is also given credence by the same
example 10.2 in MPI-3.1.

The previous code assumed that "array_of_commands" should also be
terminated by a blank line -- but per the above, this is incorrect.
Instead, we should just parse our "count" number of strings from
"array_of_commands" and *not* look for a blank line termination.

This commit separates these two cases:

* ompi_fortran_argv_blank_f2c(): parse a Fortran array of strings out
  and stop when reaching a blank string.
* ompi_fortran_argv_count_f2c(): parse a Fortran array of strings out
  and stop when "count" number of strings have been parsed.

Signed-off-by: Jeff Squyres <jsquyres@cisco.com>
Этот коммит содержится в:
Jeff Squyres 2018-04-04 18:56:44 -07:00
родитель ef28d941d9
Коммит 0ab6b201fe
4 изменённых файлов: 93 добавлений и 20 удалений

Просмотреть файл

@ -9,7 +9,7 @@
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2010-2012 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2010-2018 Cisco Systems, Inc. All rights reserved
* $COPYRIGHT$
*
* Additional copyrights may follow
@ -58,8 +58,8 @@ BEGIN_C_DECLS
OMPI_DECLSPEC int ompi_fortran_string_c2f(char *cstr, char *fstr, int len);
/**
* Convert an array of Fortran strings to an argv-style array of C
* strings.
* Convert an array of Fortran strings that are terminated with a
* blank line to an argv-style array of C strings.
*
* @param farray Array of fortran strings
* @param string_len Length of each fortran string in the array
@ -86,8 +86,29 @@ BEGIN_C_DECLS
* number_of_argv_arrays). Hence, the advance parameter is used
* to specify this displacement.
*/
OMPI_DECLSPEC int ompi_fortran_argv_f2c(char *farray, int string_len,
int advancex, char ***cargv);
OMPI_DECLSPEC int ompi_fortran_argv_blank_f2c(char *farray, int string_len,
int advancex, char ***cargv);
/**
* Convert an array of a specific number of Fortran strings to an
* argv-style array of C strings.
*
* @param farray Array of fortran strings
* @param farray_length Number of entries in the farray array
* @param string_len Length of each fortran string in the array
* @param advance Number of bytes to advance to get to the next string
* @param cargv Returned argv-style array of C strings
*
* @retval OMPI_SUCCESS upon success
* @retval OMPI_ERROR upon error
*
* This function is just like ompi_fortran_argv_blank_f2c(),
* except that it uses farray_length to determine the length of
* farray (vs. looking for a blank string to look for the end of
* the array).
*/
OMPI_DECLSPEC int ompi_fortran_argv_count_f2c(char *farray, int farray_length, int string_len,
int advancex, char ***cargv);
/**
* Convert an array of argvs to a C style array of argvs

Просмотреть файл

@ -9,7 +9,7 @@
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2010-2012 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2010-2018 Cisco Systems, Inc. All rights reserved
* Copyright (c) 2017 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* $COPYRIGHT$
@ -101,11 +101,19 @@ int ompi_fortran_string_c2f(char *cstr, char *fstr, int len)
/*
* creates a C argument vector from an F77 array of strings
* (terminated by a blank string)
* Creates a C argument vector from an F77 array of strings. The
* array is terminated by a blank string.
*
* This function is quite similar to ompi_fortran_argv_count_f2c(),
* that it looks for a blank string to know when it has finished
* traversing the entire array (vs. having the length of the array
* passed in as a parameter).
*
* This function is used to convert "argv" in MPI_COMM_SPAWN (which is
* defined to be terminated by a blank string).
*/
int ompi_fortran_argv_f2c(char *array, int string_len, int advance,
char ***argv)
int ompi_fortran_argv_blank_f2c(char *array, int string_len, int advance,
char ***argv)
{
int err, argc = 0;
char *cstr;
@ -141,8 +149,52 @@ int ompi_fortran_argv_f2c(char *array, int string_len, int advance,
/*
* Creates a set of C argv arrays from an F77 array of argv's. The
* returned arrays need to be freed by the caller.
* Creates a C argument vector from an F77 array of array_len strings.
*
* This function is quite similar to ompi_fortran_argv_blank_f2c(),
* except that the length of the array is a parameter (vs. looking for
* a blank line to end the array).
*
* This function is used to convert "array_of_commands" in
* MPI_COMM_SPAWN_MULTIPLE (which is not precisely defined, but is
* assumed to be of length "count", and *not* terminated by a blank
* line).
*/
int ompi_fortran_argv_count_f2c(char *array, int array_len, int string_len, int advance,
char ***argv)
{
int err, argc = 0;
char *cstr;
/* Fortran lines up strings in memory, each delimited by \0. So
just convert them until we hit an extra \0. */
*argv = NULL;
for (int i = 0; i < array_len; ++i) {
if (OMPI_SUCCESS != (err = ompi_fortran_string_f2c(array, string_len,
&cstr))) {
opal_argv_free(*argv);
return err;
}
if (OMPI_SUCCESS != (err = opal_argv_append(&argc, argv, cstr))) {
opal_argv_free(*argv);
free(cstr);
return err;
}
free(cstr);
array += advance;
}
return OMPI_SUCCESS;
}
/*
* Creates a set of C argv arrays from an F77 array of argv's (where
* each argv array is terminated by a blank string). The returned
* arrays need to be freed by the caller.
*/
int ompi_fortran_multiple_argvs_f2c(int num_argv_arrays, char *array,
int string_len, char ****argv)
@ -155,9 +207,9 @@ int ompi_fortran_multiple_argvs_f2c(int num_argv_arrays, char *array,
argv_array = (char ***) malloc (num_argv_arrays * sizeof(char **));
for (i = 0; i < num_argv_arrays; ++i) {
ret = ompi_fortran_argv_f2c(current_array, string_len,
string_len * num_argv_arrays,
&argv_array[i]);
ret = ompi_fortran_argv_blank_f2c(current_array, string_len,
string_len * num_argv_arrays,
&argv_array[i]);
if (OMPI_SUCCESS != ret) {
free(argv_array);
return ret;

Просмотреть файл

@ -9,7 +9,7 @@
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2010-2012 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2010-2018 Cisco Systems, Inc. All rights reserved
* Copyright (c) 2015-2017 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* $COPYRIGHT$
@ -101,7 +101,7 @@ void ompi_comm_spawn_f(char *command, char *argv, MPI_Fint *maxprocs,
if (OMPI_IS_FORTRAN_ARGV_NULL(argv)) {
c_argv = MPI_ARGV_NULL;
} else {
ompi_fortran_argv_f2c(argv, string_len, string_len, &c_argv);
ompi_fortran_argv_blank_f2c(argv, string_len, string_len, &c_argv);
}
c_ierr = PMPI_Comm_spawn(c_command, c_argv,

Просмотреть файл

@ -9,7 +9,7 @@
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2010-2012 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2010-2018 Cisco Systems, Inc. All rights reserved
* Copyright (c) 2015-2017 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* Copyright (c) 2016 Los Alamos National Security, LLC. All rights
@ -115,8 +115,8 @@ void ompi_comm_spawn_multiple_f(MPI_Fint *count, char *array_commands,
OMPI_ARRAY_FINT_2_INT(array_maxprocs, array_size);
ompi_fortran_argv_f2c(array_commands, cmd_string_len,
cmd_string_len, &c_array_commands);
ompi_fortran_argv_count_f2c(array_commands, array_size, cmd_string_len,
cmd_string_len, &c_array_commands);
c_info = (MPI_Info *) malloc (array_size * sizeof(MPI_Info));
for (i = 0; i < array_size; ++i) {