Я пытался использовать f2py для взаимодействия оптимизированного кода Fortran для векторного и матричного умножения с Python.Чтобы получить сравнение производительности, полезное для моих целей, я выполняю один и тот же продукт внутри цикла 100000 раз.С полным кодом Fortran продукт занимает 2,4 секунды (ifort), в то время как с F2py это занимает около 11 секунд.Просто для справки, с NumPy это занимает около 20 секунд.Я прошу и фортран, и часть Python записать разницу во времени до и после цикла, и с помощью f2py они пишут по 11 секунд, поэтому код не теряет время при передаче массивов.Я пытался понять, является ли это способом хранения массива numpy, но я не могу понять проблему.Есть ли у вас какие-либо идеи?Заранее спасибо
fortran Main
program Main
implicit none
save
integer :: seed, i, j, k
integer, parameter :: states =15
integer, parameter :: tessere = 400
real, dimension(tessere,states,states) :: matrix
real, dimension(states) :: vector
real :: start, finish
real :: prod(tessere)
do i=1,tessere
do j=1,states
do k=1,states
matrix(i,j,k) = i+j+k
end do
enddo
end do
do i=1,states
vector(i) = i
enddo
call doubleSum(vector,vector,matrix,states,tessere,prod)
end program
подпрограмма fortran:
subroutine doubleSum(ket, bra, M , states, tessere,prod)
integer :: its, j, k,t
integer :: states
integer :: tessere
real, dimension(tessere,states,states) :: M
real, dimension(states) :: ket
real, dimension(states) :: bra
real, dimension(tessere) :: prod
real,dimension(tessere,states) :: ctmp
call cpu_time(start)
do t=1,100000
ctmp=0.d0
do k=1,states
do j=1,states
do its=1,tessere
ctmp(its,k)=ctmp(its,k)+ M(its,k,j)*ket(j)
enddo
enddo
enddo
do its=1,tessere
prod(its)=dot_product(bra,ctmp(its,:))
enddo
enddo
call cpu_time(finish)
print '("Time = ",f6.3," seconds.")',finish-start
end subroutine
скрипт python
import numpy as np
import time
import cicloS
M= np.random.rand(400,15,15)
ket=np.random.rand(15)
#M=np.asfortranarray(M)
#ket=np.asfortranarray(ket)
import time
start=time.time()
prod=cicloS.doublesum(ket,ket,M)
end=time.time()
print(end-start)
.pyf, созданный с помощью f2py иотредактировано
! -*- f90 -*-
! Note: the context of this file is case sensitive.
python module cicloS
interface
subroutine doublesum(ket,bra,m,states,tessere,prod)
real dimension(states),intent(in) :: ket
real dimension(states),depend(states),intent(in) :: bra
real dimension(tessere,states,states),depend(states,states),intent(in) :: m
integer, optional,check(len(ket)>=states),depend(ket) :: states=len(ket)
integer, optional,check(shape(m,0)==tessere),depend(m) :: tessere=shape(m,0)
real dimension(tessere),intent(out) :: prod
end subroutine doublesum
end interface
end python module cicloS