Я пытаюсь использовать функцию extern в Halide. В моем контексте я хочу сделать это на GPU.Использование extern на галиде с GPU
Я компилирую в компиляции AOT с оператором opencl. Конечно, OpenCL все еще может использовать процессор, поэтому я использую это:
halide_set_ocl_device_type("gpu");
В настоящем время, все расписание на compute_root().
Первый вопрос, если я использую compute_root() и OpenCL gpu, мой процесс будет вычисляться на устройстве с помощью некоторых CopyHtoD и DtoH? (Или он будет на хост-буфере)
Второй вопрос, больше связанных с функциями extern. Мы используем какой-то внешний вызов, потому что некоторые из наших алгоритмов не в Halide. Экстерн вызов:
foo.define_extern("cool_foo", args, Float(32), 4);
Экстерн получить: ехЬегп "C" INT cool_foo (buffer_t * в, Int W, внутр ч, внутр г, buffer_t * из) {..}
Но, функция cool_foo, мой buffer_t загружается только в память хоста. Адрес dev равен 0 (по умолчанию).
Если я пытаюсь скопировать память до алгоритма:
halide_copy_to_dev(NULL, &in);
Он ничего не делает.
Если я только память устройства:
in.host = NULL;
Мой указатель хоста являются пустым, но адрес устройства по-прежнему 0.
(dev_dirty правда в моем случае и host_dirty ложно)
Любая идея?
EDIT (Чтобы ответить dsharlet)
Вот структура моего кода:
данных Разбор правильно на CPU. -> Отправил буфер на графическом процессоре (с помощью halide_copy_to_dev ...) -> Ввести в структуру Halide, прочитать параметр и добавить граничное условие -> Пойти в мою внешнюю функцию -> ...
I не имеют действительного buffer_t в моей функции extern. Я планирую все в compute_root(), но использую HL_TARGET = host-opencl и устанавливаю ocl в gpu. Прежде чем войти в Halide, я могу прочитать адрес своего устройства, и все в порядке.
Вот мой код:
Перед галогенид, все было CPU материал (указатель), и мы TRANSFERT его GPU
buffer_t k = { 0, (uint8_t *) k_full, {w_k, h_k, num_patch_x * num_patch_y * 3}, {1, w_k, w_k * h_k}, {0}, sizeof(float), };
#if defined(USEGPU)
// Transfer into GPU
halide_copy_to_dev(NULL, &k);
k.host_dirty = false;
k.dev_dirty = true;
//k.host = NULL; // It's k_full
#endif
halide_func(&k)
Внутри ДРИ:
ImageParam ...
Func process;
process = halide_sub_func(k, width, height, k.channels());
process.compute_root();
...
Func halide_sub_func(ImageParam k, Expr width, Expr height, Expr patches)
{
Func kBounded("kBounded"), kShifted("kShifted"), khat("khat"), khat_tuple("khat_tuple");
kBounded = repeat_image(constant_exterior(k, 0.0f), 0, width, 0, height, 0, patches);
kShifted(x, y, pi) = kBounded(x + k.width()/2, y + k.height()/2, pi);
khat = extern_func(kShifted, width, height, patches);
khat_tuple(x, y, pi) = Tuple(khat(0, x, y, pi), khat(1, x, y, pi));
kShifted.compute_root();
khat.compute_root();
return khat_tuple;
}
Вне галоидный (Экстерн функция):
inline ....
{
//The buffer_t.dev and .host are 0 and null. I expect a null from the host, but the dev..
}
Можете ли вы поделиться кодом, определяющим и планирующим этап до этапа экстерна? Планируется ли это на графическом процессоре? Если нет, я думаю, что поведение, которое вы видите, ожидается. – dsharlet