Skip to main content

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


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)

Uploaded Source

Built Distribution

cooodecooo-0.10-py3-none-any.whl (26.3 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page