Problems with absoft fortran in mac - macos

I used to work with Intel Visual Fortran and my code runs smoothly there. However I bought Absoft Fotran Compiler and I am getting many errors...
This is a sample program where I get errors
FUNCTION norm_inv(x)
USE nrtype
USE tauchen
IMPLICIT NONE
REAL(DP), INTENT(IN) :: x
REAL(DP) :: norm_inv,zbrent,x1,x2,tol
tol=1.0E-6
x1=-10.0
x2=10.0
norm_inv=zbrent(fni,x1,x2,tol)
CONTAINS
FUNCTION fni(x0)
USE nrtype
IMPLICIT NONE
REAL(DP), INTENT(IN) :: x0
REAL(DP) :: fni,norm_cdf
fni=norm_cdf(x0)-x
END FUNCTION fni
END FUNCTION norm_inv
And the Absoft compiler tells me
Message Number: 379
A procedure name is used as an actual argument to a function or
subroutine call, but the procedure name has not been given the
EXTERNAL attribute, is not a module procedure, or is not specified in
an interface block. NOTE: Giving the EXTERNAL attribute to the name
of the SUBROUTINE being compiled is an extension to the standard.
When I declare it external it tells me
Message Number: 552 The compiler detected a conflict in declarations
for this object. Because the object has the given attribute, it must
not be declared to be the new item.

fni is an internal procedure of the function norm_inv (where the call to zbrent is made). Passing an internal procedure as an actual argument is a feature new to Fortran 2008. Crucially, this is a feature implemented in the Intel compiler, but not the Absoft.
To make the code more "portable" working around things to make fni not internal would work. Merely adding the external attribute to fni would not be sufficient, and would indeed be incorrect.

Related

which Fortran standard of these codes?

I am confused that the syntax in the subroutine of fortran code as following:
subroutine X(lr_orth_response)(mesh, st, lr, omega)
type(mesh_t), intent(in) :: mesh
type(states_t), intent(in) :: st
type(lr_t), intent(inout) :: lr
R_TYPE, intent(in) :: omega
integer :: ist, ik
PUSH_SUB(X(lr_orth_response))
do ik = st%d%kpt%start, st%d%kpt%end
do ist = 1, st%nst
call X(lr_orth_vector) (mesh, st, lr%X(dl_psi)(:,:, ist, ik), ist, ik, omega)
end do
end do
POP_SUB(X(lr_orth_response))
end subroutine X(lr_orth_response)
I've checked all Fortran standards and I cannot find any useful info about it! Does anyone know what's the label lr_orth_response? Also, accessing to data by the pointer is also confused a little bit in this line lr%X(dl_psi)(:,:, ist, ik), ist, ik, omega), in which lr is a new type lr_t defined by user but there is no member functions or variables named X(dl_psi).
This is not pure Fortran. It looks like a source that must be preprocessed by some preprocessor, perhaps the C preprocessor cpp or its variant fpp. The preprocessor will expand R_TYPE, PUSH_SUB, POP_SUB and X using some macro. Some of the macros apparently depend on some parameter called lr_orth_response. We cannot say what that parameter does in those macros without actually seeing the definition but we would need much more code from you. It is probably used for some generic programming, but hard to guess how exactly.

How do I declare the precision of a number to be an adjustable parameter?

