Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
221 Views

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

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
Highlighted
188 Views

I have also try by using the PACK instruction, but not with any success.

Does anyone have an idea. 

        INTEGER,  DIMENSION (10,3)          :: MAT_XY
        INTEGER,  DIMENSION (30)            :: PACK_XX
        LOGICAL,  DIMENSION (10,3)          :: MASK
 
 
!        PACK_XXX(:) = 0       ! for further try
 
        MASK(:,:) = .TRUE.
 
        MAT_XY=RESHAPE((/ (i,i=1,30) /),(/10,3/))
 
        PACK(MAT_XY,MASK,PACK_XX)
!         PACK(MAT_XY,.TRUE.,PACK_XX)  ! I think, this is supposed to also work

 

Thanks

0 Kudos
Highlighted
Employee
188 Views

Hi Adjeroud,

Thank you for raising this query. As your query has reached inappropriate forum, I will help you in routing this topic to the correct forum for better discussion. We appreciate your patience.

Regards,

Arvind

Intel Developer Zone Support

 

0 Kudos
Highlighted
188 Views

S R, Arvind (Intel) wrote:
I will help you in routing this topic to the correct forum for better discussion.

Thanks Arvind !

Et voila !

      PROGRAM ESSAI_POINTER

!!----------------------------------------------------------------------
!!                  ***  PROGRAM ESSAI_POINTER  ***
!!
!! ** PURPOSE :  LITTLE EXERCISE ON POINTER USES
!!
!!----------------------------------------------------------------------
      IMPLICIT NONE
      INTEGER,  DIMENSION (10,3) , TARGET  :: MAT_I
      INTEGER,  DIMENSION (:)    , POINTER :: AD1_MAT_I
      MAT_I(:,:)=0
      AD1_MAT_I(1:30) => MAT_I(:,:)

      MAT_I(:,:)=0
      AD1_MAT_I(5:11)=3

      print *,MAT_I(1:5 ,1)
      print *,MAT_I(6:10,1)
      print *,MAT_I(1:5 ,2)
      print *,MAT_I(6:10,2)
      print *,MAT_I(1:5 ,3)
      print *,MAT_I(6:10,3)

      MAT_I(3,:) = 2
      print *,""
      print *,AD1_MAT_I

      END PROGRAM ESSAI_POINTER

 

Not after the first try, but finally, I'm now able to do exactly what i need, with both method ! Pointer et EQUIVALENCE.

Thanks everyone for your support.

 

0 Kudos
Highlighted
Black Belt Retired Employee
188 Views

EQUIVALENCE is bad - don't use it in new code. As you found, you can use pointer bounds remapping.

0 Kudos
Highlighted
188 Views

Thank you Dr.  I really appreciate this kind of lighting! Moreover, EQUIVALENCE seems to be easier to use ...
So, I really enjoy not making bad choices in my early development.

for my knowledge, that it is the bad point of using EQUIVALENCE ?

0 Kudos
Highlighted
Black Belt Retired Employee
188 Views

EQUIVALENCE has been deemed obsolete in the standard. Its use can encourage errors and hard-to-maintain applications. There are almost always better ways to accomplish what EQUIVALENCE does.

0 Kudos
Highlighted
New Contributor I
188 Views

But the EQUIVALENCE has deep roots in the assembler language i.e associate the same address to different variables and is very simple to understand.

The RESHAPE statement is in my opinion absolutely obscure: which other language has a similar function ? 

People in charge of defining Fortran standard, who have made such a fuss with POINTER, TARGET, and  so on ..., are continuing to mark as obsolete useful features and add new features uselessly complicated. 

0 Kudos
Highlighted
188 Views

Steve,

>>EQUIVALENCE has been deemed obsolete in the standard. Its use can encourage errors and hard-to-maintain applications.

Then what is the functional difference with: pointer(...) => RESHAPE(other(...)) or the ASSOCIATE equivalent?

