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

How to "watch" a submodule variable in MSVS debugger?

Andreas_Z_
New Contributor I
1,084 Views

I was wondering whether it is possible to show a variable's value declared in a submodule during a debugging session in MSVS (2019), say in a watch window? My attempts have failed so far.

I know that module variables are accessible as "module1::variable_name". However, "submodule1::variable_name" does not work, nor does "module1::submodule1::variable_name" (when module1 is the module containing submodule1).  Any ideas?

Andi

0 Kudos
5 Replies
Johannes_Rieke
New Contributor III
1,066 Views

Hi Andreas,  in VS2017 (15.9.25) with PSXE 2020 update 1 integration the watch window as well as hover over works fine for submodule variables without having to define the variable with its module/submodule name in front. Maybe its an regression?

How is the submodule defined? I use the verbose definition with repeating the interface in the submodule (module function/subroutine instead of module procedure). I don't know if it makes a difference for debugging.

However, it sounds like an issue of VS 2019 integration. You should file it.

0 Kudos
Johannes_Rieke
New Contributor III
1,064 Views

This is the code with which I tested the debugging functionality in VS 2017. Maybe your code does something more complex (OO, derived types...). However it should work in VS 2019.

 

submodule (mod_test) smod_test
  contains
  
  ! this version is without repeating the interface
  module procedure foo
    implicit none
  
    d = real(i*j*k,rk)
    return
  end procedure foo
  
  
  ! this version repeats the interface
  module subroutine bar1(i, j, k, d)
    use ISO_FORTRAN_ENV, only : ik => int32
    use ISO_FORTRAN_ENV, only : rk => real64
    implicit none
    integer(ik), intent(in ) :: i, j, k
    real(rk)   , intent(out) :: d
  
    d = real(i*j*k,rk)
    return
  end subroutine bar1
  
    
  module procedure bar2  
    d = real(i*j,rk)
    return
  end procedure bar2
  
end submodule


module mod_test
  use ISO_FORTRAN_ENV, only : ik => int32
  use ISO_FORTRAN_ENV, only : rk => real64
  implicit none
  
  private
  public :: foo, bar
  
  
  interface bar
    module procedure :: bar1
    module procedure :: bar2
  end interface bar
  
  interface 
  
    module subroutine foo(i, j, k, d) 
      implicit none
      integer(ik), intent(in ) :: i, j, k
      real(rk)   , intent(out) :: d
    end subroutine foo
  
    module subroutine bar1(i, j, k, d)  
      use mod_parameter
      implicit none
      integer(ik), intent(in ) :: i, j, k
      real(rk)   , intent(out) :: d
    end subroutine bar1  
  
    module subroutine bar2(i, j, d)  
      use mod_parameter
      implicit none
      integer(ik), intent(in ) :: i, j
      real(rk)   , intent(out) :: d
    end subroutine bar2
  
  end interface
  
end module mod_test

program submodule_test2
  use ISO_FORTRAN_ENV, only : ik => int32
  use ISO_FORTRAN_ENV, only : rk => real64
  use mod_test
  implicit none
  
  integer(ik) :: i, j, k
  real   (rk) :: d
  
  ! ----------------------------------------------
  
  i = 2
  j = 5
  k = 3
  call foo(i,j,k,d)
  write(*,'(1ES18.4)') d
  call bar(i,j,k,d)
  write(*,'(1ES18.4)') d
  call bar(i,j,d)
  write(*,'(1ES18.4)') d
  
  
end program submodule_test2

 

 

0 Kudos
Andreas_Z_
New Contributor I
1,034 Views

Hi Johannes,

Thanks for your reply and for providing a test program. I was able to run your program (using VS2019, Intel Fortran Compiler 19.1.0.166) and the variables show in the debug watch windows as intended. 

Summary:  in my case, the issue is related to the use of !$OMP threadprivate(....) variables within the submodule.

Description:
One difference in my code where the issue appears is that I declared variables within the submodule declaration part, such as integer(ik),dimension(:),allocatable :: iarray, in the attached code. Debugging of this variables still works as intended within the submodule's scope.

However, after comparing to my application, I realized that the issue arises due to the use of OpenMP threadprivate directives within the submodule declaration part. If the code is not using that or not compiled with the /Qopenmp switch, the debugging / watch variables are shown as expected in VS.

Below is a short example program (adapted from Johannes' example) that demostrates the issue I experience in VS2019 (see also attached screenshot). In the screenshot, Watch1 window, the iarray values are inaccessible and a strange value range is displayed, while the actual array values are as intended. So this is likely only a debugger issue but not a Fortran problem.

OpenMP threadprivate variables from the parent module are shown correctly. Therefore, my question is whether this is a bug in the VS debugger when !$OMP directives are used in submodules or whether submodule variables should not be declared threadprivate? 

Best,
Andi

- the command line used in the VS solution was:
/nologo /debug:full /Od /Qopenmp /debug-parameters:all /warn:interfaces /module:"x64\Debug\\" /object:"x64\Debug\\" /Fd"x64\Debug\vc160.pdb" /traceback /check:bounds /libs:dll /threads /dbglibs /c

 

0 Kudos
Johannes_Rieke
New Contributor III
983 Views

Hi Andi, I think it is a bug in Intel's debugger integration in case of compiling with /Qopenmp.

I also can only see variables in normal modules (break point in a parallel region), if I prefix the module name as you described in the opener. This is true for the main thread only, in the worker threads I do not see any variables. In serial regions it works without module name prefix. This, too, can be improved by Intel.

Further OpenMP does not allow to use all Fortran (2018?) features. Steve Lionel wrote something about that in an older thread. I can't remember whether submodules are officially supported in PSXE 2020 with OpenMP. The OpenMP documentation, let's say, could be improved regarding the allowed combinations (https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-5.0.pdf page 33, line 21):

While future versions of the OpenMP specification are expected to address the following features, currently their use may result in unspecified behavior.
- Submodules
- ...

 

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
955 Views

>>the issue is related to the use of !$OMP threadprivate(....) variables within the submodule.

For debugging, you could conditionally compile in a local pointer to the watch variable.
(This may require a (conditional) TARGET on the pointee)

Jim Dempsey

0 Kudos
Reply