Fortran中的稀疏存储:仅读取和写入 [英] Sparse Storage in Fortran: Only Reading and Writing
问题描述
我有一个具有多个维度的数组(目标是允许约100个),每个维度的大小约为2 ^ 10,我只需要在其中存储约1000个双精度系数.除了读取和写入该数组外,我不需要对该数组做任何操作.该代码是用Fortran 90编写的.
I have an array with multiple dimensions (the goal is to allow for about 100) and each dimension has a size of about 2^10 and I only need to store in it about 1000 double precision coefficients. I don't need to do any operation with this array aside from reading and writing into it. The code is written in Fortran 90.
我认为,如果我的图书馆像此答案中提到的图书馆之一那样,我将能够存储这样做,但是会针对简单的读写操作进行优化吗?是否有一个最有效的图书馆?
I assume that if I a library like one of the ones mentioned in this answer I would be able to store the do this, but would this be optimized for the simple reading and writing operations? Is there a library that would be most efficient for that purpose?
编辑:通过"简单的读写操作",我的意思是.假设
By "simple reading and writing operations" I mean the following. Suppose
REAL(8), DIMENSION(1000) :: coeff1
INTEGER, DIMENSION(1000,5) :: index
我想定义coeff2
将值存储在coeff1
中,然后在index
中的索引处读取它,即
I want to define coeff2
to store the values in coeff1
and then read itat the indices in index
, that is
DO i = 1,1000
index(i,:) = [something]
coeff1(i) = [another something]
coeff2(index(i,1),index(i,2),index(i,3),index(i,4),index(i,5)) = coeff1(i)
ENDDO
然后,对于任何i
,我想访问
Then, for any i
I would like to access the value of
coeff2(index(i,1),index(i,2),index(i,3),index(i,4),index(i,5))
尽快.能够快速执行此操作是我所说的"有效".
as quickly as possible. Being able to do this fast is what I mean by "efficient".
由于[something]
中的索引最多为2 ^ 10,因此我目前将coeff2
定义如下:
Since the indices in [something]
are at most 2^10 I am currently defining coeff2
as follows:
REAL(8), DIMENSION(2**10,2**10,2**10,2**10,2**10) :: coeff2
但是这特别浪费内存,因为我需要将维数(现在是5)增加到100的数量级,并且此数组的大多数元素都等于0.因此,另一种与效率相关的度量我的想法是,随着我增加尺寸数,存储coeff2
所需的内存不应爆炸.
but this is too wasteful of memory specially since I need to increase the number of dimensions, now 5, to the order of 100 and most elements of this array are equal to 0. So, another measure of efficiency that is relevant to me is that the memory necessary to store coeff2
should not explode as I increase the number of dimensions.
推荐答案
好吧,对我来说,数据的性质和使用方式还不是很清楚.
Well, It's still not totally clear to me the nature of your data and the way you want to use it.
如果您需要索引不连续的索引数据, 稀疏矩阵可能是一个答案,并且已经在Internet上实现了许多解决方案(如您提供的链接中所示).但是,也许对于我想您想做的事情来说,这是过大的选择.也许一个简单的数据类型可以满足您的目的,就像这样:
If what you need is indexed data, whose indices are not consecutive, Sparse matrix can be an answer, and there are many solutions already implemented over the internet (as shown in the link you provided). But maybe it would be overkill for what I think you are trying to do. Maybe a simple datatype could serve your purpose, like this:
program indexed_values
implicit none
type :: indexed
integer :: index
real(8) :: value
end type
integer, parameter :: n_coeffs = 1000
integer, parameter :: n_indices = 5
integer :: i
real(8), dimension(n_coeffs) :: coeff1
integer, dimension(n_coeffs, n_indices) :: index
type(indexed), dimension(n_coeffs, n_indices) :: coeff2
type(indexed) :: var
do i = 1, n_coeffs
index(i, :) = [1, 2, 4, 16, 32] * i ! your calc here
coeff1(i) = real(i * 3, 8) ! more calc here
coeff2(i, :)%index = index(i, :)
coeff2(i, :)%value = coeff1(i)
end do
! that's how you fetch the indices and values by stored position
var = coeff2(500, 2)
print*, var%index, var%value ! outputs: 1000 1500.0
! that's how you fetch a value by its index
print*, fetch_by_index(coeff2(500, :), 1000) ! outputs: 1500.0
contains
real(8) function fetch_by_index(indexed_pairs, index)
type(indexed), dimension(:) :: indexed_pairs
integer, intent(in) :: index
integer :: i
do i=1, size(indexed_pairs)
if(index == indexed_pairs(i)%index) then
fetch_by_index = indexed_pairs(i)%value
return
end if
end do
stop "No value stored for this index"
end
end
如果按索引升序存储索引(无需遍历整个列表以失败),则可以改进所提供的按索引获取值的功能.此外,如果您将coeff1的常数结果赋给每一行的所有索引,则您甚至可以做得更好,甚至根本不需要coeff2数组,只需将coeff1用于值和索引用于索引,然后将它们与位置相关联即可.
The provided function for fetching values by its indices could be improved if your indices will be alwyas stored in ascending order (no need to traverse the whole list to fail). Moreover, if you will assing a constant result of coeff1 to all the indices at each row, you could do even better and just not having a coeff2 array at all, just have coeff1 for values and index for the indices, and correlate them by position.
这篇关于Fortran中的稀疏存储:仅读取和写入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!