2015-06-03 6 views
0

В настоящее время я пытаюсь запустить свою модель климата с новыми метеорологическими данными (которые даны в формате netcdf вместо старого формата cray). Модель компилируется плавно, однако, когда настало время для моделирования, модель хорошо работает в первый день, но она останавливается во второй день симуляции, всегда на том же шаге, независимо от того, какую дату начала я использую. Ошибка:временной массив вне границ в моделировании?

forrtl: тяжелая (408): Форт: (2): Подстрочный # 1 из TIMEVALS массива имеет значение 141, которое больше, чем верхняя граница 140.

So Я провел некоторое исследование и просмотрел свой исходный код, чтобы узнать, к какому типу относятся периоды времени, и я узнал, что он относится к этим новым метеорологическим данным, которые имеют временное измерение, и такой массив времени состоит из 140 элементов. Каждый элемент представляет собой конкретную дату и время данных meteo, которые предполагается использовать модели для моделирования ... поэтому я начал полагать, что это проблема моего кода, но мой коллеж смог запустить модель без проблемы, которые были для меня странными. Он скомпилировал модель с некоторыми разными настройками в Makefile, я не знаю, имеет ли это значение, я все еще не очень хорошо знаком с fortran и т. Д. Однако ниже приведена часть кода, который использует этот массив TIMEVALS:

  CASE(2)  ! nudging data is in netcdf-format 

      cfile = str_filter(ndg_file_nc,yr,mo,dy,hr,mi,se,ndgblock) 
      CALL message(' Adjust date using file: ',TRIM(cfile)) 

      IF (p_parallel_io) THEN 
      INQUIRE(file=cfile,exist=found) 
      IF (.NOT.found) & 
       CALL finish('NudgingInit','Nudging data file not found.') 
      ndgfile%format = NETCDF 
      CALL IO_open (cfile, ndgfile, IO_READ) 
      CALL IO_INQ_DIMID(ndgfile%file_id, 'time', ndimid) 
      CALL IO_INQ_DIMLEN(ndgfile%file_id, ndimid, nts) 
      CALL IO_INQ_VARID(ndgfile%file_id, 'time', nvarid) 
      ALLOCATE (timevals(nts)) 
      CALL IO_GET_VAR_DOUBLE (ndgfile%file_id, nvarid, timevals) 
      ihead_nc(1) = FLOOR(timevals(1))       ! ihead_nc(1) is YYYYMMDD 
      ihead_nc(2) = INT((timevals(1)-ihead_nc(1))*24._dp)  ! ihead_nc(2) is HH 
      DEALLOCATE (timevals) 
      ENDIF 

      IF (p_parallel) CALL p_bcast(ihead_nc, p_io) 
      CALL inp_convert_date(ihead_nc(1),ihead_nc(2)*10000, ndg_date0) 

      IF (p_parallel_io) THEN 
      ! skip first record and read second header 
      ALLOCATE (timevals(nts)) 
      CALL IO_GET_VAR_DOUBLE (ndgfile%file_id, nvarid, timevals) 
      ihead_nc(1) = FLOOR(timevals(2))       ! ihead_nc(1) is YYYYMMDD 
      ihead_nc(2) = INT((timevals(2)-ihead_nc(1))*24._dp)  ! ihead_nc(2) is HH 
      DEALLOCATE (timevals) 
      CALL IO_close(ndgfile) 
      ENDIF 

      IF (p_parallel) CALL p_bcast(ihead_nc, p_io) 
      CALL inp_convert_date(ihead_nc(1),ihead_nc(2)*10000, ndg_date1) 

ndg_file и ndg_date относятся к подталкиванию (данные метеоданных) Есть ли у вас какие-либо идеи о том, что может вызвать эту ошибку?

+2

Вы пытаетесь получить доступ к 'timevals (141)', хотя 'timevals' имеет только 140 элементов. Об этом говорит компилятор. Однако этого не может быть в приведенном фрагменте кода. Здесь вы получаете доступ только к 'timevals (1)' и 'timevals (2)'. Отправьте соответствующий (строка) код, то есть строку, на которую жалуется компилятор! –

+0

Я не получаю никакой ошибки при компиляции кода. Я вижу ошибку только в файле журнала ошибок, который создается моей моделью при ее запуске. Сообщение об ошибке, которое я написал в верхней части первого сообщения, является единственным ключом, который у меня есть об этой проблеме. –

+1

Если вы скомпилируете модель с помощью -traceback (и, возможно, -g), вы должны получить трассировку стека, которая покажет вам, где сбой программы. – RussF

ответ

2

У меня есть время, чтобы подробно остановиться на моих предыдущих комментариях. (Обратите внимание, что я использую курсив, обозначаю термины, о которых вы, возможно, захотите прочитать.)

Ошибка, о которой вы сообщаете, является ошибкой во время выполнения, а не той, которую компилятор может видеть во время компиляции. Если вы не понимаете разницу между временем выполнения (т.е. при выполнении кода) и время компиляции (т.е. когда компилятор превращает ваши источники в исполняемый код) выполните некоторые исследования. Кроме того, очевидно, что вы (или кто-то) дал указание компилятору создать версию кода, которая проверяет, что обращения к элементам массива находятся в границах массива. Это очень важная функция безопасности при тестировании нового программного обеспечения, но налагает штраф за производительность, когда код выполняет так много кодов, как только они прошли свои тесты, скомпилированы без этой проверки.

Я не знаю, какой компилятор вы используете, но посмотрите на его документацию, чтобы найти параметр, который включает контроль границ массива во время выполнения.

Сообщение об ошибке довольно явное - в какой-то момент вашего кода он попытался получить доступ к элементу 141 массива, содержащего всего 140 элементов. Мы не можем сказать вам, как это произошло, возможно, даже если мы не увидели весь ваш код. Такие вещи часто возникают при загрузке данных, которые не соответствуют ожиданиям программиста. Это также часто случается, когда программисты делают по-одному ошибок в письмах. Мы могли бы заметить это, глядя на весь ваш код, но вы в гораздо лучшем положении, чтобы сделать это, чем мы.

Пишешь

, но мой коллега смог запустить модель без каких-либо проблем, которые было странно для меня.Он составил модель с некоторыми различными настройками в Makefile, я не знаю, если это имеет значение,

Ну, да, это имеет значение, это имеет большое значение. Если вы пишете код, который обращается к элементу 141 массива с 140 элементами Fortran, как и многие другие скомпилированные языки, с радостью будет получать доступ к следующему местоположению в памяти после элемента 140. В общем, вы не знаете, какие данные вмешивается в программу. Если вам повезло, следующее место в памяти находится за пределами адресного пространства, которое операционная система выделила программе, и операционная система немедленно остановит программу и сообщит об ошибке сегментации.

Если вам не повезло, программа продолжает блаженно читать и записывать элемент 141, как бы там ни было.

Я предполагаю, что ваш коллега не выполнил проверку границ своей версии кода. Вам решать, может ли он сказать ему, что его код (очень вероятно) сломан.

Итак, что вы делаете? Вы отладка программа. Вы можете сделать это различными способами, самым простым из которых является (по моему мнению) вставить некоторые операторы write для печати значений переменных в критических точках кода, чтобы проверить ваши предположения о том, какие значения они могут, могут или фактически делаю. Более трудным, но стоит первоначальных усилий в плане решения будущих проблем, было бы запустить код под управлением отладчика. Есть несколько хороших отладчиков, доступных для программ Fortran на всех основных платформах.

 Смежные вопросы

  • Нет связанных вопросов^_^