Last active
August 29, 2015 14:14
-
-
Save bosilca/1716cbc1e71a3dd0baf4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: datatypes.tex | |
=================================================================== | |
--- datatypes.tex (revision 1835) | |
+++ datatypes.tex (working copy) | |
@@ -128,6 +128,7 @@ | |
lb(Typemap) & = & \min_j disp_j , \nonumber \\ | |
ub(Typemap) & = & \max_j (disp_j + \mpicode{sizeof}(type_j)) + \epsilon , \mbox{ and} | |
\nonumber \\ extent(Typemap) & = & ub(Typemap) - lb(Typemap). | |
+\label{soft-lb-ub-definition} | |
\end{eqnarray} | |
If $type_j$ requires alignment to a byte address that | |
is | |
@@ -141,7 +142,7 @@ | |
\ftype{BIND(C)} derived types, | |
or derived types that are neither \ftype{SEQUENCE} nor \ftype{BIND(C)}. | |
The complete definition of \mpiterm{extent} is given | |
-in \sectionref{subsec:pt2pt-markers}. | |
+by Equation~\ref{soft-lb-ub-definition} \sectionref{sec:pt2pt-datatype}. | |
\begin{example} | |
@@ -1311,11 +1312,30 @@ | |
specify the absolute address of the entries in the communication | |
buffer, in which case the \mpiarg{buf} argument is passed the value | |
\const{MPI\_BOTTOM}. | |
+Note that in Fortran \consti{MPI\_BOTTOM} is not usable for initialization or | |
+assignment, see Section~\ref{subsec:named-constants}. | |
The address of a location in memory can be found by invoking the | |
function\flushline | |
\mpifunc{MPI\_GET\_ADDRESS}. | |
+The relative displacement between two absolute addresses | |
+can be calculated with the function \mpifunc{MPI\_AINT\_DIFF}. A new absolute | |
+address as sum of an absolute base address and a relative displacement can be | |
+calculated with the function \mpifunc{MPI\_AINT\_ADD}. To ensure portability, | |
+arithmetic on absolute addresses should not be performed with the intrinsic | |
+operators ``-'' and ``+''. See also Sections \ref{subsec:displacement} and | |
+\ref{subsec:pt2pt-segmented} on pages \pageref{subsec:displacement} and | |
+\pageref{subsec:pt2pt-segmented}. | |
+ | |
+\begin{rationale} | |
+Address sized integer values, i.e., \type{MPI\_Aint} or | |
+\ftype{INTEGER(KIND=MPI\_ADDRESS\_KIND)} values, are signed integers, while | |
+absolute addresses are unsigned quantities. Direct arithmetic on addresses | |
+stored in address sized signed variables can cause overflows, resulting in | |
+undefined behavior. | |
+\end{rationale} | |
+ | |
\begin{funcdef}{MPI\_GET\_ADDRESS(location, address)} | |
\funcarg{\IN}{location}{location in caller memory (choice)} | |
\funcarg{\OUT}{address}{address of location (integer)} | |
@@ -1331,17 +1351,6 @@ | |
Returns the (byte) address of \mpiarg{location}. | |
-\begin{users} | |
-Current Fortran \MPI/ codes will run unmodified, and will port to any | |
-system. However, they may fail if addresses larger than $2^{32} -1$ | |
-are used in the program. New codes should be written so that they use | |
-the new functions. This provides compatibility | |
-with C/C++ and avoids errors on 64 bit architectures. However, such | |
-newly written codes may need to be (slightly) rewritten to port to old | |
-Fortran 77 environments that do not support \constskip{KIND} | |
-declarations. | |
-\end{users} | |
- | |
\begin{rationale} | |
In the \code{mpi\_f08} module, the \mpiarg{location} argument is not defined | |
with \ftype{INTENT(IN)} because existing applications may use | |
@@ -1364,7 +1373,7 @@ | |
INTEGER(KIND=MPI_ADDRESS_KIND) I1, I2, DIFF | |
CALL MPI_GET_ADDRESS(A(1,1), I1, IERROR) | |
CALL MPI_GET_ADDRESS(A(10,10), I2, IERROR) | |
- DIFF = I2 - I1 | |
+ DIFF = MPI_AINT_DIFF(I2, I1) | |
! The value of DIFF is 909*sizeofreal; the values of I1 and I2 are | |
! implementation dependent. | |
\end{verbatim} | |
@@ -1408,6 +1417,62 @@ | |
%% ``{\sf Temporary Data Movements}'' and ``{\sf Permanent Data Movements}''. | |
\end{users} | |
+To ensure portability, arithmetic on MPI addresses must be | |
+performed using the \mpifunc{MPI\_AINT\_ADD} | |
+and \mpifunc{MPI\_AINT\_DIFF} functions. | |
+ | |
+\begin{funcdef}{MPI\_AINT\_ADD(base, disp)} | |
+\funcarg{\IN}{base}{base address (integer)} | |
+\funcarg{\IN}{disp}{displacement (integer)} | |
+\end{funcdef} | |
+ | |
+\cdeclindex{MPI\_Aint}% | |
+\mpibindnotint{MPI\_Aint MPI\_Aint\_add(MPI\_Aint base, MPI\_Aint disp)} | |
+ | |
+\mpifnewbind{INTEGER(KIND=MPI\_ADDRESS\_KIND) MPI\_Aint\_add(base, disp) \fargs INTEGER(KIND=MPI\_ADDRESS\_KIND), INTENT(IN) :: base, disp} | |
+\mpifbind{INTEGER(KIND=MPI\_ADDRESS\_KIND) MPI\_AINT\_ADD(BASE, DISP) \fargs INTEGER(KIND=MPI\_ADDRESS\_KIND) BASE, DISP} | |
+ | |
+\mpifunc{MPI\_AINT\_ADD} produces a new \consti{MPI\_Aint} value that is | |
+equivalent to the sum of the \mpiarg{base} and \mpiarg{disp} arguments, where | |
+\mpiarg{base} represents a base address returned by a call to | |
+\mpifunc{MPI\_GET\_ADDRESS} and \mpiarg{disp} represents a signed integer | |
+displacement. The resulting address is valid only at the process that generated | |
+\mpiarg{base}, and it must correspond to a location in the same object | |
+referenced by \mpiarg{base}, as described in | |
+Section~\ref{subsec:pt2pt-segmented}. The addition is performed in a manner | |
+that results in the correct \consti{MPI\_Aint} representation of the output | |
+address, as if the process that originally produced \mpiarg{base} had called: | |
+ | |
+\begin{verbatim} | |
+MPI_Get_address((char *) base + disp, &result) | |
+\end{verbatim} | |
+ | |
+\begin{funcdef}{MPI\_AINT\_DIFF(addr1, addr2)} | |
+\funcarg{\IN}{addr1}{minuend address (integer)} | |
+\funcarg{\IN}{addr2}{subtrahend address (integer)} | |
+\end{funcdef} | |
+ | |
+\cdeclindex{MPI\_Aint}% | |
+\mpibindnotint{MPI\_Aint MPI\_Aint\_diff(MPI\_Aint addr1, MPI\_Aint addr2)} | |
+ | |
+\mpifnewbind{INTEGER(KIND=MPI\_ADDRESS\_KIND) MPI\_Aint\_diff(addr1, addr2) \fargs INTEGER(KIND=MPI\_ADDRESS\_KIND), INTENT(IN) :: addr1, addr2} | |
+\mpifbind{INTEGER(KIND=MPI\_ADDRESS\_KIND) MPI\_AINT\_DIFF(ADDR1, ADDR2) \fargs INTEGER(KIND=MPI\_ADDRESS\_KIND) ADDR1, ADDR2} | |
+ | |
+\mpifunc{MPI\_AINT\_DIFF} produces a new \consti{MPI\_Aint} value that is | |
+equivalent to the difference between \mpiarg{addr1} and \mpiarg{addr2} | |
+arguments, where \mpiarg{addr1} and \mpiarg{addr2} represent addresses returned | |
+by calls to \mpifunc{MPI\_GET\_ADDRESS}. The resulting address is valid only | |
+at the process that generated \mpiarg{addr1} and \mpiarg{addr2}, and | |
+\mpiarg{addr1} and \mpiarg{addr2} must correspond to locations in the same | |
+object in the same process, as described in | |
+Section~\ref{subsec:pt2pt-segmented}. The difference is calculated in a manner | |
+that results the signed difference from \mpiarg{addr1} to \mpiarg{addr2}, as if | |
+the process that originally produced the addresses had called | |
+% | |
+\verb#(char *) addr1 - (char *) addr2# | |
+% | |
+on the addresses initially passed to \mpifunc{MPI\_GET\_ADDRESS}. | |
+ | |
The following auxiliary functions provide useful information on | |
derived datatypes. | |
@@ -1640,7 +1705,7 @@ | |
Returns the lower bound and the extent of | |
\mpiarg{datatype} | |
-(as defined in \sectionref{subsec:pt2pt-markers}). | |
+(as defined in Equation \ref{soft-lb-ub-definition} page \pageref{soft-lb-ub-definition}). | |
For both functions, if either \OUT\ parameter cannot express the value | |
to be returned (e.g., if the parameter is too small to hold the output | |
@@ -2947,7 +3012,7 @@ | |
MPI_Get_address(particle[0].d, disp+1); | |
MPI_Get_address(particle[0].b, disp+2); | |
base = disp[0]; | |
-for (i=0; i < 3; i++) disp[i] -= base; | |
+for (i=0; i < 3; i++) disp[i] = MPI_Aint_diff(disp[i], base); | |
MPI_Type_create_struct(3, blocklen, disp, type, &Particlestruct); | |
@@ -2957,7 +3022,7 @@ | |
/* compute extent of the structure */ | |
MPI_Get_address(particle+1, &sizeofentry); | |
-sizeofentry -= base; | |
+sizeofentry = MPI_Aint_diff(sizeofentry, base); | |
/* build datatype describing structure */ | |
@@ -3179,7 +3244,7 @@ | |
MPI_Get_address(u, &i); | |
MPI_Get_address(u+1, &extent); | |
-extent -= i; | |
+extent = MPI_Aint_diff(extent, i); | |
MPI_Type_create_resized(MPI_INT, 0, extent, &mpi_utype[0]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment