Cannot pass a valid communicator from fortran to c/c++ - c++

After passing MPI communicator from Fortran to C/C++ and upon checking the size communicator resulted in the following error message:
An error occurred in MPI_Comm_size on communicator...MPI_COMM_WORLD
...MPI_ERR_COMM: invalid communicator
Although the communicator on C/C++ side is not MPI_COMM_NULL, looks like it is not valid either. Below are the code that produced the error message.
C++
extern "C"
{
MPI_Comm* f_MPI_Comm_f2c(MPI_Fint f_handle)
{
MPI_Comm* comm;
comm = (MPI_Comm*)malloc(sizeof(MPI_Comm));
*comm = MPI_Comm_f2c(f_handle);
assert(*comm != MPI_COMM_NULL);
int size;
MPI_Comm_size(*comm, &size);
std::cout << "size: " << size << std::endl;
return comm;
}
}
Fortran module
module mymodule
use mpi
use, intrinsic :: ISO_C_Binding, only: c_ptr, c_null_ptr
implicit none
private
interface
function f_MPI_Comm_f2c(comm) result(optr) bind(C, name="f_MPI_Comm_f2c")
import c_ptr
implicit none
integer, intent(in) :: comm
type(c_ptr) :: optr
end function f_MPI_Comm_f2c
end interface
type(c_ptr), save :: ccomm = c_null_ptr
public :: CreateCcomm
CONTAINS
subroutine CreateCcomm(com)
!type(c_ptr) :: ccomm
integer, intent(in) :: com
ccomm = f_MPI_Comm_f2c(com)
end subroutine CreateCcomm
end module mymodule
Fortran driver
program main
use mpi
use mymodule, only : CreateCcomm
IMPLICIT NONE
integer error
call MPI_Init(error)
call CreateCcomm(MPI_COMM_WORLD)
call MPI_Finalize (error)
end

Related

Implicit interface procedure pointer member for derived type

In a derived type, I am trying to use a generic procedure function pointer member-type in order to point to different same derived type-bound procedures, which happen to have different interfaces.
module SharedMod
use SettingsMod
implicit none
type, public :: shared_t
type(settings_t) :: settings
...
contains
...
procedure, pass :: run
procedure, nopass :: readSettings, getSettingsFromProg
end type shared_t
contains
subroutine run(this, sett_file)
class(shared_t) :: this
character(len = 132), intent(in), optional :: sett_file
if (present(sett_file)) then
this%settings%GetSettings => this%readSettings
else
this%settings%GetSettings => this%getSettingsFromFinelg
endif
#if defined __PROG__
call this%settings%GetSettings(this%settings)
#else
call this%settings%GetSettings(this%settings, sett_file)
#endif
...
end subroutine run
...
subroutine readSettings(setts, file)
class(settings_t) :: setts
character(len = *), intent(in) :: file
integer :: itmp
real(RDP) :: rtmp
print *, '#Shared::readSetting() : reading settings from file..'
end subroutine readSettings
subroutine getSettingsFromProg(setts)
implicit none
class(settings_t) :: setts
print *, '#Shared::getSettingsFromProg() : reading settings from PROG..'
end subroutine getSettingsFromProg
end module
module SettingsMod
implicit none
type, public :: settings_t
...
procedure(), public, pointer, nopass :: GetSettings => null()
end module
When compiling using ifort I get:
error #8191: The procedure target must be a procedure or a procedure pointer. [READSETTINGS]
this%settings%GetSettings => this%readSettings
error #8191: The procedure target must be a procedure or a procedure pointer. [GETSETTINGSFROMFINELG]
this%settings%GetSettings => this%getSettingsFromFinelg
I also tried the version where GetSettings() is a type-boud procedure, i.e.
module SettingsMod
...
type, public :: settings_t
...
contains
procedure(), public, pass :: GetSettings => getSettingsFromProg, readSettings
...
end type settings_t
abstract interface
subroutine getSettingsFromProg(this)
import settings_t
class(settings_t) :: this
end subroutine getSettingsFromFinelg
end interface
abstract interface
subroutine readSettings(this, file)
import settings_t
class(settings_t) :: this
character(len = *), intent(in) :: file
end subroutine readSettings
end interface
...
end module
having :
error #6784: The number of actual arguments cannot be greater than the number of dummy arguments. [GETSETTINGS]
call this%settings%GetSettings(sett_file)
At this point, I have two questions:
Why do I get these errors??
How would you suggest to implement such a concept, if I was clear enough to explain it?
Thanks a lot.
EDIT after first #Vladimir 's comment.
After having post the answer in which I show how I finally found a working solution, still, I have more questions now:
Why did it work adding () just to the type-bound procedures pointed to?
Why did it work without pointer assignment?
Why did the equivalent type-bound procedure version not worked, even providing abstract interfaces to the two external procedures?
Still look forward to discussion.
It worked for the function-pointer procedure member-type version, after having added () after the procedure keyword in the shared_t type-bound procedures:
module SharedMod
use SettingsMod
implicit none
type, public :: shared_t
type(settings_t) :: settings
...
contains
...
procedure, pass :: run
procedure(), nopass :: readSettings, getSettingsFromProg
end type shared_t
contains
subroutine run(this, sett_file)
class(shared_t) :: this
character(len = 132), intent(in), optional :: sett_file
#if defined __PROG__
call this%settings%GetSettings(this%settings)
#else
call this%settings%GetSettings(this%settings, sett_file)
#endif
...
end subroutine run
...
subroutine readSettings(setts, file)
class(settings_t) :: setts
character(len = *), intent(in) :: file
integer :: itmp
real(RDP) :: rtmp
print *, '#Shared::readSetting() : reading settings from file..'
end subroutine readSettings
subroutine getSettingsFromProg(setts)
implicit none
class(settings_t) :: setts
print *, '#Shared::getSettingsFromProg() : reading settings from PROG..'
end subroutine getSettingsFromProg
end module
module SettingsMod
implicit none
type, public :: settings_t
...
procedure(), public, pointer, nopass :: GetSettings => null()
end module
Still, I have more questions now:
Why did it work adding () just to the type-bound procedures pointed to?
Why did it work without pointer assignment?
Why did the equivalent type-bound procedure version not worked, even providing abstract interfaces to the two external procedures?
Looking forward to discussion.

