├── scripts ├── dependencies │ ├── patches │ │ └── .gitkeep │ ├── package_bison.sh │ ├── package_flex.sh │ ├── package_zlib.sh │ ├── package_autoconf.sh │ ├── package_ccache.sh │ ├── package_valgrind.sh │ ├── package_cmake.sh │ ├── package_python.sh │ ├── package_python3.sh │ ├── package_automake.sh │ ├── package_ruby.sh │ ├── package_libtool.sh │ ├── package_binutils.sh │ ├── package_gmp.sh │ ├── package_mpfr.sh │ ├── third_party_linker │ ├── package_mpc.sh │ ├── package_boost.sh │ ├── package_gcc.sh │ ├── defaults.sh │ ├── installer │ └── README.md ├── demo │ ├── color_ramp.png │ ├── demo_logo.png │ ├── demo_logo_small.png │ ├── demo_logo_smaller.png │ ├── mtl_generator.rb │ └── blender_load.py ├── setup │ ├── empty.h.tpl │ ├── empty.cpp.tpl │ ├── example │ │ ├── answer.h.tpl │ │ ├── answer_test.cc.tpl │ │ ├── main.cxx.tpl │ │ └── answer.cpp.tpl │ ├── empty_test.cc.tpl │ ├── CMakeLists_root.txt │ ├── CMakeLists_module.txt.tpl │ ├── CMakeLists.txt.tpl │ ├── run │ ├── add_part │ └── README.md.tpl ├── license │ ├── install_git_hook │ ├── header.txt │ ├── update_sources │ ├── pre-commit-hook │ └── licensor ├── ci │ ├── job_allscale_api │ ├── run_coverage │ ├── run_sloccount │ ├── build │ ├── job_allscale_api_coverage │ ├── run_unit_tests │ ├── clean_cmake │ ├── build_coverage │ ├── configure │ └── defaults.sh └── coverage │ ├── lcov │ └── get_version.sh │ └── create ├── createRelease.sh ├── .gitignore ├── createClang.sh ├── cmake ├── dependencies │ ├── pthread.cmake │ ├── valgrind.cmake │ ├── boost.cmake │ └── googletest.cmake ├── nproc.cmake ├── coverage.cmake ├── doxygen.cmake ├── file_globs.cmake ├── msvc_source_group.cmake ├── FindValgrind.cmake ├── msvc_settings.cmake └── build_settings.cmake ├── createDebug.sh ├── code ├── utils │ ├── include │ │ └── allscale │ │ │ └── utils │ │ │ ├── string_utils.h │ │ │ ├── printer │ │ │ ├── pairs.h │ │ │ ├── arrays.h │ │ │ ├── vectors.h │ │ │ ├── set.h │ │ │ └── join.h │ │ │ ├── unused.h │ │ │ ├── serializer │ │ │ ├── strings.h │ │ │ ├── optionals.h │ │ │ ├── pairs.h │ │ │ ├── maps.h │ │ │ ├── unordered_maps.h │ │ │ ├── tuple.h │ │ │ ├── arrays.h │ │ │ └── vectors.h │ │ │ ├── finalize.h │ │ │ ├── io_utils.h │ │ │ ├── array_utils.h │ │ │ ├── bitmanipulation.h │ │ │ ├── raw_buffer.h │ │ │ ├── concepts.h │ │ │ ├── type_list.h │ │ │ ├── range.h │ │ │ ├── vector_utils.h │ │ │ ├── static_map.h │ │ │ ├── bag.h │ │ │ ├── optional.h │ │ │ └── tuple_utils.h │ ├── CMakeLists.txt │ └── test │ │ ├── serializer │ │ ├── strings.cc │ │ ├── optionals.cc │ │ ├── vectors.cc │ │ ├── maps.cc │ │ └── pairs.cc │ │ ├── tuple_utils.cc │ │ ├── finalize.cc │ │ ├── array_utils.cc │ │ ├── raw_buffer.cc │ │ ├── range.cc │ │ ├── static_map.cc │ │ ├── optional.cc │ │ ├── type_list.cc │ │ ├── bag.cc │ │ └── table.cc ├── api │ ├── CMakeLists.txt │ ├── test │ │ ├── core │ │ │ ├── treeture.cc │ │ │ ├── data.cc │ │ │ └── impl │ │ │ │ ├── reference │ │ │ │ ├── lock.cc │ │ │ │ ├── runtime_predictor.cc │ │ │ │ └── task_id.cc │ │ │ │ └── sequential │ │ │ │ └── treeture.cc │ │ └── user │ │ │ ├── save_to_binary_test.cc │ │ │ ├── arithmetic.cc │ │ │ ├── data │ │ │ ├── bar_mesh.inl │ │ │ └── map.cc │ │ │ └── algorithm │ │ │ ├── async.cc │ │ │ └── internal │ │ │ └── operator_reference.cc │ └── include │ │ └── allscale │ │ └── api │ │ └── user │ │ ├── arithmetic.h │ │ ├── algorithm │ │ ├── async.h │ │ └── internal │ │ │ └── operation_reference.h │ │ └── save_to_binary.h ├── tutorials │ ├── src │ │ ├── prec │ │ │ ├── 00_fibonacci_c_style.cxx │ │ │ ├── 01_fibonacci_prec.cxx │ │ │ ├── 02_nqueens_c_style.cxx │ │ │ └── 03_nqueens_prec.cxx │ │ ├── adaptivegrid │ │ │ ├── animate.rb │ │ │ ├── plot.rb │ │ │ └── wave_log.h │ │ ├── matrix_multiplication │ │ │ ├── 01_basic.cxx │ │ │ ├── 02_data_structure.cxx │ │ │ ├── 03_pfor_simple.cxx │ │ │ ├── 04_pfor_collapsed.cxx │ │ │ └── 00_c_style.cxx │ │ ├── mesh │ │ │ └── 01_demo_mesh_utils.h │ │ ├── heat_stencil │ │ │ ├── 01_basic.cxx │ │ │ ├── 02_data_structure.cxx │ │ │ ├── 03_pfor.cxx │ │ │ ├── 04_pfor_collapsed.cxx │ │ │ ├── 00_c_style.cxx │ │ │ ├── 06_stencil.cxx │ │ │ └── 05_pfor_overlap.cxx │ │ └── io │ │ │ └── 00_io.cxx │ └── CMakeLists.txt └── CMakeLists.txt ├── CMakeLists.txt ├── .clang-format └── README.md /scripts/dependencies/patches/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /createRelease.sh: -------------------------------------------------------------------------------- 1 | CC=gcc-5 CXX=g++-5 cmake -D CMAKE_BUILD_TYPE=Release ../code 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build*/ 2 | third_party/ 3 | 4 | # Editor Specific 5 | *.swp 6 | *~ 7 | .\#* 8 | -------------------------------------------------------------------------------- /createClang.sh: -------------------------------------------------------------------------------- 1 | CC=clang-3.6 CXX=clang++-3.6 cmake -D CMAKE_BUILD_TYPE=Release ../code 2 | -------------------------------------------------------------------------------- /cmake/dependencies/pthread.cmake: -------------------------------------------------------------------------------- 1 | set(THEADS_PREFER_PTHEAD_FLAG on) 2 | find_package(Threads REQUIRED) 3 | -------------------------------------------------------------------------------- /createDebug.sh: -------------------------------------------------------------------------------- 1 | CC=gcc-5 CXX=g++-5 cmake -G "Eclipse CDT4 - Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug ../code 2 | -------------------------------------------------------------------------------- /scripts/demo/color_ramp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allscale/allscale_api/HEAD/scripts/demo/color_ramp.png -------------------------------------------------------------------------------- /scripts/demo/demo_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allscale/allscale_api/HEAD/scripts/demo/demo_logo.png -------------------------------------------------------------------------------- /scripts/demo/demo_logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allscale/allscale_api/HEAD/scripts/demo/demo_logo_small.png -------------------------------------------------------------------------------- /scripts/demo/demo_logo_smaller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allscale/allscale_api/HEAD/scripts/demo/demo_logo_smaller.png -------------------------------------------------------------------------------- /cmake/nproc.cmake: -------------------------------------------------------------------------------- 1 | include(ProcessorCount) 2 | 3 | ProcessorCount(NPROC) 4 | if(NOT NPROC) 5 | set(NPROC 8) 6 | endif() 7 | 8 | math(EXPR NPROC_HALF "${NPROC} / 2") 9 | -------------------------------------------------------------------------------- /scripts/setup/empty.h.tpl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace %PROJECT% { 4 | namespace %MODULE% { 5 | %NAMESPACES% 6 | } // end namespace %MODULE% 7 | } // end namespace %PROJECT% 8 | -------------------------------------------------------------------------------- /cmake/coverage.cmake: -------------------------------------------------------------------------------- 1 | if(BUILD_COVERAGE) 2 | add_custom_target(coverage 3 | COMMAND ${PROJECT_SOURCE_DIR}/../scripts/coverage/create 4 | ${PROJECT_BINARY_DIR} 5 | ) 6 | endif() 7 | -------------------------------------------------------------------------------- /scripts/license/install_git_hook: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 4 | 5 | ln -s "../../scripts/license/pre-commit-hook" "$DIR/../../.git/hooks/pre-commit" 6 | -------------------------------------------------------------------------------- /scripts/setup/empty.cpp.tpl: -------------------------------------------------------------------------------- 1 | #include "%PROJECT%/%MODULE%/%PART%.h" 2 | 3 | namespace %PROJECT% { 4 | namespace %MODULE% { 5 | %NAMESPACES% 6 | } // end namespace %MODULE% 7 | } // end namespace %PROJECT% 8 | -------------------------------------------------------------------------------- /scripts/setup/example/answer.h.tpl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace %PROJECT% { 4 | namespace %MODULE% { 5 | 6 | int answer(); 7 | 8 | } // end namespace %MODULE% 9 | } // end namespace %PROJECT% 10 | -------------------------------------------------------------------------------- /scripts/license/header.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2002-20XX Distributed and Parallel Systems Group, 3 | * Institute of Computer Science, 4 | * University of Innsbruck, Austria 5 | */ 6 | 7 | -------------------------------------------------------------------------------- /scripts/license/update_sources: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 4 | 5 | find "$DIR/../../code" -regex ".*\.\(h\|hpp\|def\|inc\|c\|cpp\|cxx\|cc\)" -exec "$DIR/licensor" "$DIR/header.txt" {} \; 6 | -------------------------------------------------------------------------------- /scripts/setup/example/answer_test.cc.tpl: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "%PROJECT%/%MODULE%/answer.h" 4 | 5 | using namespace %PROJECT%::%MODULE%; 6 | 7 | TEST(AnswerTest, Basic) { 8 | ASSERT_EQ(42, answer()); 9 | } 10 | -------------------------------------------------------------------------------- /scripts/setup/empty_test.cc.tpl: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "%PROJECT%/%MODULE%/%PART%.h" 4 | 5 | using namespace %PROJECT%::%MODULE%::%NAMESPACES%; 6 | 7 | TEST(%PART_NAME%Test, Basic) { 8 | ASSERT_EQ(2, 1 + 1); 9 | } 10 | -------------------------------------------------------------------------------- /cmake/dependencies/valgrind.cmake: -------------------------------------------------------------------------------- 1 | if(USE_VALGRIND) 2 | find_package(Valgrind REQUIRED) 3 | 4 | set(Valgrind_FLAGS 5 | --leak-check=full 6 | --show-reachable=no 7 | --track-fds=yes 8 | --error-exitcode=1 9 | --track-origins=no 10 | ) 11 | endif() 12 | -------------------------------------------------------------------------------- /scripts/dependencies/package_bison.sh: -------------------------------------------------------------------------------- 1 | NAME="bison" 2 | VERSION="3.0.4" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="$PACKAGE.tar.gz" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="b67fd2daae7a64b5ba862c66c07c1addb9e6b1b05c5f2049392cfd8a2172952e" 8 | -------------------------------------------------------------------------------- /scripts/dependencies/package_flex.sh: -------------------------------------------------------------------------------- 1 | NAME="flex" 2 | VERSION="2.5.39" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="$PACKAGE.tar.gz" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="71dd1b58158c935027104c830c019e48c73250708af5def45ea256c789318948" 8 | -------------------------------------------------------------------------------- /scripts/dependencies/package_zlib.sh: -------------------------------------------------------------------------------- 1 | NAME="zlib" 2 | VERSION="1.2.8" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="$PACKAGE.tar.xz" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="831df043236df8e9a7667b9e3bb37e1fcb1220a0f163b6de2626774b9590d057" 8 | -------------------------------------------------------------------------------- /scripts/dependencies/package_autoconf.sh: -------------------------------------------------------------------------------- 1 | NAME="autoconf" 2 | VERSION="2.68" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="$PACKAGE.tar.xz" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="c994778716e6223cf65e898e06c15ed498fe81424838adf67007282b661055ba" 8 | -------------------------------------------------------------------------------- /scripts/dependencies/package_ccache.sh: -------------------------------------------------------------------------------- 1 | NAME="ccache" 2 | VERSION="3.2.5" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="$PACKAGE.tar.bz2" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="7a553809e90faf9de3a23ee9c5b5f786cfd4836bf502744bedb824a24bee1097" 8 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/string_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | template 8 | std::string toString(const T& value) { 9 | std::stringstream res; 10 | res << value; 11 | return res.str(); 12 | } 13 | -------------------------------------------------------------------------------- /scripts/setup/example/main.cxx.tpl: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "%PROJECT%/%MODULE%/answer.h" 5 | 6 | using namespace %PROJECT%::%MODULE%; 7 | 8 | int main() { 9 | std::cout << "The answer is " << answer() << std::endl; 10 | return EXIT_SUCCESS; 11 | } 12 | -------------------------------------------------------------------------------- /scripts/ci/job_allscale_api: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 6 | 7 | source defaults.sh 8 | 9 | nice -n $NICE_LEVEL ./configure 10 | nice -n $NICE_LEVEL ./clean_cmake 11 | nice -n $NICE_LEVEL ./build 12 | nice -n $NICE_LEVEL ./run_unit_tests 13 | -------------------------------------------------------------------------------- /scripts/ci/run_coverage: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | if [[ -z "${WORKSPACE+x}" ]]; then 6 | cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 7 | source defaults.sh 8 | fi 9 | 10 | cd "$BUILD_DIR" 11 | 12 | # Adjust resource restriction. 13 | ulimit -t 14400 14 | 15 | make coverage ARGS="-j $NPROC" 16 | -------------------------------------------------------------------------------- /cmake/dependencies/boost.cmake: -------------------------------------------------------------------------------- 1 | set(BOOST_VERSION 1.59.0 CACHE STRING "Boost Version") 2 | 3 | find_package(Boost ${BOOST_VERSION} EXACT REQUIRED COMPONENTS filesystem system) 4 | 5 | if(MSVC) 6 | set(Boost_USE_STATIC_LIBS OFF) 7 | set(Boost_USE_DEBUG_RUNTIME ON) 8 | set(Boost_USE_MULTITHREADED ON) 9 | endif() 10 | -------------------------------------------------------------------------------- /scripts/ci/run_sloccount: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | if [[ -z "${WORKSPACE+x}" ]]; then 6 | cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 7 | source defaults.sh 8 | fi 9 | 10 | cd "$BUILD_DIR" 11 | 12 | rm -f sloccount.sc 13 | sloccount --duplicates --wide --details -- code/ extra/ > sloccount.sc 14 | -------------------------------------------------------------------------------- /code/utils/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_module_library(utils HEADER_ONLY) 2 | 3 | glob_executables(utils_exes src) 4 | foreach(exe ${utils_exes}) 5 | add_module_executable(utils ${exe}) 6 | endforeach(exe) 7 | 8 | glob_tests(utils_tests test) 9 | foreach(test ${utils_tests}) 10 | add_module_unittest(utils ${test}) 11 | endforeach(test) 12 | -------------------------------------------------------------------------------- /scripts/setup/example/answer.cpp.tpl: -------------------------------------------------------------------------------- 1 | #include "%PROJECT%/%MODULE%/answer.h" 2 | 3 | #include 4 | 5 | namespace %PROJECT% { 6 | namespace %MODULE% { 7 | 8 | int answer() { 9 | boost::optional oi(42); 10 | return *oi; 11 | } 12 | 13 | } // end namespace %MODULE% 14 | } // end namespace %PROJECT% 15 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/printer/pairs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace std { 7 | 8 | template 9 | ostream& operator<<(ostream& out, const pair& data) { 10 | return out << "[" << data.first << "," << data.second << "]"; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /scripts/dependencies/package_valgrind.sh: -------------------------------------------------------------------------------- 1 | NAME="valgrind" 2 | VERSION="3.11.0" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="$PACKAGE.tar.bz2" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="6c396271a8c1ddd5a6fb9abe714ea1e8a86fce85b30ab26b4266aeb4c2413b42" 8 | 9 | export CFLAGS="-O3 -fPIC" 10 | export LDFLAGS="-O3 -fPIC" 11 | -------------------------------------------------------------------------------- /scripts/ci/build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | if [[ -z "${WORKSPACE+x}" ]]; then 6 | cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 7 | source defaults.sh 8 | fi 9 | 10 | cd "$BUILD_DIR" 11 | 12 | cmake "$WORKSPACE/code" \ 13 | -DCMAKE_BUILD_TYPE="$BUILD_TYPE" \ 14 | -DCMAKE_CXX_FLAGS="-Werror" 15 | 16 | make -j "$NPROC" all tutorials 17 | -------------------------------------------------------------------------------- /scripts/ci/job_allscale_api_coverage: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 6 | 7 | source defaults.sh 8 | 9 | nice -n $NICE_LEVEL ./configure 10 | nice -n $NICE_LEVEL ./clean_cmake 11 | nice -n $NICE_LEVEL ./build_coverage 12 | nice -n $NICE_LEVEL ./run_sloccount 13 | nice -n $NICE_LEVEL ./run_coverage 14 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/unused.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /** 4 | * This header defines a macro to mark knowingly unused variables as being 5 | * unused, so that the compiler is not issuing warnings about those. 6 | */ 7 | 8 | #ifdef __GNUC__ 9 | #define __allscale_unused __attribute__((unused)) 10 | #else 11 | #define __allscale_unused 12 | #endif 13 | -------------------------------------------------------------------------------- /scripts/ci/run_unit_tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | if [[ -z "${WORKSPACE+x}" ]]; then 6 | cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 7 | source defaults.sh 8 | fi 9 | 10 | cd "$BUILD_DIR" 11 | 12 | # Adjust resource restriction. 13 | ulimit -t 14400 14 | 15 | make test ARGS="-j $NPROC" 16 | 17 | make test_tutorials ARGS="-j $NPROC" 18 | -------------------------------------------------------------------------------- /scripts/dependencies/package_cmake.sh: -------------------------------------------------------------------------------- 1 | NAME="cmake" 2 | VERSION="3.5.1" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="$PACKAGE.tar.gz" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="93d651a754bcf6f0124669646391dd5774c0fc4d407c384e3ae76ef9a60477e8" 8 | 9 | pkg_configure() { 10 | LDFLAGS="-O3" ./configure --prefix="$PREFIX/$PACKAGE" 11 | } 12 | -------------------------------------------------------------------------------- /cmake/doxygen.cmake: -------------------------------------------------------------------------------- 1 | if(BUILD_DOCS) 2 | configure_file(${PROJECT_SOURCE_DIR}/../.doxygen ${PROJECT_BINARY_DIR}/Doxyfile @ONLY) 3 | 4 | find_package(Doxygen REQUIRED) 5 | add_custom_target( 6 | ${PROJECT_NAME}_doxygen 7 | ALL 8 | COMMAND ${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/Doxyfile 9 | SOURCES ${PROJECT_SOURCE_DIR}/../.doxygen 10 | ) 11 | endif() 12 | -------------------------------------------------------------------------------- /code/api/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_module_library(api HEADER_ONLY) 2 | 3 | target_link_libraries(api INTERFACE utils) 4 | 5 | glob_executables(api_exes src) 6 | foreach(exe ${api_exes}) 7 | add_module_executable(api ${exe}) 8 | endforeach(exe) 9 | 10 | glob_tests(api_tests test) 11 | foreach(test ${api_tests}) 12 | add_module_unittest(api ${test}) 13 | endforeach(test) 14 | -------------------------------------------------------------------------------- /scripts/ci/clean_cmake: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | if [[ -z "${WORKSPACE+x}" ]]; then 6 | cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 7 | source defaults.sh 8 | fi 9 | 10 | # Cleanup all CMake files to start a clean configuration. Object files are 11 | # *not* removed to improve compile time. 12 | rm -rf "$BUILD_DIR/CMake"* "$BUILD_DIR/"*".cmake" 13 | -------------------------------------------------------------------------------- /scripts/dependencies/package_python.sh: -------------------------------------------------------------------------------- 1 | NAME="python" 2 | VERSION="2.7.12" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="Python-$VERSION.tgz" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="3cb522d17463dfa69a155ab18cffa399b358c966c0363d6c8b5b3bf1384da4b6" 8 | 9 | pkg_extract() { 10 | tar xf "$FILE" 11 | mv "Python-$VERSION" "$PACKAGE" 12 | } 13 | -------------------------------------------------------------------------------- /scripts/dependencies/package_python3.sh: -------------------------------------------------------------------------------- 1 | NAME="python3" 2 | VERSION="3.5.2" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="Python-$VERSION.tgz" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="1524b840e42cf3b909e8f8df67c1724012c7dc7f9d076d4feef2d3eff031e8a0" 8 | 9 | pkg_extract() { 10 | tar xf "$FILE" 11 | mv "Python-$VERSION" "$PACKAGE" 12 | } 13 | -------------------------------------------------------------------------------- /scripts/ci/build_coverage: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | if [[ -z "${WORKSPACE+x}" ]]; then 6 | cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 7 | source defaults.sh 8 | fi 9 | 10 | cd "$BUILD_DIR" 11 | 12 | cmake "$WORKSPACE/code" \ 13 | -DCMAKE_BUILD_TYPE="$BUILD_TYPE" \ 14 | -DCMAKE_CXX_FLAGS="-Werror" \ 15 | -DBUILD_COVERAGE=ON 16 | 17 | make -j "$NPROC" 18 | -------------------------------------------------------------------------------- /scripts/dependencies/package_automake.sh: -------------------------------------------------------------------------------- 1 | NAME="automake" 2 | VERSION="1.15" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="$PACKAGE.tar.xz" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="9908c75aabd49d13661d6dcb1bc382252d22cc77bf733a2d55e87f2aa2db8636" 8 | 9 | DEPENDS="autoconf" 10 | 11 | export PATH="$PREFIX/$(get_property autoconf PACKAGE)/bin:$PATH" 12 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This CMakeLists.txt should only be run by ExternalProject 2 | 3 | cmake_minimum_required(VERSION 3.2) 4 | 5 | option(INVOKED_AS_EXTERNAL_PROJECT OFF) 6 | if(NOT INVOKED_AS_EXTERNAL_PROJECT) 7 | message(FATAL_ERROR "Root CMakeLists.txt only used for External Projects, call CMake on `code` folder instead.") 8 | endif() 9 | 10 | enable_testing() 11 | add_subdirectory(code) 12 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/printer/arrays.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "allscale/utils/printer/join.h" 7 | 8 | namespace std { 9 | 10 | template 11 | ostream& operator<<(ostream& out, const array& data) { 12 | return out << "[" << allscale::utils::join(",", data) << "]"; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/printer/vectors.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "allscale/utils/printer/join.h" 7 | 8 | namespace std { 9 | 10 | template 11 | ostream& operator<<(ostream& out, const vector& data) { 12 | return out << "[" << allscale::utils::join(",", data) << "]"; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /scripts/dependencies/package_ruby.sh: -------------------------------------------------------------------------------- 1 | NAME="ruby" 2 | VERSION="1.9.3-p125" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="$PACKAGE.tar.gz" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="8b3c035cf4f0ad6420f447d6a48e8817e5384d0504514939aeb156e251d44cce" 8 | 9 | pkg_configure() { 10 | ./configure --prefix="$PREFIX/$PACKAGE" --enable-shared --disable-install-doc 11 | } 12 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/printer/set.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "allscale/utils/printer/join.h" 7 | 8 | namespace std { 9 | 10 | template 11 | ostream& operator<<(ostream& out, const set& data) { 12 | return out << "{" << allscale::utils::join(",", data) << "}"; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /scripts/setup/CMakeLists_root.txt: -------------------------------------------------------------------------------- 1 | # This CMakeLists.txt should only be run by ExternalProject 2 | 3 | cmake_minimum_required(VERSION 3.5) 4 | 5 | option(INVOKED_AS_EXTERNAL_PROJECT OFF) 6 | if(NOT INVOKED_AS_EXTERNAL_PROJECT) 7 | message(FATAL_ERROR "Root CMakeLists.txt only used for External Projects, call CMake on `code` folder instead.") 8 | endif() 9 | 10 | enable_testing() 11 | add_subdirectory(code) 12 | -------------------------------------------------------------------------------- /code/tutorials/src/prec/00_fibonacci_c_style.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | long fibonacci(const unsigned int number) { 5 | if(number < 2) 6 | return number; 7 | return fibonacci(number - 1) + fibonacci(number - 2); 8 | } 9 | 10 | int main() { 11 | const int N = 12; 12 | 13 | long fib = fibonacci(N); 14 | 15 | std::cout << "fibonacci(" << N << ") = " << fib << std::endl; 16 | 17 | return EXIT_SUCCESS; 18 | } 19 | -------------------------------------------------------------------------------- /scripts/dependencies/package_libtool.sh: -------------------------------------------------------------------------------- 1 | NAME="libtool" 2 | VERSION="2.4.5" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="$PACKAGE.tar.xz" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="84aac136513b009278896ffa255e4d685bcdb0cb0e5363be36adad64c986177e" 8 | 9 | DEPENDS="autoconf automake" 10 | 11 | export PATH="$PREFIX/$(get_property autoconf PACKAGE)/bin:$PATH" 12 | export PATH="$PREFIX/$(get_property automake PACKAGE)/bin:$PATH" 13 | -------------------------------------------------------------------------------- /scripts/dependencies/package_binutils.sh: -------------------------------------------------------------------------------- 1 | NAME="binutils" 2 | VERSION="2.27" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="$PACKAGE.tar.gz" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="26253bf0f360ceeba1d9ab6965c57c6a48a01a8343382130d1ed47c468a3094f" 8 | 9 | DEPENDS="bison" 10 | 11 | export PATH="$PREFIX/$(get_property bison PACKAGE)/bin:$PATH" 12 | 13 | pkg_configure() { 14 | ./configure --prefix="$PREFIX/$PACKAGE" --enable-gold 15 | } 16 | -------------------------------------------------------------------------------- /scripts/demo/mtl_generator.rb: -------------------------------------------------------------------------------- 1 | 2 | 3 | require 'chunky_png' 4 | 5 | ramp = ChunkyPNG::Image.from_file('color_ramp.png') 6 | 7 | def r(p) 8 | ChunkyPNG::Color.r(p)/256.0 9 | end 10 | def g(p) 11 | ChunkyPNG::Color.g(p)/256.0 12 | end 13 | def b(p) 14 | ChunkyPNG::Color.b(p)/256.0 15 | end 16 | 17 | ramp.height.times do |y| 18 | px = ramp.pixels[y] 19 | puts "newmtl r#{ramp.height-y-1}" 20 | puts "Kd #{r(px)} #{g(px)} #{b(px)}" 21 | puts 22 | end -------------------------------------------------------------------------------- /scripts/dependencies/package_gmp.sh: -------------------------------------------------------------------------------- 1 | NAME="gmp" 2 | VERSION="6.0.0" 3 | SUBVERSION="a" 4 | PACKAGE="$NAME-$VERSION" 5 | 6 | FILE="$PACKAGE$SUBVERSION.tar.bz2" 7 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 8 | SHA256SUM="7f8e9a804b9c6d07164cf754207be838ece1219425d64e28cfa3e70d5c759aaf" 9 | 10 | unset CC CXX LD_LIBRARY_PATH 11 | 12 | pkg_configure() { 13 | ./configure --prefix="$PREFIX/$PACKAGE" --enable-cxx 14 | } 15 | 16 | pkg_check() { 17 | make check 18 | } 19 | -------------------------------------------------------------------------------- /scripts/setup/CMakeLists_module.txt.tpl: -------------------------------------------------------------------------------- 1 | add_module_library(%MODULE%) 2 | 3 | target_link_libraries(%MODULE% ${Boost_LIBRARIES}) 4 | target_include_directories(%MODULE% SYSTEM PUBLIC ${Boost_INCLUDE_DIR}) 5 | 6 | glob_executables(%MODULE%_exes src) 7 | foreach(exe ${%MODULE%_exes}) 8 | add_module_executable(%MODULE% ${exe}) 9 | endforeach(exe) 10 | 11 | glob_tests(%MODULE%_tests test) 12 | foreach(test ${%MODULE%_tests}) 13 | add_module_unittest(%MODULE% ${test}) 14 | endforeach(test) 15 | -------------------------------------------------------------------------------- /scripts/dependencies/package_mpfr.sh: -------------------------------------------------------------------------------- 1 | NAME="mpfr" 2 | VERSION="3.1.1" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="$PACKAGE.tar.bz2" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="7b66c3f13dc8385f08264c805853f3e1a8eedab8071d582f3e661971c9acd5fd" 8 | 9 | DEPENDS="gmp" 10 | 11 | GMP_PKG=$(get_property gmp PACKAGE) 12 | 13 | unset CC CXX LD_LIBRARY_PATH 14 | export LD_RUN_PATH="$PREFIX/$GMP_PKG/lib" 15 | 16 | pkg_configure() { 17 | ./configure --prefix="$PREFIX/$PACKAGE" --with-gmp="$PREFIX/$GMP_PKG" 18 | } 19 | 20 | pkg_check() { 21 | make check 22 | } 23 | -------------------------------------------------------------------------------- /cmake/file_globs.cmake: -------------------------------------------------------------------------------- 1 | macro(glob_headers output_var input_path) 2 | file(GLOB_RECURSE ${output_var} ${input_path}/*.h ${input_path}/*.hpp ${input_path}/*.def ${input_path}/*.inc) 3 | endmacro() 4 | 5 | macro(glob_sources output_var input_path) 6 | file(GLOB_RECURSE ${output_var} ${input_path}/*.c ${input_path}/*.cpp) 7 | endmacro() 8 | 9 | macro(glob_tests output_var input_path) 10 | file(GLOB_RECURSE ${output_var} ${input_path}/*.cc) 11 | endmacro() 12 | 13 | macro(glob_executables output_var input_path) 14 | file(GLOB_RECURSE ${output_var} ${input_path}/*.cxx) 15 | endmacro() 16 | -------------------------------------------------------------------------------- /code/utils/test/serializer/strings.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "allscale/utils/serializer/strings.h" 4 | 5 | namespace allscale { 6 | namespace utils { 7 | 8 | TEST(Serializer, String) { 9 | 10 | // check that strings are recognized as serializable 11 | EXPECT_TRUE(is_serializable::value); 12 | 13 | // serialize and de-serialize a string 14 | std::string str = "Hello World"; 15 | auto archive = serialize(str); 16 | auto restore = deserialize(archive); 17 | 18 | EXPECT_EQ(str,restore); 19 | } 20 | 21 | } // end namespace utils 22 | } // end namespace allscale 23 | -------------------------------------------------------------------------------- /scripts/ci/configure: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | if [[ -z "${WORKSPACE+x}" ]]; then 6 | cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 7 | source defaults.sh 8 | fi 9 | 10 | # Assuming all required dependencies are installed, this will setup the 11 | # symlinks corresponding to the installed version selected in the dependency 12 | # installer. Just in case some versions have changed, we remove the existing 13 | # setup first. 14 | rm -rf "$WORKSPACE/third_party" 15 | PREFIX="$THIRD_PARTY_LIBS" "$WORKSPACE/scripts/dependencies/third_party_linker" 16 | 17 | # Create build directory if it does not exist. 18 | mkdir -p "$BUILD_DIR" 19 | -------------------------------------------------------------------------------- /scripts/dependencies/third_party_linker: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | export INSTALLER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 6 | export THIRD_PARTY_DIR="third_party" 7 | 8 | get_property() { 9 | echo $(echo "source \"$INSTALLER_DIR/package_$1.sh\" && echo -n \$$2" | bash -) 10 | } 11 | export -f get_property 12 | 13 | mkdir -p "$THIRD_PARTY_DIR" 14 | 15 | source "$INSTALLER_DIR/defaults.sh" 16 | 17 | echo "Prefix: $PREFIX" 18 | 19 | for pkg in "$INSTALLER_DIR/package_"*.sh; do 20 | source "$pkg" 21 | if pkg_is_installed; then 22 | echo "Adding symlink for $PACKAGE" 23 | ln -sfT "$PREFIX/$PACKAGE" "$THIRD_PARTY_DIR/$NAME" 24 | fi 25 | done 26 | -------------------------------------------------------------------------------- /scripts/dependencies/package_mpc.sh: -------------------------------------------------------------------------------- 1 | NAME="mpc" 2 | VERSION="0.9" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="$PACKAGE.tar.gz" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="fd3efe422f0d454592059e80f2c00d1a2e381bf2beda424c5094abd4deb049ac" 8 | 9 | DEPENDS="gmp mpfr" 10 | 11 | GMP_PKG=$(get_property gmp PACKAGE) 12 | MPFR_PKG=$(get_property mpfr PACKAGE) 13 | 14 | unset CC CXX LD_LIBRARY_PATH 15 | export LD_RUN_PATH="$PREFIX/$GMP_PKG/lib:$PREFIX/$MPFR_PKG/lib" 16 | 17 | pkg_configure() { 18 | ./configure --prefix="$PREFIX/$PACKAGE" \ 19 | --with-gmp="$PREFIX/$GMP_PKG" \ 20 | --with-mpfr="$PREFIX/$MPFR_PKG" 21 | } 22 | 23 | pkg_check() { 24 | make check 25 | } 26 | -------------------------------------------------------------------------------- /code/utils/test/tuple_utils.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "allscale/utils/tuple_utils.h" 4 | #include "allscale/utils/string_utils.h" 5 | 6 | namespace allscale { 7 | namespace utils { 8 | 9 | TEST(Tuple,ForEach) { 10 | 11 | auto tuple = std::make_tuple(0,2,4.3); 12 | 13 | EXPECT_EQ("(0,2,4.3)",toString(tuple)); 14 | 15 | forEach(tuple,[](auto& cur) { 16 | cur += 1; 17 | }); 18 | 19 | EXPECT_EQ("(1,3,5.3)",toString(tuple)); 20 | 21 | double sum = 0; 22 | forEach(const_cast&>(tuple),[&](const auto cur) { 23 | sum += cur; 24 | }); 25 | 26 | EXPECT_DOUBLE_EQ(9.3,sum); 27 | } 28 | 29 | 30 | } // end namespace utils 31 | } // end namespace allscale 32 | -------------------------------------------------------------------------------- /scripts/dependencies/package_boost.sh: -------------------------------------------------------------------------------- 1 | NAME="boost" 2 | VERSION="1.59.0" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="${NAME}_${VERSION//./_}.tar.bz2" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="727a932322d94287b62abb1bd2d41723eec4356a7728909e38adb65ca25241ca" 8 | 9 | BOOST_LIBS="date_time,filesystem,program_options,regex,system,serialization,thread,wave" 10 | 11 | pkg_extract() { 12 | tar xf "$FILE" 13 | mv "${NAME}_${VERSION//./_}" "$PACKAGE" 14 | } 15 | 16 | pkg_configure() { 17 | ./bootstrap.sh --prefix="$PREFIX/$PACKAGE" --with-libraries="$BOOST_LIBS" 18 | } 19 | 20 | pkg_build() { 21 | true 22 | } 23 | 24 | pkg_install() { 25 | ./b2 cxxflags="$CFLAGS" release install "-j$SLOTS" 26 | } 27 | -------------------------------------------------------------------------------- /code/tutorials/src/prec/01_fibonacci_prec.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "allscale/api/core/prec.h" 5 | 6 | using namespace allscale::api::core; 7 | 8 | long fibonacci(const unsigned int number) { 9 | auto f = prec(fun( 10 | [](const unsigned int& number) { 11 | return number < 2; 12 | }, 13 | [](const unsigned int& number) { 14 | return number; 15 | }, 16 | [](const unsigned int& number, const auto& rec) { 17 | return run(rec(number - 1)).get() + run(rec(number - 2)).get(); 18 | } 19 | )); 20 | return f(number).get(); 21 | } 22 | 23 | int main() { 24 | const int N = 12; 25 | 26 | long fib = fibonacci(N); 27 | 28 | std::cout << "fibonacci(" << N << ") = " << fib << std::endl; 29 | 30 | return EXIT_SUCCESS; 31 | } 32 | -------------------------------------------------------------------------------- /code/utils/test/finalize.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "allscale/utils/finalize.h" 4 | 5 | namespace allscale { 6 | namespace utils { 7 | 8 | TEST(Finalize, Basic) { 9 | 10 | int x = 0; 11 | auto inc = [&]{ x += 1; }; 12 | 13 | EXPECT_EQ(0,x); 14 | 15 | // used as intended 16 | { 17 | auto _ = run_finally(inc); 18 | EXPECT_EQ(0,x); 19 | } 20 | 21 | EXPECT_EQ(1,x); 22 | 23 | // incorrectly used 24 | { 25 | run_finally(inc); 26 | EXPECT_EQ(2,x); 27 | } 28 | 29 | EXPECT_EQ(2,x); 30 | 31 | 32 | // multiple uses 33 | { 34 | auto _1 = run_finally(inc); 35 | auto _2 = run_finally(inc); 36 | EXPECT_EQ(2,x); 37 | } 38 | 39 | EXPECT_EQ(4,x); 40 | 41 | } 42 | 43 | } // end namespace utils 44 | } // end namespace allscale 45 | -------------------------------------------------------------------------------- /scripts/demo/blender_load.py: -------------------------------------------------------------------------------- 1 | # adapt this path as needed 2 | PATH = "D:\\allscale_build_api_msvc2017\\tutorials\\" 3 | 4 | import bpy 5 | def set_shadeless(): 6 | for mat in bpy.data.materials: 7 | mat.use_shadeless = True 8 | 9 | def reset_blend(): 10 | for scene in bpy.data.scenes: 11 | for obj in scene.objects: 12 | scene.objects.unlink(obj) 13 | for bpy_data_iter in ( 14 | bpy.data.objects, 15 | bpy.data.meshes, 16 | bpy.data.lamps, 17 | bpy.data.cameras, 18 | ): 19 | for id_data in bpy_data_iter: 20 | bpy_data_iter.remove(id_data) 21 | 22 | def load_step(s): 23 | global PATH 24 | reset_blend() 25 | bpy.ops.import_scene.obj(filepath=PATH+'step{:03d}.obj'.format(s)) 26 | set_shadeless() 27 | 28 | -------------------------------------------------------------------------------- /scripts/license/pre-commit-hook: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for f in $(git diff --cached --name-only | grep -i "code/.*\.\(h\|hpp\|def\|inc\|c\|cpp\|cxx\|cc\)$"); do 4 | 5 | # check whether disk version is the same as the version to be commited 6 | git diff --quiet "$f" 7 | up_to_date=$? 8 | 9 | # adding license to file (if not present) 10 | scripts/license/licensor scripts/license/header.txt "$f" 11 | licened=$? 12 | 13 | # check whether modification can / needs to be commited 14 | if [[ $licened -eq 0 ]]; then 15 | if [[ $up_to_date -eq 0 ]]; then 16 | # newly licented file can be commited 17 | git add $f 18 | else 19 | # license had to be added, but there are uncommited changes 20 | echo "ERROR: file '$f' required licening but contained uncommited changes!\n" 21 | exit 1 22 | fi 23 | fi 24 | 25 | done 26 | -------------------------------------------------------------------------------- /scripts/dependencies/package_gcc.sh: -------------------------------------------------------------------------------- 1 | NAME="gcc" 2 | VERSION="5.4.0" 3 | PACKAGE="$NAME-$VERSION" 4 | 5 | FILE="$PACKAGE.tar.gz" 6 | URL="http://www.insieme-compiler.org/ext_libs/$FILE" 7 | SHA256SUM="37089e80c3f2e9a0663d7ccc51c2a6c7dbbf3275bc1e4ed1ed3b1460cd5b3030" 8 | 9 | DEPENDS="gmp mpc mpfr" 10 | 11 | GMP_PKG=$(get_property gmp PACKAGE) 12 | MPC_PKG=$(get_property mpc PACKAGE) 13 | MPFR_PKG=$(get_property mpfr PACKAGE) 14 | 15 | unset CC CXX LD_LIBRARY_PATH 16 | export LD_RUN_PATH="$PREFIX/$GMP_PKG/lib:$PREFIX/$MPC_PKG/lib:$PREFIX/$MPFR_PKG/lib" 17 | 18 | pkg_configure() { 19 | ./configure --prefix="$PREFIX/$PACKAGE" \ 20 | --with-gmp="$PREFIX/$GMP_PKG" \ 21 | --with-mpc="$PREFIX/$MPC_PKG" \ 22 | --with-mpfr="$PREFIX/$MPFR_PKG" \ 23 | --enable-languages="c,c++" \ 24 | --without-isl \ 25 | --disable-multilib \ 26 | --enable-lto 27 | } 28 | -------------------------------------------------------------------------------- /cmake/msvc_source_group.cmake: -------------------------------------------------------------------------------- 1 | macro(msvc_source_group label files) 2 | if(MSVC) 3 | set(one_value_args STRIP) 4 | cmake_parse_arguments(ARG "" "${one_value_args}" "" ${ARGN}) 5 | 6 | foreach(file ${files}) 7 | get_filename_component(file_dir ${file} DIRECTORY) 8 | 9 | # Note: CMake 3.6 REGEX REPLACE misbehaves in that it continuously 10 | # applies the replacement. Therefore REGEX MATCH and REPLACE 11 | # is used. 12 | 13 | string(REPLACE ${CMAKE_CURRENT_SOURCE_DIR}/ "" file_dir "${file_dir}") 14 | 15 | string(REGEX MATCH "^${ARG_STRIP}/?" file_dir_prefix "${file_dir}") 16 | string(REPLACE "${file_dir_prefix}" "" file_dir "${file_dir}") 17 | 18 | string(REPLACE "/" "\\" file_dir "${file_dir}") 19 | 20 | source_group("${label}\\${file_dir}" FILES ${file}) 21 | endforeach(file) 22 | endif() 23 | endmacro() 24 | -------------------------------------------------------------------------------- /code/tutorials/src/adaptivegrid/animate.rb: -------------------------------------------------------------------------------- 1 | require 'rmagick' 2 | include Magick 3 | 4 | #Get list of images at the current directory 5 | all_images = Dir["animation_*.png"] 6 | 7 | # Sort the image by the number in "animation_[NUMBER].png" 8 | all_images = all_images.sort { | a,b | Integer(a.split('_')[1].split('.')[0]) <=> Integer(b.split('_')[1].split('.')[0]) } 9 | 10 | n = all_images.size / 200 11 | if n < 1 then 12 | n = 1 13 | end 14 | 15 | #Ignore some of the images to get ~200 images 16 | n = 1 17 | images = (n - 1).step(all_images.size - 1, n).map { | i | all_images[i] } 18 | 19 | #Write gif file if there is at least one image in the directory 20 | if images.size > 0 then 21 | animation = ImageList.new(*images) 22 | animation.delay = 1 23 | animation.write("animated.gif") 24 | else 25 | puts "No \"animation_*.png\" files found" 26 | end -------------------------------------------------------------------------------- /scripts/ci/defaults.sh: -------------------------------------------------------------------------------- 1 | # CMake Build Type (Debug / Release). 2 | export BUILD_TYPE="${BUILD_TYPE:-Release}" 3 | 4 | # Number of cores used for compilation and testing. 5 | export NPROC="${NPROC:-$(nproc)}" 6 | 7 | # Set default nice level. 8 | export NICE_LEVEL="${NICE_LEVEL:-10}" 9 | 10 | # Location of Third Party Libraries. 11 | export THIRD_PARTY_LIBS="${THIRD_PARTY_LIBS:-$HOME/third_party_libs}" 12 | 13 | # Assume Workspace if not set. 14 | CI_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 15 | export WORKSPACE="${WORKSPACE:-"$(realpath "$CI_DIR/../..")"}" 16 | 17 | # Assume Build Directory if not set. 18 | export BUILD_DIR="${BUILD_DIR:-$WORKSPACE/build}" 19 | 20 | # Are we running on our CI server? 21 | if [[ "$(hostname)" == "hudson.dps.uibk.ac.at" ]]; then 22 | export RUNNING_ON_CI_SERVER="1" 23 | else 24 | export RUNNING_ON_CI_SERVER="" 25 | fi 26 | -------------------------------------------------------------------------------- /code/utils/test/array_utils.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "allscale/utils/array_utils.h" 4 | 5 | namespace allscale { 6 | namespace utils { 7 | 8 | 9 | struct DontConstructMe { 10 | DontConstructMe() = delete; 11 | int x = 0; 12 | DontConstructMe(int x) : x(x) {} 13 | }; 14 | 15 | TEST(VectorUtils, Constant) { 16 | 17 | auto arr = build_array<5>([] { return DontConstructMe(5); }); 18 | 19 | for(DontConstructMe val : arr) { 20 | EXPECT_EQ(val.x, 5); 21 | } 22 | } 23 | 24 | 25 | TEST(VectorUtils, List) { 26 | int vals[7] = {0,1,2,3,4,5,6}; 27 | int* valsPtr = vals; 28 | 29 | auto arr = build_array<7>([&valsPtr] { return DontConstructMe(*(valsPtr++)); }); 30 | 31 | for(int i = 0; i < 5; ++i) { 32 | EXPECT_EQ(arr[i].x, vals[i]); 33 | } 34 | } 35 | 36 | } // end namespace utils 37 | } // end namespace allscale 38 | -------------------------------------------------------------------------------- /scripts/setup/CMakeLists.txt.tpl: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(%PROJECT% LANGUAGES C CXX) 3 | 4 | # -- Module Path 5 | set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../cmake ${CMAKE_MODULE_PATH}) 6 | 7 | # -- Prefix Path 8 | set(THIRD_PARTY_DIR ${CMAKE_BINARY_DIR}/third_party CACHE STRING "Third Party Library Directory") 9 | file(GLOB prefix_paths ${THIRD_PARTY_DIR}/*) 10 | list(APPEND CMAKE_PREFIX_PATH ${prefix_paths}) 11 | 12 | # -- Project Settings 13 | include(build_settings) 14 | include(coverage) 15 | include(doxygen) 16 | 17 | # -- Dependency Settings 18 | include(dependencies/pthread) 19 | include(dependencies/googletest) 20 | include(dependencies/boost) 21 | include(dependencies/valgrind) 22 | 23 | # -- CMake Modules 24 | include(add_module) 25 | include(file_globs) 26 | include(msvc_source_group) 27 | include(nproc) 28 | 29 | # -- Project Modules 30 | -------------------------------------------------------------------------------- /code/api/test/core/treeture.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "allscale/api/core/treeture.h" 8 | 9 | namespace allscale { 10 | namespace api { 11 | namespace core { 12 | 13 | TEST(Treeture, Immediates) { 14 | 15 | treeture t1 = done(); 16 | t1.wait(); 17 | 18 | treeture t2 = done(12); 19 | EXPECT_EQ(12, t2.get()); 20 | 21 | treeture t3 = done(std::string("Hello")); 22 | EXPECT_EQ("Hello",t3.get()); 23 | 24 | 25 | // sequential implementation 26 | impl::sequential::treeture t4 = done(14); 27 | EXPECT_EQ(14,t4.get()); 28 | 29 | // reference implementation 30 | impl::reference::treeture t5 = done(16); 31 | EXPECT_EQ(16,t5.get()); 32 | 33 | } 34 | 35 | } // end namespace core 36 | } // end namespace api 37 | } // end namespace allscale 38 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/serializer/strings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef ALLSCALE_WITH_HPX 4 | #include 5 | #endif 6 | 7 | #include "allscale/utils/serializer.h" 8 | 9 | #include 10 | 11 | namespace allscale { 12 | namespace utils { 13 | 14 | /** 15 | * Add support for serializing / de-serializing strings. 16 | */ 17 | template<> 18 | struct serializer { 19 | 20 | static std::string load(ArchiveReader& reader) { 21 | auto size = reader.read(); 22 | std::string res; 23 | res.resize(size); 24 | reader.read(&res[0],size); 25 | return res; 26 | } 27 | static void store(ArchiveWriter& writer, const std::string& value) { 28 | writer.write(value.size()); 29 | writer.write(&value[0],value.size()); 30 | } 31 | }; 32 | 33 | } // end namespace utils 34 | } // end namespace allscale 35 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/finalize.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace allscale { 4 | namespace utils { 5 | 6 | namespace detail { 7 | 8 | /** 9 | * A utility to implement operations on scope-exit. 10 | */ 11 | template 12 | class finalizer { 13 | Op op; 14 | public: 15 | 16 | finalizer(const Op& op) : op(op) {} 17 | finalizer(const finalizer&) = delete; 18 | finalizer(finalizer&&) = default; 19 | 20 | ~finalizer() { op(); } 21 | 22 | finalizer& operator=(const finalizer&) = delete; 23 | finalizer& operator=(finalizer&&) = default; 24 | }; 25 | 26 | } 27 | 28 | /** 29 | * Creates an object which will trigger the provided operation on destruction. 30 | */ 31 | template 32 | detail::finalizer run_finally(const Op& op) { 33 | return detail::finalizer{op}; 34 | } 35 | 36 | } // end namespace utils 37 | } // end namespace allscale 38 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/serializer/optionals.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "allscale/utils/serializer.h" 4 | 5 | #include "allscale/utils/optional.h" 6 | 7 | namespace allscale { 8 | namespace utils { 9 | 10 | /** 11 | * Add support for serializing / de-serializing optional values. 12 | */ 13 | template 14 | struct serializer,typename std::enable_if::value,void>::type> { 15 | 16 | static allscale::utils::optional load(ArchiveReader& reader) { 17 | bool present = reader.read(); 18 | if (!present) return {}; 19 | return reader.read(); 20 | } 21 | 22 | static void store(ArchiveWriter& writer, const allscale::utils::optional& value) { 23 | writer.write(bool(value)); 24 | if (bool(value)) writer.write(*value); 25 | } 26 | }; 27 | 28 | 29 | } // end namespace utils 30 | } // end namespace allscale 31 | -------------------------------------------------------------------------------- /code/tutorials/src/matrix_multiplication/01_basic.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | const int N = 100; 5 | 6 | using Matrix = std::array,N>; 7 | 8 | Matrix id() { 9 | Matrix res; 10 | for(int i=0; i/dev/null) 10 | 11 | if [ -z "$GITVER" ] ; then 12 | # Get version information from file 13 | if [ -e "$TOOLDIR/../.version" ] ; then 14 | source "$TOOLDIR/../.version" 15 | fi 16 | else 17 | # Get version information from git 18 | FULL=${GITVER:1} 19 | VERSION=${GITVER%%-*} 20 | VERSION=${VERSION:1} 21 | if [ "${GITVER#*-}" != "$GITVER" ] ; then 22 | RELEASE=${GITVER#*-} 23 | RELEASE=${RELEASE/-/.} 24 | fi 25 | fi 26 | 27 | # Fallback 28 | [ -z "$VERSION" ] && VERSION="1.0" 29 | [ -z "$RELEASE" ] && RELEASE="1" 30 | [ -z "$FULL" ] && FULL="$VERSION" 31 | 32 | [ "$1" == "--version" ] && echo -n "$VERSION" 33 | [ "$1" == "--release" ] && echo -n "$RELEASE" 34 | [ "$1" == "--full" ] && echo -n "$FULL" 35 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: llvm 2 | 3 | AlignOperands: true 4 | AlignTrailingComments: true 5 | AllowShortBlocksOnASingleLine: true 6 | AllowShortCaseLabelsOnASingleLine: true 7 | AllowShortFunctionsOnASingleLine: Inline 8 | AllowShortIfStatementsOnASingleLine: true 9 | AllowShortLoopsOnASingleLine: false 10 | AlwaysBreakTemplateDeclarations: true 11 | BinPackArguments: true 12 | BinPackParameters: true 13 | BreakBeforeBinaryOperators: NonAssignment 14 | BreakBeforeBraces: Attach 15 | ColumnLimit: 160 16 | Cpp11BracedListStyle: true 17 | IndentCaseLabels: false 18 | IndentWidth: 4 19 | KeepEmptyLinesAtTheStartOfBlocks: false 20 | MaxEmptyLinesToKeep: 2 21 | NamespaceIndentation: Inner 22 | PointerAlignment: Left 23 | SpaceAfterCStyleCast: false 24 | SpaceBeforeParens: Never 25 | SpaceInEmptyParentheses: false 26 | SpacesBeforeTrailingComments: 1 27 | SpacesInAngles: false 28 | SpacesInCStyleCastParentheses: false 29 | SpacesInParentheses: false 30 | SpacesInSquareBrackets: false 31 | Standard: Cpp11 32 | TabWidth: 4 33 | UseTab: ForIndentation 34 | -------------------------------------------------------------------------------- /code/tutorials/src/mesh/01_demo_mesh_utils.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef NDEBUG 3 | #define assert_between(__low, __v, __high) \ 4 | if(__allscale_unused auto __allscale_temp_object_ = insieme::utils::detail::LazyAssertion((__low) <= (__v) && (__v) <= (__high))) \ 5 | std::cerr << "\nAssertion " #__low " <= " #__v " <= " #__high " of " __FILE__ ":" __allscale_xstr_(__LINE__) " failed!\n\t" #__v " = " << (__v) << "\n" 6 | #else 7 | #define assert_between(__low, __v, __high) if(0) std::cerr 8 | #endif 9 | 10 | #define MIN_TEMP 0 11 | #define MAX_TEMP 511 12 | 13 | #ifdef USE_TEMPERATURE_ASSERTIONS 14 | #define assert_temperature(__v) \ 15 | assert_between(MIN_TEMP, __v, MAX_TEMP) 16 | #else // USE_TEMPERATURE_ASSERTIONS 17 | #define assert_temperature(__v) if(0) std::cerr 18 | #endif // USE_TEMPERATURE_ASSERTIONS 19 | -------------------------------------------------------------------------------- /code/tutorials/src/matrix_multiplication/02_data_structure.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "allscale/api/user/data/static_grid.h" 5 | 6 | using namespace allscale::api::user; 7 | 8 | const int N = 100; 9 | 10 | using Matrix = data::StaticGrid; 11 | 12 | Matrix id() { 13 | Matrix res; 14 | for(int i=0; i 4 | #include 5 | #include 6 | 7 | namespace allscale { 8 | namespace utils { 9 | 10 | // -- some convenience utilities for stream based IO operations -- 11 | 12 | template 13 | void write(std::ostream& out, T value) { 14 | out.write((char*)&value, sizeof(T)); 15 | } 16 | 17 | template 18 | void write(std::ostream& out, const Iter& a, const Iter& b) { 19 | for(auto it = a; it != b; ++it) { 20 | out.write((char*)&(*it), sizeof(typename std::remove_reference::type)); 21 | } 22 | } 23 | 24 | template 25 | T read(std::istream& in) { 26 | T value = T(); 27 | in.read((char*)&value, sizeof(T)); 28 | return value; 29 | } 30 | 31 | template 32 | void read(std::istream& in, const Iter& a, const Iter& b) { 33 | for(auto it = a; it != b; ++it) { 34 | *it = read::type>(in); 35 | } 36 | } 37 | 38 | } // end namespace utils 39 | } // end namespace allscale 40 | -------------------------------------------------------------------------------- /code/utils/test/serializer/optionals.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "allscale/utils/serializer/optionals.h" 4 | #include "allscale/utils/serializer/strings.h" 5 | 6 | namespace allscale { 7 | namespace utils { 8 | 9 | struct NotSerializable {}; 10 | 11 | 12 | TEST(Serializer, Optional) { 13 | 14 | // check that pairs are recognized as serializable 15 | EXPECT_TRUE((is_serializable>::value)); 16 | EXPECT_TRUE((is_serializable>::value)); 17 | EXPECT_TRUE((is_serializable>::value)); 18 | 19 | } 20 | 21 | TEST(Serializer,OptionalIntNone) { 22 | // serialize and de-serialize a instance 23 | optional none; 24 | auto archive = serialize(none); 25 | auto out = deserialize>(archive); 26 | EXPECT_EQ(none,out); 27 | } 28 | 29 | TEST(Serializer,OptionalIntOne) { 30 | // serialize and de-serialize a instance 31 | optional one = 1; 32 | auto archive = serialize(one); 33 | auto out = deserialize>(archive); 34 | EXPECT_EQ(one,out); 35 | } 36 | 37 | } // end namespace utils 38 | } // end namespace allscale 39 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/array_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace allscale { 7 | namespace utils { 8 | 9 | namespace { 10 | template 11 | struct array_builder { 12 | template 13 | std::array operator()(Fn&& fn, T&&... vals) const { 14 | return array_builder{}(std::forward(fn), std::forward(vals)..., fn()); 15 | } 16 | }; 17 | 18 | template 19 | struct array_builder { 20 | template 21 | std::array operator()(Fn&&, T&&... vals) const { 22 | return { { std::forward(vals)... } }; 23 | } 24 | }; 25 | } 26 | 27 | /* 28 | * Create an Array of N elements, initialized with the elements returned by fn. Can be used to create an array of elements without default constructor 29 | * 30 | */ 31 | template::type> 32 | std::array build_array(Fn&& fn) { 33 | return array_builder<0, N, U>()(std::forward(fn)); 34 | } 35 | 36 | } // end namespace utils 37 | } // end namespace allscale 38 | -------------------------------------------------------------------------------- /code/tutorials/src/matrix_multiplication/03_pfor_simple.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "allscale/api/user/algorithm/pfor.h" 5 | #include "allscale/api/user/data/static_grid.h" 6 | 7 | using namespace allscale::api::user; 8 | using namespace allscale::api::user::algorithm; 9 | 10 | const int N = 100; 11 | 12 | using Matrix = data::StaticGrid; 13 | 14 | Matrix id() { 15 | Matrix res; 16 | for(int i=0; i 2 | 3 | #include 4 | 5 | #include "allscale/utils/raw_buffer.h" 6 | #include "allscale/utils/string_utils.h" 7 | 8 | namespace allscale { 9 | namespace utils { 10 | 11 | TEST(RawBuffer,TypeProperties) { 12 | 13 | EXPECT_TRUE(std::is_copy_constructible::value); 14 | EXPECT_TRUE(std::is_move_constructible::value); 15 | 16 | EXPECT_TRUE(std::is_copy_assignable::value); 17 | EXPECT_TRUE(std::is_move_assignable::value); 18 | 19 | EXPECT_TRUE(std::is_destructible::value); 20 | 21 | } 22 | 23 | TEST(RawBuffer,Basic) { 24 | 25 | int data[5] = { 1, 2, 3, 4, 5 }; 26 | 27 | RawBuffer buffer(data); 28 | 29 | // check consuming individual elements 30 | EXPECT_EQ(1,buffer.consume()); 31 | EXPECT_EQ(2,buffer.consume()); 32 | 33 | // consume an array of elements 34 | int* array = buffer.consumeArray(2); 35 | EXPECT_EQ(data[2],array[0]); 36 | EXPECT_EQ(data[3],array[1]); 37 | EXPECT_EQ(data+2,array); 38 | 39 | // check final element 40 | EXPECT_EQ(5,buffer.consume()); 41 | } 42 | 43 | } // end namespace utils 44 | } // end namespace allscale 45 | -------------------------------------------------------------------------------- /code/tutorials/src/matrix_multiplication/04_pfor_collapsed.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "allscale/api/user/algorithm/pfor.h" 5 | #include "allscale/api/user/data/static_grid.h" 6 | 7 | using namespace allscale::api::user; 8 | using namespace allscale::api::user::algorithm; 9 | 10 | const int N = 100; 11 | 12 | using Matrix = data::StaticGrid; 13 | using Point = allscale::utils::Vector; 14 | 15 | Matrix id() { 16 | Matrix res; 17 | for(int i=0; i [output-file] 7 | 8 | Replaces existing license header, prepends if no license header present, no 9 | changes if license up to date. If no output file is provided, the code file 10 | will be overwritten. 11 | EOS 12 | 13 | # The license recognition: 14 | # A comment at the start of the file, which contains "COPYRIGHT" 15 | LICENSE_REGEXP = /\A\s*\/\*.*?COPYRIGHT.*?\*\//mi 16 | 17 | if(ARGV.length < 2 || ARGV.length > 3) 18 | puts(USAGE) 19 | exit(false) 20 | end 21 | 22 | license = IO.read(ARGV[0]) 23 | 24 | # update license year to current 25 | license.sub!(/20XX/, Date.today.year.to_s) 26 | 27 | file = IO.read(ARGV[1]) 28 | 29 | match = LICENSE_REGEXP.match(file) 30 | 31 | # check if any existing license 32 | if(match) 33 | # if up-to-date, exit 34 | exit(true) if(match[0].strip == license.strip) 35 | # else, delete existing license 36 | file.sub!(match[0], ""); 37 | end 38 | 39 | # prepend new license 40 | output = license + file.lstrip 41 | 42 | # write ouptput to code file, or output file if specified 43 | outfn = ARGV[ARGV.length - 1] 44 | 45 | File.open(outfn, "wb+") do |f| 46 | f.print(output) 47 | end 48 | 49 | exit(true) 50 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/bitmanipulation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _MSC_VER 4 | #include 5 | #endif 6 | 7 | namespace allscale { 8 | namespace utils { 9 | 10 | /** 11 | * A wrapper function for counting leading zeros 12 | */ 13 | inline int countLeadingZeros(unsigned value) { 14 | #ifdef _MSC_VER 15 | unsigned long retVal = 0; 16 | if(_BitScanReverse(&retVal, value)) 17 | return 31-retVal; 18 | // all zeros is undefined behavior, we simply return 32 19 | return 32; 20 | #else 21 | return __builtin_clz(value); 22 | #endif 23 | } 24 | 25 | /** 26 | * A wrapper function for counting trailing zeros 27 | */ 28 | inline int countTrailingZeros(unsigned value) { 29 | #ifdef _MSC_VER 30 | unsigned long retVal = 0; 31 | if(_BitScanForward(&retVal, value)) 32 | return retVal; 33 | // all zeros is undefined behavior, we simply return 32 34 | return 32; 35 | #else 36 | return __builtin_ctz(value); 37 | #endif 38 | } 39 | 40 | /** 41 | * A wrapper function for counting 1-bits 42 | */ 43 | inline int countOnes(unsigned value) { 44 | #ifdef _MSC_VER 45 | return __popcnt(value); 46 | #else 47 | return __builtin_popcount(value); 48 | #endif 49 | } 50 | 51 | } // end namespace utils 52 | } // end namespace allscale 53 | -------------------------------------------------------------------------------- /code/api/test/core/data.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "allscale/api/core/data.h" 9 | #include "allscale/api/user/data/map.h" 10 | 11 | namespace allscale { 12 | namespace api { 13 | namespace core { 14 | 15 | 16 | TEST(Region, IsRegionTest) { 17 | 18 | // some negative tests 19 | EXPECT_FALSE(is_region::value); 20 | EXPECT_FALSE(is_region::value); 21 | 22 | // some positive test 23 | EXPECT_TRUE(is_region>::value); 24 | 25 | } 26 | 27 | 28 | TEST(Fragment, IsFragmentTest) { 29 | 30 | // some negative tests 31 | EXPECT_FALSE(is_fragment::value); 32 | EXPECT_FALSE(is_fragment::value); 33 | EXPECT_FALSE(is_fragment>::value); 34 | 35 | // some positive test 36 | EXPECT_TRUE((is_fragment>::value)); 37 | } 38 | 39 | struct no_serializable {}; 40 | 41 | TEST(SharedData, IsSharedData) { 42 | 43 | // some negative tests 44 | EXPECT_FALSE(is_shared_data::value); 45 | 46 | // some positive test 47 | EXPECT_TRUE(is_shared_data::value); 48 | 49 | } 50 | 51 | } // end namespace core 52 | } // end namespace api 53 | } // end namespace allscale 54 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/serializer/pairs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "allscale/utils/serializer.h" 4 | 5 | #include 6 | 7 | namespace allscale { 8 | namespace utils { 9 | 10 | /** 11 | * Add support for serializing / de-serializing pairs of trivial element types. 12 | */ 13 | template 14 | struct is_trivially_serializable, typename std::enable_if::value && is_trivially_serializable::value>::type> : public std::true_type {}; 15 | 16 | /** 17 | * Add support for serializing / de-serializing pairs of non-trivial element types. 18 | */ 19 | template 20 | struct serializer,typename std::enable_if< 21 | is_serializable::value && is_serializable::value && (!is_trivially_serializable::value || !is_trivially_serializable::value), 22 | void>::type> { 23 | 24 | static std::pair load(ArchiveReader& reader) { 25 | A a = reader.read(); 26 | B b = reader.read(); 27 | return std::make_pair(std::move(a),std::move(b)); 28 | } 29 | static void store(ArchiveWriter& writer, const std::pair& value) { 30 | writer.write(value.first); 31 | writer.write(value.second); 32 | } 33 | }; 34 | 35 | 36 | } // end namespace utils 37 | } // end namespace allscale 38 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/raw_buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace allscale { 4 | namespace utils { 5 | 6 | /** 7 | * A utility for interpreting raw buffers. 8 | */ 9 | class RawBuffer { 10 | 11 | char* cur; 12 | 13 | public: 14 | 15 | /** 16 | * Creates a buffer based on the given memory location. 17 | */ 18 | template 19 | RawBuffer(T* base) : cur(reinterpret_cast(base)) {} 20 | 21 | /** 22 | * Consumes an element of type T from the underlying buffer. 23 | */ 24 | template 25 | T& consume() { 26 | return consumeArray(1)[0]; 27 | } 28 | 29 | /** 30 | * Consumes an array of elements of type T form the underlying buffer. 31 | */ 32 | template 33 | T* consumeArray(std::size_t numElements) { 34 | 35 | // check that the given type allows this kind of operations 36 | static_assert( 37 | std::is_trivially_copy_assignable::value || 38 | std::is_trivially_move_assignable::value, 39 | "Invalid reinterpretation of raw data!" 40 | ); 41 | 42 | // 'parse' initial elements 43 | auto res = reinterpret_cast(cur); 44 | // progress position 45 | cur += sizeof(T) * numElements; 46 | // return result 47 | return res; 48 | } 49 | 50 | }; 51 | 52 | } // end namespace utils 53 | } // end namespace allscale 54 | -------------------------------------------------------------------------------- /scripts/dependencies/defaults.sh: -------------------------------------------------------------------------------- 1 | # default location 2 | export PREFIX="${PREFIX:-${THIRD_PARTY_LIBS:-$HOME/third_party_libs}}" 3 | 4 | # default compile flags 5 | export CFLAGS="-mtune=native -O3" 6 | export CXXFLAGS="-mtune=native -O3" 7 | export LDLAGS="-mtune=native -O3" 8 | 9 | # override compiler 10 | #GCC_PKG=$(get_property gcc PACKAGE) 11 | #export CC="$PREFIX/$GCC_PKG/bin/gcc" 12 | #export CXX="$PREFIX/$GCC_PKG/bin/g++" 13 | #export PATH="$PREFIX/$GCC_PKG/bin:$PATH" 14 | #export LD_LIBRARY_PATH="$PREFIX/$GCC_PKG/lib64" 15 | 16 | # parallel build 17 | export SLOTS="${SLOTS:-$(nproc)}" 18 | 19 | pkg_is_installed() { 20 | [[ -f "$PREFIX/$PACKAGE/.installed" ]] 21 | } 22 | 23 | pkg_download() { 24 | wget -nc "$URL" 25 | if [[ "$SHA256SUM" ]]; then 26 | echo "$SHA256SUM $FILE" | sha256sum -c 27 | fi 28 | } 29 | 30 | pkg_extract() { 31 | tar xf "$FILE" 32 | } 33 | 34 | pkg_prepare() { 35 | find "$INSTALLER_DIR/patches" -name "$NAME-*.patch" | sort | xargs -r -L 1 patch -p1 -N -i 36 | } 37 | 38 | pkg_configure() { 39 | ./configure --prefix="$PREFIX/$PACKAGE" 40 | } 41 | 42 | pkg_build() { 43 | make -j "$SLOTS" 44 | } 45 | 46 | pkg_check() { 47 | true 48 | } 49 | 50 | pkg_install() { 51 | make install 52 | } 53 | 54 | pkg_install_done() { 55 | touch "$PREFIX/$PACKAGE/.installed" 56 | } 57 | 58 | pkg_cleanup() { 59 | rm -rf "$PACKAGE" "$FILE" 60 | } 61 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/concepts.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace allscale { 6 | namespace utils { 7 | 8 | template 9 | struct is_equality_comparable : public std::false_type {}; 10 | 11 | template 12 | struct is_equality_comparable() == std::declval()),bool>::value && 14 | std::is_convertible() != std::declval()),bool>::value, 15 | void>::type> : public std::true_type {}; 16 | 17 | 18 | template 19 | struct is_value : public std::false_type {}; 20 | 21 | template 22 | struct is_value::value && 26 | 27 | // regions need to be default-constructible 28 | std::is_copy_constructible::value && 29 | 30 | // regions need to be default-constructible 31 | std::is_copy_assignable::value && 32 | 33 | // regions need to be destructible 34 | std::is_destructible::value && 35 | 36 | // regions need to be equality comparable 37 | utils::is_equality_comparable::value, 38 | 39 | void>::type> : public std::true_type {}; 40 | 41 | 42 | } // end namespace utils 43 | } // end namespace allscale 44 | -------------------------------------------------------------------------------- /code/tutorials/src/adaptivegrid/plot.rb: -------------------------------------------------------------------------------- 1 | #Usage: ruby plot.rb wave_result.csv 2 | 3 | require "gnuplot" 4 | require "csv" 5 | require "parallel" 6 | 7 | data = CSV.read(ARGV[0]) 8 | 9 | work = (1..(data.size - 1)).to_a 10 | 11 | Parallel.each(work) { | i | 12 | 13 | x = Array.new 14 | y = Array.new 15 | z = Array.new 16 | 17 | data[i].each_index do | index | 18 | if index == 0 19 | next 20 | end 21 | element = data[i][index] 22 | 23 | pos = data[0][index].split(":") 24 | if x[-1] != pos[0] 25 | x.push nil 26 | y.push nil 27 | z.push nil 28 | end 29 | x.push pos[0] 30 | y.push pos[1] 31 | z.push element 32 | #puts "[#{pos[0]}][#{pos[1]}] = #{element}" 33 | end 34 | 35 | 36 | 37 | Gnuplot.open do |gp| 38 | Gnuplot::SPlot.new( gp ) do |plot| 39 | plot.grid 40 | plot.zrange "[-0.5:1]" 41 | plot.cbrange "[-0.5:1]" 42 | plot.palette "defined (0 \"black\", 1 \"cyan\")" 43 | plot.ylabel "y" 44 | plot.xlabel "x" 45 | plot.zlabel "amp" 46 | 47 | plot.terminal "png" 48 | plot.output File.expand_path("../animation_#{i}.png", __FILE__) 49 | 50 | plot.data = [ 51 | Gnuplot::DataSet.new( [x, y, z] ) do |ds| 52 | ds.with = "pm3d" 53 | end 54 | ] 55 | end 56 | end 57 | } -------------------------------------------------------------------------------- /code/tutorials/src/matrix_multiplication/00_c_style.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const int N = 100; 4 | 5 | double** createMatrix() { 6 | double** res = new double*[N]; 7 | double* buffer = new double[N*N]; 8 | for(int i=0; i 8 | 9 | namespace allscale { 10 | namespace utils { 11 | 12 | /** 13 | * Add support for serializing / de-serializing std::maps. 14 | */ 15 | template 16 | struct serializer,typename std::enable_if::value && is_serializable::value,void>::type> { 17 | 18 | static std::map load(ArchiveReader& reader) { 19 | 20 | // create the result 21 | std::map res; 22 | 23 | // get the number of key/value pairs 24 | std::size_t numElements = reader.read(); 25 | 26 | // load all the pairs 27 | for(std::size_t i = 0; i < numElements; ++i) { 28 | const auto& key = reader.read(); 29 | const auto& value = reader.read(); 30 | res.emplace(std::move(key), std::move(value)); 31 | } 32 | 33 | // done 34 | return res; 35 | } 36 | static void store(ArchiveWriter& writer, const std::map& value) { 37 | 38 | // start with the size 39 | writer.write(value.size()); 40 | 41 | // followed by all pairs 42 | for(const auto& element : value) { 43 | writer.write(element.first); 44 | writer.write(element.second); 45 | } 46 | } 47 | }; 48 | 49 | } // end namespace utils 50 | } // end namespace allscale 51 | -------------------------------------------------------------------------------- /code/tutorials/src/prec/02_nqueens_c_style.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct Assignment { 6 | 7 | int column; // < the number of columns assigned so far 8 | int row; // < the row this queen is placed 9 | const Assignment* rest; // < the rest of this assignment 10 | 11 | Assignment() 12 | : column(-1), row(0), rest(nullptr) {} 13 | 14 | Assignment(int row, const Assignment& rest) 15 | : column(rest.column+1), row(row), rest(&rest) {} 16 | 17 | int size() const { 18 | return column + 1; 19 | } 20 | 21 | bool valid(int r) const { 22 | return valid(r,column+1); 23 | } 24 | 25 | bool valid(int r, int c) const { 26 | //assert_lt(column,c); 27 | // check end of assignment 28 | if (column<0) return true; 29 | // if in same row => fail 30 | if (row == r) return false; 31 | // if on same diagonal => fail 32 | auto diff = c - column; 33 | if (row + diff == r || row - diff == r) return false; 34 | // check nested 35 | return rest->valid(r,c); 36 | } 37 | }; 38 | 39 | int n_queens(const Assignment& a, int size) { 40 | if(a.size() >= size) 41 | return 1; 42 | 43 | int solution = 0; 44 | 45 | for(int i = 0; i < size; i++) { 46 | if(a.valid(i)) 47 | solution += n_queens(Assignment(i, a), size); 48 | } 49 | 50 | return solution; 51 | } 52 | 53 | int main() { 54 | const int N = 10; 55 | 56 | int solutions = n_queens(Assignment(), N); 57 | 58 | 59 | std::cout << "There are " << solutions << " solutions." << std::endl; 60 | 61 | return EXIT_SUCCESS; 62 | } -------------------------------------------------------------------------------- /cmake/FindValgrind.cmake: -------------------------------------------------------------------------------- 1 | # Try to find Valgrind headers and libraries. 2 | # 3 | # Usage of this module as follows: 4 | # find_package(Valgrind) 5 | # 6 | # Variables used by this module, they can change the default behaviour and need 7 | # to be set before calling find_package: 8 | # 9 | # VALGRIND_ROOT Set this variable to the root installation of valgrind if the 10 | # module has problems finding the proper installation path. 11 | # 12 | # Variables defined by this module: 13 | # Valgrind_FOUND System has valgrind 14 | # Valgrind_INCLUDE_DIR where to find valgrind/memcheck.h, etc. 15 | # Valgrind_EXECUTABLE the valgrind executable. 16 | 17 | # Get hint from environment variable (if any) 18 | if(NOT VALGRIND_ROOT AND DEFINED ENV{VALGRIND_ROOT}) 19 | set(VALGRIND_ROOT "$ENV{VALGRIND_ROOT}" CACHE PATH "Valgrind base directory location (optional, used for nonstandard installation paths)") 20 | mark_as_advanced(VALGRIND_ROOT) 21 | endif() 22 | 23 | # Search path for nonstandard locations 24 | if(VALGRIND_ROOT) 25 | set(Valgrind_INCLUDE_PATH PATHS "${VALGRIND_ROOT}/include" NO_DEFAULT_PATH) 26 | set(Valgrind_BINARY_PATH PATHS "${VALGRIND_ROOT}/bin" NO_DEFAULT_PATH) 27 | endif() 28 | 29 | find_path(Valgrind_INCLUDE_DIR valgrind HINTS ${Valgrind_INCLUDE_PATH}) 30 | find_program(Valgrind_EXECUTABLE NAMES valgrind PATH ${Valgrind_BINARY_PATH}) 31 | 32 | include(FindPackageHandleStandardArgs) 33 | find_package_handle_standard_args(Valgrind DEFAULT_MSG Valgrind_INCLUDE_DIR Valgrind_EXECUTABLE) 34 | 35 | mark_as_advanced(Valgrind_INCLUDE_DIR Valgrind_EXECUTABLE) 36 | -------------------------------------------------------------------------------- /scripts/coverage/create: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if [[ $# -ne 1 ]]; then 6 | echo "Usage: $0 " 7 | exit 1 8 | fi 9 | 10 | DIR="$(dirname $(readlink -f "$0"))" 11 | PRJ="$(readlink -f "$DIR/../..")" 12 | LCOV="$DIR/lcov/lcov" 13 | 14 | MODULE_DIRECTORIES="$( 15 | find $PRJ/code -mindepth 1 -maxdepth 1 -type d | 16 | xargs -L 1 basename | 17 | awk "{print \"--directory $1/\" \$0}" | 18 | tr '\n' ' ' 19 | )" 20 | 21 | run_unit_tests() { 22 | pushd "$1" 23 | NUM_WORKERS=4 make test ARGS=-j4 24 | popd 25 | } 26 | 27 | # reset 28 | rm -rf "$1/coverage" "$1/coverage"{,_initial,_unittests,_total}.info 29 | "$LCOV" --zerocounters --directory "$1" 30 | 31 | # initial reading 32 | "$LCOV" --quiet --capture --initial \ 33 | --base-directory "$PRJ" \ 34 | $MODULE_DIRECTORIES \ 35 | --output-file "$1/coverage_initial.info" \ 36 | --ignore-errors source \ 37 | --no-external 38 | 39 | run_unit_tests "$1" 40 | 41 | # capture unit tests results 42 | "$LCOV" --quiet --capture \ 43 | --base-directory "$PRJ" \ 44 | $MODULE_DIRECTORIES \ 45 | --output-file "$1/coverage_unittests.info" \ 46 | --ignore-errors source \ 47 | --no-external 48 | 49 | # combine baseline and unit test results 50 | "$LCOV" --add-tracefile "$1/coverage_initial.info" \ 51 | --add-tracefile "$1/coverage_unittests.info" \ 52 | --output-file "$1/coverage_total.info" 53 | 54 | # remove unwanted information 55 | "$LCOV" --remove coverage_total.info '*-prefix*' \ 56 | --output-file "$1/coverage.info" 57 | 58 | # generate report 59 | "$DIR/lcov/genhtml" "$1/coverage.info" --output-directory "$1/coverage" 60 | -------------------------------------------------------------------------------- /code/tutorials/src/heat_stencil/01_basic.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | int main() { 9 | 10 | const int N = 200; 11 | const int T = 100; 12 | 13 | const double k = 0.001; 14 | 15 | using Grid = std::array,N>; 16 | 17 | auto bufferA = std::make_unique(); 18 | auto bufferB = std::make_unique(); 19 | 20 | // initialize temperature 21 | Grid& temp = *bufferA; 22 | for(int i=0; i 2 | #include 3 | #include 4 | 5 | #include "allscale/api/user/data/static_grid.h" 6 | 7 | using namespace allscale::api::user; 8 | 9 | 10 | int main() { 11 | 12 | const int N = 200; 13 | const int T = 100; 14 | 15 | const double k = 0.001; 16 | 17 | using Grid = data::StaticGrid; 18 | 19 | Grid bufferA; 20 | Grid bufferB; 21 | 22 | // initialize temperature 23 | Grid& temp = bufferA; 24 | for(int i=0; i 2 | 3 | #include "allscale/utils/range.h" 4 | 5 | namespace allscale { 6 | namespace utils { 7 | 8 | template 9 | std::size_t count(const range& r) { 10 | std::size_t count = 0; 11 | for(auto it = r.begin(); it != r.end(); ++it) { 12 | count++; 13 | } 14 | return count; 15 | } 16 | 17 | 18 | TEST(Range, PlainArray) { 19 | 20 | int data[12] = { 1, 2, 3 }; 21 | 22 | using range = range; 23 | 24 | range e { &data[0],&data[0] }; 25 | 26 | EXPECT_TRUE(e.empty()); 27 | EXPECT_EQ(0,count(e)); 28 | EXPECT_EQ(e.size(),count(e)); 29 | 30 | 31 | 32 | range a { &data[0],&data[12] }; 33 | EXPECT_FALSE(a.empty()); 34 | EXPECT_EQ(12,count(a)); 35 | EXPECT_EQ(a.size(),count(a)); 36 | 37 | EXPECT_EQ(1, a.front()); 38 | EXPECT_EQ(0, a.back()); 39 | 40 | } 41 | 42 | 43 | TEST(Range, Vector) { 44 | 45 | std::vector data(12); 46 | data[0] = 1; 47 | data[1] = 2; 48 | data[2] = 3; 49 | 50 | using range = range::const_iterator>; 51 | 52 | range e { data.begin(),data.begin() }; 53 | 54 | EXPECT_TRUE(e.empty()); 55 | EXPECT_EQ(0,count(e)); 56 | EXPECT_EQ(e.size(),count(e)); 57 | 58 | 59 | 60 | range a { data.begin(),data.end() }; 61 | EXPECT_FALSE(a.empty()); 62 | EXPECT_EQ(12,count(a)); 63 | EXPECT_EQ(a.size(),count(a)); 64 | 65 | EXPECT_EQ(1, a.front()); 66 | EXPECT_EQ(0, a.back()); 67 | 68 | EXPECT_NE(e,data); 69 | EXPECT_NE(data,e); 70 | 71 | EXPECT_EQ(a,data); 72 | EXPECT_EQ(data,a); 73 | 74 | } 75 | 76 | } // end namespace utils 77 | } // end namespace allscale 78 | -------------------------------------------------------------------------------- /scripts/setup/run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 6 | TGT="$DIR/../.." 7 | 8 | render_template() { 9 | sed -e "s/%PROJECT%/$project/g" -e "s/%MODULE%/$module/g" "$1" > "$2" 10 | } 11 | 12 | add_module() { 13 | module="$1" 14 | 15 | mkdir "$TGT/code/$module" 16 | mkdir -p "$TGT/code/$module/"{"include/$project/$module",src,test} 17 | 18 | render_template "$DIR/CMakeLists_module.txt.tpl" "$TGT/code/$module/CMakeLists.txt" 19 | 20 | echo "add_subdirectory($module)" >> "$TGT/code/CMakeLists.txt" 21 | } 22 | 23 | if [[ $# -eq 0 || "$1" == "-h" || "$1" == "--help" ]]; then 24 | echo "Usage: $0 [module-name]..." 25 | exit 1 26 | fi 27 | 28 | # setup project name, modules remain in $@ 29 | project="$1" 30 | shift 31 | 32 | if [[ ! -d "$TGT/code" ]]; then 33 | # setup README 34 | render_template "$DIR/README.md.tpl" "$TGT/README.md" 35 | 36 | # CMakeLists.txt chain loader 37 | cp "$DIR/CMakeLists_root.txt" "$TGT/CMakeLists.txt" 38 | 39 | mkdir "$TGT/code" 40 | 41 | # setup root CMakeLists 42 | render_template "$DIR/CMakeLists.txt.tpl" "$TGT/code/CMakeLists.txt" 43 | 44 | # setup example module 45 | add_module example 46 | render_template "$DIR/example/answer.h.tpl" "$TGT/code/example/include/$project/example/answer.h" 47 | render_template "$DIR/example/answer.cpp.tpl" "$TGT/code/example/src/answer.cpp" 48 | render_template "$DIR/example/answer_test.cc.tpl" "$TGT/code/example/test/answer_test.cc" 49 | render_template "$DIR/example/main.cxx.tpl" "$TGT/code/example/src/main.cxx" 50 | fi 51 | 52 | for module in "$@"; do 53 | add_module "$module" 54 | done 55 | -------------------------------------------------------------------------------- /code/tutorials/src/heat_stencil/03_pfor.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "allscale/api/user/data/static_grid.h" 6 | 7 | using namespace allscale::api::user; 8 | using namespace allscale::api::user::algorithm; 9 | 10 | 11 | int main() { 12 | 13 | const int N = 200; 14 | const int T = 100; 15 | 16 | const double k = 0.001; 17 | 18 | using Grid = data::StaticGrid; 19 | 20 | Grid bufferA; 21 | Grid bufferB; 22 | 23 | // initialize temperature 24 | Grid& temp = bufferA; 25 | pfor(0,N,[&](int i){ 26 | pfor(0,N,[&](int j){ 27 | temp[{i,j}] = 0; 28 | 29 | // one hot spot in the center 30 | if (i == N/2 && j == N/2) { 31 | temp[{i,j}] = 100; 32 | } 33 | }); 34 | }); 35 | 36 | // compute simulation steps 37 | for(int t=0; t 2 | 3 | #include "allscale/api/user/save_to_binary.h" 4 | 5 | namespace allscale { 6 | namespace api { 7 | namespace user { 8 | 9 | #define outerSize 5ul 10 | #define innerSize 8ul 11 | 12 | void check(std::vector> original, std::vector> loaded) { 13 | EXPECT_EQ(outerSize, loaded.size()); 14 | 15 | for(size_t i = 0; i < outerSize; ++i) { 16 | EXPECT_EQ(innerSize, loaded[i].size()); 17 | 18 | for(size_t j = 0; j < innerSize; ++j) 19 | EXPECT_EQ(original[i][j], loaded[i][j]); 20 | } 21 | } 22 | 23 | TEST(SaveToBinary, ArtificialVectorOfVectors) { 24 | 25 | std::vector> vecVec; 26 | std::string filename("testfile.dat"); 27 | 28 | // generate arbitrary data 29 | for(size_t i = 0; i < outerSize; ++i) { 30 | vecVec.push_back(std::vector()); 31 | 32 | for(size_t j = 0; j < innerSize; ++j) 33 | vecVec[i].push_back((0.3+i)*j); 34 | } 35 | 36 | // stream 37 | saveVecVecToFile(vecVec, filename, innerSize); 38 | 39 | std::vector> loaded = readVecVecFromFile(filename, outerSize, innerSize); 40 | 41 | check(vecVec, loaded); 42 | EXPECT_EQ(0, std::remove(filename.c_str())); 43 | 44 | #ifndef _MSC_VER 45 | 46 | // memory mapped io 47 | saveVecVecToFileMM(vecVec, filename, outerSize, innerSize); 48 | loaded = readVecVecFromFileMM(filename, outerSize, innerSize); 49 | 50 | check(vecVec, loaded); 51 | EXPECT_EQ(0, std::remove(filename.c_str())); 52 | 53 | #endif 54 | 55 | } 56 | 57 | 58 | } // end namespace user 59 | } // end namespace api 60 | } // end namespace allscale 61 | -------------------------------------------------------------------------------- /code/tutorials/src/heat_stencil/04_pfor_collapsed.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "allscale/api/user/data/static_grid.h" 6 | #include "allscale/api/user/algorithm/pfor.h" 7 | 8 | using namespace allscale::api::user; 9 | using namespace allscale::api::user::algorithm; 10 | 11 | 12 | int main() { 13 | 14 | const int N = 200; 15 | const int T = 100; 16 | 17 | const double k = 0.001; 18 | 19 | using Grid = data::StaticGrid; 20 | using Point = Grid::coordinate_type; 21 | 22 | Grid bufferA; 23 | Grid bufferB; 24 | 25 | // initialize temperature 26 | Grid& temp = bufferA; 27 | pfor(Point{0,0},Point{N,N},[&](const Point& p){ 28 | temp[p] = 0; 29 | 30 | // one hot spot in the center 31 | if (p.x == N/2 && p.y == N/2) { 32 | temp[p] = 100; 33 | } 34 | }); 35 | 36 | Grid* A = &bufferA; 37 | Grid* B = &bufferB; 38 | 39 | // compute simulation steps 40 | for(int t=0; t 2 | #include 3 | #include 4 | 5 | #include "allscale/api/user/data/adaptive_grid.h" 6 | #include "allscale/api/user/data/grid.h" 7 | 8 | using namespace allscale::api::user; 9 | 10 | using TwoLayerCellConfig = data::CellConfig<2, data::layers>>; 11 | using AGrid = data::AdaptiveGrid; 12 | using Cell = typename AGrid::element_type; 13 | 14 | class WaveLog { 15 | public: 16 | WaveLog(std::ostream& out, int rows, int columns) { 17 | out << "t"; 18 | 19 | for(int i = 0; i < rows; i++) { 20 | for(int j = 0; j < columns; j++) { 21 | out << "," << i << ":" << j << ""; 22 | } 23 | } 24 | out << std::endl; 25 | }; 26 | 27 | void print(std::ostream& out, double t, const AGrid& grid) { 28 | out << t; 29 | for(int i = 0; i < grid.size()[0] * 2; i++) { 30 | for(int j = 0; j < grid.size()[1] * 2; j++) { 31 | const Cell& cell = grid[{i / 2, j / 2}]; 32 | if(cell.getActiveLayer() == 0) { 33 | out << "," << cell[{i % 2, j % 2}]; 34 | } 35 | else { 36 | out << "," << cell[{0, 0}]; 37 | } 38 | } 39 | } 40 | out << std::endl; 41 | }; 42 | 43 | void print(std::ostream& out, double t, const data::Grid& grid) { 44 | out << t; 45 | for(int i = 0; i < grid.size()[0]; i++) { 46 | for(int j = 0; j < grid.size()[1]; j++) { 47 | out << "," << grid[{i, j}]; 48 | } 49 | } 50 | out << std::endl; 51 | }; 52 | 53 | }; -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/serializer/unordered_maps.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef ALLSCALE_WITH_HPX 4 | #include "allscale/utils/serializer.h" 5 | #endif 6 | 7 | #include 8 | 9 | namespace allscale { 10 | namespace utils { 11 | 12 | /** 13 | * Add support for serializing / de-serializing std::unordered_maps. 14 | */ 15 | template 16 | struct serializer,typename std::enable_if::value && is_serializable::value,void>::type> { 17 | 18 | static std::unordered_map load(ArchiveReader& reader) { 19 | 20 | // create the result 21 | std::unordered_map res; 22 | 23 | // get the number of key/value pairs 24 | std::size_t numElements = reader.read(); 25 | 26 | // make space 27 | res.reserve(numElements); 28 | 29 | // load all the pairs 30 | for(std::size_t i = 0; i < numElements; ++i) { 31 | const auto& key = reader.read(); 32 | const auto& value = reader.read(); 33 | res.emplace(std::move(key), std::move(value)); 34 | } 35 | 36 | // done 37 | return res; 38 | } 39 | static void store(ArchiveWriter& writer, const std::unordered_map& value) { 40 | 41 | // start with the size 42 | writer.write(value.size()); 43 | 44 | // followed by all pairs 45 | for(const auto& element : value) { 46 | writer.write(element.first); 47 | writer.write(element.second); 48 | } 49 | } 50 | }; 51 | 52 | } // end namespace utils 53 | } // end namespace allscale 54 | -------------------------------------------------------------------------------- /code/tutorials/src/heat_stencil/00_c_style.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | double** allocateMemory(const int N) { 6 | double** res = new double*[N]; 7 | double* buffer = new double[N*N]; 8 | for(int i = 0; i 2 | 3 | #include "allscale/api/core/impl/reference/lock.h" 4 | 5 | namespace allscale { 6 | namespace api { 7 | namespace core { 8 | namespace impl { 9 | namespace reference { 10 | 11 | TEST(OptimisticReadWriteLock, ReadOnly) { 12 | 13 | OptimisticReadWriteLock lock; 14 | 15 | // simulate a successful read operation 16 | for(int i=0; i<10000; ++i) { 17 | auto lease = lock.start_read(); 18 | EXPECT_TRUE(lock.validate(lease)); 19 | } 20 | 21 | } 22 | 23 | TEST(OptimisticReadWriteLock, ReadWrite) { 24 | 25 | OptimisticReadWriteLock lock; 26 | 27 | // simulate a successful a read and and upgrade to write operation 28 | for(int i=0; i<10000; ++i) { 29 | // start a read 30 | auto lease = lock.start_read(); 31 | 32 | // upgrade to a write operation 33 | EXPECT_TRUE(lock.try_upgrade_to_write(lease)); 34 | 35 | // end the write operation 36 | lock.end_write(); 37 | } 38 | 39 | } 40 | 41 | TEST(OptimisticReadWriteLock, ReadWriteInterleaving) { 42 | 43 | OptimisticReadWriteLock lock; 44 | 45 | auto& lockA = lock; 46 | auto& lockB = lock; 47 | 48 | // simulate the interleaving 49 | 50 | auto leaseA = lockA.start_read(); 51 | auto leaseB = lockB.start_read(); 52 | 53 | // update one to write 54 | EXPECT_TRUE(lockA.try_upgrade_to_write(leaseA)); 55 | EXPECT_FALSE(lockB.try_upgrade_to_write(leaseB)); 56 | 57 | // finish writing 58 | lockA.end_write(); 59 | 60 | EXPECT_FALSE(lockB.validate(leaseB)); 61 | leaseB = lockB.start_read(); 62 | 63 | EXPECT_TRUE(lockB.try_upgrade_to_write(leaseB)); 64 | lockB.end_write(); 65 | } 66 | 67 | } // end namespace reference 68 | } // end namespace impl 69 | } // end namespace core 70 | } // end namespace api 71 | } // end namespace allscale 72 | -------------------------------------------------------------------------------- /code/tutorials/src/heat_stencil/06_stencil.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "allscale/api/user/data/static_grid.h" 6 | #include "allscale/api/user/algorithm/stencil.h" 7 | 8 | using namespace allscale::api::user; 9 | using namespace allscale::api::user::algorithm; 10 | 11 | 12 | int main() { 13 | 14 | const int N = 200; 15 | const int T = 100; 16 | 17 | const double k = 0.001; 18 | 19 | using Grid = data::StaticGrid; 20 | using Point = Grid::coordinate_type; 21 | 22 | Grid temp; 23 | 24 | // initialize temperature 25 | pfor(Point{N,N},[&](const Point& p){ 26 | temp[p] = 0; 27 | 28 | // one hot spot in the center 29 | if (p.x == N/2 && p.y == N/2) { 30 | temp[p] = 100; 31 | } 32 | }); 33 | 34 | // compute simulation steps 35 | stencil(temp,T, 36 | // inner elements 37 | [k,T,N](time_t, const Point& p, const Grid& temp)->double { 38 | return temp[p] + k * ( 39 | temp[p+Point{-1,0}] + 40 | temp[p+Point{+1,0}] + 41 | temp[p+Point{0,-1}] + 42 | temp[p+Point{0,+1}] + 43 | (-4)*temp[p] 44 | ); 45 | }, 46 | // boundaries 47 | [k,T,N](time_t, const Point&, const Grid&)->double { 48 | // boundaries are constants 49 | return 0; 50 | }, 51 | // an observer 52 | observer( 53 | [T](time_t t){ return (t % (T/10)) == 0; }, 54 | [N](const Point& p){ return p.x == N/2 && p.y == N/2; }, 55 | [](time_t t, const Point&, double value){ 56 | std::cout << "t=" << t << " - center: " << value << std::endl; 57 | } 58 | ) 59 | ); 60 | 61 | // print end state 62 | std::cout << "t=" << T << " - center: " << temp[Point{N/2,N/2}] << std::endl; 63 | 64 | // check whether computation was successful 65 | return (temp[Point{N/2,N/2}] < 69) ? EXIT_SUCCESS : EXIT_FAILURE; 66 | } 67 | -------------------------------------------------------------------------------- /code/utils/test/static_map.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "allscale/utils/static_map.h" 4 | #include "allscale/utils/string_utils.h" 5 | 6 | #include "allscale/utils/printer/vectors.h" 7 | 8 | namespace allscale { 9 | namespace utils { 10 | 11 | struct A {}; 12 | struct B {}; 13 | struct C {}; 14 | 15 | TEST(StaticMap,Size) { 16 | 17 | EXPECT_LE(sizeof(StaticMap,int>),4); 18 | EXPECT_EQ(sizeof(int)*1,sizeof(StaticMap,int>)); 19 | EXPECT_EQ(sizeof(int)*2,sizeof(StaticMap,int>)); 20 | EXPECT_EQ(sizeof(int)*3,sizeof(StaticMap,int>)); 21 | 22 | } 23 | 24 | TEST(StaticMap,Basic) { 25 | 26 | StaticMap,int> map; 27 | 28 | EXPECT_EQ(sizeof(int)*3,sizeof(map)); 29 | 30 | auto& valA = map.get(); 31 | auto& valB = map.get(); 32 | auto& valC = map.get(); 33 | 34 | valA = 12; 35 | valB = 14; 36 | valC = 16; 37 | 38 | EXPECT_EQ(12,map.get()); 39 | EXPECT_EQ(14,map.get()); 40 | EXPECT_EQ(16,map.get()); 41 | 42 | EXPECT_NE(&map.get(),&map.get()); 43 | 44 | } 45 | 46 | TEST(StaticMap,Constructor) { 47 | 48 | StaticMap,int> map(12); 49 | 50 | EXPECT_EQ(sizeof(int)*3,sizeof(map)); 51 | 52 | EXPECT_EQ(12,map.get()); 53 | EXPECT_EQ(12,map.get()); 54 | EXPECT_EQ(12,map.get()); 55 | 56 | } 57 | 58 | TEST(StaticMap,Iterators) { 59 | 60 | StaticMap,int> map(12); 61 | 62 | EXPECT_EQ(sizeof(int)*3,sizeof(map)); 63 | 64 | auto& valA = map.get(); 65 | auto& valB = map.get(); 66 | auto& valC = map.get(); 67 | 68 | valA = 12; 69 | valB = 14; 70 | valC = 16; 71 | 72 | std::vector res(map.begin(),map.end()); 73 | EXPECT_EQ("[12,14,16]",toString(res)); 74 | } 75 | 76 | } // end namespace utils 77 | } // end namespace allscale 78 | -------------------------------------------------------------------------------- /code/api/include/allscale/api/user/arithmetic.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | #include 6 | 7 | #include "allscale/api/core/treeture.h" 8 | 9 | 10 | namespace allscale { 11 | namespace api { 12 | namespace user { 13 | 14 | // --- specific aggregators --- 15 | 16 | 17 | template() + std::declval())> 18 | auto add(A&& a, B&& b) { 19 | return core::combine(std::move(a),std::move(b),[](const R& a, const R& b) { return a + b; }); 20 | } 21 | 22 | template() - std::declval())> 23 | auto sub(A&& a, B&& b) { 24 | return core::combine(std::move(a),std::move(b),[](const R& a, const R& b) { return a - b; }); 25 | } 26 | 27 | template() * std::declval())> 28 | auto mul(A&& a, B&& b) { 29 | return core::combine(std::move(a),std::move(b),[](const R& a, const R& b) { return a * b; }); 30 | } 31 | 32 | 33 | template(),std::declval()))> 34 | auto min(A&& a, B&& b) { 35 | return core::combine(std::move(a),std::move(b),[](const R& a, const R& b) { return std::min(a,b); }); 36 | } 37 | 38 | template(),std::declval()))> 39 | auto max(A&& a, B&& b) { 40 | return core::combine(std::move(a),std::move(b),[](const R& a, const R& b) { return std::max(a,b); }); 41 | } 42 | 43 | } // end namespace user 44 | } // end namespace api 45 | } // end namespace allscale 46 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/type_list.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace allscale { 6 | namespace utils { 7 | 8 | 9 | // -------------------- Type List traits ---------------------------- 10 | 11 | template 12 | struct type_list { 13 | enum { length = sizeof...(Ts) }; 14 | enum { empty = (length == 0) }; 15 | }; 16 | 17 | 18 | // -- test whether a given list contains a given type -- 19 | 20 | template 21 | struct type_list_contains; 22 | 23 | template 24 | struct type_list_contains> : public std::true_type {}; 25 | 26 | template 27 | struct type_list_contains> : public type_list_contains> {}; 28 | 29 | template 30 | struct type_list_contains> : public std::false_type {}; 31 | 32 | 33 | // -- extracts a type at a given position -- 34 | 35 | template 36 | struct type_at; 37 | 38 | template 39 | struct type_at<0, type_list> { 40 | typedef H type; 41 | }; 42 | 43 | template 44 | struct type_at> { 45 | typedef typename type_at>::type type; 46 | }; 47 | 48 | 49 | // -- obtains the index of a given type -- 50 | 51 | template 52 | struct type_index; 53 | 54 | template 55 | struct type_index> { 56 | enum { value = 0 }; 57 | }; 58 | 59 | template 60 | struct type_index> { 61 | enum { value = type_index>::value + 1 }; 62 | }; 63 | 64 | 65 | } // end namespace utils 66 | } // end namespace allscale 67 | -------------------------------------------------------------------------------- /scripts/dependencies/installer: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | export INSTALLER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 6 | 7 | get_property() { 8 | echo $(echo "source \"$INSTALLER_DIR/package_$1.sh\" && echo -n \$$2" | bash -) 9 | } 10 | export -f get_property 11 | 12 | resolve_dependencies() { 13 | for pkg in $1; do 14 | resolve_dependencies_for_pkg "$pkg" 15 | done | awk '!unique[$_]++' 16 | } 17 | 18 | resolve_dependencies_for_pkg() { 19 | for pkg in $(get_property $1 DEPENDS); do 20 | resolve_dependencies_for_pkg "$pkg" 21 | done 22 | echo "$1" 23 | } 24 | 25 | install_pkg() { 26 | bash - <<-EOF 27 | set -e 28 | 29 | source "$INSTALLER_DIR/defaults.sh" 30 | source "$INSTALLER_DIR/package_$1.sh" 31 | 32 | mkdir -p \$PREFIX 33 | 34 | if pkg_is_installed; then 35 | echo "\$NAME \$VERSION already installed" 36 | exit 0 37 | fi 38 | 39 | PKG_TEMP=\$(mktemp -d) 40 | pushd \$PKG_TEMP 41 | 42 | echo "#### Downloading \$PACKAGE ####" 43 | pkg_download 44 | 45 | echo "#### Extracting \$PACKAGE ####" 46 | pkg_extract 47 | 48 | pushd \$PACKAGE 49 | 50 | echo "#### Preparing \$PACKAGE ####" 51 | pkg_prepare 52 | 53 | echo "#### Configuring \$PACKAGE ####" 54 | pkg_configure 55 | 56 | echo "#### Building \$PACKAGE ####" 57 | pkg_build 58 | 59 | echo "#### Checking \$PACKAGE ####" 60 | pkg_check 61 | 62 | echo "#### Installing \$PACKAGE ####" 63 | pkg_install 64 | 65 | popd 66 | 67 | pkg_install_done 68 | 69 | echo "#### Cleaning \$PACKAGE ####" 70 | pkg_cleanup 71 | 72 | popd 73 | 74 | rmdir \$PKG_TEMP 75 | EOF 76 | } 77 | 78 | if [[ $# -eq 0 ]]; then 79 | echo "Usage: $0 ..." 80 | exit 1 81 | else 82 | PACKAGES="$@" 83 | fi 84 | 85 | PACKAGES="$(resolve_dependencies "$PACKAGES")" 86 | 87 | for pkg in $PACKAGES; do 88 | install_pkg "$pkg" 89 | done 90 | -------------------------------------------------------------------------------- /code/tutorials/src/heat_stencil/05_pfor_overlap.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "allscale/api/user/data/static_grid.h" 6 | #include "allscale/api/user/algorithm/pfor.h" 7 | 8 | using namespace allscale::api::user; 9 | using namespace allscale::api::user::algorithm; 10 | 11 | 12 | int main() { 13 | 14 | const int N = 200; 15 | const int T = 100; 16 | 17 | const double k = 0.001; 18 | 19 | using Grid = data::StaticGrid; 20 | using Point = Grid::coordinate_type; 21 | 22 | Grid bufferA; 23 | Grid bufferB; 24 | 25 | // initialize temperature 26 | Grid& temp = bufferA; 27 | auto ref = pfor(Point{0,0},Point{N,N},[&](const Point& p){ 28 | temp[p] = 0; 29 | 30 | // one hot spot in the center 31 | if (p.x == N/2 && p.y == N/2) { 32 | temp[p] = 100; 33 | } 34 | }); 35 | 36 | Grid* A = &bufferA; 37 | Grid* B = &bufferB; 38 | 39 | // compute simulation steps 40 | for(int t=0; t 4 | #include 5 | #include 6 | 7 | namespace allscale { 8 | namespace utils { 9 | 10 | namespace detail { 11 | 12 | template 13 | struct get_size { 14 | std::size_t operator()(const Iter& a, const Iter& b) { 15 | return std::distance(a,b); 16 | } 17 | }; 18 | 19 | template 20 | struct get_size { 21 | std::size_t operator()(const T* a, const T* b) { 22 | return b - a; 23 | } 24 | }; 25 | } 26 | 27 | 28 | template 29 | struct range { 30 | Iter _begin; 31 | Iter _end; 32 | 33 | using value_type = typename std::iterator_traits::value_type; 34 | 35 | Iter begin() const { 36 | return _begin; 37 | } 38 | 39 | Iter end() const { 40 | return _end; 41 | } 42 | 43 | bool empty() const { 44 | return _begin == _end; 45 | } 46 | 47 | std::size_t size() const { 48 | return detail::get_size()(_begin,_end); 49 | } 50 | 51 | const value_type& front() const { 52 | return *_begin; 53 | } 54 | 55 | const value_type& back() const { 56 | return *(_end - 1); 57 | } 58 | }; 59 | 60 | template 61 | bool operator==(const std::vector& data, const range& range) { 62 | if (data.size() != range.size()) return false; 63 | return std::equal(data.begin(), data.end(), range.begin()); 64 | } 65 | 66 | template 67 | bool operator==(const range& range, const std::vector& data) { 68 | return data == range; 69 | } 70 | 71 | template 72 | bool operator!=(const std::vector& data, const range& range) { 73 | return !(data == range); 74 | } 75 | 76 | template 77 | bool operator!=(const range& range, const std::vector& data) { 78 | return data != range; 79 | } 80 | 81 | } // end namespace utils 82 | } // end namespace allscale 83 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/serializer/tuple.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "allscale/utils/serializer.h" 4 | 5 | #include 6 | 7 | #include "allscale/utils/tuple_utils.h" 8 | 9 | namespace allscale { 10 | namespace utils { 11 | 12 | /** 13 | * No tuple is trivially serializable, since object layout is unspecified. 14 | */ 15 | template 16 | struct is_trivially_serializable, void> : public std::false_type {}; 17 | 18 | 19 | namespace detail { 20 | 21 | // a utility assisting in loading non-trivial tuples from stream 22 | 23 | template 24 | struct load_helper { 25 | 26 | using inner = load_helper; 27 | 28 | template 29 | std::tuple operator()(ArchiveReader& in, Cur&& ... cur) const { 30 | using cur_t = std::remove_reference_t(std::declval>()))>; 31 | return inner{}(in,std::move(cur)...,in.read()); 32 | } 33 | 34 | }; 35 | 36 | template 37 | struct load_helper<0,Args...> { 38 | 39 | std::tuple operator()(ArchiveReader&, Args&& ... args) const { 40 | return std::make_tuple(std::move(args)...); 41 | } 42 | 43 | }; 44 | 45 | } 46 | 47 | 48 | /** 49 | * Add support for serializing / de-serializing tuples of non-trivial element types. 50 | */ 51 | template 52 | struct serializer,typename std::enable_if::value,void>::type> { 53 | 54 | static std::tuple load(ArchiveReader& reader) { 55 | return detail::load_helper{}(reader); 56 | } 57 | 58 | 59 | static void store(ArchiveWriter& writer, const std::tuple& value) { 60 | forEach(value,[&](const auto& cur){ 61 | writer.write(cur); 62 | }); 63 | } 64 | }; 65 | 66 | 67 | } // end namespace utils 68 | } // end namespace allscale 69 | -------------------------------------------------------------------------------- /code/utils/test/optional.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "allscale/utils/optional.h" 6 | #include "allscale/utils/string_utils.h" 7 | 8 | namespace allscale { 9 | namespace utils { 10 | 11 | TEST(Optional,Basics) { 12 | 13 | using opt_type = optional; 14 | 15 | EXPECT_TRUE(std::is_copy_constructible::value); 16 | EXPECT_TRUE(std::is_move_constructible::value); 17 | 18 | EXPECT_TRUE(std::is_copy_assignable::value); 19 | EXPECT_TRUE(std::is_move_assignable::value); 20 | 21 | EXPECT_TRUE(std::is_destructible::value); 22 | 23 | } 24 | 25 | TEST(Optional, Copy) { 26 | 27 | using opt_t = optional; 28 | 29 | opt_t none; 30 | opt_t zero = 0; 31 | opt_t one = 1; 32 | 33 | EXPECT_FALSE(bool(none)); 34 | EXPECT_TRUE(bool(zero)); 35 | EXPECT_TRUE(bool(one)); 36 | 37 | EXPECT_LT(none,zero); 38 | EXPECT_LT(zero,one); 39 | 40 | EXPECT_EQ(none,none); 41 | EXPECT_EQ(zero,zero); 42 | EXPECT_EQ(one,one); 43 | 44 | opt_t cpy = one; 45 | 46 | EXPECT_TRUE(bool(cpy)); 47 | EXPECT_TRUE(bool(one)); 48 | EXPECT_EQ(one,cpy); 49 | } 50 | 51 | TEST(Optional, Move) { 52 | 53 | using opt_t = optional; 54 | 55 | opt_t one = 1; 56 | 57 | opt_t mov = std::move(one); 58 | 59 | EXPECT_TRUE(bool(mov)); 60 | EXPECT_FALSE(bool(one)); 61 | EXPECT_EQ(1,*mov); 62 | } 63 | 64 | 65 | TEST(Optional, Int) { 66 | 67 | using opt_t = optional; 68 | 69 | opt_t none; 70 | opt_t zero = 0; 71 | opt_t one = 1; 72 | 73 | EXPECT_FALSE(bool(none)); 74 | EXPECT_TRUE(bool(zero)); 75 | EXPECT_TRUE(bool(one)); 76 | 77 | EXPECT_LT(none,zero); 78 | EXPECT_LT(zero,one); 79 | 80 | } 81 | 82 | TEST(Optional, Print) { 83 | 84 | using opt_t = optional; 85 | 86 | EXPECT_EQ("Nothing",toString(opt_t())); 87 | EXPECT_EQ("Just(1)",toString(opt_t(1))); 88 | 89 | } 90 | 91 | } // end namespace utils 92 | } // end namespace allscale 93 | -------------------------------------------------------------------------------- /code/tutorials/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_custom_target(tutorials) 2 | add_custom_target(test_tutorials) 3 | 4 | if(MSVC) 5 | set_target_properties(tutorials PROPERTIES FOLDER tutorials) 6 | set_target_properties(test_tutorials PROPERTIES FOLDER tutorials) 7 | endif() 8 | 9 | file(GLOB tutorials RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/src src/*) 10 | foreach(tutorial ${tutorials}) 11 | add_custom_target(tutorials_${tutorial}) 12 | add_dependencies(tutorials tutorials_${tutorial}) 13 | 14 | add_custom_target(test_tutorials_${tutorial}) 15 | add_dependencies(test_tutorials test_tutorials_${tutorial}) 16 | 17 | if(MSVC) 18 | set_target_properties(tutorials_${tutorial} PROPERTIES FOLDER tutorials/${tutorial}) 19 | set_target_properties(test_tutorials_${tutorial} PROPERTIES FOLDER tutorials/${tutorial}) 20 | endif() 21 | 22 | glob_executables(tutorial_exes src/${tutorial}) 23 | foreach(exe ${tutorial_exes}) 24 | add_module_executable(tutorials ${exe} NO_LIB EXCLUDE_FROM_ALL OUTPUT_TARGET_NAME exe_tgt) 25 | 26 | # api dependency 27 | target_link_libraries(${exe_tgt} api) 28 | 29 | # pthread dependency 30 | target_link_libraries(${exe_tgt} Threads::Threads) 31 | 32 | # add to tutorials target 33 | add_dependencies(tutorials_${tutorial} ${exe_tgt}) 34 | 35 | # setup as test 36 | if(NOT MSVC) 37 | add_custom_target(${exe_tgt}_test COMMAND $) 38 | else() 39 | add_custom_target(${exe_tgt}_test COMMAND ${tutorial}/$(Configuration)/$) 40 | endif() 41 | add_dependencies(${exe_tgt}_test ${exe_tgt}) 42 | add_dependencies(test_tutorials_${tutorial} ${exe_tgt}_test) 43 | 44 | if(MSVC) 45 | set_target_properties(${exe_tgt} PROPERTIES 46 | FOLDER tutorials/${tutorial} 47 | RUNTIME_OUTPUT_DIRECTORY ${tutorial} 48 | ) 49 | set_target_properties(${exe_tgt}_test PROPERTIES 50 | FOLDER tutorials/${tutorial} 51 | RUNTIME_OUTPUT_DIRECTORY ${tutorial} 52 | ) 53 | endif() 54 | endforeach(exe) 55 | endforeach(tutorial) 56 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/serializer/arrays.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef ALLSCALE_WITH_HPX 4 | #include 5 | #endif 6 | 7 | #include "allscale/utils/serializer.h" 8 | 9 | #include 10 | 11 | namespace allscale { 12 | namespace utils { 13 | 14 | 15 | namespace detail { 16 | 17 | template 18 | struct array_load_helper { 19 | 20 | template 21 | std::array operator()(ArchiveReader& reader, Args&& ... args) { 22 | return array_load_helper()(reader,args...,reader.read()); 23 | } 24 | }; 25 | 26 | template 27 | struct array_load_helper { 28 | 29 | template 30 | std::array operator()(ArchiveReader&, Args&& ... args) { 31 | return std::array{ 32 | { args... } 33 | }; 34 | } 35 | 36 | }; 37 | 38 | } 39 | 40 | /** 41 | * Add support for serializing / de-serializing arrays of trivial element types. 42 | */ 43 | template 44 | struct is_trivially_serializable, typename std::enable_if::value>::type> : public std::true_type {}; 45 | 46 | /** 47 | * Add support for serializing / de-serializing arrays of non-trivial element types. 48 | */ 49 | template 50 | struct serializer,typename std::enable_if::value && is_serializable::value,void>::type> { 51 | 52 | static std::array load(ArchiveReader& reader) { 53 | // support loading of array for elements without default constructor 54 | return detail::array_load_helper()(reader); 55 | } 56 | static void store(ArchiveWriter& writer, const std::array& value) { 57 | for(const auto& cur : value) { 58 | writer.write(cur); 59 | } 60 | } 61 | }; 62 | 63 | } // end namespace utils 64 | } // end namespace allscale 65 | 66 | -------------------------------------------------------------------------------- /code/api/test/core/impl/reference/runtime_predictor.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include "allscale/api/core/impl/reference/runtime_predictor.h" 7 | 8 | namespace allscale { 9 | namespace api { 10 | namespace core { 11 | namespace impl { 12 | namespace reference { 13 | 14 | using duration = RuntimePredictor::duration; 15 | 16 | 17 | TEST(RuntimePredictor, Basic) { 18 | 19 | RuntimePredictor predictor; 20 | 21 | // the highest layer should run infinitely (initially) 22 | EXPECT_EQ(duration::max(),predictor.predictTime(0)); 23 | 24 | // the lowest layer should run in zero time (initially) 25 | EXPECT_EQ(duration::zero(), predictor.predictTime(RuntimePredictor::MAX_LEVELS-1)); 26 | } 27 | 28 | TEST(RuntimePredictor, Estimate) { 29 | 30 | RuntimePredictor predictor; 31 | 32 | // register a time 33 | predictor.registerTime(5,duration(64000)); 34 | 35 | EXPECT_EQ(duration(256000),predictor.predictTime(3)); 36 | EXPECT_EQ(duration(128000),predictor.predictTime(4)); 37 | EXPECT_EQ(duration(64000),predictor.predictTime(5)); 38 | EXPECT_EQ(duration(32000),predictor.predictTime(6)); 39 | EXPECT_EQ(duration(16000),predictor.predictTime(7)); 40 | 41 | predictor.registerTime(5,duration(64000)); 42 | 43 | EXPECT_EQ(duration(256000),predictor.predictTime(3)); 44 | EXPECT_EQ(duration(128000),predictor.predictTime(4)); 45 | EXPECT_EQ(duration(64000),predictor.predictTime(5)); 46 | EXPECT_EQ(duration(32000),predictor.predictTime(6)); 47 | EXPECT_EQ(duration(16000),predictor.predictTime(7)); 48 | 49 | predictor.registerTime(6,duration(64000)); 50 | 51 | EXPECT_LT(duration(256000),predictor.predictTime(3)); 52 | EXPECT_LT(duration(128000),predictor.predictTime(4)); 53 | EXPECT_LT(duration(64000),predictor.predictTime(5)); 54 | EXPECT_LT(duration(32000),predictor.predictTime(6)); 55 | EXPECT_LT(duration(16000),predictor.predictTime(7)); 56 | 57 | } 58 | 59 | } // end namespace reference 60 | } // end namespace impl 61 | } // end namespace core 62 | } // end namespace api 63 | } // end namespace allscale 64 | -------------------------------------------------------------------------------- /scripts/setup/add_part: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 6 | TGT="$DIR/../.." 7 | 8 | render_template() { 9 | header="$TGT/code/$module/include/$project/$module/$1.h" 10 | local source="$TGT/code/$module/src/$1.cpp" 11 | local test="$TGT/code/$module/test/$1_test.cc" 12 | 13 | cp "$DIR/empty.h.tpl" "$header" 14 | cp "$DIR/empty.cpp.tpl" "$source" 15 | 16 | for d in $(echo $part_dir | tr " /" "_ "); do 17 | local ns="namespace $d {\n%NAMESPACES%\n} // end namespace $d" 18 | sed "s#%NAMESPACES%#$ns#" -i "$header" 19 | sed "s#%NAMESPACES%#$ns#" -i "$source" 20 | done 21 | sed "s/%NAMESPACES%//" -i "$header" 22 | sed "s/%NAMESPACES%//" -i "$source" 23 | 24 | cp "$DIR/empty_test.cc.tpl" "$test" 25 | local ns=$(echo $part_dir | sed -e "s/ /_/g" -e "s/\//::/g") 26 | sed -e "s/%NAMESPACES%/$ns/" -e "s/::;/;/" -i "$test" 27 | 28 | sed -e "s/%PROJECT%/$project/g" -e "s/%MODULE%/$module/g" -e "s#%PART%#$1#g" -i "$header" 29 | sed -e "s/%PROJECT%/$project/g" -e "s/%MODULE%/$module/g" -e "s#%PART%#$1#g" -i "$source" 30 | sed -e "s/%PROJECT%/$project/g" -e "s/%MODULE%/$module/g" -e "s#%PART%#$1#g" -e "s/%PART_NAME%/$(basename "$part")/g" -i "$test" 31 | } 32 | 33 | if [[ $# -lt 3 || "$1" == "-h" || "$1" == "--help" ]]; then 34 | echo "Usage: $0 ..." 35 | echo 36 | echo -e "\tExamples:" 37 | echo -e "\t\t$0 my_project my_module foo" 38 | echo -e "\t\t$0 my_project my_module foo/bar/baz" 39 | exit 1 40 | fi 41 | 42 | # parts remain in $@ 43 | project="$1" 44 | module="$2" 45 | shift 2 46 | 47 | # check project and module name 48 | if [[ ! -d "$TGT/code/$module/include/$project/$module" ]]; then 49 | echo "Double check project-name / module-name" 1>&2 50 | exit 1 51 | fi 52 | 53 | for part in "$@"; do 54 | part_dir=$(dirname "$part") 55 | if [[ "$part_dir" == "." ]]; then 56 | part_dir="" 57 | else 58 | part_dir="$part_dir/" 59 | fi 60 | 61 | mkdir -p "$TGT/code/$module/include/$project/$module/$part_dir" 62 | mkdir -p "$TGT/code/$module/src/$part_dir" 63 | mkdir -p "$TGT/code/$module/test/$part_dir" 64 | 65 | render_template "$part" 66 | done 67 | 68 | touch "$TGT/code/CMakeLists.txt" 69 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/serializer/vectors.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef ALLSCALE_WITH_HPX 4 | #include "allscale/utils/serializer.h" 5 | #endif 6 | 7 | #include 8 | 9 | #include "allscale/utils/serializer/arrays.h" 10 | 11 | namespace allscale { 12 | namespace utils { 13 | 14 | /** 15 | * Add support for serializing / de-serializing std::vectors. 16 | */ 17 | template 18 | struct serializer,typename std::enable_if::value,void>::type> { 19 | 20 | static std::vector load(ArchiveReader& reader) { 21 | 22 | // create the result 23 | std::vector res; 24 | 25 | // load the size 26 | auto size = reader.read(); 27 | 28 | // load all in one step 29 | res.resize(size); 30 | reader.read(&res[0],size); 31 | 32 | // done 33 | return res; 34 | } 35 | static void store(ArchiveWriter& writer, const std::vector& value) { 36 | 37 | // start with the size 38 | writer.write(value.size()); 39 | 40 | // followed by all the elements 41 | writer.write(&value[0],value.size()); 42 | } 43 | }; 44 | 45 | 46 | /** 47 | * Add support for serializing / de-serializing std::vectors. 48 | */ 49 | template 50 | struct serializer,typename std::enable_if::value && is_serializable::value,void>::type> { 51 | 52 | static std::vector load(ArchiveReader& reader) { 53 | 54 | // create the result 55 | std::vector res; 56 | 57 | // load the size 58 | auto size = reader.read(); 59 | 60 | // make some space 61 | res.reserve(size); 62 | 63 | // load the elements 64 | for(std::size_t i=0; i()); 66 | } 67 | 68 | // done 69 | return res; 70 | } 71 | static void store(ArchiveWriter& writer, const std::vector& value) { 72 | 73 | // start with the size 74 | writer.write(value.size()); 75 | 76 | // followed by all the elements 77 | writer.write(&value[0],value.size()); 78 | } 79 | }; 80 | 81 | } // end namespace utils 82 | } // end namespace allscale 83 | -------------------------------------------------------------------------------- /code/tutorials/src/io/00_io.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "allscale/api/user/data/static_grid.h" 4 | #include "allscale/api/core/io.h" 5 | 6 | using namespace allscale::api::user; 7 | using namespace allscale::api::core; 8 | 9 | // -- size of the grid -- 10 | const int size = 10; 11 | 12 | // -- files that store the data -- 13 | const std::string binary_filename = "binary"; 14 | const std::string text_filename = "text"; 15 | 16 | // -- grid -- 17 | using Grid = data::StaticGrid; 18 | 19 | // -- store -- 20 | void store() { 21 | Grid grid; 22 | 23 | // -- initialize the grid -- 24 | algorithm::pfor(Grid::coordinate_type{}, grid.size(), [&](const auto& p){ 25 | grid[p] = (int)(p[0] * size + p[1]); 26 | }); 27 | 28 | // -- store the grid -- 29 | FileIOManager& manager = FileIOManager::getInstance(); 30 | 31 | Entry binary = manager.createEntry(binary_filename, Mode::Binary); 32 | 33 | auto output_stream = manager.openOutputStream(binary); 34 | 35 | // write data to file in parallel 36 | algorithm::pfor(Grid::coordinate_type{}, grid.size(), [&](const auto& p){ 37 | output_stream.atomic([&](auto& out) { 38 | out.write(p); 39 | out.write(grid[p]); 40 | }); 41 | }); 42 | 43 | manager.close(output_stream); 44 | } 45 | 46 | // -- load -- 47 | void load() { 48 | Grid grid; 49 | 50 | FileIOManager& manager = FileIOManager::getInstance(); 51 | 52 | Entry binary = manager.createEntry(binary_filename, Mode::Binary); 53 | 54 | // -- read data -- 55 | auto in = manager.openInputStream(binary); 56 | for(int i = 0; i < size * size; i++) { 57 | auto coord = in.read(); 58 | auto count = in.read(); 59 | grid[coord] = count; 60 | } 61 | 62 | // -- write data ordered -- 63 | Entry text = manager.createEntry(text_filename, Mode::Text); 64 | 65 | auto output_stream_text = manager.openOutputStream(text); 66 | 67 | for(int i = 0; i < size; i++) { 68 | for(int j = 0; j < size; j++) { 69 | output_stream_text << grid[{i, j}]; 70 | if(j != size - 1) 71 | output_stream_text << ", "; 72 | } 73 | output_stream_text << "\n"; 74 | } 75 | 76 | // remove the created files 77 | manager.remove(binary); 78 | manager.remove(text); 79 | 80 | } 81 | 82 | int main() { 83 | 84 | // -- generate a grid and store it -- 85 | store(); 86 | 87 | // -- load the grid, structure it and store it again -- 88 | load(); 89 | 90 | return EXIT_SUCCESS; 91 | } 92 | -------------------------------------------------------------------------------- /code/api/include/allscale/api/user/algorithm/async.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "allscale/utils/assert.h" 6 | 7 | #include "allscale/api/core/prec.h" 8 | 9 | namespace allscale { 10 | namespace api { 11 | namespace user { 12 | namespace algorithm { 13 | 14 | 15 | 16 | // --------------------------------------------------------------------------------------------- 17 | // Declarations 18 | // --------------------------------------------------------------------------------------------- 19 | 20 | 21 | /** 22 | * A simple job wrapper processing a given task asynchronously. The task 23 | * is wrapped to a simple recursion where there is a single base 24 | * case step. 25 | * 26 | * @tparam Action the type of action 27 | * @param action the action to be processed 28 | * @return a treeture providing a reference the the result 29 | */ 30 | template 31 | core::treeture> async(const Action& action); 32 | 33 | 34 | /** 35 | * A simple job wrapper processing a given task asynchronously after the 36 | * given dependencies are satisfied. The task is wrapped to a simple recursion 37 | * where there is a single base case step. 38 | * 39 | * @tparam Dependencies the dependencies to await 40 | * @tparam Action the type of action 41 | * @param action the action to be processed 42 | * @return a treeture providing a reference the the result 43 | */ 44 | template 45 | core::treeture> async(Dependencies&& deps, const Action& action); 46 | 47 | 48 | 49 | 50 | // --------------------------------------------------------------------------------------------- 51 | // Definitions 52 | // --------------------------------------------------------------------------------------------- 53 | 54 | 55 | template 56 | core::treeture> async(const Action& action) { 57 | return async(core::after(), action); 58 | } 59 | 60 | 61 | template 62 | core::treeture> async(Dependencies&& deps, const Action& action) { 63 | struct empty {}; 64 | return core::prec( 65 | [](empty){ return true; }, 66 | [=](empty){ 67 | return action(); 68 | }, 69 | [=](empty,const auto&){ 70 | assert_fail() << "Should not be reached!"; 71 | return action(); 72 | } 73 | )(std::move(deps), empty()); 74 | } 75 | 76 | 77 | } // end namespace algorithm 78 | } // end namespace user 79 | } // end namespace api 80 | } // end namespace allscale 81 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/vector_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace allscale { 6 | namespace utils { 7 | 8 | namespace { 9 | 10 | /** 11 | * The terminal case of a function where a variable number of arguments is written into a vector in proper order. 12 | * 13 | * @tparam T the element type maintained within the extended vector 14 | * @param vector the vector to which nothing is written to 15 | */ 16 | template 17 | inline void appendToVector(std::vector&) {} 18 | 19 | /** 20 | * A variable-argument function writing elements into a vector in the given order. 21 | * 22 | * @tparam T the type of element maintained within the modified vector 23 | * @tparam Elements the types of the remaining elements (need to be convertible to T) 24 | * @param vector the vector to be written to 25 | * @param first the next element to be added 26 | * @param rest the remaining elements to be added 27 | */ 28 | template 29 | inline void appendToVector(std::vector& vector, const T& first, const Elements& ... rest) { 30 | vector.push_back(first); 31 | appendToVector(vector, rest...); 32 | } 33 | 34 | } 35 | 36 | /** 37 | * Create an empty vector containing no elements. 38 | * 39 | * @tparam T the type of element to be stored in the resulting vector 40 | * @return the resulting vector 41 | */ 42 | template 43 | inline std::vector toVector() { 44 | return std::vector (); 45 | } 46 | 47 | /** 48 | * Creates a vector containing the given elements. 49 | * 50 | * @tparam T the type of element to be stored in the resulting vector 51 | * @tparam Elements the types of the remaining elements (need to be convertible to T) 52 | * @param first the first element to be within the list 53 | * @param rest the remaining elements to be stored within the list 54 | * @return the resulting vector 55 | */ 56 | template 57 | inline std::vector toVector(const T& first, const Elements& ... rest) { 58 | std::vector res; 59 | res.reserve(1 + sizeof...(rest)); 60 | appendToVector(res, first, rest...); 61 | return res; 62 | } 63 | 64 | 65 | template 66 | struct is_vector : public std::false_type {}; 67 | 68 | template 69 | struct is_vector> : public std::true_type {}; 70 | 71 | template 72 | struct is_vector : public is_vector {}; 73 | 74 | template 75 | struct is_vector : public is_vector {}; 76 | 77 | } // end namespace utils 78 | } // end namespace allscale 79 | -------------------------------------------------------------------------------- /scripts/setup/README.md.tpl: -------------------------------------------------------------------------------- 1 | # %PROJECT% 2 | 3 | Description goes here... 4 | 5 | ## Installation 6 | 7 | ### Dependencies 8 | 9 | See `scripts/dependencies/README.md` for more details. Otherwise do 10 | 11 | $ scripts/dependencies/installer boost 12 | 13 | ### Configuration 14 | 15 | Following options can be supplied to CMake 16 | 17 | | Option | Values | 18 | | ------------------- | --------------- | 19 | | -DCMAKE_BUILD_TYPE | Release / Debug | 20 | | -DBUILD_SHARED_LIBS | ON / OFF | 21 | | -DBUILD_TESTS | ON / OFF | 22 | | -DBUILD_DOCS | ON / OFF | 23 | | -DBUILD_COVERAGE | ON / OFF | 24 | | -DUSE_ASSERT | ON / OFF | 25 | | -DUSE_VALGRIND | ON / OFF | 26 | | -DTHIRD_PARTY_DIR | \ | 27 | 28 | The files `cmake/build_settings.cmake` and `code/CMakeLists.txt` state their 29 | default value. 30 | 31 | ### Building / Testing 32 | 33 | $ mkdir build 34 | $ cd build 35 | $ ../scripts/dependencies/third_party_linker 36 | $ cmake ../code 37 | $ make -j8 38 | $ ctest -j8 39 | 40 | ## Development 41 | 42 | ### Adding new Modules 43 | 44 | The setup script can be run again to add new modules, just provide the same 45 | project name. 46 | 47 | $ scripts/setup/run %PROJECT% frontend backend utils 48 | 49 | ### Adding new Parts to Modules 50 | 51 | There is a utility script to add new *parts* to an existing module. The project 52 | name and module name must be provided followed by a list of *parts* to 53 | generate. Folders will be created along the way. 54 | 55 | $ scripts/setup/add_part %PROJECT% frontend sema extensions/malloc_extension 56 | 57 | This will add the files `sema.h`, `sema.cpp` and `sema_test.cc` to the 58 | *frontend* module. Furthermore new subfolders `extensions` will be created 59 | containing `malloc_extension.h`, `malloc_extension.cpp` and 60 | `malloc_extension_test.cc` in their respective subdirectories. 61 | 62 | ### Executable Bit 63 | 64 | When working on Windows via SMB share, consider setting following Git setting. 65 | 66 | $ git config core.filemode false 67 | 68 | ### Licensor 69 | 70 | A script, together with a Git hook, is provided to automatically add a license 71 | header to each source file upon commit. See `scripts/license`. 72 | 73 | ### Visual Studio Solution 74 | 75 | $ cmake -G "Visual Studio 15 2017 Win64" -DBUILD_SHARED_LIBS=OFF Z:\path\to\project 76 | 77 | Add path for third-party libraries when needed. 78 | 79 | ### Coverage 80 | 81 | Building the coverage us currently only supported on Linux, as Perl and Bash 82 | are required. To build and view the coverage set the corresponding CMake flag 83 | to `ON` and run: 84 | 85 | $ make 86 | $ make coverage 87 | $ xdg-open coverage/index.html 88 | -------------------------------------------------------------------------------- /cmake/dependencies/googletest.cmake: -------------------------------------------------------------------------------- 1 | if(BUILD_TESTS AND NOT TARGET googletest) 2 | include(ExternalProject) 3 | 4 | if(MSVC) 5 | # disable checked iterators 6 | set(_additional_c_flags /D_ITERATOR_DEBUG_LEVEL=0) 7 | set(_additional_cxx_flags /D_ITERATOR_DEBUG_LEVEL=0) 8 | # disable warning regarding deprecated tr1 namespace (introduced with MSVC 2017 15.5.1) 9 | set(_additional_c_flags "${_additional_c_flags} /D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1") 10 | set(_additional_cxx_flags "${_additional_cxx_flags} /D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1") 11 | 12 | set(_additional_flags -DCMAKE_C_FLAGS=${_additional_c_flags} -DCMAKE_CXX_FLAGS=${_additional_cxx_flags}) 13 | endif() 14 | 15 | if(BUILD_SHARED_LIBS) 16 | set(_prefix ${CMAKE_SHARED_LIBRARY_PREFIX}) 17 | set(_suffix ${CMAKE_SHARED_LIBRARY_SUFFIX}) 18 | set(_linking SHARED) 19 | else() 20 | set(_prefix ${CMAKE_STATIC_LIBRARY_PREFIX}) 21 | set(_suffix ${CMAKE_STATIC_LIBRARY_SUFFIX}) 22 | set(_linking STATIC) 23 | endif() 24 | 25 | # gtest should be build with the same compiler as the project using it 26 | ExternalProject_Add( 27 | googletest 28 | URL http://insieme-compiler.org/ext_libs/gtest-1.8.0.tar.gz 29 | URL_HASH SHA256=58a6f4277ca2bc8565222b3bbd58a177609e9c488e8a72649359ba51450db7d8 30 | INSTALL_COMMAND "" 31 | CMAKE_ARGS ${CMAKE_EXTERNALPROJECT_FORWARDS} ${_additional_flags} 32 | BUILD_BYPRODUCTS 33 | /googlemock/gtest/${LIBRARY_OUTPUT_DIRECTORY}/${_prefix}gtest${_suffix} 34 | /googlemock/gtest/${LIBRARY_OUTPUT_DIRECTORY}/${_prefix}gtest_main${_suffix} 35 | DOWNLOAD_NO_PROGRESS 1 36 | EXCLUDE_FROM_ALL 1 37 | ) 38 | ExternalProject_Get_Property(googletest source_dir binary_dir) 39 | 40 | # workaround https://itk.org/Bug/view.php?id=15052 41 | file(MAKE_DIRECTORY ${source_dir}/googletest/include) 42 | 43 | if(MSVC) 44 | set(GTEST_LIBRARY_PATH ${binary_dir}/googlemock/gtest/$(Configuration)) 45 | else() 46 | set(GTEST_LIBRARY_PATH ${binary_dir}/googlemock/gtest/${LIBRARY_OUTPUT_DIRECTORY}) 47 | endif() 48 | 49 | # import libgtest 50 | add_library(gtest ${_linking} IMPORTED) 51 | set(gtest ${_prefix}gtest${_suffix}) 52 | set_target_properties(gtest PROPERTIES 53 | IMPORTED_LOCATION ${GTEST_LIBRARY_PATH}/${gtest} 54 | 55 | # attach include path 56 | INTERFACE_INCLUDE_DIRECTORIES ${source_dir}/googletest/include 57 | 58 | # attach pthread dependency 59 | INTERFACE_LINK_LIBRARIES Threads::Threads 60 | ) 61 | add_dependencies(gtest googletest) 62 | 63 | # import libgtest_main 64 | add_library(gtest_main ${_linking} IMPORTED) 65 | set(gtest_main ${_prefix}gtest_main${_suffix}) 66 | set_target_properties(gtest_main PROPERTIES IMPORTED_LOCATION ${GTEST_LIBRARY_PATH}/${gtest_main}) 67 | add_dependencies(gtest_main googletest) 68 | endif() 69 | -------------------------------------------------------------------------------- /code/api/test/user/arithmetic.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | #include "allscale/api/core/treeture.h" 5 | #include "allscale/api/user/arithmetic.h" 6 | 7 | #include "allscale/utils/string_utils.h" 8 | 9 | #include "allscale/api/core/impl/sequential/treeture.h" 10 | #include "allscale/api/core/impl/reference/treeture.h" 11 | 12 | namespace allscale { 13 | namespace api { 14 | namespace user { 15 | 16 | using namespace core; 17 | 18 | namespace { 19 | 20 | template 21 | void check(const Op& op, const A& a, const B& b, const C& res) { 22 | 23 | // check all allowed combinations 24 | EXPECT_EQ(res, op(done(a),done(b)).get()); 25 | 26 | EXPECT_EQ(res, op(done(a),impl::sequential::done(b)).get()); 27 | EXPECT_EQ(res, op(done(a),impl::reference::done(b)).get()); 28 | 29 | EXPECT_EQ(res, op(impl::sequential::done(a),done(b)).get()); 30 | EXPECT_EQ(res, op(impl::sequential::done(a),impl::sequential::done(b)).get()); 31 | 32 | EXPECT_EQ(res, op(impl::reference::done(a),done(b)).get()); 33 | EXPECT_EQ(res, op(impl::reference::done(a),impl::reference::done(b)).get()); 34 | 35 | } 36 | 37 | } 38 | 39 | 40 | TEST(Arithmetic,add) { 41 | 42 | auto op = [](auto&& a, auto&& b) { 43 | return add(std::move(a),std::move(b)); 44 | }; 45 | 46 | // check with integers 47 | check(op,8,4,12); 48 | check(op,10,8,18); 49 | 50 | // and doubles 51 | check(op,1.0,2.0,3.0); 52 | 53 | // and strings 54 | check(op,std::string("ab"),std::string("cd"),std::string("abcd")); 55 | } 56 | 57 | 58 | TEST(Arithmetic,sub) { 59 | 60 | auto op = [](auto&& a, auto&& b) { 61 | return sub(std::move(a),std::move(b)); 62 | }; 63 | 64 | // check with integers 65 | check(op,8,2,6); 66 | 67 | // and doubles 68 | check(op,3.0,2.0,1.0); 69 | } 70 | 71 | TEST(Arithmetic,mul) { 72 | 73 | auto op = [](auto&& a, auto&& b) { 74 | return mul(std::move(a),std::move(b)); 75 | }; 76 | 77 | // check with integers 78 | check(op,8,2,16); 79 | 80 | // and doubles 81 | check(op,3.0,2.0,6.0); 82 | } 83 | 84 | 85 | TEST(Arithmetic,min) { 86 | 87 | auto op = [](auto&& a, auto&& b) { 88 | return min(std::move(a),std::move(b)); 89 | }; 90 | 91 | // check with integers 92 | check(op,8,2,2); 93 | 94 | // and doubles 95 | check(op,3.0,2.0,2.0); 96 | } 97 | 98 | TEST(Arithmetic,max) { 99 | 100 | auto op = [](auto&& a, auto&& b) { 101 | return max(std::move(a),std::move(b)); 102 | }; 103 | 104 | // check with integers 105 | check(op,8,2,8); 106 | 107 | // and doubles 108 | check(op,3.0,2.0,3.0); 109 | } 110 | 111 | } // end namespace user 112 | } // end namespace api 113 | } // end namespace allscale 114 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/printer/join.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace allscale { 4 | namespace utils { 5 | 6 | namespace detail { 7 | 8 | template 9 | struct DefaultElementPrinter { 10 | void operator()(std::ostream& out, const T& value) const { 11 | out << value; 12 | } 13 | }; 14 | 15 | template 16 | class joinable { 17 | 18 | Iter begin; 19 | Iter end; 20 | Sep sep; 21 | ElementPrinter printer; 22 | 23 | public: 24 | 25 | joinable(const Iter& begin, const Iter& end, const Sep& sep, const ElementPrinter& printer = ElementPrinter()) 26 | : begin(begin), end(end), sep(sep), printer(printer) {} 27 | 28 | friend 29 | std::ostream& operator<<(std::ostream& out, const joinable& j) { 30 | if (j.begin == j.end) return out; 31 | Iter cur = j.begin; 32 | j.printer(out, *cur); 33 | cur++; 34 | while(cur != j.end) { 35 | out << j.sep; 36 | j.printer(out, *cur); 37 | cur++; 38 | } 39 | return out; 40 | } 41 | 42 | }; 43 | 44 | } 45 | 46 | 47 | template::value_type> 48 | detail::joinable> join(const char* sep, const Iter& begin, const Iter& end) { 49 | return detail::joinable>(begin,end,sep); 50 | } 51 | 52 | template::value_type> 53 | detail::joinable> join(const std::string& sep, const Iter& begin, const Iter& end) { 54 | return detail::joinable>(begin,end,sep); 55 | } 56 | 57 | template 58 | auto join(const Sep& sep, const Container& c) -> decltype(join(sep, c.cbegin(), c.cend())) { 59 | return join(sep, c.cbegin(), c.cend()); 60 | } 61 | 62 | template 63 | detail::joinable join(const char* sep, const Iter& begin, const Iter& end, const Printer& printer) { 64 | return detail::joinable(begin,end,sep,printer); 65 | } 66 | 67 | template 68 | detail::joinable join(const std::string& sep, const Iter& begin, const Iter& end, const Printer& printer) { 69 | return detail::joinable(begin,end,sep,printer); 70 | } 71 | 72 | template 73 | auto join(const Sep& sep, const Container& c, const Printer& p) -> decltype(join(sep, c.cbegin(), c.cend(),p)) { 74 | return join(sep, c.cbegin(), c.cend(),p); 75 | } 76 | 77 | 78 | } // end namespace utils 79 | } // end namespace allscale 80 | -------------------------------------------------------------------------------- /code/api/test/user/data/bar_mesh.inl: -------------------------------------------------------------------------------- 1 | /** 2 | * A utility to generate meshes for bars. 3 | */ 4 | 5 | struct Vertex {}; 6 | struct Edge : public allscale::api::user::data::edge {}; 7 | struct Refine : public allscale::api::user::data::hierarchy {}; 8 | 9 | 10 | template 11 | using BarMesh = allscale::api::user::data::Mesh< 12 | allscale::api::user::data::nodes, 13 | allscale::api::user::data::edges, 14 | allscale::api::user::data::hierarchies, 15 | levels, 16 | partitionDepth 17 | >; 18 | 19 | template 20 | using BarMeshBuilder = allscale::api::user::data::MeshBuilder,allscale::api::user::data::edges,allscale::api::user::data::hierarchies,levels>; 21 | 22 | namespace detail { 23 | 24 | template 25 | void createLevelVertices(BarMeshBuilder& builder, unsigned numVertices) { 26 | 27 | // insert vertices 28 | auto vertices = builder.template create(numVertices); 29 | assert_eq(numVertices,vertices.size()); 30 | 31 | // connect vertices through edges 32 | for(unsigned i = 1; i < numVertices; ++i) { 33 | builder.template link(vertices[i],vertices[i-1]); 34 | } 35 | 36 | for(unsigned i = 0; i < numVertices - 1; ++i) { 37 | builder.template link(vertices[i],vertices[i+1]); 38 | } 39 | 40 | } 41 | 42 | 43 | template 44 | struct BarMeshLevelBuilder { 45 | 46 | template 47 | void operator()(BarMeshBuilder& builder, unsigned numVertices) { 48 | createLevelVertices(builder,numVertices); 49 | BarMeshLevelBuilder()(builder,numVertices * 2); 50 | 51 | // connect hierarchical edges 52 | for(unsigned i = 0; i( 54 | allscale::api::user::data::NodeRef(i), 55 | allscale::api::user::data::NodeRef(2*i) 56 | ); 57 | 58 | builder.template link( 59 | allscale::api::user::data::NodeRef(i), 60 | allscale::api::user::data::NodeRef(2*i+1) 61 | ); 62 | } 63 | } 64 | 65 | }; 66 | 67 | template<> 68 | struct BarMeshLevelBuilder<0> { 69 | 70 | template 71 | void operator()(BarMeshBuilder& builder, unsigned numVertices) { 72 | createLevelVertices<0>(builder,numVertices); 73 | } 74 | 75 | }; 76 | 77 | 78 | } 79 | 80 | 81 | template 82 | BarMesh createBarMesh(unsigned length) { 83 | using builder_type = BarMeshBuilder; 84 | 85 | // create a mesh builder 86 | builder_type builder; 87 | 88 | // fill mesh on all levels 89 | detail::BarMeshLevelBuilder()(builder,length); 90 | 91 | // finish the mesh 92 | return std::move(builder).template build(); 93 | 94 | } 95 | -------------------------------------------------------------------------------- /code/api/test/user/algorithm/async.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include "allscale/api/user/algorithm/async.h" 9 | #include "allscale/api/core/io.h" 10 | 11 | namespace allscale { 12 | namespace api { 13 | namespace user { 14 | namespace algorithm { 15 | 16 | // --- basic async usage --- 17 | 18 | TEST(Async,Basic) { 19 | 20 | auto job = async([]{ return 12; }); 21 | EXPECT_EQ(12,job.get()); 22 | 23 | } 24 | 25 | 26 | TEST(Async,SideEffects) { 27 | 28 | std::atomic counter(0); 29 | 30 | EXPECT_EQ(0,counter.load()); 31 | core::treeture task = async([&]{ 32 | counter = 1; 33 | }); 34 | 35 | // the given task should be valid 36 | EXPECT_TRUE(task.isValid()); 37 | 38 | // wait for the task to complete 39 | task.wait(); 40 | 41 | // check whether side-effects took place 42 | EXPECT_EQ(1,counter.load()); 43 | EXPECT_TRUE(task.isDone()); 44 | 45 | } 46 | 47 | 48 | TEST(Async, Dependencies) { 49 | std::atomic counter(0); 50 | 51 | auto a = async([&]() { 52 | std::this_thread::sleep_for(std::chrono::seconds(1)); 53 | counter = 0; 54 | }); 55 | 56 | auto b = async(allscale::api::core::after(a), [&]() { 57 | ASSERT_EQ(0, counter.load()); 58 | std::this_thread::sleep_for(std::chrono::seconds(1)); 59 | counter = 1; 60 | }); 61 | 62 | auto c = async(allscale::api::core::after(b), [&]() { 63 | ASSERT_EQ(1, counter.load()); 64 | counter = 2; 65 | }); 66 | 67 | c.wait(); 68 | 69 | EXPECT_EQ(2, counter.load()); 70 | } 71 | 72 | 73 | TEST(Async,ExecuteOnce) { 74 | 75 | std::atomic counter(0); 76 | 77 | for(int i=0; i<100; i++) { 78 | EXPECT_EQ(i,counter.load()); 79 | auto job = async([&]{ 80 | counter++; 81 | }); 82 | EXPECT_TRUE(job.isValid()); 83 | job.wait(); 84 | EXPECT_EQ(i+1,counter.load()); 85 | } 86 | 87 | } 88 | 89 | TEST(Async, WriteFile) { 90 | const std::string filename("asyncTest.dat"); 91 | core::FileIOManager& manager = core::FileIOManager::getInstance(); 92 | core::Entry binary = manager.createEntry(filename, core::Mode::Binary); 93 | 94 | core::treeture asyncWrite = async([&] { 95 | // create output stream 96 | auto fout = manager.openOutputStream(binary); 97 | 98 | // write data 99 | fout.write(7); 100 | 101 | // close output stream 102 | manager.close(fout); 103 | }); 104 | 105 | // the given task should be valid 106 | EXPECT_TRUE(asyncWrite.isValid()); 107 | 108 | // wait for the task to complete 109 | asyncWrite.wait(); 110 | 111 | // check file content 112 | auto fin = manager.openInputStream(binary); 113 | EXPECT_EQ(7, fin.read()); 114 | manager.close(fin); 115 | 116 | manager.remove(binary); 117 | } 118 | 119 | } // end namespace algorithm 120 | } // end namespace user 121 | } // end namespace api 122 | } // end namespace allscale 123 | -------------------------------------------------------------------------------- /code/api/include/allscale/api/user/algorithm/internal/operation_reference.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "allscale/api/core/treeture.h" 4 | 5 | #include "allscale/utils/assert.h" 6 | 7 | namespace allscale { 8 | namespace api { 9 | namespace user { 10 | namespace algorithm { 11 | namespace internal { 12 | 13 | 14 | /** 15 | * An operation reference is an (optional) base implementation 16 | * of the return values of asynchronous operations. Unlike plain 17 | * treetures, operator references are waiting for their tasks 18 | * to be completed before destruction. 19 | */ 20 | class operation_reference { 21 | 22 | /** 23 | * The treeture wrapped by this references, which corresponds 24 | * to the root task of the asynchronously started task. 25 | */ 26 | core::treeture handle; 27 | 28 | public: 29 | 30 | /** 31 | * A simple constructor taking 'ownership' on the given treeture. 32 | */ 33 | operation_reference(core::treeture&& handle) 34 | : handle(std::move(handle)) {} 35 | 36 | /** 37 | * A default constructor, not owning or syncing on anything. 38 | */ 39 | operation_reference() {}; 40 | 41 | /** 42 | * Operation references may not be copied. 43 | */ 44 | operation_reference(const operation_reference&) = delete; 45 | 46 | /** 47 | * Operation references may be moved. 48 | */ 49 | operation_reference(operation_reference&&) = default; 50 | 51 | /** 52 | * Operation references may not be copied. 53 | */ 54 | operation_reference& operator=(const operation_reference&) = delete; 55 | 56 | /** 57 | * Operation references may be moved. 58 | */ 59 | operation_reference& operator=(operation_reference&&) = default; 60 | 61 | /** 62 | * Upon destruction, the references is waiting on the underlying 63 | * task if it is still owned. 64 | */ 65 | ~operation_reference() { 66 | // if handle is still valid, wait for its completion 67 | if (handle.isValid()) handle.wait(); 68 | } 69 | 70 | /** 71 | * A non-blocking check whether the referenced operation is done. 72 | */ 73 | bool isDone() const { 74 | return handle.isDone(); 75 | } 76 | 77 | /** 78 | * Determines whether a task is attached to this reference. 79 | */ 80 | bool isValid() const { 81 | return handle.isValid(); 82 | } 83 | 84 | /** 85 | * Disconnects the referenced task, causing this reference no longer 86 | * to wait on the given task upon destruction. 87 | * 88 | * @return returns the maintained task handle 89 | */ 90 | core::treeture detach() { 91 | return std::move(handle); 92 | } 93 | 94 | /** 95 | * Blocks until the underlying operation has been completed. 96 | */ 97 | void wait() { 98 | handle.wait(); 99 | } 100 | 101 | }; 102 | 103 | 104 | } // end namespace internal 105 | } // end namespace algorithm 106 | } // end namespace user 107 | } // end namespace api 108 | } // end namespace allscale 109 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/static_map.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "allscale/utils/type_list.h" 7 | 8 | namespace allscale { 9 | namespace utils { 10 | 11 | // -------------------------------------------------------------------- 12 | // Declarations 13 | // -------------------------------------------------------------------- 14 | 15 | 16 | /** 17 | * A static map mapping a given value to each of a given list of types. 18 | */ 19 | template 20 | class StaticMap; 21 | 22 | /** 23 | * An auxiliary type for forming lists of keys. 24 | */ 25 | template 26 | struct keys {}; 27 | 28 | 29 | // -------------------------------------------------------------------- 30 | // Definitions 31 | // -------------------------------------------------------------------- 32 | 33 | namespace key_utils { 34 | 35 | template 36 | struct is_keys : public std::false_type {}; 37 | 38 | template 39 | struct is_keys> : public std::true_type {}; 40 | 41 | template 42 | struct invalid_key : public std::false_type {}; 43 | } 44 | 45 | template 46 | class StaticMap { 47 | 48 | static_assert(key_utils::is_keys::value, "First template parameters must be of form keys<...>"); 49 | 50 | }; 51 | 52 | 53 | template 54 | class StaticMap,Value> { 55 | 56 | using key_list = type_list; 57 | 58 | std::array values; 59 | 60 | public: 61 | 62 | // -- accessors and mutators -- 63 | 64 | StaticMap(const Value& value) { 65 | for(auto& cur : values) cur = value; 66 | } 67 | 68 | StaticMap() = default; 69 | StaticMap(const StaticMap&) = default; 70 | StaticMap(StaticMap&&) = default; 71 | 72 | StaticMap& operator=(const StaticMap&) = default; 73 | StaticMap& operator=(StaticMap&&) = default; 74 | 75 | // -- accessors and mutators -- 76 | 77 | template 78 | Value& get() { 79 | return values[type_index::value]; 80 | } 81 | 82 | template 83 | const Value& get() const { 84 | return values[type_index::value]; 85 | } 86 | 87 | auto begin() { 88 | return values.begin(); 89 | } 90 | 91 | auto begin() const { 92 | return values.begin(); 93 | } 94 | 95 | auto end() { 96 | return values.end(); 97 | } 98 | 99 | auto end() const { 100 | return values.end(); 101 | } 102 | 103 | template 104 | void forEach(const Body& body) { 105 | for(auto& cur : values) { 106 | body(cur); 107 | } 108 | } 109 | 110 | template 111 | void forEach(const Body& body) const { 112 | for(const auto& cur : values) { 113 | body(cur); 114 | } 115 | } 116 | 117 | }; 118 | 119 | } // end namespace utils 120 | } // end namespace allscale 121 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/bag.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "allscale/utils/printer/join.h" 7 | 8 | namespace allscale { 9 | namespace utils { 10 | 11 | /** 12 | * A data structure for maintaining a collection of 13 | * objects with duplicates. 14 | */ 15 | template 16 | class Bag { 17 | 18 | // the element type maintained in this bag 19 | using element_type = T; 20 | 21 | // internally, the data is maintained in a simple list 22 | std::vector data; 23 | 24 | public: 25 | 26 | /** 27 | * Tests whether this bag is empty or not. 28 | */ 29 | bool empty() const { 30 | return data.empty(); 31 | } 32 | 33 | /** 34 | * Determines the number of elements in this bag. 35 | */ 36 | std::size_t size() const { 37 | return data.size(); 38 | } 39 | 40 | /** 41 | * Inserts a new element in this bag. 42 | */ 43 | void insert(const T& element) { 44 | data.push_back(element); 45 | } 46 | 47 | /** 48 | * Removes an element from this bag. 49 | */ 50 | void remove(const T& element) { 51 | auto pos = std::find(data.begin(),data.end(),element); 52 | if (pos == data.end()) return; 53 | data.erase(pos); 54 | } 55 | 56 | /** 57 | * Tests whether the given element is contained within this bag. 58 | */ 59 | bool contains(const T& element) { 60 | auto pos = std::find(data.begin(),data.end(),element); 61 | return pos != data.end(); 62 | } 63 | 64 | // add support for scans 65 | 66 | /** 67 | * Obtains an iterator pointing to the start of the range of 68 | * elements contained in this bag. 69 | */ 70 | auto begin() const { 71 | return data.begin(); 72 | } 73 | 74 | /** 75 | * Obtains an iterator pointing to the end of the range of 76 | * elements contained in this bag. 77 | */ 78 | auto end() const { 79 | return data.end(); 80 | } 81 | 82 | /** 83 | * Runs a combined update and filter operation on the elements 84 | * in this bag. The elements are passed by reference to the given 85 | * body -- which may return false if elements shell be removed, tue 86 | * otherwise. 87 | */ 88 | template 89 | void updateFilter(const Body& body) { 90 | // remove all elements where the predicate is violated 91 | auto newEnd = std::remove_if(data.begin(), data.end(), [&](T& i) { return !body(i); }); 92 | data.erase(newEnd,data.end()); 93 | } 94 | 95 | /** 96 | * Removes all elements from this bag which do not satisfy the 97 | * given predicates. 98 | */ 99 | template 100 | void filter(const Predicate& pred) { 101 | updateFilter([&](const T& i) { 102 | return pred(i); 103 | }); 104 | } 105 | 106 | /** 107 | * Adds printer support to this bag. 108 | */ 109 | friend std::ostream& operator<<(std::ostream& out, const Bag& bag) { 110 | return out << "{" << utils::join(",",bag.data) << "}"; 111 | } 112 | 113 | }; 114 | 115 | 116 | } // end namespace utils 117 | } // end namespace allscale 118 | -------------------------------------------------------------------------------- /code/api/test/user/data/map.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include "allscale/api/user/data/map.h" 5 | 6 | namespace allscale { 7 | namespace api { 8 | namespace user { 9 | namespace data { 10 | 11 | #include "data_item_test.inl" 12 | 13 | TEST(SetRegion,Basic) { 14 | 15 | SetRegion a,b; 16 | a.add(5); 17 | a.add(6); 18 | 19 | b.add(6); 20 | b.add(7); 21 | 22 | testRegion(a,b); 23 | 24 | } 25 | 26 | TEST(MapFragment,Basic) { 27 | 28 | SetRegion a,b; 29 | a.add(5); 30 | a.add(6); 31 | 32 | b.add(6); 33 | b.add(7); 34 | 35 | testFragment>(a,b); 36 | 37 | } 38 | 39 | TEST(Map,Basic) { 40 | 41 | // check whether Map implements the data_item concept (syntax) 42 | EXPECT_TRUE((core::is_data_item>::value)); 43 | 44 | 45 | 46 | // TODO: semantic data item checks 47 | 48 | } 49 | 50 | TEST(Map,Interact) { 51 | 52 | SetRegion keys; 53 | keys.add(2); 54 | keys.add(3); 55 | keys.add(5); 56 | 57 | 58 | // create a map data item 59 | Map data(keys); 60 | 61 | // use map data item 62 | data[2] = 12; 63 | data[3] = 14; 64 | data[5] = 18; 65 | 66 | } 67 | 68 | 69 | 70 | TEST(Map,ExampleManagement) { 71 | 72 | // create several ranges 73 | SetRegion a, b; 74 | for(int i=0; i<5; i++) { 75 | a.add(i); 76 | } 77 | for(int i=5; i<10; i++) { 78 | b.add(i); 79 | } 80 | 81 | EXPECT_TRUE(SetRegion::intersect(a,b).empty()); 82 | 83 | // create fragments 84 | MapFragment fA(a); 85 | MapFragment fB(b); 86 | 87 | // do some computation 88 | for(int t = 0; t<10; t++) { 89 | 90 | Map a = fA.mask(); 91 | for(int i=0; i<5; i++) { 92 | EXPECT_EQ(a[i],t); 93 | a[i]++; 94 | } 95 | 96 | Map b = fB.mask(); 97 | for(int i=5; i<10; i++) { 98 | EXPECT_EQ(b[i],t); 99 | b[i]++; 100 | } 101 | 102 | } 103 | 104 | // ------------------------------------------------ 105 | 106 | // now re-balance fragments by introducing a new fragment C 107 | SetRegion c; 108 | c.add(8,9); 109 | MapFragment fC(c); 110 | fC.insertRegion(fB,c); 111 | 112 | SetRegion nb; 113 | nb.add(3,4,5,6,7); 114 | fB.resize(nb); 115 | fB.insertRegion(fA,SetRegion::intersect(a,nb)); 116 | 117 | SetRegion na = SetRegion::difference(a,nb); 118 | fA.resize(na); 119 | 120 | // ------------------------------------------------ 121 | 122 | // do some computation on the re-shaped distribution 123 | for(int t = 10; t<20; t++) { 124 | 125 | Map a = fA.mask(); 126 | for(int i=0; i<3; i++) { 127 | EXPECT_EQ(a[i],t); 128 | a[i]++; 129 | } 130 | 131 | Map b = fB.mask(); 132 | for(int i=3; i<8; i++) { 133 | EXPECT_EQ(b[i],t); 134 | b[i]++; 135 | } 136 | 137 | Map c = fC.mask(); 138 | for(int i=8; i<10; i++) { 139 | EXPECT_EQ(c[i],t); 140 | c[i]++; 141 | } 142 | 143 | } 144 | 145 | } 146 | 147 | 148 | } // end namespace data 149 | } // end namespace user 150 | } // end namespace api 151 | } // end namespace allscale 152 | -------------------------------------------------------------------------------- /code/utils/test/type_list.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "allscale/utils/type_list.h" 4 | 5 | namespace allscale { 6 | namespace utils { 7 | 8 | struct A {}; 9 | struct B {}; 10 | struct C {}; 11 | 12 | 13 | TEST(TypeList,Basic) { 14 | 15 | EXPECT_EQ(0,(type_list<>::length)); 16 | EXPECT_EQ(1,(type_list::length)); 17 | EXPECT_EQ(2,(type_list::length)); 18 | EXPECT_EQ(3,(type_list::length)); 19 | EXPECT_EQ(4,(type_list::length)); 20 | 21 | EXPECT_TRUE((type_list<>::empty)); 22 | EXPECT_FALSE((type_list::empty)); 23 | EXPECT_FALSE((type_list::empty)); 24 | EXPECT_FALSE((type_list::empty)); 25 | 26 | } 27 | 28 | TEST(TypeList,Contains) { 29 | 30 | EXPECT_FALSE((type_list_contains>::value)); 31 | EXPECT_FALSE((type_list_contains>::value)); 32 | EXPECT_FALSE((type_list_contains>::value)); 33 | 34 | EXPECT_TRUE((type_list_contains>::value)); 35 | EXPECT_FALSE((type_list_contains>::value)); 36 | EXPECT_FALSE((type_list_contains>::value)); 37 | 38 | EXPECT_TRUE((type_list_contains>::value)); 39 | EXPECT_TRUE((type_list_contains>::value)); 40 | EXPECT_FALSE((type_list_contains>::value)); 41 | 42 | EXPECT_TRUE((type_list_contains>::value)); 43 | EXPECT_TRUE((type_list_contains>::value)); 44 | EXPECT_TRUE((type_list_contains>::value)); 45 | 46 | EXPECT_TRUE((type_list_contains>::value)); 47 | EXPECT_TRUE((type_list_contains>::value)); 48 | EXPECT_TRUE((type_list_contains>::value)); 49 | 50 | 51 | } 52 | 53 | TEST(TypeList,TypeAt) { 54 | 55 | EXPECT_EQ(typeid(A),typeid(type_at<0,type_list>::type)); 56 | 57 | EXPECT_EQ(typeid(A),typeid(type_at<0,type_list>::type)); 58 | EXPECT_EQ(typeid(B),typeid(type_at<1,type_list>::type)); 59 | 60 | EXPECT_EQ(typeid(A),typeid(type_at<0,type_list>::type)); 61 | EXPECT_EQ(typeid(B),typeid(type_at<1,type_list>::type)); 62 | EXPECT_EQ(typeid(C),typeid(type_at<2,type_list>::type)); 63 | 64 | EXPECT_EQ(typeid(A),typeid(type_at<0,type_list>::type)); 65 | EXPECT_EQ(typeid(B),typeid(type_at<1,type_list>::type)); 66 | EXPECT_EQ(typeid(C),typeid(type_at<2,type_list>::type)); 67 | EXPECT_EQ(typeid(A),typeid(type_at<3,type_list>::type)); 68 | 69 | } 70 | 71 | 72 | TEST(TypeList,TypeIndex) { 73 | 74 | EXPECT_EQ(0,(type_index>::value)); 75 | 76 | EXPECT_EQ(0,(type_index>::value)); 77 | EXPECT_EQ(1,(type_index>::value)); 78 | 79 | EXPECT_EQ(0,(type_index>::value)); 80 | EXPECT_EQ(1,(type_index>::value)); 81 | EXPECT_EQ(2,(type_index>::value)); 82 | 83 | EXPECT_EQ(0,(type_index>::value)); 84 | EXPECT_EQ(1,(type_index>::value)); 85 | EXPECT_EQ(2,(type_index>::value)); 86 | EXPECT_EQ(0,(type_index>::value)); 87 | 88 | } 89 | 90 | 91 | } // end namespace utils 92 | } // end namespace allscale 93 | -------------------------------------------------------------------------------- /code/utils/test/serializer/vectors.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "allscale/utils/serializer/vectors.h" 4 | #include "allscale/utils/serializer/strings.h" 5 | 6 | namespace allscale { 7 | namespace utils { 8 | 9 | struct NotSerializable {}; 10 | 11 | 12 | TEST(Serializer, StdVectors) { 13 | 14 | // check that strings are recognized as serializable 15 | EXPECT_TRUE((is_serializable>::value)); 16 | EXPECT_TRUE((is_serializable>::value)); 17 | EXPECT_TRUE((is_serializable>::value)); 18 | EXPECT_TRUE((is_serializable>::value)); 19 | 20 | // this should work also for a nested vectors 21 | EXPECT_TRUE((is_serializable>>::value)); 22 | 23 | // and with other types 24 | EXPECT_TRUE((is_serializable>::value)); 25 | 26 | // but not with non-serializable typse 27 | EXPECT_FALSE((is_serializable::value)); 28 | EXPECT_FALSE((is_serializable>::value)); 29 | 30 | } 31 | 32 | TEST(Serializer,StdVectorInt) { 33 | // serialize and de-serialize a vector 34 | std::vector in { 1, 2, 3, 4 }; 35 | auto archive = serialize(in); 36 | auto out = deserialize>(archive); 37 | 38 | EXPECT_EQ(in,out); 39 | } 40 | 41 | 42 | 43 | class SerializableButNotDefaultConstructable { 44 | 45 | int x; 46 | 47 | SerializableButNotDefaultConstructable(int x) : x(x) {} 48 | 49 | public: 50 | 51 | static SerializableButNotDefaultConstructable get(int x) { 52 | return SerializableButNotDefaultConstructable(x); 53 | } 54 | 55 | static SerializableButNotDefaultConstructable load(ArchiveReader& reader) { 56 | return SerializableButNotDefaultConstructable(reader.read()); 57 | } 58 | 59 | void store(ArchiveWriter& writer) const { 60 | writer.write(x); 61 | } 62 | 63 | bool operator==(const SerializableButNotDefaultConstructable& other) const { 64 | return x == other.x; 65 | } 66 | 67 | 68 | friend std::ostream& operator<<(std::ostream& out, const SerializableButNotDefaultConstructable& obj) { 69 | return out << obj.x; 70 | } 71 | 72 | }; 73 | 74 | 75 | TEST(Serializer,StdVectorNoDefaultConstructor) { 76 | 77 | // make sure the test type is realy not default-constructable 78 | EXPECT_FALSE(std::is_default_constructible::value); 79 | 80 | // but it is serializable 81 | EXPECT_TRUE(is_serializable::value); 82 | 83 | // and so is the enclosing array 84 | EXPECT_TRUE((is_serializable>::value)); 85 | 86 | // serialize and de-serialize a string 87 | std::vector in { 88 | SerializableButNotDefaultConstructable::get(1), 89 | SerializableButNotDefaultConstructable::get(2), 90 | SerializableButNotDefaultConstructable::get(3) 91 | }; 92 | 93 | auto archive = serialize(in); 94 | auto out = deserialize>(archive); 95 | 96 | EXPECT_EQ(in,out); 97 | } 98 | 99 | } // end namespace utils 100 | } // end namespace allscale 101 | -------------------------------------------------------------------------------- /code/api/test/core/impl/sequential/treeture.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "allscale/api/core/impl/sequential/treeture.h" 4 | 5 | namespace allscale { 6 | namespace api { 7 | namespace core { 8 | namespace impl { 9 | namespace sequential { 10 | 11 | TEST(Treeture,Basic) { 12 | 13 | treeture t1; 14 | t1.get(); 15 | 16 | treeture t2 = 12; 17 | EXPECT_EQ(12, t2.get()); 18 | 19 | } 20 | 21 | TEST(Operator,Done) { 22 | 23 | treeture t1 = done(); 24 | t1.get(); 25 | 26 | treeture t2 = done(12); 27 | EXPECT_EQ(12, t2.get()); 28 | 29 | } 30 | 31 | TEST(Operator, Task) { 32 | 33 | treeture t1 = spawn([](){ return 12; }); 34 | EXPECT_EQ(12, t1.get()); 35 | 36 | } 37 | 38 | TEST(Operator, Seq) { 39 | 40 | int x = 3; 41 | 42 | // build a not-yet started sequential tasks 43 | auto ls = seq( 44 | spawn([&]{ x++; }), 45 | spawn([&]{ x*=2; }), 46 | spawn([&]{ x-=1; x*=2; }) 47 | ); 48 | 49 | // should not be executed yet 50 | EXPECT_EQ(3,x); 51 | 52 | // the treeture conversion should trigger the execution 53 | treeture s = std::move(ls); 54 | EXPECT_EQ(14,x); 55 | 56 | // and the get should do nothing 57 | s.get(); 58 | EXPECT_EQ(14,x); 59 | 60 | } 61 | 62 | 63 | template 64 | auto sum(lazy_unreleased_treeture&& a, lazy_unreleased_treeture&& b) { 65 | return combine(std::move(a),std::move(b),[](int a, int b) { return a+b; }); 66 | } 67 | 68 | 69 | TEST(Operation, Sum) { 70 | 71 | auto t = sum(done(4),done(8)); 72 | EXPECT_EQ(12,t.get()); 73 | 74 | } 75 | 76 | TEST(Treeture, Dependencies) { 77 | 78 | int x = 0; 79 | 80 | treeture a = spawn([&]{ 81 | EXPECT_EQ(0,x); 82 | x++; 83 | }); 84 | 85 | treeture b = spawn(after(a), [&]{ 86 | EXPECT_EQ(1,x); 87 | x++; 88 | }); 89 | 90 | treeture c = spawn(after(b), [&]{ 91 | EXPECT_EQ(2,x); 92 | x++; 93 | }); 94 | 95 | treeture d = spawn(after(a,b,c), [&]{ 96 | EXPECT_EQ(3,x); 97 | x++; 98 | }); 99 | 100 | d.get(); 101 | EXPECT_EQ(4,x); 102 | } 103 | 104 | // --- benchmark --- 105 | 106 | const int N = 38; 107 | 108 | template 109 | struct c_fib { 110 | enum { value = c_fib::value + c_fib::value }; 111 | }; 112 | 113 | template<> 114 | struct c_fib<0> { 115 | enum { value = 0 }; 116 | }; 117 | 118 | template<> 119 | struct c_fib<1> { 120 | enum { value = 1 }; 121 | }; 122 | 123 | int s_fib(int x) { 124 | return (x <= 1) ? x : s_fib(x-1) + s_fib(x-2); 125 | } 126 | 127 | unreleased_treeture gen_fib(int x) { 128 | auto fib = [](int x) { 129 | return make_lazy_unreleased_treeture([=]() { return gen_fib(x); }); 130 | }; 131 | if (x <= 1) { 132 | return done(x); 133 | } 134 | return sum(fib(x-1),fib(x-2)); 135 | } 136 | 137 | int p_fib(int x) { 138 | return gen_fib(x).get(); 139 | } 140 | 141 | TEST(Benchmark,SeqFib) { 142 | EXPECT_EQ(c_fib::value, s_fib(N)); 143 | } 144 | 145 | TEST(Benchmark,ParFib) { 146 | EXPECT_EQ(c_fib::value, p_fib(N)); 147 | } 148 | 149 | } // end namespace sequential 150 | } // end namespace impl 151 | } // end namespace core 152 | } // end namespace api 153 | } // end namespace allscale 154 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AllScale API 2 | 3 | The AllScale API comprises the AllScale Core API and AllScale User API. 4 | 5 | The AllScale User API comprises an extendable set of parallel primitives and data constructs to support the effective implementation of efficient HPC applications. 6 | 7 | The AllScale Core API defines the interface between the AllScale User API and the underlying implemenations, including the AllScale Compiler and Runtime environment itself. 8 | 9 | For more detailed information visit our [wiki](https://github.com/allscale/allscale_api/wiki) or [project website](http://www.allscale.eu/home). 10 | 11 | ## Quickstart 12 | 13 | This project requires C++14 features as offered by e.g. GCC >= 4.9 (GCC 5.2.1 is used for development and testing). 14 | Furthermore CMake 3.2 (or later) is required for the build and testing process. 15 | Simply execute the following commands to build the project and run all tests. 16 | 17 | $ mkdir build 18 | $ cd build 19 | $ cmake ../code 20 | $ make -j8 21 | $ ctest -j8 22 | 23 | ## Advanced Options 24 | 25 | ### Configuration 26 | 27 | Following options can be supplied to CMake 28 | 29 | | Option | Values | 30 | | ----------------------- | --------------- | 31 | | -DCMAKE_BUILD_TYPE | Release / Debug | 32 | | -DBUILD_SHARED_LIBS | ON / OFF | 33 | | -DBUILD_TESTS | ON / OFF | 34 | | -DBUILD_DOCS | ON / OFF | 35 | | -DBUILD_COVERAGE | ON / OFF | 36 | | -DUSE_ASSERT | ON / OFF | 37 | | -DALLSCALE_CHECK_BOUNDS | ON / OFF | 38 | | -DUSE_VALGRIND | ON / OFF | 39 | | -DENABLE_PROFILING | ON / OFF | 40 | 41 | The files `cmake/build_settings.cmake` and `code/CMakeLists.txt` state their 42 | default value. 43 | 44 | ### Building / Testing 45 | 46 | $ mkdir build 47 | $ cd build 48 | $ cmake ../code 49 | $ make -j8 50 | $ ctest -j8 51 | 52 | ## Development 53 | 54 | ### Executable Bit 55 | 56 | When working on Windows via SMB share, consider setting following Git setting. 57 | 58 | $ git config core.filemode false 59 | 60 | ### Licensor 61 | 62 | A script, together with a Git hook, is provided to automatically add a license 63 | header to each source file upon commit. See `scripts/license`. 64 | 65 | ### Eclipse Project 66 | 67 | $ cmake -G "Eclipse CDT4 - Unix Makefiles" /path/to/project 68 | 69 | ### Visual Studio Solution 70 | 71 | $ cmake -G "Visual Studio 15 2017 Win64" -DBUILD_SHARED_LIBS=OFF Z:\path\to\project 72 | 73 | Add path for third-party libraries when needed. 74 | 75 | ### Coverage 76 | 77 | Building the coverage us currently only supported on Linux, as Perl and Bash 78 | are required. To build and view the coverage set the corresponding CMake flag 79 | to `ON` and run: 80 | 81 | $ make 82 | $ make coverage 83 | $ xdg-open coverage/index.html 84 | 85 | ## Troubleshooting 86 | 87 | ### Getting GCC 5 / CMake 3.5 / Valgrind (for Testing) 88 | 89 | The dependency installer can setup these required tools for you. Its README 90 | (`scripts/dependencies/README.md`) holds the details. 91 | 92 | It is preferred to use the operating system's package manager, if applicable. 93 | 94 | ### No Source Folder in Eclipse Project 95 | 96 | Make sure your build folder is located outside the source folder. Eclipse is 97 | not capable of dealing with such a setup correctly. 98 | -------------------------------------------------------------------------------- /code/utils/test/bag.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "allscale/utils/bag.h" 4 | #include "allscale/utils/string_utils.h" 5 | 6 | namespace allscale { 7 | namespace utils { 8 | 9 | TEST(Bag,Basic) { 10 | 11 | Bag b; 12 | 13 | EXPECT_TRUE(b.empty()); 14 | EXPECT_EQ(0, b.size()); 15 | 16 | EXPECT_FALSE(b.contains(12)); 17 | EXPECT_FALSE(b.contains(14)); 18 | EXPECT_FALSE(b.contains(16)); 19 | 20 | 21 | b.insert(12); 22 | EXPECT_FALSE(b.empty()); 23 | EXPECT_EQ(1, b.size()); 24 | 25 | EXPECT_TRUE(b.contains(12)); 26 | EXPECT_FALSE(b.contains(14)); 27 | EXPECT_FALSE(b.contains(16)); 28 | 29 | 30 | b.insert(14); 31 | EXPECT_FALSE(b.empty()); 32 | EXPECT_EQ(2, b.size()); 33 | 34 | EXPECT_TRUE(b.contains(12)); 35 | EXPECT_TRUE(b.contains(14)); 36 | EXPECT_FALSE(b.contains(16)); 37 | 38 | 39 | b.insert(12); 40 | EXPECT_FALSE(b.empty()); 41 | EXPECT_EQ(3, b.size()); 42 | 43 | EXPECT_TRUE(b.contains(12)); 44 | EXPECT_TRUE(b.contains(14)); 45 | EXPECT_FALSE(b.contains(16)); 46 | 47 | 48 | // remove some items 49 | 50 | b.remove(12); 51 | EXPECT_FALSE(b.empty()); 52 | EXPECT_EQ(2, b.size()); 53 | 54 | EXPECT_TRUE(b.contains(12)); 55 | EXPECT_TRUE(b.contains(14)); 56 | EXPECT_FALSE(b.contains(16)); 57 | 58 | 59 | b.remove(12); 60 | EXPECT_FALSE(b.empty()); 61 | EXPECT_EQ(1, b.size()); 62 | 63 | EXPECT_FALSE(b.contains(12)); 64 | EXPECT_TRUE(b.contains(14)); 65 | EXPECT_FALSE(b.contains(16)); 66 | 67 | 68 | b.remove(14); 69 | EXPECT_TRUE(b.empty()); 70 | EXPECT_EQ(0, b.size()); 71 | 72 | EXPECT_FALSE(b.contains(12)); 73 | EXPECT_FALSE(b.contains(14)); 74 | EXPECT_FALSE(b.contains(16)); 75 | 76 | } 77 | 78 | 79 | TEST(Bag,Iterators) { 80 | 81 | Bag b; 82 | 83 | // check the empty bag 84 | EXPECT_EQ(b.begin(),b.end()); 85 | 86 | // insert some stuff 87 | for(int i = 0; i<10; ++i) { 88 | for(int j=0; j a; 108 | 109 | EXPECT_EQ("{}",toString(a)); 110 | 111 | a.insert(12); 112 | EXPECT_EQ("{12}",toString(a)); 113 | 114 | a.insert(14); 115 | EXPECT_EQ("{12,14}",toString(a)); 116 | 117 | a.insert(12); 118 | EXPECT_EQ("{12,14,12}",toString(a)); 119 | 120 | } 121 | 122 | TEST(Bag, UpdateAndFilter) { 123 | 124 | Bag b; 125 | 126 | for(int i=0; i<10; i++) { 127 | b.insert(i); 128 | } 129 | 130 | EXPECT_EQ(10, b.size()); 131 | 132 | // filter out all odd numbers 133 | b.filter([](int i) { return (i % 2) == 1; }); 134 | 135 | EXPECT_EQ(5, b.size()); 136 | 137 | for(int i = 1; i<10; i+=2) { 138 | EXPECT_TRUE(b.contains(i)) << "Missing " << i; 139 | } 140 | 141 | // increase all by one and filter even values 142 | b.updateFilter([](int& cur) { 143 | cur++; 144 | return (cur % 3) != 0; 145 | }); 146 | 147 | EXPECT_EQ(4, b.size()); 148 | 149 | for(int i : { 2, 4, 8, 10 }) { 150 | EXPECT_TRUE(b.contains(i)) << "Missing " << i; 151 | } 152 | } 153 | 154 | 155 | } // end namespace utils 156 | } // end namespace allscale 157 | -------------------------------------------------------------------------------- /cmake/msvc_settings.cmake: -------------------------------------------------------------------------------- 1 | if(MSVC) 2 | # enable minimal rebuild 3 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Gm") 4 | # enable debug information(required for /Gm) 5 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zi") 6 | # increase number of sections in *.obj file 7 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") 8 | # increase stack size to 32 megabytes (required for some unit tests) 9 | set(CMAKE_CXX_STACK_SIZE "33554432") 10 | # disable optimizations(compilation speed) 11 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Od") 12 | # disable some warnings 13 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_CRT_SECURE_NO_WARNINGS") 14 | # Boost: No auto-lib 15 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /DBOOST_ALL_NO_LIB") 16 | # disable warning "assignment operator could not be generated" 17 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd\"4512\"") 18 | # disable warning "nonstandard extension: enum '[EnumName::ENUM]' used in qualified name" 19 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd\"4482\"") 20 | # disable warning "unkown pragma" 21 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd\"4068\"") 22 | # disable warning "declaration hides class member" 23 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd\"4458\"") 24 | # disable warning "forcing value to bool 'true' or 'false'(performance warning)" 25 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd\"4800\"") 26 | # disable warning "symbol will be dynamically initialized(implementation limitation)" because MSVC 2015.1 is still buggy on that 27 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd\"4592\"") 28 | # disable warning regarding deprecated tr1 namespace (introduced with MSVC 2017 15.5.1) 29 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING") 30 | 31 | # remove NDEBUG from release flags 32 | string(REPLACE "/DNDEBUG" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") 33 | string(REPLACE "/DNDEBUG" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") 34 | if(NOT USE_ASSERT) 35 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /DNDEBUG") 36 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /DNDEBUG") 37 | endif() 38 | 39 | # disable checked iterators 40 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D_ITERATOR_DEBUG_LEVEL=0") 41 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_ITERATOR_DEBUG_LEVEL=0") 42 | 43 | # properly configure how to link the MSVC runtime library, static <-> shared and debug <-> release 44 | if(BUILD_SHARED_LIBS) 45 | message(STATUS "MSVC: using dynamically-linked runtime") 46 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd") 47 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD") 48 | else() 49 | message(STATUS "MSVC: using statically-linked runtime") 50 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") 51 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") 52 | endif() 53 | 54 | # windows library naming policies 55 | set(CMAKE_FIND_LIBRARY_PREFIXES "") 56 | set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib") # if you're thinking about adding ".dll" here, read up on "import libraries" in Windows 57 | 58 | # library output 59 | if(${CMAKE_BUILD_TYPE} STREQUAL Release) 60 | set(LIBRARY_OUTPUT_DIRECTORY Release) 61 | else() 62 | set(LIBRARY_OUTPUT_DIRECTORY Debug) 63 | endif() 64 | 65 | # solution configuration 66 | set(CMAKE_CONFIGURATION_TYPES Debug Release CACHE STRING "Visual Studio Solution Configuration" FORCE) 67 | 68 | # no ZERO_CHECK target 69 | set(CMAKE_SUPPRESS_REGENERATION true) 70 | endif() 71 | -------------------------------------------------------------------------------- /code/tutorials/src/prec/03_nqueens_prec.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include "allscale/api/core/prec.h" 3 | #include "allscale/api/user/arithmetic.h" 4 | 5 | using namespace allscale::api::core; 6 | 7 | template 8 | auto reduceIf(const Iter& a, const Iter& b, const Filter& filter, const Map& map, const Reduce& reduce) { 9 | using treeture_type = typename allscale::utils::lambda_traits::result_type::treeture_type; 10 | using result_type = typename allscale::utils::lambda_traits::result_type; 11 | 12 | // check that the interval is not empty 13 | if (a>b) return result_type(0); 14 | 15 | // spawn tasks and collect without heap allocation 16 | assert_lt(b-a,32); 17 | std::bitset<32> mask; 18 | std::array tasks; 19 | std::size_t j = 0; 20 | for(Iter i = a; i 36 | auto sumIf(const Iter& a, const Iter& b, const Filter& filter, const Map& map) { 37 | return reduceIf(a,b,filter,map,std::plus()); 38 | } 39 | 40 | struct Assignment { 41 | 42 | int column; // < the number of columns assigned so far 43 | int row; // < the row this queen is placed 44 | const Assignment* rest; // < the rest of this assignment 45 | 46 | Assignment() 47 | : column(-1), row(0), rest(nullptr) {} 48 | 49 | Assignment(int row, const Assignment& rest) 50 | : column(rest.column+1), row(row), rest(&rest) {} 51 | 52 | int size() const { 53 | return column + 1; 54 | } 55 | 56 | bool valid(int r) const { 57 | return valid(r,column+1); 58 | } 59 | 60 | bool valid(int r, int c) const { 61 | assert_lt(column,c); 62 | // check end of assignment 63 | if (column<0) return true; 64 | // if in same row => fail 65 | if (row == r) return false; 66 | // if on same diagonal => fail 67 | auto diff = c - column; 68 | if (row + diff == r || row - diff == r) return false; 69 | // check nested 70 | return rest->valid(r,c); 71 | } 72 | }; 73 | 74 | int nqueens(int size) { 75 | // create the recursive version 76 | auto compute = prec( 77 | [size](const Assignment& args) { 78 | // check whether the assignment is complete 79 | return args.size() >= size; 80 | }, 81 | [](const Assignment&) { 82 | // if a complete assignment is reached, we have a solution 83 | return 1; 84 | }, 85 | [size](const Assignment& a, const auto& rec) { 86 | return sumIf(0,size, 87 | [&](int i){ return a.valid(i); }, 88 | [&](int i){ return rec(Assignment(i,a)); } 89 | ); 90 | } 91 | ); 92 | 93 | // compute the result 94 | return compute(Assignment()).get(); 95 | } 96 | 97 | int main() { 98 | const int N = 10; 99 | 100 | int solutions = nqueens(N); 101 | 102 | std::cout << "There are " << solutions << " solutions." << std::endl; 103 | } -------------------------------------------------------------------------------- /code/utils/test/table.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "allscale/utils/table.h" 6 | #include "allscale/utils/string_utils.h" 7 | #include "allscale/utils/printer/vectors.h" 8 | 9 | namespace allscale { 10 | namespace utils { 11 | 12 | 13 | TEST(Table,TypeProperties) { 14 | 15 | using table_t = Table>; 16 | 17 | EXPECT_TRUE(std::is_copy_constructible::value); 18 | EXPECT_TRUE(std::is_move_constructible::value); 19 | 20 | EXPECT_TRUE(std::is_copy_assignable::value); 21 | EXPECT_TRUE(std::is_move_assignable::value); 22 | 23 | EXPECT_TRUE(std::is_destructible::value); 24 | 25 | } 26 | 27 | TEST(Table,BasicCtors) { 28 | 29 | using table_t = Table>; 30 | 31 | table_t table(5); 32 | 33 | EXPECT_FALSE(table.empty()); 34 | EXPECT_EQ(5,table.size()); 35 | EXPECT_TRUE(table.isOwner()); 36 | EXPECT_EQ("[[],[],[],[],[]]",toString(table)); 37 | 38 | for(auto& cur : table) { 39 | cur.push_back(12); 40 | } 41 | 42 | EXPECT_EQ("[[12],[12],[12],[12],[12]]",toString(table)); 43 | 44 | Table> copy(table); 45 | EXPECT_EQ("[[12],[12],[12],[12],[12]]",toString(copy)); 46 | 47 | EXPECT_TRUE(table.isOwner()); 48 | EXPECT_TRUE(copy.isOwner()); 49 | 50 | Table> move(std::move(table)); 51 | 52 | EXPECT_FALSE(table.isOwner()); 53 | EXPECT_TRUE(copy.isOwner()); 54 | EXPECT_TRUE(move.isOwner()); 55 | 56 | EXPECT_EQ("[[12],[12],[12],[12],[12]]",toString(table)); 57 | EXPECT_EQ("[[12],[12],[12],[12],[12]]",toString(copy)); 58 | EXPECT_EQ("[[12],[12],[12],[12],[12]]",toString(move)); 59 | 60 | } 61 | 62 | TEST(Table,BasicAssignment) { 63 | 64 | using table_t = Table>; 65 | 66 | table_t table(5); 67 | 68 | EXPECT_FALSE(table.empty()); 69 | EXPECT_EQ(5,table.size()); 70 | EXPECT_TRUE(table.isOwner()); 71 | EXPECT_EQ("[[],[],[],[],[]]",toString(table)); 72 | 73 | for(auto& cur : table) { 74 | cur.push_back(12); 75 | } 76 | 77 | EXPECT_EQ("[[12],[12],[12],[12],[12]]",toString(table)); 78 | 79 | Table> copy; 80 | copy = table; 81 | EXPECT_EQ("[[12],[12],[12],[12],[12]]",toString(copy)); 82 | 83 | EXPECT_TRUE(table.isOwner()); 84 | EXPECT_TRUE(copy.isOwner()); 85 | 86 | Table> move; 87 | move = std::move(table); 88 | 89 | EXPECT_FALSE(table.isOwner()); 90 | EXPECT_TRUE(copy.isOwner()); 91 | EXPECT_TRUE(move.isOwner()); 92 | 93 | EXPECT_EQ("[[12],[12],[12],[12],[12]]",toString(table)); 94 | EXPECT_EQ("[[12],[12],[12],[12],[12]]",toString(copy)); 95 | EXPECT_EQ("[[12],[12],[12],[12],[12]]",toString(move)); 96 | 97 | } 98 | 99 | 100 | TEST(Table,InitCtor) { 101 | 102 | Table table(5,5); 103 | EXPECT_EQ("[5,5,5,5,5]",toString(table)); 104 | 105 | } 106 | 107 | TEST(Table,Empty) { 108 | 109 | Table table; 110 | 111 | EXPECT_EQ(0,table.size()); 112 | EXPECT_TRUE(table.empty()); 113 | 114 | EXPECT_EQ(table.begin(),table.end()); 115 | 116 | } 117 | 118 | 119 | TEST(Table,ExternOwn) { 120 | 121 | const int N = 4; 122 | 123 | int data[N] = { 1, 2, 3, 4 }; 124 | 125 | Table table(data,data+N); 126 | 127 | EXPECT_FALSE(table.empty()); 128 | EXPECT_EQ(N,table.size()); 129 | EXPECT_FALSE(table.isOwner()); 130 | 131 | EXPECT_EQ("[1,2,3,4]",toString(table)); 132 | } 133 | 134 | } // end namespace utils 135 | } // end namespace allscale 136 | -------------------------------------------------------------------------------- /code/utils/test/serializer/maps.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "allscale/utils/serializer/maps.h" 4 | #include "allscale/utils/serializer/strings.h" 5 | 6 | namespace allscale { 7 | namespace utils { 8 | 9 | struct NotSerializable {}; 10 | 11 | 12 | TEST(Serializer, StdMaps) { 13 | 14 | // check that strings are recognized as serializable 15 | EXPECT_TRUE((is_serializable>::value)); 16 | EXPECT_TRUE((is_serializable>::value)); 17 | EXPECT_TRUE((is_serializable>::value)); 18 | EXPECT_TRUE((is_serializable>::value)); 19 | 20 | // but not with non-serializable types 21 | EXPECT_FALSE((is_serializable>::value)); 22 | EXPECT_FALSE((is_serializable>::value)); 23 | 24 | // this should work also for a nested maps 25 | EXPECT_TRUE((is_serializable,int>>::value)); 26 | 27 | // and with other types 28 | EXPECT_TRUE((is_serializable>::value)); 29 | 30 | } 31 | 32 | TEST(Serializer,StdMapInt) { 33 | // serialize and de-serialize a map 34 | std::map in = {{0, 2}, {12, 929}, {47, 42}}; 35 | auto archive = serialize(in); 36 | auto out = deserialize>(archive); 37 | 38 | EXPECT_EQ(in,out); 39 | } 40 | 41 | 42 | 43 | class SerializableButNotDefaultConstructable { 44 | 45 | int x; 46 | 47 | SerializableButNotDefaultConstructable(int x) : x(x) {} 48 | 49 | public: 50 | 51 | static SerializableButNotDefaultConstructable get(int x) { 52 | return SerializableButNotDefaultConstructable(x); 53 | } 54 | 55 | static SerializableButNotDefaultConstructable load(ArchiveReader& reader) { 56 | return SerializableButNotDefaultConstructable(reader.read()); 57 | } 58 | 59 | void store(ArchiveWriter& writer) const { 60 | writer.write(x); 61 | } 62 | 63 | bool operator==(const SerializableButNotDefaultConstructable& other) const { 64 | return x == other.x; 65 | } 66 | 67 | bool operator<(const SerializableButNotDefaultConstructable& other) const { 68 | return x < other.x; 69 | } 70 | 71 | 72 | friend std::ostream& operator<<(std::ostream& out, const SerializableButNotDefaultConstructable& obj) { 73 | return out << obj.x; 74 | } 75 | 76 | }; 77 | 78 | 79 | TEST(Serializer,StdMapNoDefaultConstructor) { 80 | 81 | // make sure the test type is really not default-constructible 82 | EXPECT_FALSE(std::is_default_constructible::value); 83 | 84 | // but it is serializable 85 | EXPECT_TRUE(is_serializable::value); 86 | 87 | // and so is the enclosing map 88 | EXPECT_TRUE((is_serializable>::value)); 89 | 90 | // serialize and de-serialize a string 91 | std::map in { 92 | { SerializableButNotDefaultConstructable::get(1), SerializableButNotDefaultConstructable::get(2) }, 93 | { SerializableButNotDefaultConstructable::get(3), SerializableButNotDefaultConstructable::get(4) }, 94 | { SerializableButNotDefaultConstructable::get(5), SerializableButNotDefaultConstructable::get(6) } 95 | }; 96 | 97 | auto archive = serialize(in); 98 | auto out = deserialize>(archive); 99 | 100 | EXPECT_EQ(in,out); 101 | } 102 | 103 | } // end namespace utils 104 | } // end namespace allscale 105 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/optional.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "allscale/utils/assert.h" 4 | 5 | #include 6 | 7 | namespace allscale { 8 | namespace utils { 9 | 10 | template 11 | class optional { 12 | 13 | // true, if the object is valid, false otherwise 14 | bool valid; 15 | 16 | // the stored object, if present 17 | char obj[sizeof(T)]; 18 | 19 | public: 20 | 21 | optional() : valid(false) {}; 22 | 23 | optional(const optional& other) : valid(other.valid) { 24 | if (valid) new (obj) T(other.asRef()); 25 | } 26 | 27 | optional(optional&& other) : valid(other.valid) { 28 | if (valid) new (obj) T(std::move(other.asRef())); 29 | other.discard(); 30 | } 31 | 32 | optional(const T& val) : valid(true) { 33 | new (obj) T(val); 34 | } 35 | 36 | optional(T&& val) : valid(true) { 37 | new (obj) T(std::move(val)); 38 | }; 39 | 40 | ~optional() { 41 | if (valid) asPtr()->~T(); 42 | } 43 | 44 | // Operator: 45 | 46 | explicit operator bool() const { 47 | return valid; 48 | } 49 | 50 | T& operator*() { 51 | return asRef(); 52 | } 53 | 54 | const T& operator*() const { 55 | return asRef(); 56 | } 57 | 58 | optional& operator=(const optional& other) { 59 | if (this == &other) return *this; 60 | 61 | // discard old state 62 | discard(); 63 | 64 | // if the other is representing none => done 65 | if (!other.valid) return *this; 66 | 67 | // copy other state 68 | if (!valid) { 69 | valid = true; 70 | new (obj) T(other.asRef()); 71 | } else { 72 | asRef() = other.asRef(); 73 | } 74 | 75 | // done 76 | return *this; 77 | } 78 | 79 | optional& operator=(optional&& other) { 80 | if (this == &other) return *this; 81 | 82 | // discard old state 83 | discard(); 84 | 85 | // if the other is representing none => done 86 | if (!other.valid) return *this; 87 | 88 | // copy other state 89 | if (!valid) { 90 | valid = true; 91 | new (obj) T(std::move(other.asRef())); 92 | } else { 93 | asRef() = std::move(other.asRef()); 94 | } 95 | 96 | // invalidate other 97 | other.discard(); 98 | 99 | // done 100 | return *this; 101 | } 102 | 103 | bool operator==(const optional& other) const { 104 | return (!valid && !other.valid) || (valid && other.valid && asRef() == other.asRef()); 105 | } 106 | 107 | bool operator!=(const optional& other) const { 108 | return !(*this == other); 109 | } 110 | 111 | bool operator<(const optional& other) const { 112 | if (!valid) return other.valid; 113 | if (!other.valid) return false; 114 | return asRef() < other.asRef(); 115 | } 116 | 117 | friend std::ostream& operator<<(std::ostream& out, const optional& opt) { 118 | if (!bool(opt)) return out << "Nothing"; 119 | return out << "Just(" << *opt << ")"; 120 | } 121 | 122 | private: 123 | 124 | T* asPtr() { 125 | return reinterpret_cast((void*)&obj[0]); 126 | } 127 | 128 | const T* asPtr() const { 129 | return reinterpret_cast((void*)&obj[0]); 130 | } 131 | 132 | T& asRef() { 133 | assert_true(valid); 134 | return *asPtr(); 135 | } 136 | 137 | const T& asRef() const { 138 | assert_true(valid); 139 | return *asPtr(); 140 | } 141 | 142 | void discard() { 143 | if (!valid) return; 144 | asPtr()->~T(); 145 | valid = false; 146 | } 147 | 148 | }; 149 | 150 | template 151 | optional make_optional(const T& val) { 152 | return { val }; 153 | } 154 | 155 | template 156 | optional make_optional(T&& val) { 157 | return { std::move(val) }; 158 | } 159 | 160 | } // end namespace utils 161 | } // end namespace allscale 162 | -------------------------------------------------------------------------------- /code/api/test/user/algorithm/internal/operator_reference.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include "allscale/api/user/algorithm/internal/operation_reference.h" 7 | 8 | #include "allscale/api/core/prec.h" 9 | #include "allscale/api/user/algorithm/async.h" 10 | 11 | namespace allscale { 12 | namespace api { 13 | namespace user { 14 | namespace algorithm { 15 | namespace internal { 16 | 17 | TEST(OperatorReference,TypeTraits) { 18 | 19 | EXPECT_TRUE(std::is_default_constructible::value); 20 | 21 | EXPECT_FALSE(std::is_copy_constructible::value); 22 | EXPECT_TRUE(std::is_move_constructible::value); 23 | 24 | EXPECT_FALSE(std::is_copy_assignable::value); 25 | EXPECT_TRUE(std::is_move_assignable::value); 26 | 27 | EXPECT_TRUE(std::is_destructible::value); 28 | 29 | } 30 | 31 | TEST(OperatorReference,NoTask) { 32 | 33 | operation_reference empty; 34 | 35 | EXPECT_TRUE(empty.isDone()); 36 | EXPECT_FALSE(empty.isValid()); 37 | 38 | } 39 | 40 | 41 | TEST(OperatorReference,SimpleTask) { 42 | 43 | std::atomic counter(0); 44 | 45 | operation_reference task = algorithm::async([&]{ 46 | counter = 1; 47 | }); 48 | 49 | EXPECT_TRUE(task.isValid()); 50 | 51 | // wait for the task to complete 52 | task.wait(); 53 | 54 | // check whether side-effects took place 55 | EXPECT_EQ(1,counter.load()); 56 | EXPECT_TRUE(task.isDone()); 57 | 58 | } 59 | 60 | 61 | TEST(OperatorReference,Move) { 62 | 63 | std::atomic counter(0); 64 | 65 | operation_reference task = algorithm::async([&]{ 66 | counter = 1; 67 | }); 68 | 69 | EXPECT_TRUE(task.isValid()); 70 | 71 | task.wait(); 72 | EXPECT_TRUE(task.isDone()); 73 | 74 | // -- move task through constructor -- 75 | operation_reference moveCtr = std::move(task); 76 | 77 | // check validity 78 | EXPECT_FALSE(task.isValid()); 79 | EXPECT_TRUE(moveCtr.isValid()); 80 | 81 | EXPECT_TRUE(task.isDone()); 82 | 83 | // -- move through assignment -- 84 | operation_reference moveAss; 85 | moveAss = std::move(moveCtr); 86 | 87 | EXPECT_FALSE(task.isValid()); 88 | EXPECT_FALSE(moveCtr.isValid()); 89 | EXPECT_TRUE(moveAss.isValid()); 90 | 91 | EXPECT_TRUE(task.isDone()); 92 | EXPECT_TRUE(moveCtr.isDone()); 93 | 94 | // wait for the completion 95 | moveAss.wait(); 96 | EXPECT_EQ(1,counter.load()); 97 | 98 | EXPECT_TRUE(task.isDone()); 99 | EXPECT_TRUE(moveCtr.isDone()); 100 | EXPECT_TRUE(moveAss.isDone()); 101 | 102 | } 103 | 104 | 105 | TEST(OperatorReference,Scoping) { 106 | 107 | std::atomic counter(0); 108 | 109 | operation_reference task = algorithm::async([&]{ 110 | counter = 1; 111 | }); 112 | 113 | { 114 | // move the task to a copy 115 | operation_reference cpy = std::move(task); 116 | // here there should be an implicit wait 117 | } 118 | 119 | // the counter should be 1 now 120 | EXPECT_EQ(1,counter.load()); 121 | 122 | } 123 | 124 | 125 | TEST(OperatorReference,Detach) { 126 | 127 | std::atomic counter(0); 128 | 129 | operation_reference task = algorithm::async([&]{ 130 | counter = 1; 131 | }); 132 | 133 | EXPECT_TRUE(task.isValid()); 134 | 135 | auto job = task.detach(); 136 | 137 | EXPECT_FALSE(task.isValid()); 138 | EXPECT_TRUE(task.isDone()); 139 | 140 | job.wait(); 141 | 142 | EXPECT_EQ(1,counter.load()); 143 | EXPECT_TRUE(job.isDone()); 144 | 145 | } 146 | 147 | 148 | } // end namespace internal 149 | } // end namespace algorithm 150 | } // end namespace user 151 | } // end namespace api 152 | } // end namespace allscale 153 | -------------------------------------------------------------------------------- /code/utils/include/allscale/utils/tuple_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace allscale { 7 | namespace utils { 8 | 9 | namespace detail { 10 | 11 | template 12 | struct tuple_for_each_helper { 13 | template 14 | void operator()(const Op& op, std::tuple& tuple) { 15 | tuple_for_each_helper()(op,tuple); 16 | op(std::get(tuple)); 17 | } 18 | template 19 | void operator()(const Op& op, const std::tuple& tuple) { 20 | tuple_for_each_helper()(op,tuple); 21 | op(std::get(tuple)); 22 | } 23 | }; 24 | 25 | template<> 26 | struct tuple_for_each_helper<0> { 27 | template 28 | void operator()(const Op&, const std::tuple&) { 29 | // nothing 30 | } 31 | }; 32 | 33 | } 34 | 35 | /** 36 | * A utility to apply an operator on all elements of a tuple in order. 37 | * 38 | * @param tuple the (mutable) tuple 39 | * @param op the operator to be applied 40 | */ 41 | template 42 | void forEach(std::tuple& tuple, const Op& op) { 43 | detail::tuple_for_each_helper()(op,tuple); 44 | } 45 | 46 | /** 47 | * A utility to apply an operator on all elements of a tuple in order. 48 | * 49 | * @param tuple the (constant) tuple 50 | * @param op the operator to be applied 51 | */ 52 | template 53 | void forEach(const std::tuple& tuple, const Op& op) { 54 | detail::tuple_for_each_helper()(op,tuple); 55 | } 56 | 57 | namespace detail { 58 | 59 | template 60 | auto map_helper(const std::tuple& in, const Op& op, std::integer_sequence) { 61 | return std::make_tuple(op(std::get(in))...); 62 | } 63 | 64 | template 65 | auto map_helper(std::tuple& in, const Op& op, std::integer_sequence) { 66 | return std::make_tuple(op(std::get(in))...); 67 | } 68 | 69 | } 70 | 71 | /** 72 | * A utility to apply a transformation on each element of a given tuple and return a a tuple containing 73 | * the results. 74 | * 75 | * @param tuple the (constant) input tuple 76 | * @param op the operation to be applied on each element of the tuple 77 | */ 78 | template 79 | auto map(const std::tuple& tuple, const Op& op) { 80 | return detail::map_helper(tuple,op,std::make_integer_sequence()); 81 | } 82 | 83 | /** 84 | * A utility to apply a transformation on each element of a given tuple and return a a tuple containing 85 | * the results. 86 | * 87 | * @param tuple the (mutable) input tuple 88 | * @param op the operation to be applied on each element of the tuple 89 | */ 90 | template 91 | auto map(std::tuple& tuple, const Op& op) { 92 | return detail::map_helper(tuple,op,std::make_integer_sequence()); 93 | } 94 | 95 | } // end namespace utils 96 | } // end namespace allscale 97 | 98 | namespace std { 99 | 100 | template 101 | std::ostream& operator<<(std::ostream& out, const std::tuple& tuple) { 102 | out << "("; 103 | std::size_t count = 0; 104 | const std::size_t numElements = sizeof...(Elements); 105 | allscale::utils::forEach(tuple,[&](const auto& cur) { 106 | out << cur; 107 | count++; 108 | if (count != numElements) out << ","; 109 | }); 110 | return out << ")"; 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /cmake/build_settings.cmake: -------------------------------------------------------------------------------- 1 | option(BUILD_SHARED_LIBS "Link libraries dynamically" ON) 2 | option(BUILD_TESTS "Enable testing" ON) 3 | option(BUILD_DOCS "Enable documentation" OFF) 4 | option(BUILD_COVERAGE "Enables code coverage report" OFF) 5 | option(USE_ASSERT "Enable assertions" ON) 6 | option(USE_VALGRIND "Allow Valgrind for unit tests" OFF) 7 | option(ENABLE_PROFILING "Enable AllScale profiling support" OFF) 8 | 9 | # ALLSCALE_CHECK_BOUNDS ... Enable bounds checks for AllScale data items and utility structures 10 | 11 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 12 | 13 | if(NOT CMAKE_BUILD_TYPE) 14 | set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "CMake Build Type" FORCE) 15 | endif() 16 | 17 | if(BUILD_TESTS) 18 | enable_testing() 19 | endif() 20 | 21 | # check correct flags for code coverage 22 | if(BUILD_COVERAGE AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 23 | message(FATAL_ERROR "Code coverage report only supported when using GCC") 24 | endif() 25 | if(BUILD_COVERAGE AND NOT BUILD_TESTS) 26 | message(FATAL_ERROR "Code coverage report requires -DBUILD_TESTS=ON") 27 | endif() 28 | 29 | if(ENABLE_PROFILING) 30 | add_definitions(-DENABLE_PROFILING) 31 | endif() 32 | 33 | if(NOT DEFINED ALLSCALE_CHECK_BOUNDS AND CMAKE_BUILD_TYPE STREQUAL "Debug") 34 | set(ALLSCALE_CHECK_BOUNDS "ON") 35 | endif() 36 | 37 | if(ALLSCALE_CHECK_BOUNDS) 38 | add_definitions(-DALLSCALE_CHECK_BOUNDS) 39 | endif() 40 | 41 | if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") 42 | # C flags 43 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -std=c99") 44 | set(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -ggdb") 45 | set(CMAKE_C_FLAGS_RELEASE "-O2") 46 | 47 | # C++ flags 48 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -std=c++14") 49 | set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3 -ggdb") 50 | set(CMAKE_CXX_FLAGS_RELEASE "-O2") 51 | 52 | # Yo Dawg, I heard you like templates! 53 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-900") 54 | 55 | # Disable unused lambda capture warnings for clang 5 and higher 56 | # otherwise clang will correctly report some which are required to work around an MSVC bug 57 | if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9.9) 58 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-lambda-capture") 59 | endif() 60 | 61 | # \[T]/ Praise the sun. There be dragons ahead. 62 | if(NOT USE_ASSERT) 63 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNDEBUG") 64 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNDEBUG") 65 | endif() 66 | 67 | if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") 68 | # allow arbitrary library linking order (in case `-as-needed` is default) 69 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-as-needed") 70 | set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} -Wl,--no-as-needed") 71 | set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-as-needed") 72 | endif() 73 | 74 | if(BUILD_COVERAGE) 75 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage") 76 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") 77 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") 78 | set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} --coverage") 79 | set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage") 80 | endif() 81 | elseif(MSVC) 82 | include(msvc_settings) 83 | set(USE_VALGRIND OFF) 84 | else() 85 | message(FATAL_ERROR "Unhandled Compiler: ${CMAKE_CXX_COMPILER_ID}") 86 | endif() 87 | 88 | # Forward settings for external projects. 89 | set(CMAKE_EXTERNALPROJECT_FORWARDS 90 | -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} 91 | -DCMAKE_C_COMPILER_ARG1=${CMAKE_C_COMPILER_ARG1} 92 | -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} 93 | -DCMAKE_CXX_COMPILER_ARG1=${CMAKE_CXX_COMPILER_ARG1} 94 | -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} 95 | -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} 96 | ) 97 | -------------------------------------------------------------------------------- /code/utils/test/serializer/pairs.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "allscale/utils/serializer/pairs.h" 4 | #include "allscale/utils/serializer/strings.h" 5 | 6 | namespace allscale { 7 | namespace utils { 8 | 9 | struct NotSerializable {}; 10 | 11 | 12 | TEST(Serializer, StdPairs) { 13 | 14 | // check that pairs are recognized as serializable 15 | EXPECT_TRUE((is_serializable>::value)); 16 | EXPECT_TRUE((is_serializable>::value)); 17 | EXPECT_TRUE((is_serializable>::value)); 18 | EXPECT_TRUE((is_serializable>::value)); 19 | EXPECT_TRUE((is_serializable>::value)); 20 | 21 | EXPECT_FALSE((is_serializable>::value)); 22 | EXPECT_FALSE((is_serializable>::value)); 23 | 24 | 25 | 26 | // check support for trivially serializable elements 27 | EXPECT_TRUE((is_trivially_serializable>::value)); 28 | EXPECT_TRUE((is_trivially_serializable>::value)); 29 | EXPECT_TRUE((is_trivially_serializable>::value)); 30 | EXPECT_FALSE((is_trivially_serializable>::value)); 31 | EXPECT_FALSE((is_trivially_serializable>::value)); 32 | 33 | EXPECT_FALSE((is_trivially_serializable>::value)); 34 | EXPECT_FALSE((is_trivially_serializable>::value)); 35 | 36 | } 37 | 38 | TEST(Serializer,StdPairInt) { 39 | // serialize and de-serialize a map 40 | std::pair in {0, 2}; 41 | auto archive = serialize(in); 42 | auto out = deserialize>(archive); 43 | EXPECT_EQ(in,out); 44 | } 45 | 46 | 47 | class SerializableButNotDefaultConstructable { 48 | 49 | int x; 50 | 51 | SerializableButNotDefaultConstructable(int x) : x(x) {} 52 | 53 | public: 54 | 55 | static SerializableButNotDefaultConstructable get(int x) { 56 | return SerializableButNotDefaultConstructable(x); 57 | } 58 | 59 | static SerializableButNotDefaultConstructable load(ArchiveReader& reader) { 60 | return SerializableButNotDefaultConstructable(reader.read()); 61 | } 62 | 63 | void store(ArchiveWriter& writer) const { 64 | writer.write(x); 65 | } 66 | 67 | bool operator==(const SerializableButNotDefaultConstructable& other) const { 68 | return x == other.x; 69 | } 70 | 71 | bool operator<(const SerializableButNotDefaultConstructable& other) const { 72 | return x < other.x; 73 | } 74 | 75 | 76 | friend std::ostream& operator<<(std::ostream& out, const SerializableButNotDefaultConstructable& obj) { 77 | return out << obj.x; 78 | } 79 | 80 | }; 81 | 82 | 83 | TEST(Serializer,StdPairNoDefaultConstructor) { 84 | 85 | // make sure the test type is really not default-constructible 86 | EXPECT_FALSE(std::is_default_constructible::value); 87 | 88 | // but it is serializable 89 | EXPECT_TRUE(is_serializable::value); 90 | 91 | // and so is the enclosing map 92 | EXPECT_TRUE((is_serializable>::value)); 93 | 94 | // serialize and de-serialize a string 95 | std::pair in 96 | { SerializableButNotDefaultConstructable::get(1), SerializableButNotDefaultConstructable::get(2) }; 97 | 98 | auto archive = serialize(in); 99 | auto out = deserialize>(archive); 100 | 101 | EXPECT_EQ(in,out); 102 | } 103 | 104 | } // end namespace utils 105 | } // end namespace allscale 106 | -------------------------------------------------------------------------------- /code/api/test/core/impl/reference/task_id.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "allscale/api/core/impl/reference/task_id.h" 6 | 7 | #include "allscale/utils/string_utils.h" 8 | 9 | #include "allscale/utils/printer/vectors.h" 10 | 11 | namespace allscale { 12 | namespace api { 13 | namespace core { 14 | namespace impl { 15 | namespace reference { 16 | 17 | bool isParentOf(const TaskID& a, const TaskID& b) { 18 | return a.isParentOf(b); 19 | } 20 | 21 | bool isNotParentOf(const TaskID& a, const TaskID& b) { 22 | return !a.isParentOf(b); 23 | } 24 | 25 | TEST(TaskPath, TypeProperties) { 26 | EXPECT_EQ(0, TaskPath::Left); 27 | EXPECT_EQ(1, TaskPath::Right); 28 | } 29 | 30 | TEST(TaskID, TypeProperties) { 31 | 32 | EXPECT_TRUE(std::is_default_constructible::value); 33 | EXPECT_TRUE(std::is_trivially_constructible::value); 34 | 35 | EXPECT_TRUE(std::is_trivially_copy_constructible::value); 36 | EXPECT_TRUE(std::is_trivially_copy_assignable::value); 37 | 38 | EXPECT_TRUE(std::is_trivially_move_constructible::value); 39 | EXPECT_TRUE(std::is_trivially_move_assignable::value); 40 | 41 | } 42 | 43 | TEST(TaskID, Basic) { 44 | 45 | TaskID a = 12; 46 | EXPECT_EQ("T-12",toString(a)); 47 | 48 | TaskID b = a; 49 | EXPECT_EQ(a,b); 50 | 51 | auto c = a.getLeftChild(); 52 | auto d = a.getRightChild(); 53 | 54 | EXPECT_NE(a,c); 55 | EXPECT_NE(a,d); 56 | EXPECT_NE(c,d); 57 | 58 | EXPECT_EQ("T-12.0",toString(c)); 59 | EXPECT_EQ("T-12.1",toString(d)); 60 | 61 | EXPECT_EQ("T-12.1.0.0",toString(d.getLeftChild().getLeftChild())); 62 | EXPECT_EQ("T-12.1.0.1",toString(d.getLeftChild().getRightChild())); 63 | EXPECT_EQ("T-12.1.1.0",toString(d.getRightChild().getLeftChild())); 64 | EXPECT_EQ("T-12.1.1.1",toString(d.getRightChild().getRightChild())); 65 | 66 | EXPECT_EQ("T-12.1.0.0.0",toString(d.getLeftChild().getLeftChild().getLeftChild())); 67 | EXPECT_EQ("T-12.1.0.0.1",toString(d.getLeftChild().getLeftChild().getRightChild())); 68 | EXPECT_EQ("T-12.1.0.1.0",toString(d.getLeftChild().getRightChild().getLeftChild())); 69 | EXPECT_EQ("T-12.1.0.1.1",toString(d.getLeftChild().getRightChild().getRightChild())); 70 | EXPECT_EQ("T-12.1.1.0.0",toString(d.getRightChild().getLeftChild().getLeftChild())); 71 | EXPECT_EQ("T-12.1.1.0.1",toString(d.getRightChild().getLeftChild().getRightChild())); 72 | EXPECT_EQ("T-12.1.1.1.0",toString(d.getRightChild().getRightChild().getLeftChild())); 73 | EXPECT_EQ("T-12.1.1.1.1",toString(d.getRightChild().getRightChild().getRightChild())); 74 | 75 | EXPECT_PRED2(isNotParentOf,a,a); 76 | EXPECT_PRED2(isNotParentOf,a,b); 77 | 78 | EXPECT_PRED2(isParentOf,a,c); 79 | EXPECT_PRED2(isParentOf,a,d); 80 | 81 | EXPECT_PRED2(isParentOf,a,c.getLeftChild()); 82 | EXPECT_PRED2(isParentOf,a,c.getRightChild()); 83 | 84 | } 85 | 86 | 87 | TEST(TaskID, Order) { 88 | 89 | std::vector list { 90 | TaskID(12), 91 | TaskID(14), 92 | TaskID(12).getLeftChild(), 93 | TaskID(12).getRightChild().getRightChild(), 94 | TaskID(12).getRightChild(), 95 | TaskID(12).getLeftChild().getLeftChild() 96 | }; 97 | 98 | std::sort(list.begin(),list.end()); 99 | 100 | EXPECT_EQ("[T-12,T-12.0,T-12.0.0,T-12.1,T-12.1.1,T-14]",toString(list)); 101 | 102 | for(auto itA = list.begin(); itA != list.end(); ++itA) { 103 | for(auto itB = list.begin(); itB != list.end(); ++itB) { 104 | 105 | auto a = *itA; 106 | auto b = *itB; 107 | 108 | if (itA < itB) { 109 | EXPECT_LT(a,b); 110 | } else if (itA == itB) { 111 | EXPECT_FALSE(a < b); 112 | EXPECT_EQ(a,b); 113 | } else { 114 | EXPECT_LT(b,a); 115 | } 116 | } 117 | } 118 | 119 | } 120 | 121 | } // end namespace reference 122 | } // end namespace impl 123 | } // end namespace core 124 | } // end namespace api 125 | } // end namespace allscale 126 | -------------------------------------------------------------------------------- /code/api/include/allscale/api/user/save_to_binary.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "allscale/api/core/io.h" 4 | #include "allscale/api/user/algorithm/pfor.h" 5 | 6 | 7 | namespace allscale { 8 | namespace api { 9 | namespace user { 10 | 11 | // Save vector of vectors to binary in parallel 12 | template 13 | void saveVecVecToFile(std::vector> vecVec, std::string filename, size_t innerSize) { 14 | core::FileIOManager& manager = core::FileIOManager::getInstance(); 15 | size_t outerSize = vecVec.size(); 16 | 17 | // generate output data 18 | core::Entry binary = manager.createEntry(filename, core::Mode::Binary); 19 | auto fout = manager.openOutputStream(binary); 20 | 21 | // fout.write(innerSize); 22 | 23 | std::vector idxVec; 24 | for(size_t i = 0; i < innerSize; ++i) 25 | idxVec.push_back(i); 26 | 27 | algorithm::pfor(idxVec, [&](size_t& i) { 28 | fout.atomic([&](auto& out) { 29 | // write preamble 30 | out.write(i); 31 | 32 | // write data 33 | for(size_t j = 0; j < outerSize; ++j) { 34 | out.write(vecVec[j][i]); 35 | } 36 | }); 37 | }); 38 | 39 | manager.close(fout); 40 | 41 | } 42 | 43 | template 44 | void saveVecVecToFileMM(std::vector> vecVec, std::string filename, unsigned outerSize, unsigned innerSize) { 45 | core::FileIOManager& manager = core::FileIOManager::getInstance(); 46 | 47 | // generate output data 48 | core::Entry binary = manager.createEntry(filename, core::Mode::Binary); 49 | core::MemoryMappedOutput fout = manager.openMemoryMappedOutput(binary, sizeof(T)* outerSize*innerSize); 50 | 51 | std::vector idxVec; 52 | for(size_t i = 0; i < innerSize; ++i) 53 | idxVec.push_back(i); 54 | 55 | auto dataOut = &fout.access();//std::array>(); 56 | algorithm::pfor(idxVec, [&](size_t& i) { 57 | // write data 58 | for(size_t j = 0; j < outerSize; ++j) { 59 | dataOut[i*outerSize + j] = vecVec[j][i]; 60 | } 61 | }); 62 | manager.close(fout); 63 | } 64 | 65 | // Read vector of vectors to binary in parallel 66 | template 67 | std::vector> readVecVecFromFile(std::string filename, size_t outerSize, size_t innerSize) { 68 | std::vector> vecVec; 69 | core::FileIOManager& manager = core::FileIOManager::getInstance(); 70 | 71 | core::Entry binary = manager.createEntry(filename, core::Mode::Binary); 72 | auto fin = manager.openInputStream(binary); 73 | 74 | for(size_t j = 0; j < outerSize; ++j) { 75 | vecVec.push_back(std::vector()); 76 | for(size_t i = 0; i < innerSize; ++i) 77 | vecVec[j].push_back(T()); 78 | } 79 | 80 | for(size_t i = 0; i < innerSize; ++i) { 81 | // read position from file 82 | size_t idx = fin.read(); 83 | 84 | for(size_t j = 0; j < outerSize; ++j) { 85 | // read data 86 | vecVec[j][idx] = (fin.read()); 87 | } 88 | } 89 | 90 | manager.close(fin); 91 | return vecVec; 92 | } 93 | 94 | 95 | // Read vector of vectors to binary in parallel 96 | template 97 | std::vector> readVecVecFromFileMM(std::string filename, unsigned outerSize, unsigned innerSize) { 98 | std::vector> vecVec; 99 | core::FileIOManager& manager = core::FileIOManager::getInstance(); 100 | 101 | core::Entry binary = manager.createEntry(filename, core::Mode::Binary); 102 | auto fin = manager.openMemoryMappedInput(binary); 103 | auto dataIn = &fin.access();//>(); 104 | 105 | for(size_t j = 0; j < outerSize; ++j) { 106 | vecVec.push_back(std::vector()); 107 | for(size_t i = 0; i < innerSize; ++i) 108 | vecVec[j].push_back(T()); 109 | } 110 | 111 | for(size_t i = 0; i < innerSize; ++i) { 112 | for(size_t j = 0; j < outerSize; ++j) { 113 | // read data 114 | vecVec[j][i] = dataIn[i*outerSize + j]; 115 | } 116 | } 117 | 118 | manager.close(fin); 119 | return vecVec; 120 | } 121 | 122 | } // end namespace user 123 | } // end namespace api 124 | } // end namespace allscale 125 | -------------------------------------------------------------------------------- /scripts/dependencies/README.md: -------------------------------------------------------------------------------- 1 | # Dependencies Installer 2 | 3 | These scripts ease the environment setup procedure required to build this 4 | project. Each file with the prefix `package_` contains meta data and build 5 | instructions for a specific package as well as its dependencies. A default set 6 | of instructions is inherited from `defaults.sh`, but can be overwritten by each 7 | package. 8 | 9 | The `installer` can be used to install packages, dependencies will be resolved 10 | automatically. Simply provide the name of the packages which should be 11 | installed as arguments to the installer. 12 | 13 | $ ./installer gcc ruby valgrind 14 | 15 | The default `PREFIX` is set in `defaults.sh` and can be overwritten via an 16 | environment variable: 17 | 18 | $ PREFIX=/opt/custom-libs ./installer gcc ruby valgrind 19 | 20 | While `PREFIX` takes precedence, the environment variable `THIRD_PARTY_LIBS` is 21 | also considered. 22 | 23 | ## Patches 24 | 25 | The default `pkg_prepare` action will apply all patches inside the `patches` 26 | directory which are prefixed with the package name. The order is inferred from 27 | the filename which should have the following structure: 28 | 29 | --.patch 30 | 31 | Examples: 32 | 33 | boost-0001-regex-fix.patch 34 | llvm-0001-insieme-clang.patch 35 | llvm-0002-fix-typos.patch 36 | 37 | ## Third Party Sym-Linker 38 | 39 | All packages installed by the installer are separated by their name and 40 | version, this allows one to have multiple versions of a package installed 41 | side-by-side. Hence the content of `PREFIX` can be shared across multiple 42 | projects. 43 | 44 | In order for a project to find its required dependencies another layer of 45 | indirection has to be added. 46 | 47 | Each project should contain a `third_party` folder inside the project's build 48 | directory. This folder should contain symlinks, one for each dependency, 49 | pointing to the installed package in `PREFIX`. The `third_party` folder should 50 | not contain different versions of the same package. Example: 51 | 52 | $ PREFIX="$HOME/third_party_libs" 53 | $ ls -l $PREFIX 54 | drwxr-xr-x. 4 alex dps 4.0K Nov 18 15:14 autoconf-2.68/ 55 | drwxr-xr-x. 4 alex dps 4.0K Nov 18 15:14 automake-1.15/ 56 | drwxr-xr-x. 7 alex dps 4.0K Nov 18 15:14 binutils-2.27/ 57 | drwxr-xr-x. 5 alex dps 4.0K Nov 18 15:14 bison-3.0.4/ 58 | drwxr-xr-x. 4 alex dps 4.0K Nov 18 15:14 boost-1.50.0/ 59 | drwxr-xr-x. 4 alex dps 4.0K Nov 18 15:14 boost-1.59.0/ 60 | drwxr-xr-x. 5 alex dps 4.0K Nov 18 15:14 cmake-3.2.1/ 61 | drwxr-xr-x. 5 alex dps 4.0K Nov 18 15:14 cmake-3.6.1/ 62 | ... 63 | $ ls -l MyAwesomeProject/build/third_party 64 | lrwxrwxrwx. 1 alex dps 47 Nov 22 13:17 autoconf -> /home/alex/third_party_libs/autoconf-2.68/ 65 | lrwxrwxrwx. 1 alex dps 47 Nov 22 13:17 automake -> /home/alex/third_party_libs/automake-1.15/ 66 | lrwxrwxrwx. 1 alex dps 47 Nov 22 13:17 binutils -> /home/alex/third_party_libs/binutils-2.27/ 67 | lrwxrwxrwx. 1 alex dps 45 Nov 22 13:17 bison -> /home/alex/third_party_libs/bison-3.0.4/ 68 | lrwxrwxrwx. 1 alex dps 46 Nov 22 13:17 boost -> /home/alex/third_party_libs/boost-1.59.0/ 69 | lrwxrwxrwx. 1 alex dps 45 Nov 22 13:17 cmake -> /home/alex/third_party_libs/cmake-3.2.1/ 70 | ... 71 | 72 | The `third_party_linker` can create these symlinks for you, it uses the same 73 | version of a package as defined in the related `package_` file. The folder 74 | `third_party` is created in the current working directory when invoking 75 | `third_party_linker`. 76 | 77 | ## Custom GCC 78 | 79 | If you chose to use GCC provided by the installer, `PATH` and `LD_LIBRARY_PATH` 80 | should be set accordingly. 81 | 82 | export PATH="$PREFIX/gcc-$GCC_VERSION/bin:$PATH" 83 | export LD_LIBRARY_PATH="$PREFIX/gcc-$GCC_VERSION/lib64" 84 | 85 | ## Use custom GCC for dependency Installation 86 | 87 | After installing GCC via this installer, open `default.sh` with an editor and 88 | set `CC`, `CXX`, `PATH` and `LD_LIBRARY_PATH` to the newly installed GCC. 89 | Continue the installation process. 90 | --------------------------------------------------------------------------------