ошибка сегментации при решении большой системы линейных уравнений с использованием скальпека ПДГЭСВ - PullRequest
2 голосов
/ 30 мая 2019

Параллельный код Фортрана, который решает систему линейных одновременных уравнений Ax = b с использованием подпрограммы скальпека PDGESV, завершается с ошибкой (выход с ошибкой сегментации), когда нет.уравнений, N, становится большим.Я не определил точное значение N, при котором возникают проблемы, но, например, код отлично работает для всех значений, которые я тестировал до N = 50000, но не работает при N = 94423.

В частности, сбой происходит во время вызова подпрограммы скальпека PDGESV (т.е. не при выделении / освобождении памяти);он входит в процедуру PDGESV, но не выходит из этой процедуры.

Я работаю над системой Linux Mint 18.3 Sylvia с 148 ГБ памяти, используя процессор Intel® R Xeon® R E5-1660 v4.@ 3,20 ГГц процессор.Я использую mpifortran, используя gfortran.

Я в некоторой степени уверен, что нет проблем с самим кодом Fortran, так как код отлично работает для всех значений N и конфигурации процесса, которые у меня естьпопытался до N = 50000, выход с кодом INFO = 0, который указывает, что ошибок не было.(Я также запустил слегка модифицированную версию программы, которая явно проверила остаток для матрицы решений x *, то есть вычислила Ax * - b и нашла, правильно, максимальные абсолютные значения, близкие к нулю).Если бы была какая-то проблема с матрицей единственного числа, мы, конечно, вместо этого наблюдали бы выход из процедуры PDGESV с ненулевым кодом INFO.

Памяти машины также, кажется, достаточно ;для проблемного случая N = 94423 нам требуется только 65 ГБ памяти по сравнению с доступной 148 ГБ памяти, и во время выделения нет проблем (более того, последовательный код, решающий ту же проблему и использующий память 65 ГБ, работает без ошибок).

У меня такое ощущение, что вместо этого есть некоторая проблема, возможно, превышающая некоторый предел по умолчанию для того, какая память доступна для одного процесса в mpi?то есть, возможно, я просто пропускаю некоторые соответствующие флаги во время компиляции / выполнения?

Я пытался использовать команду 'ulimit -s unlimited', но это не решило проблему.

Я копируюкод Фортрана ниже;это простая тестовая программа, которая 1) выделяет место для матрицы A и вектора b, 2) заполняет их записи случайными записями 3) вызывает PDGESV и затем 4) освобождает память.

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

Примечание. Я также пытался использовать компилятор PGI fortran и наблюдал ту же ошибку в том же тестовом примере.(см. вывод ошибок ниже).

Код Fortran:

      PROGRAM SOLVE_LU
      USE MPI
      IMPLICIT NONE
      INTEGER :: N
      DOUBLE PRECISION, ALLOCATABLE, DIMENSION(:,:) :: LOCAL_A
      DOUBLE PRECISION, ALLOCATABLE, DIMENSION(:) :: LOCAL_B 
      INTEGER :: ISTATUS
C     FOR LAPACK PDGESV CALL
      INTEGER  :: INFO,  NRHS, IA, JA, IB, JB
      INTEGER, ALLOCATABLE, DIMENSION (:) :: IPIV
c     FOR READING COMMAND LINE ARGUMENTS
      INTEGER :: IARGC, N_COMMAND_ARG
      CHARACTER :: ARGV*10 
C     WE USE FOLLOWING COMMAND LINE ARGUMENTS 
C     ARG 1 : N (DIMENSION OF PROBLEM)
C     ARG 2 : NPROW (NO. OF ROWS OF PROCESSES IN A RECTANGULAR ARRAY)
C     ARG 3 : NPCOL (NO. OF COLUMNS OF PROCESSES IN A RECTANGULAR ARRAY)
C     ARG 4 : BLACS BLOCK SIZE MB (BLOCKS ARE OF SIZE MB * MB) 
C   
c     FOR PARALLEL PROCESS ARRAY
      INTEGER  :: NPROW, NPCOL, ICTXT,MYROW, MYCOL, MB, NB, MLOC, NLOC
      INTEGER :: IDESCA(9), IDESCB(9)
      INTEGER :: IERR
      INTEGER :: NUMROC


c     for random number seed
      INTEGER :: ISEEDSIZE
      INTEGER, ALLOCATABLE, DIMENSION ( :) :: SEED

