I’ve added a wiki page for the const correctness proposal,
please review.
http://svn.mpi-forum.org/trac/mpi-forum-web/wiki/ConstCorrectness
thanks,
.Erez
From:
mpi-conts-bounces@lists.mpi-forum.org
[mailto:mpi-conts-bounces@lists.mpi-forum.org] On Behalf Of Erez Haba
Sent: Wednesday, February 27, 2008 1:50 PM
To: mpi-conts@lists.mpi-forum.org
Subject: Re: [Mpi-conts] MPI wokgroup - adding const keyword to the C
bindings
For those who were not able to read the pptx slides here’s
a ppt version.
From: Erez Haba
Sent: Tuesday, February 26, 2008 9:22 AM
To: 'mpi-conts@lists.mpi-forum.org'
Subject: MPI wokgroup - adding const keyword to the C bindings
Hello all,
This email thread discusses the proposal to add const
correctness to the MPI C bindings. Below you can find the original proposal and
attached is the slides presented at the Jan forum meeting.
To be able to present this proposal in the March forum meeting I
think that we still need to work on few items, specifically the motivation for
this proposal and addressing concerned that were raised before.
The TODO list includes,
-
Post this proposal on
the wiki pages
-
Review/rewrite the
executive summary of this proposal. (any suggestions?)
-
Address issues that
were raised as cons for this proposal.
Specifically backward compatibility and clarify the (incorrect)
claim that the C standard does not allow a function to modify an object passed
in as const (using another pointer).
-
Any other issues
raised (or not) that the proposal is missing?
-
Review the changes to
the standard as proposed below for completeness.
That is, the proposal below just addresses the API. a) is this
complete? b) are there any other required text modification to the standard?
-
Prototype the proposal
(i.e., have a mpi.h header file) and test it.
I can test the header with the ANL, Intel test suites plus a
handful of others.
I think that we need one conf call to discuss this proposal.
(I’m shooting for Mon/Tue/Wed next week at 9am PST)
Let me know what you think.
Thanks,
.Erez
P.S. note that the list name is misspelled as mpi-conts (not
const) when you’re sending email.
From:
owner-mpi-21@mpi-forum.org [mailto:owner-mpi-21@mpi-forum.org] On Behalf Of Erez
Haba
Sent: Monday, December 17, 2007 11:48 PM
To: mpi-21@mpi-forum.org
Subject: [mpi-21] Proposal EH2: add const keyword to the C bindings
This
is the proposal to add the const keyword to the MPI C bindings
where appropriate. I think that this change is appropriate for the MPI 2.2
revision.
Thanks,
.Erez
Background:
The
const keyword in C defines a contract between the library implementer and the
library user. Using the const keyword the library contracts that it will not
change its input object. This contract enables some compile-time optimization,
but more important it provides clearer and const-correct interface to the
library user. (more on http://en.wikipedia.org/wiki/Const_correctness)
The
MPI C bindings as defined by the MPI 1.1 & 2.0 standards are missing the const
keyword for many of the input only parameters.
Proposal:
Add
the const keyword to the API’s listed below.
Rational:
The
missing const keyword means that the contract between the user and the MPI
library is weaker than it should be. Users need to cast away const-ness before calling
MPI and compilers cannot optimize the caller or the library code taking into
account the const-ness of the parameter.
The
C++ binding has already implemented a const correct interface. This change
catches up with the C++ interface. (I notice that C++ interface implementations
cast away the const-ness when calling their C binding).
Backward
Compatibility:
There
should not be any backward compatibility issue: already compiled programs
should run without a problem with a new dynamically loaded library as there is
no change to the size of the parameters. The C linkers do not check for const
correctness, thus no error here. Recompiled programs should see no new
compilation errors or warning since the const keyword guarantees a stronger
contract; any non const pointer is automatically promoted to be const.
Cons:
Compilers
that still do not support the const keyword.
MPI
library implementations need to change their C header files.
Source
level backward compatibility issue, in-case I am wrong.
Note:
adding the const keyword to the point-to-point and collectives API’s send
buffer depends on the “Proposal EH1: Send buffer access”.
Adding
the const keyword:
I
have compiled the list of API’s that are missing the const keywords.
I’ve grouped these API’s by functionality and the parameter where
the const keyword is applied. The last section lists 4 API’s where I
suggest not adding the const keyword as it would break source level backward
compatibility.
/* Point-to-point send buffer */
int
MPI_Bsend(const void*, int, MPI_Datatype, int, int, MPI_Comm);
int
MPI_Bsend_init(const void*, int, MPI_Datatype, int,int, MPI_Comm,
MPI_Request*);
int
MPI_Ibsend(const void*, int, MPI_Datatype, int, int, MPI_Comm,
MPI_Request*);
int
MPI_Irsend(const void*, int, MPI_Datatype, int, int, MPI_Comm,
MPI_Request*);
int
MPI_Isend(const void*, int, MPI_Datatype, int, int, MPI_Comm,
MPI_Request*);
int
MPI_Issend(const void*, int, MPI_Datatype, int, int, MPI_Comm,
MPI_Request*);
int
MPI_Rsend(const void*, int, MPI_Datatype, int, int, MPI_Comm);
int
MPI_Rsend_init(const void*, int, MPI_Datatype, int,int, MPI_Comm,
MPI_Request*);
int
MPI_Send(const void*, int, MPI_Datatype, int, int, MPI_Comm);
int
MPI_Send_init(const void*, int, MPI_Datatype, int, int, MPI_Comm,
MPI_Request*);
int
MPI_Sendrecv(const void*, int, MPI_Datatype,int, int, void*, int,
MPI_Datatype, int, int, MPI_Comm, MPI_Status*);
int
MPI_Sendrecv_replace(void*, int, MPI_Datatype, int, int, int, int, MPI_Comm,
MPI_Status*);
int
MPI_Ssend(const void*, int, MPI_Datatype, int, int, MPI_Comm);
int
MPI_Ssend_init(const void*, int, MPI_Datatype, int,int, MPI_Comm,
MPI_Request*);
/* Collectives send buffer */
int
MPI_Accumulate(const void*, int, MPI_Datatype, int, MPI_Aint, int,
MPI_Datatype, MPI_Op, MPI_Win);
int
MPI_Allgather(const void* , int, MPI_Datatype, void*, int, MPI_Datatype,
MPI_Comm);
int
MPI_Allgatherv(const void* , int, MPI_Datatype, void*, const
int*, const int*, MPI_Datatype, MPI_Comm);
int
MPI_Allreduce(const void* , void*, int, MPI_Datatype, MPI_Op, MPI_Comm);
int
MPI_Alltoall(const void* , int, MPI_Datatype, void*, int, MPI_Datatype,
MPI_Comm);
int
MPI_Alltoallv(const void* , const int*, const int*,
MPI_Datatype, void*, const int*, const int*, MPI_Datatype,
MPI_Comm);
int
MPI_Alltoallw(const void*, const int [], const int [],
MPI_Datatype [], void*, const int [], const int [], MPI_Datatype
[], MPI_Comm);
int
MPI_Exscan(const void*, void*, int, MPI_Datatype, MPI_Op, MPI_Comm) ;
int
MPI_Gather(const void* , int, MPI_Datatype, void*, int, MPI_Datatype,
int, MPI_Comm);
int
MPI_Gatherv(const void* , int, MPI_Datatype, void*, const int*, const
int*, MPI_Datatype, int, MPI_Comm);
int
MPI_Reduce(const void* , void*, int, MPI_Datatype, MPI_Op, int,
MPI_Comm);
int
MPI_Reduce_scatter(const void* , void*, const int*, MPI_Datatype,
MPI_Op, MPI_Comm);
int
MPI_Scan(const void* , void*, int, MPI_Datatype, MPI_Op, MPI_Comm );
int
MPI_Scatter(const void* , int, MPI_Datatype, void*, int, MPI_Datatype,
int, MPI_Comm);
int
MPI_Scatterv(const void* , const int*, const int*,
MPI_Datatype, void*, int, MPI_Datatype, int, MPI_Comm);
/* RMA put buffer */
int
MPI_Put(const void*, int, MPI_Datatype, int, MPI_Aint, int,
MPI_Datatype, MPI_Win);
/* File IO write buffer */
int
MPI_File_iwrite(MPI_File, const void*, int, MPI_Datatype,
MPIO_Request*);
int
MPI_File_iwrite_at(MPI_File, MPI_Offset, const void*, int, MPI_Datatype,
MPIO_Request*);
int
MPI_File_iwrite_shared(MPI_File, const void*, int, MPI_Datatype,
MPIO_Request*);
int
MPI_File_write(MPI_File, const void*, int, MPI_Datatype, MPI_Status*);
int
MPI_File_write_all(MPI_File, const void*, int, MPI_Datatype,
MPI_Status*);
int
MPI_File_write_all_begin(MPI_File, const void*, int, MPI_Datatype);
int
MPI_File_write_all_end(MPI_File, const void*, MPI_Status*);
int
MPI_File_write_at(MPI_File, MPI_Offset, const void*, int, MPI_Datatype,
MPI_Status*);
int
MPI_File_write_at_all(MPI_File, MPI_Offset, const void*, int,
MPI_Datatype, MPI_Status*);
int
MPI_File_write_at_all_begin(MPI_File, MPI_Offset, const void*, int, MPI_Datatype);
int
MPI_File_write_at_all_end(MPI_File, const void*, MPI_Status*);
int
MPI_File_write_ordered(MPI_File, const void*, int, MPI_Datatype,
MPI_Status*);
int
MPI_File_write_ordered_begin(MPI_File, const void*, int, MPI_Datatype);
int
MPI_File_write_ordered_end(MPI_File, const void*, MPI_Status*);
int
MPI_File_write_shared(MPI_File, const void*, int, MPI_Datatype,
MPI_Status*);
/* Input string */
int
MPI_Add_error_string(int, const char*);
int
MPI_Close_port(const char*);
int
MPI_Comm_accept(const char*, MPI_Info, int, MPI_Comm, MPI_Comm*);
int
MPI_Comm_connect(const char*, MPI_Info, int, MPI_Comm, MPI_Comm*);
int
MPI_Comm_set_name(MPI_Comm, const char*);
int
MPI_Comm_spawn(const char*, char*[], int, MPI_Info, int, MPI_Comm,
MPI_Comm*, int []);
int
MPI_File_delete(const char*, MPI_Info);
int
MPI_File_open(MPI_Comm, const char*, int, MPI_Info, MPI_File*);
int
MPI_File_set_view(MPI_File, MPI_Offset, MPI_Datatype, MPI_Datatype, const
char*, MPI_Info);
int
MPI_Info_delete(MPI_Info, const char*);
int
MPI_Info_get(MPI_Info, const char*, int, char*, int*);
int
MPI_Info_get_valuelen(MPI_Info, const char*, int*, int*);
int
MPI_Info_set(MPI_Info, const char*, const char*);
int
MPI_Lookup_name(const char*, MPI_Info, char*);
int
MPI_Publish_name(const char*, MPI_Info, const char*);
int
MPI_Type_set_name(MPI_Datatype, const char*);
int
MPI_Unpublish_name(const char*, MPI_Info, const char*);
int
MPI_Win_set_name(MPI_Win, const char*);
/* Index/Count arrays */
int
MPI_Cart_create(MPI_Comm, int, const int*, const int*, int,
MPI_Comm*);
int
MPI_Cart_map(MPI_Comm, int, const int*, const int*, const
int*);
int
MPI_Cart_rank(MPI_Comm, const int*, int*);
int
MPI_Cart_sub(MPI_Comm, const int*, MPI_Comm*);
int
MPI_Graph_create(MPI_Comm, int, const int*, const int*, int,
MPI_Comm*);
int
MPI_Graph_map(MPI_Comm, int, const int*, const int*, int*);
int
MPI_Group_excl(MPI_Group, int, const int*, MPI_Group*);
int
MPI_Group_incl(MPI_Group, int, const int*, MPI_Group*);
int
MPI_Group_translate_ranks(MPI_Group, int, const int*, MPI_Group, int*);
int
MPI_Type_create_darray(int, int, int, const int [], const int [],
const int [], const int [], int, MPI_Datatype, MPI_Datatype*);
int
MPI_Type_create_hindexed(int, const int [], const MPI_Aint [],
MPI_Datatype, MPI_Datatype*);
int
MPI_Type_create_indexed_block(int, int, const int [], MPI_Datatype,
MPI_Datatype*);
int
MPI_Type_create_struct(int, const int [], const MPI_Aint [], const
MPI_Datatype [], MPI_Datatype*);
int
MPI_Type_create_subarray(int, const int [], const int [], const
int [], int, MPI_Datatype, MPI_Datatype*);
int
MPI_Type_hindexed(int, const int*, const MPI_Aint*, MPI_Datatype,
MPI_Datatype*);
int
MPI_Type_indexed(int, const int*, const int*, MPI_Datatype,
MPI_Datatype*);
int
MPI_Type_struct(int, const int*, const MPI_Aint*, MPI_Datatype*,
MPI_Datatype*);
/* Pack/Unpack datarep string and input buffer */
int
MPI_Pack(const void*, int, MPI_Datatype, void*, int, int*,
MPI_Comm);
int
MPI_Pack_external(const char*, const void*, int, MPI_Datatype,
void*, MPI_Aint, MPI_Aint*);
int
MPI_Pack_external_size(const char*, int, MPI_Datatype, MPI_Aint*);
int
MPI_Unpack(const void*, int, const int*, void*, int,
MPI_Datatype, MPI_Comm);
int
MPI_Unpack_external(const char*, const void*, MPI_Aint,
MPI_Aint*, void*, int, MPI_Datatype);
/* Miscellany */
int
MPI_Address(const void*, MPI_Aint*);
int
MPI_Get_address(const void*, MPI_Aint*);
int
MPI_Status_c2f(const MPI_Status*, MPI_Fint*);
int
MPI_Status_f2c(const MPI_Fint*, MPI_Status*);
int
MPI_Test_cancelled(const MPI_Status*, int*);
/* NOT CHANGING the following API's to keep backward compatibility
and ease of use */
int
MPI_Comm_spawn(const char*, /*const*/char*[],
int, MPI_Info, int, MPI_Comm, MPI_Comm*, int []);
int
MPI_Comm_spawn_multiple(int, /*const*/char*[], /*const*/char**[], /*const*/int
[],/*const*/MPI_Info [], int, MPI_Comm,
MPI_Comm*, int []);
int
MPI_Group_range_excl(MPI_Group, int, /*const*/int
[][3], MPI_Group*);
int
MPI_Group_range_incl(MPI_Group, int, /*const*/int
[][3], MPI_Group*);