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

ASSUME_ALIGNED Directive GRIPE

jimdempseyatthecove
Honored Contributor III
1,323 Views

When ASSUME_ALIGNED Directive is used on a pointer it specifies the pointer is alligned but not the data to which it points. Is there a syntax which can be used to specify the data to which a pointer points is aligned?

I know I can work around this by calling a subroutine with the pointer providing the reference to the aligned item then specify the dummy argument with ASSUMED_ALIGNED. But this is a bit of a hoop-jumping exercize.

To have parity (parody) with allocatable arrays then the behavior on the pointer would imply the allocatable arraydescriptor is alligned and not the data it references (which is not the case).

Since the the memory of reference is used for ASSUMED_ALIGNED in the case of allocatable arrays why then is not the memory of reference by way of pointer used for ASSUMED_ALIGNED?

Jim Dempsey

0 Kudos
12 Replies
Intel_C_Intel
Employee
1,323 Views

Dear Jim,

Assume-aligned support was initially just for C and recently added to Fortran to unify the compiler hints between the languages. Perhaps we still have some holes in its implementation.

The hint is supposed to apply to the data associated with a pointer variable, not to the variable itself (the latter would be less useful, since the compiler typically can control the alignment of that variable pretty well).

So, in C:

void doit(int *p)

{

int i;

__assume_aligned(p,16);

for (i=0; i<4; i++)

{

p = 0;

}

}

Which enables vectorization with 16-byte aligned data movement for what p points-to (the scalar variable p itself resides on the stack):

mov eax, DWORD PTR [4+esp]

pxor xmm0, xmm0

movdqa XMMWORD PTR [eax], xmm0

Likewise, in Fortran, as you already suggested, the following syntax would be used to inform the compiler that the reference variable a points-to 16-byte aligned data, but it says nothing about scalar variable a itself:

subroutine doit(a)

integer i

real a(4)

!DIR$ ASSUME_ALIGNED a:16

do i = 1, 4

a(i) = 0

enddo

end

Also, constant subscript expressionsare evenallowed in thehint(e.g. a(2)) to define an offset with respect to a base, a feature I am rather fond of.

If you have found a Fortran example with an explicit pointer where the hint seems to apply to the variable, not the associated data, or if you have read this somewhere, please let me know.

Smiley with tongue out [:-P]

Aart Bik

http://www.aartbik.com/

0 Kudos
Steven_L_Intel1
Employee
1,323 Views

The Fortran manual does say:

If address is a Cray POINTER or it has the POINTER attribute, it is the POINTER and not the pointee or the TARGET that is assumed aligned

This is consistent with other attributes which apply to pointers. Note that Fortran pointers are not like C pointers in the sense that there is no inderiction operator. I agree that it seems less than helpful in this context.

0 Kudos
Intel_C_Intel
Employee
1,323 Views

Thanks Steve. Please verify my example below to see if I did my Fortran homework right, but I just verified that the vectorizer indeed analyzes the assume aligned onpointee Titself (as documented), although I fail to see much use of this (note, however, that in this case the vectorizer uses 16-byte aligned on the actual data "A" which is progagated through pointer-analysis, so that ultimately the loop is 16-byte aligned, but no thanks to the directive):

SUBROUTINE CRAY

REAL A(4)

REAL T(4)

POINTER (P,T)

P = LOC(A)

!DIR$ ASSUME_ALIGNED T:16

DO I = 1, 4

T(I) = 1

ENDDO

END

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,323 Views

Forgive my ignorance for lack of sitting on the Fortran standards committee....

Fortran is generallya by-Reference language.

real :: arrayA(100)
real, allocatable :: arrayB(:)
real, pointer :: arrayC(:)
...
do i=1,100
arrayA(i) = arrayB(i)+arrayC(i)
end do

Syntatically arrayA, arrayB and arrayC are all references to the respective arrays regardless of the underlaying type of the variable. There is no syntatical distinction on the expression in regards to if the token is: a) a dummy variable with explicit diminsion (no descriptor), b) a pointer (with descriptor), c) an allocatable (with descriptor), or d) an array of known dimension (no descriptor).

Why then would you treat pointer different from the other forms of reference?

Jim

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,323 Views

Aart,

I would prefer to use ASSUMED_ALIGNED as an attribute in the declaration of the variable (array) and therefore avoid sprinkling

