Thursday, June 24, 2021

Create Basic Python C++ Extensions on Fedora Linux 34

Building  Fibonacci sequence is supposed to be performed by C++ code below as a procedure invoked from Python via Python API. 

Vectors are part of STL. Vectors in C++ are sequence containers representing arrays that can change their size during runtime . They use contiguous storage locations for their elements just as efficiently as in arrays, which means that their elements can also be accessed using offsets on regular pointers to its elements.

(.env) [boris@fedora33server FIBOPLUS]$ cat fibos.h

#pragma once
#include <vector>
#include <cstddef>

namespace xps {

std::vector<int> fibosList(int lim_up) ;

}  // namespace xps

(.env) [boris@fedora33server FIBOPLUS]$ cat fibos.cpp
#include <iostream>
#include <vector>
#include "fibos.h"

namespace xps {

int cpp_fib(int n)
{
    if (n < 2)
        return n;
    else
        return cpp_fib(n-1)+cpp_fib(n-2);
}

std::vector<int>  fibosList(int lim_up)
{    
    std::vector<int> result;
    int n;
    for(n=0; n <= lim_up; n++)
    {
           result.push_back(cpp_fib(n));
    }
    return result;
 }
} //namespace

(.env) [boris@fedora33server FIBOPLUS]$ cat fibos_wrapper.cpp
#include <Python.h>
#include <iostream>
#include <vector>
#include "fibos.h"
#pragma GCC diagnostic ignored "-Wsign-compare"

// Our Python binding to our C function
extern "C"{}

namespace {

static PyObject *fibos(PyObject* self, PyObject* args)
{
    int m;
    if(!PyArg_ParseTuple(args,"i",&m))
        return NULL;

    std::vector<int>fibos = xps::fibosList(m);
    PyObject* result = PyList_New(fibos.size());
    for(int i = 0; i < fibos.size(); i++) {
        PyList_SetItem(result, i, PyLong_FromLong(fibos[i]));
    }
    return result;
}

// Our Module's Function Definition struct
// We require this `NULL` to signal the end of our method
// definition
static PyMethodDef myMethods[] = {
    { "fibos", fibos, METH_VARARGS, "Calculate prime numbers" },
    { NULL, NULL, 0, NULL }
};

// Our Module Definition struct
static struct PyModuleDef myModule = {
    PyModuleDef_HEAD_INIT,
    "myModule",
    "Test Module",
    -1,
    myMethods
};

// Initializes our module using our above struct
PyMODINIT_FUNC PyInit_myModule(void)
{
    return PyModule_Create(&myModule);
};
} // namespace
(.env) [boris@fedora33server FIBOPLUS]$ cat setup.py
from distutils.core import setup, Extension
import sysconfig

language = 'c++'
std = 'c++17'
default_compile_args = sysconfig.get_config_var('CFLAGS').split()
extra_compile_args = [f"-std={std}", "-Wall", "-Wextra", "-Werror", "-DNDEBUG", "-O3"]
setup(name = 'myModule', version = '1.0',  \
   ext_modules = [Extension('myModule', ['fibos_wrapper.cpp','fibos.cpp'])])
   
(.env) [boris@fedora33server FIBOPLUS]$ python setup.py install
running install
running build
running build_ext
building 'myModule' extension
creating build
creating build/temp.linux-x86_64-3.9
gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/home/boris/FIBOPLUS/.env/include -I/usr/include/python3.9 -c fibos.cpp -o build/temp.linux-x86_64-3.9/fibos.o
gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -O2 -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/home/boris/FIBOPLUS/.env/include -I/usr/include/python3.9 -c fibos_wrapper.cpp -o build/temp.linux-x86_64-3.9/fibos_wrapper.o
creating build/lib.linux-x86_64-3.9
g++ -pthread -shared -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -g -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -g build/temp.linux-x86_64-3.9/fibos.o build/temp.linux-x86_64-3.9/fibos_wrapper.o -L/usr/lib64 -o build/lib.linux-x86_64-3.9/myModule.cpython-39-x86_64-linux-gnu.so
running install_lib
copying build/lib.linux-x86_64-3.9/myModule.cpython-39-x86_64-linux-gnu.so -> /home/boris/FIBOPLUS/.env/lib64/python3.9/site-packages
running install_egg_info
Removing /home/boris/FIBOPLUS/.env/lib64/python3.9/site-packages/myModule-1.0-py3.9.egg-info
Writing /home/boris/FIBOPLUS/.env/lib64/python3.9/site-packages/myModule-1.0-py3.9.egg-info

(.env) [boris@fedora33server FIBOPLUS]$ ll
total 24
drwxrwxr-x. 4 boris boris   63 Jun 26 18:41 build
-rw-rw-r--. 1 boris boris  394 Jun 26 18:34 fibos.cpp
-rw-rw-r--. 1 boris boris  131 Jun 26 18:28 fibos.h
-rw-rw-r--. 1 boris boris 1215 Jun 26 18:37 fibos_wrapper.cpp
-rw-rw-r--. 1 boris boris   84 Jun 26 18:06 MyProgList.py
-rw-rw-r--. 1 boris boris  280 Jun 26 17:43 MyProg.py
-rw-rw-r--. 1 boris boris  368 Jun 26 18:31 setup.py
(.env) [boris@fedora33server FIBOPLUS]$ python MyProgList.py

Input upper limit : 11
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
(.env) [boris@fedora33server FIBOPLUS]$ python MyProgList.py

Input upper limit : 13
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233]
(.env) [boris@fedora33server FIBOPLUS]$ python MyProgList.py

Input upper limit : 15
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
(.env) [boris@fedora33server FIBOPLUS]$ python MyProgList.py

Input upper limit : 17
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597]































No comments:

Post a Comment