Сумма параллельного блока ArrayFire - PullRequest
2 голосов
/ 25 июня 2019

Я хочу сделать следующее: у меня есть «расширенный» массив в первом измерении (строки).Например, у меня есть изображение 1080 строк и 1920 столбцов.Этот расширенный массив имеет (8 * 1080) строк и 1920 столбцов, 8 означает размер «блока строк».Я хочу создать новый массив размером 8x1.Этот новый массив будет содержать сумму каждого блока в i-м (i = 0 до 7).

В вышеприведенном примере первый элемент нового массива (i = 0) будет суммойиз этих пикселей в расширенном массиве (линейные индексы по столбцам):

0, 8 (потому что 8 является ПЕРВЫМ элементом второго блока), 16 (третий блок) .....

другим примером является второй элемент:

1, 9, 17, ...

Я думаю, что это можно распараллелить?Я пытаюсь решить эту проблему, но я не могу, я пытался gfor, но не мог найти способ сделать это, разве это невозможно с arrayfire?любая помощь приветствуется!

Я пытался использовать gfor, но я не мог решить эту проблему.

Вот код, который я попробовал: rx - это 8x1 (p_squared_1 = 8), а rx_all - эторасширенный (p_squared * строки, столбцы) массив.Заметьте, я использую оператор seq "+", потому что, если я пытаюсь написать "i + p_squared_1", возникает двусмысленность, я думаю ... это ошибка с моей стороны, но я не смог найти другой способ добавить значение вследующий объект).

af::array rx(p_squared_1, 1);
gfor(af::seq i, rows*cols*(p_squared_1-1)) {
    rx(i) = af::sum<float>(rx_all(i.operator+( (const int)p_squared_1)));
}
af::eval(rx);
cout << af::sum<float>(rx);

Я ожидаю получить массив 8x1, где каждый i-й элемент является суммой i-тых элементов каждого блока в расширенном массиве.

1 Ответ

1 голос
/ 25 июня 2019

Я думаю, что вы можете добиться этого, выполнив af::moddims и af::sum.

array img_expanded(1080*8, 1920);

array img_expanded_reshaped = moddims(img_expanded, 8, 1920*1080);
array result = sum(img_expanded_reshaped, 1);

Вызов moddims преобразует массив в массив 8x (1920 * 1080), а затем вы выполняете суммированиево втором измерении.

Оптимизированный макет

Вы могли бы получить лучшую производительность, если бы рассматривали сторону 1920 года как ведущее измерение.Это не только будет соответствовать расположению изображения в памяти процессора и позволит избежать транспонирования при передаче в и из графического процессора, но измененный массив будет иметь большее первое измерение, поэтому он будет лучше использовать графический процессор.

array img_expanded(1920, 1080*8);

array img_expanded_reshaped = moddims(img_expanded, 1920*1080, 8);
array result = sum(img_expanded_reshaped, 0);

Это потребует от вас рефакторинга больше, чем эта часть кода.

...