Rufen Sie C-Sprachfunktionen von Python auf, um mehrdimensionale Arrays auszutauschen

Einführung

Dieses Mal verwende ich ctypes, um meine eigene C-Funktion von Python aus aufzurufen. Ich hatte keinen japanischen Artikel darüber, wie man eine Variable vom Typ "double **" als Argument einer C-Funktion angibt und das Ergebnis als Typ "double **" an Python zurückgibt, also suchte ich kurz. Um genau zu sein, handelt es sich nicht um einen mehrdimensionalen Array-Austausch, sondern um einen variablen Austausch vom Typ "Double **" (leise).

Code

Bereiten Sie zunächst die folgende selbst erstellte Funktion vor. Dieses Mal werden wir allen Elementen der Argumentmatrix n hinzufügen.

libadd.c


#include <stdio.h>

void add_matrix(double **matrix, int row, int col, int n) {
  int i, j;
  for(i=0; i<row; i++){
      for(j=0; j<col; j++){
	      matrix[i][j] = matrix[i][j] + n;
      }
  }
}

Und kompiliere wie folgt.


$ gcc -cpp -fPIC -shared libadd.c -lm -o libadd.so -O3

Sie müssen "libadd.so" mit der Option -shared erstellen.

Dann Python-Seite,

test.py



from ctypes import *
import ctypes.util  
from numpy.ctypeslib import ndpointer 
import numpy as np
from numpy.random import *

#Die Libadd, die Sie gerade erstellt haben.Geben Sie diese Datei an
lib = np.ctypeslib.load_library("libadd.so",".")

#Mach es richtig
row = 20
col = 5
n = 5
matrix = rand(row, col)

#Bereiten Sie den Zeigertyp des Doppelzeigers vor
_DOUBLE_PP = ndpointer(dtype=np.uintp, ndim=1, flags='C')
#add_matrix()Geben Sie den Typ des Funktionsarguments an(ctypes) 
lib.add_matrix.argtypes = [_DOUBLE_PP, c_int32, c_int32, c_int32]
#add_matrix()Gibt den Wertetyp an, der von der Funktion zurückgegeben wird(Diesmal kein Rückgabewert)
lib.add_matrix.restype = None

#Magie
tp = np.uintp
mpp = (matrix.__array_interface__['data'][0] + np.arange(matrix.shape[0])*matrix.strides[0]).astype(tp)

#int-Typ ist auch c-Typ c_In int-Typ konvertieren und übergeben
n = ctypes.c_int(n)
row = ctypes.c_int(row)
col = ctypes.c_int(col)

print("before:", matrix)

lib.add_matrix(mpp, row, col, n)

print("after:", matrix)

Ich werde es so vorbereiten. Hier sind einige Dinge, auf die Sie achten sollten (wo ich süchtig bin):

Ich dachte auch, dass _DOUBLE_PP mit POINTER (POINTER (c_double)) verwendet werden könnte, aber es wurde nicht mit Bezug auf die C-Seite übergeben. (Bitte sagen Sie mir, ob es eine andere gute Methode gibt.)

Das Ausführungsergebnis ist wie folgt.

Ausführungsergebnis



