I develop a fairly large Fortran code for which I've used the Intel Fortran compiler for over 10 years. The latest version 2017.0.109 for Windows produces an error on this line of code:
M4%PARTICLE_STORAGE(IPC)%INTEGERS(:,LP%STORAGE_INDEX) = M2%ADOPT_PARTICLE_STORAGE(IPC)%INTEGERS(:,CNT)
The error is 408, subscript #2 of the array INTEGERS has value 1005 which greater than 1000. However, when I write out both of the array subscripts, LP%STORAGE_INDEX and CNT, both are well under 1000, and I checked the size of the arrays too.
Unfortunately, I cannot reproduce this error in a short code snippet. The arrays structures are fairly complicated, and I suspect that might have something to do with it. I am running with full debugging on. Has something changed in the way the compiler deals with derived types, pointers, etc.?
Unfortunately, asking if "something changed" is not likely to be useful. First thing I would do is when the debugger stops for this error look at the Locals window to see what variable might have the value 1005. That's a pretty specific value, not an uninitialized value that might suggest stack corruption. There could still be some data corruption going on elsewhere in the code.
If you can't identify it, submit a report to Intel Premier Support and attach a ZIP with everything needed to build, run and reproduce the problem.
The variable LP%STORAGE_INDEX is 1005 according to the Locals list (and when I highlight the value in VS). However, a print statement just before the line of failure reports the value to be 2. Other values, like IPC, are different in print statements compared to the Locals stack.
Sounds like stack corruption, then. Tricky to track down. Does this program call any non-Fortran routines? What compile options have you specified? If it's an existing project that you're now building with 17.0, try turning on Fortran > Run-Time > Check Stack Frame, rebuild and see what it does.
There are OpenMP calls, but I am running with only one thread and there are no OpenMP calls in the routine that is failing. I have not compiled any options, other than just running in debug mode. The Check Stack Frame option has been on by default. I see in VS that there is a "Stack Frame" tab, but I cannot decipher its meaning. It refers to libifcoremdd.dll
The Stack Frame tab in the debugger is for moving up and down the call tree. Check Stack Frame adds code to check for stack corruption after calls.
What I generally do in such cases is set a breakpoint at the beginning of the affected routine and watch what happens to the relevant variables as I step through it. Would 2 have been the correct value?
It's possible that there's a compiler bug, but we'd need the complete test case to investigate it. That you're seeing this in debug mode (you haven't enabled optimization, have you?) eliminates a lot of possibilities.
I did the following, and the program now runs without the seg fault. This is my typical way to fix things that I don't quite understand -- I just simplify it. I figure having that derived type as an array index was making things more complicated. STORAGE_INDEX_SAVE = LP%STORAGE_INDEX M4%PARTICLE_STORAGE(IPC)%INTEGERS(:,STORAGE_INDEX_SAVE) = M2%ADOPT_PARTICLE_STORAGE(IPC)%INTEGERS(:,CNT)
If you had stack corruption you haven't fixed the problem just moved it eleswhere. Having changed the code you are probably now corrupting something else that maybe isn't as critical. Change the code in a small way or change compiler version or options it will may well come back to bite you. It makes more sense to find the root cause and fix it.
To explore the issue, what does the following do?
!$OMP FLUSH(LP%STORAGE_INDEX,CNT) M4%PARTICLE_STORAGE(IPC)%INTEGERS(:,LP%STORAGE_INDEX) = M2%ADOPT_PARTICLE_STORAGE(IPC)%INTEGERS(:,CNT)
No doubt that I've just dodged the bullet. The trouble with the particular simulation I'm running is that there's no clear "right answer" as it involves randomly generated particles blowing about in the wind. At the moment, the only right and wrong outcome is whether or not I get an access violation. I'll see if I can reconstruct the problem, and then try the OMP call.
Ugh -- I think I figured out the problem, and it's my bad programming. Here is a simple version of what's happening:
INTEGER, POINTER :: I INTEGER, DIMENSION(10,1000) :: A INTEGER, DIMENSION(10, 3000) :: B ... A(3,2) = 2 I => A(3,2) B(3,6) = 2002 A(:,I) = B(:,6)
In the last line of code, I am over-writing the value of the pointer I. My guess is that in previous versions of the compiler, I retained its original value while now I is being reset from 2 to 2002 and over-shooting the array bounds of A.
Lesson learned -- don't use pointer indices in array manipulations where the pointer can be revalued. Obvious in simple code, but this bit of code has gotten too complicated. Needs an overhaul.
So I think the compiler is fine. My mistake. Thanks for the help.
Glad to see you figured it out.
By the way, you may have noticed your posts here show as "(name withheld)". This is because your "Display Name" is your email address. If you wish to fix this, click on your name at the upper right of the page and select Dashboard, then edit your profile to select a new display name.
I tried to change my name, but I cannot figure it out. I am on the page with my email address at top, followed by check boxes for various email subscription preferences. There is a dotted box around my email address, and I pull down menu with "edit" as an option, but I cannot edit the name. Tried with both Firefox and MS Explorer. At the top of the page called "Your Intel DZ Profile" I do see my proper name and an empty box for a picture, I would guess. But I cannot change my public profile.
Steve Lionel (Intel) wrote:
On the Dashboard page, click the blue pencil icon to the right of "Personal Profile".
In and attempt to help and recalling this option was "well hidden" from my own experiences I just spent a couple of minutes clicking around for something I knew existed and eventually found that the "little blue pencil" was the royal jelly. A more obvious link would be helpful if that is possible.