- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
After struggling at length with the FORALL construct, but eventually applying it with some level of comfort, it (of course) became deprecated.
Consequently, I have code for which I'm trying to replace FORALL constructs with DO CONCURRENT equivalents.
The following is a simplified equivalent of a more complex code, and I understand that DO CONCURRENT is not required for the intended result in this example, but it reproduces the compiler response that is giving me concern:
Program Test_Do_Concurrent
IMPLICIT NONE
Integer, Parameter :: NSpans=3,NBins=5
Integer :: ia,ib,ispan
Real :: DataSpan(2,NSpans),BinEdge(0:NBins,NSpans),BinWidth(NSpans)
Data DataSpan /0.,10., 0.,100., 0.,1000./
BinWidth = (DataSpan(2,:)-Dataspan(1,:))/NBins
Do Concurrent (ib=0:NBins, ia=1:NSpans)
BinEdge(ib,ia) = DataSpan(1,ia) + ib*BinWidth(ia)
EndDo
Do ispan=1,NSpans
Write(*,'(*(f0.0,2X))')BinEdge(:,ispan)
EndDo
End Program Test_Do_Concurrent
Curiously, although this compiles with no errors, the compiler flags the integers ia and ib as unused variables! But the code executes exactly as expected, which clearly indicates that ia and ib are used.
It gets weirder yet: the above was built in Visual Studio 2017, using Intel Parallel Studio XE 19.1.3.311, with the project configured as 64-bit. If I change the project configuration to x86 (32-bit), now the compiler recognizes ia and ib as used variables!
I gather from the Intel documentation of DO CONCURRENT (which I must confess did not significantly advance my understanding) that variables and functions in a DO CONCURRENT block are under very onerous restrictions, but it's not at all clear how that would cause them to become 'invisible' to the compiler, and moreover only in the 64-bit configuration.
I can only speculate that this has something to do with 'locality', another recent Fortran obfuscation that has me similarly baffled. Indeed, if I modify the Do Concurrent command to be:
Do Concurrent (ib=0:NBins, ia=1:NSpans) Shared(ia,ib)
as well as specify /Qparallel in the command line (after the compiler informed me that 'Shared' would be ignored unless I did so), then ia and ib are recognized as being used, in both 32-bit and 64-bit configurations.
Is there a straightforward (or arcane, if necessary) explanation for this behavior? Thanks for any info!
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ib and ia here are "construct entities", existing only within the DO CONCURRENT, but I agree that the compiler should not consider them unused. My guess is that it is a case that was overlooked - as the compiler goes along, it marks variables in its symbol table as used, and the construct entities are not the same ia and ib as outside the DO CONCURRENT, but the warning is still wrong.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Steve, thanks for your reply-
That makes sense, but the construct entities ia and ib in the DO CONCURRENT loop are apparently not completely autonomous from those defined outside the loop, because if I remove the declaration of ia and ib as integers in the main program, the compiler considers it a flat-out error for both ia and ib (#6404: This name does not have a type, and must have an explicit type), and points directly at the line executing the DO CONCURRENT. And the inconsistency in the compiler's response depending on 32-bit vs 64-bit configuration remains baffling.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, that is correct behavior. If you use implicit none, all variables, including construct entities, must be typed. It takes its type from what was declared in the outer scope, but the variable itself is independent. You can demonstrate this by assigning something to ia outside the DO CONCURRENT and then looking at its value after.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I did as you suggested, and compiled/ran the following modification of the above test code:
Program Test_Do_Concurrent
IMPLICIT NONE
Integer, Parameter :: NSpans=3,NBins=5
Integer :: ia,ib,ispan
Real :: DataSpan(2,NSpans),BinEdge(0:NBins,NSpans),BinWidth(NSpans)
Data DataSpan /0.,10., 0.,100., 0.,1000./
ia = 55
ib = 66
Write(*,*)ia,ib
BinWidth = (DataSpan(2,:)-Dataspan(1,:))/NBins
Do Concurrent (ib=0:NBins, ia=1:NSpans)
BinEdge(ib,ia) = DataSpan(1,ia) + ib*BinWidth(ia)
EndDo
Do ispan=1,NSpans
Write(*,'(*(f0.0,2X))')BinEdge(:,ispan)
EndDo
Write(*,*)ia,ib
End Program Test_Do_Concurrent
and the output is:
55 66
0. 2. 4. 6. 8. 10.
0. 20. 40. 60. 80. 100.
0. 200. 400. 600. 800. 1000.
55 66
indicating that the assignments to ia and ib in the outer scope were unchanged by the activity in the DO CONCURRENT loop.
Running the above in the VS debugger shows that, just before execution of the DO CONCURRENT, there are two independent pairs of variables named ia and ib, both assigned the values 55 and 66 respectively. While subsequently marching through the internals of the DO CONCURRENT loop, neither of these pairs of ia, ib variables ever change their value.
I don't expect I'll ever fully understand the nuances of DO CONCURRENT, but it would be nice to know that I can ignore the unused variable warning in this context.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I compiled both examples with the current compiler, 2021.8.0. It was released as part of oneAPI HPC Toolkit 2023.1.
I don't get any warning messages.
$ ifort --version
ifort (IFORT) 2021.8.0 20221119
Copyright (C) 1985-2022 Intel Corporation. All rights reserved.
$ ifort -qopenmp concurrent1.f90
$ a.out
0. 2. 4. 6. 8. 10.
0. 20. 40. 60. 80. 100.
0. 200. 400. 600. 800. 1000.
$ ifort -qopenmp concurrent.f90
$ a.out
55 66
0. 2. 4. 6. 8. 10.
0. 20. 40. 60. 80. 100.
0. 200. 400. 600. 800. 1000.
55 66
No warnings without -qopenmp either.
$ ifort concurrent1.f90
$ ifort concurrent.f90
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I was going to gently chide @Barbara_P_Intel for not adding -warn, since unused variable warnings are not the default, but even when I add that I don't get any complaints from the current compiler.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page