2015-09-07 2 views
0

Есть ли кто-нибудь, кто когда-либо отправлял массивы CUDA через MPI через самую последнюю версию mpy4py (и pyCUDA 2015.1.3)? Чтобы отправить массив, необходимо преобразовать соответствующий тип данных в смежный буфер. Это преобразование выполняется с помощью следующего лямбда:Как использовать pyCUDA для трансляции через MPI?

to_buffer = lambda arr: None if arr is None else lambda arr: arr.gpudata.as_buffer(arr.nbytes 

Полный вид сценария следующим образом:

import numpy 
    from mpi4py import MPI 

    import pycuda.gpuarray as gpuarray 
    import pycuda.driver as cuda 
    import pycuda.autoinit 
    import numpy 

    to_buffer = lambda arr: None if arr is None else lambda arr: arr.gpudata.as_buffer(arr.nbytes) 

    print "pyCUDA version " + str(pycuda.VERSION) 
    a_gpu = gpuarray.to_gpu(numpy.random.randn(4,4).astype(numpy.float32)) 

    comm = MPI.COMM_WORLD 
    rank = comm.Get_rank() 

    comm.Bcast([ to_buffer(agpu , MPI.FLOAT], root=0) 

Но, к сожалению, вся эта красота аварий с этими ошибками:

pyCUDA version (2015, 1, 3) 
    Traceback (most recent call last): 
    File "./test_mpi.py", line 21, in <module> 
    comm.Bcast([ to_buffer(numpy.random.randn(4,4).astype(numpy.float32)) , MPI.FLOAT], root=0) 
    File "Comm.pyx", line 405, in mpi4py.MPI.Comm.Bcast (src/mpi4py.MPI.c:66743) 
    File "message.pxi", line 388, in mpi4py.MPI._p_msg_cco.for_bcast (src/mpi4py.MPI.c:23220) 
    File "message.pxi", line 355, in mpi4py.MPI._p_msg_cco.for_cco_send (src/mpi4py.MPI.c:22959) 
    File "message.pxi", line 111, in mpi4py.MPI.message_simple (src/mpi4py.MPI.c:20516) 
    File "message.pxi", line 51, in mpi4py.MPI.message_basic (src/mpi4py.MPI.c:19644) 
    File "asbuffer.pxi", line 108, in mpi4py.MPI.getbuffer (src/mpi4py.MPI.c:6757) 
    File "asbuffer.pxi", line 50, in mpi4py.MPI.PyObject_GetBufferEx (src/mpi4py.MPI.c:6093) 
    TypeError: expected a readable buffer object 

Любые идеи, что продолжается? Может быть, у кого-то есть альтернативная мантра?

Заранее благодарен!

+1

простой mpi требует объектов, которые поддерживают протокол буфера в * host * памяти. «DeviceAllocation» находится в памяти устройства. Я не думаю, что это могло бы работать – talonmies

+0

@talonmies, возможно, вы правы, но я думаю, что a_gpu действительно находится на GPU, но to_buffer скопирует его на хост. Если это неверно, объясните подробнее. Спасибо! –

+0

Вы можете прочитать документацию 'as_buffer' [здесь] (http://documen.tician.de/pycuda/driver.html#pycuda.driver.DeviceAllocation) и ее источник [здесь] (https://github.com/ индуктор/PyCuda/BLOB/fde69b0502d944a2d41e1f1b2d0b78352815d487/SRC/CPP/cuda.hpp # L1547). Я не вижу нигде, где будет запускаться копия устройства для размещения, создавая объект-буфер из DeviceAllocation. Вы? – talonmies

ответ

1

Все, что необходимо, чтобы вызвать передачу MPI с объектом буферной памяти действительным хоста или Numpy массива, например:

comm.Bcast(a_gpu.get(), root=0) 

вместо лямбда для преобразования DeviceAllocation объекта к объекту буфера