Can I mimic multiple passed-object dummy arguments in Fortran?

I would like to write a procedure which takes two passed-object dummy arguments, such as
module m
type, abstract :: Parent
contains
procedure(f_Parent), deferred :: f
end type
abstract interface
subroutine f_Parent(foo,bar)
import Parent
implicit none
class(Parent), intent(in) :: foo
class(Parent), intent(in) :: bar
end subroutine
end interface
type, extends(Parent) :: Child
contains
procedure, public :: f => f_Child
end type
contains
subroutine f_Child(foo,bar)
implicit none
class(Child), intent(in) :: foo
class(Child), intent(in) :: bar
end subroutine
end module
but this is not allowed by the Fortran standard, as bar is not a passed-object dummy argument, and so must be class(Parent) and not class(Child).
My current solution is
subroutine f_Child(foo,bar)
implicit none
class(Child), intent(in) :: foo
class(Parent), intent(in) :: bar
select type(bar); type is(Child)
end select
end subroutine
which works, but the select type construct is too slow, and dominates the runtime of my code (this subroutine is called many times).
I have tried having a single passed-object argument which holds both foo and bar, e.g. as an array or pointer, but this is also forbidden by the standard.
Is there any way of mimicking the behaviour of having multiple passed-object dummy arguments which does not incur the cost of a select type construct? Or maybe a faster way of getting an argument of class(Child) from class(Parent)?
You can do it by using single dispatch twice:
Module m
Implicit None
Type, Public, Abstract :: Parent
Contains
Procedure( i_Parent_Parent ), Public , Deferred :: f
Procedure( i_Child_Parent ), Pass( bar ), Private, Deferred :: f_c_p
Procedure( i_set ), Public , Deferred :: set
End Type Parent
Type, Public, Extends( Parent ) :: Child
Integer , Private :: data
Contains
Procedure , Public :: f => f_Child_Parent
Procedure, Pass( bar ), Private :: f_c_p => f_Child_Child
Procedure , Public :: set => f_Child_set
End Type Child
Private
Abstract Interface
Subroutine i_Parent_Parent( foo, bar )
Import :: Parent
Implicit None
Class( Parent ), Intent( In ) :: foo
Class( Parent ), Intent( In ) :: bar
End Subroutine i_Parent_Parent
Subroutine i_Child_Parent( foo, bar )
Import :: Parent, Child
Implicit None
Class( Child ), Intent( In ) :: foo
Class( Parent ), Intent( In ) :: bar
End Subroutine i_Child_Parent
Subroutine i_set( foo, data )
Import :: Parent
Class( Parent ), Intent( InOut ) :: foo
Integer , Intent( In ) :: data
End Subroutine i_set
End Interface
Contains
Subroutine f_Child_Parent( foo, bar )
Implicit None
Class( Child ), Intent( In ) :: foo
Class( Parent ), Intent( In ) :: bar
Call bar%f_c_p( foo )
End Subroutine f_Child_Parent
Subroutine f_Child_Child( foo, bar )
Implicit None
Class( Child ), Intent( In ) :: foo
Class( Child ), Intent( In ) :: bar
Write( *, * ) 'In child child foo%data = ', foo%data, ' bar%data = ', bar%data
End Subroutine f_Child_Child
Subroutine f_Child_set( foo, data )
Implicit None
Class( Child ), Intent( InOut ) :: foo
Integer , Intent( In ) :: data
foo%data = data
End Subroutine f_Child_set
End Module m
Program driver
Use m, Only : Parent, Child
Class( Parent ), Allocatable :: foo, bar
Allocate( Child :: foo )
Allocate( Child :: bar )
Call foo%set( 3 )
Call bar%set( 4 )
Call foo%f( bar )
End Program driver
ian#eris:~/work/stack$ gfortran-8 -std=f2008 -fcheck=all -Wall -Wextra dd.f90
ian#eris:~/work/stack$ ./a.out
In child child foo%data = 3 bar%data = 4
ian#eris:~/work/stack$
Whether this is quicker than select type will be implementation dependent, but I think it is cleaner.

OCaml Typechecking Problem When Using Two Parameterized Modules

I have two modules, Graph and Game, which are parametrized by other modules. They also contain functions f and g which cause typechecking problems when I use them in a testing module. I left out lots of the code that is not important for this problem.
Here is a Graph module that has some module AbstractUSet. AbstractUSet.t is used a lot in the original code. The function f shall later take another function and do some work. The problem is, that the other function comes from another module and has a different type.
module UTYPE = sig
type t
val compare : t -> t -> int
end
module type GRAPH = sig
module U : UTYPE
module AbstractUSet : Set.S
val f : (AbstractUSet.t -> AbstractUSet.t) -> AbstractUSet.t -> AbstractUSet.t
end
module Graph (UA : UTYPE) : (GRAPH with module U=UA) = struct
module U=UA
module AbstractUSet = Set.Make(struct type t=U.t let compare=U.compare end)
let f g uset = g uset
end
The other module is the Game module. It does lots of things with AbstractVSet.t. It contains the function g that shall later be input for the function f from the Graph module.
module type GAME_PIECE = sig
type t
val compare : t -> t -> int
end
module type GAME = sig
module P : GAME_PIECE
module AbstractVSet : Set.S
val g : AbstractVSet.t -> AbstractVSet.t
end
module GameInstance (NA : GAME_PIECE) : (GAME with module P=NA) = struct
module P = NA
module AbstractVSet = Set.Make(struct type t=P.t let compare=P.compare end)
let g vset = vset
end
And this is my module for testing. In the very end, both UTYPE and GAME_PIECE are the same, but I can't make that clear to OCaml. I've commented the lines that don't typecheck. The compiler says there are clashes between MyGame.AbstractVSet.t and MyGraph.AbstractUSet.t.
module TestGame = struct
include(Game(struct type t=string let compare=compare end))
end
module TestGraph = struct
include(Graph(struct type t=string let compare=compare end))
end
module Test = struct
module MyGame = TestGame
module MyGraph = TestGraph
let stringlist = ["a";"b"]
let uset = MyGraph.uset_from_ulist stringlist // works fine
let vset = MyGame.vset_from_vlist stringlist // works fine
let result = MyGraph.f (MyGame.g) vset // does not typecheck!
end
If you ask, why I'm using so many modules: The project is a lot bigger than this code extract, and it is intended to be like this ;)
Can anyone help me how I can make it clear to the OCaml compiler that both UTYPE and GAME_PIECE are the same in the Test module??
Thanks a lot for your help!!!
The first issue is that your abstract set modules are different: the result of two functor applications in OCaml are only equals if the functor applications are applied to exactly the same named modules. For instance, in
module A = struct type t = int end
module F(X:sig type t end) = struct type t end
module FA = F(A)
module B = A
module FA' = F(B)
module C = F(struct type t end)
The types FA.t and Fa'.t are the same
let f (x:FA.t): FA'.t = x
But the types C.t and FA.t are different:
let f (x:C.t): FA'.t = x
Error: This expression has type C.t but an expression was expected of type
FA'.t
But this part can be fixed by not using anonymous structure when they are unnecessary:
module Graph (UA : UTYPE) : (GRAPH with module U=UA) = struct
module U=UA
module AbstractUSet = Set.Make(U)
let f g uset = g uset
end
Then, you are left with the "problem" that Game(M).AbstractUSet and
Graph(M).AbstractUSet defines two distinct types. (Note that this probably the right behavior outside of tests). For the test, one option is to simply expose the information that those modules are the result of functor applications. For instance, one can redefine the GAME module type (and GameInstance functor) to:
module type GAME = sig
type set
module P : GAME_PIECE
module AbstractVSet: Set.S with type t = set
val g : AbstractVSet.t -> AbstractVSet.t
end
module GameInstance (NA : GAME_PIECE) :
(GAME with type set:= Set.Make(NA).t and module P=NA) = struct
module P = NA
module AbstractVSet = Set.Make(NA)
let g vset = vset
end
Here, we have ketp the information that GameInstance(M).AbstractVSet.t is the
same type as Set.Make(M).t.
Combined wit the same operation on the graph part:
module type GRAPH = sig
type set
module U : UTYPE
module AbstractUSet : Set.S with type t = set
val f : (AbstractUSet.t -> AbstractUSet.t) -> AbstractUSet.t -> AbstractUSet.t
end
module Graph (UA : UTYPE) :
(GRAPH with type set := Set.Make(UA).t and module U=UA) = struct
module U=UA
module AbstractUSet = Set.Make(UA)
let f g uset = g uset
end
we are preserving enough type information to keep the equality for the test:
module TestGame = GameInstance(String)
module TestGraph = Graph(String)
module Test = struct
module MyGame = TestGame
module MyGraph = TestGraph
let result vset = MyGraph.f (MyGame.g) vset (* does typecheck *)
end

