stranger0612
stranger0612

Reputation: 301

cython prints wrong values of numbers bigger than 65535

I recognized a strange behavior of numbers passed to a function in cython with a value bigger than 65535. But this only appears if a pass those numbers to a function. If I define them like

cdef long long a = 145574697

everything works fine. To clarify my issue I pass the two dummy functions I used to investigate this problem

def bigNum1():
    cdef long long a = 500000
    cdef long long b = 10547746498
    cdef long long c = 65536
    cdef long long d = 65535
    print(a, b, c, d)


def bigNum2(long long a, long long b, long long c, long long d):
    print(a, b, c, d)

And the "setup.py" which was called to get the ".pyd" file.

from distutils.core import setup
from Cython.Build import cythonize


setup(
    ext_modules = cythonize("bigNumbers.pyx")
)

Afterwards I created the ".pyd" file with the command

python setup.py build_ext --inplace

using the command prompt. The used c compiler was gcc.

If I then call either "bigNum1" or "bigNum2" the following output will result.

bigNum1: (500000, 10547746498, 65536, 65535)
bigNum2: (41248, 442029762, 0, 65535).

As you see, all numbers bigger than 65535 are displayed wrong, using bigNum2. Followed you see the call of this functions.

import bigNumbers

bigNumbers.bigNum1()

a = 500000
b = 10547746498
c = 65536
d = 65535


bigNumbers.bigNum2(a, b, c, d)

I hope you understand my issue. My guess is, that I made a wrong declartion in bigNum2 that results in a wrong type or I have to make some kind of typecast before I pass the number to this method.

EDIT:

This is the text displayed during the process of the cmd prompt

python setup.py build_ext --inplace
Compiling bigNumbers.pyx because it changed.
[1/1] Cythonizing bigNumbers.pyx
running build_ext
building 'bigNumbers' extension
D:\WinPython3610\cgg64Bit\bin\gcc.exe -mdll -O -Wall -ID:\WinPython3610\python-3
.6.1.amd64\include -ID:\WinPython3610\python-3.6.1.amd64\include -c bigNumbers.c
 -o build\temp.win-amd64-3.6\Release\bignumbers.o
writing build\temp.win-amd64-3.6\Release\bigNumbers.cp36-win_amd64.def
D:\WinPython3610\cgg64Bit\bin\gcc.exe -shared -s build\temp.win-amd64-3.6\Releas
e\bignumbers.o build\temp.win-amd64-3.6\Release\bigNumbers.cp36-win_amd64.def -L
D:\WinPython3610\python-3.6.1.amd64\libs -LD:\WinPython3610\python-3.6.1.amd64\P
Cbuild\amd64 -lpython36 -lvcruntime140 -o L:\User\neon3_worksp
ace\CythonSource\src\bigNumbers.cp36-win_amd64.pyd

EDIT2:

I use the Winpython package "WinPython 3.6.1.0Qt5-64bit" which comes with cython 0.25.2. But I upgraded it with pip to gain the newest version.

First of all i tried to get my .pyd using the tutorial here.

http://docs.cython.org/en/latest/src/quickstart/build.html

But during the build I got an error message "error: Unable to find vcvarsall.bat". That why I decided to use Mingw with gcc. But this also created an error, which is described on this post.

ValueError: Unknown MS Compiler version 1900

And I solved it with the answer of Indrajit Kanjilal. And there we are now. I can create a .pyd file, can call the function, but if the value is bigger than 65535 the error occurs. Hope that helps.

Upvotes: 1

Views: 311

Answers (1)

danny
danny

Reputation: 5270

In short, don't mix compilers when linking.

The issue here is not related to Cython but with using

  1. Visual Studio built Python distribution
  2. MingW GCC built Python extension

and linking them together. Due to compiler implementation differences, in particular for the above Visual Studio implements long ints differently, this will break in various fun ways.

When writing Python extensions, best to always use the same compiler as was used for the Python distribution to build the extensions.

For the official Python distributions these are Visual Studio 9 to 15 for Py 2.6 to 3.6 - see Which Microsoft Visual C++ compiler to use with a specific Python version on the Python wiki.

Solution is either to use Visual Studio 15.0 (aka VS 2014, used for Python 3.6), or to use a conda environment which builds everything including Python with GCC.

Upvotes: 1

Related Questions