limitations

limitations

Hi,

I recently encountered a problem that I have not seen before, and am not sure I understand.  I have been working on some code for around 10 years now.  This code is all compiled into a single executable file.  The program is designed to undertake repeated numerical optimisations a large number of times (running into the billions), and stores results in a series of allocatable arrays (to avoid stack over-flow issues).  I also use a large number of allocatable variables as globals, which are referenced throughout the code.  I recently found that adding a single global allocatable array to my program now produces unreliable results.  Specifically, if you run the program without the addition of (global) allocable variable X, then you get some answer for a particular optimisation Y1.  If you then add the allocatable variable X, and allocate but do not use it, then you get the same result Y1 if teh revised code is run through VS.  But if you then run the revised code outside of the debugger, then you get result Y2.ne.Y1 - using the same compiled version of the code (ie, not recompiling, just double clicking the executable rather than launching it through the debugger).

This is obviously a non-trivial problem for me.  Could this be happening because I have reached some sort of technical limit in relation to the use of allocatable variables?  If so, then would cutting my program up into pieces resolve the issue?  Any other comments or suggestions would be most welcome.

I am using IVS 13.0.1.119 in VS 2010 and do not provide my compiler options here, as the same result seems to crop up in both my development and release configurations.

Justin.

10 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Sounds like addressing out of range and accessing uninitialised memory locations to me.
Do you initialise your allocated arrays to zero? Does your code depend on them being initialised to a particular value?
Initialisation of allocated arrays varies between release and debug versions I believe.

If a subprogram has one or more arguments that are declared with the ALLOCATABLE attribute, the program units that call or invoke that subprogram must be provided with an explicit interface. Failing to provide an interface when one is required can cause problems of the type described, as can the use of undefined variables.

The Intel compiler allows you to receive warnings of incorrect interfaces.

Further to the points made in the previous posts, note that running a program started under a debugger (regardless of whether it is a Release build or a Debug build in Visual Studio) may change the nature of the low level memory management provided by the operating system to the program - you get the so called debug heap. This can sometimes explain mysterious changes in behaviour.

See http://msdn.microsoft.com/en-us/library/ff538841.aspx for information on how to disable the change in memory management (set the _NO_DEBUG_HEAP environment variable to 1) - it would be interesting to see if your observations become more consistent with that environment variable set.

Quote:

mecej4 wrote:

If a subprogram has one or more arguments that are declared with the ALLOCATABLE attribute, the program units that call or invoke that subprogram must be provided with an explicit interface. Failing to provide an interface when one is required can cause problems of the type described, as can the use of undefined variables.

The Intel compiler allows you to receive warnings of incorrect interfaces.

1) Apologies - how to you provide an explicit interface? I may be missing this. I do, however, have the "warn: interfaces" option turned on, and no warnings are being generated by the compiler.

Following on from mecej4's reply, and am slightly worried that I am not implementing global variables correctly in my code. To make a set of variables available to multiple subroutines I have:
1) created a Module:
Module XX
variable type statements here
End module XX
2) Used the global variables module in the required subroutine(s):
Subroutine YY
Use XX
variable type statements for subroutine YY here
program code for subroutine here
End subroutine YY
Importantly, I haven't done anything more than specify a module and use the module to set-up the global variables. Is this the right way to implement global variables? I am obviously not a programming specialist.
Many thanks,
Justin.

Quote:

jvandeven wrote:

Quote:

Apologies - how to you provide an explicit interface?


One way is to put the body of the subroutine in a module, and then USE that module in the subprograms that call the subroutine. Another is to provide interface blocks, but in this case you have to be careful about providing a correct interface block.

If /warn:interfaces is not turning up errors, however, the source of your problem may lie elsewhere

Just as local variables in a subprogram need not retain values from a previous call, module variables may come into scope and go out of scope. Do you have your "global" variables in a module that is USEd in the main program?

Justin,
I think that after 10 years of use, you have discovered the symptom of a bug that is due to an un-initilised variable, a array being addressed out of available bounds (probably through a subroutine argument) or a non SAVE variable that has not previously been a problem.
As you imply you have been changing the program, this bug might have been introduced at any stage of development.
I would recommend that you turn on as many checking options as you can and see if this throws up the error.
In the past I have resorted to this and have been amazed at how many minor problems show up. Often this highlights the unusual combination of options in a DO loop where some array subscript is not initialised for a case where it does not matter or where the evolution of code changes forgot this unusual case.
It is worth the check.
John

John,
I am (unfortunately) very familiar with the type of errors that you refer to, which can be very difficult to find. The issues that I am finding do appear to be consistent with out-of-bounds/uninitialised referencing, and I am crawling over my code to work out whether this is the case. I have also started with a fresh solution, in case some of the solution files somehow became corrupted. Encouragingly, I have been obtaining sensible results since I started with a fresh solution. I have also found this problem in the past (where something to do with the solution seems to have become corrupted), but identifying the source of the issue is then beyond me. Thanks for the suggestion,
Justin.

I have corrected this problem, and my code now appears to be working well. To do this, I reverted to an old solution that I was confident did work, and then introduced each of the amendments that I had made to my code in a piece-wise fashion, checking that each piece worked before adding the next. While I did find that a few minor changes to the program versions were necessary, nothing stood out as being very important (eg no calls outside of array bounds). Is it possible for the solution files other than the text of the program that I write to become corrupted? I can recall encountering the same sort of problem once before, which seemed to be resolved by simply loading the program files into a fresh solution.

Many thanks,

Justin.

Leave a Comment

Please sign in to add a comment. Not a member? Join today