Как получить текущие вычислительные возможности графического процессора из основной части кода?

Я пытался использовать __CUDA_ARCH__, но где-то читал, что это работает только с частью кода, относящейся к устройству. После этого я наткнулся на этот код на github: ссылка

Есть ли лучший способ добиться этого?

Я спрашиваю об этом, потому что я хотел бы определить (в коде хоста), поддерживает ли графический процессор унифицированную память, и в этом случае будет иметь место cudaMallocManaged или вместо этого будет иметь место cudaMallocs && cudaMemcpys.

Пример того, что я хотел бы сделать:

int main() {
  // IF CUDA >= 6.0 && COMPUTE CAPABILITY >= 3.0
      // USE cudaMallocManaged
  // ELSE
      // USE cudaMallocs && cudaMemcpys
  // END IF
  return 0;
}

person Community    schedule 21.11.2017    source источник
comment
Я думаю, что в SDK есть пример кода для получения вычислительных возможностей.   -  person Paul R    schedule 21.11.2017
comment
@PaulR, так что вы предлагаете мне использовать __host__ ​cudaError_t cudaGetDeviceProperties ( cudaDeviceProp* prop, int device ) и прочитать значение из переменной managedMemSupported. Что, если я захочу скомпилировать точно такой же код с каким-нибудь старым API CUDA, в котором даже нет определения того, что такое cudaMallocManaged?   -  person    schedule 21.11.2017
comment
Я не знаю - я давно не работал с CUDA - я просто вспомнил, что в SDK был пример кода, в котором сообщалось о вычислительных возможностях, вот и все.   -  person Paul R    schedule 21.11.2017
comment
@PaulR О, хорошо! Спасибо, в любом случае! ;)   -  person    schedule 21.11.2017
comment
Обратите внимание, что существует разница между запросом вычислительных возможностей через cudaGetDeviceProperties() и __CUDA_ARCH__: первый дает фактические вычислительные возможности устройства, а второй — вычислительные возможности, для которых был скомпилирован код устройства. Они могут различаться, если устройства с различными вычислительными возможностями являются двоично-совместимыми или если код PTX транслируется драйвером для фактической архитектуры.   -  person tera    schedule 21.11.2017
comment
@tera Да, это правда.   -  person    schedule 21.11.2017
comment
@tera Я хотел бы сделать возможной компиляцию на более новых и старых CUDA во время компиляции (я хочу компиляцию без ошибок) И определить, поддерживается ли унифицированная память во время выполнения.   -  person    schedule 21.11.2017
comment
В этом случае лучше запросить поддержку унифицированной памяти напрямую. вместо того, чтобы делать выводы из вычислительных возможностей.   -  person tera    schedule 21.11.2017
comment
gist.github.com/xorz57/b074171188b17baa1d4050522ca5d59f Вот что я сделал с вашей помощью мне, ребята. Дайте мне знать, если вам что-то не нравится.   -  person    schedule 21.11.2017
comment
Включаемый файл cuda_runtime_api.h имеет #define CUDART_VERSION xxxx, который можно использовать для проверки версии API среды выполнения во время компиляции. После включения этого файла вы можете сделать что-то вроде #if CUDART_VERSION >= 6000, чтобы проверить, является ли поддерживаемая версия API среды выполнения 6.0 или выше. Даже если это так, вы все равно должны использовать метод cudaGetDeviceProperties, описанный выше, для проверки поддержки управляемой памяти, прежде чем пытаться вызвать, например. cudaMallocManaged().   -  person Robert Crovella    schedule 21.11.2017
comment
@RobertCrovella Кажется, это отличное решение. Можете ли вы опубликовать это как ответ?   -  person    schedule 21.11.2017


Ответы (1)


Здесь, кажется, два вопроса:

  1. Как я могу запросить (во время компиляции) версию API среды выполнения CUDA, для которой компилируется конкретный код, чтобы я мог определить, безопасно ли использовать определенные элементы API среды выполнения (например, связанные с управляемой памятью), которые могут только появились в более новых версиях API среды выполнения?

    Один метод уже обсуждался здесь . В качестве сокращенной версии для этого конкретного случая вы можете сделать что-то вроде:

    #include <cuda_runtime_api.h>
    ...
    // test for CUDA version of 6.0 or higher
    #if CUDART_VERSION >= 6000 
    // safe to use e.g. cudaMallocManaged() here
    #else
    // e.g. do not use managed memory API here
    #endif
    
  2. Как определить, могу ли я использовать управляемую память во время выполнения?

    Как уже упоминалось в комментариях, если вы установили, что компилируемая версия CUDA — это CUDA 6.0 или выше (например, см. выше), то вам следует проверить поддержку управляемой памяти, прежде чем пытаться использовать, например, cudaMallocManaged. deviceQuery пример кода CUDA показывает общую методологию ( например, используя cudaGetDeviceProperties, тестируя свойство managedMemSupported) для тестирования возможностей во время выполнения.

person Community    schedule 21.11.2017