This question already has an answer here:
The mysterious nature of Fortran 90 modules
(1 answer)
Closed 2 years ago.
I have written the following Fortran Code in the System called "Simply Fortran":
program math2
use prec, only: print_kind_info
implicit none
call print_kind_info
end program math2
module prec
implicit none
integer, parameter :: dp = selected_real_kind(P=10,R=30)
integer, parameter :: sp = selected_real_kind(P=5,R=15)
integer, parameter :: dp_alt = kind(0.d0)
public :: dp, sp, print_kind_info
private
contains
! Subroutine comes here
subroutine print_kind_info()
real(sp) :: sing_prec
real(dp) :: double_prec
print*,'Single precision is kind ',sp
print*,'Double precision is kind ',dp
print*,'Kind of double precision number is ',dp_alt
end subroutine print_kind_info
end module prec
However, the module which I call 'prec' is not found. More precisely, the error message is the following:
use prec, only: print_kind_info
1
Fatal Error: Can't open module file 'prec.mod' for reading at (1): No such file or directory
compilation terminated.
Error(E42): Last command making (build\prec.o) returned a bad status
Error(E02): Make execution terminated
* Failed *
What I have to do that the module (see above code) is recognized properly? It is recognized in File Outline, but it is not inside the "module" folder. And I really don't have a plan here what to do. Moreover I have no experience with the Makefile environment (this BASHrc-like things I am not familar with).
Simply said: The problem is that the compiler doesn't know the module prec.mod at is defined after the main program but is used already in the main program.
So first define the module and after that the main program.
Better would be to place the module in a separate files and the main program in another file and compile these (in the right order) and link everything together.
Related
I am working with GFortran and CodeBlocks but I'm having an issue about Modules and Multiple files.
i keep getting this error:
Fatal Error: Can't open module file 'mesh.mod' for reading at (1): No such file or directory
For some reason, GFortran is not building the 'mesh.mod' file.
This problem does not occur when I put all the code in a single .f90 file.
Bellow is an example of code that this error happens.
main.f90
MODULE MESH
IMPLICIT NONE
INTEGER :: IMAX,JMAX,NMAX
REAL(8), ALLOCATABLE :: XD(:),YD(:),FX(:,:),FY(:,:)
REAL(8) :: PI,E,DX,DY,H,L,RHO,MU
PARAMETER (PI = ACOS(-1.D0))
PARAMETER (E = 2.718)
END MODULE MESH
!**************************************************************
program Cavity
Use Mesh
implicit none
Real(8), Allocatable :: func(:)
Real(8) :: Der,DfDx
integer :: i
IMAX=10
DX=1./10
Allocate(xd(IMAX),func(IMAX))
Do i=1,IMAX
xd(i)=i*DX
End Do
Do i=1,IMAX
func(i) = xd(i)**2
End Do
Der=Dfdx(func,2)
Write(*,*) Der
End program Cavity
Derivatives.f90
Real(8) Function DfDx(f,i)
Use Mesh
implicit none
Real(8) :: f(1:Imax)
integer :: i
DfDx=(f(i+1)-f(i-1))/(2d0*dx)
return
end function DfDx
When I use console command line compilation instead of CodeBlocks interface I already solved this problem (Compiling Multiple Files with modules) but I'm still getting this problem with CodeBlocks.
Does anyone know how to solve this issue?
Assuming what you have written is how your code is, then it appears that the problem is that the module mesh is inside the main program and not a separate file. You should have three files: Mesh.f90, Derivatives.f90 and Main.f90.
Mesh.f90 is exactly as you have it,
module Mesh
implicit none
integer :: IMAX,JMAX,NMAX
real(8), allocatable :: XD(:),YD(:),FX(:,:),FY(:,:)
real(8) :: PI,E,DX,DY,H,L,RHO,MU
parameter (PI = ACOS(-1.D0))
parameter (E = 2.718)
end module Mesh
Derivatives.f90 should be written as another module, using contains:
module Derivatives
use mesh
contains
real(8) function dfdx(f,i)
real(8) :: f(i:imax)
integer :: i
DfDx=(f(i+1)-f(i-1))/(2d0*dx)
end function dfdx
end module Derivatives
and the Main.f90 will then use both modules. Note that I had to eliminate the variable DfDx; this is because it conflicts with the function DfDx in module Derivatives
program Cavity
Use Mesh
use Derivatives
implicit none
Real(8), Allocatable :: func(:)
Real(8) :: Der
integer :: i
IMAX=10
DX=1./10
Allocate(xd(IMAX),func(IMAX))
Do i=1,IMAX
xd(i)=i*DX
End Do
Do i=1,IMAX
func(i) = xd(i)**2
End Do
Der=Dfdx(func,2)
Write(*,*) Der
End program Cavity
I do not know how CodeBlocks works, but I would presume it lets you choose the compilation order. If that is the case, you should compile Mesh.f90 first, then Derivatives.f90, then compile Main.f90 before linking them to an executable.
When I compiled & linked them, I got an answer of 0.200000002980232; hopefully that links up to what you have as well.
On codeblock, you may go to Project properties > Build targets
Then select the file you want to build first (say mod.f90).
In the "Selected file properties" go to "Build"
Here,change the priority weight. Lower weight implies the file will be built first.
The problem is that in CodeBlocks "projects are built in the order of appearence, from top to bottom" (CodeBlocks Wiki), in other words, the files are compiled alphabetically.
Which means that in my case, Derivatives.f90 was being compiled before than Main.f90 causing the error.
A way to circumvent the problem is to set only the Main.f90 file as build target in CodeBlocks:
Menu Project/Properties...
In Build Target Files at the tab Build targets check only Main.f90
And use the command Include 'File_Name.f90' inside the Main.f90 code to include the other f90 files for compilation in the right order.
I have been trying to compile an O-O fortran code with the fortran compiler of the Oracle Solaris Studio 12.4 suite (the latest as far as I know). But the compiler crashes. Here is a simplified version of my problem.
I define two simple types with one type-bound procedure each. One of the procedures has a variable of the other type as dummy argument:
MODULE MY_MODULE
type type0
real :: value = 0
contains
procedure :: print_value
end type type0
type type1
real :: value = 0
contains
procedure :: print_diff
end type type1
CONTAINS
subroutine print_value(self)
class(type0), intent(in) :: self
print*, self%value
end subroutine print_value
subroutine print_diff(self,var0)
class(type1), intent(in) :: self
type(type0), intent(in) :: var0
print*,self%value - var0%value
end subroutine print_diff
END MODULE MY_MODULE
PROGRAM MY_PROG
use my_module, only: type0,type1
type(type0) :: var0
type(type1) :: var1
var0%value = 3
var1%value = 10
call var1%print_diff(var0)
END PROGRAM MY_PROG
This program compiles and executes fine with gfortran:
[> gfortran myprog.f03 -o myprog.x
[> ./myprog.x
7.0
However, compilation with the Solaris f95 crashes:
[> f95 myprog.f03 -o myprog.x
f90: Internal Error, code=fw-interface-ctyp1-796, last src=myprog.f03:4
If I do any further simplification to the source code, then f95 compiles successfully. For instance, it works fine if:
type0 has no type-bound procedure
type1 has no type-bound procedure
procedure print_diff is replaced by a subroutine with no other argument than self
Is there anything I am doing wrong?
Is there an installation problem with my Solaris compiler? Is someone able to compile this code successfully with an other Solaris compiler?
Does someone know what the error code means (I haven't been able to find that out)?
After reporting my problem to Oracle, I just got their answer:
Thank you for reporting this and sorry for the problem. This is a known problem. It has already been fixed in our current development and ported to Studio 12.4. If you have a support contract, you can get the Studio 12.4 patch for it, otherwise the next release will contain the fix.
I am new to mingw32-gfortran, and I am finding it hard to statically link the specific dll's. I am trying to write a code on finding large factorials,the code compiles without any errors on code::blocks but gives an error about missing dll's when opened from cmd. Is there anyway to statically link these dll's to my exe (I don't mind if it is bloated,I just want my code to be portable).
Does gfortran provide similar libraries for static linking? I have also posted my code for any reference. It would really mean much to me if someone here helped me out, I have already tried code blocks forums,and read numerous posts on other websites. Still no luck.
Note : I use Win 7 64-bit
! A fortran95 program for G95
! By WQY
program main
implicit none
integer ,allocatable,dimension (:) :: a
integer :: re_i,n,digit=1,temp=0,zero=0,i,j,beg,rate,ends
allocate(a(10000000))
a(1)=1
print*,'please enter the number'
read *, n
call system_clock(beg,rate)
do j=2,n
do i=zero+1,digit
temp=temp+a(i)*j
a(i)=temp-(temp/10)*10
temp=temp/10
end do
do while (temp>0)
digit=digit+1
a(digit) = temp-(temp/10)*10
temp = (temp/10)
end do
do while(a(zero+1)==0)
zero=zero+1
end do
end do
call system_clock(ends,rate)
write(*,1,advance='no') a(digit)
write (*,2,advance ='no') '.'
write (*,1) ( a(i),i=digit-1,digit-50,-1)
1 format(120i1)
print *,' X 10^' ,digit-1
2 format(100a1)
print '("computation time ",f6.3," seconds")',real(ends-beg)/real(rate)
re_i=system("pause")
end
Does anyone know how to compile a program in gfortan from command line? Errors seems to pop up every time I try to do so.
I have an integer variable that is declared at the head of my subroutine. After I've used it as a control variable inside a forall construct, I can no longer use it as the control variable of a do loop. The compiler (Intel, v. 12.0.3) complains
xyz.f90(1210): error #6404: This name does not have a type, and must have an explicit type. [I]
do i=1,sp_basis%num_dim
---------------^
xyz.f90(1210): error #6063: An INTEGER or REAL data type is required in this context. [I]
do i=1,sp_basis%num_dim
I have tried to write a small example to replicate this behaviour (and compiled the file with the same compiler options as the actual problematic one, apart from -c), but this compiled & worked nicely, so below is my (slightly shortened) problematic code (implicit none applies to the entire module this code belongs to):
subroutine xyz(stuff)
use data, only: ppm, npeaks
! some declarations
integer :: i ! ...
associate(sp_basis => public_spectra%basis(counter))
spots = npeaks * np
allocate(ref_curves(spots,npeaks,sp_basis%num_dim), stat=stat)
if (stat.ne.0) then
! ...
end if
forall (i=1:max_dim) uppers(i) = ubound(sp_int%int,i)
forall (i=1:max_dim) lowers(i) = lbound(sp_int%int,i)
forall (i=1:npeaks,j=1:sp_basis%num_dim) peak_pos_hertz(j,i) = ppm_to_hertz(ppm(permutation(j),i), sp_axes(j))
do peak_considered=1,npeaks
do pos=(peak_considered-1)*np+1,peak_considered*np
do i=1,sp_basis%num_dim ! <-- COMPLAINT
If I change i to a name that was not used as a forall construct's control variable everything works. Also, this is the second time I've run into this problem.
This is how the compilation is done (xyz.f90 is one of many files that make up the entire program):
ifort -c -g -C -check noarg_temp_created -traceback -warn -warn nodeclarations -nogen-interface xyz.f90
Does any of you know what the problem might be?
Thanks a lot for your time!
For all those interested, it's a bug in the Intel compiler. Here you can read more about it. Also it sounds like this bug will be fixed in a compiler version that is to be released some time in 2012.
In summary, is it possible to access via use association a preprocessor directive defined in a Fortran module?
Context
I use preprocessor statements to define subroutines to print warning and error messages. For example, I use the following module/subroutine, in the file errors.f, to print warning messages
module errors
use, intrinsic :: iso_fortran_env, only : error_unit=>stderr
implicit none
contains
!> Print formatted warning message.
subroutine warn_print( file, line, mesg )
implicit none
character(len=*), intent(in) :: file
integer, intent(in) :: line
character(len=*), intent(in) :: mesg
write(stderr,'(a,a,a,i4,a,a)') "WARNING::", file, ":", line, ": ", mesg
end subroutine warn_print
end module errors
and, in a separate file errors.h, I use the above module and define a preprocessor macro
use errors
#define warn( text )warn_print(__FILE__,__LINE__,text)
I then #include the file errors.h in whichever file/module I wish to use the warning print routine which allows me to simply write
call warn("Some warning message")
and the compiler will automatically include the file and line number at which the warning message was called.
Question
The use of #include 'errors.h' is rather idiosyncratic in Fortran code and it hides the use of the errors module. Ideally I would prefer to define the above preprocessor in the errors module itself. However, then when using that module, this preprocessor directive is not available to the program/module which uses this module.
Is there a way to make a preprocessor directive accessible via use association?
The only other way I can think of doing it is to just have the errors module and define the preprocessor directive in my call to the compiler (using, for example, the -D flag with ifort). Any suggestions for any alternative way of achieving the above would be greatly appreciated.
No, it is simply not possible, since the preprocessing and the compilation stages are completely separate one from each other and the C preprocessor does not know anything about the Fortran USE statement.
I use to #include 'config.h' (from autoconf) in most of my .F90 sources, without problems.
This may not be what you are looking for, but if you are using ifort, you can use traceback functionality to achieve something similar (a bit more powerful, but also more ugly), e.g.
program tracetest
call sub(5)
write(*,*) '=== DONE ==='
end program tracetest
subroutine sub(n)
use ifcore
integer :: n
character(len=60) :: str
write(str,*) '=== TROUBLE DETECTED: n =',n ! code -1 means "do not abort"
call tracebackqq(str,-1)
end subroutine sub
Then, compile with -traceback to see the source file, line, and stack trace. The stack trace and line may be obscured because of inlining; to avoid that, you can specify -traceback -O0 to get smth like this:
=== TROUBLE DETECTED: n = 5
Image PC Routine Line Source
a.out 0000000000473D0D Unknown Unknown Unknown
a.out 0000000000472815 Unknown Unknown Unknown
a.out 0000000000423260 Unknown Unknown Unknown
a.out 0000000000404BD6 Unknown Unknown Unknown
a.out 0000000000402C14 sub_ 12 tracetest.f90
a.out 0000000000402B18 MAIN__ 2 tracetest.f90
a.out 0000000000402ADC Unknown Unknown Unknown
libc.so.6 000000323201EC5D Unknown Unknown Unknown
a.out 00000000004029D9 Unknown Unknown Unknown
=== DONE ===
Alternatively, if want to keep the optimizations, and also want to see the correct line (12), you can compile with (for example) -fast -traceback -debug all,inline_debug_info. Something similar may be available in other compilers, but I am not sure.