'Initializes a new matrix object in one of two ways. If array is a numpy
ndarray, memory for a matrix with the same dimensions is allocated on
the GPU. If the copy_to_device flag is set to True, the GPU matrix is
initialized with the given ndarray. If array is not an ndarray, it must
be a cudamat structure (typically the user will never use this way of
calling __init__).'

def __init__(self, array, copy_to_device=True):

    if (type(array) == np.ndarray):
        array = reformat(array)
        self.mat = cudamat()
        self.size = self.mat.size
        self.p_mat = ct.pointer(self.mat)
        self.numpy_array = array
        _cudamat.init_from_array(self.p_mat, array.ctypes.data_as(ct.POINTER(ct.c_float)), ct.c_int(array.shape[0]), ct.c_int(array.shape[1]))
        if copy_to_device:
            err_code = _cudamat.copy_to_device(self.p_mat)
            if err_code:
                raise generate_exception(err_code)
    else:
        mat = array
        self.mat = mat
        self.p_mat = ct.pointer(self.mat)
    self.T = TransposedCUDAMatrix(self.mat)
    self.__free_device_memory = _cudamat.free_device_memory
