如何从Chapel

时间:2017-08-22 03:57:44

标签: sparse-matrix chapel

这次我有一个矩阵--IN A FILE--名为“matrix.csv”,我想读它。我可以用两种口味,密集和稀疏来做。

matrix.csv

3.0, 0.8, 1.1, 0.0, 2.0
0.8, 3.0, 1.3, 1.0, 0.0
1.1, 1.3, 4.0, 0.5, 1.7
0.0, 1.0, 0.5, 3.0, 1.5
2.0, 0.0, 1.7, 1.5, 3.0

稀疏

matrix.csv
1,1,3.0
1,2,0,8
1,3,1.1
// 1,4 is missing
1,5,2.0
...
5,5,3.0

假设文件非常大。在这两种情况下,我都希望将这些内容读入具有适当尺寸的Matrix中。在密集的情况下,我可能不需要提供元数据。在第二个,我想我应该提供矩阵的“框架”,如

matrix.csv
nrows:5
ncols:5

但我不知道标准模式。

== UPDATE ==

有点难以找到,但mmreadsp可以将你的日子从“崩溃服务器”改为“在11秒内完成”。感谢Brad Cray(不是他的真名)指出来了!

2 个答案:

答案 0 :(得分:1)

前言

由于Chapel矩阵表示为数组,因此这个问题等同于:

"如何从Chapel"中的文件中读取数组

理想情况下,csv模块或专用IO格式化程序(类似于JSON formatter)可以更优雅地处理csv I / O,但这个答案反映了数组I / O选项从Chapel 1.16预发布版开始。

密集阵列I / O

密集数组很容易,因为DefaultRectangular数组(Chapel数组的默认type)带有.readWriteThis(f)方法。此方法允许用户使用内置write()read()方法读取和写入数组,如下所示:

var A: [1..5, 1..5] real;

// Give this array some values
[(i,j) in A.domain] A[i,j] = i + 10*j;

var writer = open('dense.txt', iomode.cw).writer();

writer.write(A);

writer.close();

var B: [1..5, 1..5] real;
var reader = open('dense.txt', iomode.r).reader();
reader.read(B);
reader.close();

assert(A == B);

dense.txt看起来像这样:

11.0 21.0 31.0 41.0 51.0
12.0 22.0 32.0 42.0 52.0
13.0 23.0 33.0 43.0 53.0
14.0 24.0 34.0 44.0 54.0
15.0 25.0 35.0 45.0 55.0

但是,这假设您事先知道阵列形状。我们可以通过在文件顶部写入数组形状来删除此约束,如下所示:

var A: [1..5, 1..5] real;

[(i,j) in A.domain] A[i,j] = i + 10*j;

var writer = open('dense.txt', iomode.cw).writer();

writer.writeln(A.shape);
writer.write(A);

writer.close();

var reader = open('dense.txt', iomode.r).reader();
var shape: 2*int;
reader.read(shape);
var B: [1..shape[1], 1..shape[2]] real;
reader.read(B);
reader.close();

assert(A == B);

现在,dense.txt看起来像这样:

(5, 5)
11.0 21.0 31.0 41.0 51.0
12.0 22.0 32.0 42.0 52.0
13.0 23.0 33.0 43.0 53.0
14.0 24.0 34.0 44.0 54.0
15.0 25.0 35.0 45.0 55.0

稀疏阵列I / O

稀疏数组需要更多工作,因为DefaultSparse数组(稀疏教堂数组的默认type)仅提供.writeThis(f)方法而不是.readThis(f)方法截至Chapel 1.16预发布。这意味着我们内置了对编写稀疏数组的支持,但没有读取它们。

由于您特别要求csv格式,我们将在csv中执行稀疏数组:

// Create parent domain, sparse subdomain, and sparse array
const D = {1..10, 1..10};
var spD: sparse subdomain(D);
var A: [spD] real;

// Add some non-zeros:
spD += [(1,1), (1,5), (2,7), (5, 4), (6, 6), (9,3), (10,10)];

// Set non-zeros to 1.0 (to make things interesting?)
A = 1.0;

var writer = open('sparse.csv', iomode.cw).writer();

// Write shape
writer.writef('%n,%n\n', A.shape[1], A.shape[2]);

// Iterate over non-zero indices, writing: i,j,value
for (i,j) in spD {
  writer.writef('%n,%n,%n\n', i, j, A[i,j]);
}

writer.close();

var reader = open('sparse.csv', iomode.r).reader();

// Read shape
var shape: 2*int;
reader.readf('%n,%n', shape[1], shape[2]);

// Create parent domain, sparse subdomain, and sparse array
const Bdom = {1..shape[1], 1..shape[2]};
var spBdom: sparse subdomain(Bdom);
var B: [spBdom] real;

// This is an optimization that bulk-adds the indices. We could instead add
// the indices directly to spBdom and the value to B[i,j] each iteration
var indices: [1..0] 2*int,
    values: [1..0] real;