In 2013 there was a question on converting a big working code from double to quadruple precision: "Converting a working code from double-precision to quadruple-precision: How to read quadruple-precision numbers in FORTRAN from an input file", and the consensus was to declare variables using an adjustable parameter "WP" that specifies the "working precision", instead of having a separate version of the program with variables declared using D+01, and another version using Q+01. This way we can easily switch back and forth by defining WP=real128 or WP=real64 at the top, and the rest doesn't need to change.
But how do we do this?
I tried the suggestion in the answer to that question, by making a simple code TEST.F90:
PROGRAM TEST
use ISO_FORTRAN_ENV
WP= real128
IMPLICIT NONE
real (WP) :: X
X= 5.4857990945E-4_WP
END PROGRAM TEST
compiled with:
~/gcc-4.6/bin/gfortran -o tst.x TEST.F90
But it gives:
IMPLICIT NONE
1
Error: Unexpected IMPLICIT NONE statement at (1)
QLEVEL16.F90:5.12:
real (WP) :: MEL
1
Error: Parameter 'wp' at (1) has not been declared or is a variable, which does not reduce to a constant expression
QLEVEL16.F90:6.29:
MEL= 5.4857990945E-4_WP
1
Error: Missing kind-parameter at (1)
The kind specifier must be an integer parameter - and you do not declare it appropriately. Furthermore, implicit none must go before any declaration.
Here is a working version addressing both issues:
PROGRAM TEST
use ISO_FORTRAN_ENV
IMPLICIT NONE
integer, parameter :: WP= real128
real (WP) :: X
X= 5.4857990945E-4_WP
END PROGRAM TEST
Actually many code using this WP approach. Many with select_*_kind intrinsic function. But I think there is a 'easier' way. It's to use default precision without specifying any kind keyword andusing compiler's flag to choose what the default precision is.
Pro is this method is easier if you don't need a precise control of precision on each variable. Con is that will heavily depend on compiler flags, which varies for each compiler or even might not available.
For gfortran, there is more flags -freal4-real8 or -freal4-real16 to promote each explicitly specified lower precision variable to higher precision.

Fortran - explicit interface

I'm very new to Fortran, and for my research I need to get a monster of a model running, so I am learning as I am going along. So I'm sorry if I ask a "stupid" question.
I'm trying to compile (Mac OSX, from the command line) and I've already managed to solve a few things, but now I've come across something I am not sure how to fix. I think I get the idea behind the error, but again, not sure how to fix.
The model is huge, so I will only post the code sections that I think are relevant (though I could be wrong). I have a file with several subroutines, that starts with:
!==========================================================================================!
! This subroutine simply updates the budget variables. !
!------------------------------------------------------------------------------------------!
subroutine update_budget(csite,lsl,ipaa,ipaz)
use ed_state_vars, only : sitetype ! ! structure
implicit none
!----- Arguments -----------------------------------------------------------------------!
type(sitetype) , target :: csite
integer , intent(in) :: lsl
integer , intent(in) :: ipaa
integer , intent(in) :: ipaz
!----- Local variables. ----------------------------------------------------------------!
integer :: ipa
!----- External functions. -------------------------------------------------------------!
real , external :: compute_water_storage
real , external :: compute_energy_storage
real , external :: compute_co2_storage
!---------------------------------------------------------------------------------------!
do ipa=ipaa,ipaz
!------------------------------------------------------------------------------------!
! Computing the storage terms for CO2, energy, and water budgets. !
!------------------------------------------------------------------------------------!
csite%co2budget_initialstorage(ipa) = compute_co2_storage(csite,ipa)
csite%wbudget_initialstorage(ipa) = compute_water_storage(csite,lsl,ipa)
csite%ebudget_initialstorage(ipa) = compute_energy_storage(csite,lsl,ipa)
end do
return
end subroutine update_budget
!==========================================================================================!
!==========================================================================================!
I get error messages along the lines of
budget_utils.f90:20.54:
real , external :: compute_co2_storage
1
Error: Dummy argument 'csite' of procedure 'compute_co2_storage' at (1) has an attribute that requires an explicit interface for this procedure
(I get a bunch of them, but they are essentially all the same). Now, looking at ed_state_vars.f90 (which is "used" in the subroutine), I find
!============================================================================!
!============================================================================!
!---------------------------------------------------------------------------!
! Site type:
! The following are the patch level arrays that populate the current site.
!---------------------------------------------------------------------------!
type sitetype
integer :: npatches
! The global index of the first cohort in all patches
integer,pointer,dimension(:) :: paco_id
! The number of cohorts in each patch
integer,pointer,dimension(:) :: paco_n
! Global index of the first patch in this vector, across all patches
! on the grid
integer :: paglob_id
! The patches containing the cohort arrays
type(patchtype),pointer,dimension(:) :: patch
Etc etc - this goes one for another 500 lines or so.
So to get to the point, it seems like the original subroutine needs an explicit interface for its procedures in order to be able to use the (dummy) argument csite. Again, I am SO NEW to Fortran, but I am really trying to understand how it "thinks". I have been searching what it means to have an explicit interface, when (and how!) to use it etc. But I can't figure out how it applies in my case. Should I maybe use a different compiler (Intel?). Any hints?
Edit: So csite is declared a target in all procedures and from the declaration type(site type) contains a whole bunch of pointers, as specified in sitetype. But sitetype is being properly used from another module (ed_state_vars.f90) in all procedures. So I am still confused why it gives me the explicit interface error?
"explicit interface" means that the interface to the procedure (subroutine or function) is declared to the compiler. This allows the compiler to check consistency of arguments between calls to the procedure and the actual procedure. This can find a lot of programmer mistakes. You can do this writing out the interface with an interface statement but there is a far easier method: place the procedure into a module and use that module from any other entity that calls it -- from the main program or any procedure that is itself not in the module. But you don't use a procedure from another procedure in the same module -- they are automatically known to each other.
Placing a procedure into a module automatically makes its interface known to the compiler and available for cross-checking when it is useed. This is easier and less prone to mistakes than writing an interface. With an interface, you have to duplicate the procedure argument list. Then if you revise the procedure, you also have to revise the calls (of course!) but also the interface.
An explicit interface (interface statement or module) is required when you use "advanced" arguments. Otherwise the compiler doesn't know to generate the correct call
If you have a procedure that is useed, you shouldn't describe it with external. There are very few uses of external in modern Fortran -- so, remove the external attributes, put all of your procedures into a module, and use them.
I ran into the same problems you encountered whilst I was trying to install ED2 on my mac 10.9. I fixed it by including all the subroutines in that file in a module, that is:
module mymodule
contains
subroutine update_budget(csite,lsl,ipaa,ipaz)
other subroutines ecc.
end module mymodule
The same thing had to be done to some 10 to 15 other files in the package.
I have compiled all the files and produced the corresponding object files but now I am getting errors about undefined symbols. However I suspect these are independent of the modifications so if someone has the patience this might be a way to solve at least the interface problem.

