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

How to check if a module is being used?

Navdeep_Rana
Beginner
1,162 Views

I would like check if a module is being used, and use conditionals to execute different commands. For example

if (mod_algorithm_1_is_used) then
    call algorithm_one()
else
    call algorithm_two()
endif

Is there a way to do it?

Do modules define some variable when used?

 

0 Kudos
1 Solution
Juergen_R_R
Valued Contributor I
1,162 Views

Say I have two input-output modules. The standard way and the other which uses parallel hdf5.

If there is a way to check which of the module is loaded, I can easily put a conditional and switch between standard-io and hdf5-io.

Navdeep, my solution would be the following: either just two different types which extend an abstract base type (e.g. obj_t), and then normal_io_t and hdf5_io_t which get allocated depending on your different needs for output, the first using the routines from one module, the other types the routines from the other module. Or you just have one object type container which has a flag specifying whether your output is 'normal' or 'hdf5'. This is the case if in your program you want to support IO of both flavours simultaneously. Otherwise you could just compile to different instances of your program with the different IO modules. 

 

 

 

View solution in original post

0 Kudos
8 Replies
Juergen_R_R
Valued Contributor I
1,162 Views

This question seems a bit strange to me. You can define module variables that are public and experted by the module, e.g.

module foo_1
   implicit none
   private
   integer, parameter, public :: foo_1_is_used = .true.
end module foo_1

The problem is, if you want to use that module variable (which is a global variable here) in some other module or the main program, you actually _must_ USE the module foo_1. Otherwise your code will not compile, and you will get an error.

 

0 Kudos
DataScientist
Valued Contributor I
1,162 Views

The answer to your question is "No", as far I know. There is no such method in Fortran standard. But really, there is no need for such capability. I suspect what you trying to do could be easily implemented using the modern Fortran standard syntax. But you don't tell us here what you intend to do.

0 Kudos
Navdeep_Rana
Beginner
1,162 Views

Juergen R. wrote:

This question seems a bit strange to me. You can define module variables that are public and experted by the module, e.g.

module foo_1
   implicit none
   private
   integer, parameter, public :: foo_1_is_used = .true.
end module foo_1

The problem is, if you want to use that module variable (which is a global variable here) in some other module or the main program, you actually _must_ USE the module foo_1. Otherwise your code will not compile, and you will get an error.

 

Yes, First I thought of this solution. But as you said, the variable foo_1_is_used is only available if I use module foo_1 not otherwise.

0 Kudos
Navdeep_Rana
Beginner
1,162 Views

A. King wrote:

The answer to your question is "No", as far I know. There is no such method in Fortran standard. But really, there is no need for such capability. I suspect what you trying to do could be easily implemented using the modern Fortran standard syntax. But you don't tell us here what you intend to do.

Say I have two input-output modules. The standard way and the other which uses parallel hdf5.

If there is a way to check which of the module is loaded, I can easily put a conditional and switch between standard-io and hdf5-io.

0 Kudos
Juergen_R_R
Valued Contributor I
1,163 Views

Say I have two input-output modules. The standard way and the other which uses parallel hdf5.

If there is a way to check which of the module is loaded, I can easily put a conditional and switch between standard-io and hdf5-io.

Navdeep, my solution would be the following: either just two different types which extend an abstract base type (e.g. obj_t), and then normal_io_t and hdf5_io_t which get allocated depending on your different needs for output, the first using the routines from one module, the other types the routines from the other module. Or you just have one object type container which has a flag specifying whether your output is 'normal' or 'hdf5'. This is the case if in your program you want to support IO of both flavours simultaneously. Otherwise you could just compile to different instances of your program with the different IO modules. 

 

 

 

0 Kudos
Navdeep_Rana
Beginner
1,162 Views

Juergen R. wrote:

Say I have two input-output modules. The standard way and the other which uses parallel hdf5.

If there is a way to check which of the module is loaded, I can easily put a conditional and switch between standard-io and hdf5-io.

Navdeep, my solution would be the following: either just two different types which extend an abstract base type (e.g. obj_t), and then normal_io_t and hdf5_io_t which get allocated depending on your different needs for output, the first using the routines from one module, the other types the routines from the other module. Or you just have one object type container which has a flag specifying whether your output is 'normal' or 'hdf5'. This is the case if in your program you want to support IO of both flavours simultaneously. Otherwise you could just compile to different instances of your program with the different IO modules.

Thanks for the suggestion. I will stick with compiling different instances, keeping it simple.

0 Kudos
JVanB
Valued Contributor II
1,162 Views

You need a failover if the module variable isn't accessible. Implicit typing and host association can provide this:

module root
   implicit none
   type check(key)
      integer, kind:: key
   end type check
end module root

module M1
   use root
   implicit none
   type(check(1)) M1_is_used
end module M1

module M2
   use root
   implicit none
   type(check(1)) M2_is_used
end module M2

program P
   use root
   implicit none
   call S1
end program P

subroutine S1
   use M1
   implicit none
   write(*,*) 'Is M1 used? ',F1()
   write(*,*) 'Is M2 used? ',F2()
   contains
      function F1()
         use root
         implicit type(check(0)) (M)
         logical F1
         F1 = M1_is_used%key /= 0
      end function F1
      function F2()
         use root
         implicit type(check(0)) (M)
         logical F2
         F2 = M2_is_used%key /= 0
      end function F2
end subroutine S1

Output with ifort:

 Is M1 used?  T
 Is M2 used?  F

Of course there is the problem that if subroutine algorithm_one is itself defined in module M1 then there will be a failure at link time if M1 is not used. Hopefully this is not the case, but stub external subroutines algorithm_one and algorithm_two could be provided to satisfy the linker. Neither Fortran nor the linker would get confused by the presence of such stub external subroutines. Now, if either required am explicit interface one might have to get more creative :)

 

 

0 Kudos
Navdeep_Rana
Beginner
1,162 Views

Repeat Offender wrote:

You need a failover if the module variable isn't accessible. Implicit typing and host association can provide this:

module root
   implicit none
   type check(key)
      integer, kind:: key
   end type check
end module root

module M1
   use root
   implicit none
   type(check(1)) M1_is_used
end module M1

module M2
   use root
   implicit none
   type(check(1)) M2_is_used
end module M2

program P
   use root
   implicit none
   call S1
end program P

subroutine S1
   use M1
   implicit none
   write(*,*) 'Is M1 used? ',F1()
   write(*,*) 'Is M2 used? ',F2()
   contains
      function F1()
         use root
         implicit type(check(0)) (M)
         logical F1
         F1 = M1_is_used%key /= 0
      end function F1
      function F2()
         use root
         implicit type(check(0)) (M)
         logical F2
         F2 = M2_is_used%key /= 0
      end function F2
end subroutine S1

Output with ifort:

 Is M1 used?  T
 Is M2 used?  F

Of course there is the problem that if subroutine algorithm_one is itself defined in module M1 then there will be a failure at link time if M1 is not used. Hopefully this is not the case, but stub external subroutines algorithm_one and algorithm_two could be provided to satisfy the linker. Neither Fortran nor the linker would get confused by the presence of such stub external subroutines. Now, if either required am explicit interface one might have to get more creative :)

 

 

Thanks for the information, I will check it out.

What I was looking for is if any straightforward inbuilt method exists.

0 Kudos
Reply