Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
The Intel sign-in experience is changing in February to support enhanced security controls. If you sign in, click here for more information.
27555 Discussions

How to call subroutine with real(8), intent(inout), pointer :: a2d( : , : )

MWind2
New Contributor III
499 Views

How to call subroutine from

real(8), pointer :: a2d( : , : )
!...
else if( idim==2 ) then
    a2d(bounds(1)%lb:bounds(1)%ub,bounds(2)%lb:bounds(2)%ub)=>array_data
    !a2d(0:aidimn(1)-1, 0:aidimn(2)-1)=>array_data
    ! manipulate a2d test
    call S2DSA(a2d)
    !do i=0,2
    !  a2d(i,3)=PI*a2d(i,0)*a2d(i,0)*a2d(i,1)*a2d(i,2)/4
    !end do
    ! end manipulate a2d
!...
subroutine S2DSA(a2)
real(8), dimension(:,:),intent(inout) :: a2
do i=0,2
  a2(i,3)=PI*a2(i,0)*a2(i,0)*a2(i,1)*a2(i,2)/4
end do
end subroutine S2DSA

I get error as is 

error #8055: The procedure has a dummy argument that has the ALLOCATABLE, ASYNCHRONOUS, OPTIONAL, POINTER, TARGET, VALUE or VOLATILE attribute.
Required explicit interface is missing from original source. [A2D]

0 Kudos
1 Solution
MWind2
New Contributor III
382 Views

Thanks to all responding. Fortran is obviously not my first language.  One solution seems to be 

subroutine dfnr8(SA)
use ifcom
use ISO_C_BINDING
  implicit none
  INTERFACE
   SUBROUTINE  S2DSA(LB1,UB1,LB2,UB2,A2D)
      INTEGER, INTENT(IN) :: LB1,UB1,LB2,UB2
      real(8), INTENT(INOUT), pointer :: a2d(:, : )
   END SUBROUTINE  S2DSA
...

for the 2d case.

View solution in original post

11 Replies
mecej4
Black Belt
462 Views

There are several circumstances in which an implicit interface is inadequate for calling a subroutine. Arguments with the pointer attribute and assumed shape arguments are two such cases. In addition, in your example code, you indicate that you wish to remap the dummy argument array with non-default bounds.

All these questions could be addressed here or the relevant details looked up in a Fortran guide book. However, a more important question is: "Why move a one line calculation into a separate subroutine?" In other words, if you can describe the reasons why you wish to create S2DSA, a more helpful answer may become possible.

In the meantime, try the following code with and without the two instances of "0:" on line-39.

program tptr
implicit none
integer :: i, j, idim
real, pointer :: a2d( : , : )
real, target :: array_data(3,4)
type bound_T
   integer :: lb, ub
end type
type(bound_T) :: bounds(2)
!
idim =2
do i = 1, 3
   do j = 1,3
      array_data(i,j) = i+j*0.1
   end do
end do
array_data(:,4) = -99.0
print 10,(array_data(i,:),i=1,3)
print *
bounds(1)%lb = 0; bounds(1)%ub = 2
bounds(2)%lb = 0; bounds(2)%ub = 3
if( idim==2 ) then
   a2d(bounds(1)%lb:bounds(1)%ub,bounds(2)%lb:bounds(2)%ub) => array_data(:,1:3)
   print 10,(a2d(i,:),i=0,2)
   print *
   print 20,lbound(a2d,1),ubound(a2d,1),lbound(a2d,2),ubound(a2d,2)
   call S2DSA(a2d)
   print *
   print 10,(a2d(i,:),i=0,2)
endif
10 format(4F10.1)
20 format('A2D has dimensions ',i1,':',i1,', ',i1,':',i1)

CONTAINS

subroutine S2DSA(a2)
implicit none
integer i,r1,r2,c1,c2
real, dimension(0:,0:),intent(inout) :: a2   ! Without the two 0s, lower bounds default to 1
r1 = lbound(a2,1); r2 = ubound(a2,1)
c1 = lbound(a2,2); c2 = ubound(a2,2)
print 20,r1,r2,c1,c2
20 format('A2  has dimensions ',i1,':',i1,', ',i1,':',i1)
do i=r1,r2
   a2(i,c2) = a2(i,c1)*a2(i,c1)*a2(i,c1+1)*a2(i,c1+2)
end do
end subroutine S2DSA
end program

 

MWind2
New Contributor III
452 Views

The main reason for the way the original is written is that it is meant to handle any safearray with dimension one to five and instead of requiring code to process in fortran with each case within the code for all, a user supplied subroutine can handle a match with each dimensional case. Also, changes to the array are intended to be preserved upon return to the created safearray.. The zero index was simply my preference. See dfadn.f90 which the 2d part has the first attempt at calling a sub instead of being within the if else if. 

jimdempseyatthecove
Black Belt
435 Views

Why not simplify by using "old school" programming:

...
if( idim==2 ) then
  call S2DSA(array_data(:,1:3),bounds(1)%lb,bounds(1)%ub,bounds(2)%lb,bounds(2)%ub)
endif
...

subroutine S2DSA(a2,r1,r2,c1,c2)
implicit none
integer i,r1,r2,c1,c2
real, dimension(r1:r2,c1:c2),intent(inout) :: a2   ! Without the two 0s, lower bounds default to 1
do i=r1,r2
   a2(i,c2) = a2(i,c1)*a2(i,c1)*a2(i,c1+1)*a2(i,c1+2)
end do
end subroutine S2DSA

Something like that.

Jim Dempsey

JNichols
New Contributor I
427 Views

I am also interested in why we are still using the dimension statement, it makes the code harder to read, you find say a2 then you need to look to the left for the dimensions.  

People say nothing is impossible, but I do nothing every day - from WP. 

 

andrew_4619
Honored Contributor II
410 Views

worse than that John you sometimes you see the dimension on a separate line remote from the type, I would have though having attributes  remote from the thing is a throwback that should be deprecated.....

 

JNichols
New Contributor I
387 Views

I agree, I saw that one a few weeks ago in a program and it had me stumped for a while.  

MWind2
New Contributor III
383 Views

Thanks to all responding. Fortran is obviously not my first language.  One solution seems to be 

subroutine dfnr8(SA)
use ifcom
use ISO_C_BINDING
  implicit none
  INTERFACE
   SUBROUTINE  S2DSA(LB1,UB1,LB2,UB2,A2D)
      INTEGER, INTENT(IN) :: LB1,UB1,LB2,UB2
      real(8), INTENT(INOUT), pointer :: a2d(:, : )
   END SUBROUTINE  S2DSA
...

for the 2d case.

JohnNichols
Valued Contributor II
365 Views

it was an interesting problem, it supplied an interesting debate and kept these chaps, using the term in the non-gender specific meaning like guys is no longer gender specific, interested,

 

One cannot ask more.  

Or as Hardy once said 1729 is such a boring number and as his student replied - Sir it is not.  

JohnNichols
Valued Contributor II
358 Views

LOL it is not a prime, it has many factors. 

MWind2
New Contributor III
349 Views

Code used with 2d,3d

Reply