Skip to content

Commit 0ab6b20

Browse files
committed
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 <[email protected]>
1 parent ef28d94 commit 0ab6b20

File tree

4 files changed

+93
-20
lines changed

4 files changed

+93
-20
lines changed

ompi/mpi/fortran/base/fortran_base_strings.h

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* University of Stuttgart. All rights reserved.
1010
* Copyright (c) 2004-2005 The Regents of the University of California.
1111
* All rights reserved.
12-
* Copyright (c) 2010-2012 Cisco Systems, Inc. All rights reserved.
12+
* Copyright (c) 2010-2018 Cisco Systems, Inc. All rights reserved
1313
* $COPYRIGHT$
1414
*
1515
* Additional copyrights may follow
@@ -58,8 +58,8 @@ BEGIN_C_DECLS
5858
OMPI_DECLSPEC int ompi_fortran_string_c2f(char *cstr, char *fstr, int len);
5959

6060
/**
61-
* Convert an array of Fortran strings to an argv-style array of C
62-
* strings.
61+
* Convert an array of Fortran strings that are terminated with a
62+
* blank line to an argv-style array of C strings.
6363
*
6464
* @param farray Array of fortran strings
6565
* @param string_len Length of each fortran string in the array
@@ -86,8 +86,29 @@ BEGIN_C_DECLS
8686
* number_of_argv_arrays). Hence, the advance parameter is used
8787
* to specify this displacement.
8888
*/
89-
OMPI_DECLSPEC int ompi_fortran_argv_f2c(char *farray, int string_len,
90-
int advancex, char ***cargv);
89+
OMPI_DECLSPEC int ompi_fortran_argv_blank_f2c(char *farray, int string_len,
90+
int advancex, char ***cargv);
91+
92+
/**
93+
* Convert an array of a specific number of Fortran strings to an
94+
* argv-style array of C strings.
95+
*
96+
* @param farray Array of fortran strings
97+
* @param farray_length Number of entries in the farray array
98+
* @param string_len Length of each fortran string in the array
99+
* @param advance Number of bytes to advance to get to the next string
100+
* @param cargv Returned argv-style array of C strings
101+
*
102+
* @retval OMPI_SUCCESS upon success
103+
* @retval OMPI_ERROR upon error
104+
*
105+
* This function is just like ompi_fortran_argv_blank_f2c(),
106+
* except that it uses farray_length to determine the length of
107+
* farray (vs. looking for a blank string to look for the end of
108+
* the array).
109+
*/
110+
OMPI_DECLSPEC int ompi_fortran_argv_count_f2c(char *farray, int farray_length, int string_len,
111+
int advancex, char ***cargv);
91112

