РУКОВОДСВО ПОЛЬЗОВАТЕЛЯ ПО BLAS и LAPACK

Первое издание, Август 2000
Содержание руководства может пересматриваться без предварительного уведомления.
All Rights Reserved, Copyright FUJITSU LIMITED 2000
перевод Балуева А. Н.

Оглавление

  • 3. Пример программы, использующей п-б подпрограммы
  • 4. Компиляция и компоновка

    3. Пример программы, использующей п-б подпрограммы

    В начало страницы

    В разделе на простом примере описывается, как вызывать п-б подпрограммы BLAS и LAPACK из OpenMP Fortran-программы.

    3.1 Линейные уравнения

    3.1.1 Задача

    В начало страницы

    Рассмотрим систему линейных уравнений

    Ax = b

    где A есть вещественная полная матрица порядка n, b -- вектор правой части порядка n, а x --- вектор-решение. Для нас интересен случай, когда мы имеем много векторов правых частей, для каждого из которых нужно получить решение. Такая задача в матричной форме может быть записана как

    AX = B

    где каждый столбец из B , обозначаемый как bi ( i = 1,2,...,m) , представляет очередной вектор правой части, и каждый стобец из X, обозначаемый как xi ( i = 1,2,...,m) , есть вектор-решение, соответствующее bi

    3.1.2 Пример кода

    В начало страницы

    Вообще говоря, пользователь должен выбрать подпрограмму DGESV из LAPACK, подпрограмму-драйвер, для решения уравнений в приведенной выше матричной форме. Но в целях объяснения давайте воспользуемся родом компонентных подпрограмм DGETRF и DGETRS, которые называются вычислительными подпрограммами в руководстве по LAPACK. Первая из них вычисляет LU-факторизацию заданной матрицы коэффициентов A, а вторая решает факторизованную систему, находя решения X.

    Предположим, что мы хотим решить уравнения порядка 200 при 80 различных векторах правых частей. Сначала рассмотрим применение обычных, не поточно- безопасных BLAS и LAPACK. Пример такой программы приведен ниже, где подпрограмма inita устанавливает коэффициентную матрицу в массив a, матрица правых частей, состоящая из bi, устанавливается по заданным решениям, а подпрограмма check проверяет полученные опять решения xi на их точность.

    Пример с употреблением обычных, не п-б, BLAS и LAPACK

    implicit real*8 (a-h,o-z) 
    parameter(maxn=200,m=80,k=maxn+1) 
    parameter(zero=0.0d0,one=1.0d0) 
    real*8 a(k,maxn),aa(k,maxn),x(k,m),b(k,m) 
    integer ip(maxn)
    
    C	===========================================================
    C	Определение матрицы
    
    C	===========================================================
    n=maxn
    call inita(a,k,n)
    do i=1,n
    do j=1,n
    aa(j,i)=a(j,i)
    end do
    end do
    C	===========================================================
    C	LU-разложение
    C	===========================================================
    call dgetrf(n,n,a,k,ip,info) 
    C	===========================================================
    C	Определение векторов
    C	===========================================================
    do jm=1,m
    do jn=1,n
    x(jn,jm)=jn+jm
    end do
    end do
    call dgemm('N','N',n,m,n,one,aa,k,x,k,zero,b,k)
    C	===========================================================
    C	Решение
    C	===========================================================
    call dgetrs('N',n,m,a,k,ip,b,k,info)
    if(info.ne.0) then
    write(6,*) 'error in dgetrs   info = ',info
    stop
    end if
    C	===========================================================
    C	Проверка результата
    C	===========================================================
    call check(a,b,k,n,m)
    end
    

    Теперь воспользуемся п-б версией LAPACK. LU-факторизация производится так же, как и в рассмотренном примере, но процедура получения решения X немного отличается и мы хотим использовать кратные CPU. В следующем примере вызываются подпрограммы п-б версии LAPACK. 80 векторов правых частей разделяются на группы, каждая содержит одно и то же количество, mblk, векторов правых частей и эти группы передаются одновременно подпрограмме DGETRS. Заметим также, что начальная установка X для получения правых частей производится блоками посредством вызова поточно-безопасной подпрограммы DGEMM для умножения матриц.

    Пример BLAS, LAPACK п-б версии
    implicit real*8 (a-h,o-z)
    parameter(maxn=200,m=80,mblk=4,k=maxn) 
    parameter(zero=0.0d0,one=1.0d0) 
    real*8 a(k,maxn),aa(k,maxn),x(k,m),b(k,m) 
    integer ip(maxn)
    C	===========================================================
    C	Определение матрицы
    C	===========================================================
    n=maxn
    call inita(a,k,n)
    do i=1,n
    do j=1,n
    aa(j,i)=a(j,i)
    end do
    end do
    C	===========================================================
    C	LU-разложение
    C	===========================================================
    call dgetrf(n,n,a,k,ip,info)
    !$OMP PARALLEL PRIVATE(mb,info)
    !$OMP DO
    do i=1,m,mblk
    mb=min(mblk,m-i+1)
    C	===========================================================
    C	Определение векторов
    C	===========================================================
    do jm=1,mb
    do jn=1,n
    x(jn,jm+i-1)=jn+i+jm-1
    end do
    end do
    call dgemm('N','N',n,mb,n,one,aa,k,x(1,i),k,zero
    &	,b(1,i),k)
    C	===========================================================
    C	Решение
    C	===========================================================
    call dgetrs('N',n,mb,a,k,ip,b(1,i),k,info) 
    if(info.ne.0) then
    write(6,*) 'error in dgetrs   info = ',info
    stop
    end if
    end do
    !$OMP END PARALLEL
    C	===========================================================
    C	Проверка результата
    C	===========================================================
    call check(a,b,k,n,m)
    end
    
    Пояснения

    1. Пара директив !$OMP PARALLEL и !$OMP END PARALLEL определяют область параллельности, код между этими директивами выполняется параллельно кратными потоками. Директива !$OMP PARALLEL создает группу кратных потоков, а предложение PRIVATE(...) указывает, что переменные или массивы в скобках располагаются в своей копии памяти в каждом потоке. Переменные и массивы, которые не фигурируют в предложении PRIVATE, имеют только одну копию, разделяемую всеми потоками в параллельной части.

    2. Директива !$OMP DO указывает, что конструкция DO, расположенная сразу после директивы, может исполняться параллельно по отношению к параметру DO в кратных потоках. Другими словами, вычисления для каждого значения параметра DO производятся в потоке асинхронно по отношению к остальным потокам.

    3. Более важной характеристикой является то, что приведенный выше код может компилироваться без параметра --openmp, компоноваться с библиотеками BLAS и LAPACK и затем правильно работать, выдавая те же результаты, хотя его исполнение будет итти дольше. Это происходит потому, что в таком случае директивы OpenMP рассматриваются как комментарии и выполняемые операторы Fortran ничем не отличаются от обычных конструкций Fortran.

    4. Компиляция и компоновка

    В начало страницы

    Поточно-безопасные версии BLAS и LAPACK должны вызываться из OpenMP Fortran программ. Компиляция должна производиться с помощью компилятора Fujitsu Fortran. В настоящем разделе описываются процедуры компиляции таких программ. Пользователи, использующие подпрограммы и BLAS и LAPACK, должны следовать указаниям радела "4.2 Поточно-безопасная версия LAPACK", а подпрограммы BLAS могут компоноваться неявно.

    4.1 Поточно-безопасная версия BLAS

    В начало страницы

    BLAS можно использовать компоновкой ее с пользовательскими программами, написанными на языке Fortran. Она компонуется с пользовательской программой при указании -lblasmt в командной строке для lf95. Пишите -lblasmt после исходных и объектных имен Fortran'а. Другие параметры, относящиеся к оптимизации, указываются по мере необходимости.

    Например: lf95 a.f -lblasmt

    Когда пользовательская программа написана с OpenMP Fortran API, требуется параметр --openmp.

    Например:lf95 --openmp a.f -lblasmt

    Исполнение программы производится указанием ее имени после приглашения. Количество создаваемых потоков может указываться переменной окружения OMP_NUM_THREADS. Нужно заметить, что при компиляции с параметром --openmp все массивы, используемые в программе пользователя, помещаются в области стека и может случиться, что стек превысит отведенные для него пределы. В таком случае пользователь может увеличить стек командой limit (в случае csh) или ulimit (в случаях sh или ksh).

    4.2 Поточно-безопасная версия LAPACK

    В начало страницы

    LAPACK может использоваться компоновкой ее с пользовательской программой, написанной на языке Fortran. Она присоединяется к пользовательской программе при указании -llapackmt в командной строке для lf95. Поскольку LAPACK вызывает BLAS, пишите -lblasmt после -llapackmt.

    Пример: lf95 a.f -llapackmt -lblasmt

    Если программа написана с OpenMP Fortran API, требуется параметр --openmp. Пример: lf95 --openmp a.f -llapackmt -lblasmt Рис. 1 показывает ход обработки программы пользователя, использующей BLAS и LAPACK, от компиляции до исполнения.

    Start
    |	--------------
    |   .........<....... |User Program|
    |   .	--------------
    ---------------
    |   Fortran   |
    |(compilation)|
    ---.-----------	-------------------
    .   |	|   BLAS library  |
    --------<...................   |	|	|
    |Object|.........>.......... | .........<...... | LAPACK library | ----- . | . | |
    ---------------	|  Fortran library|
    |   Fortran   |	-------------------
    |  (Linkage)  |
    --.------------
    ------------<...............    |
    |Executable|	|
    | program  |.........>......    |
    ------------	.    |
    -------------........>........: Data flow |(Execution)|------>------: Processing flow
    -------------
    |
    End
    
    
    Рис. 1 Ход обработки от компиляции до исполнения (BLAS, LAPACK)

<<< Оглавление Страницы: 3  4 >>>