C      ----------------------------------------
C      -------  EXECUTABLE STATEMENTS   -------


C      ===============================================
C      READ IN COMMAND LINE ARGUMENTS IF PRESENT

      N_COMMAND_ARG = iargc()
      IF (N_COMMAND_ARG == 2) THEN
          WRITE(*,*) 'ILLEGAL NO. OF COMMAND LINE PARAMETERS'
          STOP
      ENDIF
      IF (N_COMMAND_ARG .GE. 1)THEN
          CALL GETARG(1,argv)
C          WRITE(*,*)'ARGV = ',ARGV
          READ (ARGV,'(I10)') N
      ELSE
          N = 100
      ENDIF   

      IF (N_COMMAND_ARG .GE. 3)THEN
          CALL GETARG(2,argv)
          READ (ARGV,'(I10)') NPROW
          CALL GETARG(3,argv)
          READ (ARGV,'(I10)') NPCOL

      ELSE
          NPROW = 2
          NPCOL = 2
      ENDIF 

      IF (N_COMMAND_ARG .GE. 4)THEN
          CALL GETARG(4,argv)
          READ (ARGV,'(I10)') MB
      ELSE
          MB = 8
      ENDIF
      NB = MB

C     ==============================================
C     INITIALISE THE BLACS PROCESS GRID, FIND DIMENSIONS OF LOCAL
C     MATRICES / VECTORS AND ALLOCATE SPACE

      CALL SL_INIT(ICTXT, NPROW, NPCOL)
      CALL BLACS_GRIDINFO( ICTXT, NPROW, NPCOL, MYROW, MYCOL )

      MLOC = NUMROC(N, MB, MYROW, 0, NPROW)
      NLOC = NUMROC(N, NB, MYCOL, 0, NPCOL)

      IF( MYROW.EQ.0 .AND. MYCOL.EQ.0 )WRITE(*,*)
     @       'WE ARE SOLVING A SYSTEM OF ', N, ' LINEAR EQUATIONS'

      WRITE(*,*) 'PROC: ',MYROW, MYCOL,'HAS  MLOC, NLOC =', MLOC,NLOC

c      ==============================================
C     ALLOCATE SPACE FOR MATRIX A AND VECTORS B AND X

      WRITE(*,*) 'PROC: ',MYROW, MYCOL,' ALLOCATING SPACE ...'

      ALLOCATE ( LOCAL_A(MLOC,NLOC), STAT = ISTATUS )
      IF(ISTATUS .NE. 0) THEN
          WRITE(*,*)'UNABLE TO ALLOCATE LOCAL_A, PROCESS: ',MYROW,MYCOL
          STOP
      ENDIF

      ALLOCATE ( LOCAL_B(MLOC), STAT = ISTATUS )
      IF (ISTATUS /= 0) THEN
          WRITE(*,*)
     @ ' FAILED TO ALLOCATE SPACE FOR LOCAL_B, PROCESS: ',MYROW,MYCOL
          STOP
      ENDIF

c     BLACS DESCRIPTOR FOR A AND ITS COPY
      CALL DESCINIT (IDESCA, N, N, MB, NB, 0, 0,
     @               ICTXT, MLOC, IERR)


c     BLACS DESCRIPTOR FOR B AND SOLN VECTOR X
      CALL DESCINIT (IDESCB, N, 1, MB, 1, 0, 0, ICTXT, MLOC, IERR)  

c      ==============================================
C      FILL ENTRIES OF MATRIX A AND R.H.S. VECTOR B WITH RANDOM ENTRIES

      WRITE(*,*)'PROC: ',MYROW, MYCOL,
     @        ' CONSTRUCTING MATRIX A AND RHS VECTOR B ...'

      CALL RANDOM_SEED

      CALL RANDOM_SEED ( SIZE = ISEEDSIZE ) ! GET SIZE OF SEED ARRAY

      ALLOCATE ( SEED(1:ISEEDSIZE) )
      CALL RANDOM_SEED ( GET = SEED )

      SEED(1) = SEED(1) + NPCOL*MYROW + MYCOL ! ENSURES DIFFERENT SEED
                                              ! FOR EACH PROCESS
      CALL RANDOM_SEED ( PUT = SEED )

      CALL RANDOM_NUMBER(LOCAL_B)

      CALL RANDOM_NUMBER(LOCAL_A)

