How to create page-locked memory from a existing numpy array in PyCUDA?
Question: The [PyCUDA help explains how to create an empty or zeroed
array](http://documen.tician.de/pycuda/driver.html#pagelocked-allocation) but
not how to move(?) an existing numpy array into page-locked memory. Do I need
to get a pointer for the numpy array and pass it to
`pycuda.driver.PagelockedHostAllocation`? And how would I do that?

**UPDATE**

<\--sniped -->

**UPDATE 2**

Thanks **talonmies** for you help. Now the memory transfare is page-locked but
the program ends with the following error:

    
    
    PyCUDA WARNING: a clean-up operation failed (dead context maybe?)
    cuMemFreeHost failed: invalid context
    

This is the updated code:

    
    
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    
    import numpy as np
    import ctypes
    from pycuda import driver, compiler, gpuarray
    from pycuda.tools import PageLockedMemoryPool
    import pycuda.autoinit
    
    memorypool = PageLockedMemoryPool()
    
    indata = np.random.randn(5).astype(np.float32)
    outdata = gpuarray.zeros(5, dtype=np.float32)
    
    pinnedinput = memorypool.allocate(indata.shape,np.float32)
    
    source = indata.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
    dest = pinnedinput.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
    sz = indata.size * ctypes.sizeof(ctypes.c_float)
    ctypes.memmove(dest,source,sz)
    
    
    kernel_code = """
     __global__ void kernel(float *indata, float *outdata) {
     int globalid = blockIdx.x * blockDim.x + threadIdx.x ;
     outdata[globalid] = indata[globalid]+1.0f;
    
     }
     """
    
    mod = compiler.SourceModule(kernel_code)
    kernel = mod.get_function("kernel")
    
    kernel(
     driver.In(pinnedinput), outdata,
     grid = (5,1),
     block = (1, 1, 1),
    )
    print indata
    print outdata.get()
    memorypool.free_held()
    


Answer: You will need to copy the data from your source array to the array holding the
page locked allocation returned from pycuda. The most straightforward way to
do that is via `ctypes`:

    
    
    import numpy
    import ctypes
    
    x=numpy.array([1,2,3,4],dtype=numpy.double)
    y=numpy.zeros_like(x)
    
    source = x.ctypes.data_as(ctypes.POINTER(ctypes.c_double))
    dest = y.ctypes.data_as(ctypes.POINTER(ctypes.c_double))
    sz = x.size * ctypes.sizeof(ctypes.c_double)
    
    ctypes.memmove(dest,source,sz)
    
    print y
    

The `numpy.ctypes` interface can be used to get a pointer to the memory used
to hold an arrays data, and then the `ctypes.memmove` used to copy between two
different ndarrays. All the usual caveats of working with naked C pointers
apply, so some care is required, but it is straightforward enough to use.

