Nano Hash - криптовалюты, майнинг, программирование

Приложение выдает ошибку сегментации через некоторое время при вызове процедуры (содержащей локальные массивы) в цикле

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

! Test local coarray in procedure called in a loop.
!
program main
    use, intrinsic :: iso_fortran_env, only : input_unit, output_unit, error_unit

    implicit none

    ! Variable declaration.
    integer :: me, ti
    integer :: GHOST_WIDTH, TSTART, TSTEPS

    sync all

    ! Initialize.
    GHOST_WIDTH = 1
    TSTART = 0
    TSTEPS = 100000
    me = this_image()

    ! Iterate.
    do ti = TSTART + 1, TSTART + TSTEPS
        call Aldeal( GHOST_WIDTH )
        if ( me == 1 ) write( output_unit, * ) ti
    end do

    if ( me == 1 ) write( output_unit, * ) "All done!"

    contains
        subroutine Aldeal( width )
            integer, intent(in) :: width

            integer, allocatable, codimension[:] :: shell1_Co, shell2_Co, shell3_Co

            allocate( shell1_Co[*], shell2_Co[*], shell3_Co[*] )

            deallocate( shell1_Co, shell2_Co, shell3_Co )

            return
        end subroutine Aldeal
end program main

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

forrtl: severe (174): SIGSEGV, segmentation fault occurred
In coarray image 1
Image              PC                Routine            Line        Source             
coarray_main       0000000000406063  Unknown               Unknown  Unknown
libpthread-2.17.s  00007F21D8B845F0  Unknown               Unknown  Unknown
libicaf.so         00007F21D90970D5  for_rtl_ICAF_CO_D     Unknown  Unknown
coarray_main       0000000000405054  main_IP_aldeal_            37  coarray_main.f90
coarray_main       0000000000404AEC  MAIN__                     23  coarray_main.f90
coarray_main       0000000000404A22  Unknown               Unknown  Unknown
libc-2.17.so       00007F21D85C5505  __libc_start_main     Unknown  Unknown
coarray_main       0000000000404929  Unknown               Unknown  Unknown

Abort(0) on node 0 (rank 0 in comm 496): application called MPI_Abort(comm=0x84000003, 0) - process 0

И та же ошибка повторяется и для других изображений.

Строка 23 находится call Aldeal( GHOST_WIDTH ) внутри цикла do основной программы. А строка 37 соответствует оператору deallocate( shell1_Co, shell2_Co, shell3_Co ) в подпрограмме.

Кроме того, если я удаляю оператор освобождения из подпрограммы, она выдает ту же ошибку, но номера строк в операторе ошибки на этот раз равны 23 и 39. Строка 39 соответствует оператору end subroutine Aldeal.

Я не могу понять, что именно я делаю неправильно. Пожалуйста помоги.

P.S. Я использую Centos 7 с Intel(R) Parallel Studio XE 2019 Update 4 для Linux.


  • В подобных случаях обычно лучше обратиться за помощью к поставщику компилятора. Я предлагаю размещать сообщения на форумах Intel или использовать ваш контракт на поддержку. (Также не работает бета-версия для следующего выпуска.) 22.09.2019
  • Успешно работает до конца с GNU Fortran 9.2 + OpenCoarrays 2.7.1 + Open MPI 4.0.1. 22.09.2019
  • @francescalus, спасибо. Ранее я задавал вопрос на форуме Intel. Но этот пост еще не опубликован. Поэтому я решил опубликовать его здесь, надеясь, что вместо этого я смогу получить некоторую помощь здесь. 22.09.2019
  • Правильно @jacob. Он отлично работает при компиляции с помощью gfortran. Но моя проблема в том, что в CentOS отсутствует поддержка opencoarrays. Поэтому я застрял с компилятором Intel Fortran. 22.09.2019
  • В качестве обходного пути (если он подходит) вы можете сделать coarrays локальными переменными (с атрибутом SAVE) и вести всю необходимую бухгалтерию. 23.09.2019
  • Боюсь, я не смогу добавить атрибут сохранения к локальным массивам во всех подпрограммах, которые у меня есть. Комассивы — это не просто скалярные переменные. В большинстве случаев это 2D или 3D массивы. Если я это сделаю, скоро я потеряю память. Спасибо за предложение. 23.09.2019

Ответы:


1

Наблюдения:

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

module mod_coarray_error
    implicit none

    type :: int_t
        integer, allocatable, dimension(:) :: var
    end type int_t

    contains
        subroutine Aldeal_type( width )
            integer, intent(in) :: width

            type(int_t), allocatable, codimension[:] :: int_t_Co

            allocate( int_t_Co[*] )

            allocate( int_t_Co%var(width) )
            sync all

            ! deallocate( int_t_Co%var )
            deallocate( int_t_Co )

            return
        end subroutine Aldeal_type
end module mod_coarray_error


program main
    use, intrinsic :: iso_fortran_env, only : input_unit, output_unit, error_unit
    use :: mod_coarray_error

    implicit none

    ! Variable declaration.
    integer :: me, ti
    integer :: GHOST_WIDTH, TSTART, TSTEPS, SAVET

    sync all

    ! Initialize.
    GHOST_WIDTH = 3
    TSTART = 0
    TSTEPS = 100000
    SAVET = 1000
    me = this_image()

    ! Iterate.
    do ti = TSTART + 1, TSTART + TSTEPS
        sync all
        call Aldeal_type( GHOST_WIDTH )
        if ( mod( ti, SAVET ) == 0 ) then
            if ( me == 1 ) write( output_unit, * ) ti
        end if
    end do

    sync all

    if ( me == 1 ) write( output_unit, * ) "All done!"
end program main

Кроме того, этот код отлично работает до конца при компиляции в Windows.

Теперь, если я добавлю параметр компилятора heap-arrays 0, код будет работать до конца даже в Linux.

Пробовал увеличивать количество циклов, т.е. TSTEPS в коде до 1e7. Даже тогда он успешно работает до конца. Но я наблюдаю следующие эффекты:

  1. Код становится медленнее по мере увеличения числа циклов, т. е. требуется больше времени для выполнения от ti = 1e6 до ti = 2e6, чем время, необходимое для выполнения от ti = 1 до ti = 1e6.
  2. Память, используемая программой, продолжает увеличиваться, т. е. каждое изображение, которое потребляет 2GB в начале выполнения программы, потребляет 3.5GB в ti = 2e6, 4.7GB в ti = 4e6 и 6GB в ti = 6e6.
  3. Память, используемая программой, относительно меньше при работе в Windows, но она продолжает увеличиваться по мере увеличения количества циклов. Например, каждое изображение, которое потребляет 100MB при запуске, потребляет 1.5GB при ti = 2e6, 2.5GB при ti = 4e6 и 3.5GB при ti = 6e6.
  4. Использование опции компилятора /heap-arrays0 в Windows никак не влияет ни на прогон (так как он и без него успешно запускался), ни на количество потребляемой памяти при запуске.
  5. Исходный код, размещенный в вопросе, по-прежнему выдает ошибку даже при компиляции с использованием вышеуказанного параметра компилятора. В винде вроде тоже не запускается.

В конце концов, я все еще не понимаю, что происходит.

P.S. Я разместил вопрос на форуме Intel, но пока не получил ответа.

28.09.2019
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..