ENH: metis: use PrecisionAdaptor to support 64 bit indices
This commit is contained in:
parent
da07aa9ac0
commit
01ea3cc790
@ -36,6 +36,7 @@ Description
|
||||
#ifndef PrecisionAdaptor_H
|
||||
#define PrecisionAdaptor_H
|
||||
|
||||
#include "tmpNrc.H"
|
||||
#include "Field.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -44,34 +45,34 @@ namespace Foam
|
||||
{
|
||||
|
||||
//- A const Field wrapper with possible data conversion
|
||||
template<class Type, class InputType>
|
||||
template<class Type, class InputType, template<class> class Container = Field>
|
||||
class ConstPrecisionAdaptor
|
||||
:
|
||||
public tmp<Field<Type>>
|
||||
public tmpNrc<Container<Type>>
|
||||
{
|
||||
// Private Member Functions
|
||||
|
||||
//- Copy in field
|
||||
void copyInput(const Field<InputType>& input)
|
||||
void copyInput(const Container<InputType>& input)
|
||||
{
|
||||
this->clear();
|
||||
|
||||
Field<Type>* p = new Field<Type>(input.size());
|
||||
Container<Type>* p = new Container<Type>(input.size());
|
||||
this->reset(p);
|
||||
std::copy(input.cbegin(), input.cend(), p->begin());
|
||||
}
|
||||
|
||||
//- Construct from tmp Field, copy/move as required
|
||||
void moveInput(tmp<Field<InputType>>& input)
|
||||
void moveInput(tmp<Container<InputType>>& input)
|
||||
{
|
||||
if (std::is_same<Type, InputType>::value)
|
||||
{
|
||||
auto& tinput = reinterpret_cast<tmp<FieldType>&>(input);
|
||||
auto& tinput = reinterpret_cast<tmp<Container<Type>>&>(input);
|
||||
|
||||
if (tinput.isTmp())
|
||||
{
|
||||
this->clear();
|
||||
this->swap(tinput);
|
||||
// Reset to tmp
|
||||
this->reset(tinput.ptr());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -89,15 +90,15 @@ class ConstPrecisionAdaptor
|
||||
public:
|
||||
|
||||
//- The adapted field type
|
||||
typedef Field<Type> FieldType;
|
||||
typedef Container<Type> FieldType;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from Field<InputType>, copying on input as required
|
||||
ConstPrecisionAdaptor(const Field<InputType>& input)
|
||||
//- Construct from Container<InputType>, copying on input as required
|
||||
ConstPrecisionAdaptor(const Container<InputType>& input)
|
||||
:
|
||||
tmp<Field<Type>>()
|
||||
tmpNrc<Container<Type>>()
|
||||
{
|
||||
if (std::is_same<Type, InputType>::value)
|
||||
{
|
||||
@ -110,31 +111,31 @@ public:
|
||||
}
|
||||
|
||||
|
||||
//- Construct from tmp Field, copy/move as required
|
||||
ConstPrecisionAdaptor(tmp<Field<InputType>>&& input)
|
||||
//- Construct from tmp Container, copy/move as required
|
||||
ConstPrecisionAdaptor(tmp<Container<InputType>>&& input)
|
||||
:
|
||||
tmp<Field<Type>>()
|
||||
tmpNrc<Container<Type>>()
|
||||
{
|
||||
this->moveInput(input);
|
||||
}
|
||||
|
||||
|
||||
//- Construct from tmp Field, copy/move as required
|
||||
ConstPrecisionAdaptor(const tmp<Field<InputType>>& input)
|
||||
//- Construct from tmp Container, copy/move as required
|
||||
ConstPrecisionAdaptor(const tmp<Container<InputType>>& input)
|
||||
:
|
||||
tmp<Field<Type>>()
|
||||
tmpNrc<Container<Type>>()
|
||||
{
|
||||
this->moveInput(const_cast<tmp<Field<InputType>>&>(input));
|
||||
this->moveInput(const_cast<tmp<Container<InputType>>&>(input));
|
||||
}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return the field
|
||||
static const Field<Type>& get
|
||||
static const Container<Type>& get
|
||||
(
|
||||
const Field<InputType>& input,
|
||||
Field<Type>& dst
|
||||
const Container<InputType>& input,
|
||||
Container<Type>& dst
|
||||
)
|
||||
{
|
||||
if (std::is_same<Type, InputType>::value)
|
||||
@ -152,25 +153,23 @@ public:
|
||||
|
||||
|
||||
//- A Field wrapper with possible data conversion
|
||||
template<class Type, class InputType>
|
||||
template<class Type, class InputType, template<class> class Container = Field>
|
||||
class PrecisionAdaptor
|
||||
:
|
||||
public tmp<Field<Type>>
|
||||
public tmpNrc<Container<Type>>
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- Reference to underlying field
|
||||
Field<InputType>& ref_;
|
||||
Container<InputType>& ref_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Copy in field
|
||||
void copyInput(const Field<InputType>& input)
|
||||
void copyInput(const Container<InputType>& input)
|
||||
{
|
||||
this->clear();
|
||||
|
||||
Field<Type>* p = new Field<Type>(input.size());
|
||||
Container<Type>* p = new Container<Type>(input.size());
|
||||
this->reset(p);
|
||||
std::copy(input.cbegin(), input.cend(), p->begin());
|
||||
}
|
||||
@ -179,15 +178,15 @@ class PrecisionAdaptor
|
||||
public:
|
||||
|
||||
//- The adapted field type
|
||||
typedef Field<Type> FieldType;
|
||||
typedef Container<Type> FieldType;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from Field<InputType>, copying on input as required
|
||||
PrecisionAdaptor(Field<InputType>& input)
|
||||
//- Construct from Container<InputType>, copying on input as required
|
||||
PrecisionAdaptor(Container<InputType>& input)
|
||||
:
|
||||
tmp<Field<Type>>(),
|
||||
tmpNrc<Container<Type>>(),
|
||||
ref_(input)
|
||||
{
|
||||
if (std::is_same<Type, InputType>::value)
|
||||
|
@ -42,6 +42,7 @@ See also
|
||||
|
||||
#include "refCount.H"
|
||||
#include "word.H"
|
||||
#include "tmp.H"
|
||||
#include <utility>
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -229,6 +230,9 @@ public:
|
||||
//- Transfer ownership of the managed pointer.
|
||||
// Fatal for a null managed pointer or if the object is const.
|
||||
inline void operator=(const tmpNrc<T>& t);
|
||||
|
||||
//- Conversion to tmp
|
||||
inline operator tmp<T>();
|
||||
};
|
||||
|
||||
|
||||
|
@ -427,4 +427,18 @@ inline void Foam::tmpNrc<T>::operator=(const tmpNrc<T>& t)
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::tmpNrc<T>::operator tmp<T>()
|
||||
{
|
||||
if (isTmp())
|
||||
{
|
||||
return tmp<T>(ptr());
|
||||
}
|
||||
else
|
||||
{
|
||||
return tmp<T>(cref());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
@ -28,6 +28,7 @@ License
|
||||
#include "metisDecomp.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "Time.H"
|
||||
#include "PrecisionAdaptor.H"
|
||||
|
||||
// Probably not needed...
|
||||
#define MPICH_SKIP_MPICXX
|
||||
@ -39,13 +40,13 @@ License
|
||||
//
|
||||
// Metis has an 'idx_t' type, but the IDXTYPEWIDTH define is perhaps
|
||||
// more future-proof?
|
||||
#ifdef IDXTYPEWIDTH
|
||||
static_assert
|
||||
(
|
||||
sizeof(Foam::label) == (IDXTYPEWIDTH/8),
|
||||
"sizeof(Foam::label) == (IDXTYPEWIDTH/8), check your metis headers"
|
||||
);
|
||||
#endif
|
||||
//#ifdef IDXTYPEWIDTH
|
||||
//static_assert
|
||||
//(
|
||||
// sizeof(Foam::label) == (IDXTYPEWIDTH/8),
|
||||
// "sizeof(Foam::label) == (IDXTYPEWIDTH/8), check your metis headers"
|
||||
//);
|
||||
//#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -86,10 +87,10 @@ Foam::label Foam::metisDecomp::decomposeSerial
|
||||
|
||||
const dictionary* coeffsDictPtr = decompDict_.findDict("metisCoeffs");
|
||||
|
||||
label numCells = xadj.size()-1;
|
||||
idx_t numCells = xadj.size()-1;
|
||||
|
||||
// Decomposition options
|
||||
List<label> options(METIS_NOPTIONS);
|
||||
List<idx_t> options(METIS_NOPTIONS);
|
||||
METIS_SetDefaultOptions(options.begin());
|
||||
|
||||
// Processor weights initialised with no size, only used if specified in
|
||||
@ -97,10 +98,10 @@ Foam::label Foam::metisDecomp::decomposeSerial
|
||||
Field<real_t> processorWeights;
|
||||
|
||||
// Cell weights (so on the vertices of the dual)
|
||||
List<label> cellWeights;
|
||||
List<idx_t> cellWeights;
|
||||
|
||||
// Face weights (so on the edges of the dual)
|
||||
List<label> faceWeights;
|
||||
List<idx_t> faceWeights;
|
||||
|
||||
// Check for externally provided cellweights and if so initialise weights
|
||||
// Note: min, not gMin since routine runs on master only.
|
||||
@ -184,51 +185,56 @@ Foam::label Foam::metisDecomp::decomposeSerial
|
||||
}
|
||||
}
|
||||
|
||||
label ncon = 1;
|
||||
label nProcs = nDomains_;
|
||||
idx_t ncon = 1;
|
||||
idx_t nProcs = nDomains_;
|
||||
|
||||
// Addressing
|
||||
ConstPrecisionAdaptor<idx_t, label, List> xadj_metis(xadj);
|
||||
ConstPrecisionAdaptor<idx_t, label, List> adjncy_metis(adjncy);
|
||||
|
||||
// Output: cell -> processor addressing
|
||||
decomp.setSize(numCells);
|
||||
PrecisionAdaptor<idx_t, label, List> decomp_metis(decomp);
|
||||
decomp_metis.ref().setSize(numCells);
|
||||
|
||||
// Output: number of cut edges
|
||||
label edgeCut = 0;
|
||||
idx_t edgeCut = 0;
|
||||
|
||||
if (method == "recursive")
|
||||
{
|
||||
METIS_PartGraphRecursive
|
||||
(
|
||||
&numCells, // num vertices in graph
|
||||
&ncon, // num balancing constraints
|
||||
const_cast<labelUList&>(xadj).begin(), // indexing into adjncy
|
||||
const_cast<labelUList&>(adjncy).begin(), // neighbour info
|
||||
cellWeights.begin(),// vertex wts
|
||||
nullptr, // vsize: total communication vol
|
||||
faceWeights.begin(),// edge wts
|
||||
&nProcs, // nParts
|
||||
&numCells, // num vertices in graph
|
||||
&ncon, // num balancing constraints
|
||||
xadj_metis.ref().begin(), // indexing into adjncy
|
||||
adjncy_metis.ref().begin(), // neighbour info
|
||||
cellWeights.begin(), // vertex wts
|
||||
nullptr, // vsize: total communication vol
|
||||
faceWeights.begin(), // edge wts
|
||||
&nProcs, // nParts
|
||||
processorWeights.begin(), // tpwgts
|
||||
nullptr, // ubvec: processor imbalance (default)
|
||||
nullptr, // ubvec: processor imbalance (default)
|
||||
options.begin(),
|
||||
&edgeCut,
|
||||
decomp.begin()
|
||||
decomp_metis.ref().begin()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
METIS_PartGraphKway
|
||||
(
|
||||
&numCells, // num vertices in graph
|
||||
&ncon, // num balancing constraints
|
||||
const_cast<labelUList&>(xadj).begin(), // indexing into adjncy
|
||||
const_cast<labelUList&>(adjncy).begin(), // neighbour info
|
||||
cellWeights.begin(),// vertex wts
|
||||
nullptr, // vsize: total communication vol
|
||||
faceWeights.begin(),// edge wts
|
||||
&nProcs, // nParts
|
||||
&numCells, // num vertices in graph
|
||||
&ncon, // num balancing constraints
|
||||
xadj_metis.ref().begin(), // indexing into adjncy
|
||||
adjncy_metis.ref().begin(), // neighbour info
|
||||
cellWeights.begin(), // vertex wts
|
||||
nullptr, // vsize: total communication vol
|
||||
faceWeights.begin(), // edge wts
|
||||
&nProcs, // nParts
|
||||
processorWeights.begin(), // tpwgts
|
||||
nullptr, // ubvec: processor imbalance (default)
|
||||
nullptr, // ubvec: processor imbalance (default)
|
||||
options.begin(),
|
||||
&edgeCut,
|
||||
decomp.begin()
|
||||
decomp_metis.ref().begin()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ have_metis()
|
||||
|
||||
# ----------------------------------
|
||||
|
||||
local good label
|
||||
local label
|
||||
|
||||
# Ensure consistent sizes between OpenFOAM and metis header
|
||||
# Extract IDXTYPEWIDTH from metis.h: regex as per ThirdParty Allwmake
|
||||
@ -116,18 +116,6 @@ have_metis()
|
||||
"$header")
|
||||
: "${label:=unknown}"
|
||||
|
||||
if [ "$WM_LABEL_SIZE" = "$label" ]
|
||||
then
|
||||
good=true
|
||||
else
|
||||
if [ -n "$warn" ]
|
||||
then
|
||||
echo "$warn (label=$WM_LABEL_SIZE, ${header##*/} has '$label')"
|
||||
fi
|
||||
no_metis
|
||||
return 1
|
||||
fi
|
||||
|
||||
# OK
|
||||
echo "metis (label=$label) - $prefix"
|
||||
export HAVE_METIS=true
|
||||
|
Loading…
Reference in New Issue
Block a user