c      ==============================================
C      CALL LAPACK LU SOLVER ROUTINE

      WRITE(*,*)'PROC: ',MYROW, MYCOL,
     @    'NOW SOLVING SYSTEM AX = B USING SCALAPACK PDGESV ..'
      ALLOCATE ( IPIV(MLOC + MB), STAT=ISTATUS )
      IF(ISTATUS /= 0) THEN
          WRITE(*,*)'UNABLE TO ALLOCATE IPIV, PROCESS: ',MYROW,MYCOL
          STOP
      ENDIF


      IA = 1
      JA = 1
      IB = 1
      JB = 1
      NRHS = 1
      INFO = 0

      CALL PDGESV(N, NRHS, LOCAL_A, IA, JA, IDESCA, IPIV, 
     @            LOCAL_B, IB, JB, IDESCB, INFO )

      IF( MYROW.EQ.0 .AND. MYCOL.EQ.0 ) THEN
          WRITE(*,*)
          WRITE(*,*) 'INFO code returned by PDGESV = ', INFO
          WRITE(*,*)
      END IF


c      ==============================================
C     DEALLOCATE MEMORY
      DEALLOCATE(LOCAL_A, STAT=ISTATUS)
      IF(ISTATUS /= 0) THEN
          WRITE(*,*)'UNABLE TO DEALLOCATE ' 
          STOP
      ENDIF   


      DEALLOCATE(LOCAL_B, STAT=ISTATUS)
      IF(ISTATUS /= 0) THEN
          WRITE(*,*)'UNABLE TO DEALLOCATE ' 
          STOP
      ENDIF   


      DEALLOCATE(IPIV, STAT=ISTATUS)
      IF(ISTATUS /= 0) THEN
          WRITE(*,*)'UNABLE TO DEALLOCATE ' 
          STOP
      ENDIF   

c     ===================================================
c     RELEASE BLACS CONTEXT

      CALL BLACS_GRIDEXIT(ictxt)
      CALL BLACS_EXIT(0)


      END PROGRAM SOLVE_LU

Я скомпилировал приведенный выше код с помощью: mpifort -Wall -mcmodel = medium -static-libgfortran -m64 / opt/openblas/lib/libopenblas.a /usr/local/lib/libscalapack.a /opt/openblas/lib/libopenblas.a -lm -lpthread -lgfortran -lm -lpthread -lgfortran -o para.exe solve_by_lu_parallelpt.for_for_libloss.o/openblas/lib/libopenblas.a /usr/local/lib/libscalapack.a /opt/openblas/lib/libopenblas.a -lm -lpthread -lgfortran -lm -lpthread -lgfortran

, которая не выдает ошибокили предупреждения, и запустите его с (например):

mpirun -n 4 ./para.exe 944 2 2 32> DUMP05

Где здесь мы решаем систему из 944 уравнений, используя2x2 массив процессов BLACS с размером блока 32.

Для этого небольшого случая Nмы получаем (успешное выполнение) вывод:

МЫ РЕШАЕМ СИСТЕМУ 944 ЛИНЕЙНЫХ УРАВНЕНИЙ

PROC: 0 0 HAS MLOC, NLOC = 480 480

PROC: 00 РАСПРЕДЕЛИТЕЛЬНОЕ ПРОСТРАНСТВО ...

ПРОЦЕСС: 1 0 ИМЕЕТ MLOC, NLOC = 464 480

ПРОЦЕСС: 1 0 РАСПРЕДЕЛИТЕЛЬНОЕ ПРОСТРАНСТВО ...

ПРОЦ.ВЕКТОР А И RHS B ...

ПРОЦЕСС: 10 0 СТРОИТЕЛЬНАЯ МАТРИЦА ВЕКТОР А И RHS B ...

PROC: 1 1 ИМЕЕТ MLOC, NLOC = 464 464

PROC: 1 1 РАСПРЕДЕЛИТЕЛЬНОЕ ПРОСТРАНСТВО ...

PROC: 1 1 СТРОИТЕЛЬНАЯ МАТРИЦА А И RHS ВЕКТОР B ...

PROC: 0 1 ИМЕЕТ MLOC, NLOC = 480 464

PROC: 0 1 РАСПРЕДЕЛИТЕЛЬНОЕ ПРОСТРАНСТВО ...

PROC: 0 1 СТРОИТЕЛЬНАЯ МАТРИЦА А И RHS ВЕКТОР B ...

