Commit a282e79c authored by Christian Godenschwager's avatar Christian Godenschwager
Browse files

Added support for ParMetis library

Also added wrapper for Metis & ParMetis to prevent it from polluting the global name space
parent 98827cd5
Pipeline #4441 passed with stage
in 70 minutes and 47 seconds
......@@ -70,6 +70,7 @@ option ( WALBERLA_BUILD_TUTORIALS "Build Tutorials"
option ( WALBERLA_BUILD_WITH_MPI "Build with MPI" ON )
option ( WALBERLA_BUILD_WITH_METIS "Build with metis graph partitioner" OFF )
option ( WALBERLA_BUILD_WITH_PARMETIS "Build with ParMetis graph partitioner" OFF )
option ( WALBERLA_BUILD_WITH_GPROF "Enables gprof" )
option ( WALBERLA_BUILD_WITH_GCOV "Enables gcov" )
......@@ -853,6 +854,28 @@ else()
set ( METIS_FOUND OFF CACHE BOOL "Metis found" FORCE )
endif()
if ( WALBERLA_BUILD_WITH_PARMETIS )
find_path(PARMETIS_INCLUDE_DIR parmetis.h
/usr/local/include
/usr/include
${PARMETIS_ROOT}/include
$ENV{PARMETIS_ROOT}/include
)
find_library(PARMETIS_LIBRARY parmetis
/usr/local/lib
/usr/lib
${PARMETIS_ROOT}/lib
$ENV{PARMETIS_ROOT}/lib
)
if( PARMETIS_INCLUDE_DIR AND PARMETIS_LIBRARY AND METIS_LIBRARY )
include_directories( ${PARMETIS_INCLUDE_DIR} )
list ( APPEND SERVICE_LIBS ${PARMETIS_LIBRARY} ${METIS_LIBRARY} )
endif()
endif()
############################################################################################################################
......
......@@ -24,12 +24,12 @@
#include "waLBerlaDefinitions.h" // for macro WALBERLA_BUILD_WITH_METIS
#include "BlockID.h"
#include "MetisWrapper.h"
#include "Types.h"
#include "core/Abort.h"
#include "core/debug/Debug.h"
#include "core/logging/Logging.h"
#include "core/load_balancing/MetisWrapper.h"
#include "core/math/KahanSummation.h"
#include <boost/function.hpp>
......@@ -144,10 +144,10 @@ public:
static void metis2( const std::vector< BLOCK* >& blocks, const uint_t numberOfProcesses, const CommFunction & commFunction );
private:
static inline uint_t metisAdaptPartVector( std::vector< idx_t >& part, const uint_t numberOfProcesses );
static inline uint_t metisAdaptPartVector( std::vector< int64_t >& part, const uint_t numberOfProcesses );
template< typename BLOCK >
static memory_t metisMaxMemory( const std::vector< BLOCK* >& blocks, const uint_t numberOfProcesses, const std::vector< idx_t >& part );
static memory_t metisMaxMemory( const std::vector< BLOCK* >& blocks, const uint_t numberOfProcesses, const std::vector< int64_t >& part );
static inline std::ostream & metisErrorCodeToStream( int errorCode, std::ostream & oss );
static inline std::string metisErrorCodeToString( int errorCode );
......@@ -781,51 +781,51 @@ uint_t GlobalLoadBalancing::metis( const std::vector< BLOCK* >& blocks, const me
// translate block forest to metis graph structure
idx_t nvtxs = numeric_cast<idx_t>( blocks.size() ); // number of vertices in the graph
idx_t ncon = 2; // number of balancing constraints
int64_t nvtxs = numeric_cast<int64_t>( blocks.size() ); // number of vertices in the graph
int64_t ncon = 2; // number of balancing constraints
for( uint_t i = 0; i != blocks.size(); ++i )
blocks[i]->setIndex(i);
std::vector< idx_t > xadj; // adjacency structure ...
std::vector< idx_t > adjncy; // ... of the graph
std::vector< idx_t > vwgt( uint_c(ncon * nvtxs) ); // weights of the vertices
std::vector< idx_t > adjwgt; // weights of the edges
std::vector< int64_t > xadj; // adjacency structure ...
std::vector< int64_t > adjncy; // ... of the graph
std::vector< int64_t > vwgt( uint_c(ncon * nvtxs) ); // weights of the vertices
std::vector< int64_t > adjwgt; // weights of the edges
xadj.push_back(0);
for( uint_t i = 0; i != blocks.size(); ++i ) {
const BLOCK* block = blocks[i];
idx_t next = xadj.back() + numeric_cast< idx_t >( block->getNeighborhoodSize() );
int64_t next = xadj.back() + numeric_cast< int64_t >( block->getNeighborhoodSize() );
xadj.push_back( next );
for( uint_t j = 0; j != block->getNeighborhoodSize(); ++j ) {
adjncy.push_back( numeric_cast<idx_t>( block->getNeighbor(j)->getIndex() ) );
adjncy.push_back( numeric_cast<int64_t>( block->getNeighbor(j)->getIndex() ) );
adjwgt.push_back( metisConfig.communicationFunction().empty() ? 1 :
( numeric_cast<idx_t>( static_cast< memory_t >(0.5) + metisConfig.communicationFunction()( block, block->getNeighbor(j) ) ) ) );
( numeric_cast<int64_t>( static_cast< memory_t >(0.5) + metisConfig.communicationFunction()( block, block->getNeighbor(j) ) ) ) );
}
vwgt[ i * 2 ] = numeric_cast< idx_t >( static_cast< workload_t >(0.5) + blocks[i]->getWorkload() );
vwgt[ i * 2 + 1 ] = numeric_cast< idx_t >( static_cast< memory_t >(0.5) + blocks[i]->getMemory() );
vwgt[ i * 2 ] = numeric_cast< int64_t >( static_cast< workload_t >(0.5) + blocks[i]->getWorkload() );
vwgt[ i * 2 + 1 ] = numeric_cast< int64_t >( static_cast< memory_t >(0.5) + blocks[i]->getMemory() );
}
idx_t nparts = numeric_cast< idx_t >( numberOfProcesses ); // number of parts to partition the graph
idx_t objval;
int64_t nparts = numeric_cast< int64_t >( numberOfProcesses ); // number of parts to partition the graph
int64_t objval;
std::vector< idx_t > part( uint_c(nvtxs) );
std::vector< int64_t > part( uint_c(nvtxs) );
real_t maxUbvec = metisConfig.maxUbvec();
real_t ubvec[] = { real_c(1.01), maxUbvec };
// first call to METIS: always try to balance the workload as good as possible, but allow large imbalances concerning the memory (-> ubvec[1])
int ret = METIS_PartGraphRecursive( &nvtxs, &ncon, &(xadj[0]), &(adjncy[0]), &(vwgt[0]), NULL, &(adjwgt[0]), &nparts, NULL,
&(ubvec[0]), NULL /*idx t *options*/, &objval, &(part[0]) );
int ret = core::METIS_PartGraphRecursive( &nvtxs, &ncon, &(xadj[0]), &(adjncy[0]), &(vwgt[0]), NULL, &(adjwgt[0]), &nparts, NULL,
&(ubvec[0]), NULL /*idx t *options*/, &objval, &(part[0]) );
// if METIS was successful AND the memory limit of each process is not violated (which is highly unlikely due to a large value for ubvec[1])
// then the algorithm is finished
if( ret == METIS_OK && metisMaxMemory( blocks, numberOfProcesses, part ) <= memoryLimit ) {
if( ret == core::METIS_OK && metisMaxMemory( blocks, numberOfProcesses, part ) <= memoryLimit ) {
nProcesses = metisAdaptPartVector( part, numberOfProcesses );
......@@ -844,16 +844,16 @@ uint_t GlobalLoadBalancing::metis( const std::vector< BLOCK* >& blocks, const me
real_t minUbvec = real_t(1);
ubvec[1] = minUbvec;
ret = METIS_PartGraphRecursive( &nvtxs, &ncon, &(xadj[0]), &(adjncy[0]), &(vwgt[0]), NULL, &(adjwgt[0]), &nparts, NULL,
&(ubvec[0]), NULL /*idx t *options*/, &objval, &(part[0]) );
ret = core::METIS_PartGraphRecursive( &nvtxs, &ncon, &(xadj[0]), &(adjncy[0]), &(vwgt[0]), NULL, &(adjwgt[0]), &nparts, NULL,
&(ubvec[0]), NULL /*idx t *options*/, &objval, &(part[0]) );
// ... if this doesn't work OR if the memory limit is still violated then METIS is unable to find a valid partitioning
if( ret != METIS_OK ) {
if( ret != core::METIS_OK ) {
std::string error( "METIS_ERROR" );
if( ret == METIS_ERROR_INPUT ) error.assign( "METIS_ERROR_INPUT" );
else if( ret == METIS_ERROR_MEMORY ) error.assign( "METIS_ERROR_MEMORY" );
if( ret == core::METIS_ERROR_INPUT ) error.assign( "METIS_ERROR_INPUT" );
else if( ret == core::METIS_ERROR_MEMORY ) error.assign( "METIS_ERROR_MEMORY" );
// DEBUG_LOGGING_SECTION { std::cout << "ERROR: static load balancing with METIS failed (" << error << ")" << std::endl; }
return 0;
......@@ -881,10 +881,10 @@ uint_t GlobalLoadBalancing::metis( const std::vector< BLOCK* >& blocks, const me
ubvec[1] = ( maxUbvec + minUbvec ) / real_c(2);
ret = METIS_PartGraphRecursive( &nvtxs, &ncon, &(xadj[0]), &(adjncy[0]), &(vwgt[0]), NULL, &(adjwgt[0]), &nparts, NULL,
&(ubvec[0]), NULL /*idx t *options*/, &objval, &(part[0]) );
ret = core::METIS_PartGraphRecursive( &nvtxs, &ncon, &(xadj[0]), &(adjncy[0]), &(vwgt[0]), NULL, &(adjwgt[0]), &nparts, NULL,
&(ubvec[0]), NULL /*idx t *options*/, &objval, &(part[0]) );
if( ret == METIS_OK && metisMaxMemory( blocks, numberOfProcesses, part ) <= memoryLimit ) {
if( ret == core::METIS_OK && metisMaxMemory( blocks, numberOfProcesses, part ) <= memoryLimit ) {
nProcesses = metisAdaptPartVector( part, numberOfProcesses );
......@@ -913,8 +913,8 @@ void GlobalLoadBalancing::metis2( const std::vector< BLOCK* >& blocks, const uin
if( blocks.empty() )
return;
idx_t nvtxs = 0; // number of vertices in the graph
idx_t ncon = 1; // number of balancing constraints
int64_t nvtxs = 0; // number of vertices in the graph
int64_t ncon = 1; // number of balancing constraints
uint_t j = 0;
for( uint_t i = 0; i != blocks.size(); ++i )
......@@ -947,10 +947,10 @@ void GlobalLoadBalancing::metis2( const std::vector< BLOCK* >& blocks, const uin
commFunction( blockPairs, communicationWeights );
std::vector< idx_t > xadj; // adjacency structure ...
std::vector< idx_t > adjncy; // ... of the graph
std::vector< idx_t > vwgt; // weights of the vertices
std::vector< idx_t > adjwgt; // weights of the edges
std::vector< int64_t > xadj; // adjacency structure ...
std::vector< int64_t > adjncy; // ... of the graph
std::vector< int64_t > vwgt; // weights of the vertices
std::vector< int64_t > adjwgt; // weights of the edges
xadj.push_back( 0 );
uint_t commIdx = 0;
......@@ -963,7 +963,7 @@ void GlobalLoadBalancing::metis2( const std::vector< BLOCK* >& blocks, const uin
++nvtxs;
xadj.push_back( xadj.back() );
vwgt.push_back( numeric_cast<idx_t>( blocks[ i ]->getWorkload() ) );
vwgt.push_back( numeric_cast<int64_t>( blocks[ i ]->getWorkload() ) );
for( uint_t k = 0; k != block->getNeighborhoodSize(); ++k )
{
......@@ -971,10 +971,10 @@ void GlobalLoadBalancing::metis2( const std::vector< BLOCK* >& blocks, const uin
{
if( communicationWeights[ commIdx ] > real_t(0) )
{
adjncy.push_back( numeric_cast<idx_t>( block->getNeighbor( k )->getIndex() ) );
adjncy.push_back( numeric_cast<int64_t>( block->getNeighbor( k )->getIndex() ) );
WALBERLA_ASSERT_LESS( commIdx, communicationWeights.size() );
WALBERLA_ASSERT_GREATER( numeric_cast<idx_t>( communicationWeights[ commIdx ] ), idx_t(0) );
adjwgt.push_back( numeric_cast<idx_t>( communicationWeights[ commIdx ] ) );
WALBERLA_ASSERT_GREATER( numeric_cast<int64_t>( communicationWeights[ commIdx ] ), int64_t(0) );
adjwgt.push_back( numeric_cast<int64_t>( communicationWeights[ commIdx ] ) );
xadj.back() += 1;
}
++commIdx;
......@@ -987,21 +987,21 @@ void GlobalLoadBalancing::metis2( const std::vector< BLOCK* >& blocks, const uin
WALBERLA_ASSERT_EQUAL( adjncy.size(), adjwgt.size() );
WALBERLA_ASSERT_EQUAL( adjncy.size(), communicationWeights.size() );
idx_t nparts = numeric_cast<idx_t>( numberOfProcesses ); // number of parts to partition the graph
idx_t objval;
int64_t nparts = numeric_cast<int64_t>( numberOfProcesses ); // number of parts to partition the graph
int64_t objval;
std::vector< idx_t > part( uint_c(nvtxs) );
std::vector< int64_t > part( uint_c(nvtxs) );
idx_t options[ METIS_NOPTIONS ];
METIS_SetDefaultOptions( options );
options[ METIS_OPTION_NITER ] = 1000;
options[ METIS_OPTION_NSEPS ] = 100;
options[ METIS_OPTION_NCUTS ] = 100;
int64_t options[ METIS_NOPTIONS ];
core::METIS_SetDefaultOptions( options );
options[ core::METIS_OPTION_NITER ] = 1000;
options[ core::METIS_OPTION_NSEPS ] = 100;
options[ core::METIS_OPTION_NCUTS ] = 100;
int ret = METIS_PartGraphKway( &nvtxs, &ncon, &( xadj[ 0 ] ), &( adjncy[ 0 ] ), &( vwgt[ 0 ] ), NULL, &( adjwgt[0] ),
int ret = core::METIS_PartGraphKway( &nvtxs, &ncon, &( xadj[ 0 ] ), &( adjncy[ 0 ] ), &( vwgt[ 0 ] ), NULL, &( adjwgt[0] ),
&nparts, NULL, NULL, options, &objval, &( part[ 0 ] ) );
if( ret != METIS_OK )
if( ret != core::METIS_OK )
{
WALBERLA_ABORT( "METIS partitioning failed! Error: " << metisErrorCodeToString( ret ) );
}
......@@ -1028,24 +1028,16 @@ void GlobalLoadBalancing::metis2( const std::vector< BLOCK* >& blocks, const uin
std::ostream & GlobalLoadBalancing::metisErrorCodeToStream( int errorCode, std::ostream & oss )
{
switch( errorCode )
{
case METIS_OK:
if( errorCode == core::METIS_OK)
oss << "OK, no METIS error";
break;
case METIS_ERROR_INPUT:
else if( errorCode == core::METIS_ERROR_INPUT )
oss << "Error in METIS input";
break;
case METIS_ERROR_MEMORY:
else if (errorCode == core::METIS_ERROR_MEMORY )
oss << "METIS could not allocate enough memory";
break;
case METIS_ERROR:
else if (errorCode == core::METIS_ERROR )
oss << "Unknown type of error";
break;
default:
else
oss << "Unknown error code";
break;
}
return oss;
}
......@@ -1060,7 +1052,7 @@ std::string GlobalLoadBalancing::metisErrorCodeToString( int errorCode )
uint_t GlobalLoadBalancing::metisAdaptPartVector( std::vector< idx_t >& part, const uint_t numberOfProcesses )
uint_t GlobalLoadBalancing::metisAdaptPartVector( std::vector< int64_t >& part, const uint_t numberOfProcesses )
{
std::vector<bool> hasBlock( numberOfProcesses, false );
for( uint_t i = 0; i != part.size(); ++i )
......@@ -1090,7 +1082,7 @@ uint_t GlobalLoadBalancing::metisAdaptPartVector( std::vector< idx_t >& part, co
template< typename BLOCK >
memory_t GlobalLoadBalancing::metisMaxMemory( const std::vector< BLOCK* >& blocks, const uint_t numberOfProcesses,
const std::vector< idx_t >& part ) {
const std::vector< int64_t >& part ) {
WALBERLA_ASSERT_EQUAL( blocks.size(), part.size() );
......
//======================================================================================================================
//
// This file is part of waLBerla. waLBerla is free software: you can
// redistribute it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// waLBerla 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 General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
//
//! \file MetisWrapper.cpp
//! \ingroup blockforest
//! \author Christian Godenschwager <christian.godenschwager@fau.de>
//
//======================================================================================================================
#include "MetisWrapper.h"
#define WALBERLA_METIS_NOPTIONS METIS_NOPTIONS
#undef METIS_NOPTIONS
#include "waLBerlaDefinitions.h"
#include "core/Abort.h"
#include <boost/type_traits/is_same.hpp>
#ifdef WALBERLA_BUILD_WITH_METIS
#ifdef _MSC_VER
# pragma push_macro( "INT32_MIN" )
# pragma push_macro( "INT32_MAX" )
# pragma push_macro( "INT64_MIN" )
# pragma push_macro( "INT64_MAX" )
# ifdef INT32_MIN
# undef INT32_MIN
# endif
# ifdef INT32_MAX
# undef INT32_MAX
# endif
# ifdef INT64_MIN
# undef INT64_MIN
# endif
# ifdef INT64_MAX
# undef INT64_MAX
# endif
#endif
#ifdef WALBERLA_BUILD_WITH_METIS
# include "metis.h"
#endif
#ifdef _MSC_VER
# pragma pop_macro( "INT64_MAX" )
# pragma pop_macro( "INT64_MIN" )
# pragma pop_macro( "INT32_MAX" )
# pragma pop_macro( "INT32_MIN" )
#endif
static_assert(WALBERLA_METIS_NOPTIONS == METIS_NOPTIONS, "The macro METIS_NOPTIONS defined in blockforest/loadbalancing/MetisWRapper.h does not match the value in metis.h!");
#endif // WALBERLA_BUILD_WITH_METIS
namespace walberla {
namespace core {
#ifdef WALBERLA_BUILD_WITH_METIS
int METIS_PartGraphKway( ::walberla::int64_t *nvtxs, ::walberla::int64_t *ncon, ::walberla::int64_t *xadj, ::walberla::int64_t *adjncy,
::walberla::int64_t *vwgt, ::walberla::int64_t *vsize, ::walberla::int64_t *adjwgt, ::walberla::int64_t *nparts,
double *tpwgts, double *ubvec, ::walberla::int64_t *options, ::walberla::int64_t *edgecut, ::walberla::int64_t *part)
{
static_assert(boost::is_same< ::walberla::int64_t, ::idx_t >::value, "You have to compile the metis library with 64-bit wide integer type support!");
static_assert(boost::is_same< double, ::real_t >::value, "You have to compile the metis library with 64-bit wide floating-point type support!");
return ::METIS_PartGraphKway( nvtxs, ncon, xadj, adjncy, vwgt, vsize, adjwgt, nparts, tpwgts, ubvec, options, edgecut, part );
}
int METIS_PartGraphRecursive( ::walberla::int64_t *nvtxs, ::walberla::int64_t *ncon, ::walberla::int64_t *xadj, ::walberla::int64_t *adjncy,
::walberla::int64_t *vwgt, ::walberla::int64_t *vsize, ::walberla::int64_t *adjwgt, ::walberla::int64_t *nparts,
double *tpwgts, double *ubvec, ::walberla::int64_t *options, ::walberla::int64_t *edgecut, ::walberla::int64_t *part)
{
static_assert(boost::is_same< ::walberla::int64_t, ::idx_t >::value, "You have to compile the metis library with 64-bit wide integer type support!");
static_assert(boost::is_same< double, ::real_t >::value, "You have to compile the metis library with 64-bit wide floating-point type support!");
return ::METIS_PartGraphRecursive( nvtxs, ncon, xadj, adjncy, vwgt, vsize, adjwgt, nparts, tpwgts, ubvec, options, edgecut, part );
}
int METIS_SetDefaultOptions( ::walberla::int64_t *options )
{
static_assert(boost::is_same< ::walberla::int64_t, ::idx_t >::value, "You have to compile the metis library with 64-bit wide integer type support!");
return ::METIS_SetDefaultOptions( options );
}
const int METIS_OK = ::METIS_OK;
const int METIS_ERROR = ::METIS_ERROR;
const int METIS_ERROR_INPUT = ::METIS_ERROR_INPUT;
const int METIS_ERROR_MEMORY = ::METIS_ERROR_MEMORY;
const int METIS_OPTION_PTYPE = ::METIS_OPTION_PTYPE;
const int METIS_OPTION_OBJTYPE = ::METIS_OPTION_OBJTYPE;
const int METIS_OPTION_CTYPE = ::METIS_OPTION_CTYPE;
const int METIS_OPTION_IPTYPE = ::METIS_OPTION_IPTYPE;
const int METIS_OPTION_RTYPE = ::METIS_OPTION_RTYPE;
const int METIS_OPTION_DBGLVL = ::METIS_OPTION_DBGLVL;
const int METIS_OPTION_NITER = ::METIS_OPTION_NITER;
const int METIS_OPTION_NCUTS = ::METIS_OPTION_NCUTS;
const int METIS_OPTION_SEED = ::METIS_OPTION_SEED;
const int METIS_OPTION_NO2HOP = ::METIS_OPTION_NO2HOP;
const int METIS_OPTION_MINCONN = ::METIS_OPTION_MINCONN;
const int METIS_OPTION_CONTIG = ::METIS_OPTION_CONTIG;
const int METIS_OPTION_COMPRESS = ::METIS_OPTION_COMPRESS;
const int METIS_OPTION_CCORDER = ::METIS_OPTION_CCORDER;
const int METIS_OPTION_PFACTOR = ::METIS_OPTION_PFACTOR;
const int METIS_OPTION_NSEPS = ::METIS_OPTION_NSEPS;
const int METIS_OPTION_UFACTOR = ::METIS_OPTION_UFACTOR;
const int METIS_OPTION_NUMBERING = ::METIS_OPTION_NUMBERING;
const int METIS_OPTION_HELP = ::METIS_OPTION_HELP;
const int METIS_OPTION_TPWGTS = ::METIS_OPTION_TPWGTS;
const int METIS_OPTION_NCOMMON = ::METIS_OPTION_NCOMMON;
const int METIS_OPTION_NOOUTPUT = ::METIS_OPTION_NOOUTPUT;
const int METIS_OPTION_BALANCE = ::METIS_OPTION_BALANCE;
const int METIS_OPTION_GTYPE = ::METIS_OPTION_GTYPE;
const int METIS_OPTION_UBVEC = ::METIS_OPTION_UBVEC;
#else // build without Metis
int METIS_PartGraphKway( ::walberla::int64_t * /*nvtxs*/, ::walberla::int64_t * /*ncon*/, ::walberla::int64_t * /*xadj*/, ::walberla::int64_t * /*adjncy*/,
::walberla::int64_t * /*vwgt*/, ::walberla::int64_t * /*vsize*/, ::walberla::int64_t * /*adjwgt*/, ::walberla::int64_t * /*nparts*/,
double * /*tpwgts*/, double * /*ubvec*/, ::walberla::int64_t * /*options*/, ::walberla::int64_t * /*edgecut*/, ::walberla::int64_t * /*part*/)
{
WALBERLA_ABORT( "You are trying to use Metis functionality but waLBerla is not configured to use it. Set 'WALBERLA_BUILD_WITH_METIS' to 'ON' in your CMake cache to build against an installed version of Metis!" );
}
int METIS_SetDefaultOptions( ::walberla::int64_t * /*options*/ )
{
WALBERLA_ABORT("You are trying to use Metis functionality but waLBerla is not configured to use it. Set 'WALBERLA_BUILD_WITH_METIS' to 'ON' in your CMake cache to build against an installed version of Metis!");
}
const int METIS_OK = 0;
const int METIS_ERROR = 0;
const int METIS_ERROR_INPUT = 0;
const int METIS_ERROR_MEMORY = 0;
const int METIS_OPTION_PTYPE = 0;
const int METIS_OPTION_OBJTYPE = 0;
const int METIS_OPTION_CTYPE = 0;
const int METIS_OPTION_IPTYPE = 0;
const int METIS_OPTION_RTYPE = 0;
const int METIS_OPTION_DBGLVL = 0;
const int METIS_OPTION_NITER = 0;
const int METIS_OPTION_NCUTS = 0;
const int METIS_OPTION_SEED = 0;
const int METIS_OPTION_NO2HOP = 0;
const int METIS_OPTION_MINCONN = 0;
const int METIS_OPTION_CONTIG = 0;
const int METIS_OPTION_COMPRESS = 0;
const int METIS_OPTION_CCORDER = 0;
const int METIS_OPTION_PFACTOR = 0;
const int METIS_OPTION_NSEPS = 0;
const int METIS_OPTION_UFACTOR = 0;
const int METIS_OPTION_NUMBERING = 0;
const int METIS_OPTION_HELP = 0;
const int METIS_OPTION_TPWGTS = 0;
const int METIS_OPTION_NCOMMON = 0;
const int METIS_OPTION_NOOUTPUT = 0;
const int METIS_OPTION_BALANCE = 0;
const int METIS_OPTION_GTYPE = 0;
const int METIS_OPTION_UBVEC = 0;
#endif
} // namespace core
} // namespace walberla
\ No newline at end of file
//======================================================================================================================
//
// This file is part of waLBerla. waLBerla is free software: you can
// redistribute it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// waLBerla 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 General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
//
//! \file MetisWrapper.h
//! \ingroup blockforest
//! \author Christian Godenschwager <christian.godenschwager@fau.de>
//
//======================================================================================================================
#include "core/DataTypes.h"
#include "core/mpi/MPIWrapper.h"
namespace walberla {
namespace core {
int METIS_PartGraphKway( int64_t *nvtxs, int64_t *ncon, int64_t *xadj, int64_t *adjncy, int64_t *vwgt, int64_t *vsize, int64_t *adjwgt,
int64_t *nparts, double *tpwgts, double *ubvec, int64_t *options, int64_t *edgecut, int64_t *part );
int METIS_PartGraphRecursive( int64_t *nvtxs, int64_t *ncon, int64_t *xadj, int64_t *adjncy, int64_t *vwgt, int64_t *vsize, int64_t *adjwgt,
int64_t *nparts, double *tpwgts, double *ubvec, int64_t *options, int64_t *edgecut, int64_t *part );
int METIS_SetDefaultOptions(int64_t *options );
#ifndef METIS_NOPTIONS
# define METIS_NOPTIONS 40
#endif
extern const int METIS_OK;
extern const int METIS_ERROR;
extern const int METIS_ERROR_INPUT;
extern const int METIS_ERROR_MEMORY;
extern const int METIS_OPTION_PTYPE;
extern const int METIS_OPTION_OBJTYPE;
extern const int METIS_OPTION_CTYPE;
extern const int METIS_OPTION_IPTYPE;
extern const int METIS_OPTION_RTYPE;
extern const int METIS_OPTION_DBGLVL;
extern const int METIS_OPTION_NITER;
extern const int METIS_OPTION_NCUTS;
extern const int METIS_OPTION_SEED;
extern const int METIS_OPTION_NO2HOP;
extern const int METIS_OPTION_MINCONN;
extern const int METIS_OPTION_CONTIG;
extern const int METIS_OPTION_COMPRESS;
extern const int METIS_OPTION_CCORDER;
extern const int METIS_OPTION_PFACTOR;
extern const int METIS_OPTION_NSEPS;
extern const int METIS_OPTION_UFACTOR;
extern const int METIS_OPTION_NUMBERING;
extern const int METIS_OPTION_HELP;
extern const int METIS_OPTION_TPWGTS;
extern const int METIS_OPTION_NCOMMON;
extern const int METIS_OPTION_NOOUTPUT;
extern const int METIS_OPTION_BALANCE;
extern const int METIS_OPTION_GTYPE;
extern const int METIS_OPTION_UBVEC;
} // namespace core
} // namespace walberla
\ No newline at end of file
//======================================================================================================================
//
// This file is part of waLBerla. waLBerla is free software: you can
// redistribute it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// waLBerla 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 General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
//
//! \file ParMetisWrapper.cpp
//! \ingroup blockforest
//! \author Christian Godenschwager <christian.godenschwager@fau.de>
//
//======================================================================================================================
#include "waLBerlaDefinitions.h"
#ifdef WALBERLA_BUILD_WITH_PARMETIS
#ifdef _MSC_VER
# pragma push_macro( "INT32_MIN" )
# pragma push_macro( "INT32_MAX" )
# pragma push_macro( "INT64_MIN" )
# pragma push_macro( "INT64_MAX" )