]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
OK for DataArrays.
authorAnthony Geay <anthony.geay@edf.fr>
Mon, 9 Mar 2015 14:41:47 +0000 (15:41 +0100)
committerAnthony Geay <anthony.geay@edf.fr>
Mon, 9 Mar 2015 14:41:47 +0000 (15:41 +0100)
src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i
src/MEDCoupling_Swig/MEDCouplingMemArray.i
src/MEDCoupling_Swig/MEDCouplingPickleTest.py [new file with mode: 0644]

index 05722176c5b5e84b42d4d73ab3e315643a754e84..21f462ba01bb3545ef0dfef7d64f182813dac29b 100644 (file)
@@ -82,7 +82,7 @@ void numarrdeal(void *pt, void *wron)
     {
       Py_XINCREF(obj);
       PyArrayObject *objC=reinterpret_cast<PyArrayObject *>(obj);
-      objC->flags|=NPY_OWNDATA;
+      objC->flags|=NPY_ARRAY_OWNDATA;
       Py_XDECREF(weakRefOnOwner);
       Py_XDECREF(obj);
     }
@@ -282,24 +282,36 @@ MCData *BuildNewInstance(PyObject *elt0, int npyObjectType, PyTypeObject *pytype
   if(PyArray_ISBEHAVED(elt0))//aligned and writeable and in machine byte-order
     {
       PyArrayObject *elt0C=reinterpret_cast<PyArrayObject *>(elt0);
-      PyArrayObject *eltOwning=(PyArray_FLAGS(elt0C) & NPY_OWNDATA)?elt0C:NULL;
-      int mask=NPY_OWNDATA; mask=~mask;
+      PyArrayObject *eltOwning=(PyArray_FLAGS(elt0C) & NPY_ARRAY_OWNDATA)?elt0C:NULL;
+      int mask=NPY_ARRAY_OWNDATA; mask=~mask;
       elt0C->flags&=mask;
       PyObject *deepestObj=elt0;
       PyObject *base=elt0C->base;
       if(base) deepestObj=base;
+      bool isSpetialCase(false);
       while(base)
         {
           if(PyArray_Check(base))
             {
               PyArrayObject *baseC=reinterpret_cast<PyArrayObject *>(base);
-              eltOwning=(PyArray_FLAGS(baseC) & NPY_OWNDATA)?baseC:eltOwning;
+              eltOwning=(PyArray_FLAGS(baseC) & NPY_ARRAY_OWNDATA)?baseC:eltOwning;
               baseC->flags&=mask;
               base=baseC->base;
               if(base) deepestObj=base;
             }
           else
-            break;
+            {
+              isSpetialCase=true;
+              break;
+            }
+        }
+      if(isSpetialCase)
+        {// this case is present for numpy arrayint coming from load of pickelized string. The owner of elt0 is not an array -> A copy is requested.
+          std::size_t nbOfElems(sz0*sz1);
+          T *dataCpy=(T*)malloc(sizeof(T)*nbOfElems);
+          std::copy(reinterpret_cast<const T*>(data),reinterpret_cast<const T*>(data)+nbOfElems,dataCpy);
+          ret->useArray(dataCpy,true,ParaMEDMEM::C_DEALLOC,sz0,sz1);
+          return ret.retn();
         }
       typename ParaMEDMEM::MemArray<T>& mma=ret->accessToMemArray();
       if(eltOwning==NULL)
@@ -363,7 +375,7 @@ int NumpyArrSetBaseObjectExt(PyArrayObject *arr, PyObject *obj)
  
 
         /* If this array owns its own data, stop collapsing */
-        if (PyArray_CHKFLAGS(obj_arr, NPY_OWNDATA)) {
+        if (PyArray_CHKFLAGS(obj_arr, NPY_ARRAY_OWNDATA )) { 
             break;
         }   
 
index ef5df069e47913dba63b5fafc8b4500edddc96e5..ef598e15644e446a27c3ae13fc388499ce703eda 100644 (file)
@@ -2231,18 +2231,14 @@ namespace ParaMEDMEM
         if(PyTuple_Size(args)==2 && PyDict_Check(PyTuple_GetItem(args,1)) && PyDict_Size(PyTuple_GetItem(args,1))==1 )
           {// NOT general case. only true if in unpickeling context ! call __init__. Because for all other cases, __init__ is called right after __new__ !
             PyObject *zeNumpyRepr(0);
-            {
-              PyObject *tmp1(PyInt_FromLong(0));
-              zeNumpyRepr=PyDict_GetItem(PyTuple_GetItem(args,1),tmp1);//borrowed
-              Py_DECREF(tmp1);
-            }
-            {
-              PyObject *tmp3(PyTuple_New(1));
-              PyTuple_SetItem(tmp3,0,zeNumpyRepr); Py_XINCREF(zeNumpyRepr);
-              PyObject *tmp2(PyObject_CallObject(initMeth,tmp3));
-              Py_XDECREF(tmp2);
-              Py_DECREF(tmp3);
-            }
+            PyObject *tmp1(PyInt_FromLong(0));
+            zeNumpyRepr=PyDict_GetItem(PyTuple_GetItem(args,1),tmp1);//borrowed
+            Py_DECREF(tmp1);
+            PyObject *tmp3(PyTuple_New(1));
+            PyTuple_SetItem(tmp3,0,zeNumpyRepr); Py_XINCREF(zeNumpyRepr);
+            PyObject *tmp2(PyObject_CallObject(initMeth,tmp3));
+            Py_XDECREF(tmp2);
+            Py_DECREF(tmp3);
           }
         Py_DECREF(initMeth);
         return instance;
@@ -4592,21 +4588,14 @@ namespace ParaMEDMEM
         if(PyTuple_Size(args)==2 && PyDict_Check(PyTuple_GetItem(args,1)) && PyDict_Size(PyTuple_GetItem(args,1))==1 )
           {// NOT general case. only true if in unpickeling context ! call __init__. Because for all other cases, __init__ is called right after __new__ !
             PyObject *zeNumpyRepr(0);
-            {
-              PyObject *tmp1(PyInt_FromLong(0));
-              zeNumpyRepr=PyDict_GetItem(PyTuple_GetItem(args,1),tmp1);//borrowed
-              Py_DECREF(tmp1);
-            }
-            {
-              PyObject *tmp3(PyTuple_New(1));
-              PyTuple_SetItem(tmp3,0,zeNumpyRepr); Py_XINCREF(zeNumpyRepr);
-              // agy : WHY ! I don't know but valgrind complains strongly if not done !
-              // Question is why double does not need it ? It leads to mem leak !
-              //Py_XINCREF(zeNumpyRepr);
-              PyObject *tmp2(PyObject_CallObject(initMeth,tmp3));
-              Py_XDECREF(tmp2);
-              Py_DECREF(tmp3);
-            }
+            PyObject *tmp1(PyInt_FromLong(0));
+            zeNumpyRepr=PyDict_GetItem(PyTuple_GetItem(args,1),tmp1);//borrowed
+            Py_DECREF(tmp1);
+            PyObject *tmp3(PyTuple_New(1));
+            PyTuple_SetItem(tmp3,0,zeNumpyRepr); Py_XINCREF(zeNumpyRepr);
+            PyObject *tmp2(PyObject_CallObject(initMeth,tmp3));
+            Py_XDECREF(tmp2);
+            Py_DECREF(tmp3);
           }
         Py_DECREF(initMeth);
         return instance;
diff --git a/src/MEDCoupling_Swig/MEDCouplingPickleTest.py b/src/MEDCoupling_Swig/MEDCouplingPickleTest.py
new file mode 100644 (file)
index 0000000..3eb1658
--- /dev/null
@@ -0,0 +1,70 @@
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2015  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from MEDCoupling import *
+
+if MEDCouplingHasNumPyBindings():
+    from numpy import *
+    pass
+
+from platform import architecture
+from sys import getrefcount
+
+import os,gc,weakref,cPickle,unittest
+
+class MEDCouplingPickleTest(unittest.TestCase):
+    @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy")
+    def test1(self):
+        """ Test of a simple DataArrayDouble."""
+        x=DataArrayDouble(10,1) ; x.iota() ; x.rearrange(2) ; x.setInfoOnComponents(["aa","bbb"])
+        x.setName("toto")
+        pickled=cPickle.dumps(x,cPickle.HIGHEST_PROTOCOL)
+        xx=cPickle.loads(pickled)
+        self.assertTrue(xx.isEqual(x,1e-16))
+        # Bigger to check that the behavior is OK for large strings.
+        x=DataArrayDouble(1200) ; x.iota() ; x.setInfoOnComponents(["aa"])
+        x.setName("titi")
+        pickled=cPickle.dumps(x,cPickle.HIGHEST_PROTOCOL)
+        xx=cPickle.loads(pickled)
+        self.assertTrue(xx.isEqual(x,1e-16))
+        pass
+
+    @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy")
+    def test2(self):
+        """ Test of a simple DataArrayInt."""
+        x=DataArrayInt(10) ; x.iota() ; x.rearrange(2) ; x.setInfoOnComponents(["aa","bbb"])
+        x.setName("toto")
+        pickled=cPickle.dumps(x,cPickle.HIGHEST_PROTOCOL)
+        xx=cPickle.loads(pickled)
+        self.assertTrue(xx.isEqual(x))
+        # Bigger to check that the behavior is OK for large strings.
+        x=DataArrayInt(1200) ; x.iota() ; x.setInfoOnComponents(["aa"])
+        x.setName("titi")
+        pickled=cPickle.dumps(x,cPickle.HIGHEST_PROTOCOL)
+        xx=cPickle.loads(pickled)
+        self.assertTrue(xx.isEqual(x))
+        pass
+
+    def setUp(self):
+        pass
+    pass
+
+if __name__=="__main__":
+    unittest.main()