|
| View previous topic :: View next topic |
| Author |
Message |
tesfortran
Joined: 04 Dec 2012 Posts: 3
|
Posted: Tue Dec 04, 2012 12:14 pm Post subject: array pointers with differing rank |
|
|
I am working with some very complex, and rather old fortran code (most of it was written in fortran77 but some was earlier). I need to have the memory dynamically allocated and am therefore converting "COMMON" block statements to modules with use statements.
I have come to a problem where the rank of a given variable within the common block changes between routines (the overall memory footprint is the same however).
A highly simplified example of this would be
Subroutine sub1
COMMON /cblock/array(L,N,M)
!code using the array in a 3D manner
End
Subroutine sub2
COMMON /cblock/array(L*N*M)
!code using the array in a 1D manner
End
As you can see the array is of rank 3 in the first routine and of rank 1 in the second routine.
I have searched high and low for a method of making this function with allocatable arrays, but have not been successful.
It seems like with all the additional functionality built into the modern fortran standards there should be a way to duplicate what the common blocks did in an instance like this.
Thank you. |
|
| Back to top |
|
 |
mkcolg
Joined: 30 Jun 2004 Posts: 4996 Location: The Portland Group Inc.
|
Posted: Tue Dec 04, 2012 1:11 pm Post subject: |
|
|
Hi tesfortran,
I think the best option for you is to use the "!DIR$ IGNORE_TKR" Directive. For full details please refer to the end of Chapter 6 in the PGI Compiler Reference Manual.
The other option is to move sub2 out of the module and then F77 calling conventions would be used.
Hope this helps,
Mat |
|
| Back to top |
|
 |
tesfortran
Joined: 04 Dec 2012 Posts: 3
|
Posted: Tue Dec 04, 2012 2:16 pm Post subject: |
|
|
I am not real sure if this will accomplish what I am looking for or not. I think I may need some more code to explain what I am doing.
take the following example old code
PROGRAM main
call init
call sub1
call sub2
.
.
.
End
Subroutine init
PARAMETER(L=3,M=5,N=12)
COMMON /cblock1/array1(L,M,N)
COMMON /cblock2/array2(L,M,N)
DO k=1,N
DO j=1,M
DO i=1,L
array1=0.0
array2=0.0
End DO
End DO
End DO
End
Subroutine sub1
PARAMETER(L=3,M=5,N=12)
COMMON /cblock1/array1(L,M,N)
COMMON /cblock2/array2(L,M,N)
.
!code using the array1 in a 3D manner
.
End
Subroutine sub2
PARAMETER(L=3,M=5,N=12)
COMMON /cblock1/array1(L*M*N)
COMMON /cblock2/array2(L,M,N)
.
!code using the array1 in a 1D manner
.
End
In this code sub1 treats the block of memory (array1), which has a total number of elements of L*M*N, as a 3D array L by M by N. However, sub2 treats the memory as a 1D array. for a similar common block (cblock2), which was used consistently between routines, I moved the arrays to a module as follows in the newer code
PROGRAM main
call alloc
call init
call sub1
call sub2
.
.
.
End
Subroutine alloc
use cblock2
PARAMETER(L=3,M=5,N=12)
COMMON /cblock1/array1(L,M,N)
ALLOCATE(array2(L,M,N)
End
Subroutine init
use cblock2
PARAMETER(L=3,M=5,N=12)
COMMON /cblock1/array1(L,M,N)
DO k=1,N
DO j=1,M
DO i=1,L
array1=0.0
array2=0.0
End DO
End DO
End DO
End
Subroutine sub1
use cblock2
PARAMETER(L=3,M=5,N=12)
COMMON /cblock1/array1(L,M,N)
.
!code using the array1 in a 3D manner
.
End
Subroutine sub2
use cblock2
PARAMETER(L=3,M=5,N=12)
COMMON /cblock1/array1(L*M*N)
.
!code using the array1 in a 1D manner
.
End
Module cblock2
real, allocatable :: array2(:,:,:)
End module cblock2
I would like to do a similar thing with the cblock1 but I am unsure as to how to use it as a 3d array in sub2 as it is declared as a 1D array in the use module
The old code treated the same memory as two completely different shapes/ranks depending on how they are declared in the individual common blocks but now with the "use" statement each routine sees the exact same declaration. I have tried an alias in the use statement (e.g. use cblock1, array1D(:)=>array1) but that does not seem to be correct syntax. All I want to do is duplicate the way that the old program used the memory but with dynamic array sizes.
If your suggestion could be used to accomplish this please give an example of what the code should look like before compiling with the "!DIR$ IGNORE_TKR" directive.
Thanks |
|
| Back to top |
|
 |
mkcolg
Joined: 30 Jun 2004 Posts: 4996 Location: The Portland Group Inc.
|
Posted: Tue Dec 04, 2012 2:34 pm Post subject: |
|
|
You need to pass the arrays to sub2. Something like:
| Code: | Module cblock1
PARAMETER(L=3,M=5,N=12)
real, allocatable :: array1(:,:,:)
End module cblock1
Module cblock2
use cblock1
real, allocatable :: array2(:,:,:)
End module cblock2
PROGRAM main
use cblock1
use cblock2
call init
call sub1
call sub2(array2)
...
END program main
Subroutine sub1
use cblock1
use cblock2
.
!code using the array1 in a 3D manner
.
End
Subroutine sub2 (array2)
use cblock1
real array2(*)
..
end |
or something like
| Code: | Module cblock
PARAMETER(L=3,M=5,N=12)
real, allocatable :: array1(:,:,:)
real, allocatable :: array2(:,:,:)
contains
Subroutine sub1
.
!code using the array1 in a 3D manner
.
End subroutine sub1
Subroutine sub2(A2)
!DIR$ IGNORE_TKR A2
real A2(*)
...
End subroutine sub2
End module cblock
PROGRAM main
use cblock
call init
call sub1
call sub2(array2)
...
END program main
|
I may be off a bit on my code here, but hopefully this will help get you started.
- Mat |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2002 phpBB Group
|