Как запросить длину строки с clGetPlatformInfo (и друзьями)? - PullRequest
2 голосов
/ 20 сентября 2011

Краткая версия: существует ли официальный / правильный способ запроса размера строк, например CL_PLATFORM_VENDOR?

Длинная версия: Глядя на функции OpenCL, такие как clGetPlatformInfo , я хочу выяснить, сколько места нужно выделить для результата. Функция имеет такую ​​подпись:

cl_int clGetPlatformInfo(cl_platform_id platform,
    cl_platform_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret)

Документы говорят:

param_value_size

Specifies the size in bytes of memory pointed to by
param_value. This size in bytes must be greater
than or equal to size of return type specified in the
table below.

Все возвращаемые типы перечислены как char[]. Я хотел знать, сколько места нужно зарезервировать, поэтому я назвал это следующим образом: я передаю 0 для param_value_size и NULL для param_value, надеясь получить правильный размер, возвращаемый в param_value_size_ret:

  size_t size = 0;
  l_success = clGetPlatformInfo(platform_id,
                                CL_PLATFORM_VENDOR, 0, NULL, &size);

  if( l_success != CL_SUCCESS)
  {
    printf("Failed getting vendor name size.\n");
    return -1;
  }
  printf("l_success = %d, size = %d\n", l_success, size);
  char* vendor = NULL;
  vendor = malloc(size);
  if( vendor )
  {
    l_success = clGetPlatformInfo(platform_id,
                                  CL_PLATFORM_VENDOR, size, vendor, &size);
    if( l_success != CL_SUCCESS )
    {
      printf("Failed getting vendor name.\n");
      return -1;
    }
    printf("Vendor name is '%s', length is %d\n", vendor, strlen(vendor));
  } else {
    printf("malloc failed.\n");
    return -1;
  }

Он вел себя, как я и надеялся, он возвращает размер строки 19, «NVIDIA Corporation» (размер включает нулевой терминатор) и strlen возвращает 18. Это «правильный» способ запроса размера параметра или мне просто повезло с реализацией моего поставщика? Кто-нибудь видел, как эта идиома провалилась на каком-то продавце?

Редактировать: Бит, который сбивает меня с толку: «Этот размер в байтах должен быть больше или равен размеру возвращаемого типа», похоже, что когда я передаю 0 и NULL вызов должен завершиться неудачей, поскольку он не больше или равен размеру возвращенного значения . Я не уверен, почему они говорят «тип возврата».

Ответы [ 2 ]

4 голосов
/ 20 сентября 2011

Да, это - правильный путь.

В том же документе, который вы упомянули :

Если param_value равно NULL, оно игнорируется.

И ниже:

Возвращает CL_SUCCESS, если функция выполнена успешно.В противном случае он возвращает следующее:

...

CL_INVALID_VALUE, если param_name не является одним из поддерживаемых значений или если размер в байтах, заданный param_value_size, меньше размератипа возврата и param_value не является значением NULL.

Таким образом, даже если это не указано явно, если param_value равно NULL, ошибки не должно быть, поэтому код должен работать

Вот фрагмент кода из Привязки Khronos OpenCL C ++ ( specs ).Они тоже так делают, и я думаю, что это считается «официальным»:

// Specialized GetInfoHelper for STRING_CLASS params
template <typename Func>
struct GetInfoHelper<Func, STRING_CLASS>
{
    static cl_int get(Func f, cl_uint name, STRING_CLASS* param)
    {
        ::size_t required;
        cl_int err = f(name, 0, NULL, &required);
        if (err != CL_SUCCESS) {
            return err;
        }

        char* value = (char*) alloca(required);
        err = f(name, required, value, NULL);
        if (err != CL_SUCCESS) {
            return err;
        }

        *param = value;
        return CL_SUCCESS;
    }
};
1 голос
/ 31 июля 2014

Обратите внимание на пример, что при запросе значения четвертый параметр должен быть NULL.В противном случае некоторые платформы отвечают CL_INVALID_VALUE как возвращаемым.

Поскольку предварительный запрос и malloc каким-то образом перегружены, я использую один большой буфер символов в качестве временного решения.

char vendor[10240];
l_success = clGetPlatformInfo( platform_id,
                     CL_PLATFORM_VENDOR, sizeof(vendor), vendor, NULL);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...