Печать не будет работать внутри функции Fortran - PullRequest
0 голосов
/ 02 мая 2018

Я написал фортран-функцию для вызова функции blas уровня 3 sgemm. Я передаю матрицы для умножения на эту функцию и возвращаю результат. Код работает и результат также правильный. Но внутри есть оператор print, который ничего не печатает. Почему это происходит?

function matmul(A,B) result(C)
    real,dimension(:,:),allocatable::A
    real,dimension(:,:),allocatable::B
    real,dimension(:,:),allocatable::C

    integer::m,n,k

    m = size(A,1)
    n = size(A,2)
    k = size(B,2)

    print *,"INSIDE FN"

    call sgemm ('N','N',m,k,n,1.0,A,n,B,k,0.0,C,k)




end function matmul

1 Ответ

0 голосов
/ 04 мая 2018

Выбранное вами имя функции, MATMUL, является внутренней функцией Fortran (см. Раздел 13.7.105 стандарта Fortran или здесь ). Реализованная вами функция пытается «перегрузить / затенить» эту встроенную функцию с тем же именем. Это возможно в Фортране, но вы должны явно сообщить об этом компилятору. При составлении следующего кода:

function matmul(A,B) result(C)
  real,dimension(:,:),allocatable::A,B,C
  print *,"matmul overloaded"
  C=A
end function matmul

program test
  real, dimension(:,:), allocatable :: A,B,C
  allocate(A(1,1),B(1,1),C(1,1))
  C = matmul(A,B)
end program test

Программа test не знает о существовании и / или интерфейсе вашей собственной подпрограммы matmul. И программа test, и подпрограмма matmul живут в двух неподключенных программных блоках, и, как следствие, компилятор будет предполагать, что должна вызываться встроенная функция MATMUL.

EXTERNAL атрибут: (см. STDF2003 :: 5.3.9 )

Поскольку компилятор не имеет механизма доступа к пользовательскому коду matmul из программного блока test, его интерфейс неявный . Если вы хотите указать, что имя matmul является именем внешней или фиктивной процедуры, мы можем использовать оператор external:

program test
  external :: matmul
  real, dimension(:,:), allocatable :: A,B,C
  allocate(A(1,1),B(1,1),C(1,1))
  C = matmul(A,B)
end program test

INTERFACE блок: (см. STDF2003 :: 12,4 )

С атрибутом external вы просто указываете, что matmul является внешней или фиктивной процедурой. Он не указывает интерфейс, который остается неявным. Интерфейс, однако, может быть определен с помощью блока интерфейса как

program test
  real, dimension(:,:), allocatable :: A,B,C
  allocate(A(1,1),B(1,1),C(1,1))

  interface
    function matmul(A,B) result(C)
      real,dimension(:,:),allocatable::A,B,C
    end function matmul
  end interface

  C = matmul(A,B)
end program test

Последнее автоматически достигается при помещении функции matmul в модуль и использовании этого модуля.

примечание: информация, свободно принятая из Modern Fortran Explained, M. Меткалф, Дж. Рейд и М. Коэн , (Оксфорд, 2013)

...