- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, I'm wondering if there exists a way (other than branching) for exiting or cycling within a inner block in a do block:
... do i=1,10 block integer :: k ... if (...) then ... cycle !not possible end if ... end block end do
More general, the question is, if its possible to terminate the execution of a block-construct without using IF/GOTO? I've looked into the standard but I've found no other possibilities...
IMO such a feature would be especially usefull in combination with DO CONCURRENT and the need of iteration local variables.
Thanks
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Is this what you had in mind?
program test implicit none integer :: i DOXYZ: do i=1,10 block integer :: k k=-100 if (mod(i,3).eq.0) then k=i*i+1 write(*,*)'For i = ',i,', k set to ',k,', cycling' cycle DOXYZ end if end block write(*,*)'Block ended with i = ',i end do DOXYZ end program
If not, and you really want CYCLE and EXIT to apply to just the block and not to the entire loop body, I don't know what the meaning of CYCLE should then be, because the block is not by itself a construct for repetition. Similarly, allowing EXIT to exit the block construct would give that construct a facility that is not provided in the older IF ... THEN ... ELSE...ENDIF construct.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Not sure I too understand what exactly you mean by CYCLE an inner block - if you want to cycle, why not make the inner block a DO loop also?
Anyways, note EXIT statement is supported in BLOCK construct per Fortran 2008 standard and if I'm not mistaken (Intel can confirm), this feature will be available in Intel Fortran starting with 16.0 release (you can test it in 16.0 beta). See a use for it in a branch prediction pattern in message#5 of this thread: https://software.intel.com/en-us/forums/topic/516000.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for your answer!
Hmm strange...
Okay I've tested your example and it works even without the use of a label. In my particular code I'm using it within a module procedure and for some curious reason the compiler gives me the error message:
error #6604: The construct name in the CYCLE statement does not match any DO construct to which the CYCLE statement belongs. [DOXYZ] cycle DOXYZ --------------------------^
without the label:
error #6602: A CYCLE or EXIT statement must not be used with a non-DO block. cycle --------------------^
Maybe a bug? I'm using ifort 16.0 beta
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We would have to see the full context (module source code, complete) to reproduce and understand what the compiler is saying.
My example code has just a single loop, so the label XYZ is not needed. However, if you had two nested DO loops, you might need labels if you wanted the CYCLE inside the BLOCK construct to cycle the outer DO loop rather than the inner DO loop.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When I modify your example, so that I would only exit the block and not the loop and change the DO to a DO CONCURRENT:
program test implicit none integer :: i do concurrent (i=1:10) block integer :: k k=-100 if (mod(i,3).eq.0) then k=i*i+1 write(*,*)'For i = ',i,', k set to ',k,', cycling' exit end if end block write(*,*)'Block ended with i = ',i end do end program
I get the error message:
error #8432: An EXIT statement shall not belong to a DO CONCURRENT construct. exit ------------^
So the exit statement gets associated with the do-construct and not with the block-construct. I'm not sure if a block-construct even understands the exit command. The standard says:
6 2 An EXIT statement belongs to a particular construct. If a construct name appears, the EXIT statement belongs 7 to that construct; otherwise, it belongs to the innermost DO construct in which it appears.
If I name the block:
program test implicit none integer :: i do concurrent (i=1:10) DOXYZ: block integer :: k k=-100 if (mod(i,3).eq.0) then k=i*i+1 write(*,*)'For i = ',i,', k set to ',k,', cycling' exit DOXYZ end if end block DOXYZ write(*,*)'Block ended with i = ',i end do end program
I get the error:
error #8490: Transfer of control to the interior of this block from outside the block is prohibited. [LA]
Buuh, that seems all too strange to me...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Both of those from post 6 look like compiler bugs to me. I will escalate them to development. Issue ID is DPD200372670.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The first compiler error from post 6 might actually not be a bug: As quoted above, the standard says, that a exit statement gets automatically associated with the innermost loop when a name is omitted, even though the standard also prohibits the use of an exit statement in combination with a do concurrent loop...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You're right - I had not noticed that. This rule needed to be added to prevent changing the meaning of F2003-compliant code. Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Regarding #8
I see nothing inherently wrong with an exit in a DO CONCURRENT because it is the responsibility of the programmer to make sense of what happens due to the discrepancies resulting from the loop actually being performed concurrently (multiple threads), concurrently (multiple vector lanes) or sequentially.
As an approximate equivalent, assume an array of random data, where you use a parallel do to perform a search, or DO CONCURRENT to perform the search. Where any of the concurrencies that can find a match can exit and cause the other concurrencies to exit, with the caveated that the first match temporally found is not necessarily the match returned (race condition), nor is the match returned necessarily the same as that returned had the array been searched sequentially. The programmer assumes the responsibility to sort this out.
Parallel do does not have this capability, neither does do concurrent, but you can start a parallel region, split the array into sections, have each thread search the section using a for loop, and if found a match, inform all threads a match was found (thus causing the additional threads to abort their search). This is not an unusual circumstance, and I see no reason why exit cannot be treated in this way.
This said, there are too many other programmers, not willing to take on the responsibility, and wanting the compiler to say "can't do that". IMHO this this should be a warning, not an error.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I forgot to add an additional 2 cents
Inside the DO CONCURRENT and inside the PARALLE DO it is perfectly acceptable to have a STOP statement, which essentially forces all concurrencies to exit, not only the loop but the process as well.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The bug will be fixed in 16.0 Update 1.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks!

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page