Python/C API - Comment définir l'opérateur + sur mon objet ?

ndubien Messages postés 557 Date d'inscription dimanche 25 septembre 2005 Statut Membre Dernière intervention 10 mai 2014 - 10 mai 2014 à 19:29
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 - 17 mai 2014 à 19:27
Bonjour,

J'utilise actuellement Python/C API pour développer (en C/C++) un module pour Python gérant les Vector côté GPU.

Je souhaiterais être en mesure d'additionner deux Vector à l'aide de l'opérateur classique : + (ie. vc = va + vb). J'ai lu que pour cela, il fallait définir l'opération nb_add dans PyNumberMethods.

J'ai bien défini cette opération cependant même si l'appel à nb_add se passe bien (à première vue), lorsque j'essaie d'appeler le nouveau Vector, j'obtiens une segfault.

Voici le code réalisant l'addition de deux Vector (qui devrait en théorie marcher d'après http://computer-programming-forum.com/56-python/4e13ee2bfe2fec9c.htm ):
PyObject *Vector_add(PyObject *a, PyObject *b)
{__LOG__
VectorObject *voa, *vob, *voc;
if (! isVector(a) || ! isVector(b))
{
PyErr_SetString(PyExc_TypeError, "In mathmodule_Vector_add: a and b must be defined as Vector instances");
return NULL;
}
voa = (VectorObject*) a;
vob = (VectorObject*) b;
voc = (VectorObject*) PyObject_New(VectorObject, &VectorType);
if (voc == NULL) return NULL;

setVectorPtr(voc, new Vector(getVectorPtr(voa)->getSize()));
add(*getVectorPtr(voa), *getVectorPtr(vob), *getVectorPtr(voc));
return (PyObject*) voc;
}

Voici un exemple de cheminement qui permet d'obtenir l'erreur (j'ai compilé la source avec dbg=1 afin d'avoir un output plus verbeux):
In [1]: import mathmodule
In mathmodule.cu at line 28 void initmathmodule()
In objects/Matrix.cu at line 6 void init_matrix()
In objects/Vector.cu at line 7 void init_vector()
In objects/VectorObject.cpp at line 12 void init_vectorobject()

In [2]: import numpy

In [3]: va = mathmodule.Vector(numpy.random.random(5))
In objects/VectorObject.cpp at line 17 int Vector_init(VectorObject*, PyObject*, PyObject*)
In objects/Vector.cu at line 23 Vector::Vector(const double*, const unsigned int&)

In [4]: vb = mathmodule.Vector(numpy.random.random(5))
In objects/VectorObject.cpp at line 17 int Vector_init(VectorObject*, PyObject*, PyObject*)
In objects/Vector.cu at line 23 Vector::Vector(const double*, const unsigned int&)

In [5]: vc = va + vb
In objects/VectorObject.cpp at line 46 PyObject* Vector_add(PyObject*, PyObject*)
In objects/Vector.cu at line 12 Vector::Vector(const unsigned int&)
In kernels/add.cu at line 17 bool add(const Vector&, const Vector&, Vector&)
In objects/Vector.cu at line 18 Vector::Vector(const Vector&)
In objects/Vector.cu at line 18 Vector::Vector(const Vector&)
In objects/Vector.cu at line 18 Vector::Vector(const Vector&)
In objects/Vector.cu at line 35 Vector::~Vector():2
In objects/Vector.cu at line 35 Vector::~Vector():2
In objects/Vector.cu at line 35 Vector::~Vector():2
In kernels/add.cu at line 27 bool add(const Vector&, const Vector&, Vector&) TOOK: 0.208512ms

In [6]: va
Out[6]: <mathmodule.Vector at 0x7f352c06e5a0>

In [7]: vb
Out[7]: <mathmodule.Vector at 0x7f352c06e600>

In [8]: vc
Segmentation fault

vc renvoie une segfault immédiatement lorsque j'essaie d'y accéder. D'où peut provenir ce problème ? Ai-je oublié de signaler à l'API Python que l'objet vc devait continuer à exister ?

Le code complet du module est disponible ici : https://github.com/dubzzz/cuda-mathmodule-for-python/blob/master/src/objects/VectorObject.cpp

Merci d'avance pour vos réponses,
Nicolas

1 réponse

yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 26
17 mai 2014 à 19:27
Salut,

as-tu essayé simplement ceci :

add(*getVectorPtr(voa), *getVectorPtr(vob), (Vector&)*voc);



bye...
0
Rejoignez-nous