A: That depends on your code. The short answer: if your code is a custom simulation or an iterative algorithm, then the answer is most likely yes.
The long answer is that LibGeoDecomp focuses on stencil codes: space- and time-discrete simulations in which the simulation space is decomposed according to a regular grid and time is split into discrete global time steps. Nevertheless, it has limited support for irregular spatial decompositions, too.
A: Please see our issue tracker on Bitbucket.
A: Take a look at the unit tests! Tests
src/foo/xy.h are commonly found
src/foo/test/unit/xytest.h. If the class uses
parallelism, e.g. MPI, then look
Comments in our source are not few because we're lazy, but because we've -- quite painfully -- learned that the only thing worse than undocumented code is code whose documentation doesn't match it's internal workings. Given the fact that, over the course of the years, most parts of the library have been rewritten multiple times, I estimate the likelihood of the source and its documentation diverging at about 1.0.
Instead our comments focus on explaining why some part of the code is not written in a straightforward manner -- while our code strives to be self-explaining: speaking names, short methods, etc. The tests document how a class' interface is meant to be used and how the code works.
A: Common pitfall! Maybe. Maybe not. There are however two common fallacies which you might want to check first. My experience is that most codes fall victim to the one or the other. Don't worry though, they're easily fixed.
Initializer, the main function to implement is
grid(GridBase. Some folks will then go ahead and only initialize those cells which are of interest to them (e.g. in an implementation of Conway's Game of Life they might set only a couple of cells which are marked as
gridare freshly initialized by their default constructor. But in other cases it'll break: if you call
Simulatortwice, it will re-initialize it's grid with the help of the
Initializer. But if that one doesn't flush all the cells bad things will happen. The reason why we don't re-initialize all cells by default is simple: performance. Some codes would suffer by this. Solution:
gridhas a member
boundingBox(). This will yield you a
CoordBoxobject which you can use to traverse all coordinates of to-be-initialized cells. Please visit this code for an example of proper initialization.
thisis currently pointing) if you have already written those members in the current iterations. For similar reasons to the point above, we do not copy old values to the new grid by default: it's slow and in fact most applications can do without. Solution:You should rather read the members of the last time step's cells, which can be accessed through the neighborhood object, and only read those members from
this, which have already been written by the current invocation of
update(). The 3D Jacobi code in our repo demonstrates that a default copy from the last time step is in deed not required, as it will overwrite its only data member in any case. If everything else fails:
*this = hood[Coordmight help.
A: LibGeoDecomp is a project of the Ste||ar Group, a joint initiative of researchers with scalable computing solutions. Main development is done at the Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU), Germany. Project lead is Andreas Schäfer. We try to keep a current list of team members here.
A: It is a popular conception to view software as a stack of layers, where each layer functions by interacting with its surrounding layers -- and in turn adds overhead. LibGeoDecomp could be viewed as such a layer, which sits between the user's model and the runtime (e.g. MPI and/or CUDA). The assumption that this automatically adds overhead is wrong though. First of all, most of the integration of the model with the library happens at compile time, so no method call overheads or similar remain. Secondly, LibGeoDecomp's functionality is beyond simply wrapping certain interfaces and data structures. By inversion of control it is able to transform algorithms and data structures to achieve an optimal match between hard- and software. In most cases the result will be a code with a better performance than a native, but baseline manual implementation. See our publications for measurements.
A: Yes, stencil codes are not a new topic. But that is the point, really. There are a lot of papers out there which follow the pattern We took stencil code FOO and did implement it with record breaking performance on architecture BAR, where FOO mostly refers to Jacobi or LBM while BAR will most likely be a GPU, or a large scale multi-core cluster. People write temporal and spatial blocking code, domain decompositions, parallel IO... they do this again and again. And why? Because there are currently few options for reusing implementations. This is why we believe that the time for a generic solution has come.
Besides: LibGeoDecomp is no longer just a stencil code library: we can do particle-in-cell, meshfree, n-body...
A: There surely are a number of packages which appear at a first glance to provide a similar functionality. Some are DSLs, some are libraries. But then again, we believe LibGeoDecomp has some key advantages. Please look here for a short review of how it relates to the competition. Here is a list of similar packages:
A: Yes and no. While the
code may be considered an embedded DSL (embedded into
C++), the main part of the library is really a library with a
2-way callback. In a way it's similar to Qt. Qt handles the
event loop and will call back your code when it's appropriate.
So does LibGeoDecomp. Only that we don't do GUIs, but
simulations. Our callback works like this: you start a
simulation by calling
object. The Simulator will then call back your model
update() in your cell class). Your cell may then
in turn call back the library via a so-called neighborhood
object. The neighborhood object really is a proxy object by
which user code may get access to neighboring cells of the
last time step. For more details take a look at the
So much for the callback. The reasons why we don't use a full DSL with an external compiler are simple:
A: It is hard to predict the future, so I won't try. LibGeoDecomp has been around since 2006, which makes it older than CUDA (2007) and the latest release of PVM (2009, does anyone even remember PVM?) and only slightly younger than the first Intel dual core processor (Paxville DP, 2005). Today LibGeoDecomp is standing stronger than ever, so we have no reason to abandon it. Even if we would: its code is well hackable and maintainable, its license is a permissive, liberal open source license. Others could take over, if need be.
A: A common question is this: How hard is it for a third party developer to add features to LibGeoDecomp? There is probably no globally accepted metric for how well extendable a code is, so let me just list a couple of facts:
A: This depends on which of the libraries features you wish to use. Most dependencies are optional. For a basic build you'll only need:
Additionally you may wish to provide:
If you don't just want to use the library, but also to modify it, then the build system may want to auto-regenerate LibGeoDecomp's internal MPI datatypes. This requires:
Some of the examples come with a Qt GUI and may a camera for input. For those you will need:
A: LibGeoDecomp is written in standard C++ so it should work out of the box with all C++ compilers. But because the world is big and bad (and so is the C++ standard) things are not that easy. We test LibGeoDecomp regularly with the following compilers:
A: Theoretically LibGeoDecomp shouldn't be picky regarding the version of a given package. However, here is a list of versions that we regularly test for compatibility.
|Package||Minimum Version||Tested Versions|
|CMake||2.6.4||2.6.4, 2.8.2, 2.8.5, 2.8.8, 2.8.9, 2.8.11, 3.0.2|
|CUDA||4.0||5.5.22, 6.0.37, 6.5.14, 7.0.18|
|Open MPI||1.4.2, 1.5.3, 1.5.5, 1.6.0, 1.6.5, 1.8.3|
|Intel MPI||4.0.1, 4.0.3|
|Boost||1.37, y1.44, 1.47, 1.48, 1.49, 1.53, 1.56|
|Qt||4.0||4.8.1, 4.8.2, 4.8.5, 4.8.6|
|OpenCV||2.3.1a, 2.4.5, 2.4.9|
A: With CMake you can select the C++ compiler
CMAKE_CXX_COMPILER. Additionally I'd suggest
you to set some compiler flags to tone down the warnings
caused by some Boost libraries:
cmake -DCMAKE_CXX_COMPILER=icpc -DADDITIONAL_COMPILE_FLAGS="-Wall -Wno-sign-compare -wd383 -wd981 -wd1418 ../.."
A: JUQUEEN is the IBM Blue Gene/Q at Forschungszentrum Jülich. At
the point of this writing, it is
European system. Building on JUQUEEN is slightly tricky,
as you'll want to use
xlc++, IBM's C++ compiler,
which still has troubles with templates. And pretty much
everything in LibGeoDecomp is a template. Also, no interactive
jobs are available on this machine, which means you can't run
the unit tests on your build machine.
module load boost module load cmake cmake -DUNITEXEC=echo -DMPIEXEC=echo -DCMAKE_C_COMPILER=xlc -DCMAKE_CXX_COMPILER=mpixlcxx -DADDITIONAL_COMPILE_FLAGS="-I/bgsys/local/boost/1.47.0" -DBoost_NO_BOOST_CMAKE=true -DBOOST_INCLUDEDIR="/bgsys/local/boost/1.47.0" -DLIB_LINKAGE_TYPE=STATIC -DWITH_QT=false ../../
A: You can't pull external HG repositories on SuperMUC and there
is no build of Boost for the PGI and Intel compilers. You'll
thus have to
scp your checkout of LibGeoDecomp to
one of the login nodes. And I suggest using GCC for
compilation. In essence, the default build flags are
absolutely fine for this machine:
module load cmake module load boost/1.47_gcc cd libgeodecomp/ BUILD_DIR=build/`uname -ms | sed s/\ /-/g` mkdir -p $BUILD_DIR cd $BUILD_DIR cmake ../../ make -j10
A: LibGeoDecomp will build on Tsubame almost out of the box. Since firewall rules are strict, you may not be able to directly clone our BitBucket/GitHub repository, but will rather have to copy it over from another machine.
cd libgeodecomp/ BUILD_DIR=build/`uname -ms | sed s/\ /-/g` mkdir -p $BUILD_DIR cd $BUILD_DIR cmake -DWITH_BOOST_ASIO=false -DWITH_BOOST_MPI=false -DWITH_TYPEMAPS=false ../../ make -j10 make check
Here is how to build with GCC:
# fixme: drop this module load PrgEnv-gnu module load cmake module load boost cd libgeodecomp/ BUILD_DIR=build/`uname -ms | sed s/\ /-/g` mkdir -p $BUILD_DIR cd $BUILD_DIR cmake -DWITH_QT=false -DMPIEXEC=/bin/echo -DWITH_TYPEMAPS=false -DLIB_LINKAGE_TYPE=STATIC -DBoost_USE_STATIC_LIBS=true ../../ make -j10
Minor changes for Intel's compiler ICPC:
module load PrgEnv-intel module load cmake module load boost cd libgeodecomp/ BUILD_DIR=build/`uname -ms | sed s/\ /-/g` mkdir -p $BUILD_DIR cd $BUILD_DIR cmake -DWITH_QT=false -DMPIEXEC=/bin/echo -DWITH_TYPEMAPS=false -DLIB_LINKAGE_TYPE=STATIC -DBoost_USE_STATIC_LIBS=true ../../ make -j10
A: If you've installed Boost in a non-standard location (e.g.
your home), then you can always set
BOOST_ROOT. This is how we build on Tsubame 2.0:
cmake -DBOOST_ROOT=/home/usr5/A2401222/boost_1_50_0/ -DCMAKE_CXX_COMPILER=icpc -DADDITIONAL_COMPILE_FLAGS="-Wall -Wno-sign-compare -wd383 -wd981 -wd1418" ../../
A: Easy: send us your CMake
output and make output! Which system (hardware vendor,
operating system) are you trying to build on?
CMake should do the right thing to discover
your environment. But given the variety of target platforms, I
wouldn't wonder if it fails on some systems. We'll be happy to
fix that! Below is a script which captures the relevant output
in the files
Run it from your build directory.
cmake ../.. 2>&1 | tee cmake.log make 2>&1 | tee make.log
A: Under certain conditions the value of a build variable and
CMake's argument parsing may interfere. In this case you
:STRING to the definition. Here you
see how to set a certain machine architecture, handy if you're
building on a 64-bit capable machine whose toolchain defaults
to building 32-bit code.
cmake -DADDITIONAL_COMPILE_FLAGS:STRING="-march=core2 -m64" ../../
A: LibGeoDecomp makes heavy use of C++ class templates, so making it work with Fortran might not appear to be straightforward. Indeed it takes some thinking, but in the end it's not really complicated. Here is a quick example.
A: Quite simple, really: you call us, we call you, you call us. A bit more verbose:
Simulatorobject with your simulation model as a template parameter. The model describes the data a single grid cell holds and the computations it performs in each time step.
Initializerto set up initial conditions,
Writersfor output, and optionally
Steerersfor modifying the simulation at runtime) have been added, you call
Simulatorwill then call back your code's
update(): once for each cell and timestep.
update()to retrieve the state of your cell and the neighboring cells in the last time step.
More details can be found in the examples. I highly recommend to take a look at the implementations of Jacobi and Game of Life.