Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mpi4: MPI_Info_get_string #4887

Closed
hzhou opened this issue Nov 11, 2020 · 6 comments · Fixed by #4904
Closed

mpi4: MPI_Info_get_string #4887

hzhou opened this issue Nov 11, 2020 · 6 comments · Fixed by #4904
Assignees

Comments

@hzhou
Copy link
Contributor

hzhou commented Nov 11, 2020

mpi-forum/mpi-issues#146
https://github.com/mpi-forum/mpi-issues/files/3951818/misc-2_safe_get_changes.pdf

@shintaro-iwasaki shintaro-iwasaki self-assigned this Nov 11, 2020
@shintaro-iwasaki
Copy link
Contributor

shintaro-iwasaki commented Nov 12, 2020

I have a question about the implementation of MPI_Info_get_string().

Problem

According to https://github.com/mpi-forum/mpi-issues/files/3951818/misc-2_safe_get_changes.pdf, the behavior of MPI_Info_get_string() looks different between Fortran and C/C++.

In C, buflen includes the required space for the null terminator. In C, this
function returns a null terminated string in all cases where the buflen input
value is greater than 0.

So if "MPI_KEY_XXX" is mapped to "abcdef", the straightforward behavior is:

C version

int buflen = 4;
char str[4];
ierr = MPI_Info_get_string(info, "MPI_KEY_XXX", *buflen, str, flag);
// str = ['a', 'b', 'c', '\0'].
// buflen = 7 (EDIT: 2020/11/12 5:22PM CT)

Fortran version (my syntax might be wrong)

integer buflen
character str*4

buflen = 4
call MPI_Info_get_string(info, "MPI_KEY_XXX", buflen, str, flag, ierr);
C str = ['a', 'b', 'c', 'd'].
C buflen = 6 (EDIT: 2020/11/12 5:22PM CT)

How to deal with it?

Possible solutions

  1. My interpretation is wrong. The specification does not explain Fortran's behavior, so I can use the implementation for C.
  2. My interpretation is correct, but I can use the C version because No Fortran user cares the last character of a string.
  3. Versioning two functions somehow (by defining "MPI_INFO_GET_STRING()" and using an aliasing technique. I don't know how it works with PMPI).
  4. I am referring to an outdated material.

If 3, I'd like to know a reference implementation since I believe some existing MPI functions have adopted this technique.

@hzhou
Copy link
Contributor Author

hzhou commented Nov 12, 2020

You forgot to describe what is the value of buflen, which is an inout parameter.

I think my current opinion is along your option 2. But if we do that, for your fortran example, the return of str is `abc\0'.

because No Fortran user cares the last character of a string.

This may not be true. I am not sure how Fortran deals with NULL character. Ideally, in the fortran binding, we should replace the NULL character (and every extra space) with blank (space). Alternatively, in the binding, we could allocate a temporary buffer with 1 more space and simply do a extra copy for the Fortran on output. We'll need adjust the off-by-1 of buflen as well. Since we don't really care about the performance of getting info and we don't really expect too large a value string, I think this allocation of temp buffer and extra copy is feasible.

Actually, we have a maximum info value length of 1024, so we could simply use a temporary stack buffer.

@shintaro-iwasaki
Copy link
Contributor

shintaro-iwasaki commented Nov 12, 2020

You forgot to describe what is value of buflen, which is an inout parameter.

Thanks. Yes, you're right. The return value of buflen can be also different; for "ABCDEF" 7 will be set in C while 6 will be set in Fortran.

I am not sure how Fortran deals with NULL character.

It seems that that character will be treated as "\0" character, which is different from a single whitespace.

Ideally, in the fortran binding, we should replace the NULL character with blank (space). Alternatively, in the binding, we could allocate a temporary buffer with 1 more space and simply do a extra copy for the Fortran on output. We'll need adjust the off-by-1 of buflen as well. Since we don't really care about the performance of getting info and we don't really expect too large a value string, I think this allocation of temp buffer and extra copy is feasible.

I am not sure how I can create different versions for the same function. Can the current Fortran binding mechanism create a totally different function with the same name (if so, I'd be happy if someone would point out such an MPI function in MPICH)?

@shintaro-iwasaki
Copy link
Contributor

PMPI wouldn't be an issue (https://www.mpi-forum.org/docs/mpi-3.1/mpi31-report.pdf p.561). I just need to write it down somewhere.

  1. document the implementation of different language bindings of the MPI interface if they are layered on top of each other, so that the profiler developer knows whether she must implement the profile interface for each binding, or can economize by implementing it only for the lowest level routines.

@hzhou
Copy link
Contributor Author

hzhou commented Nov 12, 2020

I am not sure how I can create different versions for the same function.

We always use separate wrapper functions for the Fortran binding, ref. src/binding/fortran/mpif_h/buildiface, or reference one of the generated binding function, e.g. sendf.c.

  1. Versioning two functions somehow (by defining "MPI_INFO_GET_STRING()" and using an aliasing technique.

Actually we have a precedent doing this. Reference 11cfc75, where we use a MPII_ function that supports an extra flag parameter.

@shintaro-iwasaki
Copy link
Contributor

Thanks a lot! I now got how to implement this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants