how to compiler union/map using gfortran - fortran

I am trying to port code compiled with ifort to gfortran. When I update gfortran to version 6 and compile the code with UNION/MAP, there is an error:
Unexpected UNION statement at (1).
How can I fix this?
union
map
integer*4 :: ndim_par=0
integer*4 :: ndim_par_actual=0
end map
map
integer*4 :: mamb
integer*4 :: mobs
end map
end union

Related

PGI compilation problem in Fortran: deferred procedure creates segmentation fault

I am testing the PGI Fortran 19.10 compiler.
And I get a segmentation fault after compilation with PGI when I run the file named test.f90 ; while when I compile and run with gfortran or ifort I get no problem.
the filetest.f90:
MODULE modu
IMPLICIT NONE
! Format
type, abstract :: FormatFile
contains
procedure(File_open_file),nopass, deferred :: open_files
end type FormatFile
type, extends(FormatFile) :: FormatA
contains
procedure, nopass :: open_files => open_fileA
end type FormatA
! Type
type, abstract :: TypeFile
class(FormatFile), allocatable :: format
end type TypeFile
type, extends(TypeFile) :: TypeB
end type TypeB
! FileHandler
type, public :: FileHandler
private
class(TypeFile), allocatable :: type
contains
procedure, pass(fd), public :: open_file
end type FileHandler
abstract interface
subroutine File_open_file( fd )
import FileHandler
class(FileHandler), intent(inout) :: fd
end subroutine
end interface
CONTAINS
subroutine write_output()
IMPLICIT NONE
type(FileHandler) :: FileH
!-------------------------------------------------------------------------
print*, 'write_output: start.'
allocate(TypeB :: FileH%type)
allocate( FormatA :: FileH%type%format)
call FileH%open_file()
print*, 'write_output: end.'
end subroutine write_output
subroutine open_file( fd )
implicit none
class(FileHandler), intent(inout) :: fd
!-------------------------------------------------------------------------
print *, 'open_file: start'
call fd%type%format%open_files(fd)
print *, 'open_file: end'
end subroutine open_file
subroutine open_fileA( fd )
implicit none
class(FileHandler), intent(inout) :: fd
!-------------------------------------------------------------------------
print *, 'open_fileA: start'
!print*, 'job done'
print *, 'open_fileA: end'
end subroutine open_fileA
end module modu
PROGRAM main_prog
USE modu
print*, "Start main"
call write_output()
print*, "End main"
END PROGRAM main_prog
Therefore the command pgfortran -c test.f90 && pgfortran -o main_test test.o && ./main_test returns me:
Start main
write_output: start.
open_file: start
Segmentation fault (core dumped)
While it run as expected with gfortran or ifort. Otherwise I also tested this code with the option -Mnollvm of the PGI compiler, and it yields the same segmentation fault.
Of course in this simple example I could remove the intermediate object TypeFile, which remove the segmentation fault problem ; but I really need it in some bigger project.
So am I missing something ? or is it a bug of the PGI compiler ?

PGI compiler creates an error with a fortran type-bound procedures

I am working on a Fortran code. And I have to deal with many different type of output file. So to manage all of them, I use type objects.
Until now, I have compiled my code with gfortran on linux and windows (and ifort on linux) ; and it works as expected.
Because, I want in a close future to integrate GPU parallel computing to my code with OpenACC, I have to be able to compile it with pgfortran (the PGI compiler for Fortran).
Here arrives my problem, the compilation (with pgfortran 18-4-0 on windows) returns me no warning, but at the execute the code crashes with a strange error: [Exit 3221225477] test.exe.
Therefore, I tried to isolate the problem, in order to solve it. I finally get the following MWE:
MODULE VTK_IO
implicit none
type, abstract :: FormatVTK
contains
procedure(VTK_open_file),nopass, deferred :: open_file_VTK
procedure(VTK_close_file),nopass, deferred :: close_file_VTK
end type FormatVTK
type, extends(FormatVTK) :: FormatAscii
contains
procedure, nopass :: open_file_VTK => open_file_ascii
procedure, nopass :: close_file_VTK => close_file_ascii
end type FormatAscii
type, public :: VTKfileHandler
integer :: unit
class(FormatVTK), allocatable :: type
end type VTKfileHandler
abstract interface
subroutine VTK_open_file( fd )
import VTKfileHandler
class(VTKfileHandler), intent(inout) :: fd
end subroutine
subroutine VTK_close_file(fd)
import VTKfileHandler
class(VTKfileHandler), intent(in) :: fd
end subroutine
end interface
contains
subroutine open_file_ascii( fd )
implicit none
class(VTKfileHandler), intent(inout) :: fd
character(len=80) :: f
!-------------------------------------------------------------------------
write(unit=*, fmt=*) 'open_file_ascii: start'
! stop 6969
f='test_file.txt'
open(newunit = fd%unit, &
file = trim(adjustl(f)), &
form = 'FORMATTED', & ! FORMATTED
access = 'STREAM', & ! SEQUENTIAL
action = 'WRITE', &
status = 'REPLACE')
write(unit=fd%unit,fmt='(100A)') "# vtk DataFile Version "
write(unit=*, fmt=*) 'open_file_ascii: end'
end subroutine open_file_ascii
subroutine close_file_ascii(fd)
implicit none
class(VTKfileHandler), intent(in) :: fd
!-------------------------------------------------------------------------
close(unit=fd%unit)
write(unit=*, fmt=*) 'close_file_ascii: done'
end subroutine close_file_ascii
end module vtk_IO
PROGRAM Test_open
USE VTK_IO
IMPLICIT NONE
type :: OutputFile
class (VTKfileHandler), allocatable :: VTKfile
end type OutputFile
type (OutputFile) :: OutsFiles
!----------------------------------------------------------------------------
print*, 'START: Test_open'
Print*,'initialise_outputs: start'
allocate(VTKfileHandler :: OutsFiles%VTKfile )
allocate(FormatAscii :: OutsFiles%VTKfile%type)
Print*,'initialise_outputs: end'
call OutsFiles%VTKfile%type%open_file_VTK(OutsFiles%VTKfile)
call OutsFiles%VTKfile%type%close_file_VTK(OutsFiles%VTKfile)
print*, 'END: Test_open'
END PROGRAM Test_open
It seems like the type-bound procedure open_file_VTK is not targetting the procedure open_file_ascii. I think that the compiler get lost with the type-bounded procedure. For example, if I remove the OutsFiles and use directly a VTKfile in the main, it works. But, of course, I need this embedding type OutputFile, in my big code ; otherwise it would be too easy.
So is it a bug from the compiler ? Or can I do something to solve this problem ?

f2py error wrong elsize

OS Ubuntu 14.04 on 64-bit notebook
I compile a function written in the Fortran code using f2py
then I call this function from Python.
And I get error message:
ValueError: failed to initialize intent(inout) array -- expected elsize=4 but got 8
It looks like my Fortran code is being compiled as a 32-bit in spite of 64-bit machine.
On 32-bit computer everything works fine.
What do I do wrong?
It looks like I have found solution.
First, reported error raises only when integer arrays are being passed to Fortran subroutine. Integer values and real arrays (I suppose, values too) pass correctly, when I use default Python int and float, while in Fortran I declare them as INTEGER*4 and REAL*8.
But in the case of integer arrays this did not work. Minor corrections needed, namely, integer arrays in Python should be declared as (or converted to) np.int32 type and declared as INTEGER*4 in Fortran subroutine.
Here are samples of array declaration/conversion that worked in my project.
Python:
import numpy as np
import Fortran_file
#.... some code
# variable "data" is integer 2-D array
data = data.astype(np.int32) # data.astype(int) gives error
data = np.asfortranarray(data)
array1 = np.zeros(5, dtype=np.int32, order='F') # dtype=int gives error
array2 = np.zeros(5, dtype=float, order='F')
ivalue = 2 # conversion to np.int32 is not needed
Fortran_file.Fortran_subroutine(data, ivalue, array1, array2)
Fortran:
SUBROUTINE Fortran_subroutine (matrix, value, array1, array2)
IMPLICIT NONE
INTEGER*4 :: matrix(:,:)
!f2py INTENT(INOUT) :: matrix(:,:)
INTEGER*4 :: value
!f2py INTENT(INOUT) :: value
INTEGER*4 :: array1(5)
!f2py INTENT(INOUT):: array1(5)
REAL*8 :: array2(5)
!f2py INTENT(INOUT) :: array2(5)
Again, this had sense on 64-bit OS. When I used 32-bit OS, everything worked without these tricks.
I have not experimented with other data types.

invalid character at name 1

Trying to learn Fortran for a project. In a very simple program I am getting invalid character error.
program foo
implicit none
integer :: n_samp
integer :: samp_len
integer :: x_len
integer :: y_len
n_samp=2
samp_len=2
y_len=11
x_len=2
real(8),dimension(n_samp,samp_len,y_len,x_len)=Yvec
end program foo
error generated by GFORTRAN
t.f90:11.12:
real(8), dimension(n_samp,samp_len,y_len,x_len)=Yvec
1
Error: Invalid character in name at (1)
What is the cause of this error?
The correct syntax is
real(8), dimension(n_samp,samp_len,y_len,x_len) :: Yvec
The :: is obligatory when specifying any attributes (as the dimension in your case).
As #AlexanderVoigt points out, all variable declaration must be placed in the declaration part of the code, i.e., at the beginning.
I do not recommend using real(8) because that is not well defined, the 8 can mean anything, it is an index to a table of kinds and different compilers can have something different at place 8 in that table. See Fortran 90 kind parameter
That's simple: You are not allowed to have declarations in the main body (that is after some instructions)! Instead, you should use parameters:
program foo
implicit none
integer,parameter :: n_samp=2
integer,parameter :: samp_len=2
integer,parameter :: x_len=11
integer,parameter :: y_len=2
real(8),dimension(n_samp,samp_len,y_len,x_len) :: Yvec ! Add. typo here
end program foo

fortran "array of arrays" and "pack" issues

I seem to have hit a wall while coding these past few days. from what i can gather, it is possible to make arrays of arrays in fortran ala Fortran array of variable size arrays
type par
.... !data
integer :: location
end type par
type locations
....! data
type (par), allocatable, dimension(:) :: pars
end type locations
type (par), allocatable, dimension(:) :: all_pars
type (locations), allocatable, dimension(:) :: all_loc
.... !read numpars, numlocs from file etc
allocate(all_pars(numpars))
allocate(all_locs(numlocs))
!initialize all_pars
do n = 1:numpars
....
all_pars(n)%location = some_location
enddo
!get particles in each location
do n = 1:numlocs
allocate(all_locs(n)%pars(count(all_pars(:)%location .ne. n)))
all_locs(n)%pars = pack(all_pars, (all_pars(:)%location .ne. n)) !ERROR: An assignment of different structure types is invalid.
enddo
the compiler does not complain with my equivalent lines of code for the stack overflow example above, but it indeed does have an issue when i attempt to use that array to store the result of a pack function call. i suspect that it may be the case that the allocate function is not behaving as expected, but since the code does not compile, i cannot debug it....
the squirrely idea for pack usage comes from http://flibs.sourceforge.net/fortran_aspects.html , about halfway down the page.
I am running on a linux system, with ifort 12.1.3.293
any help is much appreciated
This may be an extended comment rather than an answer ...
to get it to compile I modified your posted code to;
program main
implicit none
integer :: numpars, numlocs, n
type par
!data
integer :: location
end type par
type locations
! data
type (par), allocatable, dimension(:) :: pars
end type locations
type (par), allocatable, dimension(:) :: all_pars
type (locations), allocatable, dimension(:) :: all_locs
!read numpars, numlocs from file etc
numpars = 10
numlocs = 4
allocate(all_pars(numpars))
allocate(all_locs(numlocs))
!initialize all_pars
all_pars(1:numpars:4)%location = 1
all_pars(2:numpars:4)%location = 2
all_pars(3:numpars:4)%location = 3
all_pars(4:numpars:4)%location = 4
!get particles in each location
do n = 1,numlocs
! allocate(all_locs(n)%pars(count(all_pars(:)%location .ne. n)))
all_locs(n)%pars = pack(all_pars, (all_pars(:)%location .ne. n))
enddo
end program
and it compiles without a hitch on my Mac with Intel Fortran 13.something. Of course, since you've only posted a syntactically-slightly-incorrect part of your code I can't be sure that this tells you very much.
Since you don't show that your code uses implicit none your error might be down to the difference between all_loc and all_locs or some other similar issue.
Note, in passing, that with Fortran allocatable arrays you don't need to allocate all_locs(n)%pars prior to setting its value with the call to pack, the compiler will take care of that for you. This, though, is not the source of your error.