A decorator that compiles C/C++ functions with Clang in Python
Project description
A decorator that compiles C/C++ functions with Clang in Python
Like Numba, but Jerry-built and pre-alpha :)
pip install cooodecooo
Tested against Windows 10 / Python 3.10 / Anaconda
Here are 2 examples:
Find RGB colors
import cv2
import numpy as np
from cooodecooo import ccoo
# The name of the variable needs to be `clangpath`, if you change it, it won't work
clangpath = r"C:\Program Files\LLVM\bin\clang.exe"
# The names of the 2 functions (Python / C) need to be equal (colorsearch2 - colorsearch2)
@ccoo
def colorsearch2(**kwargs): # put here always **kwargs
# The variable that contains the C source code must be named - c_source_code -
c_source_code = r"""
__declspec(dllexport) void colorsearch2(unsigned char *pic, unsigned char *colors, int width, int totallengthpic, int totallengthcolor, int *outputx, int *outputy, int *lastresult) {
int counter = 0;
for (int i = 0; i <= totallengthcolor; i += 3) {
int r = i;
int g = i + 1;
int b = i + 2;
for (int j = 0; j <= totallengthpic; j += 3) {
if ((colors[r] == pic[j]) && (colors[g] == pic[j + 1]) && (colors[b] == pic[j + 2])) {
int dividend = j / 3;
int quotient = dividend / width;
int remainder = dividend % width;
int upcounter = counter;
outputx[upcounter] = quotient;
outputy[upcounter] = remainder;
lastresult[0] = upcounter;
counter++;
}
}
}
}
"""
# Where do you want to save the shared library? The name of the variable cannot be changed! It needs to be - c_save_path -
c_save_path = "cloop.so"
# That's it, no return value! Scroll down for more details.
def get_pixelcolor(pic, colors):
totallenghtpic = (pic.shape[0] * pic.shape[1] * pic.shape[2]) - 1
totallengthcolor = (colors.shape[0] * colors.shape[1]) - 1
outputx = np.zeros(totallenghtpic, dtype=np.int32)
outputy = np.zeros(totallenghtpic, dtype=np.int32)
lastresult = np.zeros(1, dtype=np.int32)
# Use the same signature as in the C function # unsigned char *pic, unsigned char *colors, int width, int totallengthpic, int totallengthcolor, int *outputx, int *outputy, int *lastresult
# Pointers only work when numpy arrays are passed to the function
varstopass = {
"pic": pic,
"colors": colors,
"width": pic.shape[1],
"totallengthpic": totallenghtpic,
"totallengthcolor": totallengthcolor,
"outputx": outputx,
"outputy": outputy,
"lastresult": lastresult,
}
# The compiled function doesn't return anything, it writes the results in given numpy arrays by using pointers
# In this example: outputx/outputy/lastresult
_ = colorsearch2(**varstopass)
return np.dstack([outputx[: lastresult[0] + 1], outputy[: lastresult[0] + 1]])[0]
picx = r"C:\Users\hansc\Downloads\pexels-alex-andrews-2295744.jpg"
pic = cv2.imread(picx)
colors = np.array(
[
(66, 71, 69),
(62, 67, 65),
(144, 155, 153),
(52, 57, 55),
(127, 138, 136),
(53, 58, 56),
(51, 56, 54),
(32, 27, 18),
(24, 17, 8),
],
dtype=np.uint8,
)
resu = get_pixelcolor(pic, colors)
Levenshtein Distance
import numpy as np
from cooodecooo import ccoo
clangpath = r"C:\Program Files\LLVM\bin\clang.exe"
@ccoo
def levenshtein_distance(**kwargs):
c_source_code = r"""
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int minim(int a, int b, int c)
{
int m = a;
if (b < m)
m = b;
if (c < m)
m = c;
return m;
}
__declspec(dllexport) void levenshtein_distance(char *s1, char *s2, int len1, int len2, int *resultsx)
{
//printf("%d %d\n", len1, len2);
int *d = (int *)malloc((len1 + 1) * (len2 + 1) * sizeof(int));
int i, j;
for (i = 0; i <= len1; i++)
d[i * (len2 + 1) + 0] = i;
for (j = 0; j <= len2; j++)
d[0 * (len2 + 1) + j] = j;
for (i = 1; i <= len1; i++)
{
for (j = 1; j <= len2; j++)
{
//printf("%c %c\n", s1[i - 1], s2[j - 1]);
//fflush(stdout);
int cost = (s1[i - 1] == s2[j - 1]) ? 0 : 1;
d[i * (len2 + 1) + j] = minim((d[(i - 1) * (len2 + 1) + j] + 1),
(d[i * (len2 + 1) + (j - 1)] + 1),
(d[(i - 1) * (len2 + 1) + (j - 1)] + cost));
}
}
resultsx[0] = d[len1 * (len2 + 1) + len2];
printf("%d\n", resultsx[0]);
free(d);
}
"""
c_save_path = "levete.so"
s01 = ("kitten").encode()
s02 = ("sitting").encode()
s1 = np.array(list(s01), dtype=np.uint8)
s2 = np.array(list(s02), dtype=np.uint8)
len1 = len(s1)
len2 = len(s2)
resultsx = np.array([0], dtype=np.int32)
_ = levenshtein_distance(s1=s1, s2=s2, len1=len1, len2=len2, resultsx=resultsx)
print(resultsx)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
cooodecooo-0.10.tar.gz
(25.5 kB
view hashes)
Built Distribution
cooodecooo-0.10-py3-none-any.whl
(26.3 kB
view hashes)
Close
Hashes for cooodecooo-0.10-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d8d786990680242160939b50f75c146e8cc999857cae260d71974f9737b4f025 |
|
MD5 | cf9b8b0c2f8edefab81777e1fd4aa4cb |
|
BLAKE2b-256 | ed13d56f63773154cec371b02975356fe2d0a2c45f5732c50c30c36a95233d53 |