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

Problem with a pointer procedure pointing to bound-type subroutine

FlyingHermes
New Contributor I
1,772 Views

Hi,

I am trying turn an existing code into Oriented-Object.
I need to define a pointer procedure which points to a bound-type subroutine
The source code is provided below:
- the typedef_module.f90 module defines the derived-type variable and its bound procedure.
- the second_module.f90 module makes the pointer procedure affectation and the procedure call
- the main.f90 is the main program

The compilation/execution is acheived by the following command:
ifort -c typdef_module.f90; ifort -c second_module.f90; ifort main.f90 typdef_module.f90 second_module.f90; ./a.out

[fortran]Program Main
use TypeDef_Module ,only: MyType
use Second_Module ,only: Action
implicit none
integer :: iinp, iout
type(MyType) :: TypVar
iinp = 5
call Action( TypVar, iinp, iout )
write(*,*) iout
End Program [/fortran]
[fortran]Module TypeDef_Module implicit none private public MyType Type :: MyType contains procedure ,nopass :: Fct End Type contains Subroutine Fct ( iinp, iout ) integer ,intent(in) :: iinp integer ,intent(out) :: iout iout = 2 * iinp End Subroutine End Module [/fortran]
[fortran]Module Second_Module implicit none private public Action contains Subroutine Action ( TypVar, iinp, iout ) use TypeDef_Module ,only: MyType implicit none type(MyType) ,intent(in) :: TypVar integer ,intent(in) :: iinp integer ,intent(out) :: iout interface Subroutine Fct_Interface ( iinp, iout ) integer ,intent(in) :: iinp integer ,intent(out) :: iout End Subroutine end interface procedure(Fct_Interface) ,pointer :: funct funct => TypVar%Fct() call funct( iinp, iout ) End Subroutine End Module [/fortran]
This code leads to the following compilation error:

[bash]$ ifort -c second_module.f90 second_module.f90(19): error #6553: A function reference is invoking a subroutine subprogram. [FCT] funct => TypVar%Fct() --------------------^ second_module.f90(19): error #6402: prPromoteSym : Illegal KIND & CLASS mix [FCT] funct => TypVar%Fct() --------------------^ second_module.f90(19): error #7021: Name invalid in this context [FCT] funct => TypVar%Fct() --------------------^ second_module.f90: error #5270: Internal Compiler Error: symbol not a SYMTOK second_module.f90: catastrophic error: **Internal compiler error: segmentation violation signal raised** Please report this error along with the circumstances in which it occurred in a Software Problem Report. Note: File and line given may not be explicit cause of this error. compilation aborted for second_module.f90 (code 1)[/bash]
Is there something I am doing wrong ?Thanks for your help.

By the way I am using:

[bash]$ ifort -V Intel Fortran Compiler XE for applications running on IA-32, Version 12.1.1.256 Build 20111011 Copyright (C) 1985-2011 Intel Corporation. All rights reserved. FOR NON-COMMERCIAL USE ONLY
[/bash]

0 Kudos
7 Replies
FlyingHermes
New Contributor I
1,772 Views
I managed to make the code work using a non-type-bound function (instead of subroutine).
However, I need a type-bound subroutine:

[bash]Program Main use TypeDef_Module ,only: MyType use Second_Module ,only: Action implicit none integer :: iinp, iout type(MyType) :: TypVar iinp = 5 call Action( TypVar, iinp, iout ) write(*,*) iout End Program Module TypeDef_Module implicit none private public MyType, Fct Type :: MyType contains procedure ,nopass :: Fct End Type contains Function Fct ( iinp ) result(iout) integer ,intent(in) :: iinp integer :: iout iout = 2 * iinp End Function End Module Module Second_Module implicit none private public Action contains Subroutine Action ( TypVar, iinp, iout ) use TypeDef_Module ,only: MyType, Fct implicit none type(MyType) ,intent(in) :: TypVar integer ,intent(in) :: iinp integer ,intent(out) :: iout interface Function Fct_Interface ( iinp ) result(iout) integer ,intent(in) :: iinp integer :: iout End Function end interface procedure(Fct_Interface) ,pointer :: funct ! funct => TypVar%Fct ! associate (TypFct => TypVar%Fct) ! funct => TypFct ! end associate funct => Fct iout = funct( iinp ) End Subroutine End Module[/bash]In the above code, Fct is exactly the same procedure than TypVar%Fct, except that is is not bound to a type.
If I comment line 50 and uncomment line 46, I get the following error:

