Fortran-nf90_开放式-SIGSEGV
我正在使用一个旧的fortran程序打开一个netcdf文件,读取其内容,执行一些计算和插值,并将数据写入另一种文件格式。我在fortran方面的经验很少,因此,如果您有任何帮助,我将不胜感激 程序编译成功:Fortran-nf90_开放式-SIGSEGV,fortran,netcdf,Fortran,Netcdf,我正在使用一个旧的fortran程序打开一个netcdf文件,读取其内容,执行一些计算和插值,并将数据写入另一种文件格式。我在fortran方面的经验很少,因此,如果您有任何帮助,我将不胜感激 程序编译成功: ifort -c -CB -CU -ftrapuv -par_report0 -vec_report0 -heap-arrays -O0 -stand f90 -check all -traceback -fstack-protector -assume protect_parens -i
ifort -c -CB -CU -ftrapuv -par_report0 -vec_report0 -heap-arrays -O0 -stand f90 -check all -traceback -fstack-protector -assume protect_parens -implicitnone -debug -gen-interfaces -check arg_temp_created -ftrapuv -g -convert big_endian -I/opt/cray/netcdf/4.3.0/INTEL/130/include/ CAM_netcdf_to_WRF_intermediate.f90 ; ifort CAM_netcdf_to_WRF_intermediate.o -L/opt/cray/netcdf/4.3.0/INTEL/130/lib -lnetcdf -lnetcdff
程序崩溃,在尝试读取netcdf文件时超出范围:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7657d33 in nf_open_ (A1=0x18 <Address 0x18 out of bounds>, A2=0x4e04bc <__NLITPACK_19>,
A3=0x7fffffff90ec, C1=128) at fort-control.c:27
27 fort-control.c: No such file or directory.
程序接收信号SIGSEGV,分段故障。
nf_open_中的0x00007FF7657D33(A1=0x18,A2=0x4e04bc,
A3=0x7FFFFF90EC,C1=128)在炮台控制中心。c:27
27 fort control.c:没有这样的文件或目录。
使用“bt full”运行GDB:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7657d33 in nf_open_ (A1=0x18 <Address 0x18 out of bounds>, A2=0x4e04bc <__NLITPACK_19>,
A3=0x7fffffff90ec, C1=128) at fort-control.c:27
27 fort-control.c: No such file or directory.
(gdb) bt full
#0 0x00007ffff7657d33 in nf_open_ (A1=0x18 <Address 0x18 out of bounds>,
A2=0x4e04bc <__NLITPACK_19>, A3=0x7fffffff90ec, C1=128) at fort-control.c:27
B1 = 0x0
B3 = 5113020
#1 0x00007ffff76630ac in NETCDF::nf90_open (
path=<error reading variable: Cannot access memory at address 0x18>, mode=0, ncid=-858993460,
chunksize=<error reading variable: Cannot access memory at address 0x0>,
cache_size=<error reading variable: Cannot access memory at address 0x0>,
cache_nelems=<error reading variable: Cannot access memory at address 0x0>,
cache_preemption=<error reading variable: Cannot access memory at address 0x0>,
comm=<error reading variable: Cannot access memory at address 0x0>,
info=<error reading variable: Cannot access memory at address 0x0>, .tmp.PATH.len_V$ffc=128)
at netcdf4_file.f90:64
nf90_open = -144388088
ret = 0
preemption_out = 0
nelems_out = -1
size_out = 0
preemption_in = 32767
nelems_in = -134664192
size_in = 32767
程序接收信号SIGSEGV,分段故障。
nf_open_中的0x00007FF7657D33(A1=0x18,A2=0x4e04bc,
A3=0x7FFFFF90EC,C1=128)在炮台控制中心。c:27
27 fort control.c:没有这样的文件或目录。
(gdb)英国电信全部
#0 0x00007FF7657D33处于nf_打开状态(A1=0x18,
A2=0x4e04bc,A3=0x7fffffff90ec,C1=128)在炮台控制区。c:27
B1=0x0
B3=5113020
#NETCDF::nf90_中的1 0x00007ffff76630ac打开(
路径=,模式=0,ncid=-858993460,
chunksize=,
缓存大小=,
cache_nelems=,
缓存_抢占=,
通信=,
info=,.tmp.PATH.len_V$ffc=128)
在netcdf4_文件中.f90:64
nf90_开放=-144388088
ret=0
抢占权输出=0
nelems_out=-1
大小_out=0
抢占权=32767
nelems_in=-134664192
尺寸_英寸=32767
计划如下:
program CAM_netcdf_to_WRF_intermediate
use netcdf
implicit none
! Declarations:
integer, parameter :: outfile_diagnostics = 16
integer, parameter :: infile_CAM_files_and_dates = 15
character(len=24) :: HDATE
! dimensions:
integer, parameter :: nx_CAM=288,ny_CAM=192,nz_CAM=26 &
,nfields=5,nfields2d=9,nfields2d_to_read=5 &
,nz_soil=4,nz_CLM=1,nfields_soil=2
integer, parameter :: nz_WRF=38
character(len=128) :: netcdf_cam_filename,netcdf_clm_filename,netcdf_pop_filename
character(len=128) :: netcdf_ice_filename
integer :: iEOF
logical :: EOF
! open outpuf log file:
open(outfile_diagnostics,form='formatted',file="Output/CCSM2WRF.log")
! read the first date and netcdf file name from the input file:
open(infile_CAM_files_and_dates,form='formatted',file="Input/CCSM2WRF.input")
read(infile_CAM_files_and_dates,*,iostat=iEOF) netcdf_cam_filename,netcdf_clm_filename,&
netcdf_pop_filename,netcdf_ice_filename,hdate
if (iEOF<0) then;
print *, "EOF True"
EOF=.true.;
else;
print *, "EOF False"
EOF=.false.;
end if
call dummy_read(nz_WRF,hdate,outfile_diagnostics,netcdf_cam_filename &
,netcdf_clm_filename,netcdf_pop_filename &
,netcdf_ice_filename,nx_CAM,ny_CAM,nz_CAM)
stop
end program CAM_netcdf_to_WRF_intermediate
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SUBROUTINE HANDLE_ERR(STATUS)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
use netcdf
implicit none
INTEGER STATUS
IF (STATUS .NE. NF90_NOERR) THEN
PRINT *, NF90_STRERROR(STATUS)
STOP 'Stopped'
ENDIF
END SUBROUTINE HANDLE_ERR
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Subroutine dummy_read &
(nz_WRF,outfile_diagnostics,netcdf_cam_filename &
,netcdf_clm_filename,netcdf_pop_filename,netcdf_ice_filename &
,nx_CAM,ny_CAM,nz_CAM)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
use netcdf
implicit none
integer :: nz_WRF
integer :: nx_CAM,ny_CAM,nz_CAM
character(len=128) :: filename
character(len=24) :: HDATE
integer :: outfile_diagnostics
integer :: STATUS, NCID, NCID_clm, NCID_pop, NCID_ice
character(len=128) :: netcdf_cam_filename, netcdf_clm_filename, netcdf_pop_filename
character(len=128) :: netcdf_ice_filename
! open output files for metgrid in WRF/WPS intermediate format:
write(filename,'("Output/FILE:",A13)') hdate(1:13)
write(outfile_diagnostics,*) "output intermediate file filename=",filename
open(10,form='unformatted',file=filename)
write(filename,'("Output/SST:",A13)') hdate(1:13)
write(outfile_diagnostics,*) "output intermediate SST file filename=",filename
open(11,form='unformatted',file=filename)
STATUS = NF90_OPEN(netcdf_cam_filename, 0, NCID)
! STATUS = NF90_OPEN(path = "Inputdata/ind/cam_CCSM4_historical_197909-197912-1979090100.nc", mode= 0, ncid = NCID)
IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)
print *, "first status conditional statement"
STATUS = NF90_OPEN(netcdf_clm_filename, 0, NCID_clm)
IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)
STATUS = NF90_OPEN(netcdf_pop_filename, 0, NCID_pop)
IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)
STATUS = NF90_OPEN(netcdf_ice_filename, 0, NCID_ice)
IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)
status=NF90_CLOSE(NCID)
status=NF90_CLOSE(NCID_clm)
status=NF90_CLOSE(NCID_pop)
status=NF90_CLOSE(NCID_ice)
print *, "Leaving dummy, going to MAIN"
return
end Subroutine dummy_read
将CAM\u netcdf\u编程到\u WRF\u中间
使用netcdf
隐式无
! 声明:
整数,参数::outfile_diagnostics=16
整数,参数::infle\u CAM\u文件和日期=15
字符(len=24)::HDATE
! 尺寸:
整数,参数::nx_CAM=288,ny_CAM=192,nz_CAM=26&
,nfields=5,nfields2d=9,nfields2d-to-read=5&
,nz_土壤=4,nz_CLM=1,nfields_土壤=2
整数,参数::nz_WRF=38
字符(len=128)::netcdf\u cam\u文件名、netcdf\u clm\u文件名、netcdf\u pop\u文件名
字符(len=128)::netcdf\u ice\u文件名
整数::iEOF
逻辑::EOF
! 打开outpuf日志文件:
打开(outfile_diagnostics,form='formatted',file=“Output/CCSM2WRF.log”)
! 从输入文件中读取第一个日期和netcdf文件名:
打开(填充CAM文件和日期,form='formatted',file=“Input/CCSM2WRF.Input”)
读取(填充CAM文件和日期,*,iostat=iEOF)netcdf CAM文件名,netcdf clm文件名&
netcdf_pop_文件名,netcdf_ice_文件名,hdate
如果(iEOF您的子例程调用与实际定义不匹配
您对dummy\u read
的调用是:
call dummy_read(nz_WRF,hdate,outfile_diagnostics,netcdf_cam_filename &
,netcdf_clm_filename,netcdf_pop_filename &
,netcdf_ice_filename,nx_CAM,ny_CAM,nz_CAM)
Subroutine dummy_read &
(nz_WRF,outfile_diagnostics,netcdf_cam_filename &
,netcdf_clm_filename,netcdf_pop_filename,netcdf_ice_filename &
,nx_CAM,ny_CAM,nz_CAM)
而您的dummy\u read
声明是:
call dummy_read(nz_WRF,hdate,outfile_diagnostics,netcdf_cam_filename &
,netcdf_clm_filename,netcdf_pop_filename &
,netcdf_ice_filename,nx_CAM,ny_CAM,nz_CAM)
Subroutine dummy_read &
(nz_WRF,outfile_diagnostics,netcdf_cam_filename &
,netcdf_clm_filename,netcdf_pop_filename,netcdf_ice_filename &
,nx_CAM,ny_CAM,nz_CAM)
或者以不同的方式展示:
call dummy_read(nz_WRF,hdate, outfile_diagnostics,netcdf_cam_filename,netcdf_clm_filename,netcdf_pop_filename,netcdf_ice_filename,nx_CAM,ny_CAM,nz_CAM)
Subroutine dummy_read(nz_WRF,outfile_diagnostics,netcdf_cam_filename,netcdf_clm_filename,netcdf_pop_filename,netcdf_ice_filename,nx_CAM, ny_CAM,nz_CAM)
这会导致参数不匹配。伪参数outfile\u diagnostics
与实际参数hdate
相关联,依此类推。您将10个参数传递给声明为取9的子例程
您可能想知道为什么编译器在这种情况下生成可执行文件而不是生成错误。这是因为您使用隐式接口调用过程,Fortran相信您会做正确的事情。Fortran可以检测参数不匹配,但要做到这一点,您需要提供显式接口。除了显式打开接口,最简单的方法是将该过程设置为模块过程(通过将子例程放入模块)或内部过程(通过将该过程放置在包含的
语句之后的主程序中)
您还可以要求编译器提供高级别警告以避免此问题。使用gfortran with-Wall
编译时,代码会产生此警告:
call dummy_read(nz_WRF,hdate,outfile_diagnostics,netcdf_cam_filename &
1
Warning: Type mismatch in argument 'outfile_diagnostics' at (1); passed CHARACTER(1) to INTEGER(4)
自动地,iFoT提供了选项>代码> Gen接口< /代码>标志,它将自动生成包含外部过程的模块。但是,我认为这是一个工具来帮助端口代码达到比依赖的更高的语言标准。
您的子程序调用与实际定义不匹配。
您对
dummy\u read
的调用是:
call dummy_read(nz_WRF,hdate,outfile_diagnostics,netcdf_cam_filename &
,netcdf_clm_filename,netcdf_pop_filename &
,netcdf_ice_filename,nx_CAM,ny_CAM,nz_CAM)
Subroutine dummy_read &
(nz_WRF,outfile_diagnostics,netcdf_cam_filename &
,netcdf_clm_filename,netcdf_pop_filename,netcdf_ice_filename &
,nx_CAM,ny_CAM,nz_CAM)
而您的dummy\u read
声明是:
call dummy_read(nz_WRF,hdate,outfile_diagnostics,netcdf_cam_filename &
,netcdf_clm_filename,netcdf_pop_filename &
,netcdf_ice_filename,nx_CAM,ny_CAM,nz_CAM)
Subroutine dummy_read &
(nz_WRF,outfile_diagnostics,netcdf_cam_filename &
,netcdf_clm_filename,netcdf_pop_filename,netcdf_ice_filename &
,nx_CAM,ny_CAM,nz_CAM)
或者以不同的方式展示:
call dummy_read(nz_WRF,hdate, outfile_diagnostics,netcdf_cam_filename,netcdf_clm_filename,netcdf_pop_filename,netcdf_ice_filename,nx_CAM,ny_CAM,nz_CAM)
Subroutine dummy_read(nz_WRF,outfile_diagnostics,netcdf_cam_filename,netcdf_clm_filename,netcdf_pop_filename,netcdf_ice_filename,nx_CAM, ny_CAM,nz_CAM)
这会导致参数不匹配。伪参数outfile\u diagnostics
与实际参数hdate
相关联,依此类推。您将10个参数传递给声明为取9的子例程
您可能想知道为什么编译器在这种情况下生成可执行文件而不是生成错误。这是因为您使用隐式接口调用过程,Fortran相信您会做正确的事情。Fortran可以检测参数不匹配,但要做到这一点,您需要提供显式接口。除了显式打开接口,最简单的方法是将该过程设置为模块过程(通过将子例程放入模块)或内部过程(通过将该过程放置在包含的
语句之后的主程序中)
您还可以要求编译器提供高级别警告以避免此问题。使用gfortran with-Wall
编译时,代码会产生此警告:
call dummy_read(nz_WRF,hdate,outfile_diagnostics,netcdf_cam_filename &
1
Warning: Type mismatch in argument 'outfile_diagnostics' at (1); passed CHARACTER(1) to INTEGER(4)
自动地,iFoT提供了选项>代码> Gen接口< /代码>标志,它将自动生成包含外部过程的模块。但是,我会认为这是一个工具来帮助端口代码达到比依赖的更高的语言标准。
使用<代码> -G追踪-<代码>以获得更有用的回溯。Mark-我不确定你的意思-fortran函数“nf90_open”不在代码中,但加载了此语句(“use netcdf”)。调用和dummy_read
的定义之间的参数不匹配是示例中的输入错误,还是实际代码中也存在此错误?@casey-