12

I'm creating a project that uses Python OpenCV. My image processing is a bit slow, so I thought I can made the code faster by creating a .pyd file (I read that somewhere).

I am able to create a .c file using Cython, but how to make a .pyd? While they are a kind of .dll, should I make a .dll first and convert it? And I think they're not platform-independent, what are equivalents on Unix?

Thanks for any help!

linusg
  • 6,289
  • 4
  • 28
  • 78

4 Answers4

13

You have to run a setup.py file in a terminal. This one is an example that uses numpy

try:
    from setuptools import setup
    from setuptools import Extension
except ImportError:
    from distutils.core import setup
    from distutils.extension import Extension

from Cython.Distutils import build_ext
import numpy as np

ext_modules = [Extension("my_code_cython",["my_code_cython.pyx"]),
               Extension("another_code_cython",["another_code_cython.pyx"])]

setup(
    name= 'Generic model class',
    cmdclass = {'build_ext': build_ext},
    include_dirs = [np.get_include()],
    ext_modules = ext_modules)

In the terminal (cmd in Windows) you have to execute the command

python setup.py build_ext --inplace

It is important that I suppose you have installed the compiler (Microsoft Visual C++ Compiler Package for Python 2.7 for example). You can find more information in https://github.com/cython/cython/wiki/CythonExtensionsOnWindows

sebacastroh
  • 608
  • 4
  • 13
  • 1
    Thanks for that, I've figured it out already :). Can I use this on *nix to create `.so` files using gcc? – linusg Apr 30 '16 at 10:17
  • 2
    Yes, that's the code I use on both Windows and *nix (Ubuntu in my case) – sebacastroh May 01 '16 at 02:31
  • The issue with this, at least for me, is that I do not know how to specify a different compiler using `setuptools` (or `distutils`). For example, an Intel compiler in Windows. – Breno Aug 19 '21 at 01:00
  • is this still the latest answer - I tried using the code above (modified with my .py file name) and it kinda just gets stuck with the warning: xxxx\Cython\Compiler\Main.py:369 FutureWarning: Cython directive 'language_level' not set ........... tree = Parsing.p_moduile(s, pxd, full_module_name) – Salvatore Jan 04 '23 at 02:19
1

If you try to find your answer using cython with Visual Studio to convert python code into pyd( Python Dynamic Module ) then, you will have a blurry answer. As, visual code that you expect to work might not due to compatibility issue with later versions. For instance, 1900, 1929 of msvc.

You will need to edit cygwin-compiler in disutils to get things done. If you want to use MingW then also you need to include the configuration of compiler used in disutils.

A very simple way is that we can use Nuitka, it is very simplifed and reliable to convert python code into C and Python Dynamic Library. No configuration, no support addition required.

Let's grab basics

1). Install nuitka, pip install nuitka

2). Install MingW, from Sourceforge

3). Add mingW to path

And everything is good to go now. 4).Open cmd as admin, type python -m nuitka --module file.py

Nuitka will create file.c, file.pyi(For imports) and file.cp39_architecture.pyd in current directory. From file.pyd you can import the module directly into your main.py and it will be lightning fast.

But, it you want to create standalone application then try, python -m nuitkafile.py

PyGuy
  • 51
  • 3
1

Prerequisites
Cython
MinGW-w64 added to your PATH environment variable

You need to add a function called inityourfilename to your .py file Then have to make a .c file by

cython --embed yourfile.py

Then you need to compile it into a .o file using gcc replace the text after -I with the path to your Python include folder

If your MinGW is 64 bit then this command

gcc -mdll -O -Wall -IC:\\Users\\yourusername\\AppData\\Local\\Programs\\Python\\Python39\\include -c -DMS_WIN64 yourfile.c

If your MinGW is 32 bit remove the -DMS_WIN64 flag

To make the .pyd file from .o file

gcc -shared -LC:\\Users\\yourusername\\AppData\\Local\\Programs\\Python\\Python39\\libs yourfile.o -lpython39 -o yourfile.pyd   

Replace text after -L with path to your libs folder
Replace -lpython39 with your python version ie -lpython38 if you have python 3.8

Now check your .pyd file by importing it into another file

Anonymous
  • 596
  • 1
  • 9
  • 26
0

Use cythonize with respective dependencies:

from setuptools.extension import Extension
extensions.append(Extension("write the file names.pyx"))
from Cython.Build import cythonize
ext_modules = cythonize(extensions)

then,

setup(ext_modules=ext_modules, **setup_kwargs)
hp_elite
  • 158
  • 1
  • 6