Функция OpenCL clCreateContextFromType приводит к утечкам памяти - PullRequest
0 голосов
/ 08 апреля 2020

Я запустил valgrind для одного из моих OpenCL-кодов с открытым исходным кодом (https://github.com/fangq/mmc), и он обнаружил много утечек памяти в коде хоста OpenCL . Большинство из них указывало на строку , где я создал объект контекста, используя clCreateContextFromType.

. Я дважды проверил все свои переменные OpenCL, очереди команд, ядра и программы и убедился, что они все правильно выпущены , но, тем не менее, при тестировании на примерах программ каждый вызов функции mmc_run_cl() увеличивает память на 300-400 МБ и не освобождается при возврате.

вы можете воспроизвести отчет valgrind, выполнив следующие команды в терминале:

git clone https://github.com/fangq/mmc.git
cd mmc/src
make clean
make all
cd ../examples/validation
valgrind --show-leak-kinds=all --leak-check=full ../../src/bin/mmc -f cube2.inp -G 1 -s cube2 -n 1e4 -b 0 -D TP -M G -F bin

при условии, что в вашей системе установлены gcc / git / libOpenCL и valgrind. Измените вход -G 1 на другой номер, если вы хотите запустить его на других устройствах OpenCL (добавьте -L в список).

В приведенной ниже таблице я перечисляю повторный счетчик каждой обнаруженной утечки valgrind на графическом процессоре NVIDIA (TitanV) на коробке Linux (Ubuntu 16.04) с самым последним драйвером + cuda 9.

Опять же, большинство утечек связано с линией clCreateContextFromType, которая, как я полагаю, имеет некоторый объем памяти графического процессора не были выпущены, но я освободил все ресурсы GPU в конце кода хоста.

замечаете ли вы что-то, что я пропустил в коде хоста? Ваш вклад очень важен

counts |        error message
------------------------------------------------------------------------------------
    380 ==27828==    by 0x402C77: main (mmc.c:67)
Code: entry point to the below errors

     64 ==27828==    by 0x41CF02: mcx_list_gpu (mmc_cl_utils.c:135)
Code: OCL_ASSERT((clGetPlatformIDs(0, NULL, &numPlatforms)));

      4 ==27828==    by 0x41D032: mcx_list_gpu (mmc_cl_utils.c:154)
Code: context=clCreateContextFromType(cps,devtype[j],NULL,NULL,&status);

     58 ==27828==    by 0x41DF8A: mmc_run_cl (mmc_cl_host.c:111)
Code: entry point to the below errors

    438 ==27828==    by 0x41E006: mmc_run_cl (mmc_cl_host.c:124)
Code: OCL_ASSERT(((mcxcontext=clCreateContextFromType(cprops,CL_DEVICE_TYPE_ALL,...));

     13 ==27828==    by 0x41E238: mmc_run_cl (mmc_cl_host.c:144)
Code: OCL_ASSERT(((mcxqueue[i]=clCreateCommandQueue(mcxcontext,devices[i],prop,&status),status)));

      1 ==27828==    by 0x41E7A6: mmc_run_cl (mmc_cl_host.c:224)
Code:  OCL_ASSERT(((gprogress[0]=clCreateBufferNV(mcxcontext,CL_MEM_READ_WRITE, NV_PIN, ...);

      1 ==27828==    by 0x41E7F9: mmc_run_cl (mmc_cl_host.c:225)
Code: progress = (cl_uint *)clEnqueueMapBuffer(mcxqueue[0], gprogress[0], CL_TRUE, ...);

     10 ==27828==    by 0x41EDFA: mmc_run_cl (mmc_cl_host.c:290)
Code: status=clBuildProgram(mcxprogram, 0, NULL, opt, NULL, NULL);

      7 ==27828==    by 0x41F95C: mmc_run_cl (mmc_cl_host.c:417)
Code: OCL_ASSERT((clEnqueueReadBuffer(mcxqueue[devid],greporter[devid],CL_TRUE,0,...));

Обновление [04/11/2020]:

Читая комментарий @ doqtor, я провел следующий тест на 5 разностных устройствах, 2 графических процессора NVIDIA, 2 графических процессора AMD и 1 процессор Intel. То, что он сказал, было правильным - утечка памяти не происходит в библиотеке Intel OpenCL, я также обнаружил, что драйвер AMD OpenCL тоже подойдет. Единственная проблема заключается в том, что библиотека NVIDIA OpenCL, похоже, имеет утечку на обоих графических процессорах, которые я тестировал (Titan V и RTX2080).

Мои результаты испытаний приведены ниже. Профилирование памяти / ЦП с использованием psrecord введено в этом посте .

enter image description here

Я открою новый вопрос и щедрость о том, как уменьшить эта утечка памяти с NVIDIA OpenCL. Если у вас есть опыт в этом, пожалуйста, поделитесь. опубликует ссылку ниже. спасибо

1 Ответ

1 голос
/ 11 апреля 2020

Я дважды проверил все свои переменные OpenCL, очереди команд, ядра и программы и убедился, что все они правильно освобождены ...

Ну, я все еще нашел одну (крошечную) утечка памяти в мм c код:

==15320== 8 bytes in 1 blocks are definitely lost in loss record 14 of 1,905
==15320==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==15320==    by 0x128D48: mmc_run_cl (mmc_cl_host.c:137)
==15320==    by 0x11E71E: main (mmc.c:67)

Память, выделенная greporter, не освобождается. Так что это вы должны исправить.

Остальные потенциальные утечки памяти в библиотеке OpenCL. Они могут быть или не быть утечками памяти, так как, например, библиотека может использовать пользовательские распределители памяти, которые valgrind не распознает или выполняет некоторые другие приемы. Об этом много тем:

В общем, вы ничего не можете с этим поделать, если не хотите погружаться в библиотечный код и сделать что-нибудь об этом. Я бы посоветовал тщательно подавлять те сообщения, которые поступают из библиотеки. Файл подавления может быть сгенерирован, как описано в руководстве по valgrind: https://valgrind.org/docs/manual/manual-core.html#manual -core.suppress

... но, тем не менее, при тестировании на примерах программ каждый вызов функция mmc_run_cl () увеличивает память на 300-400 МБ и не освобождает при возврате

Как вы это проверили? Я не видел подозрительно растущей памяти. Я установил -n 1000e4, и он работал в течение примерно 2 минут, когда выделенная память все время оставалась неизменной на уровне ~ 0,6% от объема моей оперативной памяти. Обратите внимание, что я не использовал nvidia CUDA, но POCL на графическом процессоре Intel и процессоре и связывался с libOpenCL, установленным из пакета ocl-icd-libopencl1:amd64 в Ubuntu 18.04. Таким образом, вы можете попытаться присвоить этому go и проверить, не изменит ли это что-либо.

======== Обновить ============== ==================

Я перезапустил его, как вы описали в комментарии, и после первой итерации использование памяти составило 0,6% затем после 2-й итерации она увеличилась до 0,9%, и после этого следующие итерации не увеличили использование памяти. Valgrind также не сообщил ничего более нового, кроме того, что я наблюдал ранее. Поэтому я хотел бы предложить связать с nvidia-cuda libOpenCL, отличным от nvidia, и повторить тестирование.

...