Является ли "import numpy as cp" хорошей практикой для обработки не-GPU ситуаций? - PullRequest
3 голосов
/ 23 сентября 2019

Я пишу код, который идеально запускается на GPU для скорости, используя CuPy.Тем не менее, я хочу, чтобы код мог запускаться (хотя и медленнее) с использованием простой реализации.На данный момент я делаю следующее:

import numpy as np
if gpu_present:
    import cupy as cp
else:
    import numpy as cp

Я боюсь, что позже у меня могут возникнуть проблемы.Это хорошая практика?

1 Ответ

1 голос
/ 25 сентября 2019

Когда сценарий небольшой и используемое пространство имен можно исправить при запуске, я часто использую глобальную переменную с именем xp (аналогично вашему решению).Подобный шаблон, который я также иногда использую, состоит в том, чтобы сделать его атрибутом экземпляра класса (снова названного xp);это более приемлемо для будущих расширений, потому что каждый экземпляр может иметь отдельное значение для этого атрибута.Аналогичный, гораздо более надежный, но громоздкий подход заключается в том, чтобы xp был первым аргументом каждой функции.

При написании библиотеки, которая может использоваться при любых обстоятельствах (например, многопоточный код с использованием как NumPy, так и CuPy).в одном процессе) лучше сделать так, чтобы каждая функция / класс обрабатывал пространство имен соответствующим образом для аргументов.Я часто использую get_array_module утилиту для этой цели. CuPy имеет эту функцию , хотя для установки требуется CuPy. Chainer также имеет его .Это также просто написать самостоятельно.Используя эту утилиту, вы можете сделать код пригодным для использования с массивами NumPy или CuPy без глобального переключателя.

Также обратите внимание, что NumPy> = 1.17 может отправлять массивы CuPy в соответствующие подпрограммы CuPy, поэтому вы можете напрямую передавать массивы CuPyдо numpy.* функции в большинстве случаев.Если ваш код выполняет вычисления только для заданных массивов, вам даже не нужно вообще использовать пространство имен cupy (вам все равно нужно использовать его для создания нового массива без предоставления другого, такого как cupy.ones и cupy.random.*).

...