如何在 Chapel 中附加稀疏域
How to append a sparse domain in Chapel
我正在使用读取 CSV 的循环填充 Chapel 中的稀疏数组。
我想知道最好的模式是什么。
var dnsDom = {1..n_dims, 1..n_dims};
var spsDom: sparse subdomain(dnsDom);
for line in file_reader.lines() {
var i = line[1]:int;
var j = line[2]:int;
spsDom += (i,j);
}
这是一种有效的方法吗?
我是否应该创建一个临时元组数组并每隔(比如)10,000 行追加 spsDom
?
谢谢!
您在代码段中显示的方式将在每次 +=
操作时扩展稀疏域的内部数组。正如你所建议的;以某种方式缓冲读取索引,然后批量添加它们肯定会表现更好,因为对添加索引数组进行了多项优化。
您可以类似地做一个 +=
,其中右侧是一个数组:
spsDom += arrayOfIndices;
稀疏域上 +=
运算符的重载实际上是在调用主要的批量加法方法 bulkAdd
。该方法本身有几个标志,在某些情况下可以帮助您获得更高的性能。请注意,+=
重载以可能的 "safest" 方式调用 bulkAdd
方法。即索引数组可以是随机顺序,可以包含重复项等。如果您有数组(在您的情况下是从文件中读取的索引)满足某些要求(它们是有序的吗?是否有重复项?是否需要保留输入数组?),你可以直接使用bulkAdd
并传递几个优化标志。
有关 bulkAdd
的文档,请参阅 http://chapel.cray.com/docs/latest/builtins/internal/ChapelArray.html#ChapelArray.bulkAdd。
编辑: 建立在相关片段之上的片段:
var dnsDom = {1..n_dims, 1..n_dims};
var spsDom: sparse subdomain(dnsDom);
//create an index buffer
config const indexBufferSize = 100;
var indexBufferDom: {0..#indexBufferSize};
var indexBuffer: [indexBufferDom] 2*int;
var count = 0;
for line in file_reader.lines() {
indexBuffer[count] = (line[1]:int, line[2]:int);
count += 1;
// bulk add indices if the buffer is full
if count == indexBufferSize {
spsDom.bulkAdd(indexBuffer, dataSorted=true,
preserveInds=false,
isUnique=true);
count = 0;
}
}
// dump the final buffer that is (most likely) partially filled
spsDom.bulkAdd(indexBuffer[0..#count], dataSorted=true,
preserveInds=false,
isUnique=true);
我还没有测试过它,但我认为这应该捕获传递给 bulkAdd 的基本 idea.The 标志应该会产生最佳性能。当然,这取决于输入缓冲区是否已排序且没有任何重复项。另外,请注意,与连续的相比,初始的 bulkAdd 会快得多。而且它们可能会变慢,因为该方法需要筛选现有索引并在必要时移动它们。因此,更大的缓冲区可以提供更好的性能。
我正在使用读取 CSV 的循环填充 Chapel 中的稀疏数组。
我想知道最好的模式是什么。
var dnsDom = {1..n_dims, 1..n_dims};
var spsDom: sparse subdomain(dnsDom);
for line in file_reader.lines() {
var i = line[1]:int;
var j = line[2]:int;
spsDom += (i,j);
}
这是一种有效的方法吗?
我是否应该创建一个临时元组数组并每隔(比如)10,000 行追加 spsDom
?
谢谢!
您在代码段中显示的方式将在每次 +=
操作时扩展稀疏域的内部数组。正如你所建议的;以某种方式缓冲读取索引,然后批量添加它们肯定会表现更好,因为对添加索引数组进行了多项优化。
您可以类似地做一个 +=
,其中右侧是一个数组:
spsDom += arrayOfIndices;
稀疏域上 +=
运算符的重载实际上是在调用主要的批量加法方法 bulkAdd
。该方法本身有几个标志,在某些情况下可以帮助您获得更高的性能。请注意,+=
重载以可能的 "safest" 方式调用 bulkAdd
方法。即索引数组可以是随机顺序,可以包含重复项等。如果您有数组(在您的情况下是从文件中读取的索引)满足某些要求(它们是有序的吗?是否有重复项?是否需要保留输入数组?),你可以直接使用bulkAdd
并传递几个优化标志。
有关 bulkAdd
的文档,请参阅 http://chapel.cray.com/docs/latest/builtins/internal/ChapelArray.html#ChapelArray.bulkAdd。
编辑: 建立在相关片段之上的片段:
var dnsDom = {1..n_dims, 1..n_dims};
var spsDom: sparse subdomain(dnsDom);
//create an index buffer
config const indexBufferSize = 100;
var indexBufferDom: {0..#indexBufferSize};
var indexBuffer: [indexBufferDom] 2*int;
var count = 0;
for line in file_reader.lines() {
indexBuffer[count] = (line[1]:int, line[2]:int);
count += 1;
// bulk add indices if the buffer is full
if count == indexBufferSize {
spsDom.bulkAdd(indexBuffer, dataSorted=true,
preserveInds=false,
isUnique=true);
count = 0;
}
}
// dump the final buffer that is (most likely) partially filled
spsDom.bulkAdd(indexBuffer[0..#count], dataSorted=true,
preserveInds=false,
isUnique=true);
我还没有测试过它,但我认为这应该捕获传递给 bulkAdd 的基本 idea.The 标志应该会产生最佳性能。当然,这取决于输入缓冲区是否已排序且没有任何重复项。另外,请注意,与连续的相比,初始的 bulkAdd 会快得多。而且它们可能会变慢,因为该方法需要筛选现有索引并在必要时移动它们。因此,更大的缓冲区可以提供更好的性能。