Skip to content

Commit a6b88da

Browse files
authored
Merge pull request #15 from gjbex/development
Update for Cython 3.x
2 parents 85d5d3d + 9172fc9 commit a6b88da

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+6689
-970
lines changed

python_for_hpc.pptx

-1.15 KB
Binary file not shown.

source-code/cython/Classes/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
points.c

source-code/cython/Classes/Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
VERSION = cpython-311-x86_64-linux-gnu
2+
POINTS_LIB = points.$(VERSION).so
3+
POINTS_PURE_LIB = points_pure.$(VERSION).so
4+
5+
all: $(POINTS_LIB)
6+
7+
$(POINTS_LIB): points.pyx points_pure.py
8+
python setup.py build_ext --inplace
9+
10+
clean:
11+
python setup.py clean
12+
$(RM) points.c points_pure.c $(POINTS_LIB) $(POINTS_PURE_LIB)

source-code/cython/Classes/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Classes
2+
3+
Illustration of using Cython extension types (aka cdef classes).
4+
5+
## What is it?
6+
7+
1. `points.pyx`: implementation of a cdef class, and a Python
8+
child class thereof.
9+
1. `points_pure.py`: implementation in Cython's pure Python
10+
syntax.
11+
1. `points_python.py`: Python implementation of the class.
12+
1. `driver.py`: Python script that uses both classes.
13+
1. `setup.py`: Python installation file to build the Cython
14+
extension.
15+
1. `distances_cython.py`: Python script to compute distances between
16+
points using Cython class.
17+
1. `distances_python.py`: Python script to compute distances between
18+
points using Python class.
19+
1. `distances_internal.py`: Python script to compute distances between
20+
points using Cython class, computing the distances using a static
21+
class method..
22+
1. `Makefile`: make file to build the extension.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env python
2+
3+
import argparse
4+
import itertools
5+
import pyximport
6+
pyximport.install(pyimport=True, language_level='3str')
7+
from points_pure import Point
8+
import random
9+
10+
11+
def main():
12+
arg_parser = argparse.ArgumentParser(description='compute distances')
13+
arg_parser.add_argument('--n', type=int, default=10,
14+
help='number of points')
15+
options = arg_parser.parse_args()
16+
points = [Point(random.random(), random.random()) for _ in range(options.n)]
17+
min_distance = 2.0
18+
max_distance = 0.0
19+
for i, p1 in enumerate(points):
20+
for p2 in points[i+1:]:
21+
d = p1.distance(p2)
22+
min_distance = min(d, min_distance)
23+
max_distance = max(d, max_distance)
24+
print(f'min. distance: {min_distance}')
25+
print(f'max. distance: {max_distance}')
26+
27+
if __name__ == '__main__':
28+
main()
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env python
2+
3+
import argparse
4+
import itertools
5+
import pyximport
6+
pyximport.install(pyimport=True, language_level='3str')
7+
from points_pure import Point
8+
import random
9+
10+
11+
def main():
12+
arg_parser = argparse.ArgumentParser(description='compute distances')
13+
arg_parser.add_argument('--n', type=int, default=10,
14+
help='number of points')
15+
options = arg_parser.parse_args()
16+
points = [Point(random.random(), random.random()) for _ in range(options.n)]
17+
min_distance, max_distance = Point.min_max_distance(points)
18+
print(f'min. distance: {min_distance}')
19+
print(f'max. distance: {max_distance}')
20+
21+
if __name__ == '__main__':
22+
main()
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/usr/bin/env python
2+
3+
import argparse
4+
import itertools
5+
from points_python import Point
6+
import random
7+
8+
9+
def main():
10+
arg_parser = argparse.ArgumentParser(description='compute distances')
11+
arg_parser.add_argument('--n', type=int, default=10,
12+
help='number of points')
13+
options = arg_parser.parse_args()
14+
points = [Point(random.random(), random.random()) for _ in range(options.n)]
15+
min_distance = 2.0
16+
max_distance = 0.0
17+
for i, p1 in enumerate(points):
18+
for p2 in points[i+1:]:
19+
d = p1.distance(p2)
20+
min_distance = min(d, min_distance)
21+
max_distance = max(d, max_distance)
22+
print(f'min. distance: {min_distance}')
23+
print(f'max. distance: {max_distance}')
24+
25+
if __name__ == '__main__':
26+
main()

source-code/cython/Classes/driver.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env python
2+
3+
from points import Point, ColoredPoint
4+
5+
p = Point(1.0, -2.0)
6+
print(p)
7+
print(f'point = {p.x}, {p.y}')
8+
print(p.distance())
9+
10+
p1 = ColoredPoint(1.0, -2.0, 'blue')
11+
print(p1.color)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env python
2+
3+
import pyximport
4+
pyximport.install(pyimport=True, language_level='3str')
5+
6+
from points_pure import Point, ColoredPoint
7+
8+
p = Point(1.0, -2.0)
9+
print(p)
10+
print(f'point = {p.x}, {p.y}')
11+
print(p.distance())
12+
13+
p1 = ColoredPoint(1.0, -2.0, 'blue')
14+
print(p1.color)

