我想对syevd
非连续数组调用 Lapack95 子程序,如下所示:
real :: mat(15000, 15000), vec(15000)
mat=1.d0
associate(eig_vects=>mat(:10000,:10000),eig_vals=>vec(:10000))
call syevd(eig_vects,eig_evals,'V')
end associate
这样做安全吗?之前,我在将不连续的数组切片传递给子例程时遇到了问题(无法分配该子例程创建的临时数组)。使用指针eig_vects
作为参数时是否会出现类似的问题?
Lapack95 不是 Lapack 的独立实现,而是经典 Lapack 的包装器,具有更现代的接口。特别是,Lapack95 的虚拟数组参数是假定形状(可能不连续),而在经典 Lapack 中,它们是假定大小(因此是连续的)。
由于调用链的末尾(经典 Lapack)需要连续的数组,因此如果您想处理不连续的数组,无论如何都必须进行临时复制。唯一的问题是“在哪里”:
associate( eig_vects=>mat(:10000,:10000) )
不进行任何复制,eigs_vects
只是此处的一种别名call syevd(eig_vects,eig_evals,'V')
也不会进行任何复制,因为 Lapack95 的接口syevd
可以处理不连续的数组。*syevd
;但您无法控制其执行方式。例如,通常,Intel 编译器使用堆栈来处理临时数组,而对于如此大的矩阵,它将失败。正如@VladimirFГероямслава 所建议的,您最好明确分配一个连续的数组来一次性使用:
请注意,它
vec(:10000)
是连续的,因此您不需要为其分配另一个数组。请注意,您也可以直接调用经典的 Lapack 例程,因为它们的接口可以处理这种情况而无需任何复制,这要归功于问题大小和“主要维度”的解耦: