- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Assume I want to convert a 1d allocatable array (with 100 elements) into a 10x10 2d allocatable array, without making a copy of the original data (this solution is too expensive given the actual size of my arrays).
Assuming that my 100 elements are sorted in the correct order (row-major order for the Fortran arrays), it seems I would just need to modify the array descriptor. How can I do this?
For instance, if V is originally[1,2,3,4] and I want to transform it into
V = [1 3
2 4 ],
while retaining the allocatable nature of V.
Thank you!
Olivier
PS: Note that if the arrayis not declared as allocatable and contains contiguous data then this is trivial.
Assuming that my 100 elements are sorted in the correct order (row-major order for the Fortran arrays), it seems I would just need to modify the array descriptor. How can I do this?
For instance, if V is originally[1,2,3,4] and I want to transform it into
V = [1 3
2 4 ],
while retaining the allocatable nature of V.
Thank you!
Olivier
PS: Note that if the arrayis not declared as allocatable and contains contiguous data then this is trivial.
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can't change the rank of an existing array. But what you could do is this:
[cpp]USE, INTRINSIC :: ISO_C_BINDING INTEGER, POINTER :: V2D(:.:) ... call C_F_POINTER (C_LOC(V), V2D, [2,2])[/cpp]Now, V2D is a 2D array with the contents of V. However, you cannot deallocate V2D - any deallocation has to be of V.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you Steve - I guess I need to find another way of programming what I want to do.
Olivier
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - opmkl
Thank you Steve - I guess I need to find another way of programming what I want to do.
Olivier
A possible, though rather abstruse, way of doing this would be to put operations which involve the 2D version of V into separate subroutines in a separate file. The calling routine would pass the 1D version, and the subroutine would declare the incoming variable as 2D. An interface block would be needed in the calling routine to fool it into thinking that the subroutine was expecting a 1D vector to be passed to it.
For example, if the calling routine contained:
[plain]n=size(v1,1) sqrt_n=int(sqrt(n)) ! Assuming you want a square 2D array ! as per your example. interface subroutine do_something_to_v1(n, v1) integer, value :: n real, intent(inout), dimension(n**2) :: v1 end subroutine do_something_to_v1 end interface call do_something_to_v1(sqrt_n, v1) [/plain]
...and the subroutine was declared in a separate file (not a USED module) as:
[plain]subroutine do_something_to_v1(n,v2) integer, value :: n real, intent(inout), dimension(n,n) :: v2 ... end subroutine do_something_to_v1 [/plain]
... then v2 would bereceived bythe subroutine as if it were an n-by-n array, without any copying taking place because all that's being put on the stack is the memory address of v1. v2 is kind-of allocatable in that it exists only when being worked on, and the samecode will work regardless of the dimension assigned to v1. Any overhead associated with the calling of the subroutines should be removed by the compiler during optimisation.
I did say it was abstruse, but I've used this approach successfully to pass 2D arrays to VML functions that expect to receive 1D vectors. I expect the same would work in reverse.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, that's the traditional way of doing it when your dummy arrays are not allocatable. However, in my case, I need to keep the allocatable properties of my arrays in the subsequent subroutines that manipulate them.
Ideally, only the array descriptor would need to be updated. But there are probably some hurdles to do this (it would be implemented otherwise,I reckon) - Steve may be able to shed some light on this.
Thanks!
Olivier
Ideally, only the array descriptor would need to be updated. But there are probably some hurdles to do this (it would be implemented otherwise,I reckon) - Steve may be able to shed some light on this.
Thanks!
Olivier
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Changing the rank of an array means changing the size of the descriptor as you have a new set of bounds to list. There is no support for this at all.
You can, as has been suggested in this thread, manipulate the data in the array using a different shape, but you can't "reshape" the original array.
You can, as has been suggested in this thread, manipulate the data in the array using a different shape, but you can't "reshape" the original array.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I see. I didn't know the descriptors had variable lengths. I thought they were structures of fixed size (since arrays have a rank of 7 at most).
Thanks Steve,
Olivier
Thanks Steve,
Olivier
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, the descriptor varies by rank. Fortran 2008 increases the number of dimensions to 15 - we may support 31 in the future.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page