我在模块中有几个名称不同的参数数组:
subroutine sub(n,...
...
end
在此模块的例程中
para1
我想在n=1
时使用para2
,在n=2
时使用real*8, pointer :: ptr(:)
,等等。有一些解决方案,一种是使数组paras = [para1 ,para2 ...]并正确索引,效果很好。但我想尝试使用指针
n
,然后根据PARAMETER attribute conflicts with TARGET attribute at (1)
将其分配给不同的参数数组,但问题是“ parameter
”。如果删除SAVE
属性,则该例程的安全性较差,并且假定了parameter
属性。
我错过了什么吗?为什么我们不能合并target
和static func apply<T>(fn: (T ...) -> T, xs: [T]) -> T {
return fn(xs) // gives '[T]' is not convertible to 'T' error
}
?为此,有没有好的方法呢?
答案 0 :(得分:2)
parameter
和target
属性确实存在冲突。具有target
属性的对象必须是变量(Fortran 2018 8.5.17,C861);命名常量(具有parameter
属性的对象)不是变量(F2018、8.5.13,C850)。
要使用目标数组,则必须使用变量。拥有一个“安全的”变量以防止其值被编程错误或类似情况所修改是很棘手的。有几种考虑因素可以阻止变量出现在变量定义上下文中。如果您可以安排这种状态,则编译器可能会发现您的错误。这样容易发生吗?
在纯过程和intent(in)
伪参数之外,最诱人的禁止是使用受保护的模块变量:
module pars
real, save, target, protected :: para1(74) = [...]
real, save, target, protected :: para2(1) = [6]
end module
subroutine sub (...)
use pars
real, pointer :: p
p => para1
end subroutine sub
要受到保护,这些值可以安全地在模块pars
外部进行修改吗? las,即使这是真的,也无济于事:受到保护,我们甚至无法指向模块变量的指针。
总而言之,您的编译器不会发现容易检测到修改可变目标数组的编程错误,因此,如果要使用数组作为目标,则必须小心。
答案 1 :(得分:0)
在注释中@ ja72的建议之后,这是尝试对参数使用单个2D数组。这与gfortran-8.2(在MacOS10.11上)配合得很好。
import os
import numpy as np
import time
import matplotlib.pyplot as plt
# take a slice of the data
def slice_data(roi):
dic = {}
data = np.zeros((512,512,256))
dic['data'] = np.squeeze( data[roi[0]:roi[1]+1, roi[2]:roi[3]+1, roi[4]:roi[5]+1] )
return dic
# save slices if the data
def save_slices(roi, save=False):
var = 'data'
for i in range(0,6):
# iterate to simulate a time series of data
a = slice_data(roi)[var]
var_dir = 'save_test/'
if not os.path.exists(var_dir): os.makedirs(var_dir)
file = var_dir + '{0:04d}{1}'.format(i,'.npy')
if save is True:
np.save(file, a)
## define slices
roix=[256, 256, 0, 512, 0, 256] # yz plane slice
roiy=[0, 512, 256, 256, 0, 256] # xz plane slice
roiz=[0, 512, 0, 512, 128, 128] # xy plane slice
## Calculate slices and do not save the results
dtx = []
dty = []
dtz = []
for i in range(100):
time0 = time.time()
save_slices(roix)
time1 = time.time()
dtx.append(time1-time0)
time0 = time.time()
save_slices(roiy)
time1 = time.time()
dty.append(time1-time0)
time0 = time.time()
save_slices(roiz)
time1 = time.time()
dtz.append(time1-time0)
plt.figure(1)
plt.plot(dtx)
plt.plot(dty)
plt.plot(dtz)
plt.title('time to run code without saving data')
print('mean time x-slice: {} sec'.format(np.mean(dtx)))
print('mean time y-slice: {} sec'.format(np.mean(dty)))
print('mean time z-slice: {} sec'.format(np.mean(dtz)))
## Calculate slices and do save the results
dtx = []
dty = []
dtz = []
for i in range(100):
time0 = time.time()
save_slices(roix, save=True)
time1 = time.time()
dtx.append(time1-time0)
time0 = time.time()
save_slices(roiy, save=True)
time1 = time.time()
dty.append(time1-time0)
time0 = time.time()
save_slices(roiz, save=True)
time1 = time.time()
dtz.append(time1-time0)
plt.figure(2)
plt.plot(dtx)
plt.plot(dty)
plt.plot(dtz)
plt.title('time to run code and save data')
print('mean time x-slice: {} sec'.format(np.mean(dtx)))
print('mean time y-slice: {} sec'.format(np.mean(dty)))
print('mean time z-slice: {} sec'.format(np.mean(dtz)))
但是,由于代码变得有点复杂(由于重塑),并且可能无法与旧的编译器一起使用,因此使用非参数数组可能会更直接...