Рассмотрим следующий код:
template <typename T> __host__ __device__ int foo1(const T& x);
template <typename T> __host__ __device__ int foo2(T x);
Эти две функции соответствуют двум распространенным способам передачи «in» -параметров, а не «out» или «in / out» параметров. Второе проще, в этом нет ссылок или адресов; но первый гарантирует отсутствие копирования более сложных типов, поэтому его часто предпочитают.
Моя проблема с передачей значений constexpr
- функции первого типа (foo1
). Если это на стороне хоста - нет проблем. constexpr
переменные имеют адреса, и компилятор позаботится обо мне и сделает что-то разумное.
Но - то же самое не относится к стороне устройства. Если мы скомпилируем:
constexpr const int c { 123 };
__host__ int bar() { return foo1(c); }
__device__ int baz() { return foo1(c); }
Первая функция будет работать нормально, но вторая не сможет скомпилировать (GodBolt).
Я не могу предоставить оба функции, так как компилятор не сможет выбирать между ними (часто / всегда). И я не хочу просто передавать значения, потому что я хочу избежать копий больших T
; или потому что я обязан предоставить foo1()
с помощью какого-то формального ограничения.
Что я тогда могу сделать?
Я также упомяну, что хочу написать один и тот же код на устройстве и на стороне хоста.