// Variables to be read into
var i, j: int,
    val: real;
while reader.readf('%n,%n,%n', i, j, val) {
  indices.push_back((i,j));
  values.push_back(val);
}

// bulk add the indices to spBdom and add values to B element-wise
spBdom += indices;
for (ij, v) in zip(indices, values) {
  B[ij] = v;
}

reader.close();

// Sparse arrays can't be zippered with anything other than their domains and
// sibling arrays, so we need to do an element-wise assertion:
assert(A.domain == B.domain);
for (i,j) in A.domain {
  assert(A[i,j] == B[i,j]);
}

sparse.csv看起来像这样:

10,10
1,1,1
1,5,1
2,7,1
5,4,1
6,6,1
9,3,1
10,10,1

MatrixMarket模块

最后,我提到有一个MatrixMarket包模块支持密集和&使用matrix market format的稀疏数组I / O.这个目前没有显示在公共文档中,因为一旦包管理器足够可靠,它就会作为独立包移出,但是你可以在目前使用use MatrixMarket;的教堂程序中使用它。

以下是source code,其中包含作为评论的界面文档。

以下是tests,如果您愿意从示例中学习,而不是文档&源代码。

答案 1 :(得分:0)

向教授致敬。 Rudolf Zitny&教授。 Petr Vopenka

enter image description here  (如果有人碰巧记得PC工具实用程序,由Zitny教授开创并创作的Matrix工具,对于大规模F77 FEM矩阵的智能抽象表示同样不可或缺,使用COMMON - 块和类似的技巧数值处理项目中的大型和稀疏矩阵高效存储和操作......)

观察:

对于需要使用" frame"以及构建稀疏矩阵的最后一句话,我不能不同意。

矩阵总是只是某种形式主义的解释

虽然稀疏矩阵在矩阵上共享相同的视图,但作为解释,每个模块的实现总是严格基于一些具体的表示。 / p>

总是使用不同的单元格 - 布局策略来处理不同类型的稀疏性(诀窍是对单元格元素使用最少需要的[SPACE],同时具有一些可接受的处理[TIME]开销,当试图在这样的矩阵上执行经典的矩阵/向量运算时(通常没有用户知道或者手动"打扰底层的稀疏矩阵表示,用于存储单元格值,以及如何最优化)解码/翻译成目标稀疏矩阵的表示。

直观地说,Matrix Tools会以最佳内存布局尽可能紧凑地显示每个表示(非常类似于压缩硬盘的PC Tools) ,铺设扇区数据,以避免任何不必要的非连续的HDD容量浪费)和非常(逐个类型)表示 - 意识处理程序将提供任何外部观察者假设矩阵解释所需的完整错觉(在计算阶段)。

让我们首先意识到,在源端(python-?)不知道用于稀疏矩阵表示的平台特定规则的所有细节。 ,JSON-meta-payload-?等)和目标方( LinearAlgebra ver-1.16尚未确认不公开(WIP),并没有多少开始实施。

(尚未知)稀疏矩阵表示的实际具体化(无论是file://,DMA访问还是CSP-通道或任何其他非InRAM存储器或InRAM存储器映射的方法)不会改变交叉表示xlator的解决方案。

作为一名材料专家,您可能会喜欢表示不是Cantor-set驱动(运行(几乎)无限,密集的枚举)对象的概念,而是使用Vopenka的替代品Set Theory(如此可爱,介绍了Vopenka" Meditations About The Science Bases of the Cases")的历史和数学背景,以及对这些情况的更近距离的观点。改变定义的地平线(不仅由观察者视角的实际锐度引起,而且在更广泛和一般意义上的这种原理),留下pi级和sigma级半套准备好连续处理新兴的新细节,因为它们进入了我们公认的观点部分(一旦出现在“地平线”和“定义的地平线”中)关于观察到的(和数学化的)现象。

稀疏矩阵(作为表示)帮助我们构建我们需要的解释,以便在进一步处理中使用迄今为止获得的数据单元&#34 ;作为矩阵"。

这就是说,工作流总是需要知道先验:

a)稀疏矩阵源系统中使用的约束和规则表示
b)中介通道施加的附加约束(表达性,格式,自我修复/容易出错),无论它是文件,CSP通道还是ZeroMQ / nanomsg智能插座信令 - / messaging-plane分布式代理基础设施
c)目标系统表示中施加的约束和规则,设置用于定义/加载/存储/进一步处理的规则&计算稀疏矩阵类型的一个选择必须在目标计算生态系统中满足/遵循

不知道 a)会为成功和有效的交叉代表管道准备策略带来不必要的大量开销,即从源代码转换常见的解释输入 b)代表。忽略 c)总是会导致惩罚 - 在 b)介导的重建传播过程中,在目标生态系统中支付额外的管理费用对目标的解释 - 表示