Предположим, у меня есть stl::array<float, 24> foo
, который является линеаризованным подвесом STL в массив массивных массивов формата Column-Major. af::array bar = af::array(4,3,2, 1, f32);
. Поэтому у меня есть объект af::dim4
dims
с размерами bar
, у меня есть до 4 af::seq
-объектов, и у меня есть линеаризованный массив foo
.Как явно получить линейные индексы от arrayfire?
Как можно явно указать индексы foo
(то есть линеаризованная версия bar
), представляющая, например, 2.nd и 3.rd row, то есть bar(af::seq(1,2), af::span, af::span, af::span)
? У меня есть небольшой пример кода, приведенный ниже, который показывает, что я хочу. В конце я также объясню, почему я хочу этого.
af::dim4 bigDims = af::dim4(4,3,2);
stl::array<float, 24> foo; // Resides in RAM and is big
float* selBuffer_ptr; // Necessary for AF correct type autodetection
stl::vector<float> selBuffer;
// Load some data into foo
af::array selection; // Resides in VRAM and is small
af::seq selRows = af::seq(1,2);
af::seq selCols = af::seq(bigDims[1]); // Emulates af::span
af::seq selSlices = af::seq(bigDims[2]); // Emulates af::span
af::dim4 selDims = af::dim4(selRows.size, selCols.size, selSlices.size);
dim_t* linIndices;
// Magic functionality getting linear indices of the selection
// selRows x selCols x selSlices
// Assign all indexed elements to a consecutive memory region in selBuffer
// I know their positions within the full dataset, b/c I know the selection ranges.
selBuffer_ptr = static_cast<float> &(selBuffer[0]);
selection = af::array(selDims, selBuffer_ptr); // Copies just the selection to the device (e.g. GPU)
// Do sth. with selection and be happy
// I don't need to write back into the foo array.
Arrayfire должны иметь такую логику реализована для того, чтобы получить доступ к элементам, и я нашел несколько связанных классов/функций, таких как af::index, af::seqToDims, af::gen_indexing, af::array::operator()
- однако я не мог понять простой способ еще вне.
Я думал о принципиально переопределении operator()
, чтобы он работал аналогично, но не требовал ссылки на массив-объект. Но это может быть потрачено впустую, если в инфраструктуре arrayfire есть простой способ.
фона: Причина, почему я хочу сделать это, потому что arrayfire не позволяет хранить данные только в основной памяти (CPU-контекста), будучи связан с ГПУ бэкэндом. Поскольку у меня есть большой кусок данных, которые нужно обрабатывать только по частям, а VRAM довольно ограничен, я хотел бы создать экземпляр af::array
-объектов ad-hoc из stl-контейнера, который всегда находился в основной памяти.
Конечно, я знаю, что я мог бы программировать магию индекса, чтобы обойти мою проблему, но я бы хотел использовать довольно сложные объекты af::seq
, которые могли бы сделать эффективную реализацию сложной логики индекса.
Зачем нужны линейные индексы в этом случае? Если вы можете показать какой-то код о том, что вы планируете делать после того, как получите линейные индексы, которые будут великолепны. –