|
|
 |
 |
 |
 |
Fortran Programming Language
|
 |
 |
 |
 |
 |
 |
 |
 |
Thread-safe Fortran
"Colin Watters" <qolin.see_signat @nowhere.co.uk> wrote in message news:f44l4j$i8p$1$830fa7a5@news.demon.co.uk... > I am interested in this, having taken some steps to convert one of my DLLs > towards thread-safety. I wonder if folks here have any more comments or > insights on this.
Declare all of your procedures as PURE or RECURSIVE. This guarantees that local variables will not be shared between instances if you didn't give them the SAVE attribute. See ISO/IEC 1539-1:1997(E), sections 7.5.2.3, 12.5.2.4. -- write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, & 6.0134700243160014d-154/),(/'x'/)); end
James Van Buskirk wrote:
(snip) > Declare all of your procedures as PURE or RECURSIVE. This > guarantees that local variables will not be shared between > instances if you didn't give them the SAVE attribute. See > ISO/IEC 1539-1:1997(E), sections 7.5.2.3, 12.5.2.4.
RECURSIVE makes sense to me, but PURE isn't so obvious. Some of the names IBM uses are REENTRANT, REFRESHABLE, and SERIALLY REUSABLE. It isn't obvious to me that PURE can't be only SERIALLY REUSABLE, unless PURE implies RECURSIVE. -- glen
On 6 jun, 07:56, glen herrmannsfeldt <g@ugcs.caltech.edu> wrote:
> James Van Buskirk wrote: > (snip) > > Declare all of your procedures as PURE or RECURSIVE. This > > guarantees that local variables will not be shared between > > instances if you didn't give them the SAVE attribute. See > > ISO/IEC 1539-1:1997(E), sections 7.5.2.3, 12.5.2.4. > RECURSIVE makes sense to me, but PURE isn't so obvious. > Some of the names IBM uses are REENTRANT, REFRESHABLE, > and SERIALLY REUSABLE. It isn't obvious to me that PURE can't > be only SERIALLY REUSABLE, unless PURE implies RECURSIVE. > -- glen
PURE would imply many things - I do not think you are allowed to use the SAVE attribute then, as this would violate the idea that any invocation of the routine with the same arguments should have the same result. If you use RECURSIVE you will not have the restrictions that are involved with PURE, but for thread-safety you need to be very careful when setting variables outside the routine (variables in the module the routine belongs to for instance). At any one time such variables must have a well-defined value and if two threads can independently change the value, then you have a perfect receipe for disaster, actually a disaster that can be very difficult to track down (perhaps even detect that it is there!) But RECURSIVE is definitely a necessary (but not sufficient) condition - some compilers define the local variables in a routine to be static, with an option to change that, but you do not want to rely on that! It is all too easy to forget it. Regards, Arjen
Arjen Markus wrote: > On 6 jun, 07:56, glen herrmannsfeldt <g @ugcs.caltech.edu> wrote: ... >> RECURSIVE makes sense to me, but PURE isn't so obvious. >> Some of the names IBM uses are REENTRANT, REFRESHABLE, >> and SERIALLY REUSABLE. It isn't obvious to me that PURE can't >> be only SERIALLY REUSABLE, unless PURE implies RECURSIVE. ... > PURE would imply many things - I do not think you are allowed > to use the SAVE attribute then, as this would violate the > idea that any invocation of the routine with the same arguments should > have the same result.
But Fortran's definition of PURE *doesn't* require that invocations of the routine with the same arguments should have the same result. A function with no arguments at all that returns the value of some expression involving MODULE or COMMON variables can be declared PURE in Fortran. Such variables can change between calls to such a PURE procedure. There is a constraint that no local variables can have the SAVE attribute if the procedure is PURE, but the above isn't the reason (since that proposed reason isn't guaranteed anyway). The conventional definition of PURE (as found, for example, in the Wikipedia listing for pure functions) is not Fortran's definition. It's important to bear that in mind. Procedures with SAVEd local variables, or that use MODULE and/or COMMON variables, can be made thread safe provided you guard all uses or definitions of such variables with monitors or semaphors or some other such feature. It can even be quite useful to have such things. (Of course, *standard* Fortran doesn't have such features, but many implementations that permit multiple threads provide them as extensions.) -- J. Giles "I conclude that there are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies." -- C. A. R. Hoare
"Arjen Markus" <arjen.mar @wldelft.nl> wrote in message news:1181111383.194251.296200@n4g2000hsb.googlegroups.com... > But RECURSIVE is definitely a necessary (but not sufficient) > condition - some compilers define the local variables in a > routine to be static, with an option to change that, but > you do not want to rely on that! It is all too easy to forget it.
You seem to have been distracted by the irrelevances that Glen delights in posting as followups to my posts. Here I was trying to point out that PURE or RECURSIVE imply that local variables in a procedure are AUTOMATIC -- something you can't say otherwise in Fortran (at least f95) without an extension. PURE does not imply RECURSIVE because a specification function must be PURE but not RECURSIVE. PURE procedures, like RECURSIVE ones, are designed to have multiple active instances because their instances may be invoked in any order, which in my perception counts concurrent order. Thus the compiler can't arbitrarily make local variables of a PURE procedure have the SAVE attribute because then you could detect a violation of 12.5.2.4 during concurrent execution. -- write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, & 6.0134700243160014d-154/),(/'x'/)); end
James Van Buskirk wrote:
(snip) > You seem to have been distracted by the irrelevances that Glen > delights in posting as followups to my posts. Here I was trying > to point out that PURE or RECURSIVE imply that local variables in > a procedure are AUTOMATIC -- something you can't say otherwise in
This gets to the point of my post... > Fortran (at least f95) without an extension. PURE does not imply > RECURSIVE because a specification function must be PURE but not > RECURSIVE. PURE procedures, like RECURSIVE ones, are designed > to have multiple active instances because their instances may be > invoked in any order, which in my perception counts concurrent
but does it count in the standard as concurrent? > order. Thus the compiler can't arbitrarily make local variables > of a PURE procedure have the SAVE attribute because then you could > detect a violation of 12.5.2.4 during concurrent execution.
I see PURE described as needed for FORALL expressions, and FORALL indicates that the evaluations may be done in any order. I don't see any statement that PURE is sufficient for concurrent execution. I might have missed it, though. -- glen
glen herrmannsfeldt <g @ugcs.caltech.edu> wrote: > I see PURE described as needed for FORALL expressions, and FORALL > indicates that the evaluations may be done in any order. I don't > see any statement that PURE is sufficient for concurrent execution. > I might have missed it, though. You won't see that statement in quite those terms in the standard - certainly not in the normative text - because that's an implementation issue. However, it is absolutely certain that PURE was designed to allow concurrent execution. Whether the words in the standard exactly say that is beside the point. Whether it achieves it is also perhaps a didfferent point. That *WAS* the intention. I was there and, while the intentions of some things are hard to say precisely, this isn't one of those things. PURE was imported from HPF, which had the primary goal of facilitaing parallelism. Once it was there, PURE did also get adopted to other purposes. But it cam in first as a facilitator of parallelism. The execution model of Fortran, through at least f2003 is one of sequential execution. (I've heard that the coarray stuff proposed in f2008 has some major changes there, but I'll stick to f2003 and below for this). However, there are portions of the standard that are consciously designed to facilitate various optimizations such as parallel computation. (Some might find it slightly odd to call parallel computation an optimization, but at some level one can view it that way). PURE was part of one of those packages. -- Richard Maine | Good judgement comes from experience; email: last name at domain . net | experience comes from bad judgement. domain: summertriangle | -- Mark Twain
glen herrmannsfeldt wrote: > James Van Buskirk wrote: >> order. Thus the compiler can't arbitrarily make local variables >> of a PURE procedure have the SAVE attribute because then you could >> detect a violation of 12.5.2.4 during concurrent execution. > I see PURE described as needed for FORALL expressions, and FORALL > indicates that the evaluations may be done in any order. I don't > see any statement that PURE is sufficient for concurrent execution. > I might have missed it, though.
PURE is sufficient to _allow_ the processor to set up things such that the function can be called multiple times concurrently; this can be deduced from the description. PURE does not guarantee that the processor will set things up such that the function can be called multiple times concurrently; as a trivial contradiction, the processor may not support concurrent processing. Any times that the processor happens to interpret standard-conforming Fortran in a way that includes concurrent processing, it must do so in a thread-safe manner or else will not conform to the standard. If a processor includes extensions to allow the programmer to specify that something is executed concurrently (e.g., OpenMP), then that is non-standard, and the standard says nothing about it. However, in cases where the processor includes such extensions, implementing PURE functions in a non-thread-safe way would be a startlingly poor quality of implementation. - Brooks -- The "bmoses-nospam" address is valid; no unmunging needed.
Brooks Moses wrote:
(snip) > PURE is sufficient to _allow_ the processor to set up things such that > the function can be called multiple times concurrently; this can be > deduced from the description. > PURE does not guarantee that the processor will set things up such that > the function can be called multiple times concurrently; as a trivial > contradiction, the processor may not support concurrent processing.
This sounds like what I was considering when writing the previous posts. > Any times that the processor happens to interpret standard-conforming > Fortran in a way that includes concurrent processing, it must do so in a > thread-safe manner or else will not conform to the standard. If a > processor includes extensions to allow the programmer to specify that > something is executed concurrently (e.g., OpenMP), then that is > non-standard, and the standard says nothing about it. However, in cases > where the processor includes such extensions, implementing PURE > functions in a non-thread-safe way would be a startlingly poor quality > of implementation.
If the concurrent implementations is done by adding routines to a non-concurrent implementation, such as calling C routines implementing MPI from a non-concurrent Fortran implementation, it would not be surprising to find a non-thread-save PURE. Even RECURSIVE might not be thread-safe, though it does require a separate copy of all local variables. -- glen
Hello, Richard Maine wrote: > The execution model of Fortran, through at least f2003 is one of > sequential execution. (I've heard that the coarray stuff proposed in > f2008 has some major changes there, but I'll stick to f2003 and below > for this). However, there are portions of the standard that are > consciously designed to facilitate various optimizations such as > parallel computation. (Some might find it slightly odd to call parallel > computation an optimization, but at some level one can view it that > way). PURE was part of one of those packages.
The new DO CONCURRENT is another parallel structure. In fact, parts of it are taken from FORALL. -- Dan Nagle Purple Sage Computing Solutions, Inc.
On 6 jun, 18:39, "James Van Buskirk" <not_va@comcast.net> wrote:
> "Arjen Markus" <arjen.mar @wldelft.nl> wrote in message > news:1181111383.194251.296200@n4g2000hsb.googlegroups.com... > > But RECURSIVE is definitely a necessary (but not sufficient) > > condition - some compilers define the local variables in a > > routine to be static, with an option to change that, but > > you do not want to rely on that! It is all too easy to forget it. > You seem to have been distracted by the irrelevances that Glen > delights in posting as followups to my posts. Here I was trying > to point out that PURE or RECURSIVE imply that local variables in > a procedure are AUTOMATIC -- something you can't say otherwise in > Fortran (at least f95) without an extension. PURE does not imply > RECURSIVE because a specification function must be PURE but not > RECURSIVE. PURE procedures, like RECURSIVE ones, are designed > to have multiple active instances because their instances may be > invoked in any order, which in my perception counts concurrent > order. Thus the compiler can't arbitrarily make local variables > of a PURE procedure have the SAVE attribute because then you could > detect a violation of 12.5.2.4 during concurrent execution.
But PURE restricts a number of other things you might like to do, I was thinking of writing debug output to a file. You can't do that in a PURE subprogram, but you can if the subprogram is declared RECURSIVE. (And there are restrictions to the use of variables from outside the local scope, but then you would need to be very careful with these uses any way.) I was imperfectly alluding to those extra restrictions. Regards, Arjen
|
 |
 |
 |
 |
|