Cython: Buffer type mismatch, expected 'int' but got 'long'

13,931

Solution 1

You are using Cython's int type, which is just C int. I think on Mac (or most architectures) it is int 32-bit. See wiki or intel or Does the size of an int depend on the compiler and/or processor?

On the other hand, long means int64. dtype='int' or dtype=np.int are all equivalent to np.int64.

I think you might just explicitly define it as one of the numpy type:

cimport numpy as np
import numpy as np
cdef myfunction(np.ndarray[np.int64_t, ndim=1] y):
     #do something
     pass

That way it reads more clear and there will not be any confusion later.

EDIT

The newer memoryviews syntax would be like this:

cdef myfunction(double[:] y):
    #do something with y
    pass

Solution 2

I did what the error message told me: I changed the memoryview base type from int to long and it seemed to work.

%%cython
def fun(long[:] x):
    return x[0]

y=np.array([1,2,3],dtype=int)
fun(y)    # returns 1
Share:
13,931
hlin117
Author by

hlin117

Software Engineer at Uber Technologies. Previously student at the University of Illinois at Urbana-Champaign. Interests include Machine Learning Bioinformatics Mathematics

Updated on July 02, 2022

Comments

  • hlin117
    hlin117 almost 2 years

    I'm having trouble passing in this memoryview of integers into this (rather trivial) function. Python is giving me this error:

    ValueError: Buffer dtype mismatch, expected 'int' but got 'long'
    

    Can someone help me understand what's going on? Searching around stackoverflow, it seems that it has to do with how python interprets types, and how C interprets types.

    %%cython
    def myfunction(int [:] y):
        pass
    
    # Python code
    import numpy as np
    y = np.array([0, 0, 1, 1])
    myfunction(y)
    

    This produces the ValueError from above.

    EDIT: Here are some other things I've discovered.

    To clarify, this error persists if I declare y the following ways:

    y = np.array([0, 0, 1, 1], dtype='int')
    y = np.array([0, 0, 1, 1], dtype=np.int)
    y = np.array([0, 0, 1, 1], dtype=np.int64)
    

    However, it works if I declare y with

    y = np.array([0, 0, 1, 1], dtype=np.int32)
    

    Does anyone want to give a suggestion why this is the case? Would throwing in np.int32 work on different computers? (I use a macbook pro retina, 2013.)

  • hlin117
    hlin117 over 8 years
    Thanks for the insight. Would throwing in np.int64_t work on every computer? (I know that I asked whether throwing in dtype=np.int32 would work on all computers, but this option was in the python code. I'm wondering whether the np.int64_t option you provided above works on all computers, given it's cython code.)
  • CT Zhu
    CT Zhu over 8 years
    I think so. Because it is in the function declaration, as long as we pass a np.int64 array to it, it will do fine. How internally np.int64_t would be translated into C type it numpy's problem, not our problem (and I would trust it has already been taken care of, :P). Sorry this is not a definitive answer, but I have seen this usage in tutorials and other peoples' code quite often.
  • DavidW
    DavidW over 8 years
    I believe the memoryview syntax is now preferred to declaring it as a numpy array (it works more generally, and at the basically same speed). The point about the np.int64 is right though.