I have intention to point with the same procedure to two different procedures but I have not experienced programmer in Fortran so I need help.
This is my simple code:
module types
type :: type_one
integer, private :: a1,a2
contains
procedure, public :: f_data => set_data_a1
procedure, public :: f_data => cal_data_a2
end type type_one
private :: set_data_a1,cal_data_a2
contains
integer function set_data_a1(this)
class(type_one) :: this
this%a1 = 2
end function set_data_a1
integer function calc_data_a2(this)
class(type_one) :: this
this%a2 = this%a1 + 3
end function calc_data_a2
end module types
program types_pro
implicit none
type(type_one) :: type_obj
type_obj%f_data()
end program types_pro
I got this error:
`There is already a procedure with binding name 'f_data' for the derived type 'type_one' |
Is it possible to call both procedures at the same time with type_obj%f_data()?
A generic name, such as your f_data, allows calling procedures with different input signatures (rank, type, kind, and number of arguments) by the same name. But, because they have the same argument signatures the compiler can't determine which of calc_data_a1 and calc_data_a2 to execute when your code makes a call to f_data.
Which leads me to a question for you: How do you expect the compiler or code to behave ? What do you want the compiler to do ? (OK that was two questions.)
As a general rule, if you want the compiler to execute two procedures you have to make two calls. You could, I suppose, have one procedure call the other if you want both to run when one is called.
If you want to wrap multiple functions behind the same name they have to have different input signatures so that the compiler can work out which one to call.
Obviously my earlier version of this answer wasn't explicit enough:
No, there is no way to write your code to execute two different procedures in response to a single call to one of them. (Unless, that is, the one calls the other.) Furthermore, it is unreasonable to expect a single (procedure) pointer to point, at any one time, at more than one target.
Related
EDIT to provide more details:
1) The code that provides the libraries cannot be (easily) changed so profile_v1_type and profile_v2_type should be assumed to be immutable.
I have implemented #francescalus suggestion and it works for my small test case, but I was insufficiently clear about the problem, I think. The reason being that I can only modify my code not the code/types coming from the library. The problem will be that both will have t in the profile_type that gets imported which clash with the parent type.
But I am going to implement something where I replicate the contents of the derived type that I want and then use pointers and type-bound procedures to point to the components of the profile_type version that I want to use. It's not as clean as I wanted it to be but it's much better than I have now.
I am supporting a code that interfaces with another that has 2 versions - the two versions are very similar in interface and although the inputs and outputs are identical in property, they are obviously different derived types (they come from different libraries and differ slightly in the variables contained within. Most variable names inside these types are the same though crucially).
It is (apparently) necessary to support both at runtime, otherwise I would preprocess this all at compile time.
At the moment I have lazily copied and pasted the same code for each version (and all of the versions of derived types it uses) into separate subroutines (*_v1.f90, *_v2.f90).
This is annoying and not very maintainable.
What I'd like to be able to do is use some kind of pointer that doesn't care about what it's pointing to (or rather gets its type information from what it points to and is smart enough to know what's inside).
As I said above, the names are mostly the same, e.g. (t, for temperature, say)
From v1 of library:
TYPE profile_v1_type
REAL :: t
! loads of other stuff
END TYPE profile_v1_type
From v2 of library:
TYPE profile_v2_type
REAL :: t
! loads of other stuff, more than the first version
END TYPE profile_v2_type
In my code:
TYPE profile_container_type
TYPE(profile_v1_type) :: profile_v1
TYPE(profile_v2_type) :: profile_v2
! other arrays that are common inputs to both
END TYPE
! It's actually USE'd then allocated and initialised elsewhere, but I hope you get the idea
!USE profile_container_mod, ONLY : profile_container
TYPE(profile_container_type), TARGET :: profile_container
TYPE(*) :: p
REAL :: t1
!Version determined by a namelist
IF (Version == 1) THEN
p => profile_container % profile_v1
ELSE IF (Version == 2) THEN
p => profile_container % profile_v2
ENDIF
t1 = p % t + 1
.
.
.
ifort 19 gives these (expected) errors:
test.f90(24): error #8776: An assumed type object must be a DUMMY argument. [P]
TYPE(*), POINTER :: p
--------------------^
test.f90(24): error #8772: An assumed type object must not have the ALLOCATABLE, CODIMENSION, POINTER, INTENT(OUT) or VALUE attribute. [P]
TYPE(*), POINTER :: p
--------------------^
test.f90(39): error #6460: This is not a field name that is defined in the encompassing structure. [T]
t1 = p % t + 1
---------^
compilation aborted for test.f90 (code 1)
replace TYPE(*) with CLASS(*) gives the (still expected):
test2.f90(39): error #6460: This is not a field name that is defined in the encompassing structure. [T]
t1 = p % t + 1 ! or some clever function...
---------^
compilation aborted for test2.f90 (code 1)
This is fixed by SELECTing the type that you want to handle, but my point is that I want to do the same thing for either the v1 and v2 code (it will never be both). And I want to do it many times, not in this routine but in about a dozen routines.
I am open to using C pointers if the responder is able to provide a simple example to follow. I have tried (not recently) to solve this problem using C interoperability, but obviously without success!
Unlimited polymorphic entities are not the correct approach here.
Instead, we can define a base type which incorporates all of the common data and processing for the various other types. Here, let's call this base type profile_base_type:
type profile_base_type
real t
end type
The other two specific profiles can extend this base:
type, extends(profile_base_type) :: profile_v1_type
! v1 specific parts
end type
type, extends(profile_base_type) :: profile_v2_type
! v2 specific parts
end type
Then we can declare a polymorphic pointer of the base type
class(profile_base_type), pointer :: p
which can point to targets of either of the extending types:
p => profile_container%profile_v1
p => profile_container%profile_v2
Now, we can access the components of p which are in the type profile_base_type
t1 = p%t + 1
without having to use a select type construct.
Naturally, those specific aspects of the extending types cannot be accessed in this way but there are other considerations for that.
Updating some archaic F77 that no longer fully supported our needs. I am looking for the functional equivalent of VB's "WITH" statement to support the conversion from a mass of F77 disconnected, individual variables to hierarchical derived Types. While the code is much easier to read and understand the downside is that the code becomes very cumbersome and prone to typos. So, the use of WITH would greatly ease the conversion burden.
VB's "WITH" statement executes a series of statements on a single object or a user-defined type.
Example:
if I want to reference elements my derived Type named Loads I would write code with Loads% prefixing each element and that is cumbersome. The WITH statement allows one to re-write the block with an assumed reference to Loads%.
WITH Loads%
ID = blah
Description = blahblah
Duty(I) = 2
End WITH
Suggestions...?
There's no Fortran construct which provides a precise analog to what you describe as VB's with statement. For your particular example, you could write something along the lines of ...
Given a derived type definition such as
type :: load
character(4) :: id
character(32) :: description
integer, dimension(4) :: duties
end type load
and a variable of that type
type(load) :: loads
you can use a default constructor to set the values of the members of loads, like this:
loads = load('myid', 'my description', [1,2,3,4])
or even like this:
loads = load(duties=[3,4,5,6], id = 'id2', description='description')
If you look around on SO for Qs and As on the subject of Fortran derived type constructor you'll find out how to build more complicated constructors which don't need all the members to be given values when they are called. There are some useful resources elsewhere on the internet too.
If one of your concerns is to avoid typing long, and possibly multipart, entity names then the associate construct might help. For example, if, rather than loads the name of the variable you wanted to avoid typing was something like long%structured%entity you might write
associate (shnm => long%structured%entity`)
shnm%id = 'idxx'
*etc*
end associate
I'm sure you could easily come up with more extensive examples of the use of with which would not be easy to translate to Fortran without repeated writing of loads%.
For instance, I have a definition of type A in moduleA:
Module moduleA
implicit none
type A
private
integer::N
contains
...
procedure,pass::f=>f1
endtype
private::f1
contains
real function f1(self,x)
real::x(self%n)
end function
...
end Module
Then I found I meet a trouble when I override function f in other modules since I can not get the value of N. Even though I can have a method to get that, it seems that something like real :: x(self%get()) is impossible in the declaration. I want to keep the rule of "private" in OPP. So what choices can I have?
You cannot do that. At least in the way you describe. It would be better to see an example of the overriding to suggest other options.
The private attribute works differently in Fortran and therefore you should not directly use rules from other languages that use OOP where private means something different.
In Fortran private is about the local module, in C++ it is about the derived classes. This is very different and you cannot use the C++ (or Java, etc.) rules for private in Fortran when private in fact means something else.
To be clear, I assume you wanted this kind of overriding:
real function f2(self,x)
class(B) :: self
real::x(self%get())
end function
You than get these messages:
private.f90(15): error #8497: Illegal use of a procedure name in an expression, possibly a function call missing parenthesis. [GET]
real::x(self%get())
---------------------^
or
real::x(self%get())
1
Error: 'get' at (1) should be a FUNCTION
So the compilers will not accept a type-bound procedure in the declaration. They would accept an ordinary procedure.
This compiles in gfortran, but not in Intel Fortran. But get() must be public, which you might not want:
real function f1(self,x)
class(A) :: self
real::x(get(self))
end function
real function f2(self,x)
class(B) :: self
real::x(get(self))
end function
In ifort I get
error #8383: The dummy arguments of an overriding and overridden binding that correspond by position must have the same characteristics, except for the type of the passed object dummy arguments.
which is weird.
I read this link, it talks about Self-defining INTERFACE.
But I got confused about the saying
A Procedure should be able to read it’s own interface specification in
and INTERFACE block.
What is own interface specification? What does this link mean?
Before I start: This is about explicit interfaces. If in doubt, you should use MODULES so you don't have to worry about this.
Now to the question.
If you have a function, say this:
function square(a)
implicit none
real, intent(in) :: a
real :: square
square = a * a
end function square
And this function is in a separate file, to be compiled separately from the calling routine, then it would be advisable that the calling routine is told of the interface of this function. Something like this:
interface
function square(a)
implicit none
real, intent(in) :: a
real :: square
end function square
end interface
should be in the calling routine's declaration block. This way, the calling routine, while not knowing how the square function works, knows what types of parameters to pass to it, and what to expect back.
It is quite common to put this into a separate file, and include this file everywhere this function might be called.
Here's the issue: There are no checks that the interface block actually matches the real thing. So the idea of this proposal seems to be that in the code implementing the square function, you should be able to also include this separate file and then the compiler could check whether the interface block matches the declaration, and throw an error if wrong.
At the moment, though, including this interface block is explicitly forbidden by the standard.
I am writing some simulation code (almost) from scratch and want to use OOP features from fortran to keep it easier to maintain. I've learned in a fortran workshop, that one should be carefull when using OOP features within performance critical parts of the code.
My naive first approach (ignoring the warning) would be the following snippet. The background is the calculation of a system energy which needs an interaction potential. For this potential, I use an abstract type (potential). All users can then add their own potentials as extensions and define a keyword that is used to allocate their potential. The energy calculation in the main program does not change.
module system_mod
implicit none
type, abstract :: potential
contains
procedure(init), deferred :: init
procedure(eval), deferred :: eval
end type
type, extends(potential) :: my_potential
! some parameters
contains
procedure :: init => init_my_potential
procedure :: eval => eval_my_potential
end type
! omitted: other extensions of 'potential'
! and abstract interface of potential
type :: system
! some components
class(potential), allocatable :: pair_potential
contains
procedure :: init ! subroutine, which is used to allocate pair_potential depending on a passed keyword
end type
contains
! implementation of all routines
end module system_mod
program main
use system_mod, only: potential, my_potential, system
implicit none
character(len=3) :: keyword !
integer :: i
real :: coordinates(n,3) ! n is a huge number
real :: energy, system_energy
type(system) :: test_system
call test_system%init ( keyword )
! keyword tells which of the extensions of 'potential' is allocated
do i = 1, n
energy = test_system%pair_potential%eval ( ... )
system_energy = system_energy + energy
end do
end program
I think my main problem concerning the performance is that I don't get what the compiler actually does at compile time and which things are done at run time.
So my questions are:
How or when does the compiler check, which instance of 'eval' to use?
When the keyword is known at compile time, is there a type check in every iteration of the loop?
Would it be better to, for example, use a procedure pointer in the main program, and associate it at the beginning to the according 'eval' procedure?
Thank you very much in advance!
It has a virtual table of procedures that are possible to be called for the binding for all extended types and decides in run-time from this table.
Setting keyword may not help, it depends on how much the compiler is clever. I would use type instead of class if the type is known at the compile time. This is very likely to skip the vtable look-up.
The procedure pointer will affect the flow of the instructions too, although you may save some part of the vtable look-up. This really depends on the internals and is worth a try and some performance measurement.