!DIR$ ASSUME_ALIGNED ...

throught the program.

With the !DIR$ am I permitted to do the following

real, pointer :: foo(:)

...

!dir$ ASSUMED_ALIGNED foo(1):16

Noting that foo is a pointer to an array.

Jim

0 Kudos
Intel_C_Intel
Employee
1,323 Views

Dear Jim,

I actually agree with you that treating pointers differently seems strange and, I must admit, it certainly was not what I expected (to assure our customers, please note that I wrote the alignment analyzer on an intermediate representation; as long as our Fortran front-end experts like Steve et al. and all other compiler engineers speak the same intermediate, even when not all compiler engineers are ultimate Fortran experts, we can still write correct a Fortran compiler [ok, now let the jokes begin....]).

Giventhese semantics, I dont see another short-term solution other than to provide hints on the data assigned to the pointer, or to annotate at a loop level using the sledgehammer vector aligned. Could you please provide a complete example with a typical usage, so I may be able to suggest something more concrete?

Aart Bik

http://www.aartbik.com/

0 Kudos
Steven_L_Intel1
Employee
1,323 Views

Aart, your example uses Cray pointers and there you name the data and not the pointer.Jim is trying to use standard Fortran pointers where there is no separate pointer variable - whether you reference the pointer or the pointed-to data depends on context.

As an example of the ambiguity, consider the definition of the INTENT attribute as it applies to POINTER arguments. Does it say what you can do to the pointer or what you can do to the data? The standards committee eventually decided it meant the pointer (so an INTENT(IN) pointer cannot be reassociated, but you can do anything you want to the data pointed to!)

Jim, I would encourage you to submit a feature request to Intel Premier Support asking that ASSUME_ALIGNED apply to the pointed-to data.

0 Kudos
Intel_C_Intel
Employee
1,323 Views
MADsblionel:

Aart, your example uses Cray pointers and there you name the data and not the pointer.

Hi Steve,

I know Jim was not directly interested in Cray-pointers, but my example was simply to test whether the alignment analysis adheres to the documentation you just quoted. As for the use of pointeeT instead of pointer P, I was forced to do this, as P is rejected (and the compiler already has direct control over the alignment of the actual data "A"):

!DIR$ ASSUME_ALIGNED T:16

(okay)

!DIR$ ASSUME_ALIGNED P:16

cray.f(7) : Error: The memory reference associated with an ASSUME_ALIGNED directive must be an array or subscripted array reference.


!DIR$ ASSUME_ALIGNED P:16
---------------------^
cray.f(7) : Severe: Please report this error along with the circumstances in which it occurred in a Software Problem Report
!DIR$ ASSUME_ALIGNED P:16
^
[ Aborting due to internal error. ]
compilation aborted for cray.f (code 1)

(yup, that's right, internal error!).

Aart

0 Kudos
Steven_L_Intel1
Employee
1,323 Views

Thanks, Aart, I've reported the error.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,323 Views

>>As an example of the ambiguity, consider the definition of the INTENT attribute as it applies to POINTER arguments.<<

And the same ambiguity exist when you use an allocatable array. Descriptor vs what descriptor references. Setting that aside.

I do not pass pointers as pointer arguments. I call subroutines with the call using the pointer but the subroutine declared as taking a reference to what the pointer points to. There is no problem with this and I can place the ASSUME_ALIGNED on the dumy argument declaration.

The problem area is when declaring a pointer in a module (for global access by routines USEing that module). There is no current syntax to declare that the pointer is restricted to point to alligned data, or a more relaxed definition "the data to which the pointer points has been declared as being aligned but the programmer is responsible for assigning aligned references". The more ridged method should be easy enough to do. Also, a debugging option can be set to test the alignment on => assignment.

Jim

0 Kudos
Steven_L_Intel1
Employee
1,323 Views

There's no semantic ambiguitry with allocatable arrays. There's only one object, the array. That it happens to be passed by descriptor is irrelevant as there's nothing you can do to the descriptor on its own - there's no pointer assignment or NULLIFYfor allocatables. With pointers, you can manipulate the pointer separately from the data depending on what syntax you use.

I agree that ASSUME_ALIGNED should apply to the data.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,323 Views

>> there's nothing you can do to the descriptor on its own - there's no pointer assignment or NULLIFYfor allocatables<

MOVE_ALLOC does both at the same time.

Jim

0 Kudos
Reply