source-code/cython/Classes/points.pyx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from libc.math cimport sqrt
2+
3+
cdef class Point:
4+
5+
cdef double _x, _y
6+
7+
def __init__(self, x, y):
8+
self._x = x
9+
self._y = y
10+
11+
cpdef distance(self, other):
12+
return sqrt((self._x - other._x)**2 + (self._y - other._y)**2)
13+
14+
property x:
15+
def __get__(self):
16+
return self._x
17+
def __set__(self, value):
18+
self._x = float(value)
19+
20+
property y:
21+
def __get__(self):
22+
return self._y
23+
def __set__(self, value):
24+
self._y = float(value)
25+
26+
27+
class ColoredPoint(Point):
28+
29+
def __init__(self, x, y, color):
30+
super().__init__(x, y)
31+
self._color = color
32+
33+
@property
34+
def color(self):
35+
return self._color
36+
37+
@color.setter
38+
def color(self, value):
39+
self._color = str(value)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import cython
2+
from cython.cimports.libc.math import sqrt
3+
4+
5+
@cython.cfunc
6+
def _min_max_distance(points: cython.list) -> cython.tuple[cython.double, cython.double]:
7+
min_distance : cython.double = 2.0
8+
max_distance : cython.double = 0.0
9+
for i in range(len(points)):
10+
p1 : Point = points[i]
11+
for j in range(i+1, len(points)):
12+
p2 : Point = points[j]
13+
distance = sqrt((p1._x - p2._x)*(p1._x - p2._x) + (p1._y - p2._y)*(p1._y - p2._y))
14+
if distance < min_distance:
15+
min_distance = distance
16+
if distance > max_distance:
17+
max_distance = distance
18+
return min_distance, max_distance
19+
20+
21+
@cython.cclass
22+
class Point:
23+
24+
_x: cython.double
25+
_y: cython.double
26+
27+
def __init__(self, x: cython.double, y: cython.double) -> None:
28+
self._x = x
29+
self._y = y
30+
31+
@cython.ccall
32+
def distance(self, other: Point) -> cython.double:
33+
return sqrt((self._x - other._x)*(self._x - other._x) + (self._y - other._y)*(self._y - other._y))
34+
35+
@staticmethod
36+
def min_max_distance(points: list) -> tuple[float, float]:
37+
return _min_max_distance(points)
38+
39+
@property
40+
def x(self) -> cython.double:
41+
return self._x
42+
43+
@x.setter
44+
def x(self, value: cython.double) -> None:
45+
self._x = float(value)
46+
47+
@property
48+
def y(self) -> cython.double:
49+
return self._y
50+
51+
@y.setter
52+
def y(self, value: cython.double) -> None:
53+
self._y = float(value)
54+
55+
def __str__(self) -> str:
56+
return f"Point({self.x}, {self.y})"
57+
58+
59+
class ColoredPoint(Point):
60+
61+
def __init__(self, x, y, color):
62+
super().__init__(x, y)
63+
self._color = color
64+
65+
@property
66+
def color(self):
67+
return self._color
68+
69+
@color.setter
70+
def color(self, value):
71+
self._color = str(value)
72+
73+
def __str__(self):
74+
return f"ColoredPoint({self.x}, {self.y}, {self.color})"
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from math import sqrt
2+
3+
class Point:
4+
5+
_x: float
6+
_y: float
7+
8+
def __init__(self, x: float, y: float) -> None:
9+
self.x = x
10+
self.y = y
11+
12+
def distance(self, other) -> float:
13+
return sqrt((self.x - other.x)*(self.x - other.x) + (self.y - other.y)*(self.y - other.y))
14+
15+
@property
16+
def x(self) -> float:
17+
return self._x
18+
19+
@x.setter
20+
def x(self, value: float) -> None:
21+
self._x = float(value)
22+
23+
@property
24+
def y(self) -> float:
25+
return self._y
26+
27+
@y.setter
28+
def y(self, value: float) -> None:
29+
self._y = float(value)
30+
31+
def __str__(self) -> str:
32+
return f"Point({self.x}, {self.y})"
33+
34+
35+
class ColoredPoint(Point):
36+
37+
def __init__(self, x, y, color):
38+
super().__init__(x, y)
39+
self._color = color
40+
41+
@property
42+
def color(self):
43+
return self._color
44+
45+
@color.setter
46+
def color(self, value):
47+
self._color = str(value)
48+
49+
def __str__(self):
50+
return f"ColoredPoint({self.x}, {self.y}, {self.color})"

source-code/cython/Classes/setup.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env python
2+
3+
from distutils.core import setup
4+
from Cython.Build import cythonize
5+
6+
setup(
7+
ext_modules=cythonize(['points.pyx', 'points_pure.py'],
8+
language_level='3str')
9+
)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
hello_world.c
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
cmake_minimum_required(VERSION 3.22)
2+
3+
project(HelloWorld LANGUAGES C)
4+
5+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
6+
7+
find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
8+
find_package(Cython REQUIRED)
9+
find_package(PythonExtensions REQUIRED)
10+
# include_directories(${PYTHON_INCLUDE_DIRS})
11+
12+
add_cython_target(hello_world hello_world.pyx PY3 OUTPUT_VAR hello_world_src)
13+
add_library(hello_world MODULE ${hello_world_src})
14+
target_include_directories(hello_world PRIVATE ${PYTHON_INCLUDE_DIRS})
15+
set_target_properties(hello_world PROPERTIES PREFIX "")
16+
17+
install(TARGETS hello_world DESTINATION .)
18+
install(FILES say_hello.py
19+
DESTINATION .
20+
RENAME say_hello
21+
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
22+
)
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION = cpython-34m
1+
VERSION = cpython-311-x86_64-linux-gnu
22
HELLO_WORLD_LIB = hello_world.$(VERSION).so
33

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

99
clean:
1010
python setup.py clean
11-
rm -f hello_world.c $(HELLO_WORLD_LIB)
11+
$(RM) $(HELLO_WORLD_LIB) hello_world.c
12+
$(RM) -r build

0 commit comments

Comments
 (0)