PROC: 0 0 СЕЙЧАС РЕШЕНИЕ СИСТЕМЫ AX = B С ИСПОЛЬЗОВАНИЕМ SCALAPACK PDGESV

.. PROC: 1 0 СЕЙЧАС РЕШЕНИЕ СИСТЕМЫ AX = B ИСПОЛЬЗОВАНИЕ SCALAPACK PDGESV

.. PROC: 1 1 СЕЙЧАС РЕШЕНИЕ СИСТЕМЫ AX = B С ИСПОЛЬЗОВАНИЕМ SCALAPACK PDGESV

.. ПРОЦЕСС: 0 1 СЕЙЧАС РЕШЕНИЕ СИСТЕМЫ AX = B ИСПОЛЬЗОВАНИЕ SCALAPACK PDGESV

..

Код INFO возвращенпо PDGESV = 0

Пока все хорошо.Однако вместо этого при запуске:

mpirun -n 4 ./para.exe 94423 2 2 32> DUMP06

выдает следующую ошибку (обратите внимание, что для такого выполнения требуется 65 ГБ памяти и требуетсяоколо 45 минут на моей машине):

Программа получила сигнал SIGSEGV: Ошибка сегментации - недопустимая ссылка на память.

Программа получила сигнал SIGSEGV: Ошибка сегментации - недопустимая ссылка на память.

Программный полученный сигнал SIGSEGV: Ошибка сегментации - недопустимая ссылка на память.

Программный полученный сигнал SIGSEGV: Ошибка сегментации - недопустимая ссылка на память.

Программный полученный сигнал SIGSEGV: Ошибка сегментации - недопустимая ссылка на память.

Программный полученный сигнал SIGSEGV: Ошибка сегментации - недопустимая ссылка на память.

Программный полученный сигнал SIGSEGV: Ошибка сегментации - недопустимая ссылка на память.

Программный полученный сигнал SIGSEGV: Ошибка сегментации - недопустимая памятьссылка.

Обратный след для этой ошибки:

Backtrace для этой ошибки:

Backtrace для этой ошибки:

Backtrace для этой ошибки:

Backtrace для этой ошибки:

Backtrace для этой ошибки:

Backtrace для этой ошибки:

Backtrace для этой ошибки:

По какой-то причине информация о backtrace не печатается, но выполняется тот же код с компилятором PGI fortran (включендругой компьютер под управлением Red Hat Linux 7.3) выдает ошибку со следующим выводом:

[sca1993: 113193] * Обработка полученного сигнала *

[sca1993: 113193] Сигнал: Ошибка сегментации (11)

[sca1993: 113193] Код сигнала: Адрес не отображается (1)

[sca1993: 113193] Сбой по адресу: 0x2b8c5a036390

[sca1993: 113193] [0] /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../ .. /lib64/libpthread.so.0(+0xf5d0)[0x2b900528c5d0]

[sca1993: 113193] [1] /usr/local/pgi/linux86-64/17.7/lib/libblas.so.0(+0x280c950)[0x2b9003acc950]

[sca1993: 113193] [2] /usr/local/pgi/linux86-64/17.7/lib/libblas.so.0(daxpy_k_HASWELL+0x7f)[0x2b9003acc54f]

[sca1993: 113193] [3] / usr /local / pgi / linux86-64 / 17.7 / lib / libblas.so.0 (dger_k_HASWELL + 0xd5) [0x2b9003ad6635]

[sca1993: 113193] [4] / usr / local / pgi / linux86-64 /17.7 / lib / libblas.so.0 (dger_ + 0x21f) [0x2b90013d9f5f]

[sca1993: 113193] [5] ./para_try.exe[0x446e70]

[sca1993: 113193][6] ./para_try.exe[0x41b4ad]

[sca1993: 113193] [7] ./para_try.exe[0x4071e1]

[sca1993: 113193] [8] ./para_try.exe [0x406b39]

[sca1993: 113193] [9] ./para_try.exe[0x404ba6]

[sca1993: 113193] [10] ./para_try.exe[0x403654]

[sca1993: 113193] [11] /usr/lib/gcc/x86_64-redhat-linux/4.8.5 /../../../../ lib64 / libc.so.6 (__libc_start_main + 0xf5) [0x2b9005cb83d5]

[sca1993: 113193] [12] ./para_try.exe[0x403549]

[sca1993: 113193] * Сообщение об ошибке *

Если у кого-нибудь есть предложения, я был бы очень признателен. Большое спасибо, Dan.

...