92113
/**
93114
* Convert an array of argvs to a C style array of argvs

ompi/mpi/fortran/base/strings.c

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* University of Stuttgart. All rights reserved.
1010
* Copyright (c) 2004-2005 The Regents of the University of California.
1111
* All rights reserved.
12-
* Copyright (c) 2010-2012 Cisco Systems, Inc. All rights reserved.
12+
* Copyright (c) 2010-2018 Cisco Systems, Inc. All rights reserved
1313
* Copyright (c) 2017 Research Organization for Information Science
1414
* and Technology (RIST). All rights reserved.
1515
* $COPYRIGHT$
@@ -101,11 +101,19 @@ int ompi_fortran_string_c2f(char *cstr, char *fstr, int len)
101101

102102

103103
/*
104-
* creates a C argument vector from an F77 array of strings
105-
* (terminated by a blank string)
104+
* Creates a C argument vector from an F77 array of strings. The
105+
* array is terminated by a blank string.
106+
*
107+
* This function is quite similar to ompi_fortran_argv_count_f2c(),
108+
* that it looks for a blank string to know when it has finished
109+
* traversing the entire array (vs. having the length of the array
110+
* passed in as a parameter).
111+
*
112+
* This function is used to convert "argv" in MPI_COMM_SPAWN (which is
113+
* defined to be terminated by a blank string).
106114
*/
107-
int ompi_fortran_argv_f2c(char *array, int string_len, int advance,
108-
char ***argv)
115+
int ompi_fortran_argv_blank_f2c(char *array, int string_len, int advance,
116+
char ***argv)
109117
{
110118
int err, argc = 0;
111119
char *cstr;
@@ -141,8 +149,52 @@ int ompi_fortran_argv_f2c(char *array, int string_len, int advance,
141149

142150

143151
/*
144-
* Creates a set of C argv arrays from an F77 array of argv's. The
145-
* returned arrays need to be freed by the caller.
152+
* Creates a C argument vector from an F77 array of array_len strings.
153+
*
154+
* This function is quite similar to ompi_fortran_argv_blank_f2c(),
155+
* except that the length of the array is a parameter (vs. looking for
156+
* a blank line to end the array).
157+
*
158+
* This function is used to convert "array_of_commands" in
159+
* MPI_COMM_SPAWN_MULTIPLE (which is not precisely defined, but is
160+
* assumed to be of length "count", and *not* terminated by a blank
161+
* line).
162+
*/
163+
int ompi_fortran_argv_count_f2c(char *array, int array_len, int string_len, int advance,
164+
char ***argv)
165+
{
166+
int err, argc = 0;
167+
char *cstr;
168+
169+
/* Fortran lines up strings in memory, each delimited by \0. So
170+
just convert them until we hit an extra \0. */
171+
172+
*argv = NULL;
173+
for (int i = 0; i < array_len; ++i) {
174+
if (OMPI_SUCCESS != (err = ompi_fortran_string_f2c(array, string_len,
175+
&cstr))) {
176+
opal_argv_free(*argv);
177+
return err;
178+
}
179+
180+
if (OMPI_SUCCESS != (err = opal_argv_append(&argc, argv, cstr))) {
181+
opal_argv_free(*argv);
182+
free(cstr);
183+
return err;
184+
}
185+
186+
free(cstr);
187+
array += advance;
188+
}
189+
190+
return OMPI_SUCCESS;
191+
}
192+
193+
194+
/*
195+
* Creates a set of C argv arrays from an F77 array of argv's (where
196+
* each argv array is terminated by a blank string). The returned
197+
* arrays need to be freed by the caller.
146198
*/
147199
int ompi_fortran_multiple_argvs_f2c(int num_argv_arrays, char *array,
148200
int string_len, char ****argv)
@@ -155,9 +207,9 @@ int ompi_fortran_multiple_argvs_f2c(int num_argv_arrays, char *array,
155207
argv_array = (char ***) malloc (num_argv_arrays * sizeof(char **));
156208

157209
for (i = 0; i < num_argv_arrays; ++i) {
158-
ret = ompi_fortran_argv_f2c(current_array, string_len,
159-
string_len * num_argv_arrays,
160-
&argv_array[i]);
210+
ret = ompi_fortran_argv_blank_f2c(current_array, string_len,
211+
string_len * num_argv_arrays,
212+
&argv_array[i]);
161213
if (OMPI_SUCCESS != ret) {
162214
free(argv_array);
163215
return ret;

ompi/mpi/fortran/mpif-h/comm_spawn_f.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* University of Stuttgart. All rights reserved.
1010
* Copyright (c) 2004-2005 The Regents of the University of California.
1111
* All rights reserved.
12-
* Copyright (c) 2010-2012 Cisco Systems, Inc. All rights reserved.
12+
* Copyright (c) 2010-2018 Cisco Systems, Inc. All rights reserved
1313
* Copyright (c) 2015-2017 Research Organization for Information Science
1414
* and Technology (RIST). All rights reserved.
1515
* $COPYRIGHT$
@@ -101,7 +101,7 @@ void ompi_comm_spawn_f(char *command, char *argv, MPI_Fint *maxprocs,
101101
if (OMPI_IS_FORTRAN_ARGV_NULL(argv)) {
102102
c_argv = MPI_ARGV_NULL;
103103
} else {
104-
ompi_fortran_argv_f2c(argv, string_len, string_len, &c_argv);
104+
ompi_fortran_argv_blank_f2c(argv, string_len, string_len, &c_argv);
105105
}
106106

107107
c_ierr = PMPI_Comm_spawn(c_command, c_argv,

ompi/mpi/fortran/mpif-h/comm_spawn_multiple_f.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* University of Stuttgart. All rights reserved.
1010
* Copyright (c) 2004-2005 The Regents of the University of California.
1111
* All rights reserved.
12-
* Copyright (c) 2010-2012 Cisco Systems, Inc. All rights reserved.
12+
* Copyright (c) 2010-2018 Cisco Systems, Inc. All rights reserved
1313
* Copyright (c) 2015-2017 Research Organization for Information Science
1414
* and Technology (RIST). All rights reserved.
1515
* 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,
115115

116116
OMPI_ARRAY_FINT_2_INT(array_maxprocs, array_size);
117117

118-
ompi_fortran_argv_f2c(array_commands, cmd_string_len,
119-
cmd_string_len, &c_array_commands);
118+
ompi_fortran_argv_count_f2c(array_commands, array_size, cmd_string_len,
119+
cmd_string_len, &c_array_commands);
120120

121121
c_info = (MPI_Info *) malloc (array_size * sizeof(MPI_Info));
122122
for (i = 0; i < array_size; ++i) {

0 commit comments

Comments
 (0)