To me, the pointer route is not only confusing, and complicated (Luigi's sentiments), but from my viewpoint is more "hard-to-maintain".

My reasoning is the EQUIVILENCE is placed with the variable declarations. Thus providing some indication that the variable/array is multi-purposed as well as how it is repurposed, whereas using a pointer hides this multi-purposes-ness from all places except where it is used. IOW pointer can tend towards being blindsided. I suppose one could argue that the foundation array having TARGET provides the heads up to some extent for pointer=> but no such heads up for ASSOCIATE.

Jim Dempsey

0 Kudos
Highlighted
Black Belt Retired Employee
188 Views

I would say that most users of EQUIVALENCE don't understand how it works and aren't aware of the rules the compiler assumes are valid. For example, if you EQUIVALENCE an INTEGER and a REAL, and define the INTEGER, the REAL becomes undefined. The typical use of EQUIVALENCE in the past was to save storage by overlaying variables on the same memory location. It was never intended to be used for reinterpreting a value. I have seen programs misuse EQUIVALENCE and COMMON in ways that the standard prohibits and then the programmers complain when the code no longer works due to an optimization.

Pointer bounds remapping is the proper solution for this case. Some of the other substitutes for EQUIVALENCE are clunky, such as TRANSFER, but the meaning is clear and both the user and the compiler are clear as to what is happening.

I don't get the gripe about ASSOCIATE.

0 Kudos
Highlighted
188 Views

>>I don't get the gripe about ASSOCIATE

While ASSOCIATE does not provide for re-typing a variable/array, it does provide for repurposing the, or part of the, variable/array.
The non-portable UNION can also do the same. There are many cases in programming where it is expedient to represent the same memory location(s) as differing types. Reading data files form old systems with non-conforming data layouts.

Jim Dempsey

0 Kudos
Highlighted
Black Belt Retired Employee
188 Views

ASSOCIATE can do much more than UNION or EQUIVALENCE. It can create arrays that are discontiguous, but it's mainly intended as an aid to clarity.

0 Kudos
Highlighted
Valued Contributor III
188 Views

I eliminated equivalence from all my code many tears ago, I found it had been used in some very cludgy ways and was a source of some unpredictable results. Irrespective of if you like it or not, It  has been declared obsolete and thus it is not wise to be developing new code that uses it. In my world all new code should only be compiled with standards checking on. Simillarly  I won't use a circular saw without the safety guard ot drive my car without a seat belt.

 

0 Kudos
Highlighted
New Contributor I
188 Views

Not using EQUIVALENCE that has a deep root in the assembler language can prevents you to create efficient software architectures.

Coding is a bit different thing. 

 

0 Kudos
Highlighted
188 Views

>>ASSOCIATE can do much more than UNION or EQUIVALENCE...
Correct, however, it cannot retype a variable/array/array section, or re-layout a record, whereas a UNION (or a "cast") can.

Jim Dempsey

0 Kudos
Highlighted
188 Views

Thank you for all your answers, which I read with great interest.
Your opinions seem to differ. So here is how I construct my conclusion:

jimdempseyatthecove (Blackbelt) wrote:
[…] My reasoning is the EQUIVALENCE is placed with the variable declarations. […]
Jim Dempsey

That's a very positive point!  
Equivalence has a very simple and clear use for developers and the variables will be very clearly identified.
In addition, the associated variables can no longer be changed by mistake in the rest of the developments.
In our developments, all variables are declared and initialized in modules separate from the rest of the code. So there is very little risk of REAL/INTEGER confusion.  


Steve Lionel (Ret.) (Blackbelt)
wrote:
[…] if you EQUIVALENCE an INTEGER and a REAL, and define the INTEGER, the REAL becomes undefined. […]

This means that the compiler or the execution will inform me of the improper use of an undefined variable in case of an error.

Luigi R. wrote:

Not using EQUIVALENCE that has a deep root in the assembler language can prevents you to create efficient software architectures.


The performance of my code is a real priority.
It seems to me that efficiency and performance have more or less the same meaning.
 
My conclusion is that EQUIVALENCE is an excellent solution to my problem. But I'm just a paper belt... so I'm very interested in your explanations!


Thanks thanks thanks :-)

0 Kudos
Highlighted
188 Views

FYI Being a paper belt has no bearing on your programming ability. Welcome to this forum.

Jim Dempsey

0 Kudos
Highlighted
Valued Contributor III
188 Views

jimdempseyatthecove (Blackbelt) wrote:

>>ASSOCIATE can do much more than UNION or EQUIVALENCE...
Correct, however, it cannot retype a variable/array/array section, or re-layout a record, whereas a UNION (or a "cast") can. ..

Jim, what do you mean by "re-layout a record"?

0 Kudos
Highlighted
188 Views

...

TYPE MyRecord
UNION
  MAP
     REAL(8) :: BLA
  END MAP
  MAP
     CHARACTER(LEN=8) :: NAME
  END MAP
  MAP
     INTEGER(4) :: COUNT
  END MAP
END UNION
... ! other record items
   REAL(8) :: OTHER(nnn)
END TYPE MyRecord

And use that type to read records from a file (as binary).

When the data file contains POD (plain old data), and when you cannot tell what the record is until after you read the record, it is useful to be able to describe the record in a manner that has a multiplicity of declarations. A similar issue when writing arbitrary POD files.

Jim Dempsey

0 Kudos
Highlighted
Valued Contributor III
188 Views

Thanks, I presumed you were referring to UNIONs but I wanted to be sure.

Would you by any chance have a fully worked out, real-life example of record processing using this non-standard UNION type along with some measure of performance you get, either in terms of speed and/or data size that you think is important to consider?

Now, one can achieve something similar to the above use case of UNIONs involving POD via polymorphiic types, TRANSFER, etc. in Fortran.  But then the issue brought up often is performance.  But as far as I know, there has been no objective quantification of any difference in performance with UNIONs vs some standard-conforming one, just words and references to inefficient assembler code, etc.  That does not help move beyond the status quo with Fortran.  With an actual example, if someone can illustrate substantial difference in non-standard UNION and what the standard offers now, that could help contemplate what to consider in a future revision to the standard - it's worth an online discussion (see below) among the interested parties. 

Readers: please see this recent site at GitHub: https://github.com/j3-fortran/fortran_proposals

0 Kudos