Как я могу использовать несколько графических процессоров в чашке? - PullRequest
0 голосов
/ 19 сентября 2019

Я пытаюсь распараллелить множественное умножение матриц, используя несколько графических процессоров в CUPY.

Cupy ускоряет умножение матриц (например, $ A \ times B $).Мне интересно, если у меня есть четыре квадратные матрицы A, B, C, D.Я хочу рассчитать AB и CD на двух разных локальных графических процессорах.Как я могу сделать это в CUPY?

Например, в tenorflow,

for i in xrange(FLAGS.num_gpus):
  with tf.device('/gpu:%d' % i):

Есть ли аналогичный способ в CUPY.Особенность Cupy заключается в том, что он выполняет код сразу, поэтому он не может запустить следующую строку (например, $ C \ times D $), пока не закончится текущая строка (например, $ A \ times B $).

Спасибоза помощь Тос.Теперь новый вопрос, скажем, у меня есть десять из этих пар матриц, хранящихся в двух трехмерных массивах (скажем,? *? * 10).Как я могу написать цикл для хранения результата умножения?

anumpy #size(1e5,1e5,10)
bnumpy #size(1e5,1e5,10)

for i in range(10):
   #say I have 3 gpus
   with cupy.cuda.Device(i % 3):
      a = cupy.array(anumpy[:,:,i])
      b = cupy.array(bnumpy[:,:,i])
      ab[:,:,math.floor(i/3)] = a @ b

Как я могу объединить эти 3 ab в разных устройствах?Могу ли я иметь массивы с одинаковыми именами в разных графических процессорах?

Ответы [ 3 ]

1 голос
/ 19 сентября 2019

CuPy не синхронизирует выполнение устройства в большинстве операций.Код, подобный A.dot(B), возвращается сразу после запуска матричного продукта на устройстве, не дожидаясь самой операции на стороне устройства, поэтому, если операция достаточно тяжелая (например, матрицы большие), вычисления эффективно перекрываются со вторым матричным продуктомна другом устройстве.

0 голосов
/ 20 сентября 2019

Я не уверен на 100%, правильно ли я понимаю вопрос, но думаю, это может быть что-то вроде этого:

def my_cal(gpu_id, anumpy, bnumpy):
  a = None
  b = None
  ab = None

  with cupy.cuda.Device(gpu_id):
    for i in range(10):
        a = cupy.array(anumpy[:,:,i])
        b = cupy.array(bnumpy[:,:,i])
        ab[:,:,math.floor(i/3)] = a @ b
  return cupy.asnumpy(ab)


np_ab0 = my_cal(0, anumpy, bnumpy)
np_ab1 = my_cal(1, anumpy, bnumpy)
np_ab2 = my_cal(2, anumpy, bnumpy)
0 голосов
/ 19 сентября 2019

Используйте with cupy.cuda.Device(i) и избегайте операций блокировки.Например, чтобы вычислить matmul пар массивов ЦП, отправьте результаты в CPU (cupy.asnumpy) после вызова всех операций matmul.

a = cupy.array(a)
b = cupy.array(b)
ab = a @ b
# ab = cupy.asnumpy(ab)  # not here
with cupy.cuda.Device(1):
    c = cupy.array(c)
    d = cupy.array(d)
    cd = c @ d
    cd = cupy.asnumpy(cd)
ab = cupy.asnumpy(ab)
...