[bash]second_module.f90(19): error #8191: The procedure target must be a procedure or a procedure pointer. [FCT] funct => TypVar%Fct --------------------^ second_module.f90(19): error #8180: The procedure pointer and the procedure target must have matching result types. [FUNCT] funct => TypVar%Fct ----^ second_module.f90(19): error #8178: The procedure pointer and the procedure target must have matching arguments. funct => TypVar%Fct ----^ compilation aborted for second_module.f90 (code 1) second_module.f90(19): error #8191: The procedure target must be a procedure or a procedure pointer. [FCT] funct => TypVar%Fct --------------------^ second_module.f90(19): error #8180: The procedure pointer and the procedure target must have matching result types. [FUNCT] funct => TypVar%Fct ----^ second_module.f90(19): error #8178: The procedure pointer and the procedure target must have matching arguments. funct => TypVar%Fct ----^ compilation aborted for second_module.f90 (code 1) [/bash]
I have also tried to used an associated block, without any success.
0 Kudos
Anonymous66
Valued Contributor I
1,772 Views
Hello,
The Fortran standard does not allow assigning a procedure pointer to type-bound procedure. This is why "funct => TypVar%Fct" results in error messages.

In regards to your original post, an Internal Compiler Error means there is a bug in the compiler. I will investigate it further and get back to you.

Regards,
Annalee
Intel Developer Support
0 Kudos
Anonymous66
Valued Contributor I
1,772 Views
I have reported the Internal Compiler Error to the developers. The issue number is DPD200179510.

I will post any updates I receive on the problem to this thread.
0 Kudos
FlyingHermes
New Contributor I
1,772 Views
OK... bad news.

So, do you have any recommendations to solve my problem which is the following:

I want to solve a system of ODE equations using an external library such as DVODE or IODE (the Intel Ordinary Differential Equation Solver library). Both these libraries provides subroutine procedures (DVODE/DODESOL) which require procedure arguments for evaluating the ODE system Right-Hand-Side (RHS) and its associated jacobian (JAC).

I defined an abstract type called with an type-bound procedure which integrates the system according to a specific integration method defined at run-time. An ODE system is then created extending this type. Therefore, procedures for evaluating the RHS and the JAC can varie at rune-time. As a consequence, I need a way, in the integration procedure, to call the ODE solver procedure with different RHS and JAC procedure. Instead of:
[fortran]call DODESOL ( ..., FCT_RHS, FCT_JAC, ... )[/fortran] I need some thing like this:
[bash]call DODESOL ( ..., This%FCT_RHS, This%FCT_JAC, ... )[/bash] where "This" in the passeddummy argumenent corresponding to the system to be integrated.Unfortunately, this last formulation generate errors since the compiler think a variable is passed instead of a procedure leading th the following error
[bash]error #6635: This actual argument must be the name of a procedure and not a data object.[/bash] Thanks

0 Kudos
Anonymous66
Valued Contributor I
1,772 Views
I would suggest adding procedure pointers to your type which point to the underlying procedures. You can then pass these procedures to the differential equation solvers.

Your call to the ODE solver would look something like:

[fortran]call DODESOL ( ..., This%FCT_RHS_procedure_pointer, This%FCT_JAC_procedure_pointer, ... )[/fortran]
0 Kudos
Anonymous66
Valued Contributor I
1,772 Views

We are planning to include a fix for the Internal Compiler Error in the next major release which is currentlyscheduled for later this year.

0 Kudos
Anonymous66
Valued Contributor I
1,772 Views
This is issue has been fixed in Intel® Fortran Composer XE for Linux* 2013 which is now available at the Intel® Registration Center. Regards, Annalee Intel Developer Support * Other names and brands may be claimed as the property of others.
0 Kudos
Reply