Как добавить разреженный домен в Chapel


Я заполняю разреженный массив в Chapel циклом, который читает над CSV.

Мне интересно, какая модель лучше.

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);
}

Является ли это эффективным способом сделать это?
Должен ли я создать временный массив кортежей и добавить spsDom каждые (скажем) 10 000 строк?

Спасибо!

1 3

1 ответ:

Способ, который вы показываете в сниппете, будет расширять внутренние массивы разреженного домена при каждой операции +=. Как вы и предлагали; каким-то образом буферизация индексов чтения, а затем их массовое добавление, безусловно, будет работать лучше из-за нескольких оптимизаций для добавления массива индексов.

Аналогично можно сделать += , где правая сторона является массивом:

spsDom += arrayOfIndices;
Эта перегрузка оператора += на разреженных доменах фактически вызывает основной метод массового сложения bulkAdd. Сам метод имеет несколько флагов, которые могут помочь вам получить еще большую производительность в некоторых случаях. Обратите внимание, что перегрузка += вызывает метод bulkAdd самым "безопасным" способом. т. е. массив индексов может быть в случайном порядке, может включать дубликаты и т. д. Если у вас есть массивы (в вашем случае индексы, которые Вы читаете из файла), удовлетворяющие некоторым требованиям (упорядочены ли они? Есть ли дубликаты? Вам нужно сохранить входной массив?), вы можете использовать bulkAdd напрямую и пройти несколько оптимизаций флаги.

См. http://chapel.cray.com/docs/latest/builtins/internal/ChapelArray.html#ChapelArray.bulkAdd для документации 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);

Я не проверял его, но я думаю, что это должно захватить основную идею.Флаги, переданные в булкадд, должны привести к наилучшей производительности. Конечно, это зависит от сортировки входного буфера и отсутствия дубликатов. Кроме того, обратите внимание что начальный булькадд будет намного быстрее по сравнению с последовательными. И они, вероятно, станут медленнее, поскольку метод должен просеять существующие индексы и при необходимости сдвинуть их. Таким образом, больший буфер может обеспечить лучшую производительность.