From d5aa59ef00bcdfc0438394590df015bbec7c8e0a Mon Sep 17 00:00:00 2001 From: Anida Khizar Date: Thu, 16 Feb 2023 16:46:36 +0100 Subject: [PATCH] Swig for paramedloader, still some problems with python test --- src/CMakeLists.txt | 1 + src/ParaMEDLoader/ParaMEDFileMesh.cxx | 4 +- src/ParaMEDLoader_Swig/CMakeLists.txt | 106 ++++++++++++++++++ .../CTestTestfileInstall.cmake.in | 35 ++++++ src/ParaMEDLoader_Swig/ParaMEDLoader.i | 33 ++++++ src/ParaMEDLoader_Swig/ParaMEDLoaderTest.py | 96 ++++++++++++++++ .../ParaMEDMEMTest_MEDLoader.cxx | 25 +++++ src/PyWrapping/CMakeLists.txt | 5 +- src/PyWrapping/medcoupling.i | 1 + 9 files changed, 303 insertions(+), 3 deletions(-) create mode 100644 src/ParaMEDLoader_Swig/CMakeLists.txt create mode 100644 src/ParaMEDLoader_Swig/CTestTestfileInstall.cmake.in create mode 100644 src/ParaMEDLoader_Swig/ParaMEDLoader.i create mode 100755 src/ParaMEDLoader_Swig/ParaMEDLoaderTest.py diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4fd69dc4c..df1746b75 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -67,6 +67,7 @@ IF(MEDCOUPLING_USE_MPI) ENDIF(NOT MEDCOUPLING_MICROMED) IF(MEDCOUPLING_ENABLE_PYTHON) ADD_SUBDIRECTORY(ParaMEDMEM_Swig) + ADD_SUBDIRECTORY(ParaMEDLoader_Swig) ENDIF(MEDCOUPLING_ENABLE_PYTHON) IF(MEDCOUPLING_BUILD_TESTS) IF(NOT MEDCOUPLING_MICROMED) diff --git a/src/ParaMEDLoader/ParaMEDFileMesh.cxx b/src/ParaMEDLoader/ParaMEDFileMesh.cxx index 768f5713d..c10d05ee9 100644 --- a/src/ParaMEDLoader/ParaMEDFileMesh.cxx +++ b/src/ParaMEDLoader/ParaMEDFileMesh.cxx @@ -109,7 +109,6 @@ MEDFileUMesh *ParaMEDFileUMesh::ParaNew(const std::vector& distrib, co return ParaMEDFileUMesh::NewPrivate(fid,com,distrib,fileName,mName,dt,it,mrs); } - /*! * Opens the given file in parallel so that each processor can load its part of the mesh \a mName. * The mesh will be equally and linearly distributed among all processes: @@ -157,7 +156,7 @@ MEDFileUMesh *ParaMEDFileUMesh::NewPrivate(med_idt fid, const MPI_Comm& com, con INTERP_KERNEL::NormalizedCellType geoType = typesDistrib[0][0].first; med_geometry_type geoMedType(typmai3[geoType]); med_bool changement,transformation; - med_int totalNumberOfElements(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoMedType,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation)); + med_int totalNumberOfElements(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoMedType,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)); mcIdType nbEltsInDistribLoc = distrib.size(); mcIdType nbEltsInDistribTot = -1; @@ -168,6 +167,7 @@ MEDFileUMesh *ParaMEDFileUMesh::NewPrivate(med_idt fid, const MPI_Comm& com, con #endif if(nbEltsInDistribTot != totalNumberOfElements) { + std::cout << totalNumberOfElements << std::endl; if(nbEltsInDistribTot > totalNumberOfElements) throw INTERP_KERNEL::Exception("ParaMEDFileMesh::NewPrivate : Some of your partitions overlap each other ! Each element in your distribution vector must appear only once ! "); else diff --git a/src/ParaMEDLoader_Swig/CMakeLists.txt b/src/ParaMEDLoader_Swig/CMakeLists.txt new file mode 100644 index 000000000..11c92cdd5 --- /dev/null +++ b/src/ParaMEDLoader_Swig/CMakeLists.txt @@ -0,0 +1,106 @@ +# Copyright (C) 2012-2022 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 +# + +ADD_DEFINITIONS(${PYTHON_DEFINITIONS} ${NUMPY_DEFINITIONS} ${SCIPY_DEFINITIONS}) + +IF (NOT DEFINED MSVC) + ADD_DEFINITIONS(-Wsign-compare -Wconversion) +ENDIF() + +FIND_PACKAGE(SWIG REQUIRED) +INCLUDE(${SWIG_USE_FILE}) + +SET_SOURCE_FILES_PROPERTIES(ParaMEDLoader.i PROPERTIES CPLUSPLUS ON) +IF ("${PYTHON_VERSION_MAJOR}" STREQUAL "3") + SET_SOURCE_FILES_PROPERTIES(ParaMEDLoader.i PROPERTIES SWIG_FLAGS "-py3") +ELSE() + SET_SOURCE_FILES_PROPERTIES(ParaMEDLoader.i PROPERTIES SWIG_DEFINITIONS "-shadow") +ENDIF() +SET(SWIG_MODULE_ParaMEDLoader_EXTRA_FLAGS "${NUMPY_DEFINITIONS};${SCIPY_DEFINITIONS}") +IF(MEDCOUPLING_USE_64BIT_IDS) + STRING(APPEND SWIG_MODULE_ParaMEDLoader_EXTRA_FLAGS ";-DMEDCOUPLING_USE_64BIT_IDS") +ENDIF(MEDCOUPLING_USE_64BIT_IDS) + +#/usr/lib64/python3.9/site-packages/openmpi/mpi4py/include/mpi4py + +INCLUDE_DIRECTORIES( + ${PYTHON_INCLUDE_DIRS} + "/usr/lib64/python3.9/site-packages/openmpi/mpi4py/include" + ${MEDFILE_INCLUDE_DIRS} + ${MPI_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDLoader + ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDMEM + ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDMEM/MPIAccess + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling_Swig + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases + + ) + +SET (SWIG_MODULE_ParaMEDLoader_EXTRA_DEPS + ${paramedloader_HEADERS_HXX} + ${medloader_HEADERS_HXX} + ${medcoupling_HEADERS_HXX} ${medcoupling_HEADERS_TXX} + ${interpkernel_HEADERS_HXX} ${interpkernel_HEADERS_TXX}) + +IF(${CMAKE_VERSION} VERSION_LESS "3.8.0") + SWIG_ADD_MODULE(ParaMEDLoader python ParaMEDLoader.i) +ELSE() + SWIG_ADD_LIBRARY(ParaMEDLoader LANGUAGE python SOURCES ParaMEDLoader.i) +ENDIF() + +SWIG_LINK_LIBRARIES(ParaMEDLoader ${PYTHON_LIBRARIES} paramedloader) +SWIG_CHECK_GENERATION(ParaMEDLoader) + +# +# Tests +# +IF(MEDCOUPLING_BUILD_PY_TESTS) + SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH NOCHECK ${CMAKE_CURRENT_BINARY_DIR}/../PyWrapping) + SALOME_ACCUMULATE_ENVIRONMENT(MED_RESOURCES_DIR NOCHECK ${CMAKE_SOURCE_DIR}/resources) + SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) + + # MPICH does not support --oversubscribe: + IF(NOT ${MPIEXEC_EXECUTABLE} MATCHES "mpich") + SET(_oversub_opt "--oversubscribe") + ENDIF() + ADD_TEST(NAME TestParaMEDFileMesh + COMMAND ${MPIEXEC} -np 2 ${_oversub_opt} ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/ParaMEDLoaderTest.py) + SET_TESTS_PROPERTIES(TestParaMEDFileMesh PROPERTIES ENVIRONMENT "${tests_env}") + +ENDIF() + + +# Installation +INSTALL(TARGETS _ParaMEDLoader DESTINATION ${MEDCOUPLING_INSTALL_PYTHON}) +INSTALL(FILES ParaMEDLoader.i DESTINATION ${MEDCOUPLING_INSTALL_HEADERS}) +INSTALL(FILES ParaMEDLoaderTest.py DESTINATION ${MEDCOUPLING_INSTALL_SCRIPT_PYTHON}) +SALOME_INSTALL_SCRIPTS(${CMAKE_CURRENT_BINARY_DIR}/ParaMEDLoader.py ${MEDCOUPLING_INSTALL_PYTHON} EXTRA_DPYS "${SWIG_MODULE_ParaMEDLoader_REAL_NAME}") + +# Application tests + +SET(TEST_INSTALL_DIRECTORY ${MEDCOUPLING_INSTALL_TESTS}/ParaMEDLoader_Swig) +INSTALL(FILES ParaMEDLoaderTest.py DESTINATION ${TEST_INSTALL_DIRECTORY}) +CONFIGURE_FILE(CTestTestfileInstall.cmake.in "CTestTestfileST.cmake" @ONLY) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/CTestTestfileST.cmake + DESTINATION ${TEST_INSTALL_DIRECTORY} + RENAME CTestTestfile.cmake) + diff --git a/src/ParaMEDLoader_Swig/CTestTestfileInstall.cmake.in b/src/ParaMEDLoader_Swig/CTestTestfileInstall.cmake.in new file mode 100644 index 000000000..fda2a7699 --- /dev/null +++ b/src/ParaMEDLoader_Swig/CTestTestfileInstall.cmake.in @@ -0,0 +1,35 @@ +# Copyright (C) 2015-2022 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 +# + +set(MPIEXEC @MPIEXEC@) +set(_oversub_opt @_oversub_opt@) + +SET(TEST_NAMES + ParaMEDFileMeshTest +) + +SET(PATH_FOR_PYTHON $ENV{PATH}) + +SET(TEST_NAME ${COMPONENT_NAME}_${TEST_NAMES}) +ADD_TEST(${TEST_NAME} ${MPIEXEC} -np 2 ${_oversub_opt} -path "${PATH_FOR_PYTHON}" python3 ParaMEDLoaderTest.py) +SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES + LABELS "${COMPONENT_NAME}" + TIMEOUT ${TIMEOUT} + ) + diff --git a/src/ParaMEDLoader_Swig/ParaMEDLoader.i b/src/ParaMEDLoader_Swig/ParaMEDLoader.i new file mode 100644 index 000000000..a9086e10e --- /dev/null +++ b/src/ParaMEDLoader_Swig/ParaMEDLoader.i @@ -0,0 +1,33 @@ +// Copyright (C) 2017-2022 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 +// + +%module ParaMEDLoader + +%{ +#include "ParaMEDFileMesh.hxx" +#include "ParaMEDLoader.hxx" +%} + +//typemap before includes... +%include "mpi4py/mpi4py.i" +%mpi4py_typemap(Comm, MPI_Comm); +%mpi4py_typemap(Info, MPI_Info); + +%include "ParaMEDFileMesh.hxx" +%include "ParaMEDLoader.hxx" diff --git a/src/ParaMEDLoader_Swig/ParaMEDLoaderTest.py b/src/ParaMEDLoader_Swig/ParaMEDLoaderTest.py new file mode 100755 index 000000000..902bb426c --- /dev/null +++ b/src/ParaMEDLoader_Swig/ParaMEDLoaderTest.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2022 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 * +import sys, os, tempfile +import unittest +import math +from mpi4py import MPI +from MEDLoaderDataForTest import WriteInTmpDir + +class ParaMEDLoaderTest(unittest.TestCase): + + def genGlobMesh(self): + """ The global mesh """ + coords=[0.,0., 1.,0., 2.,0., 0.,1., 1.,1., 1.,1.5, 2.,1.5, + 0.,2., 1.,2., 1.,2.5, 2.,2.5, 0.,3., 1.,3., 2.,3.] + conn=[0,1,4,3, 1,2,6,5, 3,4,8,7, 5,6,10,9, 7,8,12,11, 9,10,13,12] + mesh = MEDCouplingUMesh("mesh",2) + mesh.allocateCells(7) + mesh.insertNextCell(NORM_QUAD4,conn[0:4]) + mesh.insertNextCell(NORM_QUAD4,conn[4:8]) + mesh.insertNextCell(NORM_QUAD4,conn[8:12]) + mesh.insertNextCell(NORM_QUAD4,conn[12:16]) + mesh.insertNextCell(NORM_QUAD4,conn[16:20]) + mesh.insertNextCell(NORM_QUAD4,conn[20:24]) + myCoords = DataArrayDouble(coords,14,2) + mesh.setCoords(myCoords) + mesh.simplexize(0) + mesh.checkConsistencyLight() + return mesh + + def genGlobField(self): + """ The global field lying on the global mesh deifned above """ + mesh = self.genGlobMesh() + field = MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) + field.setMesh(mesh) + field.setName("field") + da = DataArrayDouble(mesh.getNumberOfCells()) + da.iota() + da *= 10 + field.setArray(da) + return field + + @WriteInTmpDir + def testParaMEDLoader_1(self): + """ The main method of the test """ + size = MPI.COMM_WORLD.size + rank = MPI.COMM_WORLD.rank + + if size != 2: + raise RuntimeError("Should be run on 2 procs!") + + path = os.getcwd() + print(path) + # tmpdirname=tempfile.TemporaryDirectory() + # filename=tmpdirname.name+"./GlobMesh2D.med" + # print(filename) + if rank == 0: + field = self.genGlobField() + WriteField(filename, field, True) + MPI.COMM_WORLD.Barrier() + + distrib = {0:[0,1,4,5,9] , 1:[2,3,6,7,8,10,11]} + #mfu = ParaMEDFileUMesh.ParaNew(rank,size,MPI.COMM_WORLD,MPI.INFO_NULL,"./GlobMesh2D.med", "mesh") # OK + mfu = ParaMEDFileUMesh.ParaNew(distrib[rank],MPI.COMM_WORLD,MPI.INFO_NULL,filename, "mesh") + locMesh = mfu.getMeshAtLevel(0) + print(locMesh) + + # if rank == 0: + # self.assertEqual(fieldT.getArray().getValues(), [1.0]) + # elif rank == 1: + # self.assertEqual(fieldT.getArray().getValues(), [5.0]) + + MPI.COMM_WORLD.Barrier() + +if __name__ == "__main__": + unittest.main() + MPI.Finalize() diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx b/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx index 379846bd0..c843fd14f 100644 --- a/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx +++ b/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx @@ -137,3 +137,28 @@ void ParaMEDMEMTest::testParallelLoad2() MPI_Barrier(MPI_COMM_WORLD); } + +//void ParaMEDMEMTest::testParallelLoad3() +//{ +// int size; +// int rank; +// MPI_Comm_size(MPI_COMM_WORLD,&size); +// MPI_Comm_rank(MPI_COMM_WORLD,&rank); +// // +// if(size!=2) +// return ; +// +// std::vector distrib; +// if (rank == 0) +// distrib = {0,3,5}; //c++ type of indexing: index starts from zero! +// else +// distrib = {1,2,4,6}; +// +// std::string filename=INTERP_TEST::getResourceFile("SimpleNonConformingMesh2D.med"); +//// MCAuto mu = ParaMEDFileUMesh::ParaNew(distrib, MPI_COMM_WORLD, MPI_INFO_NULL, filename, "mesh"); +// MPI_Barrier(MPI_COMM_WORLD); +// +//} + + + diff --git a/src/PyWrapping/CMakeLists.txt b/src/PyWrapping/CMakeLists.txt index 5bf9f8181..3f1f11e57 100644 --- a/src/PyWrapping/CMakeLists.txt +++ b/src/PyWrapping/CMakeLists.txt @@ -44,6 +44,7 @@ INCLUDE_DIRECTORIES( ${NUMPY_INCLUDE_DIR} ${MEDFILE_INCLUDE_DIRS} ${HDF5_INCLUDE_DIRS} + "/usr/lib64/python3.9/site-packages/openmpi/mpi4py/include" ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader/Swig @@ -63,6 +64,8 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDMEM ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDMEM/MPIAccess ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDMEM_Swig + ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDLoader + ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDLoader_Swig ${PROJECT_BINARY_DIR}/doc ) @@ -92,7 +95,7 @@ IF(MEDCOUPLING_USE_MPI) INCLUDE_DIRECTORIES(${MPI_INCLUDE_DIRS}) ADD_DEFINITIONS(${MPI_DEFINITIONS}) LIST(APPEND SWIG_MODULE_medcoupling_EXTRA_FLAGS -DWITH_PARALLEL_INTERPOLATOR) - LIST(APPEND medcoupling_LIB_dependancies paramedmem) + LIST(APPEND medcoupling_LIB_dependancies paramedmem paramedloader) ENDIF(MEDCOUPLING_USE_MPI) IF(${CMAKE_VERSION} VERSION_LESS "3.8.0") diff --git a/src/PyWrapping/medcoupling.i b/src/PyWrapping/medcoupling.i index 6a2a3d26d..c621113f9 100644 --- a/src/PyWrapping/medcoupling.i +++ b/src/PyWrapping/medcoupling.i @@ -46,6 +46,7 @@ #ifdef WITH_PARALLEL_INTERPOLATOR %include "ParaMEDMEMCommon.i" +%include "ParaMEDLoader.i" #endif %constant const char __version__[]=MEDCOUPLING_GIT_SHA1; -- 2.39.2