1

I'm trying to generate a python wrapper for my C code with swig4. As I do not have any experience I'm having some issues converting a numpy-array to a c array and returning a numpy-array from a c array.

Here is my repository with all my code: https://github.com/FelixWeichselgartner/SimpleDFT

void dft(int *x, float complex *X, int N) {
    X = malloc(N * sizeof(float complex));
    float complex wExponent = -2 * I * pi / N;
    float complex temp;
    for (int l = 0; l < N; l++) {
        temp = 0 + 0 * I;
        for (int k = 0; k < N; k++) {
            temp = x[k] * cexp(wExponent * k * l) + temp;
        }
        X[l] = temp/N;
    }
}

This is what my C function looks like. int *x is a pointer to a integer array with the length N. float complex *X will be allocated by the function dft with the length of N.

/* File: dft.i */
%module dft

%{
    #define SWIG_FILE_WITH_INIT
    #include "dft.h"
%}

%include "numpy.i"

%init %{
    import_array();
%}

%apply (int * IN_ARRAY1, int DIM1) {(int *x, int N)}
%apply (float complex * ARGOUT_ARRAY1, int DIM1) {(float complex *X, int N)}

%include "dft.h"

This is what my swig file looks like. I guess the %apply part in the end is false, but I have no idea how to match this.

When I build my project by executing my build.sh file the created wrapper looks like this:

def dft(x, X, N):
    return _dft.dft(x, X, N)

Here I can see that swig did not recognize my %apply as I want it to look like this

def dft(x):
    # N is len(x)
    # do some stuff
    return X # X is a numpy.array() with len(X) == len(x)

I want to use it like this:

X = dft(x)

Obviously I get this error by executing:

File "example.py", line 12, in <module>
    X = dft(x)
TypeError: dft() missing 2 required positional arguments: 'X' and 'N'

Do I have to write my own typemap or is it possible for me to use numpy.i. And how would a typemap with an IN_ARRAY1 and ARGOUT_ARRAY1 in one function work.

Thanks for your help.

1 Answer 1

1

I was working on something similar and saw that this post had no answer. Then I realized that @schnauzbartS had already solved it and his codes are on his github (linked in the question), which is a good example.

I think a simple example people might find useful if the question is about how to typemap with IN_ARRAY1 and ARGOUT_ARRAY1 is this page:

%apply (double* IN_ARRAY1    , int DIM1) {(double* vec , int m)};
%apply (double* ARGOUT_ARRAY1, int DIM1) {(double* vec2, int n)};

Caveat: I struggled with my code a bit until I realized that IN_ARRAY from python has to be in the format of float32 not 64 (in my case it was float array). Not sure why. Another thing I found was that ARGOUT_ARRAY always needs the integer input for the size of array. So from my python end, I ended up with calling the function

myswigfunc(outarraysize,inarray,inarray2)

where outarraysize is for ARGOUT_ARRAY and the other inputs are IN_ARRAY_1 and _2 for example.

Sign up to request clarification or add additional context in comments.

2 Comments

TY for your response :). I posted six month ago how i solved it and that the solution is in my repo but @stackoverflow.com/users/100297/martijn-pieters seems to have deleted my post. Not sure why...
Oh! I see! :) Yes, I am glad that your repo is linked up there, it will definitely save lots of time for some people!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.