NVBLAS молча терпит неудачу для умножения полубольших матриц

Я следовал инструкциям здесь, чтобы запустить октаву с nvblas. У меня установлен инструментарий CUDA 7.5 и графический процессор tesla k40c. Чтобы начать октаву с nvblas, я использовал LD_PRELOAD=libnvblas.so octave, Затем я запустил следующий простой код:

N = 256
A = rand(N,N)
B = rand(N,N)
A*B

который производит матрицу с разумными значениями. Однако, если я увеличу N до 512 или любое число свыше 512, я получу все нули (или очень маленькие числа) в результате.

Если я использую OpenBLAS, этого не происходит. Матрицы должны быть достаточно маленькими, чтобы они помещались в ОЗУ карты (12 ГБ). Есть идеи, почему это может произойти?

Примечание. Если я создаю тождественные матрицы A и B, этого не происходит, но все равно происходит с A = B = единиц (N,N).

1 ответ

Решение

Извините, вопрос несколько устарел, но я попробовал его на экземпляре Amazon AWS EC2 p2.xlarge с графическим процессором k80, и, похоже, это сработало.

Я получал схожие результаты с вами (много нулей), когда у меня был параметр по умолчанию "NVBLAS_GPU_LIST 0 1" в nvblas.conf, который, кажется, ссылается на два графических процессора, поэтому я изменил его на один, и это сработало. Заполните файл ниже:

#Put here the CPU BLAS fallback Library of your choice
NVBLAS_CPU_BLAS_LIB libopenblas.so

# Specify which output log file (default is stderr)
NVBLAS_LOGFILE nvblas.log

# List of GPU devices Id to participate to the computation
# By default if no GPU are listed, only device 0 will be used
NVBLAS_GPU_LIST 0
NVBLAS_AUTOPIN_MEM_ENABLED

Программа (t1.m), слегка измененная по ссылке NVidia, для подсчета количества ненулевых элементов в выходной матрице:

N = 16384;

# from the original NVidia example:
#A = single(rand(N,N));
#B = single(rand(N,N));

# double precision seems to work fine (not checked in detail)
A = rand(N,N);
B = rand(N,N);

start = clock();
C = A * B;
elapsedTime = etime(clock(), start);
disp(elapsedTime);
gFlops = 2*N*N*N/(elapsedTime * 1e+9);
disp(gFlops);

disp("number of elements >0:")
disp(sum(sum(C > 0)));

disp("Should be:")
disp(N*N)

К вашему сведению Вот вывод nvidia-smi, когда он работал, как указано выше (он достиг максимума при использовании 172 МБ с N=16384):

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 375.51                 Driver Version: 375.51                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla K80           Off  | 0000:00:1E.0     Off |                    0 |
| N/A   44C    P0    80W / 149W |     80MiB / 11439MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID  Type  Process name                               Usage      |
|=============================================================================|
|    0     21080    C   /usr/bin/octave-cli                             78MiB |
+-----------------------------------------------------------------------------+

Вот файлы nvidia & cuda, которые я ранее установил:

cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb  
libcudnn5-dev_5.1.10-1+cuda8.0_amd64.deb
libcudnn5_5.1.10-1+cuda8.0_amd64.deb                   
nvidia-driver-local-repo-ubuntu1604_375.51-1_amd64.deb

Кажется, я набрал скорость около 8,6, примерно с 55 гфлопс в обычной октаве и 478 в версии с графическим процессором.

Другие вопросы по тегам