5

I am trying to construct a matrix of python type int, a 64bit signed integer.

cdef matrix33():
    return np.zeros((3,3),dtype=int)

cdef do_stuf(np.ndarray[int, ndim=2] matrix):
    ...
    return some_value

def start():
    print do_stuf(matrix33())

It compiles right, but when I run it I keep getting this error:

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

I can not work with python long's, but I don't know how to properly convert to a 64 int.

UPDATE

Okey. I am quite sure that I used Cython correctly. The code that I wrote was for an minmax search in the game of capture go / atari go.

By far the most called functions are these:

cdef isThere_greedy_move(np.ndarray[np.int64_t, ndim=2]board, int player):
    cdef int i, j
    for i in xrange(len(board)):
        for j in xrange(len(board)):
            if board[i,j] == 0:
                board[i,j] = player
                if player in score(board):
                    board[i,j] = 0
                    return True
                board[i,j] = 0
    return False


# main function of the scoring system.
# returns list of players that eat a stone
cdef score(np.ndarray[np.int64_t, ndim=2] board):
    scores = []
    cdef int i,j
    cdef np.ndarray[np.int64_t, ndim = 2] checked
    checked = np.zeros((board.shape[0], board.shape[1]), dtype = int)
    for i in xrange(len(board)):
        for j in xrange(len(board)):
            if checked[i,j] == 0 and board[i,j] !=0:
                life, newly_checked = check_life(i,j,board,[])
                if not life:
                    if -board[i,j] not in scores:
                        scores.append(-board[i,j])
                        if len(scores) == 2:
                            return scores
                checked = update_checked(checked, newly_checked)
    return scores

# helper functions of score/1
cdef check_life(int i, int j, np.ndarray[np.int64_t, ndim=2] board, checked):
    checked.append((i,j))
    if liberty(i,j,board):
        return True, checked
    for pos in [[1,0],[0,1],[-1,0],[0,-1]]:
        pos = np.array([i,j]) + np.array(pos)
        if check_index(pos[0],pos[1],len(board)) and board[pos[0],pos[1]] == board[i,j] and (pos[0],pos[1]) not in checked:
            life, newly_checked = check_life(pos[0],pos[1],board,checked)
            if life:
                checked = checked + newly_checked             
                return life, checked
    return False, []    # [] is a dummy.

cdef liberty(int i,int j, np.ndarray[np.int64_t, ndim=2] board):
    for pos in [np.array([1,0]),np.array([0,1]),np.array([-1,0]),np.array([0,-1])]:
        pos = np.array([i,j]) - pos
        if check_index(pos[0],pos[1],len(board)) and board[pos[0],pos[1]] == 0:
            return True
    return False

I would really have thought that this would be a chance to shine for cython. To solve 3x3 capture go:

Python 2.7 does a consistent 2.28 seconds, with cython it is a consistent 2.03 Both were tested with the python time module and on an i7 processor of less than 60C°

Now the question for me is if I am going to switch to Haskell or C++ for this project...

1 Answer 1

6

Cython's int type is the same as a C int, i.e. usually (but not necessarily) 32-bit. You should declare the dtype in matrix33 as np.int64 and in do_stuf as its C counterpart, np.int64_t:

cimport numpy as np
import numpy as np

cdef do_stuff(np.ndarray[np.int64_t, ndim=2] matrix):
    pass

cdef matrix33():
    return np.zeros((3,3), dtype=int)

def start():
    print do_stuff(matrix33())
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you, the code now runs correct. But, it runs just as fast as it does when I declare everything long. I know the long object is not fast, as it can not overflow and is treated different (uses more cycles). I would like to use an int that can overflow and that is faster than the python type long.
Also, the speed up over interpreted python is just under 10%, which makes me suspicious that I don't quite have the types right...
@user1020753: the types are right. The speedup depends on what you're doing in your functions.
@user1020753 Your functions are using Python data types - lists, tuples, etc - for most of their operations. For Cython to have a large effect, it needs to be rewritten to use native C data types. Also, it would probably speed things up if you typed your functions. See docs.cython.org/src/quickstart/cythonize.html#typing-functions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.