How to merge OCaml module types (signatures) defining the same type?

In OCaml, I have two module types defining a type t:
module type Asig = sig
type t
val a : t
end
module type Bsig = sig
type t
val b : t
end
I want to automate the creation of a module type merging them. I want to create a module type equivalent to:
module type ABsig_manual = sig
type t
val a : t
val b : t
end
I tried
module type ABsig = sig
include Asig
include Bsig
end
but this fails with Error: Multiple definition of the type name t. It seems impossible to add a type constraint to the include so I'm stuck.
Context: I have a module AB that does implement both signatures and I want to feed it to a functor like:
module MakeC(AB) = struct
type t = AB.t list
let c = [AB.a; AB.b]
end
module C = MakeC(AB)
I could use two arguments like in:
module UglyMakeC(A : Asig)(B : Bsig with type t = A.t) = struct
type t = A.t list
let c = [A.a; B.b]
end
module C = UglyMakeC(AB)(AB)
but this (is ugly and) doesn't scale well to more functors or more signatures to merge.
So, how can I automate merging those two module types? I can modify A and B as needed but I want to keep them separated. Also, maybe my approach is completely wrong, and in that case I'd love pointers to a better direction.
Type sharing in OCaml - typechecker error is related but merges modules, not module types.
Here is the way to do it :
module type Asig = sig
type t
val a : t
end
module type Bsig = sig
type t
val b : t
end
module type ABsig = sig
include Asig
include Bsig with type t := t
end
It's called "destructive substitution".