Why does the following Fortran code allocate on the stack/heap depending on the contents of a derived type?

I do not understand why the following program segfaults with a SIGSEGV if the bar field is present in containerType, and works without problems if it is commented out. I'm on x86_64, compiling with both gfortran-4.4.6 and gfortran-4.6.3.
As I understand it, using a pointer to containerType should force the allocation of the contained big array to happen on the heap but that doesn't seem to be the case. Running valgrind on the executable gives me
Warning: client switching stacks? SP change: 0x7ff000448 --> 0x7fe0603f8
to suppress, use: --max-stackframe=16384080 or greater
(The rest of the output is IMHO not relevant, but I could edit it in if required). This indicates to me that there's a stack overflow; presumably due to allocating the 8*8*8*4000 * 8(bytes per real) = 16384000 bytes on the stack.
When I comment out the bar field, valgrind is perfectly happy. To make matters even stranger, compiling under gfortran-4.6.3 with '-O' also makes the problem go away (but not under gfortran-4.4.6).
Either I've stumbled on a compiler bug, or (more likely, as I'm pretty new to Fortran) I don't understand where data is allocated. Could someone enlighten me what's going on?
The code in question:
main.f90:
program main
use problematicArray
implicit none
type (containerType),pointer :: container
allocate(container)
container%foo%arrayData = 17.0
write(*,*) container%foo%arrayData(7,7,7,100)
deallocate(container)
write(*,*) 'Program finished'
end program main
problematicArray.f90:
module problematicArray
implicit none
private
integer, parameter, public :: dim1 = 4000
type, public :: typeWith4DArray
real(8), dimension(8,8,8,dim1) :: arrayData
end type typeWith4DArray
type :: typeWithChars
character(4), dimension(:), allocatable :: charData
end type typeWithChars
type, public :: containerType
type(typeWith4DArray) :: foo
type(typeWithChars) :: bar
end type containerType
end module problematicArray
This must be a bug in gfortran. I do not see anything wrong there. It also works in Intel and Oracle compilers. Best to report it to gfortran developers. I tried it with only a 2 days old build of the gfortran 4.8 trunk.
The error has nothing to do with stack/heap difference. It simply crashes during the allocate statement. It does not even work with stat= and errmsg= set.
Just a note, you can have the module and the main program inside a single source file.

