Skip to content

Update for Cython 3.x #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2499dfc
Add cellular automata example
gjbex May 7, 2022
3ace8f2
Fix typos, remove Python 2.x compatibility
gjbex Dec 14, 2022
4c17f7c
Merge remote-tracking branch 'origin/development' into development
gjbex Dec 14, 2022
d9e5d02
Remove Powerpoint, add notebook from table of contents
gjbex Dec 14, 2022
6c112c9
Add cdef class example
gjbex Dec 14, 2022
67c66d3
Add cdef class example
gjbex Dec 14, 2022
dc9cd02
Merge branch 'development' of github.com:gjbex/Python-for-HPC into de…
gjbex Dec 14, 2022
4b0ac8d
Update MPI specs
gjbex Dec 15, 2022
3612cfa
Update for Cython 3.x
gjbex Oct 30, 2023
661639c
Adapt for Cython 3.x
gjbex Oct 30, 2023
c9e1ac0
Adapt for Cython 3.x
gjbex Oct 30, 2023
81e6016
Adapt for Cython 3.x
gjbex Oct 31, 2023
962c4bf
Add C artifact to gitignore and make file
gjbex Nov 21, 2023
60afc9c
Adapt for Cython 3.x
gjbex Nov 23, 2023
7d17ec4
Simplify code
gjbex Nov 23, 2023
2d95302
Add pure Python implementation
gjbex Nov 23, 2023
b09f5af
Add timing for pure Python Cython implementation
gjbex Nov 23, 2023
d533eb0
Add comparison between cythonized and pure Python
gjbex Nov 23, 2023
171e448
Update README
gjbex Nov 23, 2023
05ce19c
Redo profile
gjbex Nov 23, 2023
e3569b1
Add CMake build files
gjbex Nov 23, 2023
8f9b017
Remove old build step
gjbex Nov 23, 2023
cc11976
Add language specification
gjbex Nov 23, 2023
634dda3
Fix CMake file
gjbex Nov 23, 2023
98c62eb
Remove C file
gjbex Nov 23, 2023
d179ef2
Adapt for Cython 3.x
gjbex Nov 23, 2023
d1e0feb
Add pure Python Cython implementation
gjbex Nov 23, 2023
5bfcddd
Adapt for Cython 3.x
gjbex Nov 24, 2023
17a86be
Fix typo
gjbex Nov 28, 2023
26830d8
Add malloc example
gjbex Dec 4, 2023
905a141
Add numpy performance tests
gjbex Dec 4, 2023
91d6982
Add pure Python implementation
gjbex Dec 4, 2023
9172fc9
Add illustration of Cython classes
gjbex Dec 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified python_for_hpc.pptx
Binary file not shown.
1 change: 1 addition & 0 deletions source-code/cython/Classes/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
points.c
12 changes: 12 additions & 0 deletions source-code/cython/Classes/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
VERSION = cpython-311-x86_64-linux-gnu
POINTS_LIB = points.$(VERSION).so
POINTS_PURE_LIB = points_pure.$(VERSION).so

all: $(POINTS_LIB)

$(POINTS_LIB): points.pyx points_pure.py
python setup.py build_ext --inplace

clean:
python setup.py clean
$(RM) points.c points_pure.c $(POINTS_LIB) $(POINTS_PURE_LIB)
22 changes: 22 additions & 0 deletions source-code/cython/Classes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Classes

Illustration of using Cython extension types (aka cdef classes).

## What is it?

1. `points.pyx`: implementation of a cdef class, and a Python
child class thereof.
1. `points_pure.py`: implementation in Cython's pure Python
syntax.
1. `points_python.py`: Python implementation of the class.
1. `driver.py`: Python script that uses both classes.
1. `setup.py`: Python installation file to build the Cython
extension.
1. `distances_cython.py`: Python script to compute distances between
points using Cython class.
1. `distances_python.py`: Python script to compute distances between
points using Python class.
1. `distances_internal.py`: Python script to compute distances between
points using Cython class, computing the distances using a static
class method..
1. `Makefile`: make file to build the extension.
28 changes: 28 additions & 0 deletions source-code/cython/Classes/distances_cython.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env python

