- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
My code involves a derived-type variable (denoted 'Object' hereafter) holding another derived-type variable as a component (denoted 'SubObject').
The SubObject has a type-bound procedure for computing some quantity, let say Q.
The Object also has a procedure for computing Q, but the actual computation is delegated to the SubObject component.
Here is simple example:
Module SubObject_Module implicit none private public :: SubObject_Type Type :: SubObject_Type contains procedure :: Compute => Compute_SubObj End Type contains Pure Subroutine Compute_SubObj( This, Inp, Out ) class(SubObject_Type) ,intent(in) :: This integer ,intent(in) :: Inp integer ,intent(out) :: Out Out = Inp * 2 End Subroutine End Module Module Object_Module use SubObject_Module ,only: SubObject_Type implicit none private public :: Object_Type Type :: Object_Type private type(SubObject_Type) :: Sub contains procedure :: Compute => Compute_Obj End Type contains Pure Subroutine Compute_Obj( This, Inp, Out ) class(Object_Type) ,intent(in) :: This integer ,intent(in) :: Inp integer ,intent(out) :: Out call This%Sub%Compute( Inp, Out ) End Subroutine End Module Program Main use Object_Module ,only: Object_Type implicit none type(Object_Type) :: Object integer :: Inp = 5, Out call Object%Compute( Inp, Out ) End Program
As you can see, in the main program I'm calling the TBP from the Object variable using "call Object%Compute(...)" (line 43).
The only task of this TBP is to call the TBP from the SubObject component, using "call This%Sub%Compute(...)" (line 34)
My real code heavily uses this delegation approach, which leads to lots of TBP being actually only wrappers to components' TBP calls.
Now, I want to avoid the extra cost of calling all those "useless" TBP (Compute_Obj) by forcing inlining of the call to the component's TBP (Compute_SubObj).
How should I do so ?
For now, I'm adding the "!DEC$ ATTRIBUTES FORCEINLINE :: Compute_SubObj" line before the "Compute_SubObj" procedure:
!DEC$ ATTRIBUTES FORCEINLINE :: Compute_SubObj Pure Subroutine Compute_SubObj( This, Inp, Out ) class(SubObject_Type) ,intent(in) :: This integer ,intent(in) :: Inp integer ,intent(out) :: Out Out = Inp * 2 End Subroutine
Is it the correct way to enforce inlining?
I know that inlining can also be changed using the following compiler options:
-inline-factor
-inline-min-size
-inline-max-size
-inline-max-total-size
-inline-max-per-routine
-inline-max-per-compile
but with no guarantee that the inlining is actually going to happen.
Am I right ?
Thank for yous enlightenment.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
flying_hermes wrote:
Hi,
My code involves a derived-type variable (denoted 'Object' hereafter) holding another derived-type variable as a component (denoted 'SubObject').
The SubObject has a type-bound procedure for computing some quantity, let say Q.
The Object also has a procedure for computing Q, but the actual computation is delegated to the SubObject component.
...
As you can see, in the main program I'm calling the TBP from the Object variable using "call Object%Compute(...)" (line 43).
The only task of this TBP is to call the TBP from the SubObject component, using "call This%Sub%Compute(...)" (line 34)
My real code heavily uses this delegation approach, which leads to lots of TBP being actually only wrappers to components' TBP calls.
Now, I want to avoid the extra cost of calling all those "useless" TBP (Compute_Obj) by forcing inlining of the call to the component's TBP (Compute_SubObj).
How should I do so ?
...
Have you investigated extended derived types and checked whether your code design can be modified to make to use of them?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Actually, in the real code, the Object derived-type contains several sub-objects and wraps all there TBP in its own TBP.
Since multiple inheritance is not supported in Fortran, type extension will not help here.
Thanks anyway for the suggestion.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
flying_hermes wrote:
Actually, in the real code, the Object derived-type contains several sub-objects and wraps all there TBP in its own TBP.
Since multiple inheritance is not supported in Fortran, type extension will not help here.
Thanks anyway for the suggestion.
Oh well, if you can't make use of the right combination of inheritance and aggregation in code design (something that many OOP experts recommend over multiple inheritance), then the complex and limiting world of compiler-specific options and optimizations beckons you..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
While I am not too up on OOP programming in Fortran, I am assuming that you will be having multiple SubObject types. In OOP programming the methods are contained within the object, therefore if the subobject cannot be determined at compile time there is no way other than pointer to function. What you could do is to have the main object explicitly contain a pointer to method and where this pointer is defined when the subobject is bound to the object. This will remove one level of indirection, but it will not yield inlining.
What you might consider looking at is: http://sourceforge.net/projects/blockit/
Blockit can be used as a preprocessor to provide templates to Fortran. Therefore, if the subobjects are determinable at compile time, the compiler should be able to inline the method.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I found several, possibly contradictory, descriptions of the -inline-forceinline option.
The first description is the following:
Instructs the compiler to force inlining of functions suggested for inlining whenever the compiler is capable doing so. Typically, the compiler targets functions that have been marked for inlining based on the presence of directives, like DEC$ ATTRIBUTES FORCEINLINE, in the source code; however, all such directives in the source code are treated only as suggestions for inlining. The option instructs the compiler to view the inlining suggestion as mandatory and inline the marked function if it can be done legally.
However, I'm not sure if this documentation refers to the version latest versions of ifort or an old one.
The second description is taken from https://software.intel.com/en-us/compiler_15.0_ug_f :
This option instructs the compiler to force inlining of functions suggested for inlining whenever the compiler is capable doing so.
Without this option, the compiler treats functions declared with an INLINE attribute as merely being recommended for inlining. When this option is used, it is as if they were declared with the directive !DIR$ ATTRIBUTES FORCEINLINE.
In the fist case, it is explicitly said that "functions are marked for inlining based on the presence of directives, like DEC$ ATTRIBUTES FORCEINLINE", while in the second case, it say that "it is as if [functions] were declared with the directive !DIR$ ATTRIBUTES FORCEINLINE"
BTW, are subroutines also inlined ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FORCEINLINE basically tells the compiler to disregard its opinion as to whether inlining is worthwhile. Yes, subroutines can be inlined - the wording is sort of C-centric where everything is a function.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page