Commit b7345df6 authored by Carsten Gräser's avatar Carsten Gräser

Merge branch 'rename-manual' into 'master'

Import the document on the functions interface

See merge request !175
parents e9573d92 041b8e9e
Pipeline #9989 passed with stage
in 5 minutes and 51 seconds
......@@ -11,3 +11,5 @@
*.toc
dune-functions-bases.pdf
dune-functions-functions.pdf
set(SOURCES
../../examples/interpolation.cc
../../examples/stokes-taylorhood.cc
)
if(LATEX_USABLE)
set(IMAGES
gfx/driven_cavity.pdf
gfx/driven_cavity_result.png
gfx/febasis_interface_schematic.pdf
)
set(BASES_SOURCES
../../examples/interpolation.cc
../../examples/stokes-taylorhood.cc
)
set(BASES_IMAGES
gfx/driven_cavity.pdf
gfx/driven_cavity_result.png
gfx/febasis_interface_schematic.pdf
)
dune_add_latex_document(dune-functions-bases.tex
BIBFILES dune-functions-bases.bib
INPUTS ${BASES_SOURCES}
IMAGES ${BASES_IMAGES})
set(FUNCTIONS_SOURCES
src/integration-test.cc
gfx/timings_gcc.pgf
gfx/timings_gcc_pgo.pgf
gfx/timings_clang.pgf
)
set(FUNCTIONS_IMAGES
gfx/functions_interface_schematic.pdf
)
dune_add_latex_document(dune-functions-functions.tex
BIBFILES dune-functions-functions.bib
INPUTS ${FUNCTIONS_SOURCES}
IMAGES ${FUNCTIONS_IMAGES})
if(LATEX_USABLE)
dune_add_latex_document(dune-functions-bases.tex
BIBFILES dune-functions-bases.bib
INPUTS ${SOURCES}
IMAGES ${IMAGES})
endif(LATEX_USABLE)
......@@ -5,7 +5,9 @@
\usepackage{scrhack} % Fix a LaTeX warning
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage[utf8x]{inputenc}
\usepackage[utf8]{inputenc}
\usepackage{fancyhdr}
\pagestyle{fancy}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
......@@ -61,9 +63,11 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%% hyperref should be loaded late to avoid incompatibilities
\usepackage[pdftitle={Function space bases in the dune-functions module},
pdfauthor={Christian Engwer, Carsten Gräser, Steffen Müthing, and Oliver Sander}]
{hyperref}
\usepackage{hyperref}
\hypersetup{pdftitle={Function space bases in the dune-functions module},
pdfauthor={Christian Engwer, Carsten Gräser, Steffen Müthing, and Oliver Sander} }
\usepackage{attachfile2}
\usepackage{fancyvrb}
......@@ -140,6 +144,9 @@
\author{Christian Engwer, Carsten Gräser,\\ Steffen Müthing, and Oliver Sander}
%\date{}
\lhead{C.~Engwer, C.~Gräser, S.~Müthing, O.~Sander}
\rhead{Bases in dune-functions}
\begin{document}
\maketitle
......
@article{bastian_et_al:dune1:2008,
author = {Bastian, P. and Blatt, M. and Dedner, A. and Engwer, C. and Kl{\"o}fkorn, R. and Ohlberger, M. and Sander, O.},
title = {A Generic Grid Interface for Adaptive and Parallel Scientific Computing. {P}art {I}: Abstract Framework},
journal = {Computing},
year = {2008},
volume = {82},
number = {2--3},
pages = {103--119}
}
@article{bastian_et_al:dune2:2008,
author = {Bastian, P. and Blatt, M. and Dedner, A. and Engwer, C. and Kl\"ofkorn, R. and Kornhuber, R. and Ohlberger, M. and Sander, O.},
title = {A Generic Grid Interface for Adaptive and Parallel Scientific Computing. {P}art {II}: Implementation and Tests in {DUNE}},
journal = {Computing},
year = {2008},
volume = {82},
number = {2--3},
pages = {121--138}
}
@misc{Niebler:rangev3,
title = {Range-v3 library},
author = {Niebler, E.},
howpublished = {\url{https://github.com/ericniebler/range-v3}}
}
@misc{DuneFunctions,
title = {Dune-functions module},
author = {Engwer, C. and Gr{\"a}ser, C. and Müthing, S. and Sander, O.},
howpublished = {\url{http://www.dune-project.org/modules/dune-functions}}
}
@misc{Adobe:asl,
title = {Adobe Source Libraries},
author = {Parent, S. and Marcus, M. and Brereton, F.},
howpublished = {\url{http://stlab.adobe.com/}}
}
@misc{Watanabe:boost_type_erasure,
title = {Boost type erasure library},
author = {Watanabe, S.},
howpublished = {\url{http://www.boost.org/doc/libs/release/libs/type_erasure/}}
}
@misc{Niebler:concepts,
author = {Niebler, E.},
title = {Concept checking in {C}++11},
howpublished = {online blog, \url{http://ericniebler.com/2013/11/23/concept-checking-in-c11}},
year = {2013},
note = {last checked on Dec.\,8.\,2015},
lastchecked = {Dec.\,8.\,2015}
}
@inproceedings{driesen_hoelzle:1996,
author = {Driesen, K. and H\"{o}lzle, U.},
title = {The Direct Cost of Virtual Function Calls in {C}++},
booktitle = {Proceedings of the 11th ACM SIGPLAN Conference on Object-oriented Programming, Systems, Languages, and Applications},
series = {OOPSLA '96},
year = {1996},
pages = {306--323},
acmid = {236369},
publisher = {ACM}
}
@Misc{hubicka:2014,
author = {Hubi\v{c}ka, J.},
title = {Devirtualization in {C}++},
howpublished = {online blog, \url{{http://hubicka.blogspot.de/2014/01/devirtualization-in-c-part-1.html}}},
year = {2014},
note = {(at least) seven parts, last checked on Dec.\,8.\,2015},
url = {http://hubicka.blogspot.de/2014/01/devirtualization-in-c-part-1.html},
lastchecked = {Dec.\,8.\,2015}
}
@misc{cpp_standard:2003,
Author = {{International Organization for Standardization}},
Month = {9},
Shortauthor = {{ISO}},
Title = {{ISO/IEC 14882:2003 Programming Language C++}},
Year = {2003}
}
@misc{cpp_standard:2011,
Author = {{International Organization for Standardization}},
Month = {9},
Shortauthor = {{ISO}},
Title = {{ISO/IEC 14882:2011 Programming Language C++}},
Year = {2011}
}
@article{engwer_graeser_muething_sander:2015,
author = {Christian Engwer and Carsten Gräser and Steffen Müthing and Oliver Sander},
title = {The Interface for Functions in the dune-functions Module},
year = {2017},
journal = {Archive of Numerical Software},
volume = {5},
number = {1},
pages = {95--105},
doi = {10.11588/ans.2017.1.27683},
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
# Building and running the code
These are the build instructions for the code to reproduce
the numerical examples in the article
> The interface for functions in the dune-functions module
by Christian Engwer, Carsten Gräser, Steffen Müthing, and Oliver Sander.
## Numerical examples
### Requirements
Since the numerical examples are self-contained, building and running
them does not require special external libraries. In particular, no
Dune installation is necessary. However, in order to exactly reproduce
the numbers in the test, specific compilers and compiler versions are
needed, because the code mainly compares the abilities of different
compiler optimizers. For the results in the text we used
* g++ (c++ compiler of the GNU compiler collection, version 4.9.2)
* clang++ (c++ compiler of the clang compiler suite, version 3.6)
While the presented tests were run with the given compiler versions,
we expect to get comparable results with newer ones.
The script generating the presented plots additionally requires
a python interpreter and the python libraries numpy and matplotlib.
### Building and running the example programs
To build and run the example programs you have to call
./run.sh
This will build the example programs, execute them, and
store the results in the newly generated directories
build_gcc, build_gcc_pgo, and build_clang.
### Generating the plots
After the examples have been built and executed, calling
./generate_plots.sh
in the same directory will generate the plots presented
in the paper.
## Full dune-functions library
Additionally to the example programs used for the paper the
full dune-functions library based on the concepts described
in the paper is also available as a dune-module. This module
requires preview versions of the upcoming 3.0 release of the
dune core modules and the dune-typetree module. These modules,
as well as dune-functions itself, can be obtained using git via
git clone https://gitlab.dune-project.org/core/dune-common.git
git clone https://gitlab.dune-project.org/core/dune-istl.git
git clone https://gitlab.dune-project.org/core/dune-geometry.git
git clone https://gitlab.dune-project.org/core/dune-localfunctions.git
git clone https://gitlab.dune-project.org/core/dune-grid.git
git clone https://gitlab.dune-project.org/staging/dune-functions.git
git clone https://gitlab.dune-project.org/pdelab/dune-typetree.git
The desired versions can be obtained via
cd dune-common ; git checkout 834b14c044 ; cd ..
cd dune-istl ; git checkout b0efdba0e6 ; cd ..
cd dune-geometry ; git checkout 2334a10bdb ; cd ..
cd dune-localfunctions ; git checkout d6ea557cb5 ; cd ..
cd dune-grid ; git checkout a1aa47aac3 ; cd ..
cd dune-typetree ; git checkout 78104bb969 ; cd ..
cd dune-functions ; git checkout aa9ed7a094 ; cd ..
To use those libraries in other dune projects, they can be
configured and build using
./dune-common/bin/dunecontrol --builddir=$PWD/build all
Note that dune-functions does not introduce any dependencies on third
party software beyond what is already required by the Dune core modules.
################################################################################
echo "Generating plots for gcc"
cd build_gcc
python ../plot.py
cp timings.pgf ../timings_gcc.pgf
cd ..
################################################################################
echo "Generating plots for gcc pgo"
cd build_gcc_pgo
python ../plot.py
cp timings.pgf ../timings_gcc_pgo.pgf
cd ..
################################################################################
echo "Generating plots for clang"
cd build_clang
python ../plot.py
cp timings.pgf ../timings_clang.pgf
cd ..
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
//
// Copyright (c) 2015, Carsten Gräser
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <memory>
#include <iostream>
#include <iomanip>
#include <array>
#include <chrono>
#include <functional>
template<class K, std::size_t N>
class StaticVector : public std::array<K, N>
{
public:
StaticVector()
{
auto& self = *this;
for (std::size_t i=0; i<N; ++i)
self[i] = 0;
}
StaticVector(const K& k)
{
auto& self = *this;
for (std::size_t i=0; i<N; ++i)
self[i] = k;
}
void axpy(const K& k, const StaticVector& other)
{
auto& self = *this;
for (std::size_t i=0; i<N; ++i)
self[i] += k*other[i];
}
void operator*=(const K& k)
{
auto& self = *this;
for (std::size_t i=0; i<N; ++i)
self[i] *= k;
}
};
template <class K, std::size_t N>
inline std::ostream& operator<< (std::ostream& s, const StaticVector<K,N>& v)
{
s << "[";
for (std::size_t i=0; i<N-1; i++)
s << v[i] << ",";
s << v[N-1] << "]";
return s;
}
template<class Domain, class Range, class F>
Range integrateOverInterval(const F& f, Domain a, Domain b, int n)
{
Domain h = (b-a)/n;
Range result = 0.0;
std::array<std::pair<double,double>,1> quadRule = {{ {0.5, 1} }};
Range localResult = 0.0;
for (std::size_t i=0; i<n; ++i)
{
for (auto&& quadPoint : quadRule)
// localResult.axpy(quadPoint.second, f(a + (i+quadPoint.first)*h));
result.axpy(quadPoint.second, f(a + (i+quadPoint.first)*h));
// result.axpy(h, localResult);
}
result *= h;
return result;
}
template<class Domain, class Range, class F>
Range integrateOverInterval_Evaluate(const F& f, Domain a, Domain b, int n)
{
Domain h = (b-a)/n;
Range result = 0.0;
std::array<std::pair<double,double>,1> quadRule = {{ {0.5, 1} }};
Range temp;
Range localResult = 0.0;
for (std::size_t i=0; i<n; ++i)
{
for (auto&& quadPoint : quadRule)
{
f.evaluate(a + (i+quadPoint.first)*h, temp);
// localResult.axpy(quadPoint.second, temp);
result.axpy(quadPoint.second, temp);
}
// result.axpy(h, localResult);
}
result *= h;
return result;
}
class Timer
{
using TimeStamp = decltype(std::chrono::high_resolution_clock::now());
TimeStamp start_;
public:
Timer () :
start_(std::chrono::high_resolution_clock::now())
{}
double msElapsed() const
{
std::chrono::duration<double, std::milli> elapsed
= std::chrono::high_resolution_clock::now()-start_;
return elapsed.count();
}
};
template<class D, class R>
class VirtualFunction
{
public:
using Domain = D;
using Range = R;
virtual void evaluate(const Domain&, Range&) const = 0;
};
template<class D, class R>
class Function
{
public:
using Domain = D;
using Range = R;
};
template<class Base>
class F : public Base
{
public:
using Range = typename Base::Range;
using Domain = typename Base::Domain;
void imp(const Domain& x, Range& y) const
{
for(std::size_t i=0; i<y.size(); ++i)
{
// y[i] = x*x;
y[i] = x+i;
// y[i] = x*x + i;
}
}
void evaluate(const Domain& x, Range& y) const
{
imp(x,y);
}
Range operator()(const Domain& x) const
{
Range y;
imp(x, y);
return y;
}
};
template<std::size_t blockSize>
void testWithVectorSize(std::size_t n)
{
double a = 0;
double b = 1;
using Range = StaticVector<double,blockSize>;
using Domain = double;
std::array<double, 4> timing;
std::array<Range, 4> result;
std::size_t N = n/blockSize;
// For each test do one warump run with N-1 before.
{
using Interface = Function<Domain, Range>;
auto f = F<Interface>();
for (int k=N-1; k<=N; ++k)
{
Timer t;
result[0] = integrateOverInterval<Domain, Range>(f, a, b, k);
timing[0] = t.msElapsed();
}
}
{
using Interface = Function<Domain, Range>;
auto f = F<Interface>();
for (int k=N-1; k<=N; ++k)
{
Timer t;
result[1] = integrateOverInterval_Evaluate<Domain, Range>(f, a, b, k);
timing[1] = t.msElapsed();
}
}
{
using Interface = Function<Domain, Range>;
auto f = F<Interface>();
for (int k=N-1; k<=N; ++k)
{
Timer t;
result[2] = integrateOverInterval<Domain, Range>(std::function<Range(Domain)>(f), a, b, k);
timing[2] = t.msElapsed();
}
}
{
using Interface = VirtualFunction<Domain, Range>;
std::shared_ptr<Interface> f = std::make_shared<F<Interface>>();
Interface& fBase = *f;
for (int k=N-1; k<=N; ++k)
{
Timer t;
result[3] = integrateOverInterval_Evaluate<Domain, Range, Interface>(fBase, a, b, k);
timing[3] = t.msElapsed();
}
}
std::cout << std::setw(3) << blockSize << " ";
for(int i=0; i<4; ++i)
std::cout << std::setw(14) << (int)(timing[i]);
for(int i=1; i<4; ++i)
if (result[0]!=result[i])
std::cout << " error";
std::cout << std::endl;
}
int main(int argc, char** argv)
{
std::size_t n = 100000000;
std::cout << "size operator() evaluate() std::function v evaluate()" << std::endl;
testWithVectorSize<1>(n);
testWithVectorSize<2>(n);
testWithVectorSize<3>(n);
testWithVectorSize<4>(n);
testWithVectorSize<5>(n);
testWithVectorSize<6>(n);
testWithVectorSize<7>(n);
testWithVectorSize<8>(n);
testWithVectorSize<9>(n);
testWithVectorSize<10>(n);
testWithVectorSize<11>(n);
testWithVectorSize<12>(n);
testWithVectorSize<13>(n);
testWithVectorSize<14>(n);
testWithVectorSize<15>(n);
testWithVectorSize<16>(n);
return 0;
}
This diff is collapsed.
This diff is collapsed.
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