2012-09-12 72 views
3

由於CUDA 3.1可以通過設置CUDA_VISIBLE_DEVICES環境變量來限制應用程序可見的GPU列表。忽略`CUDA_VISIBLE_DEVICES`環境變量

這會影響運行時API和驅動程序API(確保我自己檢查過它)。似乎設備過濾在驅動程序級別上實施得更快,並且無法忽略它。

但是,我遇到了一個封閉的源代碼應用程序,它似乎忽略了這個變量並始終使用設備0,即使我們將CUDA_VISIBLE_DEVICES設置爲空字符串,這意味着應用程序不應該看到任何支持CUDA的設備。

有問題的應用程序使用相同的CUDA庫作爲虛擬應用程序可用設備計數:

$ ldd a.out # dummy 
    linux-vdso.so.1 => (0x00007fff7ec60000) 
    libcuda.so.1 => /usr/lib64/libcuda.so.1 (0x00007f606783a000) 
    libcudart.so.4 => /usr/local/cuda41/cuda/lib64/libcudart.so.4 (0x00007f60675e3000) 
    libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f60672dd000) 
    libm.so.6 => /lib64/libm.so.6 (0x00007f606704e000) 
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f6066e37000) 
    libc.so.6 => /lib64/libc.so.6 (0x00007f6066aa7000) 
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f606688b000) 
    libz.so.1 => /lib64/libz.so.1 (0x00007f6066674000) 
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f6066470000) 
    librt.so.1 => /lib64/librt.so.1 (0x00007f6066268000) 
    /lib64/ld-linux-x86-64.so.2 (0x00007f6068232000) 


$ ldd ../../bin/one.closed.source.application # application in question 
    linux-vdso.so.1 => (0x00007fffcf99c000) 
    libcufft.so.4 => /usr/local/cuda41/cuda/lib64/libcufft.so.4 (0x00007f06ce53a000) 
    libcuda.so.1 => /usr/lib64/libcuda.so.1 (0x00007f06cdb44000) 
    libcudart.so.4 => /usr/local/cuda41/cuda/lib64/libcudart.so.4 (0x00007f06cd8ed000) 
    libz.so.1 => /lib64/libz.so.1 (0x00007f06cd6cb000) 
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f06cd4c7000) 
    librt.so.1 => /lib64/librt.so.1 (0x00007f06cd2bf000) 
    libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f06ccfb8000) 
    libm.so.6 => /lib64/libm.so.6 (0x00007f06ccd34000) 
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f06ccb1e000) 
    libc.so.6 => /lib64/libc.so.6 (0x00007f06cc78d000) 
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f06cc571000) 
    /lib64/ld-linux-x86-64.so.2 (0x00007f06d0110000) 

我很好奇,怎麼可能做這種伎倆。

回答

3

Rubber duck debugging確實有效。

原來在調用cuInitcudaSetDevice之前使用unsetenv就足夠了,環境變量的初始值將被忽略。

#include <stdio.h> 
#include <stdlib.h> 
#include <cuda.h> 

int main(int argc, char **argv, char **env) { 
    int x; 
    unsetenv("CUDA_VISIBLE_DEVICES"); 
    cuInit(0); 
    // Now we see all the devices on machine 
    cuDeviceGetCount(&x); 
    printf("%d\n",x); 
    return 0; 
}