$ python test.py
before: [[ 0.38897722  0.46313741  0.84976397  0.64423638  0.95435434]
 [ 0.60333226  0.37742093  0.3465723   0.77567722  0.74132703]
 [ 0.87302221  0.43188915  0.1211892   0.03272387  0.16480218]
 [ 0.60387532  0.37643299  0.72456328  0.67993591  0.6592758 ]
 [ 0.63544435  0.7261329   0.16825874  0.11123031  0.97664729]
 [ 0.58328763  0.85650723  0.77429203  0.12418374  0.44881621]
 [ 0.25106831  0.22417529  0.22837031  0.17608283  0.49529552]
 [ 0.75357385  0.3937937   0.99262338  0.23625638  0.37777575]
 [ 0.887013    0.85391559  0.32386967  0.30482811  0.67282479]
 [ 0.96701627  0.23598535  0.29455679  0.37472803  0.28614415]
 [ 0.82208389  0.87058549  0.21354254  0.18766391  0.13951804]
 [ 0.22836767  0.4051488   0.79205244  0.17489158  0.83368298]
 [ 0.99464033  0.91165387  0.48920652  0.69251231  0.3369773 ]
 [ 0.39567888  0.08322727  0.50138724  0.00972839  0.53206287]
 [ 0.4981778   0.81622292  0.73376253  0.19702753  0.56725497]
 [ 0.37709128  0.8219189   0.59531858  0.60284025  0.75683106]
 [ 0.11898215  0.93335749  0.39432259  0.9733907   0.355181  ]
 [ 0.54600745  0.36843876  0.52919308  0.22250149  0.66595212]
 [ 0.33897066  0.68039774  0.89937153  0.77007464  0.57667845]
 [ 0.08015923  0.42939639  0.82431951  0.05494513  0.89979669]]
after: [[ 5.38897722  5.46313741  5.84976397  5.64423638  5.95435434]
 [ 5.60333226  5.37742093  5.3465723   5.77567722  5.74132703]
 [ 5.87302221  5.43188915  5.1211892   5.03272387  5.16480218]
 [ 5.60387532  5.37643299  5.72456328  5.67993591  5.6592758 ]
 [ 5.63544435  5.7261329   5.16825874  5.11123031  5.97664729]
 [ 5.58328763  5.85650723  5.77429203  5.12418374  5.44881621]
 [ 5.25106831  5.22417529  5.22837031  5.17608283  5.49529552]
 [ 5.75357385  5.3937937   5.99262338  5.23625638  5.37777575]
 [ 5.887013    5.85391559  5.32386967  5.30482811  5.67282479]
 [ 5.96701627  5.23598535  5.29455679  5.37472803  5.28614415]
 [ 5.82208389  5.87058549  5.21354254  5.18766391  5.13951804]
 [ 5.22836767  5.4051488   5.79205244  5.17489158  5.83368298]
 [ 5.99464033  5.91165387  5.48920652  5.69251231  5.3369773 ]
 [ 5.39567888  5.08322727  5.50138724  5.00972839  5.53206287]
 [ 5.4981778   5.81622292  5.73376253  5.19702753  5.56725497]
 [ 5.37709128  5.8219189   5.59531858  5.60284025  5.75683106]
 [ 5.11898215  5.93335749  5.39432259  5.9733907   5.355181  ]
 [ 5.54600745  5.36843876  5.52919308  5.22250149  5.66595212]
 [ 5.33897066  5.68039774  5.89937153  5.77007464  5.57667845]
 [ 5.08015923  5.42939639  5.82431951  5.05494513  5.89979669]]

Machen wir das! Toll! Selbst wenn Sie dies tun, wird es je nach Inhalt des Prozesses erheblich schneller sein.

Ich habe das Gefühl, dass ich gelesen habe, dass dies mich von GIL befreien wird, daher würde ich gerne Multithreading, Multiverarbeitung oder Hybrid-Parallel verwenden, aber ... es funktioniert bisher nicht.

Referenz

Recommended Posts

Rufen Sie C-Sprachfunktionen von Python auf, um mehrdimensionale Arrays auszutauschen
Rufen Sie die c-Sprache von Python aus auf (python.h)
C-Sprache zum Anzeigen und Erinnern Teil 2 Rufen Sie die C-Sprache aus der Python-Zeichenfolge (Argument) auf
C-Sprache zum Sehen und Erinnern Teil 1 Rufen Sie die C-Sprache aus Python auf (Hallo Welt)
C-Sprache zum Anzeigen und Erinnern Teil 4 Rufen Sie die C-Sprache von Python (Argument) double auf
C-Sprache zum Anzeigen und Erinnern Teil 5 Rufen Sie die C-Sprache aus dem Python-Array (Argument) auf
[Python] So rufen Sie eine Funktion von c aus Python auf (ctypes edition)
C-Sprache zum Sehen und Erinnern Teil 3 Rufen Sie die C-Sprache aus Python auf (Argument) c = a + b
Rufen Sie Matlab von Python zur Optimierung auf
Rufen Sie C von Python mit DragonFFI auf
Rufen Sie popcount von Ruby / Python / C # auf
Einführung in Protobuf-c (C-Sprache ⇔ Python)
Python, um von einer anderen Sprache zu wechseln
Gehen Sie zur Sprache, um Teil 8 zu sehen und sich daran zu erinnern. Rufen Sie die GO-Sprache von Python aus auf
Rufen Sie C / C ++ von Python auf dem Mac auf
Rufen Sie mit ctypes Ihre eigene gemeinsam genutzte Bibliothek in C-Sprache von Python aus auf
Generieren Sie mit Python eine C-Sprache aus dem S-Ausdruck
Verwenden von C ++ - Funktionen aus Python mit pybind11
Schreiben von Protokollen in eine CSV-Datei (Python, C-Sprache)
So rufen Sie die Cloud-API über GCP-Cloud-Funktionen auf
[Python] Vorsichtsmaßnahmen beim Zuweisen von Werten zu mehrdimensionalen Arrays
Rufen Sie Python-Skripte aus Embedded Python in C ++ / C ++ auf
Ich möchte C ++ - Code aus Python-Code erstellen!
Eine einfache Möglichkeit, Java von Python aus aufzurufen
Änderungen von Python 3.0 zu Python 3.5
Änderungen von Python 2 zu Python 3.0
Einführung in die Python-Sprache
Versuchen Sie, ein Python-Modul in C-Sprache zu erstellen
Rufen Sie CPLEX von Python aus auf (DO cplex)
Post von Python nach Slack
Flirte von PHP nach Python
Anaconda aktualisiert von 4.2.0 auf 4.3.0 (python3.5 aktualisiert auf python3.6)
Studie aus Python Hour3: Funktionen
Wechseln Sie von Python2.7 zu Python3.6 (centos7)
Stellen Sie von Python aus eine Verbindung zu SQLite her
Verwenden Sie eine Skriptsprache für ein komfortables C ++ - Leben - OpenCV-Port Python zu C ++ -
Übergeben Sie die OpenCV-Daten der ursprünglichen C ++ - Bibliothek an Python
Wie man Python oder Julia von Ruby aus aufruft (experimentelle Implementierung)
Portiert von der R-Sprache von "Sazae-sans Janken Data Analysis" nach Python
[Python] Drücken Sie Keras von TensorFlow und TensorFlow von c ++, um die Ausführung zu beschleunigen.
Senden Sie eine Nachricht von IBM Cloud Functions an Slack in Python
Herstellen einer Verbindung zum Cloud Firestore über Google Cloud-Funktionen mit Python-Code
Rufen Sie dlm von Python aus auf, um ein zeitvariables Koeffizientenregressionsmodell auszuführen
Übergeben Sie die Liste von Python an C ++ als Referenz in pybind11
[Es ist noch nicht zu spät, Python ab 2020 zu lernen] Teil 3 Python Language Basic (1)
Post von Python auf Facebook Timeline
[Lambda] [Python] Von Lambda auf Twitter posten!
Stellen Sie von Python aus eine Verbindung zur utf8mb4-Datenbank her
Python (vom ersten Mal bis zur Ausführung)
Poste ein Bild von Python auf Tumblr
10 Funktionen von "Sprache mit Batterie" Python
Tipps zum Aufrufen von Python von C.
Führen Sie Python-Code über die C # -GUI aus
So verpacken Sie C in Python
Führen Sie Python-Skripte synchron von C # aus
Rufen Sie Python von Nim mit Nimpy auf
So greifen Sie über Python auf Wikipedia zu
Hat sich nicht von Python 2 auf 3 geändert