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

IFX pointer at object that has a Cray pointer

LostKiwi1
Beginner
468 Views

It is finally time for me to update some Windows research software I started developing with in the 1990s, initially with Microsoft Fortran PowerStation, then through DEC, Compaq and into Intel as the baton moved. Due in part to its origins (which really date back to the 1980s) with Fortran at its core but other languages for specialised bits, it has what is arguably not best practice: a mix of Fortan pointers and Cray points. Fortunately, there is (now rusty) assembly language in my skill set so I could look at the disassembled code to establish the cause of the problem.

 

Yesterday, getting the 25MB of source to compile under IFX only took a compiler option changes. However, progress ground to a halt until I tracked down what I believe is a compiler error (hopefully the only one I will encounter). The following minimalist program illustrates the problem and the work-around:

module CrayPointerFix
interface PointAtCrayTarget
module procedure PointAtCrayTarget
end interface
contains
subroutine PointAtCrayTarget(pVar,tVar)
!DIR$ ATTRIBUTES NO_ARG_CHECK :: PointAtCrayTarget
integer (4), pointer, intent(out) :: pVar
integer (4), target, intent(inout) :: tVar
pVar => tVar
end subroutine
end module

program Test
use CrayPointerFix
type T_Test
integer (4) :: i
end type
type (T_Test), pointer :: pTest
integer (8), automatic :: qTest
type (T_Test), target :: tTest
pointer (qTest,tTest)
nullify(pTest)
qTest = malloc(sizeof(tTest))
tTest%i = 123
pTest => tTest ! This does not correctly assign pTest as a pointer to tTest
if (pTest%i .eq. 123) then
write(*,*)'Success'
else
write(*,*)'Failure'
endif
call PointAtCrayTarget(pTest,tTest) !The work around is to off-load into a subroutine
if (pTest%i .eq. 123) then
write(*,*)'Success'
else
write(*,*)'Failure'
endif
end program

Although simplified here, code of the form pTest => tTest worked fine with all previous compilers I have used (the last of which being IVF 19.1.3.311).

 

As an aside, it would seem like pointers are the bane of my program. I think the last time I wrote a forum post was when I was transitioning from Dec/Compaq to one of the early versions of Intel Visual Fortran where, again, it was a compiler bug relating to Fortran pointers.

 

0 Kudos
3 Replies
Steve_Lionel
Honored Contributor III
426 Views

I can reproduce the problem you describe. 

0 Kudos
JohnNichols
Honored Contributor I
399 Views

It works nicely with the latest IFORT.   Playing with the program in IFX, in the main program there is no communication for the pointer to ttest, which you know, but it was fun to play with the code for a minute.  The pointer is assigned some random garbage in memory. 

0 Kudos
LostKiwi1
Beginner
416 Views

The slightly improved workaround, in case it has to deal with null (zero) cray pointers:

subroutine PointAtCrayTarget(pVar,tVar)
!DIR$ ATTRIBUTES NO_ARG_CHECK :: PointAtCrayTarget
!DIR$ ATTRIBUTES NOINLINE :: PointAtCrayTarget
integer (4), pointer, intent(out) :: pVar
integer (4), target, optional, intent(inout) :: tVar
if (present(tVar)) then
pVar => tVar
else
nullify(pVar)
endif
end subroutine

This makes use of the fact Fortran uses a null address for flagging optional parameters by reference. Attempting to pass a null Cray pointer (i.e., tTest with qTest = 0 in the opening post) generates a run-time error when debugging if the 'optional' is not specified.

0 Kudos
Reply