我想打开10,000个文件名从abc25000until 开始的文件abc35000,并将一些信息复制到每个文件中.我写的代码如下:
PROGRAM puppy
IMPLICIT NONE
integer :: i
CHARACTER(len=3) :: n1
CHARACTER(len=5) :: cnum
CHARACTER(len=8) :: n2
loop1: do i = 25000 ,35000 !in one frame
n1='abc'
write(cnum,'(i5)') i
n2=n1//cnum
print*, n2
open(unit=i ,file=n2)
enddo loop1
Run Code Online (Sandbox Code Playgroud)
结束
这段代码应该从abc24000直到开始生成文件,abc35000但它停止大约一半的说法
在test test-openFile.f90的第17行(unit = 26021,file ='')
Fortran运行时错误:打开的文件太多
我需要做些什么来修复上面的代码?
我正在尝试使用iso_c_bindings模块将Fortran 2003绑定写入CUFFT库,但我遇到cufftPlanMany子程序问题(类似于sfftw_plan_many_dftFFTW库).
绑定本身如下所示:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! cufftResult cufftPlanMany(cufftHandle *plan, int rank, int *n,
! int *inembed, int istride, int idist,
! int *onembed, int ostride, int odist,
! cufftType type, int batch)
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
interface cufftPlanMany
subroutine cufftPlanMany(plan, rank, n, &
inembed, istride, idist, &
onembed, ostride, odist, &
type, batch) &
& bind(C,name='cufftPlanMany')
use iso_c_binding
integer(c_int):: plan
integer(c_int),value:: rank, type, batch
integer(c_int):: n(*)
integer(c_int),value:: istride, idist, ostride, odist
integer(c_int):: inembed(*), onembed(*)
end subroutine cufftPlanMany
end …Run Code Online (Sandbox Code Playgroud) fortran compiler-errors gfortran fortran90 fortran-iso-c-binding
我试图提取一个大型fortran的一部分,使其成为自己的程序.一个特定的子程序导入了许多模块(这里只显示了两个模块):
subroutine myroutine(aa,bb)
use xx_module
use yy_module
...
end subroutine myroutine
Run Code Online (Sandbox Code Playgroud)
...从这些模块导入的部分中引入了许多变量.有没有一种好的方法(或好的工具)来找出哪个变量来自哪个模块,等等?或者我必须查看每个模块以查看每个模块的定义,然后分配(可能出现在不同的模块中......)?
在一些Fortran 95代码中,我有一个带指针字段的类型.我想声明一个模块变量type(foo)在编译时初始化.像这样的东西:
module foo_module
implicit none
type foo_type
integer :: x
logical, pointer :: x_flag => null()
end type foo_type
logical, target :: bar_flag
! this does not compile of course:
type(foo_type) :: bar = foo_type(1, bar_flag)
end module foo_module
Run Code Online (Sandbox Code Playgroud)
上面的代码片段无法编译.我知道我可以bar在运行时使用单独的子例程进行初始化,例如:
module foo_module
implicit none
type foo_type
integer :: x
logical, pointer :: x_flag => null()
end type foo_type
logical, target :: bar_flag
type(foo_type) :: bar
contains
subroutine init()
bar%x = 1
bar%x_flag => bar_flag
end …Run Code Online (Sandbox Code Playgroud) 当我使用Send/Recv时,我的代码可以工作但是当我用Isend/Irecv替换Send/Recv时会产生分段错误.但在去其他任何地方之前,我想验证以下代码段是否显示为alrite.
其余的代码应该没问题,因为Send/Recv可以工作; 但是我没有把它粘贴在这里作为它的长代码.
INTEGER :: IERR,TASKID,NUMTASKS,SPANX,SPANY,SPANZ,PROCSX,PROCSY,PROCSZ,STAT,STATUS(MPI_STATUS_SIZE),ISTAT(MPI_STATUS_SIZE,52)
INTEGER,DIMENSION(1:52) :: REQ
ALLOCATE(RCC(IIST:IIEND,JJST:JJEND,KKST:KKEND),STAT=IERR)
IF (IERR /=0) PRINT*,'ERROR IN RCC BY',TASKID
DO I=1,52
REQ(I)=MPI_REQUEST_NULL
ENDDO
IF (TASKID.NE.0) THEN
NT=TASKID
CALL MPI_ISEND(RCC(IIST:IIEND,JJST:JJEND,KKST:KKEND),SIZE(RCC),MPI_DOUBLE_PRECISION,0,8,MPI_COMM_WORLD,REQ(NT),IERR)
ENDIF
IF (TASKID.EQ.0) THEN
DO NT = 1,26
CALL MPI_IRECV(CC(RSPANX(NT):RSPANXE(NT),RSPANY(NT):RSPANYE(NT),RSPANZ(NT):RSPANZE(NT)),SIZECC(NT),MPI_DOUBLE_PRECISION,NT,8,MPI_COMM_WORLD,REQ(NT+26),IERR)
ENDDO
ENDIF
CALL MPI_WAITALL(52,REQ,ISTAT,IERR)
DEALLOCATE(RCC,STAT=IERR)
IF (IERR /=0) PRINT*,'ERROR IN DEALLOCATE RCC BY',TASKID
CALL MPI_FINALIZE(IERR)
RETURN
END
Run Code Online (Sandbox Code Playgroud)
但是,当我使用Isend/Irecv时,以下行不会给出分段错误.
CALL MPI_IRECV(CC(RSPANX(NT),RSPANY(NT),RSPANZ(NT)),SIZECC(NT),MPI_DOUBLE_PRECISION,NT,8,MPI_COMM_WORLD,REQ(NT+26),IERR)
Run Code Online (Sandbox Code Playgroud) 我有3个阵列,我必须做这个总结

