I would like to use FM package capabilities for the study of a problem in number theory.
I installed the package, compiled libraries, and ran the two test suites supplied, all without any problems.
I wrote test.f:
use fmzm
TYPE (IM), SAVE :: n
n = 0
WRITE(*,*) n
end
and compiled using
gfortran -c -O3 -Wall test.f
gfortran fmsave.o fm.o fmzm90.o test.o -o test
which returned no error or warning. But got disappointed by discovering the output:
./test
200000
The number 200000 appears to be a memory location for the variable n. I experimented a little, and if I change n to complex type (ZM) it outputs 200000, 199999. Similarly if I declare and initialize two variable instead of one.
If I change TYPE (IM), SAVE :: n to INTEGER n, and compile exactly as above, I get the expected 0 as output.
If I replace the code by
n = 0
do
n=n+1
if (n < 10) WRITE(*,*) n
end do
then the output 200000 repeats 9 times and then stops. So it is the WRITE function which only finds the location and not the value. PRINT does the same.
As Vladimir points out, unless you write out a value of a standard type, it seems you have to first convert to a string using a maneuver such as
str = im_format('i100', n)
str = adjustl(str)
str = trim(str)
print*, str
where the middle two lines can be left out.
I am using a program that uses mixed language C and Fortran, like in the following example.
PROGRAM boolean
USE ISO_C_BINDING
IMPLICIT NONE
LOGICAL (KIND = C_BOOL) :: cbool
INTEGER :: i, j
i = 1
j = 2
cbool = i /= j
WRITE(*,*) cbool
END PROGRAM boolean
I compile it on Windows 10 with gfortran 10 from MSYS2-MINGW64 distribution using the following command:
gfortran boolean.f90 -o boolean -Wall
And I get the following warning message:
boolean.f90:8:11:
8 | cbool = i /= j
| 1
Warning: Possible change of value in conversion from LOGICAL(4) to LOGICAL(1) at (1) [-Wconversion]
I can solve this warning by changing to:
cbool = LOGICAL(i /= j,1)
I understand that this is because a different storage size is used by C_BOOL and the default logical in gfortran.
The questions: under what circumstances is it possible for the value to change as the warning says? What is the best way to remove this warning message, appart from using the LOGICAL intrinsic function?
I am getting started with a HPC running Redhat 6.6.
As a tutorial step for another program, I am asked to compile some old F77 code.
I am running the line gfortran 3bar.f
I get the error message:
/tmp/ccgUvoGd.o: In function `MAIN__':
3bar.f:(.text+0x43): undefined reference to `mygetarg_'
3bar.f:(.text+0x61): undefined reference to `mygetarg_'
3bar.f:(.text+0x8a): undefined reference to `mygetarg_'
collect2: ld returned 1 exit status
I believe this is related to the use of the sqrt intrinsic in the code. I have done some searching on this error and gfortran, but I get some squabbling about particular versions of Fortran for this and that.
I would really appreciate it if someone could advise me on how to get this code to work, as this is really not the point of what I am doing.
The code is:
program Three_bar
implicit none
real*8 a1,a2, g1,g2, weight, sum,
1 l0,d0,sqrt
intrinsic sqrt
character*80 inp_fname, out_fname
character*4 card1
integer i, ir,iw, numb_args, iargc, numb_iter
numb_args = iargc()
if ( numb_args .ge. 2 ) then
call MYGETARG(1,inp_fname)
call MYGETARG(2,out_fname)
else if ( numb_args .eq. 1 ) then
call MYGETARG(1,inp_fname)
out_fname = 'rdcs_output'
else
inp_fname = 'rdcs_input'
out_fname = 'rdcs_output'
endif
ir = 7
open (ir, file=inp_fname,status='UNKNOWN',access='SEQUENTIAL')
iw = 8
open (iw, file=out_fname,status='UNKNOWN',access='SEQUENTIAL')
l0 = 1.0
d0 = 1.0
c loop to spend some cpu - to test recall feature
sum = 1.0
numb_iter = 20000
do 1005 i=1,numb_iter
sum = (sum*1.00001)**1.001
if ( sum .gt. 1.0e6 ) sum = 1.0
1005 continue
c read the data from param file
weight = (2.d0*sqrt(2.d0)*a1 + a2)*l0*d0
g1=(2.d0*a1+sqrt(2.d0)*a2)/(2.d0*a1*(a1+sqrt(2.d0)*a2))-1.0d0
g2 = 1.0d0/(a1 + sqrt(2.d0)*a2) -1.0d0
write (iw,601) g1,g2,weight
close (unit=ir,status='KEEP')
close (unit=iw,status='KEEP')
501 format(a4,1x,f30.0)
601 format("g1 = ",e25.16," ",/,"g2 = ",e25.16," ",/,
1 "weight = ",e25.16," ")
stop
end
As noted in the comments, the compiler complains about a missing definition of MYGETARG, not SQRT.
The way you use that function reminds me of GETARG which is a GNU extension. My guess would by that MYGETARG is a wrapper function to make the code work with different compilers.
Since you are using gfortran, I would suggest to simply use GETARG instead. Then, your code compiles on my machine, albeit a few warnings.
On the long run, you should switch to something Standard conforming, such as GET_COMMAND_ARGUMENT.
Hey I am trying to get my LAPACK libraries to work and I have searched and searched but I can't seem to figure out what I am doing wrong.
I try running my code, and I get the following error
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7FFB23D405F7
#1 0x7FFB23D40C3E
#2 0x7FFB23692EAF
#3 0x401ED1 in sgesv_
#4 0x401D0B in MAIN__ at CFDtest.f03:? Segmentation fault (core dumped)
I will paste my main code here, hopefully someone can help me with this problem.
****************************************************
PROGRAM CFD_TEST
USE MY_LIB
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
DIMENSION ET(0:10), VN(0:10), WT(0:10)
DIMENSION SO(0:10), FU(0:10), DMA(0:10,0:10)
DIMENSION DMA2(0:10,0:10), QN(0:10), WKSPCE(0:10)
INTEGER*8 :: pivot(10), inf
INTEGER*8 :: N
EXTERNAL SGESV
!SET THE PARAMETERS
SIGMA1 = 0.D0
SIGMA2 = 0.D0
TAU = 1.D0
EF = 1.D0
EXP = 2.71828182845904509D0
COST = EXP/(1.D0+EXP*EXP)
DO 1 N=2, 10
!COMPUATION OF THE NODES, WEIGHTS AND DERIVATIVE MATRIX
CALL ZELEGL(N,ET,VN)
CALL WELEGL(N,ET,VN,WT)
CALL DMLEGL(N,10,ET,VN,DMA)
!CONSTRUCTION OF THE MATRIX CORRESPONDING TO THE
!DIFFERENTIAL OPERATOR
DO 2 I=0, N
DO 2 J=0, N
SUM = 0.D0
DO 3 K=0, N
SUM = SUM + DMA(I,K)*DMA(K,J)
3 CONTINUE
OPER = -SUM
IF(I .EQ. J) OPER = -SUM + TAU
DMA2(I,J) = OPER
2 CONTINUE
!CHANGE OF THE ENTRIES OF THE MATRIX ACCORDING TO THE
!BOUNDARY CONDITIONS
DO 4 J=0, N
DMA2(0,J) = 0.D0
DMA2(N,J) = 0.D0
4 CONTINUE
DMA2(0,0) = 1.D0
DMA2(N,N) = 1.D0
!CONSTRUCTION OF THE RIGHT-HAND SIDE VECTOR
DO 5 I=1, N-1
FU(I) = EF
5 CONTINUE
FU(0) = SIGMA1
FU(N) = SIGMA2
!SOLUTION OF THE LINEAR SYSTEM
N1 = N + 1
CALL SGESV(N,N,DMA2,pivot,FU,N,inf)
DO 6 I = 0, N
FU(I) = SO(I)
6 CONTINUE
PRINT *, pivot
1 CONTINUE
RETURN
END PROGRAM CFD_TEST
*****************************************************
The commands I run to compile are
gfortran -c MY_LIB.f03
gfortran -c CFDtest.f03
gfortran MY_LIB.o CFDtest.o -o CFDtest -L/usr/local/lib -llapack -lblas
I ran the command
-fbacktrace -g -Wall -Wextra CFDtest
CFDtest: In function _fini':
(.fini+0x0): multiple definition of_fini'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o:/build/buildd/glibc-2.19/csu/../sysdeps/x86_64/crti.S:80: first defined here
CFDtest: In function data_start':
(.data+0x0): multiple definition ofdata_start'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.data+0x0): first defined here
CFDtest: In function data_start':
(.data+0x8): multiple definition of__dso_handle'
/usr/lib/gcc/x86_64-linux-gnu/4.9/crtbegin.o:(.data+0x0): first defined here
CFDtest:(.rodata+0x0): multiple definition of _IO_stdin_used'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.rodata.cst4+0x0): first defined here
CFDtest: In function_start':
(.text+0x0): multiple definition of _start'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.text+0x0): first defined here
CFDtest: In function_init':
(.init+0x0): multiple definition of _init'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o:/build/buildd/glibc-2.19/csu/../sysdeps/x86_64/crti.S:64: first defined here
/usr/lib/gcc/x86_64-linux-gnu/4.9/crtend.o:(.tm_clone_table+0x0): multiple definition of__TMC_END'
CFDtest:(.data+0x10): first defined here
/usr/bin/ld: error in CFDtest(.eh_frame); no .eh_frame_hdr table will be created.
collect2: error: ld returned 1 exit status
You haven't posted your code for MY_LIB.f03 so we cannot compile CFDtest.f03 exactly as you have supplied it.
(As an aside, the usual naming convention is that f90 in a .f90 file is not supposed to imply the language version being targeted. Rather, .f90 denotes free format while .f is used for fixed format. By extension, your .f03 files would be better (i.e., more portable if) named as .f90.)
I commented out the USE MY_LIB line and ran your code through nagfor -u -c cfd_test.f90. The output, broken down, is
Extension: cfd_test.f90, line 13: Byte count on numeric data type
detected at *#8
Extension: cfd_test.f90, line 15: Byte count on numeric data type
detected at *#8
Byte counts are not portable. The kind value for an 8-byte integer is selected_int_kind(18). (Similarly you might like to use a kind(0.0d0) kind value for your double precision data.)
Error: cfd_test.f90, line 48: Implicit type for I
detected at 2#I
Error: cfd_test.f90, line 50: Implicit type for J
detected at 2#J
Error: cfd_test.f90, line 54: Implicit type for K
detected at 3#K
Error: cfd_test.f90, line 100: Implicit type for N1
detected at N1#=
You have these implicitly typed, which implies they are 4-byte (default) integers. You should probably declare these explicitly as 8-byte integers (using the 8-byte integer kind value above) if that's what you intend.
Questionable: cfd_test.f90, line 116: Variable COST set but never referenced
Questionable: cfd_test.f90, line 116: Variable N1 set but never referenced
Warning: cfd_test.f90, line 116: Unused local variable QN
Warning: cfd_test.f90, line 116: Unused local variable WKSPCE
You need to decide what you intend to do with these, or whether they are just deletable cruft.
With the implicit integers declared explicitly, there is further output
Warning: cfd_test.f90, line 116: Variable SO referenced but never set
This looks bad.
Obsolescent: cfd_test.f90, line 66: 2 is a shared DO termination label
Your DO loops would probably be better using the modern END DO terminators (not shared!)
Error: cfd_test.f90, line 114: RETURN is only allowed in SUBROUTINEs and FUNCTIONs
This is obviously easy to fix.
For the LAPACK call, one source of explicit interfaces for these routines is the NAG Fortran Library (through the nag_library module). Since your real data is not single precision, you should be using dgesv instead of sgesv. Adding USE nag_library, ONLY: dgesv and switching to call dgesv instead of sgesv, then recompiling as above, reveals
Incorrect data type INTEGER(KIND=4) (expected INTEGER) for argument N (no. 1) of DGESV
so you should indeed be using default (4-byte integers) - at least for the LAPACK build on your system, which will almost certainly be using 4-byte integers. Thus you might want to forget all about kinding your integers and just use the default integer type for all. Correcting this gives
Array supplied for scalar argument LDA (no. 4) of DGESV
so you do need to add this argument. Maybe pass size(DMA2,1)?
With this argument added to the call the code compiles successfully, but without the definitions for your *LEGL functions I couldn't go through any run-time testing.
Here is my modified (and pretty-printed) version of your program
Program cfd_test
! Use my_lib
! Use nag_library, Only: dgesv
Implicit None
Integer, Parameter :: wp = kind(0.0D0)
Real (Kind=wp) :: ef, oper, sigma1, sigma2, tau
Integer :: i, inf, j, k, n, sum
Real (Kind=wp) :: dma(0:10, 0:10), dma2(0:10, 0:10), et(0:10), fu(0:10), &
so(0:10), vn(0:10), wt(0:10)
Integer :: pivot(10)
External :: dgesv, dmlegl, welegl, zelegl
Intrinsic :: kind, size
! SET THE PARAMETERS
sigma1 = 0._wp
sigma2 = 0._wp
tau = 1._wp
ef = 1._wp
Do n = 2, 10
! COMPUATION OF THE NODES, WEIGHTS AND DERIVATIVE MATRIX
Call zelegl(n, et, vn)
Call welegl(n, et, vn, wt)
Call dmlegl(n, 10, et, vn, dma)
! CONSTRUCTION OF THE MATRIX CORRESPONDING TO THE
! DIFFERENTIAL OPERATOR
Do i = 0, n
Do j = 0, n
sum = 0._wp
Do k = 0, n
sum = sum + dma(i, k)*dma(k, j)
End Do
oper = -sum
If (i==j) oper = -sum + tau
dma2(i, j) = oper
End Do
End Do
! CHANGE OF THE ENTRIES OF THE MATRIX ACCORDING TO THE
! BOUNDARY CONDITIONS
Do j = 0, n
dma2(0, j) = 0._wp
dma2(n, j) = 0._wp
End Do
dma2(0, 0) = 1._wp
dma2(n, n) = 1._wp
! CONSTRUCTION OF THE RIGHT-HAND SIDE VECTOR
Do i = 1, n - 1
fu(i) = ef
End Do
fu(0) = sigma1
fu(n) = sigma2
! SOLUTION OF THE LINEAR SYSTEM
Call dgesv(n, n, dma2, size(dma2,1), pivot, fu, n, inf)
Do i = 0, n
fu(i) = so(i)
End Do
Print *, pivot
End Do
End Program
In general your development experience will be the most pleasant if you use as good a checking compiler as you can get your hands on and if you make sure you ask it to diagnose as much as it can for you.
As far as I can tell, there could be a number of problems:
Your integers with INTEGER*8 might be too long, maybe INTEGER*4 or simply INTEGER would be better
You call SGESV on double arguments instead of DGESV
Your LDA argument is missing, so your code should perhaps look like CALL DGESV(N,N,DMA2,N,pivot,FU,N,inf) but you need to check whether this is what you want.
I cant figure out whats my mistake I googled the problem took "implicit none" and declared eyery variable to integer I used but I still get the follwing errors:
main.f95:37.20:
e = Collatzf(i)
1
Error: Return type mismatch of function 'collatzf' at (1) (UNKNOWN/INTEGER(4))
main.f95:37.12:
e = Collatzf(i)
1
Error: Function 'collatzf' at (1) has no IMPLICIT type
Here is my Code:
INTEGER FUNCTION Collatzf(n)
IMPLICIT NONE
INTEGER :: n, z
z = 0
DO WHILE(n /= 1)
IF (MOD(n, 2) == 0) THEN
n = n / 2
ELSE
n = 3 * n + 1
END IF
z = z + 1
END DO
Collatzf = z
END FUNCTION Collatzf
PROGRAM ProjectEuler14
IMPLICIT NONE
INTEGER :: lsg, e, s, i
lsg = 0
e = 0
s = 0
i = 2
DO WHILE(i <= 1000000)
e = Collatzf(i)
IF(e > lsg) THEN
lsg = e
s = i
END IF
i = i + 1
END DO
WRITE(*, *) s, i
END PROGRAM ProjectEuler14
Thx :)
There is no declaration for the Collatzf function inside the main program.
Program units in Fortran have a separate compilation model - when compiling a program unit the compiler technically knows nothing about other program units, unless there are statements that give it explicit knowledge about those other units. So when compiling your main program (from the PROGRAM ... statement through to the END PROGRAM statement) the compiler has no idea what Collatzf is, even though the definition of that external function immediately preceded the main program. It cannot apply implicit typing rules because you have specified IMPLICIT NONE (a good thing), so hence you see the second error.
Provide a declaration of the type of Collatzf inside the main program. Better than that - provide an interface body for that function inside the main program. Even better than that again - make that function a module procedure, and then USE the module inside the main program.
lanH's answer is correct. Three suggested solutions are:
1) "Provide a declaration of the type of Collatzf inside the main program", which means adding
INTEGER :: Collatzf
statement to the variable declaration in PROGRAM ProjectEuler14.
2) "Provide an interface body for Collatzf function", which means means adding
INTERFACE
FUNCTION Collatzf (i)
INTEGER :: Collatzf
INTEGER, INTENT(IN) :: i
END FUNCTION Collatzf
END INTERFACE
statements to the variable declaration in "PROGRAM ProjectEuler14".
3) "Make that function a module procedure, and then USE the module inside the main program", which means creating a new file, named (for simplicity) "functions.f90":
MODULE functions
CONTAINS
INTEGER FUNCTION Collatzf(n)
IMPLICIT NONE
INTEGER :: n, z
z = 0
DO WHILE(n /= 1)
IF (MOD(n, 2) == 0) THEN
n = n / 2
ELSE
n = 3 * n + 1
END IF
z = z + 1
END DO
Collatzf = z
END FUNCTION Collatzf
END MODULE functions
Then compile functions.f90 first by e.g.:
gfortran -c functions.f90
and link the compiled "functions" module into your main program:
gfortran main.f90 functions.o