J'ai 3 GPU GTX Titan dans ma machine. J'ai exécuté l'exemple fourni dans Cifar10 avec cifar10_train.py et obtenu la sortie suivante:
I tensorflow/core/common_runtime/gpu/gpu_init.cc:60] cannot enable peer access from device ordinal 0 to device ordinal 1
I tensorflow/core/common_runtime/gpu/gpu_init.cc:60] cannot enable peer access from device ordinal 1 to device ordinal 0
I tensorflow/core/common_runtime/gpu/gpu_init.cc:127] DMA: 0 1
I tensorflow/core/common_runtime/gpu/gpu_init.cc:137] 0: Y N
I tensorflow/core/common_runtime/gpu/gpu_init.cc:137] 1: N Y
I tensorflow/core/common_runtime/gpu/gpu_device.cc:694] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX TITAN, pci bus id: 0000:03:00.0)
I tensorflow/core/common_runtime/gpu/gpu_device.cc:694] Creating TensorFlow device (/gpu:1) -> (device: 1, name: GeForce GTX TITAN, pci bus id: 0000:84:00.0)
Il me semble que TensorFlow essaie de s'initialiser sur deux appareils (gpu0 et gpu1).
Ma question est pourquoi il ne fait cela que sur deux appareils et existe-t-il un moyen d'empêcher cela? (Je veux seulement qu'il fonctionne comme s'il y avait un seul GPU)
Voir: tilisation de GP
Placement manuel de l'appareil
Si vous souhaitez qu'une opération particulière s'exécute sur un appareil de votre choix au lieu de ce qui est automatiquement sélectionné pour vous, vous pouvez utiliser avec tf.device
pour créer un contexte de périphérique tel que toutes les opérations dans ce contexte auront la même affectation de périphérique.
# Creates a graph.
with tf.device('/cpu:0'):
a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')
b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')
c = tf.matmul(a, b)
# Creates a session with log_device_placement set to True.
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
# Runs the op.
print(sess.run(c))
Vous verrez que maintenant a et b sont assignés à cpu:0
. Puisqu'un périphérique n'a pas été explicitement spécifié pour l'opération MatMul
, le runtime TensorFlow en choisira un en fonction de l'opération et des périphériques disponibles (gpu: 0 dans cet exemple) et copiera automatiquement les tenseurs entre les périphériques si nécessaire.
Device mapping:
/job:localhost/replica:0/task:0/gpu:0 -> device: 0, name: Tesla K40c, pci bus
id: 0000:05:00.0
b: /job:localhost/replica:0/task:0/cpu:0
a: /job:localhost/replica:0/task:0/cpu:0
MatMul: /job:localhost/replica:0/task:0/gpu:0
[[ 22. 28.]
[ 49. 64.]]
Réponse antérieure 2.
Voir: tilisation de GP
Utilisation d'un seul GPU sur un système multi-GPU
Si vous avez plusieurs GPU dans votre système, le GPU avec l'ID le plus bas sera sélectionné par défaut. Si vous souhaitez exécuter sur un autre GPU, vous devrez spécifier explicitement la préférence:
# Creates a graph.
with tf.device('/gpu:2'):
a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a')
b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b')
c = tf.matmul(a, b)
# Creates a session with log_device_placement set to True.
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))
# Runs the op.
print sess.run(c)
Réponse antérieure 1.
De CUDA_VISIBLE_DEVICES - Masquage des GP
Votre application CUDA doit-elle cibler un GPU spécifique? Si vous écrivez du code compatible GPU, vous utilisez généralement une requête de périphérique pour sélectionner les GPU souhaités. Cependant, une solution rapide et facile pour les tests consiste à utiliser la variable d'environnement CUDA_VISIBLE_DEVICES pour restreindre les appareils que voit votre application CUDA. Cela peut être utile si vous essayez de partager des ressources sur un nœud ou si vous souhaitez que votre exécutable activé par GPU cible un GPU spécifique.
Syntaxe des variables d'environnement
Résultats
CUDA_VISIBLE_DEVICES = 1 Seul le périphérique 1 sera visible CUDA_VISIBLE_DEVICES = 0,1 Les périphériques 0 et 1 seront visibles CUDA_VISIBLE_DEVICES = ”0,1” Comme ci-dessus, les guillemets sont facultatifs CUDA_VISIBLE_DEVICES = 0,2,3 Les périphériques 0, 2 et 3 seront affichés Être visible; l'appareil 1 est masqué
CUDA énumérera les appareils visibles à partir de zéro. Dans le dernier cas, les périphériques 0, 2, 3 apparaîtront en tant que périphériques 0, 1, 2. Si vous changez l'ordre de la chaîne en "2,3,0", les périphériques 2,3,0 seront énumérés comme 0, 1,2 respectivement. Si CUDA_VISIBLE_DEVICES est défini sur un périphérique qui n'existe pas, tous les périphériques seront masqués. Vous pouvez spécifier un mélange de numéros d'appareils valides et invalides. Tous les périphériques avant la valeur non valide seront énumérés, tandis que tous les périphériques après la valeur non valide seront masqués.
Pour déterminer l'ID de périphérique pour le matériel disponible sur votre système, vous pouvez exécuter l'exécutable deviceQuery de NVIDIA inclus dans le SDK CUDA. Bonne programmation!
Chris Mason