Commit d4dc8462 authored by Dave Moxey's avatar Dave Moxey

Merge branch 'feature/collections' into 'master'

Feature/collections

This MR adds support for amalgamated operators.

See merge request !461
parents 79863088 e29fb6f5
......@@ -266,7 +266,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
# Build active components
IF (NEKTAR_BUILD_LIBRARY)
SET(NEKTAR++_LIBRARIES SolverUtils LibUtilities StdRegions SpatialDomains LocalRegions
MultiRegions)
MultiRegions Collections)
INCLUDE_DIRECTORIES(library)
ADD_SUBDIRECTORY(library)
INSTALL(EXPORT Nektar++Libraries DESTINATION ${LIB_DIR}/cmake)
......
......@@ -63,7 +63,7 @@ solvers in the nektar++-solvers package.")
SET(CPACK_RPM_PACKAGE_URL "www.nektar.info")
SET(CPACK_RPM_COMPONENT_INSTALL ON)
SET(CPACK_RPM_PACKAGE_REQUIRES "fftw3, libboost_date_time1_44_0, libboost_filesystem1_44_0, libboost_iostreams1_44_0, libboost_system1_44_0, libboost_thread1_44_0, zlib")
SET(CPACK_RPM_PACKAGE_REQUIRES "fftw3, libboost_date_time1_44_0, libboost_filesystem1_44_0, libboost_iostreams1_44_0, libboost_system1_44_0, libboost_thread1_44_0, libboost_timer1_44_0, zlib")
SET(CPACK_RPM_PACKAGE_DESCRIPTION "
The nektar++ packages provide a spectral/hp element framework for the numerical
solution of partial differential equations (PDEs). Demonstration codes are
......@@ -75,7 +75,7 @@ solvers in the nektar++-solvers package.")
MESSAGE(STATUS "Generating Packaging for DEB")
SET(CPACK_DEB_PACKAGE_URL "www.nektar.info")
SET(CPACK_DEB_COMPONENT_INSTALL ON)
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libfftw3-3,libboost-date-time1.42.0,libboost-filesystem1.42.0,libboost-iostreams1.42.0,libboost-program-options1.42.0,libboost-system1.42.0,libboost-thread1.42.0,zlib1g")
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libfftw3-3,libboost-date-time1.42.0,libboost-filesystem1.42.0,libboost-iostreams1.42.0,libboost-program-options1.42.0,libboost-system1.42.0,libboost-thread1.42.0,libboost-timer1.42.0,zlib1g")
SET(CPACK_DEBIAN_PACKAGE_DESCRIPTION
"${CPACK_PACKAGE_DESCRIPTION_SUMMARY}
${CPACK_PACKAGE_DESCRIPTION}")
......
......@@ -9,7 +9,7 @@
#If the user has not set BOOST_ROOT, look in a couple common places first.
MESSAGE(STATUS "Searching for Boost:")
SET(NEEDED_BOOST_LIBS thread iostreams date_time filesystem system
program_options regex)
program_options regex timer)
SET(Boost_DEBUG 0)
SET(Boost_NO_BOOST_CMAKE ON)
IF( BOOST_ROOT )
......@@ -66,7 +66,7 @@ IF (THIRDPARTY_BUILD_BOOST)
# Only build the libraries we need
SET(BOOST_LIB_LIST --with-system --with-iostreams --with-filesystem
--with-program_options --with-date_time --with-thread
--with-regex)
--with-regex --with-timer)
IF (NOT WIN32)
# We need -fPIC for 64-bit builds
......@@ -180,11 +180,15 @@ IF (THIRDPARTY_BUILD_BOOST)
SET(Boost_THREAD_LIBRARY boost_thread)
SET(Boost_THREAD_LIBRARY_DEBUG boost_thread)
SET(Boost_THREAD_LIBRARY_RELEASE boost_thread)
SET(Boost_TIMER_LIBRARY boost_timer)
SET(Boost_TIMER_LIBRARY_DEBUG boost_timer)
SET(Boost_TIMER_LIBRARY_RELEASE boost_timer)
SET(Boost_INCLUDE_DIRS ${TPSRC}/dist/include)
SET(Boost_CONFIG_INCLUDE_DIR ${TPINC})
SET(Boost_LIBRARY_DIRS ${TPSRC}/dist/lib)
SET(Boost_CONFIG_LIBRARY_DIR ${TPLIB})
SET(Boost_LIBRARIES boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_system boost_thread)
SET(Boost_LIBRARIES boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_system boost_thread boost_timer)
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
STRING(REPLACE ";" ", " NEEDED_BOOST_LIBS_STRING "${NEEDED_BOOST_LIBS}")
......
......@@ -352,6 +352,101 @@ Other classes:
\label{f:library:localregions}
\end{figure}
\section{Collections}
The Collections library contains optimised approaches to performing finite
element operations on multiple elements. Typically, the geometric information is
handled separately to the core reference operator, allowing the reference
operator to be applied to elements stored in contiguous blocks of memory. While
this does not necessarily reduce the operation count, data transfer from
memory to CPU is often substantially reduced and the contiguous storage
structures enable more efficient access, thereby reducing runtime.
\subsection{Structure}
The top-level container is the \texttt{Collection} class, which manages one or
more LocalRegions objects of the same type (shape and basis). The
\texttt{Operator} class generically describes an operation of these elements.
Derived classes from \texttt{Operator} are created for each specific operation
(e.g. BwdTrans, IProductWRTBase) on each element type. A factory pattern is used
to instantiate the correct class using the key triple (shape, operator, impl).
All classes relating to a particular operator are collated in a single .cpp
file.
An example template for a specific \texttt{Operator} class is as follows:
\begin{lstlisting}[style=C++Style]
class [[NAME]] : public Operator
{
public:
OPERATOR_CREATE([[NAME]])
virtual ~[[NAME]]()
{
}
virtual void operator()(
const Array<OneD, const NekDouble> &input,
Array<OneD, NekDouble> &output,
Array<OneD, NekDouble> &output1,
Array<OneD, NekDouble> &output2,
Array<OneD, NekDouble> &wsp)
{
[[IMPLEMENTATION]]
}
protected:
[[MEMBERS]]
private:
[[NAME]](
vector<StdRegions::StdExpansionSharedPtr> pCollExp,
CoalescedGeomDataSharedPtr pGeomData)
: Operator(pCollExp, pGeomData)
{
[[INITIALISATION]]
}
};
\end{lstlisting}
The placeholders in double square brackets should be replaced as follows:
\begin{itemize}
\item \texttt{[[NAME]]}: The name of the class in the form
\begin{lstlisting}
<operation>_<impl>{_<shape>}
\end{lstlisting}
where the shape need only be included if the operator is shape-specific.
\item \texttt{[[MEMBERS]]}: Any member variables necessary to store precomputed
quantities and ensure computational efficiency.
\item \texttt{[[IMPLEMENTATION]]}: The code which actually computes the action
of the operator on the elements in the collection.
\item \texttt{[[INITIALIZATION]]}: Code to initialize member variables and
precomputed quantities.
\end{itemize}
\subsection{Instantiation}
Operators are instantiated through the OperatorFactory. Therefore the operator
classes must be registered with the factory during start-up. This is achieved
using static initialisation with either the \texttt{m\_type} or
\texttt{m\_typeArr}. The latter is shown in the following example:
\begin{lstlisting}[style=C++Style]
OperatorKey BwdTrans_StdMat::m_typeArr[] = {
GetOperatorFactory().RegisterCreatorFunction(
OperatorKey(eSegment, eBwdTrans, eStdMat,false),
BwdTrans_StdMat::create, "BwdTrans_StdMat_Seg"),
GetOperatorFactory().RegisterCreatorFunction(
OperatorKey(eTriangle, eBwdTrans, eStdMat,false),
BwdTrans_StdMat::create, "BwdTrans_StdMat_Tri"),
...
};
\end{lstlisting}
This instructs the factory to use the \texttt{BwdTrans\_StdMat} class for all
shapes when performing a backward transform using the \texttt{StdMat} approach.
In contrast, if the class is shape specific, the non-array member variable would
be initialised, for example:
\begin{lstlisting}[style=C++Style]
OperatorKey BwdTrans_SumFac_Seg::m_type = GetOperatorFactory().
RegisterCreatorFunction(
OperatorKey(eSegment, eBwdTrans, eSumFac, false),
BwdTrans_SumFac_Seg::create, "BwdTrans_SumFac_Seg");
\end{lstlisting}
\section{MultiRegions}
In the MultiRegions library, all classes and routines are related to the
process of assembling a global spectral/hp expansion out of local elemental
......
......@@ -128,6 +128,76 @@ For very complex operators -- in particular \inltt{HelmholtzMatrixOp} -- always
set \inltt{DO\_BLOCK\_MAT\_OP} to \inltt{1} as sum-factorisation for these
operator types can be costly.
\section{Collections}
The Collections library adds optimisations to perform certain elemental
operations collectively by applying an operator using a matrix-matrix operation,
rather than a sequence of matrix-vector multiplications. Certain operators
benefit more than other from this treatment, so the following implementations
are available:
\begin{itemize}
\item StdMat: Perform operations using collated matrix-matrix type elemental
operation.
\item SumFac: Perform operation using collated matrix-matrix type sum
factorisation operations.
\item IterPerExp: Loop through elements, performing matrix-vector operation.
\item NoCollections: Use the original LocalRegions implementation to
perform the operation.
\end{itemize}
All configuration relating to Collections is given in the \inltt{COLLECTIONS}
XML element within the \inltt{NEKTAR} XML element.
\subsection{Default implementation}
The default implementation for all operators may be chosen through setting the
\inltt{DEFAULT} attribute of the \inltt{COLLECTIONS} XML element to one of
\inltt{StdMat}, \inltt{SumFac}, \inltt{IterPerExp} or \inltt{NoCollection}. For
example, the following uses the collated matrix-matrix type elemental operation
for all operators and expansion orders:
\begin{lstlisting}[style=XmlStyle]
<COLLECTIONS DEFAULT="StdMat" />
\end{lstlisting}
\subsection{Auto-tuning}
The choice of implementation for each operator, for the given mesh and
expansion orders, can be selected automatically through
auto-tuning. To enable this, add the following to the \nekpp session
file:
\begin{lstlisting}[style=XmlStyle]
<COLLECTIONS DEFAULT="auto" />
\end{lstlisting}
This will collate elements from the given mesh and given expansion orders,
run and time each implementation strategy in turn, and select the fastest
performing case. Note that the selections will be mesh- and order- specific.
The selections made via auto-tuning are output if the \inlsh{--verbose}
command-line switch is given.
\subsection{Manual selection}
The choice of implementation for each operator may be set manually within the
\inltt{COLLECTIONS} tag as shown in the following example. Different implementations may be chosen for different element shapes and expansion orders.
Specifying \inltt{*} for \inltt{ORDER} sets the default implementation for any
expansion orders not explicity defined.
\begin{lstlisting}[style=XmlStyle]
<COLLECTIONS>
<OPERATOR TYPE="BwdTrans">
<ELEMENT TYPE="T" ORDER="*" IMPTYPE="IterPerExp" />
<ELEMENT TYPE="T" ORDER="1-5" IMPTYPE="StdMat" />
</OPERATOR>
<OPERATOR TYPE="IProductWRTBase">
<ELEMENT TYPE="Q" ORDER="*" IMPTYPE="SumFac" />
</OPERATOR>
</COLLECTIONS>
\end{lstlisting}
Manual selection is intended to document the optimal selections on a given
hardware platform after extensive prior testing, to avoid the need to run the
auto-tuning for each run.
\subsection{Collection size}
The maximum number of elements within a single collection can be enforced using
the \inltt{MAXSIZE} attribute.
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "../user-guide"
......
SET(LibrarySubDirs LibUtilities LocalRegions MultiRegions SpatialDomains
StdRegions SolverUtils)
SET(LibrarySubDirs LibUtilities LocalRegions Collections
MultiRegions SpatialDomains StdRegions SolverUtils)
SET(UnitTestSubDirs UnitTests)
SET(DemoSubDirs Demos)
SET(TimingsSubDirs Timings)
SET(DemoSubDirs Demos)
SET(TimingsSubDirs Timings)
SUBDIRS(${LibrarySubDirs} )
......
This diff is collapsed.
SET(COLLECTIONS_SOURCES
CoalescedGeomData.cpp
Collection.cpp
CollectionOptimisation.cpp
Operator.cpp
BwdTrans.cpp
IProductWRTBase.cpp
PhysDeriv.cpp
IProductWRTDerivBase.cpp
IProduct.cpp
)
SET(SOLVER_UTILS_HEADERS
CoalescedGeomData.h
Collection.h
CollectionOptimisation.h
IProduct.h
Operator.h
)
ADD_NEKTAR_LIBRARY(Collections lib ${NEKTAR_LIBRARY_TYPE}
${COLLECTIONS_SOURCES} ${COLLECTIONS_HEADERS})
TARGET_LINK_LIBRARIES(Collections LINK_PUBLIC LocalRegions)
INSTALL(DIRECTORY ./
DESTINATION ${NEKTAR_INCLUDE_DIR}/Collections
COMPONENT dev
FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp")
///////////////////////////////////////////////////////////////////////////////
//
// File: Collection.cpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Collection top class definition
//
///////////////////////////////////////////////////////////////////////////////
#include <SpatialDomains/GeomFactors.h>
#include <Collections/CoalescedGeomData.h>
using namespace std;
namespace Nektar {
namespace Collections {
CoalescedGeomData::CoalescedGeomData(void)
{
}
CoalescedGeomData::~CoalescedGeomData(void)
{
}
const Array<OneD, const NekDouble> &CoalescedGeomData::GetJac(
vector<StdRegions::StdExpansionSharedPtr> &pCollExp)
{
if(m_oneDGeomData.count(eJac) == 0)
{
LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
int nElmts = pCollExp.size();
// set up Cached Jacobians to be continuous
int npts = 1;
for (int i = 0; i < ptsKeys.size(); ++i)
{
npts *= ptsKeys[i].GetNumPoints();
}
Array<OneD, NekDouble> newjac(npts*nElmts);
//copy Jacobians into a continuous list and set new chatched value
int cnt = 0;
for(int i = 0; i < nElmts; ++i)
{
const Array<OneD, const NekDouble> jac =
pCollExp[i]->GetMetricInfo()->GetJac(ptsKeys);
if (pCollExp[i]->GetMetricInfo()->GetGtype() ==
SpatialDomains::eDeformed)
{
Vmath::Vcopy(npts, &jac[0], 1, &newjac[cnt], 1);
}
else
{
Vmath::Fill(npts, jac[0], &newjac[cnt], 1);
}
cnt += npts;
}
m_oneDGeomData[eJac] = newjac;
}
return m_oneDGeomData[eJac];
}
const Array<OneD, const NekDouble> &CoalescedGeomData::GetJacWithStdWeights(
vector<StdRegions::StdExpansionSharedPtr> &pCollExp)
{
if(m_oneDGeomData.count(eJacWithStdWeights) == 0)
{
LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
int nElmts = pCollExp.size();
// set up Cached Jacobians to be continuous
int npts = 1;
for (int i = 0; i < ptsKeys.size(); ++i)
{
npts *= ptsKeys[i].GetNumPoints();
}
Array<OneD, NekDouble> newjac(npts*nElmts), tmp;
//copy Jacobians into a continuous list and set new chatched value
int cnt = 0;
for(int i = 0; i < nElmts; ++i)
{
const Array<OneD, const NekDouble> jac =
pCollExp[i]->GetMetricInfo()->GetJac(ptsKeys);
if (pCollExp[i]->GetMetricInfo()->GetGtype() ==
SpatialDomains::eDeformed)
{
Vmath::Vcopy(npts, &jac[0], 1, &newjac[cnt], 1);
}
else
{
Vmath::Fill(npts, jac[0], &newjac[cnt], 1);
}
pCollExp[0]->MultiplyByStdQuadratureMetric(newjac + cnt,
tmp = newjac + cnt);
cnt += npts;
}
m_oneDGeomData[eJacWithStdWeights] = newjac;
}
return m_oneDGeomData[eJacWithStdWeights];
}
const Array<TwoD, const NekDouble> &CoalescedGeomData::GetDerivFactors(
vector<StdRegions::StdExpansionSharedPtr> &pCollExp)
{
if(m_twoDGeomData.count(eDerivFactors) == 0)
{
LibUtilities::PointsKeyVector ptsKeys = pCollExp[0]->GetPointsKeys();
int nElmts = pCollExp.size();
const int coordim = pCollExp[0]->GetCoordim();
int dim = ptsKeys.size();
// set up Cached Jacobians to be continuous
int npts = 1;
for (int i = 0; i < dim; ++i)
{
npts *= ptsKeys[i].GetNumPoints();
}
Array<TwoD, NekDouble> newDFac(dim*coordim,npts*nElmts);
//copy Jacobians into a continuous list and set new chatched value
int cnt = 0;
for(int i = 0; i < nElmts; ++i)
{
const Array<TwoD, const NekDouble> Dfac =
pCollExp[i]->GetMetricInfo()->GetDerivFactors(ptsKeys);
if (pCollExp[i]->GetMetricInfo()->GetGtype() ==
SpatialDomains::eDeformed)
{
for (int j = 0; j < dim*coordim; ++j)
{
Vmath::Vcopy(npts, &Dfac[j][0], 1, &newDFac[j][cnt], 1);
}
}
else
{
for (int j = 0; j < dim*coordim; ++j)
{
Vmath::Fill(npts, Dfac[j][0], &newDFac[j][cnt], 1);
}
}
cnt += npts;
}
m_twoDGeomData[eDerivFactors] = newDFac;
}
return m_twoDGeomData[eDerivFactors];
}
}
}
///////////////////////////////////////////////////////////////////////////////
//
// File: CoalescedGeomData.h
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Coalesced geometry data definition
//
///////////////////////////////////////////////////////////////////////////////
#ifndef NEKTAR_LIBRARY_COLLECTIONS_COALESCEDGEOMDATA_H
#define NEKTAR_LIBRARY_COLLECTIONS_COALESCEDGEOMDATA_H
#include <map>
#include <vector>
#include <StdRegions/StdExpansion.h>
namespace Nektar {
namespace Collections {
enum GeomData
{
eJac,
eJacWithStdWeights,
eDerivFactors
};
class CoalescedGeomData
{
public:
CoalescedGeomData(void);
virtual ~CoalescedGeomData(void);
const Array<OneD, const NekDouble> &GetJac(
std::vector<StdRegions::StdExpansionSharedPtr> &pColLExp);
const Array<OneD, const NekDouble> &GetJacWithStdWeights(
std::vector<StdRegions::StdExpansionSharedPtr> &pColLExp);
const Array<TwoD, const NekDouble> &GetDerivFactors(
std::vector<StdRegions::StdExpansionSharedPtr> &pColLExp);
private:
std::map<GeomData,Array<OneD, NekDouble> > m_oneDGeomData;
std::map<GeomData,Array<TwoD, NekDouble> > m_twoDGeomData;
};
typedef boost::shared_ptr<CoalescedGeomData> CoalescedGeomDataSharedPtr;
static CoalescedGeomDataSharedPtr GeomDataNull;
}
}
#endif
///////////////////////////////////////////////////////////////////////////////
//
// File: Collection.cpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.