实现的代码是
do i=1,320
do j=1,320
do k=1,10
do l=1,10
do m=1,10
do r=1,10
do s=1,10
sum=sum+B(k,l,r,s,m)*P(i,j,r,s,m)
end do
end do
A(i,j,k,l,m)=sum
end do
end do
end do
end do
end do
Run Code Online (Sandbox Code Playgroud)
执行代码需要1天.有没有办法优化它?
谢谢.
即时寻找一个简明和高效的方式,采取多维片阵列,就这些切片执行标量和矩阵算术,然后最终得到的阵列保存为另一个阵列的切片.
您可以使用以下语法在fortran中做得很好:
real*8, dimension(4,4,4,4) :: matrix_a
real*8, dimension(4,4) :: matrix_b
...
matrix_a(:, 2, :, 4) = matrix_a(:, 2, :, 4) + (2 * matrix_b(:, :))
Run Code Online (Sandbox Code Playgroud)
我试图在Cython中找到这样做的方法.这是我能想到的最好的:
cdef double matrix_a[4][4][4][4]
cdef double matrix_b[4][4]
...
cdef int i0, i1
for i0 in range(4):
for i1 in range(4):
matrix_a[i0][1][i1][3] += (2 * matrix_b[i0][i1])
Run Code Online (Sandbox Code Playgroud)
显然,您可以使用Numpy数组以非常简洁的方式执行此操作,但这似乎比上面的代码要慢几个数量级.有什么方法可以让我在这两个世界中都做到最好吗?可能某种方式我可以以更快的方式调用Numpy?或者也许是某种可以从Cython中利用的C/C++ API.谢谢
我想掩盖一个Fortran数组.这是我目前正在做的方式......
where (my_array <=15.0)
mask_array = 1
elsewhere
mask_array = 0
end where
Run Code Online (Sandbox Code Playgroud)
那么我得到我的蒙面数组:
masked = my_array * mask_array
Run Code Online (Sandbox Code Playgroud)
有没有更简洁的方法来做到这一点?
我试图在每次运行后保存并重用一个2D变量但我得到一些错误,如自动对象无法保存等.这是子程序:
subroutine dust_sum_test(ngrid,count,dust_in,dust_out)
!Subroutine to accumulate and release dust in timely manner
implicit none
integer,intent(in)::ngrid
integer,intent(in)::count
real,intent(in)::dust_in(ngrid)
real,intent(out)::dust_out(ngrid)
real,save::dmsdust(ngrid,99999) ! dummy local variable
integer::i
if (count.gt.1) then
dmsdust(:,count)=dmsdust(:,count-1)+dust_in
dust_out=dmsdust(:,count)
else
dust_out=dust_in
dmsdust(:,count)=0.0
endif
write(*,*)'The current count is = ', count
end subroutine dust_sum_test
Run Code Online (Sandbox Code Playgroud)
我需要使用以前的dmsdust值添加当前值.请让我知道如何解决这个问题.
我对Fortran 90完全陌生,并且试图了解如何将数组传递给函数。我在网上浏览时,找不到足够清晰和简单的示例,因此决定在此处发布。
我希望函数能够在任何长度的数组上工作(数组的长度不应是函数的参数之一)。
我试图写一个简单的函数示例,该函数返回数组元素的总和:
function mysum(arr)
implicit none
real, dimension(:), intent(in) :: arr
real :: mysum
integer :: i,arrsize
arrsize = size(arr)
mysum=0.0
do i=1,arrsize
mysum=mysum+arr(i)
enddo
end function mysum
program test
implicit none
real, dimension(4) :: a
real :: mysum,a_sum
call random_number(a)
print *,a
a_sum=mysum(a)
print *,a_sum
end program
Run Code Online (Sandbox Code Playgroud)
当我尝试编译时,出现以下错误:
array_test.f90:17.14:
real mysum,a_sum
1
Error: Procedure 'mysum' at (1) with assumed-shape dummy argument 'arr' must have an explicit interface
Run Code Online (Sandbox Code Playgroud)
我的程序有什么问题?