Объяснение требований от входных данных к вычислениям на GPU, имеющим сложные результаты
Рассмотрим эту строку кода:
gpuArray(-1)^0.5;
Что приводит к:
ANS = 0,0000 + 1,0000i
Теперь рассмотрим следующую строку кода:
gpuArray(-1).^0.5;
Что приводит к:
Ошибка при использовании.^ POWER: необходимо вернуть сложный результат, но это не поддерживается для реального ввода X и Y на ГПУ. Вместо этого используйте POWER(COMPLEX(X), COMPLEX(Y,0)).
Проблема явно имеет отношение к double -> complex double
преобразование на GPU, что не допускается. Действительно, когда я применяю обходной путь (который также упоминается в документации), это решает проблему - но я не понимаю, почему.
Кто-нибудь пролил бы свет на это? Это какое-то ограничение VRAM? Из конкретной карты, которую я использую (у меня GTX 660 с CC 3.0)? Из реализации MATLAB (я использую R2018b)? ОС?
1 ответ
Есть несколько методов gpuArray
что ведут себя так, и причина проста: производительность.
Вполне возможно написать реализацию, например, sqrt
он работает на GPU так же, как работает реализация CPU в MATLAB (т.е. вычисляет реальный результат, если не требуется сложный результат - в этом случае возвращает сложный результат). Часть работ уже выполнена - в противном случае gpuArray
Метод не знает, когда выдать ошибку. Однако дорогая часть затем перераспределяет (сложный) выход и выполняет операцию снова.
Есть и другие небольшие заметные причуды, связанные с gpuArray
и комплексные числа - на GPU все нулевые мнимые части не удаляются, когда реализация CPU MATLAB удаляет их. Например:
>> a = [1i, 2]; gA = gpuArray(a);
>> [isreal(a(2)), isreal(gA(2))]
ans =
1×2 logical array
1 0
(Вспоминая, конечно, что MATLAB's isreal
функция говорит о хранилище, а не о значениях).
РЕДАКТИРОВАТЬ: Просто понял, что есть конкретные ссылки на документы для функций gpuArray
которые ведут себя таким образом.