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

Pointer on Array - pointer and target same size but different shape.

BRAHIM__ADJEROUD
Beginner
4,232 Views

Hello

I have a little problem with array.

I would like to be able to access it according to coordinates relating to a table of rank 3 AND also according to coordinates of table of rank 1.

Here is an example below:

integer, dimension(2,2,2) , target:: Int_array_xyz
integer, dimension(8), pointer:: Int_array_xxx

Int_array_xyz = RESHAPE((I,I=1,8),(/2,2,2/))

Int_array_xxx(1) => Int_array_xyz(1,1,1)

________________________________________

This approach is not accepted.

It is also not possible to do the following:

integer, dimension(2,2,2) :: Int_array_xyz
integer, dimension(2) :: Int_array_xxx
EQUIVALENCE (Int_array_xxx(1) , Int_array_xyz(1,1,1) )

________________________________________

I’m trying to improve a computational tool, and for some reason, the previous developer chose to reference some values in a 3-dimensional space, and other values in a 1-dimensional space.

When someone wishes to perform matrix operations by combining certain values, we are obliged to carry out an expensive and dangerous calculation of index matches.
If I could access to some of my table values alternately according to the two index systems (1 dimension and 3 dimensions) I would save a lot of development time.

I thought about using the RESHAPE function to be able to switch from a 3D system to a 1D system, but it is not possible to make a RESHAPE on itself!


 

XXX(:,:,:) = RESHAPE(XXX(:),(/2,2,2/))

So I have to create two tables. So that I double the memory space used, and also I need to synchronize the tables when one or the other is modified.
 

XYZ(:,:,:) = RESHAPE(XXX(:),(/2,2,2/))

________________________________________

Does anyone have any ideas?
Is that possible? Do I have to look further, on the side of "type" or "class"?

Thank you

0 Kudos
51 Replies
jimdempseyatthecove
Honored Contributor III
450 Views

>>would a variant type be better compared to what you have pursued with UNION..MAP feature in your code?

No.

The UNION permits one to redefine a POD blob in differing ways, and, more importantly, then be able to reference the data in a natural way. While std:variant can make storage for a variable polymorphic so to speak, it only does so for scalar variables. Additionally, the C++ variant  While you could potentially use a struct/class in the variant list, then the coding to extract/insert data is in an "unnatural" way (via use of get and put functions). IMHO C++ variant is worse than TRANSFER, as well as REINTERPRET_CAST if that were available.

Jim Dempsey

0 Kudos
FortranFan
Honored Contributor II
450 Views

jimdempseyatthecove (Blackbelt) wrote:

>>would a variant type be better compared to what you have pursued with UNION..MAP feature in your code?

No.

The UNION permits one to redefine a POD blob in differing ways, and, more importantly, then be able to reference the data in a natural way. While std:variant can make storage for a variable polymorphic so to speak, it only does so for scalar variables. Additionally, the C++ variant  While you could potentially use a struct/class in the variant list, then the coding to extract/insert data is in an "unnatural" way (via use of get and put functions). IMHO C++ variant is worse than TRANSFER, as well as REINTERPRET_CAST if that were available.

Jim Dempsey

Jim,

Thanks, based on your code and your comments here and elsewhere. I had felt your answer will "no".  So it's good to have your confirmation here

But now with your comment, "UNION permits one to redefine a POD blob in differing ways, and, more importantly, then be able to reference the data in a natural way," is it possible for you to elaborate further in your own words, or preferably illustrate with some working examples, particularly your 2 points, "redefine a POD blob in differing ways" and "able to reference the data in a natural way".

If writing your own examples and to get them to work is too much a demand on your time at present, can you please try the code I showed above in Quote #25 - you should be able to run it as-is successfully with your Intel Fortran processor - and add/edit a few illustrations to explain your points?

My hunch is in the main program I posted in Quote #25, may touch upon the aspects you indicate, like the same variable 'u' of 'union_t' is being "redefine(d) ..in differing ways" and you can then "reference it in a natural way" e.g., first instance with a string and u%name() reference.  But it will be best to read your specific explanations.

My desire here is to collect such needs from Fortranners across a broader spectrum, especially online, and bring such needs to the attention of those who truly want Fortran to advance.

0 Kudos
FortranFan
Honored Contributor II
450 Views

andrew_4619 wrote:

A variant type in Fortran would indeed be useful. I can think of several examples where that is what I  needed and instead had to adopt a more long winded/clumsy approaches.

Andrew,

If you can, please provide such feedback at https://github.com/j3-fortran/fortran_proposals.  Your comments on all matters involving Fortran proposals there will be invaluable.

0 Kudos
jimdempseyatthecove
Honored Contributor III
450 Views

>>

From my post #22 (edited to clarify)

subroutine AVRDB_Save_REALquick(val)
    use MOD_AVRDB
    implicit none
    real(8) :: val
    select case(AVRDB%out%bc%Mode)
    case(AsREAL4)
        AVRDB%out%bc%valREAL4 = val
        if((AVRDB%out%bc%ByteCount+4) .gt. AVRDB%out%bc%BlobSize) call AVRDB_WriteBlob(AVRDB%out%bc)
        AVRDB%out%bc%Blob(AVRDB%out%bc%ByteCount+1:AVRDB%out%bc%ByteCount+4) = AVRDB%out%bc%ArrayINT1(1:4)
        AVRDB%out%bc%ByteCount = AVRDB%out%bc%ByteCount + 4
        return
...

