Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28500 Discussions

IVF Integrations with VS 2005 fail to display data exported from a DLL properly

schapman
Beginner
632 Views
Hello,
We are in the process of converting a very large Fortran program from CVF to IVF, and we have hit a showstopper. Data which is declared in a DLL and exported from the DLL does not get displayed properly in a main program that accesses the DLL. For example, the attached program contains a DLL that declares and exports a single integer. When this data is used in the main, its value prints properly and is proper when assigned to a local variable. However, the value displayed by the debugger is rubbish. This is very serious as the program being converted has > 50,000 such variables. Has anyone got a clue how to aviod this.

BTW, I seem to remember a similar problem in the DVF 5 days, which was fixed. Is this a regression?

Thanks
Steve

0 Kudos
9 Replies
Steven_L_Intel1
Employee
632 Views
A showstopper? Really? I can reproduce the problem, but it also shows up in older compilers. Haven't tried with CVF yet. I'm puzzled by this as I thought we had taken care of all such issues a long time ago. I'll pass this on to the developers.

The value shown is not "rubbish" - rather, it is the address of the actual data. The debugger is not being told to follow the extra level of indirection needed by DLLIMPORTed variables. Here's a workaround. In the Locals display, select the value shown and "copy" it. Click on a Memory view tab and paste the value into the Address window and press Enter. You'll now likely see a hexadecimal display by byte. Right click in the memory display pane and you can change the view, for example, to 4-byte signed integer. This is awkward, I know, but at least it should get you going.
0 Kudos
schapman
Beginner
632 Views
Thanks you for the suggestion. We will use it, of course, now that we know how. Can you tell us how to do the same thing if the data to display is a character variable or a structure?

And yes, this is a good workaround for individual variables, but if we are checking thousands of them, it is a showstopper. The time required for the checking is just too great.
0 Kudos
Steven_L_Intel1
Employee
632 Views
Character values will show by default. Structures may be harder. I noticed you also submitted this to Intel Premier Support, though when I tried the workaround our support engineer suggested, it didn't work for me. Did it for you?

I am still a bit confused - do you regularly examine the values of thousands of individual variables in the debugger?
0 Kudos
schapman
Beginner
632 Views
Hello Steve,
No, the workaround did not work for us either. Should we go back and ask the support site to re-open this?

And no, we don't regularly examine every variable, but the code base we are converting consisits of ~400,000 SLOCs in ~120 projects, consisting of about 15 executables, 3 libraries, and 100+ DLLs. The program also includes ~20 C++ DLLs. There are enough differences between what we see in CVF and IVF that we do need to track execution paths and examine intermediate results in lots of places. That is taking a huge amount of time.

Some of the changes that have been hardest for us are:

1. AUTOMATIC is no longer supported as a standalone statement. We don't understand that, since it is a part of the Fortran 95/2003 standard. That affected all of our procedures (~5000).
2. NAMELIST is much pickier, and the NAMELIST read fails without displaying the line it doesn't like. The program uses NAMELISTs to exchange data with others in the processing chain, and IVF now insists on having exactly the same type in the namelist as the variable name. In CVF, the statement VAL = 3 would be valid in a namelist even if VAL were declared as REAL. In IVF, that is illegal. The fact that the compiler doesn't tell us where the problem occurs in the namelist is very difficult.
3. Some libraries in CVF and IVF appear to have the same names, and on our computers with both IDEs, we have been getting problems with the LIB search path causing corrupt executables. We finally fixed that by putting IVF into a separate virtual machine, where it cannot be contaminated by the old CVF IDE and associated paths.
4. We are getting different answers in the IVF code from the CVF code in some cases for no reason that we can determine. This is where the debugger is important, as we literally trace the identical execution in both versions side-by-side their in separate IDEs.

On the other hand, we are very happy with the improved syntax checking in IVF. For example, CVF used to allow statements like

IF ( struct%value ) THEN
...
END IF


even if value was not a logical, because the compiler type checking failed for elements in the structure. IVF catches this, which helps to reveal inadvertent errors in the program. Another good example is where procedures were declared as functions but then called as subroutines. CVF allows this, and IVF disallows it. The code generally feels "tighter" when compiled successfully with IVF.


0 Kudos
Steven_L_Intel1
Employee
632 Views
AUTOMATIC not supported? I think you're mistaken. You ARE mistaken in saying it's standard Fortran - it's not.

