1 // Copyright (C) 2019 EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author: Anthony Geay, anthony.geay@edf.fr, EDF R&D
21 #include "TestAdaoExchange.hxx"
23 #include "AdaoExchangeLayer4Quintet.hxx"
24 #include "AdaoExchangeLayerException.hxx"
25 #include "AdaoModelKeyVal.hxx"
26 #include "PyObjectRAII.hxx"
28 #include "py2cpp/py2cpp.hxx"
33 std::vector<double> func(const std::vector<double>& vec)
35 return {vec[0],2.*vec[1],3.*vec[2],vec[0]+2.*vec[1]+3.*vec[2]};
38 PyObject *multiFunc(PyObject *inp)
40 PyGILState_STATE gstate(PyGILState_Ensure());
41 PyObjectRAII iterator(PyObjectRAII::FromNew(PyObject_GetIter(inp)));
43 throw AdaoExchangeLayerException("Input object is not iterable !");
44 PyObject *item(nullptr);
45 PyObjectRAII numpyModule(PyObjectRAII::FromNew(PyImport_ImportModule("numpy")));
46 if(numpyModule.isNull())
47 throw AdaoExchangeLayerException("Failed to load numpy");
48 PyObjectRAII ravelFunc(PyObjectRAII::FromNew(PyObject_GetAttrString(numpyModule,"ravel")));
49 std::vector< PyObjectRAII > pyrets;
50 while( item = PyIter_Next(iterator) )
52 PyObjectRAII item2(PyObjectRAII::FromNew(item));
54 PyObjectRAII args(PyObjectRAII::FromNew(PyTuple_New(1)));
55 PyTuple_SetItem(args,0,item2.retn());
56 PyObjectRAII npyArray(PyObjectRAII::FromNew(PyObject_CallObject(ravelFunc,args)));
57 // Waiting management of npy arrays into py2cpp
58 PyObjectRAII lolistFunc(PyObjectRAII::FromNew(PyObject_GetAttrString(npyArray,"tolist")));
61 PyObjectRAII args2(PyObjectRAII::FromNew(PyTuple_New(0)));
62 listPy=PyObjectRAII::FromNew(PyObject_CallObject(lolistFunc,args2));
64 std::vector<double> vect;
66 py2cpp::PyPtr listPy2(listPy.retn());
67 py2cpp::fromPyPtr(listPy2,vect);
70 PyGILState_Release(gstate);
71 std::vector<double> res(func(vect));
72 gstate=PyGILState_Ensure();
74 py2cpp::PyPtr resPy(py2cpp::toPyPtr(res));
75 PyObjectRAII resPy2(PyObjectRAII::FromBorrowed(resPy.get()));
76 pyrets.push_back(resPy2);
79 std::size_t len(pyrets.size());
80 PyObjectRAII ret(PyObjectRAII::FromNew(PyList_New(len)));
81 for(std::size_t i=0;i<len;++i)
83 PyList_SetItem(ret,i,pyrets[i].retn());
85 //PyObject *tmp(PyObject_Repr(ret));
86 // std::cerr << PyUnicode_AsUTF8(tmp) << std::endl;
87 PyGILState_Release(gstate);
91 PyObjectRAII NumpyToListWaitingForPy2CppManagement(PyObject *npObj)
93 PyObjectRAII func(PyObjectRAII::FromNew(PyObject_GetAttrString(npObj,"tolist")));
95 throw AdaoExchangeLayerException("input pyobject does not have tolist attribute !");
96 PyObjectRAII args(PyObjectRAII::FromNew(PyTuple_New(0)));
97 PyObjectRAII ret(PyObjectRAII::FromNew(PyObject_CallObject(func,args)));
101 void AdaoExchangeTest::setUp()
105 void AdaoExchangeTest::tearDown()
109 void AdaoExchangeTest::cleanUp()
113 using namespace AdaoModel;
115 void AdaoExchangeTest::test3DVar()
118 AdaoExchangeLayer4Quintet adao;
121 std::string sciptPyOfModelMaker(mm.pyStr());
122 std::cerr << sciptPyOfModelMaker << std::endl;
125 PyObject *listOfElts( nullptr );
126 while( adao.next(listOfElts) )
128 PyObject *resultOfChunk(multiFunc(listOfElts));
129 adao.setResult(resultOfChunk);
131 PyObject *res(adao.getResult());
132 PyObjectRAII optimum(PyObjectRAII::FromNew(res));
133 PyObjectRAII optimum_4_py2cpp(NumpyToListWaitingForPy2CppManagement(optimum));
134 std::vector<double> vect;
136 py2cpp::PyPtr obj(optimum_4_py2cpp);
137 py2cpp::fromPyPtr(obj,vect);
139 CPPUNIT_ASSERT_EQUAL(3,(int)vect.size());
140 CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,vect[0],1e-7);
141 CPPUNIT_ASSERT_DOUBLES_EQUAL(3.,vect[1],1e-7);
142 CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,vect[2],1e-7);
145 void AdaoExchangeTest::testBlue()
147 class TestBlueVisitor : public RecursiveVisitor
150 void visit(GenericKeyVal *obj)
152 EnumAlgoKeyVal *objc(dynamic_cast<EnumAlgoKeyVal *>(obj));
154 objc->setVal(EnumAlgo::Blue);
156 void enterSubDir(DictKeyVal *subdir) { }
157 void exitSubDir(DictKeyVal *subdir) { }
165 AdaoExchangeLayer4Quintet adao;
168 std::string sciptPyOfModelMaker(mm.pyStr());
169 std::cerr << sciptPyOfModelMaker << std::endl;
172 PyObject *listOfElts( nullptr );
173 while( adao.next(listOfElts) )
175 PyObject *resultOfChunk(multiFunc(listOfElts));
176 adao.setResult(resultOfChunk);
178 PyObject *res(adao.getResult());
179 PyObjectRAII optimum(PyObjectRAII::FromNew(res));
180 PyObjectRAII optimum_4_py2cpp(NumpyToListWaitingForPy2CppManagement(optimum));
181 std::vector<double> vect;
183 py2cpp::PyPtr obj(optimum_4_py2cpp);
184 py2cpp::fromPyPtr(obj,vect);
186 CPPUNIT_ASSERT_EQUAL(3,(int)vect.size());
187 CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,vect[0],1e-7);
188 CPPUNIT_ASSERT_DOUBLES_EQUAL(3.,vect[1],1e-7);
189 CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,vect[2],1e-7);
192 void AdaoExchangeTest::testNonLinearLeastSquares()
194 class TestNonLinearLeastSquaresVisitor : public RecursiveVisitor
197 void visit(GenericKeyVal *obj)
199 EnumAlgoKeyVal *objc(dynamic_cast<EnumAlgoKeyVal *>(obj));
201 objc->setVal(EnumAlgo::NonLinearLeastSquares);
203 void enterSubDir(DictKeyVal *subdir) { }
204 void exitSubDir(DictKeyVal *subdir) { }
209 TestNonLinearLeastSquaresVisitor vis;
212 AdaoExchangeLayer4Quintet adao;
215 std::string sciptPyOfModelMaker(mm.pyStr());
216 std::cerr << sciptPyOfModelMaker << std::endl;
219 PyObject *listOfElts( nullptr );
220 while( adao.next(listOfElts) )
222 PyObject *resultOfChunk(multiFunc(listOfElts));
223 adao.setResult(resultOfChunk);
225 PyObject *res(adao.getResult());
226 PyObjectRAII optimum(PyObjectRAII::FromNew(res));
227 PyObjectRAII optimum_4_py2cpp(NumpyToListWaitingForPy2CppManagement(optimum));
228 std::vector<double> vect;
230 py2cpp::PyPtr obj(optimum_4_py2cpp);
231 py2cpp::fromPyPtr(obj,vect);
233 CPPUNIT_ASSERT_EQUAL(3,(int)vect.size());
234 CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,vect[0],1e-7);
235 CPPUNIT_ASSERT_DOUBLES_EQUAL(3.,vect[1],1e-7);
236 CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,vect[2],1e-7);
239 CPPUNIT_TEST_SUITE_REGISTRATION( AdaoExchangeTest );
241 #include <cppunit/CompilerOutputter.h>
242 #include <cppunit/TestResult.h>
243 #include <cppunit/TestResultCollector.h>
244 #include <cppunit/TextTestProgressListener.h>
245 #include <cppunit/BriefTestProgressListener.h>
246 #include <cppunit/extensions/TestFactoryRegistry.h>
247 #include <cppunit/TestRunner.h>
248 #include <cppunit/TextTestRunner.h>
250 int main(int argc, char* argv[])
252 // --- Create the event manager and test controller
253 CPPUNIT_NS::TestResult controller;
255 // --- Add a listener that collects test result
256 CPPUNIT_NS::TestResultCollector result;
257 controller.addListener( &result );
259 // --- Add a listener that print dots as test run.
261 CPPUNIT_NS::TextTestProgressListener progress;
263 CPPUNIT_NS::BriefTestProgressListener progress;
265 controller.addListener( &progress );
267 // --- Get the top level suite from the registry
269 CPPUNIT_NS::Test *suite =
270 CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest();
272 // --- Adds the test to the list of test to run
274 CPPUNIT_NS::TestRunner runner;
275 runner.addTest( suite );
276 runner.run( controller);
278 // --- Print test in a compiler compatible format.
279 std::ofstream testFile;
280 testFile.open("test.log", std::ios::out | std::ios::app);
281 testFile << "------ ADAO exchange test log:" << std::endl;
282 CPPUNIT_NS::CompilerOutputter outputter( &result, testFile );
285 // --- Run the tests.
287 bool wasSucessful = result.wasSuccessful();
290 // --- Return error code 1 if the one of test failed.
292 return wasSucessful ? 0 : 1;