Commit bebcf155 authored by Andrew Comerford's avatar Andrew Comerford
Browse files

Merge branch 'feature/metis5' of localhost:nektar

parents 966d08c6 e0d5a3af
SET(METIS_SEARCH_PATHS
${CMAKE_SOURCE_DIR}/ThirdParty/modmetis-4.0/
${CMAKE_SOURCE_DIR}/ThirdParty/modmetis-4.0/build/
${CMAKE_SOURCE_DIR}/../ThirdParty/modmetis-4.0/
${CMAKE_SOURCE_DIR}/../ThirdParty/modmetis-4.0/build
${CMAKE_SOURCE_DIR}/ThirdParty/metis-5.0.2/
${CMAKE_SOURCE_DIR}/ThirdParty/metis-5.0.2/build/
${CMAKE_SOURCE_DIR}/../ThirdParty/metis-5.0.2/
${CMAKE_SOURCE_DIR}/../ThirdParty/metis-5.0.2/build
${CMAKE_SOURCE_DIR}/ThirdParty/dist/lib
${CMAKE_SOURCE_DIR}/../ThirdParty/dist/lib)
FIND_LIBRARY(METIS_LIB NAMES modmetis PATHS ${METIS_SEARCH_PATHS})
FIND_LIBRARY(METIS_LIB NAMES metis PATHS ${METIS_SEARCH_PATHS})
SET(METIS_FOUND FALSE)
IF (METIS_LIB)
SET(METIS_FOUND TRUE)
GET_FILENAME_COMPONENT(METIS_PATH ${METIS_LIB} PATH)
INCLUDE_DIRECTORIES(${METIS_PATH}/../include)
MARK_AS_ADVANCED(METIS_PATH)
MARK_AS_ADVANCED(METIS_LIB)
ENDIF (METIS_LIB)
......
......@@ -221,7 +221,7 @@ MACRO(ADD_NEKTAR_LIBRARY name component type)
# NIST Sparse BLAS only static, so link into Nektar libraries directly.
TARGET_LINK_LIBRARIES( ${name} ${NIST_SPARSE_BLAS} ${METIS_LIB})
ADD_DEPENDENCIES(${name} spblastk0.9b modmetis-4.0 boost tinyxml zlib)
ADD_DEPENDENCIES(${name} spblastk0.9b modmetis-5.0.2 boost tinyxml zlib)
SET_PROPERTY(TARGET ${name} PROPERTY FOLDER ${component})
IF (NEKTAR_USE_MPI)
TARGET_LINK_LIBRARIES( ${name} ${GSMPI_LIBRARY} ${XXT_LIBRARY})
......
......@@ -4,17 +4,18 @@ SET(THIRDPARTY_BUILD_METIS ON CACHE BOOL
IF (THIRDPARTY_BUILD_METIS)
INCLUDE(ExternalProject)
EXTERNALPROJECT_ADD(
modmetis-4.0
modmetis-5.0.2
PREFIX ${TPSRC}
URL ${TPURL}/modmetis-4.0.tar.bz2
URL_MD5 "4267355e04dcc2ef36f9889a98c923a5"
URL ${TPURL}/modmetis-5.0.2.tar.bz2
URL_MD5 "ffbdc6a50283934389a0b3b0c32b62c0"
DOWNLOAD_DIR ${TPSRC}
CONFIGURE_COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX:PATH=${TPSRC}/dist ${TPSRC}/src/modmetis-4.0
CONFIGURE_COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX:PATH=${TPSRC}/dist -DCMAKE_C_FLAGS:STRING=-fPIC -DGKLIB_PATH:PATH=${TPSRC}/src/modmetis-5.0.2/GKlib ${TPSRC}/src/modmetis-5.0.2
)
SET(METIS_LIB modmetis CACHE FILEPATH
SET(METIS_LIB metis CACHE FILEPATH
"METIS library" FORCE)
MARK_AS_ADVANCED(METIS_LIB)
LINK_DIRECTORIES(${TPSRC}/dist/lib)
INCLUDE_DIRECTORIES(${TPSRC}/dist/include)
ELSE (THIRDPARTY_BUILD_METIS)
INCLUDE (FindMetis)
ENDIF (THIRDPARTY_BUILD_METIS)
......
......@@ -341,7 +341,13 @@ namespace Nektar
try
{
// Attempt partitioning using METIS.
Metis::PartGraphVKway(nGraphVerts, xadj, adjncy, vwgt, vsize, npart, vol, part);
// Check METIS produced a valid partition and fix if not.
CheckPartitions(part);
// Distribute partitioning to all processes.
for (i = 1; i < m_comm->GetSize(); ++i)
{
m_comm->Send(i, part);
......@@ -376,6 +382,39 @@ namespace Nektar
}
}
void MeshPartition::CheckPartitions(Array<OneD, int> &pPart)
{
unsigned int i = 0;
unsigned int cnt = 0;
const unsigned int npart = m_comm->GetSize();
bool valid = true;
// Check that every process has at least one element assigned
for (i = 0; i < npart; ++i)
{
cnt = std::count(pPart.begin(), pPart.end(), i);
if (cnt == 0)
{
valid = false;
}
}
// If METIS produced an invalid partition, repartition naively.
// Elements are assigned to processes in a round-robin fashion.
// It is assumed that METIS failure only occurs when the number of
// elements is approx. the number of processes, so this approach
// should not be too inefficient communication-wise.
if (!valid)
{
for (i = 0; i < pPart.num_elements(); ++i)
{
pPart[i] = i % npart;
}
}
}
void MeshPartition::OutputPartition(
LibUtilities::SessionReaderSharedPtr& pSession,
BoostSubGraph& pGraph,
......
......@@ -180,6 +180,7 @@ namespace Nektar
void PartitionGraph(BoostSubGraph& pGraph,
BoostSubGraph& pLocalPartition);
void OutputPartition(SessionReaderSharedPtr& pSession, BoostSubGraph& pGraph, TiXmlElement* pGeometry);
void CheckPartitions(Array<OneD, int> &pPart);
};
typedef boost::shared_ptr<MeshPartition> MeshPartitionSharedPtr;
......
......@@ -39,99 +39,63 @@
#include <LibUtilities/BasicConst/NektarUnivTypeDefs.hpp>
#include <LibUtilities/BasicUtils/SharedArray.hpp>
#include "metis.h"
namespace Metis
{
extern "C"
{
// -- Sparse MAtrix Reordering (equivalent to onmetis)
void METIS_NodeND (int *nVerts, int *xadj, int *adjncy, int *numflag, int *options,
int *perm, int *iperm);
void AS_METIS_NodeND(int *nVerts, int *xadj, int *adjncy, int *numflag, int *options,
int *perm, int *iperm, int *map, int *mdswitch);
void METIS_PartMeshNodal(int *nElmts, int *nVerts, int *elType, int *numflag,
int *nparts, int *edgecut, int *epart, int *npart);
void METIS_PartGraphVKway(int *nVerts, int *xadj, int *adjcy, int *vertWgt, int *vertSize,
int *wgtFlag, int *numflag, int *nparts, int *options, int *volume, int *part);
}
//#ifdef NEKTAR_USING_METIS
inline static void onmetis(int *nVerts, int *xadj, int *adjncy, int *numflag, int *options,
int *perm, int *iperm)
{
METIS_NodeND(nVerts,xadj,adjncy,numflag,options,perm,iperm);
}
inline static void as_onmetis(int *nVerts, int *xadj, int *adjncy, int *numflag, int *options,
int *perm, int *iperm, int *map, int *mdswitch)
{
AS_METIS_NodeND(nVerts,xadj,adjncy,numflag,options,perm,iperm,map,mdswitch) ;
void AS_METIS_NodeND(int *nVerts, int *xadj, int *adjncy, int *vwgt,
int *options, int *perm, int *iperm, int *map,
int *mdswitch);
}
inline static void onmetis(int nVerts, Nektar::Array<Nektar::OneD, int> xadj, Nektar::Array<Nektar::OneD, int> adjncy,
Nektar::Array<Nektar::OneD, int> perm, Nektar::Array<Nektar::OneD, int> iperm)
inline static void as_onmetis(
int nVerts,
Nektar::Array<Nektar::OneD, int> xadj,
Nektar::Array<Nektar::OneD, int> adjncy,
Nektar::Array<Nektar::OneD, int> perm,
Nektar::Array<Nektar::OneD, int> iperm,
Nektar::Array<Nektar::OneD, int> map,
int mdswitch = 1)
{
ASSERTL1(xadj.num_elements() == nVerts+1,"Array xadj out of bounds");
ASSERTL1(perm.num_elements() == nVerts,"Array perm out of bounds");
ASSERTL1(iperm.num_elements() == nVerts,"Array iperm out of bounds");
int numflag = 0;
int options[8];
options[0]=0;
METIS_NodeND(&nVerts,&xadj[0],&adjncy[0],&numflag,options,&perm[0],&iperm[0]);
AS_METIS_NodeND(&nVerts, &xadj[0], &adjncy[0], NULL, NULL, &perm[0],
&iperm[0], &map[0], &mdswitch);
}
inline static void as_onmetis(int nVerts, Nektar::Array<Nektar::OneD, int> xadj, Nektar::Array<Nektar::OneD, int> adjncy,
Nektar::Array<Nektar::OneD, int> perm, Nektar::Array<Nektar::OneD, int> iperm, Nektar::Array<Nektar::OneD, int> map,
int mdswitch)
{
ASSERTL1(xadj.num_elements() == nVerts+1,"Array xadj out of bounds");
ASSERTL1(perm.num_elements() == nVerts,"Array perm out of bounds");
ASSERTL1(iperm.num_elements() == nVerts,"Array iperm out of bounds");
int numflag = 0;
int options[8];
options[0]=0;
AS_METIS_NodeND(&nVerts,&xadj[0],&adjncy[0],&numflag,options,&perm[0],&iperm[0],&map[0],&mdswitch);
}
inline static void MeshPartition(int nElmts, int nVerts, Nektar::Array<Nektar::OneD, int>& mesh, int type, int nparts,
Nektar::Array<Nektar::OneD, int>& edgePart, Nektar::Array<Nektar::OneD, int>& nodePart)
{
int numflag = 0;
METIS_PartMeshNodal(&nElmts, &nVerts, &mesh[0], &type, &numflag, &nparts, &edgePart[0], &nodePart[0]);
}
inline static void PartGraphVKway( int& nVerts,
Nektar::Array<Nektar::OneD, int>& xadj,
Nektar::Array<Nektar::OneD, int>& adjcy,
Nektar::Array<Nektar::OneD, int>& vertWgt,
Nektar::Array<Nektar::OneD, int>& vertSize,
int& nparts,
int& volume,
Nektar::Array<Nektar::OneD, int>& part)
inline static void PartGraphVKway(
int& nVerts,
Nektar::Array<Nektar::OneD, int>& xadj,
Nektar::Array<Nektar::OneD, int>& adjcy,
Nektar::Array<Nektar::OneD, int>& vertWgt,
Nektar::Array<Nektar::OneD, int>& vertSize,
int& nparts,
int& volume,
Nektar::Array<Nektar::OneD, int>& part)
{
int wgtflag = 0;
int *wgts = 0;
int *sizes = 0;
int *vwgt = 0;
int *vsize = 0;
if (vertWgt.num_elements() > 0)
{
wgtflag += 1;
wgts = &vertWgt[0];
vwgt = &vertWgt[0];
}
if (vertSize.num_elements() > 0)
{
wgtflag += 2;
sizes = &vertSize[0];
vsize = &vertSize[0];
}
int numflag = 0;
int options[5];
options[0]=0;
METIS_PartGraphVKway(&nVerts, &xadj[0], &adjcy[0], wgts, sizes, &wgtflag,
&numflag, &nparts, options, &volume, &part[0]);
int ncon = 1;
int options[METIS_NOPTIONS];
METIS_SetDefaultOptions(options);
METIS_PartGraphKway(&nVerts, &ncon, &xadj[0], &adjcy[0], vwgt, vsize,
0, &nparts, 0, 0, options, &volume, &part[0]);
}
//#endif //NEKTAR_USING_METIS
}
#endif //NEKTAR_LIB_UTILITIES_BASICUTILS_METIS_HPP
......@@ -549,7 +549,7 @@ namespace Nektar
BottomUpSubStructuredGraphSharedPtr &bottomUpGraph,
set<int> &extraDirVerts,
const bool checkIfSystemSingular,
int mdswitch,
int mdswitch,
bool doInteriorMap)
{
int i,j,k,l,m;
......@@ -1204,7 +1204,7 @@ namespace Nektar
case eIterativeMultiLevelStaticCond:
case eXxtMultiLevelStaticCond:
{
MultiLevelBisectionReordering(boostGraphObj,perm,iperm,bottomUpGraph,mdswitch,partVerts);
MultiLevelBisectionReordering(boostGraphObj,perm,iperm,bottomUpGraph,partVerts,mdswitch);
}
break;
default:
......
......@@ -1108,8 +1108,7 @@ namespace Nektar
case eIterativeMultiLevelStaticCond:
case eXxtMultiLevelStaticCond:
{
int mdswitch = 1;
MultiLevelBisectionReordering(boostGraphObj,perm,iperm,bottomUpGraph,mdswitch,partVerts);
MultiLevelBisectionReordering(boostGraphObj,perm,iperm,bottomUpGraph,partVerts);
}
break;
default:
......
......@@ -864,8 +864,8 @@ namespace Nektar
Array<OneD, int> &perm,
Array<OneD, int> &iperm,
BottomUpSubStructuredGraphSharedPtr &substructgraph,
const int mdswitch,
std::set<int> partVerts)
std::set<int> partVerts,
int mdswitch)
{
int nGraphVerts = boost::num_vertices(graph);
int nGraphEdges = boost::num_edges (graph);
......@@ -993,7 +993,7 @@ namespace Nektar
{
Metis::as_onmetis(
nNonPartition,xadj,adjncy,perm_tmp,iperm_tmp,
septreeTmp,mdswitch);
septreeTmp, mdswitch);
}
catch(...)
{
......
......@@ -262,8 +262,8 @@ namespace Nektar
Array<OneD, int> &perm,
Array<OneD, int> &iperm,
BottomUpSubStructuredGraphSharedPtr &substructgraph,
const int mdswitch = 1,
std::set<int> partVerts = std::set<int>());
std::set<int> partVerts = std::set<int>(),
int mdswitch = 1);
// The parameter MDSWITCH.
//
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment