- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have two questions:
1. I want to write a subroutine MY_SUB(A,B,C,D) where A,B,C,D can each be either allocatable arrays or sections of allocatable arrays. Writing an explicit interface becomes a combinatorial problem, since the dummy arguments can be allocatable arrays or array sections. How do I get around this?
2. Assuming that a section of an allocatable array is passed to MY_OTHER_SUB. Is there any way to check the allocation status of the parent array? It is possible to pass an array section of an unallocated array to a subroutine, which triggers an access violation when attempting to access the array elements.
My goal is to write a robust subroutine which takes indiscriminatelyallocatable arrays or sections of allocatable arrays; and check the validity (allocation, shape and size) of these inputs.
Thanks in advance,
Olivier
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So what CAN you do? In "normal" code you could look at the value of LOC(arg) and see if it is "reasonable". It may not be zero if an array slice is passed. But if it's larger than oh, say, 4K, it's probably (but not definitely) ok. Then you can ask for the SHAPE of the array or use LBOUND and UBOUND, carefully, dimension by dimension.
If you wanted to be implementation-dependent, you could have an interface that declares the argument as assumed-shape but really fetches it as an address-sized integer array which will be the descriptor, and then peek at the descriptor fields to make sure they are "reasonable". There's a bit that tells you the allocation status is defined, and that will help.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- A is a full allocatable array (in this case, check for allocation status, size etc.)
- A is an array section (check that the array section is valid)
- A is an explicit array (check the array size).
I will try to implement your suggestion regarding examining the array descriptor - but it seems complicated, and maybe I could just forego all this and stick to a simple solution.
But then I guess another of my concerns is the efficient implementation of the calculations. Consider the example:
PROGRAM MY_PROG
IMPLICIT NONE
REAL(8),ALLOCATABLE :: R(:,:)
ALLOCATE(R(10000,100))
...
CALL SUB(R(:,20),SIZE(R,1))
END PROGRAM MY_PROG
SUBROUTINE SUB(V,N)
IMPLICIT NONE
REAL(8) V(N)
...
END SUBROUTINE SUB
In this case my actual argument is a section of anallocatable array, and my dummy argument is an explicit array. The help file stipulates that this is not an efficient way of passing arrays. Is this true here, since in this very example my array section is contiguous? Will an array temporary be created no matter what the contiguousness (?) of the array section is?
Olivier
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Make all calls to MY_SUB pass pointer to array or pointer to array slice.
Then initialize all (innitially uninitialized) array pointer that will be passed to MY_SUB to NULL()
Next, whenever you are required to construct a proper pointer into one of the pointers passed to MY_SUB you can test the source array to the construct pointer for use in MY_SUB to see if it is allocated. If if so, construct proper pointer, if not, NULL out pointer.
Now all calls to MY_SUB will have either a valid and associated pointer or .NOT. associated pointer.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[cpp]program my_prog implicit none real(8),allocateble,target :: R(:,:) real(8),pointer :: pR(:,:) => NULL() ... pR => R call check(pR) ... nullify(pR) call check(pR) ... pR => R(3:6,4:15) call check(pR) ! Note, above could error out at runtime ! use function to return pointer to rank 2 array pR => ptrRank2(R, L1, H1, L2, H2) ! asserts valid arguments if(.not. associated(pR)) goto YouHandleIt ... call check(pR) [/cpp]Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page