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

Debugger problem after switching from IFORT to IFX

jirina
New Contributor I
496 Views

I am trying to switch from IFORT to IFX. Compilation works fine for my application, however, I encountered a problem in debugger. I narrowed the problem to following code:

      PROGRAM TEST
      
      include 'frequent.inc'
      
      integer*4, allocatable :: c(:,:,:)
      
      
      nx = 100
      ny = 75
      nz = 50
      
      allocate ( c(nx,ny,nz) )
      
      call callTest ( c )
      
      deallocate ( c )
      
      call exit ( 0 )
        
      END
      
      
      subroutine callTest ( c )
      
      include 'frequent.inc'
      
      integer(4), dimension(nx,ny,nz) :: c
      
      integer(4) :: elements
      
      
      elements = size(c)
      
      return
      end subroutine callTest

The file 'frequent.inc' contains following:

        integer(4) :: nx, ny, nz
        
        COMMON /FrequentlyUsedCommon/ nx, ny, nz

If I run debugger and add the array c to Watch, I can see it has correct dimension before the call to subroutine callTest:

jirina_0-1708456257948.png

However, stepping into the called subroutine causes array dimensions in Watches to change:

jirina_1-1708456359975.png

The number of elements obtained using the function size is however correct.

Compiler options are: /nologo /debug:full /MP /Od /fixed /extend-source:132 /Qopenmp /fpscomp:general /Qdiag-disable:5462,8291,10448 /warn:declarations /warn:unused /warn:truncated_source /warn:noalignments /warn:uncalled /warn:shape /warn:interfaces /assume:byterecl /fpe:0 /module:"x64\Debug\\" /object:"x64\Debug\\" /Fd"x64\Debug\vc170.pdb" /traceback /check:pointer /check:bounds /check:uninit /check:format /check:output_conversion /check:stack /libs:dll /threads /dbglibs /Qmkl:parallel /c

 

Linker options are: /OUT:"x64\Debug\Test.exe" /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"x64\Debug\Test.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"D:\...\Test.pdb" /SUBSYSTEM:CONSOLE /STACK:1000000000

 

0 Kudos
7 Replies
jimdempseyatthecove
Honored Contributor III
490 Views

It can help to modernize your program:

    module TEST_mod
    integer :: nx, ny, nz
    interface
        subroutine callTest ( c )
            implicit none
            integer(4), dimension(:,:,:) :: c
        end subroutine callTest
    end interface    
    end module TEST_mod
    
    PROGRAM TEST
      use TEST_mod
      integer*4, allocatable :: c(:,:,:)
      
      nx = 100
      ny = 75
      nz = 50
      
      allocate ( c(nx,ny,nz) )
      
      call callTest ( c )
      
      deallocate ( c )
      
      call exit ( 0 )
        
      END
      
      
      subroutine callTest ( c )
        implicit none
        integer(4), dimension(:,:,:) :: c
        integer(4) :: elements
        elements = size(c)
      
        return
      end subroutine callTest

jimdempseyatthecove_0-1708458255802.png

Jim Dempsey

0 Kudos
JohnNichols
Valued Contributor III
479 Views

You are using different versions of Visual Studio most likely, you cannot use VS 2022 Preview without getting the error shown in the first post.  This has been discussed a bit on the forum, go back to VS 2022 before the update to 17.9

0 Kudos
jirina
New Contributor I
447 Views

Jim, thank you for pointing out the potential of making the code modern. I would of course like to do that and I am aware of it, the problem is that we are speaking about over 100 000 lines of code which was written about 20 years ago. This code uses many 3D arrays, all of them defined in the main program and used as arguments in so many subroutines and functions that rewriting this to a modern style would require a tremendous effort and a lot of time. I am afraid I will have to go this way, but I will probably start with a "compromise", whatever it can mean.

0 Kudos
jimdempseyatthecove
Honored Contributor III
428 Views

As an alternative (hack), for debugging purposes, try:

      subroutine callTest ( c )
      implicit none
      include 'frequent.inc'
      integer(4), dimension(nx,ny,nz) :: c
      integer(4) :: elements
      associate(debug_c=>c)
      elements = size(c) ! break here, examine debug_c
      end associate
      return
      end subroutine callTest

Many years ago (~15-20), I had a similar debugging issue (pre-associate) and the hack was to use a pointer (at that time did not require target attribute on the pointee).

You can consider using FPP or compiler directives to activate the code lines related to the associate / end associate lines.

 

Barbara, Steve:

While in fixed-form files one can place a D in column 1 to enable or ignore a statement (depending on command line options), there is no means in free form similar to the !$ for conditional OpenMP directives. Something like !D$<whitespace> statement", or !Debug$<whitespace> statement" would be handy.

 

Inserting

!dir$ if defined(_DEBUG) / !dir$ endif around the debug statements is unappealing.

 

Jim Dempsey

 

 

0 Kudos
jirina
New Contributor I
425 Views

Jim, thank you for the suggested alternative for debugging purposes. I am going to give it a try.

Several years ago, I started changing the legacy code I am maintaining to use modules. If I have subroutines in modules, I will not need to use interfaces and I can use assumed-size arrays, which, as I have just verified, works well in debugger. 

(It is about 1000 subroutines and 500 functions to be checked, not all of them have arrays as arguments. )

0 Kudos
jimdempseyatthecove
Honored Contributor III
414 Views

My code is about twice that size. It originally was written for Fortran IV and 77.  Full of common blocks and fixed size arrays (that could be partially filled). I had a requirement to migrate to Fortran 90/95 to get allocatables and OpenMP.  To ease conversion and provide for single source to compile using common or modules with user defined types, I used the fpp preprocessor to redefine the text of tokens between the common variable name (e.g.  NBEAD) and the module with UDT name (e.g. pTether%pFiniteSolution%NBEAD).  In addition to providing allocatables (# tethers and # finite solutions) this eliminated the copying of data in the older fixed arrays into work storage common blocks (and back again after computation). This presented a debugging problem for me and thus the use of the local defined pointer (the debugger is incapable of using the fpp #define's to locate the variable of interest).

Once I was satisfied that the results data compared between the before conversion and after conversion I use a utility I wrote in 1990, a PC version of the TECO editor. Using macros, I could scan the fpp #include files for the #defines and perform the replacements thus producing the desired source files with the correct replacement (I did this because the output of fpp was not acceptable for my purposes).

 

This was a sizable amount of work, but certainly well worth the effort.

 

The biggest problem I had was to work out the quirks of older memory constrained Fortran IV and 77 programs would repurpose (re-name) common block variables and rely on carry-over from procedure to procedure. I anticipate you have the same or similar situation.

 

Jim Dempsey

0 Kudos
jirina
New Contributor I
378 Views

Indeed, my situation is similar. The code was written in Fortran 77, it uses many common blocks and fixed size arrays. There are no user defined types used in the code.

For past few years, I have been gradually getting rid of common blocks, introducing modules; some significant effort will be required to complete this conversion.

Regarding allocatable arrays, I am considering having them all in several modules, which will allow me to get rid of using them as arguments in calls to subroutines and functions.

Reply