Intel MKL Pardiso solver compiling with Visual Studio

I am trying to do create a simple example in order to use the Pardiso solver inside MKL Intel library. I have been following the examples provided but if I place the call to Pardiso in a subroutine it does not work. I am afraid that is something related to the INCLUDE statement or the linking aspect.
Arrays used by all subroutines are contained in a module called variables
MODULE variables
INTEGER :: M ! Lines
INTEGER :: N ! Columns
REAL*8, DIMENSION(:,:), ALLOCATABLE :: MATRA ! original matrix
INTEGER, DIMENSION(:), ALLOCATABLE :: ROWSA,COLSA ! ia and ja in pardiso
REAL*8, dimension(:), ALLOCATABLE :: VALSA, RHSVC, SOLVC ! a, b, x
END MODULE variables
The file containing the program is as follows:
INCLUDE 'mkl_pardiso.f90'
program PardisoFortran
use variables
use mkl_pardiso
implicit none
! do some stuff to create the matrices
call create_matrices
call INITPARDISO
end program
Finally the file initpardiso
subroutine INITPARDISO
USE VARIABLES
USE mkl_pardiso
! pardiso variable declaration
TYPE(MKL_PARDISO_HANDLE), ALLOCATABLE :: pt(:)
INTEGER maxfct, mnum, mtype, phase, nrhs, error, msglvl
INTEGER, ALLOCATABLE, DIMENSION(:) :: iparm
INTEGER i, idum
REAL*8 waltime1, waltime2, ddum
! --- then I allocate and fill the variables
! Finally I can call pardiso
phase = 11 ! only reordering and symbolic factorization phase
CALL pardiso_64 (PT, maxfct, mnum, mtype, phase, M, VALSA, COLSA, &
ROWSA, idum, nrhs, iparm, msglvl, ddum, ddum, error)
end subroutine
Now, I added also the Additional Include Directories to Visual Studio project configuration (that is
C:\Program Files (x86)\Intel\ComposerXE-2011\mkl\include;
C:\Program Files (x86)\Intel\ComposerXE-2011\mkl\lib\intel64;
C:\Program Files (x86)\Intel\ComposerXE-2011\mkl\lib\ia32)
If I comment the call to pardiso everything works perfectly, otherwise it stops compilation with this error:
Error 1 error #6285: There is no matching specific subroutine for this generic subroutine call. [PARDISO_64] ....PardisoFortran\initpardiso.f 144
Any idea for that? Is that a problem of the INCLUDE statement on top? where should I include it?
I believe that pardiso_64 is a subroutine version which uses 64-bit integers. Your code snippets show no evidence that you have taken measures to ensure that your integers are 64-bit. I suppose you may have used compiler options or other means to tell the compiler to default to 64-bit integers.
The error message you post is typical of the error messages you get when there is a mis-match between dummy and actual arguments when calling a library generic procedure. Suppose that your integers are only 32-bit, then the compiler is looking for, and failing to find, a routine named pardiso_64 which takes 32-bit integer arguments.
I don't think that the error has anything to do with the include statement.
I see one problem in your code. The parameter 'ddum' was a scalar. It should be an array of dimension (M, nrhs). There could be more problems. I need to see the entire code to help.
As usual, the best place to ask Intel MKL related questions is the MKL forum: http://software.intel.com/en-us/forums/intel-math-kernel-library. Post your question there, with your entire program attached. You will get an answer much quicker!

Resources