Mon but:
Créez 3 tableaux numpy en python (2 d'entre eux seront initialisés avec des valeurs spécifiques), puis envoyez-les tous les trois via swig dans une fonction c ++ en tant que références vectorielles (ceci afin d'éviter de copier les données et de perdre en efficacité). Une fois dans la fonction c ++, ajoutez 2 des tableaux et mettez leur somme dans le 3e tableau.
vec_ref.h
#include <vector>
#include <iostream>
void add_vec_ref(std::vector<int>& dst, std::vector<int>& src1, std::vector<int>& src2);
vec_ref.cpp
#include "vec_ref.h"
#include <cstring> // need for size_t
#include <cassert>
void add_vec_ref(std::vector<int>& dst, std::vector<int>& src1, std::vector<int>& src2) {
std::cout << "inside add_vec_ref" << std::endl;
assert(src1.size() == src2.size());
dst.resize(src1.size());
for (size_t i = 0; i < src1.size(); i++) {
dst[i] = src1[i] + src2[i];
}
}
vec_ref.i
%module vec_ref
%{
#define SWIG_FILE_WITH_INIT
#include "vec_ref.h"
%}
%include "numpy.i"
%init %{
import_array();
%}
%include "std_vector.i"
%template(vecInt) std::vector<int>;
// %template(vecIntRef) std::vector<int> &;
// %apply (std::vector<int> * INPLACE_ARRAY1, int DIM1) {(std::vector<int> * dst, int a),(std::vector<int> * src1, int b),(std::vector<int> * src2, int c)};
// %apply (std::vector<int> * INPLACE_ARRAY1) {(std::vector<int> * dst),(std::vector<int> * src1),(std::vector<int> * src2)};
// %apply (std::vector<int> & INPLACE_ARRAY1) {(std::vector<int> & dst),(std::vector<int> & src1),(std::vector<int> & src2)};
// %apply (std::vector<int> & INPLACE_ARRAY1, int DIM1) {(std::vector<int> & dst, int a),(std::vector<int> & src1, int b),(std::vector<int> & src2, int c)};
%include "vec_ref.h"
Makefile
all:
rm -f *.so *.o *_wrap.* *.pyc *.gch vec_ref.py
swig -c++ -python vec_ref.i
g++ -O0 -g3 -fpic -c vec_ref_wrap.cxx vec_ref.h vec_ref.cpp -I/home/lmckeereid/tools/anaconda3/pkgs/python-3.7.3-h0371630_0/include/python3.7m/
g++ -O0 -g3 -shared vec_ref_wrap.o vec_ref.o -o _vec_ref.so
tester.py
import vec_ref as vec
import numpy as np
a = np.array([1,2,3], dtype=np.intc)
b = np.array([4,5,6], dtype=np.intc)
c = np.zeros(len(a), dtype=np.intc)
print('---Before---\na:', a)
print('b:', b)
print('c:', c)
vec.add_vec_ref(c,a,b)
print('---After---\na:', a)
print('b:', b)
print('c:', c)
Production:
---Before---
a: [1 2 3]
b: [4 5 6]
c: [0 0 0]
Traceback (most recent call last):
File "tester.py", line 12, in <module>
vec.add_vec_ref(c,a,b)
TypeError: in method 'add_vec_ref', argument 1 of type 'std::vector< int,std::allocator< int > > &'
J'ai essayé toutes les directives% apply et% template commentées dans vec_ref.i, mais elles n'ont pas fonctionné.
Existe-t-il des types de typographie que je devrais inclure, dont je ne suis pas?
std::vector
.Réponses:
Je suis d'accord avec @pschill: il n'est pas possible d'obtenir un std :: vector sans copier les données.
Une alternative consiste à utiliser le
std::span
modèle de classe (introduit en C ++ 20), ou unspan
modèle de classe similaire défini dans une bibliothèque.Création d' une
std::span<int>
fournirait une vue des données existantes dans unnumpy
tableau, et de fournir de nombreuses fonctions pratiques membres ( par exempleoperator[]
, itérateurs,front()
,back()
, etc.) en C ++.La création d'une étendue ne copiera jamais les données du tableau numpy.
la source
std::vector<T>& v
Vous pouvez vous référer à la bibliothèque Facebook faiss, qui réalise ce que vous voulez réaliser, d'une manière plus élégante Par:
Spécifique à Python: tableau numpy <-> interface de pointeur C ++ (vecteur)
Vous pouvez voir le code sur sa page Github .
la source