mpi-forum / mpi-issues

Tickets for the MPI Forum
http://www.mpi-forum.org/
67 stars 8 forks source link

standard-violating case-switch on non-compile-time-constant constants #657

Closed jeffhammond closed 1 year ago

jeffhammond commented 2 years ago

Problem

Example 5.20 and the code following MPI_TYPE_MATCH_SIZE in §19.1 have a case-switch on a constant handles. However, with the exception of the list of explicitly compile-time constants in §2.5.4, MPI constants are not compile-time constants and cannot be used like this. They are only required to be link-time constants and not change during the execution of applications. Furthermore, they can be const int in C, and one cannot case-switch on const int values.

Text details

All named constants, with the exceptions noted below for Fortran, can be used in initialization expressions or assignments, but not necessarily in array declarations or as labels in C switch or Fortran select/case statements. This implies named constants to be link-time but not necessarily compile-time constants. The named constants listed below are required to be compile-time constants in both C and Fortran.

switch (combiner) {
    case MPI_COMBINER_NAMED:
...
 switch(typeclass) {
           case MPI_TYPECLASS_REAL: switch(size) {
...

Proposal

Fix these examples. Add an advice to users to be very explicit about not using case-switch on constants, including error codes, other than MPI_SUCCESS, which is explicitly defined to be zero.

Changes to the Text

There are two complietly different proposals:

Impact on Implementations

Implementations are not required to change.

Impact on Users

Code that assumes these are compile-time constants is wrong and needs to change.

References and Pull Requests

Pull request PR 821 solves both issues https://github.com/mpi-forum/mpi-issues/issues/705 and https://github.com/mpi-forum/mpi-issues/issues/657. Pull request PR 775 solves only issue https://github.com/mpi-forum/mpi-issues/issues/657 and is obsolete if we decide to solve both issues through PR 821.

eschnett commented 2 years ago

The quoted statement from the standard is unambiguous for C, but does not really make sense for Fortran. "initialization expressions" are very different in these two languages.

Fortran does not make a distinction between "initialization expressions" and "switch/case statements". Both need to be compile-time constants, i.e. both need to be declared as parameter. This paragraph should be modify to reflect this.

One resolution would be to split the paragraph into two, one that discusses C and one that discusses Fortran. The former (discussing C) can remain as is. The latter (discussing Fortran) should be changed to not make a distinction between "compile-time" and "link-time" constants. I believe that this distinction does not exist in Fortran (certainly not in the standard, and to my knowledge also not in practice). This means that Fortran MPI constants are all required to be compile-time constants, i.e. need to be declared as parameter.

Another option would be to loosen the requirement to allow values that are not declared as constant, i.e. essentially global variables (formerly known as "common block entries"). However, this would break existing Fortran codes that use MPI, because this would then disallow using these MPI constants in initialization expressions.

jeffhammond commented 1 year ago

I agree we need to clean this up, but since the need for Fortran constants to use PARAMETER isn't debatable, I think it's okay to roll it into MPI-5 ABI efforts.

wesbland commented 1 year ago

I agree we need to clean this up, but since the need for Fortran constants to use PARAMETER isn't debatable, I think it's okay to roll it into MPI-5 ABI efforts.

Based on this comment, I'm going to move this to MPI 5.

jeffhammond commented 1 year ago

I'd like to have this one done as a chapter committee change (CCC) in 4.1. It's well within the guardrails we established for a CCC.

RolfRabenseifner commented 1 year ago

Is there any reason, why non-handle constants should not be implemented as compile-time constants in C? Does there exist any MPI implementation that did not implement non-handle constants as compile-time constants in C?

In the errata Issue https://github.com/mpi-forum/mpi-issues/issues/705 , all Fortran handles (except the MPI_BOTTOM, ... list) will be already compile-time constants, because Fortran does not support link-time constants.

jeffhammond commented 1 year ago

The implementation of C and Fortran constants can be different. It is so for buffer address constants already.

Many integer constants will be compile time constants. Some are required to be.

RolfRabenseifner commented 1 year ago

The changes in PR 821 are marked with PR821 and also in yellow color on pages 18, 1013, 1015, 1042 in mpi41-report_Issue705+657_PR821.pdf