#opencl #opencl-c
Вопрос:
Я пытаюсь разобраться в странном поведении, происходящем в моей функции ядра OpenCL. Я в основном пытаюсь преобразовать строку, содержащую шестнадцатеричные числа, в строку, содержащую ее десятичное представление, но по причинам, которые я не могу понять, запуск одного и того же ядра с использованием GPU и CPU дает разные результаты.
Ядро выглядит следующим образом:
// yes, there's no result defined for the moment
__kernel void testKernel(__global uint message_length, __global char *message) {
size_t converted_message_length = message_length / 2;
char converted_message[converted_message_length];
// (1) hex to decimal conversion
for (size_t idx = 0, j = 0; idx < converted_message_length; idx , j ) {
converted_message[idx] = (message[j] amp; '@' ? message[j] 9 : message[j]) << 4;
j ;
converted_message[idx] |= (message[j] amp; '@' ? message[j] 9 : message[j]) amp; 0xF;
printf("converted '%c%c' into '%i'n", message[j - 1], message[j], converted_message[idx]);
}
// (2) this should be redundant, since I already print the content...
// but actually behaves differently with different device (CPU/GPU)
for (size_t idx = 0, j = 0; idx < converted_message_length; idx , j ) {
printf("converted_message[%i]: '%i'n", idx, converted_message[idx]);
}
Теперь, если я передам в качестве аргументов testKernel
функции длину 4
и входную строку , содержащую шестнадцатеричное значение 3e2b
, я ожидаю, что они будут преобразованы в десятичные 62
числа и 43
(см. Эту таблицу для преобразования в шестнадцатеричное> десятичное).
И, если я запускаю ядро, используя свой процессор (Intel(R) Core(TM) i9-9880H), действительно, я вижу, как происходит следующее преобразование:
converted '3e' into '62'
converted '2b' into '43'
converted_message[0]: '62'
converted_message[1]: '43'
Однако, если я запущу это же ядро с помощью своего графического процессора (AMD Radeon Pro 5500M), я увижу следующие результаты:
converted '3e' into '62'
converted '2b' into '43'
converted_message[0]: '0' <-- why it is 0 ???
converted_message[1]: '0' <-- why it is 0 ???
Похоже converted_message
, что он успешно записан внутри цикла (1)
, но затем его значения теряются, когда я вхожу во внутренний (2)
цикл. Как это вообще возможно? Это OpenCL выполняет какую-то странную оптимизацию под капотом, которая проявляется только при работе на графическом процессоре ?
Комментарии:
1. Как запланировано ядро?
2. У меня однажды были такие проблемы на том же устройстве, но с другим драйвером, хотя и с плавающей точкой, где компилятор может изменять порядок операций, поэтому ошибки округления могут быть разными. Однако различные результаты не должны быть возможны с целочисленными операциями. Я подозреваю, что на одном устройстве память неправильно выделена/инициализирована.
Ответ №1:
char converted_message[converted_message_length];
Это массив переменной длины, который не поддерживается в стандартном OpenCL. Он может работать в некоторых реализациях OpenCL в качестве расширения, но не является переносимым.
Укажите фиксированный размер массива или выделите буфер на хосте.
Комментарии:
1. хорошо подмечено, большое спасибо, что указали на ссылку!