【问题标题】:Fortran warning at compile time, read error at executionFortran 编译时警告,执行时读取错误
【发布时间】:2014-01-28 09:39:43
【问题描述】:

我正在尝试使用 Intel fortran 编译器版本 14.0.1 在 Linux 集群 (Ubuntu 12.04) 中构建气象模型。但是在尝试编译 fdgrib2 模块时,我收到了以下警告消息:

/opt/intel/bin/ifort -c  -I. /usr/local/rams60/src/pre/fdgrib2/grib_get.f90
/usr/local/rams60/src/pre/fdgrib2/grib_get.f90(209): warning #8042: This argument must be of type character of length 1.   [TOKENS]
   print*,'5--'//trim(tokens(1)), len_trim(tokens(1)),ichar(tokens(1))
------------------------------------------------------------^
ar rs fdgrib2.a grib_get.o
rm -f grib_get.o

代币声明

字符(len=20)::标记(100)

尽管有此警告,但 fdgrib2 可执行文件已构建,但在尝试运行时停止并显示另一条错误消息:

/usr/local/rams60/build/fdgrib2$ ./fdgrib2 -f DGRIB_IN2
 num args:           2
  ---------------------------------------------------------------
 GRIB to GDF converter
 ---------------------------------------------------------------
 Namelist file name: DGRIB_IN2
 GRIB file name    : ./gfs.t00z.pgrbf06.grib2
 WGRIB exec        :
       Assumimg GRIB 2   : /usr/local/grib2/wgrib2/wgrib2
 Data date/time    : 99999999  
 Forecast hour     : 99999999  
 3D variables: UGRD      VGRD      TMP       HGT       RH        
 2D variables:


forrtl: severe (59): list-directed I/O syntax error, unit -5, file Internal List-Directed Read
Image              PC        Routine            Line        Source             
fdgrib2            08076240  Unknown               Unknown  Unknown
fdgrib2            08074C94  Unknown               Unknown  Unknown
fdgrib2            08057847  Unknown               Unknown  Unknown
fdgrib2            0804BFA2  Unknown               Unknown  Unknown
fdgrib2            0804A827  Unknown               Unknown  Unknown
libc.so.6          B72E94D3  Unknown               Unknown  Unknown

fdgrib2 进程在 grib_get.f90 上的命令处完成

  [fortran] call tokenize_ws(lines(1),tokens,ntok)
   nb = index(tokens(1),'=')+1
   ne = len_trim(tokens(1))
   read(tokens(1)(nb:ne),*) longdate [/fortran]

我不是专业的 Fortran 程序员,所以我不知道如何处理这个问题。任何帮助将不胜感激。

提前致谢

编辑 1

添加了打印语句来定位错误出现的时间

   call tokenize_ws(lines(1),tokens,ntok)
   nb = index(tokens(1),'=')+1
   ne = len_trim(tokens(1))

print*,'P3'
print *,lines(1)
print *,tokens(1)
print *,tokens(1)(nb:ne)

read(tokens(1)(nb:ne),*) 长日期

打印*,'P4'

和输出(通过 P3 但未到达 P4)。 2014012000是输入数据文件的正确日期和时间

 P3
 1.1:0:d=2014012000
 1.1:0:d=2014012000
 2014012000

forrtl: severe (59): list-directed I/O syntax error, unit -5, file Internal List-Directed Read
Image              PC        Routine            Line        Source             
fdgrib2            080761C0  Unknown               Unknown  Unknown

编辑 2

tokenize.f90中子程序tokenize_ws的代码

subroutine tokenize_ws(str,tokens,ntok)

implicit none

integer :: ntok
character(len=*) :: str,tokens(*)
character(len=1) :: sep,tab

integer :: ntokmax=100,npt,nch,nc,ntbeg,ntend,n