import argparse
import itertools
import pyximport
pyximport.install(pyimport=True, language_level='3str')
from points_pure import Point
import random


def main():
arg_parser = argparse.ArgumentParser(description='compute distances')
arg_parser.add_argument('--n', type=int, default=10,
help='number of points')
options = arg_parser.parse_args()
points = [Point(random.random(), random.random()) for _ in range(options.n)]
min_distance = 2.0
max_distance = 0.0
for i, p1 in enumerate(points):
for p2 in points[i+1:]:
d = p1.distance(p2)
min_distance = min(d, min_distance)
max_distance = max(d, max_distance)
print(f'min. distance: {min_distance}')
print(f'max. distance: {max_distance}')

if __name__ == '__main__':
main()
22 changes: 22 additions & 0 deletions source-code/cython/Classes/distances_internal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env python

import argparse
import itertools
import pyximport
pyximport.install(pyimport=True, language_level='3str')
from points_pure import Point
import random


def main():
arg_parser = argparse.ArgumentParser(description='compute distances')
arg_parser.add_argument('--n', type=int, default=10,
help='number of points')
options = arg_parser.parse_args()
points = [Point(random.random(), random.random()) for _ in range(options.n)]
min_distance, max_distance = Point.min_max_distance(points)
print(f'min. distance: {min_distance}')
print(f'max. distance: {max_distance}')

if __name__ == '__main__':
main()
26 changes: 26 additions & 0 deletions source-code/cython/Classes/distances_python.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env python

import argparse
import itertools
from points_python import Point
import random


def main():
arg_parser = argparse.ArgumentParser(description='compute distances')
arg_parser.add_argument('--n', type=int, default=10,
help='number of points')
options = arg_parser.parse_args()
points = [Point(random.random(), random.random()) for _ in range(options.n)]
min_distance = 2.0
max_distance = 0.0
for i, p1 in enumerate(points):
for p2 in points[i+1:]:
d = p1.distance(p2)
min_distance = min(d, min_distance)
max_distance = max(d, max_distance)
print(f'min. distance: {min_distance}')
print(f'max. distance: {max_distance}')

if __name__ == '__main__':
main()
11 changes: 11 additions & 0 deletions source-code/cython/Classes/driver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env python

from points import Point, ColoredPoint

p = Point(1.0, -2.0)
print(p)
print(f'point = {p.x}, {p.y}')
print(p.distance())

p1 = ColoredPoint(1.0, -2.0, 'blue')
print(p1.color)
14 changes: 14 additions & 0 deletions source-code/cython/Classes/driver_pure.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env python

import pyximport
pyximport.install(pyimport=True, language_level='3str')

from points_pure import Point, ColoredPoint

p = Point(1.0, -2.0)
print(p)
print(f'point = {p.x}, {p.y}')
print(p.distance())

p1 = ColoredPoint(1.0, -2.0, 'blue')
print(p1.color)
39 changes: 39 additions & 0 deletions source-code/cython/Classes/points.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from libc.math cimport sqrt

cdef class Point:

cdef double _x, _y

def __init__(self, x, y):
self._x = x
self._y = y

cpdef distance(self, other):
return sqrt((self._x - other._x)**2 + (self._y - other._y)**2)

property x:
def __get__(self):
return self._x
def __set__(self, value):
self._x = float(value)

property y:
def __get__(self):
return self._y
def __set__(self, value):
self._y = float(value)


class ColoredPoint(Point):

def __init__(self, x, y, color):
super().__init__(x, y)
self._color = color

@property
def color(self):
return self._color

@color.setter
def color(self, value):
self._color = str(value)
74 changes: 74 additions & 0 deletions source-code/cython/Classes/points_pure.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import cython
from cython.cimports.libc.math import sqrt


