import numpy as np

try:
    import cffi
    _have_cffi = True
except ImportError:
    _have_cffi = False

from numba import cuda, types
from numba.cuda.testing import (skip_on_cudasim, test_data_dir, unittest,
                                CUDATestCase)


@unittest.skipUnless(_have_cffi, 'Needs CFFI')
@skip_on_cudasim('Simulator does not support linking')
class TestCFFI(CUDATestCase):
    def test_from_buffer(self):
        ffi = cffi.FFI()

        link = str(test_data_dir / 'jitlink.ptx')
        sig = types.void(types.CPointer(types.int32))
        array_mutator = cuda.declare_device('array_mutator', sig)

        @cuda.jit(link=[link])
        def mutate_array(x):
            x_ptr = ffi.from_buffer(x)
            array_mutator(x_ptr)

        x = np.arange(2).astype(np.int32)
        mutate_array[1, 1](x)

        # The foreign function should have copied element 1 to element 0
        self.assertEqual(x[0], x[1])


if __name__ == '__main__':
    unittest.main()
