Using C .dll with complex.h library in Python very slow

332 Views Asked by At

Hello I have a function in Python, which I want to convert to C and use through a .dll.

Currently I am still experimenting and I am very new to this topic, but my main problem is when I use any function from the C library complex.h my code is very slow.

So my Python side looks like this:

import ctypes
import numpy as np
import os
import _ctypes

testnew = ctypes.CDLL("test.dll", winmode=0x8)

# Define the function argument types
testnew.testfunc.argtypes = [
    np.ctypeslib.ndpointer(dtype=np.complex128, ndim=2, flags="C"),  # sigs_in
    ctypes.c_int,  # Nsymb
    ctypes.c_int,  # Nsig
    ctypes.c_int,  # nCPE
    np.ctypeslib.ndpointer(dtype=np.complex128, ndim=2, flags="C"),  # sigs_out
    np.ctypeslib.ndpointer(dtype=np.double, ndim=2, flags="C")  # theta_rec
]

# Define the function return type
testnew.testfunc.restype = None

Nsig, Nsymb = data.shape
nCPE = 100

# Create input and output arrays
sigs_in = data.values
sigs_in = np.ascontiguousarray(sigs_in, dtype=np.complex128)

sigs_out = np.zeros_like(sigs_in)
theta_rec = np.zeros_like( sigs_in, dtype=float )

sigs_out = np.ascontiguousarray(sigs_out, dtype=np.complex128)
theta_rec = np.ascontiguousarray(theta_rec, dtype=np.double)

sigs_in = np.asarray(sigs_in, order='C')
sigs_out = np.asarray(sigs_out, order='C')
theta_rec = np.asarray(theta_rec, order='C')

# Call the function
testnew.testfunc(sigs_in, Nsymb, Nsig, nCPE, sigs_out, theta_rec)

# Print the results
print("sigs_out:")
print(sigs_out)
print("theta_rec:")
print(theta_rec)

_ctypes.FreeLibrary(testnew._handle)

And my C Code (still in development) looks like this:

#include <stdlib.h>
#define _USE_MATH_DEFINES
#include <math.h>
#include <stdio.h>
#include <complex.h>

#if defined(_WIN32)
#  define DLL00_EXPORT_API __declspec(dllexport)
#else
#  define DLL00_EXPORT_API
#endif

DLL00_EXPORT_API void testfunc(complex double *sigs_in, int Nsymb, int Nsig, int nCPE, complex double *sigs_out, double *theta_rec) {
    
    for (int i = 0; i < Nsig*Nsymb; i += Nsymb) {
        int start = (i - Nsymb*nCPE) > 0 ? (i - Nsymb*nCPE) : 0;
        int stop = (i + Nsymb*nCPE) < (Nsymb*Nsig - 2) ? (i + Nsymb*nCPE) : (Nsymb*Nsig - 2);
        double complex sumv1 = 0;
        double complex sumv2 = 0;

        for (int j = start; j < stop; j++) {
            sumv1 += cpow((sigs_in[j + 0] / cabs(sigs_in[j + 0] )), 4);
            sumv2 += cpow((sigs_in[j + 1] / cabs(sigs_in[j + 1] )), 4);
           
        }
        theta_rec[i] = carg(sumv1); //  the function carg() slows down my code a lot
    }
}

As mentioned above for example the function carg() or creal etc. slow down my code a lot. For comparison when I just remove the line theta_rec[i] = carg(sumv1); the execution takes 0.3 s while with the line it takes over 10 s.

Is there anything I could change? When I use the functions in C alone, I don't encounter these issues.

Thanks in advance.

UPDATE: I realised that somehow all the complex.h functions like cpow and also cabs slowed down the code a lot so I decided to implement them myself which helped me a lot. Running the code in C alone works just fine.

0

There are 0 best solutions below