如何在Chapel

时间:2017-07-22 15:24:18

标签: hpc chapel

我在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吗?

谢谢!

1 个答案:

答案 0 :(得分:3)

您在代码段中显示的方式将在每次+=操作时展开稀疏域的内部数组。如你所说;以某种方式缓冲读取索引,然后批量添加它们肯定会表现更好,因为有几个优化添加索引数组。

您可以类似地执行右侧是数组的+=

spsDom += arrayOfIndices;

稀疏域上+=运算符的这种重载实际上是调用主要的批量添加方法bulkAdd。该方法本身有几个标志,可以帮助您在某些情况下获得更多的性能。请注意,+=重载会调用"最安全"中的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的标志应该会产生最佳性能。当然,这取决于正在排序的输入缓冲区并且没有任何重复。另外,请注意,与连续的bulkAdd相比,初始bulkAdd会快得多。并且它们可能会变慢,因为该方法需要筛选现有的索引并在必要时进行转换。因此,更大的缓冲区可以提供更好的性能。