From 3432a279ab81dac1bc37ab9f86f4cb7fecaca318 Mon Sep 17 00:00:00 2001 From: eap Date: Thu, 5 Aug 2021 15:33:26 +0300 Subject: [PATCH] bos #24596 [CEA] New MeshGems license Fix bos #26435 MG-Tetra_HPC failed with new licence mechanism: - set input file - redirect messages to log file - read log file only if it exists - write meshes to default names in tmp as in GHS3D plugin - works with both mpi and multithread Meshes are still not loaded (since there are expected to be big) --- src/GHS3DPRLPlugin/CMakeLists.txt | 1 + .../GHS3DPRLPlugin_GHS3DPRL.cxx | 165 +++++++++++------- .../GHS3DPRLPlugin_GHS3DPRL.hxx | 1 + .../GHS3DPRLPlugin_Hypothesis.cxx | 60 ++++++- .../GHS3DPRLPlugin_Hypothesis.hxx | 8 + src/GHS3DPRLPlugin/MG_TetraHPC_API.cxx | 69 ++++++-- src/GHS3DPRLPlugin/MG_TetraHPC_API.hxx | 9 +- src/tepal2med/tetrahpc2med.cxx | 8 - 8 files changed, 231 insertions(+), 90 deletions(-) diff --git a/src/GHS3DPRLPlugin/CMakeLists.txt b/src/GHS3DPRLPlugin/CMakeLists.txt index b0b0ce8..ef597b2 100644 --- a/src/GHS3DPRLPlugin/CMakeLists.txt +++ b/src/GHS3DPRLPlugin/CMakeLists.txt @@ -53,6 +53,7 @@ SET(_link_LIBRARIES ${SMESH_SMDS} ${SMESH_StdMeshers} ${SMESH_MeshDriverGMF} + ${SMESH_SMESHUtils} ${KERNEL_SalomeGenericObj} ${KERNEL_SALOMELocalTrace} ${KERNEL_SALOMEBasics} diff --git a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.cxx b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.cxx index 71ff805..db4f829 100644 --- a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.cxx +++ b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.cxx @@ -279,11 +279,13 @@ bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh& theMesh, map aSmdsToGHS3DPRLIdMap; map aGHS3DPRLIdToNodeMap; - GHS3DPRL_In = path + "GHS3DPRL"; + _genericName = GHS3DPRLPlugin_Hypothesis::GetFileName(_hypothesis); + TCollection_AsciiString aGenericName((char*) _genericName.c_str() ); + GHS3DPRL_In = aGenericName + ".mesh"; GHS3DPRL_Out = path + casenamemed; - GHS3DPRL_Out_Mesh = path + casenamemed + "_out.mesh"; + GHS3DPRL_Out_Mesh = aGenericName + "_out.mesh"; GHS3DPRL_Outxml = path + casenamemed + ".xml"; //master file - logFileName = path + casenamemed + ".log"; // MG library output + logFileName = aGenericName + ".log"; // MG library output NbPart=_NbPart; Gradation=_Gradation; MinSize=_MinSize; @@ -295,7 +297,7 @@ bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh& theMesh, // --verbose=0 --menu=no --launchtetra=yes; run_GHS3DPRL = run_GHS3DPRL + - " --casename=" + GHS3DPRL_In + + " --casename=" + aGenericName + " --number=" + NbPart + " --medname=" + GHS3DPRL_Out + " --launchtetra=yes" + @@ -310,8 +312,6 @@ bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh& theMesh, system( run_nokeep_files.ToCString() ); //clean files run_nokeep_files = rm + GHS3DPRL_In + "* "; - fileskinmesh=path + "GHS3DPRL.mesh"; - GHS3DPRL_Out = path + casenamemed; removeFile( GHS3DPRL_Outxml ); //only the master xml file MG_TetraHPC_API mgTetraHPC( _computeCanceled, _progress ); @@ -319,30 +319,54 @@ bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh& theMesh, if ( !useLib ) mgTetraHPC.SetUseExecutable(); - exportGMF( &mgTetraHPC, fileskinmesh.ToCString(), meshDS ); + exportGMF( &mgTetraHPC, GHS3DPRL_In.ToCString(), meshDS ); - if ( useLib ) + if ( true /*useLib*/ ) { - TCollection_AsciiString cmd = TCollection_AsciiString("mg-tetra_hpc.exe") + - " --number_of_subdomains=" + NbPart + - " --gradation=" + Gradation + - " --min_size=" + MinSize + - " --max_size=" + MaxSize + - " --verbose=3" + - " --out=" + GHS3DPRL_Out_Mesh + - " " + _AdvOptions.c_str(); + TCollection_AsciiString cmd = TCollection_AsciiString(); + if (_Multithread) + cmd += "mg-tetra_hpc.exe"; + else + cmd = cmd + "mpirun --n " + NbPart + " mg-tetra_hpc_mpi.exe"; + cmd = cmd + " --in=" + GHS3DPRL_In; + if (_Multithread) + cmd = cmd +" --max_number_of_threads=" + NbPart; + cmd = cmd + " --gradation=" + Gradation; + cmd = cmd + " --min_size=" + MinSize; + cmd = cmd + " --max_size=" + MaxSize; + cmd = cmd + " --verbose=3"; + cmd = cmd + " --out=" + GHS3DPRL_Out_Mesh; + cmd = cmd + " " + _AdvOptions.c_str(); + cmd = cmd + " 1>" + logFileName; cout << endl << " Run mg-tetra_hpc as library. Creating a mesh file " << GHS3DPRL_Out_Mesh << endl << " Creating a log file : " << logFileName << endl << endl; mgTetraHPC.SetLogFile( logFileName.ToCString() ); - mgTetraHPC.Compute( cmd.ToCString() ); + std::string log; + Ok = mgTetraHPC.Compute( cmd.ToCString(), log ); - std::string log = mgTetraHPC.GetLog(); - if ( log.find(" Dlim " ) != std::string::npos || - log.find(" license ") != std::string::npos ) - return error("License problem"); + if (!Ok) + { + std::cout << "Error: " << std::endl; + std::cout << log << std::endl; + // try to guess an error from the output log + std::string log2 = mgTetraHPC.GetLog(); + if ( log2.find(" Dlim " ) != std::string::npos || + log2.find(" license ") != std::string::npos ) + return error("License problem"); + std::cout << log2 << std::endl; + if ( log2.find("You are using an empty MPI stubs library") != std::string::npos ) + { + std:string msg = "You are using an empty MPI stubs library. Please build it first to be able to use mg-tetra_hpc_mpi.exe.\n"; + msg += "./salome context\n"; + msg += "cd $MESHGEMSHOME/stubs\n"; + msg += "mpicc meshgems_mpi.c -DMESHGEMS_LINUX_BUILD -I../include -shared -fPIC -o $MESHGEMSHOME/lib/Linux_64/libmeshgems_mpi.so"; + return error(msg); + } + return error(log); + } // set --launchtetra=no int yesPos = run_GHS3DPRL.Search("launchtetra") + sizeof("launchtetra"); @@ -355,55 +379,62 @@ bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh& theMesh, cout<<" Write input file for mg-tetra_hpc "< 0) + // if mpi, convert meshes to med with xml master file + if (!_Multithread) { - pluginerror = pluginerror + "PROBLEM tetrahpc2med command"; - cout< 0) + { + pluginerror = pluginerror + "PROBLEM tetrahpc2med command"; + cout< +#include #include +#include + +#ifdef WIN32 +#include +#define getpid _getpid +#endif //============================================================================= /*! @@ -47,6 +55,56 @@ GHS3DPRLPlugin_Hypothesis::GHS3DPRLPlugin_Hypothesis (int hypId, SMESH_Gen * gen _param_algo_dim = 3; } +//======================================================================= +//function : DefaultWorkingDirectory +//======================================================================= + +std::string GHS3DPRLPlugin_Hypothesis::DefaultWorkingDirectory() +{ + TCollection_AsciiString aTmpDir; + + char *Tmp_dir = getenv("SALOME_TMP_DIR"); + if(Tmp_dir != NULL) { + aTmpDir = Tmp_dir; + } + else { +#ifdef WIN32 + aTmpDir = TCollection_AsciiString("C:\\"); +#else + aTmpDir = TCollection_AsciiString("/tmp/"); +#endif + } + return aTmpDir.ToCString(); +} + +//================================================================================ +/*! + * \brief Return a unique file name + */ +//================================================================================ + +std::string GHS3DPRLPlugin_Hypothesis::GetFileName(const GHS3DPRLPlugin_Hypothesis* hyp) +{ + std::string aTmpDir = DefaultWorkingDirectory(); + if ( !SMESH_File( aTmpDir ).exists() ) + aTmpDir = Kernel_Utils::GetTmpDirByPath( aTmpDir ); + + const char lastChar = *aTmpDir.rbegin(); +#ifdef WIN32 + if(lastChar != '\\') aTmpDir+='\\'; +#else + if(lastChar != '/') aTmpDir+='/'; +#endif + + TCollection_AsciiString aGenericName = (char*)aTmpDir.c_str(); + aGenericName += "MGTETRAHPC_"; + aGenericName += getpid(); + aGenericName += "_"; + aGenericName += Abs((Standard_Integer)(long) aGenericName.ToCString()); + + return aGenericName.ToCString(); +} + //============================================================================= /*! * @@ -290,7 +348,7 @@ std::string GHS3DPRLPlugin_Hypothesis::GetDefaultMEDName() //============================================================================= int GHS3DPRLPlugin_Hypothesis::GetDefaultNbPart() { - return 16; + return 8; } //============================================================================= diff --git a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis.hxx b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis.hxx index 0146065..5051e56 100644 --- a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis.hxx +++ b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_Hypothesis.hxx @@ -29,6 +29,7 @@ #include "SMESH_Hypothesis.hxx" #include "Utils_SALOME_Exception.hxx" +#include // Parameters for work of GHS3DPRL // @@ -41,6 +42,13 @@ public: static const char* GetHypType() { return "MG-Tetra Parallel Parameters"; } + static std::string DefaultWorkingDirectory(); + + /*! + * \brief Return a unique file name + */ + static std::string GetFileName(const GHS3DPRLPlugin_Hypothesis* hyp); + void SetMEDName(std::string theVal); std::string GetMEDName() const { return _MEDName; } diff --git a/src/GHS3DPRLPlugin/MG_TetraHPC_API.cxx b/src/GHS3DPRLPlugin/MG_TetraHPC_API.cxx index b8b59d5..f91ffaf 100644 --- a/src/GHS3DPRLPlugin/MG_TetraHPC_API.cxx +++ b/src/GHS3DPRLPlugin/MG_TetraHPC_API.cxx @@ -21,11 +21,13 @@ #include #include +#include #include -#include -#include #include +#include +#include +#include #ifdef USE_MG_LIBS @@ -584,6 +586,14 @@ void MG_TetraHPC_API::LibData::Init() bool MG_TetraHPC_API::LibData::Compute( const std::string& outFile ) { + // MG license + std::string errorTxt; + if ( !SMESHUtils_MGLicenseKeyGen::SignMesh( _tria_mesh, errorTxt )) + { + AddError( SMESH_Comment( "Problem with library SalomeMeshGemsKeyGenerator: ") << errorTxt ); + return false; + } + // Set surface mesh status_t ret = tetra_hpc_set_input_mesh( _session, _tria_mesh ); if ( ret != STATUS_OK ) MG_Error( "unable to set surface mesh"); @@ -635,7 +645,8 @@ struct MG_TetraHPC_API::LibData // to avoid compiler warnings */ //================================================================================ -MG_TetraHPC_API::MG_TetraHPC_API(volatile bool& cancelled_flag, double& progress) +MG_TetraHPC_API::MG_TetraHPC_API(volatile bool& cancelled_flag, double& progress): + _nbNodes(0), _nbEdges(0), _nbFaces(0), _nbVolumes(0) { _useLib = false; _libData = new LibData( cancelled_flag, progress ); @@ -695,7 +706,7 @@ void MG_TetraHPC_API::SetUseExecutable() */ //================================================================================ -bool MG_TetraHPC_API::Compute( const std::string& cmdLine ) +bool MG_TetraHPC_API::Compute( const std::string& cmdLine, std::string& errStr ) { if ( _useLib ) { #ifdef USE_MG_LIBS @@ -744,7 +755,7 @@ bool MG_TetraHPC_API::Compute( const std::string& cmdLine ) } // compute - bool ok = _libData->Compute( outFile ); + bool ok = _libData->Compute( outFile ); GetLog(); // write a log file _logFile = ""; // not to write it again @@ -753,16 +764,33 @@ bool MG_TetraHPC_API::Compute( const std::string& cmdLine ) #endif } - (void)cmdLine; // unused - // Run library ONLY + // add MG license key + { + std::string errorTxt, meshIn; + std::string key = SMESHUtils_MGLicenseKeyGen::GetKey( meshIn, + _nbNodes, _nbEdges, _nbFaces, _nbVolumes, + errorTxt ); + if ( key.empty() ) + { + errStr = "Problem with library SalomeMeshGemsKeyGenerator: " + errorTxt; + return false; + } + + const_cast< std::string& >( cmdLine ) += " --key " + key; + } - // int err = system( cmdLine.c_str() ); // run + std::cout << "Launching: " << cmdLine << std::endl; - // if ( err ) - // errStr = SMESH_Comment("system(mg-tetra.exe ...) command failed with error: ") - // << strerror( errno ); + int err = system( cmdLine.c_str() ); // run + + if ( err ) + { + errStr = SMESH_Comment("system command failed with error: ") + << strerror( errno ); + return false; + } + return true; - return false; } //================================================================================ @@ -1012,6 +1040,16 @@ int MG_TetraHPC_API::GmfOpenMesh(const char* theFile, int rdOrWr, int ver, int void MG_TetraHPC_API::GmfSetKwd(int iMesh, GmfKwdCod what, int nb ) { + if ( iMesh == 1 ) + { + switch ( what ) { + case GmfVertices: _nbNodes = nb; break; + case GmfEdges: _nbEdges = nb; break; + case GmfTriangles: _nbFaces = nb; break; + default:; + } + } + if ( _useLib ) { #ifdef USE_MG_LIBS switch ( what ) { @@ -1190,6 +1228,11 @@ std::string MG_TetraHPC_API::GetLog() return err; #endif } + std::cout << "_logFile: " << _logFile << std::endl; + SMESH_File file( _logFile ); - return file.getPos(); + if (file.exists() && file.size() > 0) + return file.getPos(); + else + return ""; } diff --git a/src/GHS3DPRLPlugin/MG_TetraHPC_API.hxx b/src/GHS3DPRLPlugin/MG_TetraHPC_API.hxx index b4f9153..d1aed51 100644 --- a/src/GHS3DPRLPlugin/MG_TetraHPC_API.hxx +++ b/src/GHS3DPRLPlugin/MG_TetraHPC_API.hxx @@ -52,7 +52,7 @@ public: void GmfSetLin(int iMesh, GmfKwdCod what, int id ); // required void GmfSetLin(int iMesh, GmfKwdCod what, int node1, int node2, int node3, int domain ); // tria - bool Compute( const std::string& cmdLine ); + bool Compute( const std::string& cmdLine, std::string& errStr ); // OUT from MESHGEMS int GmfOpenMesh(const char* theFile, int rdOrWr, int * ver, int * dim); @@ -81,6 +81,13 @@ private: LibData* _libData; std::set _openFiles; std::string _logFile; + + + // count mesh entities for MG license key generation + int _nbNodes; + int _nbEdges; + int _nbFaces; + int _nbVolumes; }; #endif diff --git a/src/tepal2med/tetrahpc2med.cxx b/src/tepal2med/tetrahpc2med.cxx index fc18102..901c283 100644 --- a/src/tepal2med/tetrahpc2med.cxx +++ b/src/tepal2med/tetrahpc2med.cxx @@ -840,10 +840,6 @@ int main(int argc, char *argv[]) else path="./"; casenamemed=casenamemed.section('/',-1); - if (casenamemed.length()>20){ - std::cerr<<"--medname truncated (no more 20 characters)"<0) @@ -851,10 +847,6 @@ int main(int argc, char *argv[]) else pathini="./"; casename=casename.section('/',-1); - if (casename.length()>20){ - std::cerr<<"--casename truncated (no more 20 characters)"<