I'm also astonished by your comments on NAMELIST - I know that we enhanced the error reporting to show the position in error. I'd love to see an example of this. Also, I'm unaware that we tightened up type conversion in NAMELIST. Here's an example I tried:

C:UsersSteve>t.exe
&nml i = 3.0, x = 'bad' /
forrtl: severe (17): syntax error in NAMELIST input, unit -4, file CONIN$, line 1, position 12

You are right that the run-time library routines often have the same name between CVF and IVF. You can generally resolve this by removing the paths from the system LIB and INCLUDE environment variables and, if you're using the command line, use the appropriate .bat files.

Probably the single biggest reason for different results is that CVF defaults local scalar variables to static storage (and implicit SAVE) and IVF does not. This means that if your program is incorrect and you have uninitialized variables or variables not declared SAVE when needed, you can get different results. You can try setting the project property Fortran Data > Local Variable Storage > All variables SAVE and see if that helps. If it does, you should track down the errant variables and fix the code.
0 Kudos
Steven_L_Intel1
Employee
632 Views
Oh, and yes, please reopen the issue. You can suggest that the support tech contact me if more information is needed.
0 Kudos
schapman
Beginner
632 Views
Steve,
As for the namelist, it may be because we have been using 10.1.011 instead of the latest compiler. Perhaps the line causing the error is a new addition? We will try it again later today with the new compiler.

The tightened conversion on the namelist is real; that was causing us grief because we could not find where the error was occurring. In CVF, when we had this problem, we just inserted the namelist statements into our source code, and compile them. That told us which values were incorrect. That does not work for IVF in the case of a statement like

a = 1

where a is a real, because the type will be automatically converted in the statement when it is compiled, but will not in the new namelist. When the namelist failed to list the line where the failure occurred, we were stuffed. The change that you are showing will fix that problem.

When we have an error in a namelist at the moment, we see something like:

D:sadm_worksadmu_326_branch_ivfsadmu>binsadm workstandardstandard.inp
INFO: Error reading BI namelist. Shutting down...


Image PC Routine Line Source
libifcoremdd.dll 002F33B6 Unknown Unknown Unknown
libifcoremdd.dll 002EC22D Unknown Unknown Unknown
libifcoremdd.dll 00275DD9 Unknown Unknown Unknown
sadm.exe 004F8BC5 _SADM_INPUT_LIB_m 135 sadm_input_lib.f90
sadm.exe 00431136 _SADM_LIB_mp_SERV 211 sadm_lib.f90
sadm.exe 0040281B _MAIN__ 225 sadm.f90
sadm.exe 011532BD Unknown Unknown Unknown
sadm.exe 0114D4A6 Unknown Unknown Unknown
sadm.exe 0114D2FD Unknown Unknown Unknown
kernel32.dll 7C816FD7 Unknown Unknown Unknown

Note that there is no namelist file line number here. The offending line in this case was the second value in the namelist:

&BI_LIST
BI%N_ANGLES = 1
BI %N_RANGES = 1.0 ! Bad line--n_ranges is declared as an integer
BI%FAPPLY_TO_RAID = .TRUE.
BI%RANGEOPT = 1
BI%N_RCS = 1
...
/

As for the AUTOMATIC statement, I did not know that there was no such default in the Fortran standard. I though it worked in parallel with the SAVE staement, where a single SAVE caused all data in the model to be SAVEd. It is interesting that I missed that completely when I read the new document.



0 Kudos
Steven_L_Intel1
Employee
632 Views
Steve - that INFO message you are seeing is from your application - it is using ERR= or IOSTAT= to prevent the Fortran library from displaying its own message.

I will investigate the NAMELIST issue you mention - that should not be happening. I can reproduce at least some of this.
0 Kudos
jimdempseyatthecove
Honored Contributor III
632 Views

Steve,

I am not in a position to test this but this is something you could whip-up rather quickly.

Make a shell for your main program. That is your existing main program becomes a subroutine and your new main program calls the old main as a subroutine.

Next, add a subroutine to your DLL that receives the address of a subroutine and calls that subroutine when called. Then change the call in your new main to call the DLL passing in the address of the subroutine made of yourold main.

Make sure that the subroutine in theDLL has visibility to the > 50,000 variables (add USE or COMMON, etc...)

When debugging the application and when you cannot see one of the DLL visible variables from the debugger, open the call stack pane and locate the DLL hook subroutine and set context to that. Your variables should nowbe visible.

Jim Dempsey

0 Kudos
Reply