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

Using Cray pointer allocated memory as Rank2 or Rank3 reallocatable array

Daniel_P_4
Beginner
732 Views
Hi,

If someone knows this cannot be done, or how to do this, please tell me so I can let it rest, bless my OC little heart.

Background

I have a F90 program that is already part of a commercial engineering software package. I am required to modify this program to make it a slave within larger over arching master system. I have to do all memory allocation, deallocation, etc. with calls to the API of this system. This system is not compatible with DIMENSION(:), ALLOCATABLE:: or DIMENSION(:), POINTER variables in F90, but it is compatible with Cray Pointer (aka Integer pointer) form. All my F90 allocatable and pointer-allocated arrays have to be converted to Cray Pointer equivalents.

With respect to any Rank1 array, this is not a problem. In fact, it cleans up some of the old code to do this. I have no problems with the Rank1 arrays.

However, I do have some Rank2 and Rank3 allocatable arrays. Im finding Cray Pointer conversion to be messy in these instances. For the allocate-once case, I have to do the allocation in a top-level routine and then call another routine with the Cray Pointee as an argument. The corresponding dummy variable in the subroutine is declared with the desired Rank2 or Rank3 dimension and size to reshape the array. And that is the simple scenario.

More complex is the case of Rank2 or Rank3 with re-allocation. When I find the need to reallocate, I have to return to the calling routine, reallocate, shift data (unless I reallocate on the last subscript), and then drop back into the lower level routine at the right place. This seems too tricky for my blood. Its not too hard in a prototype program, but will be tougher when I try to transplant it into the real code.

My Desirement I want the Rank1 Cray Pointee and the Rank2 (or 3) representation of the same memory to be handled inside the bounds of the same program unit. Right now, I have to pass through an interface to achieve the desired reshaping. I do not want to explicitly make any copies (I believe REALLOC will make a copy if it has too, but contiguously appends more memory in-place when possible). If I have to use F90-allocatable to make a temporary copy, it defeats my purpose, since I could just leave things that way in the first place.

Is there a way to do this with RESHAPE? My understanding is that this makes a reshaped copy. When I make changes to the Rank2 form, I want the changes to happen in the Rank1 space instantly because it is the same memory.

What I want is akin to EQUIVALENCE, but the Cray Pointee cannot be in an EQUIVALENCE statement.

My final solution has to work across several platforms, and with the exception of using the Cray Pointer, should in every other way be as generic as possible.

Right now, the only method involve popping back and forth between a calling routine that does Cray Pointer memory operations, and a called routine that does the real work.

Dan
0 Kudos
3 Replies
Steven_L_Intel1
Employee
732 Views
I'm not 100% certain I understand what you want to do, but maybe it's this:

First, declare interface blocks for the allocation routines using the C_PTR type from ISO_C_BINDING rather than using Cray pointers. For example, you might have an allocate routine such as this:

module overarching_routines
use iso_c_binding

interface
function alloc (size)
type(C_PTR) :: alloc
integer, intent(in) :: size
end function alloc
end interface
end module overarching_routines

Now when you want to use them, you can do something like this:

use overarching_routines
type(C_PTR) :: cp
real, pointer, dimension(:) :: array_1d
real, pointer, dimension(:,:) :: array_2d

cp = alloc(1000)
! Convert address to pointers of the desired shape
call C_F_POINTER (cp, array_1d, [1000])
call C_F_POINTER (cp, array_2d, [250,4])

want to reallocate? Call your reallocate routine and then repeat the C_F_POINTER calls with the new shape.
0 Kudos
Daniel_P_4
Beginner
732 Views
I'm not 100% certain I understand what you want to do, but maybe it's this:

First, declare interface blocks for the allocation routines using the C_PTR type from ISO_C_BINDING rather than using Cray pointers. For example, you might have an allocate routine such as this:

module overarching_routines
use iso_c_binding

interface
function alloc (size)
type(C_PTR) :: alloc
integer, intent(in) :: size
end function alloc
end interface
end module overarching_routines

Now when you want to use them, you can do something like this:

use overarching_routines
type(C_PTR) :: cp
real, pointer, dimension(:) :: array_1d
real, pointer, dimension(:,:) :: array_2d

cp = alloc(1000)
! Convert address to pointers of the desired shape
call C_F_POINTER (cp, array_1d, [1000])
call C_F_POINTER (cp, array_2d, [250,4])

want to reallocate? Call your reallocate routine and then repeat the C_F_POINTER calls with the new shape.

Steve,

You may have saved my bacon. This looks very promising, as long as it works on most/all F90 compliant compilers. I think our list of compilers is Windows/Intel, Linux/Intel, HP UX, IBM AIX. Do you know how standard the ISO_C_BINDING is. The "ISO" part gives me lots of hope.

Why the heck would I want to do all this? I wrote this program about 10 years ago, but I'm not a "real programmer". The project was self contained; I did not need to interface with anyone else. I had just read a F90 book, and I was hot to trot, and I wrote this program. I greatly abused my ALLOCATE privileges, mainly by not counting things up ahead of time when possible, so I made prolific use of this feature, including fairly clumsy methods of enlarging the arrays. Over the years, I have grown this program. Some parts were replaced and made more efficient, in a patchwork way of course, so by now, it's a fine example of 10-year old, single-developer, free-range, organically grown software. No one knows the program but me.

The company I did all this for was recently acquired by a much larger entity so our technology could become an internal organ of their flagship product, which is why I have to use "their" memory calls, which means all significant allocatable arrays have to be reworked into something that is compatible. I don't enjoy eviscerating my "child". Believe me; it's not something I really want to do.

You have helped me several times in the past - always useful, always appreciated. Thanks again.

Dan





0 Kudos
Steven_L_Intel1
Employee
732 Views
Oh, dear. No, this won't work on many compilers. It requires Fortran 2003 features. IBM's AIX compiler certainly supports it, HP almost certainly does not.
0 Kudos
Reply