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

Error when checking if pointer is associated

Solal_A_
Beginner
1,269 Views

I recently started to use procedure pointers and it all worked fine. Now however, I get a segmentation fault when checking if one of those pointer is associated ONLY when it is null (i.e. no error when said pointer is associated).

I built a MCVE but this example code runs fine in all conditions, so there's no point posting it here. I am then thinking the error might be somewhere else in the code. Here is my original code:

module mms
    !***************
    !some code
    !***************
    procedure(template_get_rho    ), pointer :: get_rho => null()                                         
    interface
        function template_get_rho(x1, x2, time) result(rho)                                              
            import :: dp                                                                                 
            implicit none                                                                             
            real(dp), intent(in) :: time                                                              
            real(dp), dimension(0:), intent(in)   :: x1, x2                                           
            real(dp), allocatable, dimension(:,:) :: rho                                              
        end function      
     end interface      

    !***************
    !some code
    !***************

 contains
     subroutine initialize_mms
          select case(mms_case)
          case(1)
              !***************
              !some code, get_rho is NOT associated to anything
              !***************
          case(2)
              get_rho => prob2_get_rho
          end select

          !nullify(get_rho)    <------------------------ Error here when uncommented
          !get_rho => null()   <-------- No errors here

          if(associated(get_rho)) then  <------------------ Error here when get_rho set to null()
              rho(0:nx-1, 0:ny-1) = get_rho(x, y, time)
          end if
     end subroutine

    !************
    ! some code
    !************
end module mms

 

For case(2), the code runs with no error. However, when I try to nullify(get_rho), I get a seg fault when calling the nullify statement. When I point get_rho to the null() pointer or for case(1), the seg fault happens at the associated statement.

Any idea what I'm doing wrong? I am using mpiifort 4.1.3.048 with the following debug flags:

-fpp -check all -traceback -warn all -implicitnone -heap-arrays

 

0 Kudos
8 Replies
jimdempseyatthecove
Honored Contributor III
1,269 Views

You are missing some code from your snip.

Line 22, presumably mms_case is a module integer variable not shown
Line 34, we do not know what rho is. Can we assume it is a "procedure(template_get_rho), pointer"? if so, then use => for assignment.

Jim Dempsey

0 Kudos
Solal_A_
Beginner
1,269 Views

Hi Jim,

- I have not included all the code as it is too long. 

- mms_case is actually a global variable passed by a use statement.

- I made an error while copy-pasting my code here, the assignement was indeed =>

- rho is a 2D array. get_rho points to a function returning just that.

0 Kudos
IanH
Honored Contributor II
1,269 Views

If your minimum example doesn't exhibit the problem, then that suggests that stuff that you have elided from the minimum example is problematic.  Perhaps the the elided stuff is trampling memory that causes problems with the pointer assignment.

What is the ifort version?  Is it the latest release?

If rho is a data object (a 2D array), then you can't point it at a procedure.  Are you missing parentheses after get_rho on line 34?

0 Kudos
Solal_A_
Beginner
1,269 Views

IanH,

I agree that the error might actually be somewhere else since I was not able to reproduce the error.

As I've mentioned, I'm using mpiifort 4.1.3.048 but I'm not sure what the latest is. I'm in a university and I think the sys admins only update compiler versions once or twice a year.

About rho, that was (yet again, I apologize) another typo. I have fixed it in an edit. However, the error persists even if I remove that the function call and replace it with, say, a print statement. 

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,269 Views

rho(0:nx-1, 0:ny-1) = get_rho(x, y, time)

How did you define rho? (as available to the new line 35)

Jim Dempsey

0 Kudos
Solal_A_
Beginner
1,269 Views

Jim,

I think you have missed the point. The error is before I call get_rho but when it is null() and I check if it is associated. For you info, rho is set with allocate(rho(-buf:nx-1+buf, -buf:ny-1+buf) so there's no problems there. Also, when get_rho is associated, the code runs normally. 

I have edited the post so it is more clear.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,269 Views

Earlier I posted what is below the ----

It is strange that nullify(get_rho) fails, but that get_rho => null() succeeds. This somewhat confuses what is stated below.

----------------

Do a little introspection: For nullify(get_rho) to fail implies that the memory location of the pointer is invalid. This can happen on Linux if your module is:

a) compiled as a static object (absence of -fpic) as opposed to being position independent (presence of -fpic) .AND. is assembled into a shared library (.so) which requires -fpic.

or possibly

b) compiled as a position independent  object (presence of -fpic) as opposed to a static object (absence of -fpic) .AND. is assembled into a static library (.a) or directly into the executable which both require absence of -fpic.

Jim Dempsey

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,269 Views

>>For you info, rho is set with allocate(rho(-buf:nx-1+buf, -buf:ny-1+buf) so there's no problems there.

This is still not entirely clear.

Your interface of get_rho of type template_get_rho has a return array named rho.
The module mms is shown with a procedure pointer get_rho.
The module, as shown, does not contain a module scoped array named rho

IOW the rho specified in initialize_mms cannot possibly be the same rho as specified in you code snip.

Lack of stating where the initialize_mms scoped rho is located, and allocated is not providing us readers with sufficient information to fully understand the environment of the code shown. So this lack of detail makes it difficult for us readers to provide you with anything other than a guess at the usual suspects of the problem.

This is another unfounded guess at the potential problem

Your interface to get_rho (template_get_rho) has the return argument rho attributed as allocatable with no intent. This implies that the procedure (function) pointed to by get_rho is permitted to allocate and/or reallocate and/or deallocate the return array. Also note that the left side of

    lhs  = get_rho(x, y, time)

can potentially be a pointer to a 2D array of dimension (:,:) in addition to an allocatable array of dimension (:,:).

Therefore there is a potential for some ambiguity as to if the associated(get_rho) applies to the (potential) pointer to the function or the return of the function. I think it should be the pointer to the function and that it may be a compiler bug. However, consider what is to be expected when such a function returns a pointer. Which would the associated(p) refer to??

Now then, IIF (if and only if) all the functions of template_get_rho type will never allocate or reallocate or delete the output array then remove the ", allocatable" from the interface block, and from all functions declared to be used to have its address inserted into the pointer. Doing this will remove the ambiguity from consideration by the compiler.

Jim Dempsey

0 Kudos
Reply