I started using fortran this year so i apologise if it is basic but i have been searching for a long time for an answer and i need to hand in tomorrow :( I keep getting the error:
Jamess-MacBook-Pro:Coursework2 james$ gfortran Question2cprogram.f90
gfortran: warning: couldn’t understand kern.osversion ‘14.0.0
Undefined symbols for architecture x86_64:
"___cg_solver_MOD_cg", referenced from:
_MAIN__ in ccg9ePxI.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
It is a relatively simple program just subbing in values into a subroutine "cg" called from a module cg_solver.
program Question2c
use cg_solver
use numeric_kinds
use csr_sparse_matrix
implicit none
real(dp) :: tol
real(dp), dimension(:), allocatable :: x, b, real_x
integer :: n, no_iterations
type(sp_matrix) :: a
n = 4
allocate(real_x(n))
real_x(1)=1
real_x(2)=7
real_x(3)=4
real_x(4)=13
allocate(b(n))
b(1)=30.0
b(2)=34.0
b(3)=28.0
b(4)=152.0
allocate(x(n))
allocate(a%matrix_entries(8))
a%matrix_entries(1)=4.0
a%matrix_entries(2)=2.0
a%matrix_entries(3)=3.0
a%matrix_entries(4)=1.0
a%matrix_entries(5)=7.0
a%matrix_entries(6)=2.0
a%matrix_entries(7)=1.0
a%matrix_entries(8)=11.0
allocate(a%column_no(8))
a%column_no(1)=1.0
a%column_no(2)=4.0
a%column_no(3)=2.0
a%column_no(4)=4.0
a%column_no(5)=3.0
a%column_no(6)=1.0
a%column_no(7)=2.0
a%column_no(8)=4.0
allocate(a%row_start(5))
a%row_start(1)=1.0
a%row_start(2)=3.0
a%row_start(3)=5.0
a%row_start(4)=6.0
a%row_start(5)=9.0
tol = 10**(-10)
call cg(a,b,x,n,tol,no_iterations)
print *, x
deallocate(a)
deallocate(x)
deallocate(real_x)
end program Question2c
where the module cg_solver is given from the lecturer and works fine. I think the error may be in the way that i'm calling the module or something but i can't see what is wrong; they are all in the same folder.
I've had better luck specifying the '-arch x86_64' flag for everything when using gfortran on OS X.
Might try recompiling all your files with that flag.
Related
I'm working on a computational project for a class at university and I've come across the following error message:
<undefined reference to 'tridag_'>
when trying to call the tridag subroutine to solve a tridiagonal linear set of equations. Isn't the tridag subroutine included in fortran's library? I'm using code blocks with the gnu fortran compiler. Here's the program:
double precision t0, tc, rc, dt, dx, al, time, alpha
double precision, allocatable :: tmp(:), tmpnew(:), aw(:), ap(:), ae(:), su(:), x(:)
open (1,file='input.txt'); open (2,file='output.txt')
read (1,*) ni, nt
read (1,*) t0, tc, dt, al, alpha
allocate (tmp(ni), tmpnew(ni), aw(ni), ap(ni), ae(ni), su(ni), x(ni))
dx = al/float(ni-1)
do i=1,ni
x(i)=(i-1)*dx
end do
rc=alpha*dt/dx**2
!ΑΡΧΙΚΗ ΣΥΝΘΗΚΗ
tmp=t0
do it=1,nt
time=(it-1)*dt
ap(1)=1; ae(1)=-1; su(1)=0
ap(ni)=1; aw(ni)=0; su(ni)=tc
do i=2,ni-1
ap(i)=-(1+2*rc); ae(i)=rc; aw(i)=rc; su(i)=-tmp(i)
end do
call tridag (aw, ap, ae, su, tmpnew, ni)
do i=1,ni
tmp(i)=tmpnew(i)
write(2,*) x(i),tmp(i)
end do
end do
Thanks in advance.
tridag() is not a Fortran intrinsic subroutine, it comes from an external library. You must get this library, compile the subroutine and link it with your code.
As far a I know TRIDAG comes from the Numerical Recipes book so be aware it is commercially licensed. If you get the book and the associated source code, you can use it according to the book's license. You can certainly also find the code on the internet (just use your favourite search engine to search for "TRIDAG Fortran subroutine"), but the license still applies.
Also note that there are many other tridiagonal matrix solvers available, but this site is not for locating or recommending external software libraries.
I am trying to use an old Fortran code for processing data. I have little experience with Fortran and have been unable to get past a problem that I think is to do with number types.
Part of the code I am using is at the bottom of this question. I am pretty sure, but not certain, that the second-last line (also the second-last line of this post) is the problem.
First I did this:
gfortran -g cpt_ir_.f90 -o cpt_ir_.o
./cpt_ir_.o < di.in
It resulted in this error:
Backtrace for this error:
#0 0x2B794A134467
#1 0x2B794A134AAE
#2 0x2B794ABC724F
#3 0x2B794A1FB8AB
#4 0x2B794A1F7613
#5 0x2B794A1F934E
#6 0x2B794A1FDF86
#7 0x40128A in MAIN__ at cpt_ir_.f90:29
Segmentation fault
I searched Stack Overflow and saw a suggestion to do the following to get more information:
gfortran -g -fcheck=all -Wall cpt_ir_.f90
The output is shown directly below. The Fmax... line is the final line of the code I pasted at the end of this post (further in the code there are other similar lines). However, I see that it is shown as a warning, not an error. So I although I proceed here as though it is the error, maybe there is another problem that the command above did not reveal.
cpt_ir_.f90:66.5:
Fmax=N*((4000.0/(2.0*Pi))*(2.0*Pi*timestep*1.0-15.0*29979245800.0))
1
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1)
I came across a suggestion here at Stack Overflow to use the following flags:
-fdefault-integer-8 -fno-range-check
Which I did as follows:
gfortran -g -fdefault-integer-8 -fno-range-check cpt_ir_.f90 -o cpt_ir_.o
I'm not sure if I did it correctly. I also tried them one by one. Anyway, there was no change and I got the same error. I also tried manually changing the numbers in the problem line as shown in the final line of this post. That didn't help either--I got an error that the largest number was too large for an int.
If anyone could please point me in the right direction, I would be very grateful. Please also feel free to change my tags if there are more appropriate tags for this question.
cpt_ir_.f90:
!
!
IMPLICIT NONE
INTEGER, PARAMETER :: dp=KIND(0.0D0)
REAL(KIND=dp), DIMENSION(:), ALLOCATABLE :: correlation
REAL(KIND=dp) :: integral,omega,Pi,timestep
REAL(KIND=dp), DIMENSION(3,1000000) :: dipder,dip
REAL(KIND=dp), DIMENSION(3) :: m_vec
INTEGER :: N,I,J,Nmax,Fmax
CHARACTER(LEN=100) :: line,filename
Pi=4.0D0*ATAN(1.0D0)
READ(5,*) filename
READ(5,*) timestep
OPEN(10,FILE=filename)
N=0
DO
READ(10,'(A100)',END=999) line
IF (INDEX(line,' XXX').NE.0) THEN
N=N+1
READ(line(45:),*) dip(:,N)
ENDIF
IF (INDEX(line,' XXX').NE.0) THEN
N=N+1
READ(line(45:),*) dipder(:,N)
ENDIF
ENDDO
999 CONTINUE
CLOSE(10)
Nmax=N/10
print *, Nmax
ALLOCATE(correlation(0:Nmax))
correlation=0.0_dp
DO I=1,N-Nmax
DO J=I,I+Nmax
correlation(J-I)=correlation(J-I)+DOT_PRODUCT(dipder(:,I),dipder(:,J))
ENDDO
ENDDO
DO I=0,Nmax
correlation(I)=correlation(I)/(REAL(N-I,kind=dp)*REAL(N,kind=dp))
ENDDO
OPEN(UNIT=10,FILE="dip_dip_correlation.time")
write(10,*) "XXX"
DO I=-Nmax,Nmax
write(10,*) I*timestep,correlation(ABS(I))/correlation(0)
ENDDO
CLOSE(10)
OPEN(UNIT=10,FILE="XXX")
write(10,*) "XXX"
!Fmax up to 4000 cm^-1
Fmax=N*((4000D0/(2*Pi))*(2.0D0*Pi*timestep*1.0D-15*29979245800.0))
! My try: Fmax=N*((4000.0/(2.0*Pi))*(2.0*Pi*timestep*1.0-15.0*29979245800.0))
Update based on Dan's answer:
Dan kindly pointed out that I needed to uncomment "N=N+1." Unfortunately, after fixing that, I am still seeing the segmentation fault. Just now when I ran:
gfortran -g -fcheck=all -Wall cpt_ir_.f90
on my try at the last line of the code (where I tried converting everything to a float):
Fmax=N*((4000.0/(2.0*Pi))*(2.0*Pi*timestep*1.0-15.0*29979245800.0))
I got:
Fmax=N*((4000.0/(2.0*Pi))*(2.0*Pi*timestep*1.0-15.0*29979245800.0))
1
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1)
At a glance, your line
READ(line(45:),*) dip(:,N)
is the first problem. You comment out the N=N+1 line so N = 0. Fortran is '1' indexed meaning that Fortran arrays start at 1 unless otherwise specified. So the second dimension of dip starts at 1 and you are trying to set the 'zeroth' element which does not exist.
I'm trying to write a simple Fortran library for interval arithmetic as an exercise. I want to explicitly set the rounding mode, do some work, and then restore the rounding mode to what it was originally. However, I can't figure out which library needs to be linked to resulting executable when compiling with gfortran, gcc's Fortran frontend.
! get_rounding_mode.f03
! print the rounding mode
program get_rounding_mode
f = IEEE_GET_ROUNDING_MODE()
print *,f
end program get_rounding_mode
Trying the Simplest Thing That Could Possibly Work gives me
gfortran get_rounding_mode.f03
/usr/bin/ld: /tmp/ccTLaxeN.o: in function `MAIN__':
get_rounding_mode.f03:(.text+0x20): undefined reference to `ieee_get_rounding_mode_'
collect2: error: ld returned 1 exit status
Exit 1
By looking everywhere for ieee_get_rounding I found it, but I don't know how to direct gfortran to link it since it appears to already be in libgfortran .
find /usr/ -exec nm --print-file-name '{}' '+' 2>&1 | grep 'ieee_get_rounding'
/usr/lib/libgfortran.so.5:000000000023edc0 T __ieee_arithmetic_MOD_ieee_get_rounding_mode
/usr/lib/libgfortran.so:000000000023edc0 T __ieee_arithmetic_MOD_ieee_get_rounding_mode
IEEE_GET_ROUNDING_MODE isn't a function. It is a subroutine. You need to do something like
program get_rounding_mode
use ieee_arithmetic
implicit none
ieee_rounding_type mode
real x
if (ieee_support_rounding(x)) then
call ieee_get_rounding_mode(mode) ! Get current rounding mode
call ieee_set_rounding_mode(IEEE_TO_UP) ! Set rounding up
!
! Do your work here!
!
call ieee_set_rounding_mode(mode) ! Reset rounding mode
end if
end program get_rounding_mode
Whoops, forgot the implicit none and declaration of x
I'm trying to read columns from an input file in Fortran, to use them for other calculations.
When I compile with g ++ I read this error:
Undefined symbols for architecture x86_64:
"__gfortran_set_args", referenced from:
_main in ccOO2MBV.o
"__gfortran_set_options", referenced from:
_main in ccOO2MBV.o
"__gfortran_st_close", referenced from:
_MAIN__ in ccOO2MBV.o
"__gfortran_st_open", referenced from:
_MAIN__ in ccOO2MBV.o
"__gfortran_st_read", referenced from:
_MAIN__ in ccOO2MBV.o
"__gfortran_st_read_done", referenced from:
_MAIN__ in ccOO2MBV.o
"__gfortran_transfer_real", referenced from:
_MAIN__ in ccOO2MBV.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
Where am I wrong? The code is this:
program columns
INTEGER,SAVE :: lun
INTEGER, PARAMETER :: ARRAYLEN=1440
CHARACTER :: filename
DOUBLE PRECISION, DIMENSION (1044) :: X_halo, Y_halo, Z_halo
INTEGER :: i
lun=1
filename = 'xyz.dat'
OPEN (1, FILE='xyz.dat',STATUS='old', ACTION='read', iostat=istat)
do i=1,1440
READ (1, iostat=istat) X_halo(i), Y_halo(i), Z_halo(i)
end do
CLOSE (1)
end program columns
As pointed out by #d_1999 the compiler should be gfortran, not g++.
In addition to this, changing the comment by #Ross in to an answer, your code should run with the format of READ specified, here as
READ (1, *, iostat=istat) X_halo(i), Y_halo(i), Z_halo(i)
giving the minimum change required to make your code run. In addition to this, have a look at the other differences implemented here:
program columns
! Add implicit none to catch that `istat` is not declared
IMPLICIT NONE
INTEGER,SAVE :: lun
INTEGER, PARAMETER :: ARRAYLEN=1440
! Make `filename` bigger than a single character
CHARACTER(120) :: filename
! can add `ARRAYLEN` here
DOUBLE PRECISION, DIMENSION (ARRAYLEN) :: X_halo, Y_halo, Z_halo
! Have added `istat` here
INTEGER :: i, istat
lun=1
filename = 'xyz.dat'
! Have replaced `xyz.dat` with `filename` and using a higher `UNIT` number
OPEN (UNIT=10, FILE=filename, STATUS='old', ACTION='read', IOSTAT=istat)
! Using `ARRAYLEN` for the loop.
! I've also capitalised the keywords (matter of preference)
DO i=1,ARRAYLEN
! And the important format specifier
READ (10, *, iostat=istat) X_halo(i), Y_halo(i), Z_halo(i)
END DO
CLOSE (10)
end program columns
Some of these issues (e.g. filename not being big enough) would have been caught by compiling with the -Wall flag, e.g. something like
gfortran -Wall columns.f90 -o columns.exe
I am writing a subroutine and main function to call it, but getting error as undefined reference to ___. I found one reason: When I save the main and subroutine in the same file, compile and run that file, everything runs perfectly. However, when I save them into different .f90 files and try to run the main file, I get error. Is there any way I can make subroutine into a separate file and call into main calling program?
I got confused with another place - in the main program at !------ERROR------ place. I referred to Automatic width integer descriptor in fortran 90 I can use I0 as automatic width display indicator. But when I used the same, there is run time error expected integer but got character. Any idea about this?
! saved as sub_program.f90 file
SUBROUTINE sub_program (v1,v2,ctr)
IMPLICIT NONE
INTEGER, INTENT(IN) :: ctr
INTEGER, INTENT (OUT) :: v1,v2
SELECT CASE (ctr)
CASE (1)
v1=1
v2=0
CASE (2)
v1=0
v2=1
END SELECT
RETURN
END SUBROUTINE
! main calling program, saved as caller.f90
PROGRAM caller
IMPLICIT NONE
INTEGER :: v1,v2,ctr
DO ctr = 1,2,1
CALL sub_program (v1,v2,ctr)
WRITE (*,100) 'STEP = ',ctr,'V1 = ',v1,'V2 = ',v2 !------ERROR------
100 FORMAT (I0)
END DO
END PROGRAM
Thanks!
What is your compile command? For me, this compiles and runs normally
gfortran caller.f90 foo.f90 && ./a.out
I0 is an integer indicator, but some items following your WRITE statement are character strings. You can try, for example,
100 FORMAT (3(A, I0, 1X))
where 1X refers to a space.
As a note, if formatting is not terribly important and you're only interested in seeing some quick results, you can use the free format output (WRITE(*,*) ...).
EDIT: I had incorrectly referred to FORMAT as obsolete.