In the above case a REAL(8) is the incoming argument to the subroutine. An initial test for room in the current POD blob for four bytes (sizeof(REAL(4)). The REAL(8) value is stored into the UNION variable valREAL4 (first listing in #22) with the type conversion normally performed with Fortran (AVRDB%out%bc%valREAL4 = val). REAL(8) to REAL(4) conversion.

The converted value, now as REAL(4), is lifted from the UNION via the INTEGER(1) ArrayINT1(1:4) and stored into the POD Blob, also an INTEGER(1) array (pointer) at the next location(s). Then the ByteCount is advanced.

The point I am trying to make is there is cumbersome TRANSFER, the code is easy to see as opposed to (untested)

AVRDB%out%bc%Blob(AVRDB%out%bc%ByteCount+1:AVRDB%out%bc%ByteCount+4) =
    TRANSFER(REAL(val, SELECTED_REAL_KIND(6)), INTEGER(1), 4)

Jim Dempsey

0 Kudos
LRaim
New Contributor I
450 Views

Sorry but I am not of English mother language. 

What is the meaning of "POD blob" ? 

0 Kudos
andrew_4619
Honored Contributor II
450 Views

POD - Plain Old Data - ie real, integer etc rather than a derived type or other complex entity, blob is just jargon I think in the context data point / thing / item could be used.

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
450 Views

To expand on Andrew's post, the only property from the POD's perspective is its size. Content is irrelevant. From the programming aspect, it is up to the programmer to use in the manner they desire. For example, a disk sector can be thought of as a POD. Or a track on a vinyl record is a POD. I'm not sure you are old enough to know what a mag tape record is or I would have used that for an exemplar.

For additional information, Google is your friend enter the following search phrase:

   C++ POD

Don't feel bad about asking such a question. We all do that here.

Jim Dempsey

0 Kudos
FortranFan
Honored Contributor II
450 Views

jimdempseyatthecove (Blackbelt) wrote:

From my post #22 (edited to clarify) ..

Jim,

It's still unclear what exactly you mean by "UNION permits one to redefine a POD blob in differing ways, and, more importantly, then be able to reference the data in a natural way,"

Please take a look at this link: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf.  Can you put together a Motivation section for UNION..MAP in Fortran along the same lines as shown in this document?  It'll be very useful if you can take the effort to do so.  I do not think what you have shown here thus far can help make a case for this facility of interest to you to be introduced in some form in standard Fortran (and which is my only interest in this thread).

You can, of course, continue to use the non-standard UNION..MAP from Intel Fortran for your own needs and not bother about the Fortran standard in any way to help pull together use cases, motivation, etc..  But then you know well such a non-standard UNION..MAP option is not something readers here can always consider for their own applications.

0 Kudos
jimdempseyatthecove
Honored Contributor III
450 Views

>>It's still unclear what exactly you mean by "UNION permits one to redefine a POD blob in differing ways

!!! You are one of the most (Fortran) knowledgeable posters on this forum. Am I to assume you have no experience with C/C++/(other) union statements?

A UNION is either declared in a global/module/local data/user defined type scope. When in, as an example, a user defined type, the item of interest can be read or written without the requirement of the use of a getter, putter function or the use some explicit syntax such as TRANSFER. While I cannot say about the newest Standards of Fortran, I believe one cannot use TRANSFER on the lhs of =.

The issue the link was addressing (for C++) was how to determine what to do when the union contains members that contain class/struct initializers and in particular where the initialization of a given member would conflict with that of another residing at, or overlapping, the same location(s) of the POD. Answer to this quandary is/are to a) disallow ctors of data members within the union... and then let the programmer define a union ctor that uses placemen new operators to properly construct the union. The link illustrate the use of an assignment operator for this purpose, but a proper union ctor/dtor/default would be more orthogonal with class and struct. Note, default is "do nothing".

Jim Dempsey

0 Kudos
BRAHIM__ADJEROUD
Beginner
450 Views

Ok ... it's not so easy, but thanks to this page :

https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-equivalence

I have reached my goal. So, it is possible to use the EQUIVALENCE statment to make two array of differente shape but same size following each other.

01       PROGRAM ESSAI_POINTER
02
03 !!----------------------------------------------------------------------
04 !!                  ***  PROGRAM ESSAI_POINTER  ***
05 !!
06 !! ** PURPOSE :  LITTLE EXERCISE ON POINTER USES
07 !!
08 !!----------------------------------------------------------------------
09       IMPLICIT NONE
10       INTEGER,  DIMENSION (10,3)          :: MAT_I_2
11       INTEGER,  DIMENSION (30)            :: EQ3_MMS                 
12
13       EQUIVALENCE(EQ3_MMS , MAT_I_2)               
14                  
15       MAT_I_2(:,:)=0 
16       EQ3_MMS(5:11)=3    
17   
18       print *,MAT_I_2(1:5 ,1)       
19       print *,MAT_I_2(6:10,1)      
20       print *,MAT_I_2(1:5 ,2)     
21       print *,MAT_I_2(6:10,2)  
22       print *,MAT_I_2(1:5 ,3)
23       print *,MAT_I_2(6:10,3)                                                                                              24
25       MAT_I_2(3,:) = 2
26       print *,""                                                                                                                          27       print *,EQ3_MMS
28       
29       END PROGRAM ESSAI_POINTER                 

So, now I'm going to try to do the same thing with the pointer statment. I may have made a mistake in my previous try.

Thanks

0 Kudos
Reply