! this routine "parses" character string str into different pieces
! or tokens by looking for  possible token separators (toks
! str contains nch characters.  the number of tokens identified is nto
! the character string tokens are stored in tokens.

! Modified 12/11/07: this version tokenizes by white space (spaces and tabs)
sep = char(32)
tab = char(9)

ntok=0
npt=1
nch=len_trim(str)
nc=1
do ntok=1,ntokmax
   do n=nc,nch
      if(str(n:n) /= sep .and. str(n:n) /= tab) then
         ntbeg=n
         goto 21
      endif
   enddo
   21 continue
   do n=ntbeg,nch
      if(str(n:n) == sep .or. str(n:n) == tab) then
         ntend=n-1
         goto 22
      endif
      if(n == nch) then
         ntend=n
         goto 22
      endif
   enddo
   22 continue
   tokens(ntok)=str(ntbeg:ntend)
   nc=ntend+1
   if(nc.ge.nch) goto 25
enddo

25 continue

return
end

编辑 3

添加源代码和输入文件(linux tar 文件)

http://ubuntuone.com/5tL2IO8OV5dBxhs18kt1WI

http://ubuntuone.com/1meYXbBuBt1Rxcx4ODMzVp

编辑 4

编译选项的输出 -traceback -warn -check

log file

和模型运行的输出

2014012000

       9          19 forrtl: severe (59): list-directed I/O syntax error, unit -5, file Internal List-Directed Read Image              PC

常规线路源 fdgrib2
080942C0 Unknown Unknown Unknown fdgrib2
08092D14 未知 未知 未知 fdgrib2
0806F822 grib_get_mod_mp_g 291 grib_get.f90 fdgrib2
08051CD0 MAIN__ 130 dgrib.f90 fdgrib2
0804A757 Unknown Unknown Unknown libc.so.6
B72CF4D3 未知 未知 未知

编辑 5

read(tokens(1)(nb:ne),*) longdate(字符9 到19)更改为read(tokens(1)(nb:ne-1),*) (chars 9 to 18) longdate 后,它似乎正确读取longdate,预期值为2014012000。但随后出现另一个错误,当我发布此信息时,我将继续寻找解决方案。 fdgrib2 是 grib2 文件的“相对较旧”的读取代码,但它工作并且应该仍然工作,我的错。感谢您的帮助。

print*,'P3'
print *,lines(1)
print *,tokens(1)
print *,tokens(1)(nb:ne)
print *,nb,ne
read(tokens(1)(nb:ne-1),*) longdate
print*,'P4'
print*,'ddd:', longdate

P3
 1.1:0:d=2014012000
 1.1:0:d=2014012000
 2014012000
          9          19
 P4
 ddd:  2014012000
 1--1.1:0:scan=0 input=WE:NS output=WE:SN:grid_template=0:winds(N/S):
--
 ppp0:           0         360         181 lat-lon             
 ppp0:  0.0000000E+00  0.0000000E+00  0.0000000E+00  0.0000000E+00
forrtl: severe (59): list-directed I/O syntax error, unit -5, file Internal List-Directed Read
Image              PC        Routine            Line        Source             
fdgrib2            08094350  Unknown               Unknown  Unknown
fdgrib2            08092DA4  Unknown               Unknown  Unknown
fdgrib2            0806D724  grib_get_mod_mp_g         219  grib_get.f90
fdgrib2            08051D20  MAIN__                    132  dgrib.f90
fdgrib2            0804A757  Unknown               Unknown  Unknown
libc.so.6          B72984D3  Unknown               Unknown  Unknown

【问题讨论】:

  • 由于你使用的是intel Fortran编译器,是否可以通过添加-traceback来开启回溯?这将帮助您了解程序在做什么以及它在哪里死亡。一般来说,这个标志的性能损失是如此之小,它的实用性如此之大,我总是用它来运行。此外,编译时和运行时检查也可能有所帮助:尝试将 -warn 和 -check 添加到编译和链接标志。
  • 嗨@zbeekman,我听从了你的建议并再次编译。还有更多消息但我找不到任何相关信息(至少我不能,也许其他人会看到)。日志文件可以在问题中 EDIT 4 的 URL 中找到
  • 您是否尝试使用列表导向输入从字符变量内部读取切片9:19?如果是这样,请考虑该切片中有多少个字符,以及数字 2014012000 中有多少个字符。
  • 我不会在互联网上追逐你的问题。如果您希望我查看新错误,请在此处发布足够的信息,以便我有很好的诊断机会。
  • 此问答时间过长,无法跟进。要么完全重写问题,要么问另一个问题。请注意,您的“新”错误实际上是在输入文件的不同位置出现的旧错误。其诊断和治疗很可能与前次发生的诊断和治疗相同。就我个人而言,我认为您对标记化和列表导向 i/o 的使用是不匹配的,您应该使用其中一个。我注意到您声称自己不是开发人员,但是一旦您提出有关代码的问题,您就成为了开发人员。

标签: fortran intel-fortran


【解决方案1】:

如果您还没有这样做,请修复编译器引发警告的原因。 sn-p

ichar(tokens(1))

将一个长度为 20 的字符变量传递给 ichar,它需要一个长度为 1 的变量。

我不明白这会如何导致您以后出现问题,但在尝试修复神秘错误时,抓住每一根稻草通常是个好主意。

【讨论】:

  • 是的,我评论说这无关紧要。
  • 但是如果发生了一些令人讨厌的堆栈损坏没人知道。
  • 我应该如何解决这个问题?我不是专家级程序员。
  • tokens(1)(1:1) 是单个字符。
【解决方案2】:

检查输入文件,特别是崩溃时代码当前正在处理的位置。从 tokens(1)(nb:ne) 读取 longdate 时存在一些问题,它们是由行 (1) 制成的。您可以添加一些打印语句以使其更清晰:

    print *,lines(1)
    print *,tokens(1)
    print *,tokens(1)(nb:ne)

另外,不要担心警告。这不是一段好的代码,但它在一个打印语句中,所以它只是将一些没有很好定义的东西打印到标准输出中。

【讨论】:

  • 我会尽力让你知道结果。谢谢。
  • 请看一下带有打印语句输出的编辑问题@vladimir-f
  • longdate 是如何定义的?我玩整数标量,它工作正常。不就是一个数组吗?
  • integer :: nx,ny,nrec,iscan,longdate
  • 对此我很困惑,只要检查nbne是否有正确的值,但似乎是这样。我正在我的电脑上试用它,它适用于nb = 9ne = 19
【解决方案3】:

感谢所有试图提供帮助的人。终于可以成功了。

我的问题来自未针对英特尔编译器优化的旧软件,因此在读取 grib2 文件时会出现此类错误消息(GRIB2 是气象学中使用的格式)。其实已经上传了一个新版本的软件,我可以成功编译运行了。

再次感谢

【讨论】:

    猜你喜欢
    • 2015-05-05
    • 1970-01-01
    • 2016-01-05
    • 1970-01-01
    • 1970-01-01
    • 2017-04-16
    • 2018-11-03
    • 1970-01-01
    • 2019-02-27
    相关资源
    最近更新 更多