1
1

Per #2420, string handling of the Fortran array_of_argv argument to

MPI_COMM_SPAWN_MULTIPLE was just wrong.  This commit renames a few
variables to make their meaning a bit more clear and fixes up all
known issues with converting a 2D array of Fortran strings to a set of
C-style argv vectors.

Fixes trac:2420.

This commit was SVN r23217.

The following Trac tickets were found above:
  Ticket 2420 --> https://svn.open-mpi.org/trac/ompi/ticket/2420
Этот коммит содержится в:
Jeff Squyres 2010-05-28 12:40:42 +00:00
родитель 620c0eb160
Коммит 5d386fc678
4 изменённых файлов: 47 добавлений и 26 удалений

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

@ -9,6 +9,7 @@
* University of Stuttgart. All rights reserved. * University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California. * Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved. * All rights reserved.
* Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$ * $COPYRIGHT$
* *
* Additional copyrights may follow * Additional copyrights may follow
@ -101,7 +102,8 @@ int ompi_fortran_string_c2f(char *cstr, char *fstr, int len)
* creates a C argument vector from an F77 array of strings * creates a C argument vector from an F77 array of strings
* (terminated by a blank string) * (terminated by a blank string)
*/ */
int ompi_fortran_argv_f2c(char *array, int len, char ***argv) int ompi_fortran_argv_f2c(char *array, int string_len, int advance,
char ***argv)
{ {
int err, argc = 0; int err, argc = 0;
char *cstr; char *cstr;
@ -111,7 +113,7 @@ int ompi_fortran_argv_f2c(char *array, int len, char ***argv)
*argv = NULL; *argv = NULL;
while (1) { while (1) {
if (OMPI_SUCCESS != (err = ompi_fortran_string_f2c(array, len, if (OMPI_SUCCESS != (err = ompi_fortran_string_f2c(array, string_len,
&cstr))) { &cstr))) {
opal_argv_free(*argv); opal_argv_free(*argv);
return err; return err;
@ -127,7 +129,7 @@ int ompi_fortran_argv_f2c(char *array, int len, char ***argv)
} }
free(cstr); free(cstr);
array += len; array += advance;
} }
return OMPI_SUCCESS; return OMPI_SUCCESS;
@ -135,25 +137,27 @@ int ompi_fortran_argv_f2c(char *array, int len, char ***argv)
/* /*
* creates a C argument vector from an F77 array of argvs. The * Creates a set of C argv arrays from an F77 array of argv's. The
* returned array needs to be freed by the caller * returned arrays need to be freed by the caller.
*/ */
int ompi_fortran_multiple_argvs_f2c(int count, char *array, int len, int ompi_fortran_multiple_argvs_f2c(int num_argv_arrays, char *array,
char ****argv) int string_len, char ****argv)
{ {
char ***argv_array; char ***argv_array;
int i; int i;
char *current_array = array; char *current_array = array;
int ret; int ret;
argv_array = (char ***) malloc (count * sizeof(char **)); argv_array = (char ***) malloc (num_argv_arrays * sizeof(char **));
for (i = 0; i < count; ++i) { for (i = 0; i < num_argv_arrays; ++i) {
ret = ompi_fortran_argv_f2c(current_array, len, &argv_array[i]); ret = ompi_fortran_argv_f2c(current_array, string_len,
string_len * num_argv_arrays,
&argv_array[i]);
if (OMPI_SUCCESS != ret) { if (OMPI_SUCCESS != ret) {
return ret; return ret;
} }
current_array += len * i; current_array += string_len;
} }
*argv = argv_array; *argv = argv_array;
return OMPI_SUCCESS; return OMPI_SUCCESS;

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

@ -9,6 +9,7 @@
* University of Stuttgart. All rights reserved. * University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California. * Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved. * All rights reserved.
* Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$ * $COPYRIGHT$
* *
* Additional copyrights may follow * Additional copyrights may follow
@ -34,8 +35,8 @@ OMPI_GENERATE_F77_BINDINGS (PMPI_COMM_SPAWN,
pmpi_comm_spawn_, pmpi_comm_spawn_,
pmpi_comm_spawn__, pmpi_comm_spawn__,
pmpi_comm_spawn_f, pmpi_comm_spawn_f,
(char *command, char *argv, MPI_Fint *maxprocs, MPI_Fint *info, MPI_Fint *root, MPI_Fint *comm, MPI_Fint *intercomm, MPI_Fint *array_of_errcodes, MPI_Fint *ierr, int cmd_len, int argv_len), (char *command, char *argv, MPI_Fint *maxprocs, MPI_Fint *info, MPI_Fint *root, MPI_Fint *comm, MPI_Fint *intercomm, MPI_Fint *array_of_errcodes, MPI_Fint *ierr, int cmd_len, int string_len),
(command, argv, maxprocs, info, root, comm, intercomm, array_of_errcodes, ierr, cmd_len, argv_len) ) (command, argv, maxprocs, info, root, comm, intercomm, array_of_errcodes, ierr, cmd_len, string_len) )
#endif #endif
#if OPAL_HAVE_WEAK_SYMBOLS #if OPAL_HAVE_WEAK_SYMBOLS
@ -51,8 +52,8 @@ OMPI_GENERATE_F77_BINDINGS (MPI_COMM_SPAWN,
mpi_comm_spawn_, mpi_comm_spawn_,
mpi_comm_spawn__, mpi_comm_spawn__,
mpi_comm_spawn_f, mpi_comm_spawn_f,
(char *command, char *argv, MPI_Fint *maxprocs, MPI_Fint *info, MPI_Fint *root, MPI_Fint *comm, MPI_Fint *intercomm, MPI_Fint *array_of_errcodes, MPI_Fint *ierr, int cmd_len, int argv_len), (char *command, char *argv, MPI_Fint *maxprocs, MPI_Fint *info, MPI_Fint *root, MPI_Fint *comm, MPI_Fint *intercomm, MPI_Fint *array_of_errcodes, MPI_Fint *ierr, int cmd_len, int string_len),
(command, argv, maxprocs, info, root, comm, intercomm, array_of_errcodes, ierr, cmd_len, argv_len) ) (command, argv, maxprocs, info, root, comm, intercomm, array_of_errcodes, ierr, cmd_len, string_len) )
#endif #endif
@ -63,7 +64,7 @@ OMPI_GENERATE_F77_BINDINGS (MPI_COMM_SPAWN,
void mpi_comm_spawn_f(char *command, char *argv, MPI_Fint *maxprocs, void mpi_comm_spawn_f(char *command, char *argv, MPI_Fint *maxprocs,
MPI_Fint *info, MPI_Fint *root, MPI_Fint *comm, MPI_Fint *info, MPI_Fint *root, MPI_Fint *comm,
MPI_Fint *intercomm, MPI_Fint *array_of_errcodes, MPI_Fint *intercomm, MPI_Fint *array_of_errcodes,
MPI_Fint *ierr, int cmd_len, int argv_len) MPI_Fint *ierr, int cmd_len, int string_len)
{ {
MPI_Comm c_comm, c_new_comm; MPI_Comm c_comm, c_new_comm;
MPI_Info c_info; MPI_Info c_info;
@ -92,7 +93,7 @@ void mpi_comm_spawn_f(char *command, char *argv, MPI_Fint *maxprocs,
if (OMPI_IS_FORTRAN_ARGV_NULL(argv)) { if (OMPI_IS_FORTRAN_ARGV_NULL(argv)) {
c_argv = MPI_ARGV_NULL; c_argv = MPI_ARGV_NULL;
} else { } else {
ompi_fortran_argv_f2c(argv, argv_len, &c_argv); ompi_fortran_argv_f2c(argv, string_len, string_len, &c_argv);
} }
*ierr = OMPI_INT_2_FINT(MPI_Comm_spawn(c_command, c_argv, *ierr = OMPI_INT_2_FINT(MPI_Comm_spawn(c_command, c_argv,

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

@ -9,6 +9,7 @@
* University of Stuttgart. All rights reserved. * University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California. * Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved. * All rights reserved.
* Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$ * $COPYRIGHT$
* *
* Additional copyrights may follow * Additional copyrights may follow
@ -35,8 +36,8 @@ OMPI_GENERATE_F77_BINDINGS (PMPI_COMM_SPAWN_MULTIPLE,
pmpi_comm_spawn_multiple_, pmpi_comm_spawn_multiple_,
pmpi_comm_spawn_multiple__, pmpi_comm_spawn_multiple__,
pmpi_comm_spawn_multiple_f, pmpi_comm_spawn_multiple_f,
(MPI_Fint *count, char *array_of_commands, char *array_of_argv, MPI_Fint *array_of_maxprocs, MPI_Fint *array_of_info, MPI_Fint *root, MPI_Fint *comm, MPI_Fint *intercomm, MPI_Fint *array_of_errcodes, MPI_Fint *ierr, int cmd_len, int argv_len), (MPI_Fint *count, char *array_of_commands, char *array_of_argv, MPI_Fint *array_of_maxprocs, MPI_Fint *array_of_info, MPI_Fint *root, MPI_Fint *comm, MPI_Fint *intercomm, MPI_Fint *array_of_errcodes, MPI_Fint *ierr, int cmd_string_len, int argv_string_len),
(count, array_of_commands, array_of_argv, array_of_maxprocs, array_of_info, root, comm, intercomm, array_of_errcodes, ierr, cmd_len, argv_len) ) (count, array_of_commands, array_of_argv, array_of_maxprocs, array_of_info, root, comm, intercomm, array_of_errcodes, ierr, cmd_string_len, argv_string_len) )
#endif #endif
#if OPAL_HAVE_WEAK_SYMBOLS #if OPAL_HAVE_WEAK_SYMBOLS
@ -52,8 +53,8 @@ OMPI_GENERATE_F77_BINDINGS (MPI_COMM_SPAWN_MULTIPLE,
mpi_comm_spawn_multiple_, mpi_comm_spawn_multiple_,
mpi_comm_spawn_multiple__, mpi_comm_spawn_multiple__,
mpi_comm_spawn_multiple_f, mpi_comm_spawn_multiple_f,
(MPI_Fint *count, char *array_of_commands, char *array_of_argv, MPI_Fint *array_of_maxprocs, MPI_Fint *array_of_info, MPI_Fint *root, MPI_Fint *comm, MPI_Fint *intercomm, MPI_Fint *array_of_errcodes, MPI_Fint *ierr, int cmd_len, int argv_len), (MPI_Fint *count, char *array_of_commands, char *array_of_argv, MPI_Fint *array_of_maxprocs, MPI_Fint *array_of_info, MPI_Fint *root, MPI_Fint *comm, MPI_Fint *intercomm, MPI_Fint *array_of_errcodes, MPI_Fint *ierr, int cmd_string_len, int argv_string_len),
(count, array_of_commands, array_of_argv, array_of_maxprocs, array_of_info, root, comm, intercomm, array_of_errcodes, ierr, cmd_len, argv_len) ) (count, array_of_commands, array_of_argv, array_of_maxprocs, array_of_info, root, comm, intercomm, array_of_errcodes, ierr, cmd_string_len, argv_string_len) )
#endif #endif
@ -67,7 +68,7 @@ void mpi_comm_spawn_multiple_f(MPI_Fint *count, char *array_commands,
MPI_Fint *array_info, MPI_Fint *root, MPI_Fint *array_info, MPI_Fint *root,
MPI_Fint *comm, MPI_Fint *intercomm, MPI_Fint *comm, MPI_Fint *intercomm,
MPI_Fint *array_errcds, MPI_Fint *ierr, MPI_Fint *array_errcds, MPI_Fint *ierr,
int cmd_len, int argv_len) int cmd_string_len, int argv_string_len)
{ {
MPI_Comm c_comm, c_new_comm; MPI_Comm c_comm, c_new_comm;
MPI_Info *c_info; MPI_Info *c_info;
@ -99,12 +100,13 @@ void mpi_comm_spawn_multiple_f(MPI_Fint *count, char *array_commands,
c_array_argv = MPI_ARGVS_NULL; c_array_argv = MPI_ARGVS_NULL;
} else { } else {
ompi_fortran_multiple_argvs_f2c(OMPI_FINT_2_INT(*count), array_argv, ompi_fortran_multiple_argvs_f2c(OMPI_FINT_2_INT(*count), array_argv,
argv_len, &c_array_argv); argv_string_len, &c_array_argv);
} }
OMPI_ARRAY_FINT_2_INT(array_maxprocs, array_size); OMPI_ARRAY_FINT_2_INT(array_maxprocs, array_size);
ompi_fortran_argv_f2c(array_commands, cmd_len, &c_array_commands); ompi_fortran_argv_f2c(array_commands, cmd_string_len,
cmd_string_len, &c_array_commands);
c_info = (MPI_Info *) malloc (array_size * sizeof(MPI_Info)); c_info = (MPI_Info *) malloc (array_size * sizeof(MPI_Info));
for (i = 0; i < array_size; ++i) { for (i = 0; i < array_size; ++i) {

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

@ -9,6 +9,7 @@
* University of Stuttgart. All rights reserved. * University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California. * Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved. * All rights reserved.
* Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$ * $COPYRIGHT$
* *
* Additional copyrights may follow * Additional copyrights may follow
@ -61,7 +62,8 @@ BEGIN_C_DECLS
* strings. * strings.
* *
* @param farray Array of fortran strings * @param farray Array of fortran strings
* @param len Length of fortran 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 * @param cargv Returned argv-style array of C strings
* *
* @retval OMPI_SUCCESS upon success * @retval OMPI_SUCCESS upon success
@ -72,8 +74,20 @@ BEGIN_C_DECLS
* strings. The argv array will be allocated and returned; it is * strings. The argv array will be allocated and returned; it is
* the caller's responsibility to invoke opal_argv_free() to free * the caller's responsibility to invoke opal_argv_free() to free
* it later (or equivalent). * it later (or equivalent).
*
* For 1D Fortran string arrays, advance will == string_len.
*
* However, when this function is used (indirectly) for
* MPI_COMM_SPAWN_MULTIPLE, a 2D array of Fortran strings is
* converted to individual C-style argv vectors. In this case,
* Fortran will intertwine the strings of the different argv
* vectors in memory; the displacement between the beginning of 2
* strings in a single argv vector is (string_len *
* number_of_argv_arrays). Hence, the advance parameter is used
* to specify this displacement.
*/ */
OMPI_DECLSPEC int ompi_fortran_argv_f2c(char *farray, int len, char ***cargv); OMPI_DECLSPEC int ompi_fortran_argv_f2c(char *farray, int string_len,
int advancex, char ***cargv);
/** /**
* Convert an array of argvs to a C style array of argvs * Convert an array of argvs to a C style array of argvs