0

I have a module in which I store 2D arrays (since my computational domain is a 2D grid) as a 1D vector since 99% of the other subroutines in my code work with 1D vectors. However, I have a subroutine MYsubr that works with 2D arrays , and since I am not aware of a way to reshape the vector into a matrix directly inside the "use module" I just pass it as an argument of the subroutine and then reshape it in the subroutine. Is there a better way to do this? My module is:

module myMODULE
   integer,allocatable :: var(:)
   .....
   ..... (thousands of other variables needed in mysubr)
end

and the main program calls a subroutine with "var" as an argument, but also var is recalled by the module myMODULE:

program main
   implicit none
   integer :: Nmax
   integer :: Mmax
   Nmax = 100
   Mmax = 200
    .....
   allocate(var(Nmax*Mmax))
    .....
    .....
   call MYsub(var,Nmax,Mmax)
end
subroutine MYsub(var,Nmax,Mmax)
   use myMODULE
   integer :: var(Nmax,Mmax)
    .....
    ....,
end 

In this way I can reshape var. What is the risk of this? It perfectly compiles. As long as I dont change the value of var in MYsub its clearly fine, what if I change it? should I use in MYsub this formulation to be safer:

use myMODULE, unused => var

so in this way I avoid aliasing the variable.

Millemila
  • 1,612
  • 4
  • 24
  • 45
  • In your example the interfaces of MYsub do not conform. Don't use the module in the subroutine at all and just pass the array as the argument. Thanks to the rules of sequence association you can use the 1d array and see it as a 2d array in the subroutine. – Vladimir F Героям слава Apr 29 '15 at 23:32
  • I know, but clearly I have a bunch of other variables in MY module that I need in MYsubr, so I need to use the module. I added ...... (other variables) in the module right now. And I fixed the arguments, sorry it was a minimal example I forgot them. – Millemila Apr 29 '15 at 23:36
  • Then use the only clause to only use what you need. Or use a pointer remapping and avoid the dummy argument. Having a dummy argument aliased with a module variable should be ok if you do not acces the module variable directly, be sure to use a different name and not `var` for both. – Vladimir F Героям слава Apr 29 '15 at 23:39
  • Thanks a lot. Anyway I need thousands of variables and listing them with the only clause is crazy long. So i guess my idea of doing: "myMODULE, unused => var" was ok right? And also there is no way to reshape variables in modules as far as I know. Is the pointer remapping adding overhead? If not could you provide an example? I will accept your answer if you feel like providing it. THanks. – Millemila Apr 30 '15 at 02:00
  • This page might include some useful info (e.g., reshaping of array pointer). http://stackoverflow.com/questions/5406016/changing-array-dimensions-in-fortran – roygvib Apr 30 '15 at 02:43

1 Answers1

3

First I would say if you really use thousands of variables from a module in a single subroutine then something went horribly wrong in your software design phase.

Other than that, if you used the module in the module and not inside the subroutine

module mod2
   use myMODULE

   contains

   subroutine MYsub(var,Nmax,Mmax)
      integer :: var(Nmax,Mmax)

there would be now issues, as the dummy argument shadows the host associated module variable.

When you use the module inside the subroutine, you cannot have the same name of the dummy argument and of a use-associated entity. Your renaming

use myMODULE, unused => var

is standard conforming and there are no risks in doing that. But why not just name the dummy argument differently?

In this case I would not recommend the pointer remapping, although I raised it here, it is an unnecessary complication and will also require to use a different name.

  • Thanks. Ok I exagerated not thousands but surely tens. I will go for "use myMODULE, unused => var" as I am doing thanks. Renaming the dummy argument is not safe, I wanna keep the same name, it might be that by copy and paste or by mistake I use the other variable. You would say they both point to the same memory, but I am afraid the compiler could maybe not perform some optimization if they are used both in a loop for example...but I might be wrong. By using "unused" I am sure I will not use it. – Millemila Apr 30 '15 at 19:00
  • *"You would say they both point to the same memory, but I am afraid the compiler could maybe not perform some optimization if they are used both in a loop for example..."* this kind of aliasing is actually forbidden. You are not allowed to modify a variable from a dummy argument and from use association at the same time, exactly because it is not safe as you wrote. – Vladimir F Героям слава Apr 30 '15 at 22:09