@cython.cfunc
def _min_max_distance(points: cython.list) -> cython.tuple[cython.double, cython.double]:
min_distance : cython.double = 2.0
max_distance : cython.double = 0.0
for i in range(len(points)):
p1 : Point = points[i]
for j in range(i+1, len(points)):
p2 : Point = points[j]
distance = sqrt((p1._x - p2._x)*(p1._x - p2._x) + (p1._y - p2._y)*(p1._y - p2._y))
if distance < min_distance:
min_distance = distance
if distance > max_distance:
max_distance = distance
return min_distance, max_distance


@cython.cclass
class Point:

_x: cython.double
_y: cython.double

def __init__(self, x: cython.double, y: cython.double) -> None:
self._x = x
self._y = y

@cython.ccall
def distance(self, other: Point) -> cython.double:
return sqrt((self._x - other._x)*(self._x - other._x) + (self._y - other._y)*(self._y - other._y))

@staticmethod
def min_max_distance(points: list) -> tuple[float, float]:
return _min_max_distance(points)

@property
def x(self) -> cython.double:
return self._x

@x.setter
def x(self, value: cython.double) -> None:
self._x = float(value)

@property
def y(self) -> cython.double:
return self._y

@y.setter
def y(self, value: cython.double) -> None:
self._y = float(value)

def __str__(self) -> str:
return f"Point({self.x}, {self.y})"


class ColoredPoint(Point):

def __init__(self, x, y, color):
super().__init__(x, y)
self._color = color

@property
def color(self):
return self._color

@color.setter
def color(self, value):
self._color = str(value)

def __str__(self):
return f"ColoredPoint({self.x}, {self.y}, {self.color})"
50 changes: 50 additions & 0 deletions source-code/cython/Classes/points_python.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from math import sqrt

class Point:

_x: float
_y: float

def __init__(self, x: float, y: float) -> None:
self.x = x
self.y = y

def distance(self, other) -> float:
return sqrt((self.x - other.x)*(self.x - other.x) + (self.y - other.y)*(self.y - other.y))

@property
def x(self) -> float:
return self._x

@x.setter
def x(self, value: float) -> None:
self._x = float(value)

@property
def y(self) -> float:
return self._y

@y.setter
def y(self, value: float) -> None:
self._y = float(value)

def __str__(self) -> str:
return f"Point({self.x}, {self.y})"


class ColoredPoint(Point):

def __init__(self, x, y, color):
super().__init__(x, y)
self._color = color

@property
def color(self):
return self._color

@color.setter
def color(self, value):
self._color = str(value)

def __str__(self):
return f"ColoredPoint({self.x}, {self.y}, {self.color})"
9 changes: 9 additions & 0 deletions source-code/cython/Classes/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env python

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

setup(
ext_modules=cythonize(['points.pyx', 'points_pure.py'],
language_level='3str')
)
1 change: 1 addition & 0 deletions source-code/cython/HelloWorld/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hello_world.c
22 changes: 22 additions & 0 deletions source-code/cython/HelloWorld/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
cmake_minimum_required(VERSION 3.22)

project(HelloWorld LANGUAGES C)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
find_package(Cython REQUIRED)
find_package(PythonExtensions REQUIRED)
# include_directories(${PYTHON_INCLUDE_DIRS})

add_cython_target(hello_world hello_world.pyx PY3 OUTPUT_VAR hello_world_src)
add_library(hello_world MODULE ${hello_world_src})
target_include_directories(hello_world PRIVATE ${PYTHON_INCLUDE_DIRS})
set_target_properties(hello_world PROPERTIES PREFIX "")

install(TARGETS hello_world DESTINATION .)
install(FILES say_hello.py
DESTINATION .
RENAME say_hello
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)
5 changes: 3 additions & 2 deletions source-code/cython/HelloWorld/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION = cpython-34m
VERSION = cpython-311-x86_64-linux-gnu
HELLO_WORLD_LIB = hello_world.$(VERSION).so

all: $(HELLO_WORLD_LIB)
Expand All @@ -8,4 +8,5 @@ $(HELLO_WORLD_LIB): hello_world.pyx

clean:
python setup.py clean
rm -f hello_world.c $(HELLO_WORLD_LIB)
$(RM) $(HELLO_WORLD_LIB) hello_world.c
$(RM) -r build
Loading