gfortran operator overloading derived type and real()

I want to overload an operator (*) to perform vector-scalar multiplication in the following class:
module vectorField_mod
use constants_mod
implicit none
private
public :: vectorField
public :: allocateVectorField
public :: delete
type vectorField
real(dpn),dimension(:,:,:),allocatable :: x,y,z
end type
interface operator (*)
module procedure scalarMultiply
end interface
contains
function scalarMultiply(f,g) result(q)
implicit none
type(vectorField),intent(in) :: f
real(dpn),intent(in) :: g
type(vectorField) :: q
q%x = f%x * g
q%y = f%y * g
q%z = f%z * g
q%sx = f%sx; q%sy = f%sy; q%sz = f%sz
end function
...
end module
But I'm getting the following error:
Error: Operands of binary numeric operator '*' at (1) are REAL(8)/TYPE(vectorfield)
I'm trying to implement this like:
type(vectorField) :: a
real(8) :: dt = 0.001
call allocateVectorField(a,..)
a = a*dt
Is this not a binary operation? Is there still a way to do this? Any help is greatly appreciated!
Summary:
1) The answer by #francescalus was necessary, but not sufficient to yield a successful compilation.
2) In addition, it turns out that the order of multiplication is important. That is a = adt works, but a = dta does not work (this was the problem I was having)
Here's an illustrative sample:
module constants_mod
integer,parameter :: dpn = selected_real_kind(14)
end module
module vectorField_mod
use constants_mod
implicit none
private
public :: vectorField
public :: allocateX,allocateY,allocateZ
public :: delete
public :: operator(*)
type vectorField
integer,dimension(3) :: sx,sy,sz
real(dpn),dimension(:,:,:),allocatable :: x,y,z
end type
interface delete
module procedure deallocateVectorField
end interface
interface operator (*)
module procedure scalarMultiply
end interface
contains
function scalarMultiply(f,g) result(q)
implicit none
type(vectorField),intent(in) :: f
real(dpn),intent(in) :: g
type(vectorField) :: q
q%x = f%x * g; q%y = f%y * g; q%z = f%z * g
q%sx = f%sx; q%sy = f%sy; q%sz = f%sz
end function
subroutine allocateX(field,Nx,Ny,Nz)
implicit none
type(vectorField),intent(inout) :: field
integer,intent(in) :: Nx,Ny,Nz
if (allocated(field%x)) deallocate(field%x)
allocate(field%x(Nx,Ny,Nz))
field%sx = shape(field%x)
end subroutine
subroutine allocateY(field,Nx,Ny,Nz)
implicit none
type(vectorField),intent(inout) :: field
integer,intent(in) :: Nx,Ny,Nz
if (allocated(field%y)) deallocate(field%y)
allocate(field%y(Nx,Ny,Nz))
field%sy = shape(field%y)
end subroutine
subroutine allocateZ(field,Nx,Ny,Nz)
implicit none
type(vectorField),intent(inout) :: field
integer,intent(in) :: Nx,Ny,Nz
if (allocated(field%z)) deallocate(field%z)
allocate(field%z(Nx,Ny,Nz))
field%sz = shape(field%z)
end subroutine
subroutine deallocateVectorField(field)
implicit none
type(vectorField),intent(inout) :: field
deallocate(field%x,field%y,field%z)
field%sx = 0; field%sy = 0; field%sz = 0
end subroutine
end module
program test
use constants_mod
use vectorField_mod
implicit none
type(vectorField) :: a,b
integer :: N = 1
real(dpn) :: dt = 0.1
call allocateX(a,N,N,N)
call allocateY(a,N,N,N)
call allocateZ(a,N,N,N)
call allocateX(b,N,N,N)
call allocateY(b,N,N,N)
call allocateZ(b,N,N,N)
a%x = dble(1.0); a%y = dble(1.0); a%z = dble(1.0)
b%x = dble(1.0); b%y = dble(1.0); b%z = dble(1.0)
a = b
a = a*dt ! compiles fine
a = dt*a ! does not compile
call delete(a)
call delete(b)
end program
The default accessibility of the module is private. This default applies also to the defined operator.
To make the operator identifier public (so that it can be used outside the module) use a public statement like:
public :: operator(*)