├── download_example ├── use-cmake.tipi └── CMakeLists.txt ├── .gitignore ├── .tipi ├── opts └── deps ├── doc └── techreport_lffvs.pdf ├── ext └── dset │ ├── README.md │ ├── LICENSE.txt │ └── dset.h ├── .github └── workflows │ ├── tipi.yml │ └── master.yml ├── mapmap ├── source │ ├── termination_criterion.impl.h │ ├── timer.impl.h │ ├── instance_factory.impl.h │ ├── termination_instances │ │ ├── stop_after_time.impl.h │ │ ├── stop_after_iterations.impl.h │ │ ├── stop_when_flat.impl.h │ │ └── stop_when_returns_diminish.impl.h │ ├── optimizer_instances │ │ └── envelope_instances │ │ │ ├── pairwise_potts_envelope.impl.h │ │ │ ├── pairwise_truncated_linear_envelope.impl.h │ │ │ ├── pairwise_antipotts_envelope.impl.h │ │ │ └── pairwise_truncated_quadratic_envelope.impl.h │ ├── cost_bundle.impl.h │ ├── tree_sampler.impl.h │ ├── cost_instances │ │ ├── unary_table.impl.h │ │ ├── pairwise_potts.impl.h │ │ ├── pairwise_antipotts.impl.h │ │ ├── pairwise_linear_peak.impl.h │ │ ├── pairwise_truncated_linear.impl.h │ │ └── pairwise_truncated_quadratic.impl.h │ ├── multilevel_instances │ │ └── group_same_label.impl.h │ ├── color.impl.h │ └── tree_optimizer.impl.h ├── header │ ├── termination_instances │ │ ├── stop_after_time.h │ │ ├── stop_when_flat.h │ │ ├── stop_when_returns_diminish.h │ │ └── stop_after_iterations.h │ ├── optimizer_instances │ │ ├── dp_node_solver_factory.h │ │ ├── dp_node.h │ │ ├── envelope.h │ │ ├── envelope_instances │ │ │ ├── pairwise_potts_envelope.h │ │ │ ├── pairwise_antipotts_envelope.h │ │ │ ├── pairwise_linear_peak_envelope.h │ │ │ ├── pairwise_truncated_linear_envelope.h │ │ │ └── pairwise_truncated_quadratic_envelope.h │ │ ├── dp_node_solver.h │ │ └── dynamic_programming.h │ ├── timer.h │ ├── multilevel_instances │ │ └── group_same_label.h │ ├── instance_factory.h │ ├── color.h │ ├── settings.h │ ├── defines.h │ ├── cost_instances │ │ ├── unary_table.h │ │ ├── pairwise_antipotts.h │ │ ├── pairwise_potts.h │ │ ├── pairwise_linear_peak.h │ │ ├── pairwise_truncated_linear.h │ │ ├── pairwise_truncated_quadratic.h │ │ └── pairwise_table.h │ ├── tree_sampler.h │ ├── cost_bundle.h │ ├── termination_criterion.h │ ├── graph.h │ ├── tree_optimizer.h │ ├── parallel_templates.h │ ├── tree_sampler_instances │ │ ├── optimistic_tree_sampler.h │ │ └── lock_free_tree_sampler.h │ ├── tree.h │ ├── dynamic_programming.h │ ├── costs.h │ ├── vector_types.h │ ├── multilevel.h │ └── mapmap.h └── full.h ├── test ├── util_test.h ├── test_coloring.cc ├── test_graph.cc ├── util_test.impl.h └── test_coordinate_set.cc └── LICENSE.txt /download_example/use-cmake.tipi: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .git 2 | build 3 | gtest 4 | datasets 5 | **/*.bin 6 | .vscode 7 | -------------------------------------------------------------------------------- /.tipi/opts: -------------------------------------------------------------------------------- 1 | set (TBB_TEST OFF CACHE BOOL "") 2 | add_compile_definitions(BUILD_FOR_TEST) -------------------------------------------------------------------------------- /doc/techreport_lffvs.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dthuerck/mapmap_cpu/HEAD/doc/techreport_lffvs.pdf -------------------------------------------------------------------------------- /download_example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(DOWNLOAD http://download.hrz.tu-darmstadt.de/media/FB20/GCC/project_files/mapmap/planesweep_320_256_96.bin ${CMAKE_BINARY_DIR}/demo/planesweep_320_256_96.bin) 2 | -------------------------------------------------------------------------------- /.tipi/deps: -------------------------------------------------------------------------------- 1 | { 2 | "google/googletest": { "u": true, "packages": ["GTest"], "targets": ["GTest::gtest", "GTest::gmock"] } 3 | , "oneapi-src/oneTBB" : { "@" : "v2021.5.0" , "u" : true, "packages": ["TBB"], "targets": ["TBB::tbb", "TBB::tbbmalloc"] } 4 | } -------------------------------------------------------------------------------- /ext/dset/README.md: -------------------------------------------------------------------------------- 1 | # Lock-free parallel disjoint set data structure 2 | 3 | This is a small self-contained C++11 implementation of the UNION-FIND data 4 | structure with path compression and union by rank and a few extras It supports 5 | concurrent `find()`, `same()` and `unite()` calls as described in the paper 6 | 7 | *Wait-free Parallel Algorithms for the Union-Find Problem* 8 | by Richard J. Anderson and Heather Woll 9 | 10 | In addition, this class supports optimistic locking (`try_lock()`/`unlock()`) 11 | of disjoint sets and a *combined* unite+unlock operation for pairs of sets. 12 | -------------------------------------------------------------------------------- /.github/workflows/tipi.yml: -------------------------------------------------------------------------------- 1 | name: tipi.build 2 | # This workflow is triggered on pushes to the repository. 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | name: build-linux 8 | runs-on: ubuntu-latest 9 | container: tipibuild/tipi-ubuntu 10 | steps: 11 | - name: checkout 12 | uses: actions/checkout@v2 13 | - name: tipi builds project 14 | run: | 15 | export HOME=/root 16 | mkdir -p ~/.tipi 17 | 18 | mkdir -p build/linux/bin/demo \ 19 | && curl http://download.hrz.tu-darmstadt.de/media/FB20/GCC/project_files/mapmap/planesweep_320_256_96.bin --output build/linux/bin/demo/planesweep_320_256_96.bin 20 | 21 | tipi . -t linux --dont-upgrade --verbose --test all 22 | -------------------------------------------------------------------------------- /mapmap/source/termination_criterion.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | 12 | NS_MAPMAP_BEGIN 13 | 14 | template 15 | TerminationCriterion:: 16 | TerminationCriterion() 17 | { 18 | 19 | } 20 | 21 | /* ************************************************************************** */ 22 | 23 | template 24 | TerminationCriterion:: 25 | ~TerminationCriterion() 26 | { 27 | 28 | } 29 | 30 | NS_MAPMAP_END 31 | -------------------------------------------------------------------------------- /ext/dset/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Wenzel Jakob 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. 18 | -------------------------------------------------------------------------------- /.github/workflows/master.yml: -------------------------------------------------------------------------------- 1 | name: 'build' 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - staging 8 | pull_request: 9 | types: [ opened, reopened ] 10 | 11 | jobs: 12 | build-artifacts: 13 | runs-on: ubuntu-20.04 14 | steps: 15 | - name: Build 16 | run: | 17 | a=`pwd` 18 | sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test 19 | sudo apt-get update 20 | sudo apt-get --allow-unauthenticated install -qq gcc-9 21 | sudo apt-get --allow-unauthenticated install -qq g++-9 22 | sudo apt-get --allow-unauthenticated install -qq git 23 | export CXX="g++-9" 24 | export CC="gcc-9" 25 | cd $a 26 | git clone https://github.com/dthuerck/mapmap_cpu.git . 27 | git checkout ${GITHUB_REF##*/} 28 | mkdir build 29 | cd build 30 | cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DBUILD_MEMSAVE=OFF -DBUILD_TEST=ON -DBUILD_DEMO=ON .. && make && ./mapmap_test 31 | cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DBUILD_MEMSAVE=ON -DBUILD_TEST=ON -DBUILD_DEMO=ON .. && make && ./mapmap_test -------------------------------------------------------------------------------- /mapmap/header/termination_instances/stop_after_time.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_STOP_AFTER_TIME_H_ 11 | #define __MAPMAP_STOP_AFTER_TIME_H_ 12 | 13 | #include 14 | 15 | NS_MAPMAP_BEGIN 16 | 17 | template 18 | class StopAfterTime : public TerminationCriterion 19 | { 20 | public: 21 | StopAfterTime(const luint_t max_seconds, 22 | const bool compute_before_iteration); 23 | ~StopAfterTime(); 24 | 25 | virtual bool check_termination(const SolverHistory * history); 27 | 28 | protected: 29 | luint_t m_max_seconds; 30 | bool m_compute_before_iteration; 31 | }; 32 | 33 | NS_MAPMAP_END 34 | 35 | /* include function implementations */ 36 | #include 37 | 38 | #endif /* __MAPMAP_STOP_AFTER_TIME_H_ */ 39 | -------------------------------------------------------------------------------- /mapmap/header/termination_instances/stop_when_flat.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_STOP_WHEN_FLAT_H_ 11 | #define __MAPMAP_STOP_WHEN_FLAT_H_ 12 | 13 | #include 14 | 15 | NS_MAPMAP_BEGIN 16 | 17 | template 18 | class StopWhenFlat : public TerminationCriterion 19 | { 20 | public: 21 | StopWhenFlat(const luint_t num_allowed_flat_iterations, 22 | const bool reset_after_improvement); 23 | ~StopWhenFlat(); 24 | 25 | virtual bool check_termination(const SolverHistory * history); 27 | 28 | protected: 29 | luint_t m_num_allowed_flat_iterations; 30 | bool m_reset_after_improvement; 31 | }; 32 | 33 | NS_MAPMAP_END 34 | 35 | /* include function implementations */ 36 | #include 37 | 38 | #endif /* __MAPMAP_STOP_WHEN_FLAT_H_ */ 39 | -------------------------------------------------------------------------------- /mapmap/header/optimizer_instances/dp_node_solver_factory.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_DP_NODE_SOLVER_FACTORY_H_ 11 | #define __MAPMAP_DP_NODE_SOLVER_FACTORY_H_ 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | NS_MAPMAP_BEGIN 20 | 21 | template 22 | class DPNodeSolverFactory 23 | { 24 | public: 25 | static DPNodeSolver_ptr get_enumerative_solver( 26 | DPNode * node); 27 | static DPNodeSolver_ptr get_solver( 28 | DPNode * node); 29 | }; 30 | 31 | NS_MAPMAP_END 32 | 33 | /* include function implementations */ 34 | #include 35 | 36 | #endif /* __MAPMAP_DP_NODE_SOLVER_FACTORY_H_ */ -------------------------------------------------------------------------------- /mapmap/header/timer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_TIMER_H_ 11 | #define __MAPMAP_TIMER_H_ 12 | 13 | #include 14 | 15 | NS_MAPMAP_BEGIN 16 | 17 | using t_point = std::chrono::time_point; 18 | struct _timer 19 | { 20 | _timer(); 21 | ~_timer(); 22 | 23 | void start(const std::string& s); 24 | void stop(const std::string& s); 25 | double get_ms(const std::string& s); 26 | 27 | std::map m_t_start; 28 | std::map m_t_end; 29 | }; 30 | 31 | extern _timer * __T; 32 | 33 | #define START_TIMER(str) (__T->start(str)); 34 | #define STOP_TIMER(str) (__T->stop(str)); 35 | #define PRINT_TIMER(str) (printf("(Timing) %s: %f ms\n", str, __T->get_ms(str))); 36 | #define GET_TIMER(str) (__T->get_ms(str)); 37 | 38 | NS_MAPMAP_END 39 | 40 | /* include timer implementation */ 41 | #include 42 | 43 | #endif /* __MAPMAP_TIMER_H_ */ -------------------------------------------------------------------------------- /mapmap/header/multilevel_instances/group_same_label.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_GROUP_SAME_LABEL_H_ 11 | #define __MAPMAP_GROUP_SAME_LABEL_H_ 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | NS_MAPMAP_BEGIN 19 | 20 | template 21 | class GroupSameLabel : 22 | public MultilevelCriterion 23 | { 24 | public: 25 | GroupSameLabel(); 26 | ~GroupSameLabel(); 27 | 28 | void group_nodes(std::vector& node_in_group, 29 | const LevelSet * current_level, 30 | const std::vector<_iv_st>& current_solution, 31 | std::vector<_iv_st>& projected_solution); 32 | }; 33 | 34 | NS_MAPMAP_END 35 | 36 | /* include function implementations */ 37 | #include 38 | 39 | #endif /* __MAPMAP_GROUP_SAME_LABEL_H_ */ 40 | -------------------------------------------------------------------------------- /mapmap/header/termination_instances/stop_when_returns_diminish.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_STOP_WHEN_RETURNS_DIMINISH_H_ 11 | #define __MAPMAP_STOP_WHEN_RETURNS_DIMINISH_H_ 12 | 13 | #include 14 | 15 | NS_MAPMAP_BEGIN 16 | 17 | template 18 | class StopWhenReturnsDiminish : public TerminationCriterion 19 | { 20 | public: 21 | StopWhenReturnsDiminish(const luint_t iteration_span, 22 | const _s_t improv_threshold); 23 | ~StopWhenReturnsDiminish(); 24 | 25 | virtual bool check_termination(const SolverHistory * history); 27 | 28 | protected: 29 | luint_t m_iteration_span; 30 | _s_t m_improv_threshold; 31 | }; 32 | 33 | NS_MAPMAP_END 34 | 35 | #include 36 | 37 | #endif /* __MAPMAP_STOP_WHEN_RETURNS_DIMINISH_H_ */ -------------------------------------------------------------------------------- /mapmap/header/instance_factory.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_INSTANCE_FACTORY_H_ 11 | #define __MAPMAP_INSTANCE_FACTORY_H_ 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | NS_MAPMAP_BEGIN 22 | 23 | /* ************************************************************************** */ 24 | 25 | template 26 | class InstanceFactory 27 | { 28 | public: 29 | static std::unique_ptr> 30 | get_sampler_instance( 31 | const TREE_SAMPLER_ALGORITHM& alg, 32 | Graph * graph, 33 | const bool deterministic, 34 | const uint_t seed); 35 | }; 36 | 37 | NS_MAPMAP_END 38 | 39 | /* include function implementations */ 40 | #include 41 | 42 | #endif /* __MAPMAP_INSTANCE_FACTORY_H_ */ -------------------------------------------------------------------------------- /mapmap/header/termination_instances/stop_after_iterations.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_STOP_AFTER_ITERATIONS_H_ 11 | #define __MAPMAP_STOP_AFTER_ITERATIONS_H_ 12 | 13 | #include 14 | 15 | NS_MAPMAP_BEGIN 16 | 17 | template 18 | class StopAfterIterations : public TerminationCriterion 19 | { 20 | public: 21 | StopAfterIterations( 22 | const luint_t max_iterations, 23 | const bool count_acyclic, 24 | const bool count_spanningtree, 25 | const bool multilevel); 26 | ~StopAfterIterations(); 27 | 28 | virtual bool check_termination(const SolverHistory * history); 30 | 31 | protected: 32 | luint_t m_max_iterations; 33 | bool m_count_acyclic; 34 | bool m_count_spanningtree; 35 | bool m_count_multilevel; 36 | }; 37 | 38 | NS_MAPMAP_END 39 | 40 | /* include function implementations */ 41 | #include 42 | 43 | #endif /* __MAPMAP_STOP_AFTER_ITERATIONS_H_ */ 44 | -------------------------------------------------------------------------------- /mapmap/header/color.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_COLOR_H_ 11 | #define __MAPMAP_COLOR_H_ 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | NS_MAPMAP_BEGIN 19 | 20 | /** 21 | * Implements an optimistic graph coloring based on 22 | * 23 | * A. H. Gebremedhin and F. Manne, “Scalable parallel graph coloring 24 | * algorithms,” Concurrency: Practice & Experience, vol. 12, no. 12, pp. 25 | * 1131–1146, 2000 26 | */ 27 | 28 | template 29 | class Color 30 | { 31 | public: 32 | Color(Graph& graph); 33 | Color(Graph& graph, const bool deterministic); 34 | ~Color(); 35 | 36 | void color_graph(std::vector& coloring); 37 | 38 | protected: 39 | Graph& m_graph; 40 | 41 | /* deterministic (serial) handling */ 42 | const bool m_deterministic; 43 | 44 | tbb::concurrent_vector m_conf_a; 45 | tbb::concurrent_vector m_conf_b; 46 | }; 47 | 48 | NS_MAPMAP_END 49 | 50 | #include 51 | 52 | #endif /* __MAPMAP_COLOR_H_ */ -------------------------------------------------------------------------------- /mapmap/source/timer.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | 12 | NS_MAPMAP_BEGIN 13 | 14 | _timer:: 15 | _timer() 16 | : m_t_start(), 17 | m_t_end() 18 | { 19 | } 20 | 21 | /* ************************************************************************** */ 22 | 23 | _timer:: 24 | ~_timer() 25 | { 26 | 27 | } 28 | 29 | /* ************************************************************************** */ 30 | 31 | void 32 | _timer:: 33 | start( 34 | const std::string& s) 35 | { 36 | m_t_start[s] = std::chrono::system_clock::now(); 37 | } 38 | 39 | /* ************************************************************************** */ 40 | 41 | void 42 | _timer:: 43 | stop( 44 | const std::string& s) 45 | { 46 | m_t_end[s] = std::chrono::system_clock::now(); 47 | } 48 | 49 | /* ************************************************************************** */ 50 | 51 | double 52 | _timer:: 53 | get_ms( 54 | const std::string& s) 55 | { 56 | std::chrono::duration elapsed_seconds = m_t_end[s] - m_t_start[s]; 57 | return (elapsed_seconds.count() * 1000); 58 | } 59 | 60 | _timer * __T = new _timer(); 61 | 62 | NS_MAPMAP_END -------------------------------------------------------------------------------- /mapmap/source/instance_factory.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | NS_MAPMAP_BEGIN 16 | 17 | template 18 | std::unique_ptr> 19 | InstanceFactory:: 20 | get_sampler_instance( 21 | const TREE_SAMPLER_ALGORITHM& alg, 22 | Graph * graph, 23 | const bool deterministic, 24 | const uint_t seed) 25 | { 26 | if(alg == OPTIMISTIC_TREE_SAMPLER) 27 | { 28 | return std::unique_ptr>( 29 | new OptimisticTreeSampler(graph, deterministic, 30 | seed)); 31 | } 32 | 33 | if(alg == LOCK_FREE_TREE_SAMPLER) 34 | { 35 | return std::unique_ptr>( 36 | new LockFreeTreeSampler(graph, deterministic, 37 | seed)); 38 | } 39 | 40 | return std::unique_ptr>(nullptr); 41 | } 42 | 43 | NS_MAPMAP_END -------------------------------------------------------------------------------- /test/util_test.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_UTIL_TEST_H_ 11 | #define __MAPMAP_UTIL_TEST_H_ 12 | 13 | #include 14 | 15 | #include "header/defines.h" 16 | #include "header/vector_types.h" 17 | #include "header/graph.h" 18 | #include "header/tree.h" 19 | 20 | NS_MAPMAP_BEGIN 21 | 22 | /* 23 | * Create a grid-graph with a number of connected components (i.e. 24 | * create that number of component_dim x component_dim 4-connected 25 | * grids in one graph). 26 | * Save directly in m_graph. 27 | */ 28 | template 29 | std::unique_ptr> 30 | createComponentGrid( 31 | const uint_t num_components, 32 | const uint_t component_dim); 33 | 34 | template 35 | void 36 | BFSWithCustomFunc( 37 | Tree * tree, 38 | const luint_t& root_id, 39 | std::function*, const luint_t)> 40 | per_node_func); 41 | 42 | /* comparison of vectors */ 43 | template 44 | bool 45 | cmp_vector( 46 | const std::vector& a, 47 | const std::vector& b, 48 | const size_t len = 0); 49 | 50 | NS_MAPMAP_END 51 | 52 | /* include templated implementation */ 53 | #include "test/util_test.impl.h" 54 | 55 | #endif /* __MAPMAP_UTIL_TEST_H_ */ -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Daniel Thuerck 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of mapmap_cpu nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /mapmap/header/settings.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_MAPMAP_SETTINGS_H_ 11 | #define __MAPMAP_MAPMAP_SETTINGS_H_ 12 | 13 | #include 14 | #include 15 | 16 | NS_MAPMAP_BEGIN 17 | 18 | /* 0s mark the default algorithm */ 19 | enum TREE_SAMPLER_ALGORITHM 20 | { 21 | OPTIMISTIC_TREE_SAMPLER = 0, 22 | LOCK_FREE_TREE_SAMPLER = 1 23 | }; 24 | 25 | /** 26 | * control flow struct (default values for flowgraph in paper) 27 | * 28 | * NOTE: despite settings concerning minimum iteration numbers, early 29 | * termination may be forced by a user-defined termination criterion 30 | */ 31 | struct mapMAP_control 32 | { 33 | /* switch modes on/off */ 34 | bool use_multilevel; 35 | bool use_spanning_tree; 36 | bool use_acyclic; 37 | 38 | /* multilevel settings */ 39 | /* none */ 40 | 41 | /* spanning tree settings */ 42 | uint_t spanning_tree_multilevel_after_n_iterations; 43 | 44 | /* acyclic settings */ 45 | bool force_acyclic; /* force using acyclic even if terminated */ 46 | uint_t min_acyclic_iterations; 47 | bool relax_acyclic_maximal; 48 | 49 | /* settings for tree sampling */ 50 | TREE_SAMPLER_ALGORITHM tree_algorithm; 51 | bool sample_deterministic; 52 | uint_t initial_seed; 53 | }; 54 | 55 | NS_MAPMAP_END 56 | 57 | #endif /* __MAPMAP_MAPMAP_SETTINGS_H_ */ 58 | -------------------------------------------------------------------------------- /mapmap/header/defines.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_DEFINES_H_ 11 | #define __MAPMAP_DEFINES_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | /* 18 | * ***************************************************************************** 19 | * ************************* Parallelization control *************************** 20 | * ***************************************************************************** 21 | */ 22 | 23 | #define BFS_ROOTS 32u 24 | #define DIV_UP(A, V) (A / V + (A % V == 0 ? 0 : 1)) 25 | 26 | /* 27 | * ***************************************************************************** 28 | * ************************** OS-dependent brainfuck *************************** 29 | * ***************************************************************************** 30 | */ 31 | #ifdef _MSC_VER 32 | #define FORCEINLINE __forceinline 33 | #else 34 | #define FORCEINLINE __attribute__((always_inline)) inline 35 | #endif 36 | 37 | /* 38 | * ***************************************************************************** 39 | * *************************** Namespace definitions *************************** 40 | * ***************************************************************************** 41 | */ 42 | 43 | #define NS_MAPMAP mapmap 44 | 45 | #define NS_MAPMAP_BEGIN namespace NS_MAPMAP { 46 | #define NS_MAPMAP_END } 47 | 48 | #endif /* __MAPMAP_DEFINES_H_ */ -------------------------------------------------------------------------------- /mapmap/header/cost_instances/unary_table.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_UNARY_TABLE_H_ 11 | #define __MAPMAP_UNARY_TABLE_H_ 12 | 13 | #include 14 | 15 | #include 16 | 17 | NS_MAPMAP_BEGIN 18 | 19 | template 20 | class UnaryTable : public UnaryCosts 21 | { 22 | public: 23 | UnaryTable( 24 | const luint_t node_id, 25 | const LabelSet * label_set); 26 | ~UnaryTable(); 27 | 28 | /* Builder functions */ 29 | void set_costs(const std::vector<_s_t>& costs); 30 | _s_t * get_raw_costs(); 31 | 32 | /* Interface functions */ 33 | virtual bool supports_enumerable_costs() const; 34 | 35 | virtual _v_t get_unary_costs( 36 | const _iv_t& label_vec) const; 37 | virtual _v_t get_unary_costs_enum_offset( 38 | const _iv_st& offset) const; 39 | 40 | protected: 41 | const luint_t m_node_id; 42 | const LabelSet * m_label_set; 43 | 44 | std::vector<_s_t> m_cost_table; 45 | }; 46 | 47 | NS_MAPMAP_END 48 | 49 | /* include function implementations */ 50 | #include 51 | 52 | #endif /* __MAPMAP_UNARY_TABLE_H_ */ 53 | -------------------------------------------------------------------------------- /mapmap/header/optimizer_instances/dp_node.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_HEADER_OPTIMIZER_INSTANCES_DP_NODE_H_ 11 | #define __MAPMAP_HEADER_OPTIMIZER_INSTANCES_DP_NODE_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | NS_MAPMAP_BEGIN 20 | 21 | template 22 | struct DPNode 23 | { 24 | /* input data */ 25 | TreeNode c_node; 26 | const Graph * c_graph; 27 | const LabelSet * c_labels; 28 | 29 | const UnaryCosts * c_unary; 30 | const PairwiseCosts * c_pairwise; 31 | 32 | const std::vector<_s_t*> * c_child_values; 33 | const std::vector<_iv_st*> * c_child_labels; 34 | 35 | const std::vector<_iv_st> * c_assignment; 36 | 37 | std::vector*> c_dep_costs; 38 | bool respect_dependencies; 39 | 40 | /* output data */ 41 | _s_t * c_opt_values; 42 | _iv_st * c_opt_labels; 43 | 44 | /* scratch space, externally allocated */ 45 | _s_t * c_scratch; 46 | }; 47 | 48 | NS_MAPMAP_END 49 | 50 | #endif /* __MAPMAP_HEADER_OPTIMIZER_INSTANCES_DP_NODE_H_ */ -------------------------------------------------------------------------------- /mapmap/header/tree_sampler.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_TREE_SAMPLER_H_ 11 | #define __MAPMAP_TREE_SAMPLER_H_ 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | NS_MAPMAP_BEGIN 19 | 20 | template 21 | class TreeSampler 22 | { 23 | public: 24 | TreeSampler(Graph * graph); 25 | TreeSampler(Graph * graph, const bool m_deterministic, 26 | const uint_t initial_seed); 27 | virtual ~TreeSampler(); 28 | 29 | virtual void 30 | select_random_roots(const luint_t k, std::vector& roots) = 0; 31 | virtual std::unique_ptr> sample(std::vector& roots, 32 | bool record_dependencies, bool relax = true) = 0; 33 | 34 | protected: 35 | void build_component_lists(); 36 | void create_adj_acc(); 37 | 38 | protected: 39 | Graph * m_graph; 40 | std::random_device m_rnd_dev; 41 | 42 | /* deterministic sampling with external seed */ 43 | const bool m_deterministic; 44 | const uint_t m_initial_seed; 45 | 46 | /* data needed in all derived classes */ 47 | std::vector> m_component_lists; 48 | 49 | std::vector m_adj_offsets; 50 | std::vector m_adj; 51 | }; 52 | 53 | NS_MAPMAP_END 54 | 55 | /* include function implementations */ 56 | #include 57 | 58 | #endif /* __MAPMAP_TREE_SAMPLER_H_ */ -------------------------------------------------------------------------------- /mapmap/source/termination_instances/stop_after_time.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | 12 | NS_MAPMAP_BEGIN 13 | 14 | template 15 | FORCEINLINE 16 | StopAfterTime:: 17 | StopAfterTime( 18 | const luint_t max_seconds, 19 | const bool compute_before_iteration) 20 | : m_max_seconds(max_seconds), 21 | m_compute_before_iteration(compute_before_iteration) 22 | { 23 | 24 | } 25 | 26 | /* ************************************************************************** */ 27 | 28 | template 29 | FORCEINLINE 30 | StopAfterTime:: 31 | ~StopAfterTime() 32 | { 33 | 34 | } 35 | 36 | /* ************************************************************************** */ 37 | 38 | template 39 | FORCEINLINE 40 | bool 41 | StopAfterTime:: 42 | check_termination( 43 | const SolverHistory * history) 44 | { 45 | /* calculate average iteration length */ 46 | const luint_t num_iteration = history->acyclic_iterations + 47 | history->spanningtree_iterations + 48 | history->multilevel_iterations; 49 | const luint_t runtime = history->time_history->back(); 50 | 51 | const COSTTYPE avg_iteration = runtime / (COSTTYPE) num_iteration; 52 | 53 | return (runtime + (m_compute_before_iteration ? avg_iteration : 0) >= 54 | m_max_seconds); 55 | } 56 | 57 | NS_MAPMAP_END 58 | -------------------------------------------------------------------------------- /mapmap/source/termination_instances/stop_after_iterations.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | 12 | NS_MAPMAP_BEGIN 13 | 14 | template 15 | FORCEINLINE 16 | StopAfterIterations:: 17 | StopAfterIterations( 18 | const luint_t max_iterations, 19 | const bool count_acyclic, 20 | const bool count_spanningtree, 21 | const bool count_multilevel) 22 | : m_max_iterations(max_iterations), 23 | m_count_acyclic(count_acyclic), 24 | m_count_spanningtree(count_spanningtree), 25 | m_count_multilevel(count_multilevel) 26 | { 27 | 28 | } 29 | 30 | /* ************************************************************************** */ 31 | 32 | template 33 | FORCEINLINE 34 | StopAfterIterations:: 35 | ~StopAfterIterations() 36 | { 37 | 38 | } 39 | 40 | /* ************************************************************************** */ 41 | 42 | template 43 | FORCEINLINE 44 | bool 45 | StopAfterIterations:: 46 | check_termination( 47 | const SolverHistory * history) 48 | { 49 | luint_t iterations_done = 50 | (m_count_acyclic ? history->acyclic_iterations : 0) + 51 | (m_count_spanningtree ? history->spanningtree_iterations : 0) + 52 | (m_count_multilevel ? history->multilevel_iterations : 0); 53 | 54 | return (iterations_done >= m_max_iterations); 55 | } 56 | 57 | NS_MAPMAP_END 58 | -------------------------------------------------------------------------------- /mapmap/header/cost_bundle.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_HEADER_COST_BUNDLE_H_ 11 | #define __MAPMAP_HEADER_COST_BUNDLE_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | NS_MAPMAP_BEGIN 18 | 19 | template 20 | class CostBundle 21 | { 22 | public: 23 | CostBundle(const Graph * graph); 24 | ~CostBundle(); 25 | 26 | /* global cost setting */ 27 | void set_unary_costs(const UnaryCosts * costs); 28 | void set_pairwise_costs(const PairwiseCosts * costs); 29 | 30 | /* individual cost setting */ 31 | void set_unary_costs(const luint_t node_id, 32 | const UnaryCosts * costs); 33 | void set_pairwise_costs(const luint_t edge_id, 34 | const PairwiseCosts * costs); 35 | 36 | /* individual cost retrieval */ 37 | const UnaryCosts * get_unary_costs(const luint_t 38 | node_id) const; 39 | const PairwiseCosts * get_pairwise_costs(const luint_t 40 | edge_id) const; 41 | 42 | protected: 43 | const Graph * m_graph; 44 | 45 | std::vector*> m_unary; 46 | std::vector*> m_pairwise; 47 | }; 48 | 49 | NS_MAPMAP_END 50 | 51 | /* include template instances */ 52 | #include 53 | 54 | #endif /* __MAPMAP_HEADER_COST_BUNDLE_H_ */ -------------------------------------------------------------------------------- /mapmap/header/optimizer_instances/envelope.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Nick Heppert, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_ENVELOPE_H_ 11 | #define __MAPMAP_ENVELOPE_H_ 12 | 13 | #include 14 | 15 | NS_MAPMAP_BEGIN 16 | 17 | /** 18 | * Template for implementing linear-time DP optimizers as in 19 | 20 | * Pedro F. Felzenszwalb, and Daniel P. Huttenlocher, 21 | * "Efficient belief propagation for early vision." 22 | * International Journal of Computer Vision 70.1 (2006): 41-54. 23 | */ 24 | 25 | template 26 | class PairwiseCostsEnvelope 27 | { 28 | public: 29 | virtual ~PairwiseCostsEnvelope() {}; 30 | 31 | virtual void compute_m_primes( 32 | DPNode * node, 33 | const _s_t * icosts, 34 | const _iv_st * lbl_union, 35 | const _iv_st lbl_union_size, 36 | _s_t * m_prime, 37 | _iv_st * m_prime_ix, 38 | _s_t * scratch) = 0; 39 | virtual _s_t cost_bound_d() = 0; 40 | 41 | virtual luint_t scratch_bytes_needed( 42 | DPNode * node) = 0; 43 | }; 44 | 45 | template 46 | using PairwiseCostsEnvelope_ptr = std::shared_ptr>; 48 | 49 | NS_MAPMAP_END 50 | 51 | #endif /* __MAPMAP_ENVELOPE_H_ */ 52 | -------------------------------------------------------------------------------- /mapmap/header/cost_instances/pairwise_antipotts.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_PAIRWISE_ANTIPOTTS_H_ 11 | #define __MAPMAP_PAIRWISE_ANTIPOTTS_H_ 12 | 13 | #include 14 | 15 | NS_MAPMAP_BEGIN 16 | 17 | template 18 | class PairwiseAntipotts : public PairwiseCosts 19 | { 20 | public: 21 | PairwiseAntipotts(); 22 | PairwiseAntipotts(const _s_t& c); 23 | PairwiseAntipotts( 24 | const std::initializer_list<_s_t>& ps); 25 | ~PairwiseAntipotts(); 26 | 27 | _s_t get_c() const; 28 | _s_t get_label_diff_cap() const; 29 | 30 | virtual std::unique_ptr> copy() const; 31 | 32 | virtual bool supports_enumerable_costs() const; 33 | virtual bool eq(const PairwiseCosts * costs) const; 34 | 35 | virtual _v_t get_pairwise_costs( 36 | const _iv_t& label_vec_1, 37 | const _iv_t& label_vec_2) const; 38 | virtual _v_t get_pairwise_costs_enum_offsets( 39 | const _iv_t& label_ix_vec_1, 40 | const _iv_t& label_ix_vec_2) const; 41 | 42 | protected: 43 | _s_t m_c = (_s_t) 1; 44 | }; 45 | 46 | NS_MAPMAP_END 47 | 48 | /* include function implementations */ 49 | #include 50 | 51 | #endif /* __MAPMAP_PAIRWISE_ANTIPOTTS_H_ */ -------------------------------------------------------------------------------- /test/test_coloring.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | #include "header/defines.h" 14 | #include "header/color.h" 15 | #include "test/util_test.h" 16 | 17 | NS_MAPMAP_BEGIN 18 | 19 | class mapMAPTestColoring : public testing::Test 20 | { 21 | public: 22 | using cost_t = float; 23 | 24 | const uint_t num_components = 4; 25 | const uint_t component_dim = 100; 26 | 27 | public: 28 | mapMAPTestColoring() 29 | { 30 | 31 | } 32 | 33 | ~mapMAPTestColoring() 34 | { 35 | 36 | } 37 | 38 | void 39 | SetUp() 40 | { 41 | /* create a grid graph with a given number of connected components */ 42 | m_graph = createComponentGrid(num_components, component_dim); 43 | 44 | /* Color graph */ 45 | Color col(*m_graph); 46 | col.color_graph(m_coloring); 47 | } 48 | 49 | void 50 | TearDown() 51 | { 52 | } 53 | 54 | std::unique_ptr> m_graph; 55 | std::vector m_coloring; 56 | }; 57 | 58 | TEST_F(mapMAPTestColoring, TestValid) 59 | { 60 | /* Detect collisions between the coloring of any nodes */ 61 | const luint_t num_nodes = m_graph->num_nodes(); 62 | for(luint_t i = 0; i < num_nodes; ++i) 63 | { 64 | const std::vector& edges = m_graph->inc_edges(i); 65 | 66 | for(const luint_t e_id : edges) 67 | { 68 | const GraphEdge& e = m_graph->edges()[e_id]; 69 | ASSERT_NE(m_coloring[e.node_a], m_coloring[e.node_b]); 70 | } 71 | } 72 | } 73 | 74 | NS_MAPMAP_END -------------------------------------------------------------------------------- /mapmap/header/cost_instances/pairwise_potts.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_PAIRWISE_POTTS_H_ 11 | #define __MAPMAP_PAIRWISE_POTTS_H_ 12 | 13 | #include 14 | 15 | NS_MAPMAP_BEGIN 16 | 17 | template 18 | class PairwisePotts : public PairwiseCosts 19 | { 20 | public: 21 | PairwisePotts(); 22 | PairwisePotts(const _s_t& c); 23 | PairwisePotts(const std::initializer_list<_s_t>& ps); 24 | ~PairwisePotts(); 25 | 26 | _s_t get_c() const; 27 | 28 | virtual std::unique_ptr> copy() const; 29 | 30 | virtual bool supports_enumerable_costs() const; 31 | virtual bool eq(const PairwiseCosts * costs) const; 32 | 33 | virtual _v_t get_pairwise_costs( 34 | const _iv_t& label_vec_1, 35 | const _iv_t& label_vec_2) const; 36 | virtual _v_t get_pairwise_costs_enum_offsets( 37 | const _iv_t& label_ix_vec_1, 38 | const _iv_t& label_ix_vec_2) const; 39 | 40 | protected: 41 | _s_t m_c = (_s_t) 1; 42 | }; 43 | 44 | template 45 | using PairwisePotts_ptr = std::shared_ptr>; 46 | 47 | NS_MAPMAP_END 48 | 49 | /* include function implementations */ 50 | #include 51 | 52 | #endif /* __MAPMAP_PAIRWISE_POTTS_H_ */ 53 | -------------------------------------------------------------------------------- /mapmap/header/optimizer_instances/envelope_instances/pairwise_potts_envelope.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Nick Heppert, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_PAIRWISE_POTTS_ENVELOPE_H_ 11 | #define __MAPMAP_PAIRWISE_POTTS_ENVELOPE_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | NS_MAPMAP_BEGIN 18 | 19 | template 20 | class PairwisePottsEnvelope : 21 | public PairwiseCostsEnvelope 22 | { 23 | public: 24 | PairwisePottsEnvelope(const PairwisePotts * base); 25 | ~PairwisePottsEnvelope(); 26 | 27 | virtual void compute_m_primes( 28 | DPNode * node, 29 | const _s_t * icosts, 30 | const _iv_st * lbl_union, 31 | const _iv_st lbl_union_size, 32 | _s_t * m_prime, 33 | _iv_st * m_prime_ix, 34 | _s_t * scratch); 35 | virtual _s_t cost_bound_d(); 36 | virtual luint_t scratch_bytes_needed( 37 | DPNode * node); 38 | 39 | protected: 40 | _s_t m_c = (_s_t) 1; 41 | }; 42 | 43 | template 44 | using PairwisePottsEnvelope_ptr = std::unique_ptr>; 46 | 47 | NS_MAPMAP_END 48 | 49 | /* include function implementations */ 50 | #include 51 | 52 | #endif /* __MAPMAP_AIRWISE_POTTS_ENVELOPE_H_ */ 53 | -------------------------------------------------------------------------------- /mapmap/header/termination_criterion.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_TERMINATION_CRITERION_H_ 11 | #define __MAPMAP_TERMINATION_CRITERION_H_ 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | NS_MAPMAP_BEGIN 21 | 22 | /** 23 | * ***************************************************************************** 24 | * ***************************** SolverHistory ********************************* 25 | * ***************************************************************************** 26 | */ 27 | 28 | enum SolverMode 29 | { 30 | SOLVER_ACYCLIC, 31 | SOLVER_SPANNINGTREE, 32 | SOLVER_MULTILEVEL 33 | }; 34 | 35 | template 36 | struct SolverHistory 37 | { 38 | const std::vector<_s_t> * energy_history; 39 | const std::vector * time_history; 40 | const std::vector * mode_history; 41 | 42 | luint_t acyclic_iterations; 43 | luint_t spanningtree_iterations; 44 | luint_t multilevel_iterations; 45 | }; 46 | 47 | /** 48 | * ***************************************************************************** 49 | * ************************** TerminationCriterion ***************************** 50 | * ***************************************************************************** 51 | */ 52 | 53 | template 54 | class TerminationCriterion 55 | { 56 | public: 57 | TerminationCriterion(); 58 | virtual ~TerminationCriterion(); 59 | 60 | virtual bool check_termination(const SolverHistory * history) = 0; 62 | }; 63 | 64 | NS_MAPMAP_END 65 | 66 | #include 67 | 68 | #endif /* __MAPMAP_TERMINATION_CRITERION_H_ */ 69 | -------------------------------------------------------------------------------- /mapmap/source/termination_instances/stop_when_flat.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | 12 | NS_MAPMAP_BEGIN 13 | 14 | template 15 | FORCEINLINE 16 | StopWhenFlat:: 17 | StopWhenFlat( 18 | const luint_t num_allowed_flat_iterations, 19 | const bool reset_after_improvement) 20 | : m_num_allowed_flat_iterations(num_allowed_flat_iterations), 21 | m_reset_after_improvement(reset_after_improvement) 22 | { 23 | 24 | } 25 | 26 | /* ************************************************************************** */ 27 | 28 | template 29 | FORCEINLINE 30 | StopWhenFlat:: 31 | ~StopWhenFlat() 32 | { 33 | 34 | } 35 | 36 | /* ************************************************************************** */ 37 | 38 | template 39 | FORCEINLINE 40 | bool 41 | StopWhenFlat:: 42 | check_termination( 43 | const SolverHistory * history) 44 | { 45 | const luint_t num_energy_iterations = history->energy_history->size(); 46 | 47 | if(num_energy_iterations < 2) 48 | return false; 49 | 50 | /* count flat iterations */ 51 | luint_t flat_iterations = 0; 52 | for(luint_t j = num_energy_iterations - 1; j > 0; --j) 53 | { 54 | const bool is_flat = ((*history->energy_history)[j] == 55 | (*history->energy_history)[j - 1]); 56 | const bool is_improvement = ((*history->energy_history)[j] <= 57 | (*history->energy_history)[j - 1]); 58 | 59 | if(is_flat) 60 | ++flat_iterations; 61 | if(is_improvement && m_reset_after_improvement) 62 | break; 63 | } 64 | 65 | return (flat_iterations >= m_num_allowed_flat_iterations); 66 | } 67 | 68 | NS_MAPMAP_END 69 | -------------------------------------------------------------------------------- /mapmap/header/optimizer_instances/envelope_instances/pairwise_antipotts_envelope.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_PAIRWISE_ANTIPOTTS_ENVELOPE_H_ 11 | #define __MAPMAP_PAIRWISE_ANTIPOTTS_ENVELOPE_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | NS_MAPMAP_BEGIN 18 | 19 | template 20 | class PairwiseAntipottsEnvelope : 21 | public PairwiseCostsEnvelope 22 | { 23 | public: 24 | PairwiseAntipottsEnvelope( 25 | const PairwiseAntipotts * base); 26 | ~PairwiseAntipottsEnvelope(); 27 | 28 | virtual void compute_m_primes( 29 | DPNode * node, 30 | const _s_t * icosts, 31 | const _iv_st * lbl_union, 32 | const _iv_st lbl_union_size, 33 | _s_t * m_prime, 34 | _iv_st * m_prime_ix, 35 | _s_t * scratch); 36 | virtual _s_t cost_bound_d(); 37 | virtual luint_t scratch_bytes_needed( 38 | DPNode * node); 39 | 40 | protected: 41 | _s_t m_c = (_s_t) 1; 42 | }; 43 | 44 | template 45 | using PairwiseAntipottsEnvelope_ptr = std::unique_ptr>; 47 | 48 | NS_MAPMAP_END 49 | 50 | /* include function implementations */ 51 | #include 52 | 53 | #endif /* __MAPMAP_AIRWISE_ANTIPOTTS_ENVELOPE_H_ */ 54 | -------------------------------------------------------------------------------- /mapmap/header/optimizer_instances/envelope_instances/pairwise_linear_peak_envelope.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_PAIRWISE_LINEAR_PEAK_ENVELOPE_H_ 11 | #define __MAPMAP_PAIRWISE_LINEAR_PEAK_ENVELOPE_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | NS_MAPMAP_BEGIN 18 | 19 | template 20 | class PairwiseLinearPeakEnvelope : 21 | public PairwiseCostsEnvelope 22 | { 23 | public: 24 | PairwiseLinearPeakEnvelope(const PairwiseLinearPeak * base); 26 | ~PairwiseLinearPeakEnvelope(); 27 | 28 | virtual void compute_m_primes( 29 | DPNode * node, 30 | const _s_t * icosts, 31 | const _iv_st * lbl_union, 32 | const _iv_st lbl_union_size, 33 | _s_t * m_prime, 34 | _iv_st * m_prime_ix, 35 | _s_t * scratch); 36 | virtual _s_t cost_bound_d(); 37 | virtual luint_t scratch_bytes_needed( 38 | DPNode * node); 39 | 40 | protected: 41 | _s_t m_label_diff_cap = (_s_t) 2; 42 | }; 43 | 44 | template 45 | using PairwiseLinearPeakEnvelope_ptr = 46 | std::unique_ptr>; 48 | 49 | NS_MAPMAP_END 50 | 51 | /* include function implementations */ 52 | #include 53 | 54 | #endif /* __MAPMAP_PAIRWISE_LINEAR_PEAK_ENVELOPE_H_ */ 55 | -------------------------------------------------------------------------------- /mapmap/header/cost_instances/pairwise_linear_peak.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_PAIRWISE_LINEAR_PEAK_H_ 11 | #define __MAPMAP_PAIRWISE_LINEAR_PEAK_H_ 12 | 13 | #include 14 | 15 | NS_MAPMAP_BEGIN 16 | 17 | template 18 | class PairwiseLinearPeak : public PairwiseCosts 19 | { 20 | public: 21 | PairwiseLinearPeak(); 22 | PairwiseLinearPeak(const _s_t& c, 23 | const _s_t& label_diff_cap); 24 | PairwiseLinearPeak(const std::initializer_list<_s_t>& ps); 26 | ~PairwiseLinearPeak(); 27 | 28 | _s_t get_c() const; 29 | _s_t get_label_diff_cap() const; 30 | 31 | virtual std::unique_ptr> copy() const; 32 | 33 | virtual bool supports_enumerable_costs() const; 34 | virtual bool eq(const PairwiseCosts * costs) const; 35 | 36 | virtual _v_t get_pairwise_costs( 37 | const _iv_t& label_vec_1, 38 | const _iv_t& label_vec_2) const; 39 | virtual _v_t get_pairwise_costs_enum_offsets( 40 | const _iv_t& label_ix_vec_1, 41 | const _iv_t& label_ix_vec_2) const; 42 | 43 | protected: 44 | _s_t m_c = (_s_t) 1; 45 | _s_t m_label_diff_cap = (_s_t) 2; 46 | }; 47 | 48 | template 49 | using PairwiseLinearPeak_ptr = 50 | std::shared_ptr>; 51 | 52 | NS_MAPMAP_END 53 | 54 | /* include function implementations */ 55 | #include 56 | 57 | #endif /* __MAPMAP_PAIRWISE_LINEAR_PEAK_H_ */ -------------------------------------------------------------------------------- /test/test_graph.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | #include "header/defines.h" 14 | #include "header/vector_types.h" 15 | #include "header/graph.h" 16 | #include "test/util_test.h" 17 | 18 | NS_MAPMAP_BEGIN 19 | 20 | class mapMAPTestGraph : public ::testing::Test 21 | { 22 | public: 23 | using cost_t = float; 24 | const uint_t num_components = 4; 25 | const uint_t component_dim = 10; 26 | 27 | public: 28 | mapMAPTestGraph() 29 | { 30 | } 31 | 32 | ~mapMAPTestGraph() 33 | { 34 | } 35 | 36 | void 37 | SetUp() 38 | { 39 | m_graph = createComponentGrid(num_components, component_dim); 40 | } 41 | 42 | void 43 | TearDown() 44 | { 45 | } 46 | 47 | protected: 48 | std::unique_ptr> m_graph; 49 | }; 50 | 51 | TEST_F(mapMAPTestGraph, TestInternalValues) 52 | { 53 | ASSERT_EQ(m_graph->m_nodes.size(), num_components * 54 | component_dim * component_dim); 55 | ASSERT_EQ(m_graph->m_edges.size(), num_components * 56 | ((component_dim - 1) * component_dim + 57 | component_dim * (component_dim - 1))); 58 | } 59 | 60 | TEST_F(mapMAPTestGraph, TestComponentSearch) 61 | { 62 | m_graph->update_components(); 63 | ASSERT_EQ(m_graph->num_components(), 4u); 64 | 65 | const std::vector& components = m_graph->components(); 66 | std::vector cmp_ids(num_components); 67 | for (uint_t i = 0; i < num_components; ++i) 68 | cmp_ids[i] = components[i * component_dim * component_dim]; 69 | 70 | for (uint_t i = 0; i < num_components; ++i) 71 | { 72 | for (uint_t j = 0; j < component_dim * component_dim; ++j) 73 | { 74 | ASSERT_EQ(components[i * component_dim * component_dim + j], 75 | cmp_ids[i]); 76 | } 77 | } 78 | } 79 | 80 | NS_MAPMAP_END -------------------------------------------------------------------------------- /mapmap/header/optimizer_instances/envelope_instances/pairwise_truncated_linear_envelope.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Nick Heppert, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_PAIRWISE_TRUNCATED_LINEAR_ENVELOPE_H_ 11 | #define __MAPMAP_PAIRWISE_TRUNCATED_LINEAR_ENVELOPE_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | NS_MAPMAP_BEGIN 18 | 19 | template 20 | class PairwiseTruncatedLinearEnvelope : 21 | public PairwiseCostsEnvelope 22 | { 23 | public: 24 | PairwiseTruncatedLinearEnvelope(const PairwiseTruncatedLinear * base); 26 | ~PairwiseTruncatedLinearEnvelope(); 27 | 28 | virtual void compute_m_primes( 29 | DPNode * node, 30 | const _s_t * icosts, 31 | const _iv_st * lbl_union, 32 | const _iv_st lbl_union_size, 33 | _s_t * m_prime, 34 | _iv_st * m_prime_ix, 35 | _s_t * scratch); 36 | virtual _s_t cost_bound_d(); 37 | virtual luint_t scratch_bytes_needed( 38 | DPNode * node); 39 | 40 | protected: 41 | _s_t m_label_diff_cap = (_s_t) 2; 42 | }; 43 | 44 | template 45 | using PairwiseTruncatedLinearEnvelope_ptr = 46 | std::unique_ptr>; 48 | 49 | NS_MAPMAP_END 50 | 51 | /* include function implementations */ 52 | #include 53 | 54 | #endif /* __MAPMAP_PAIRWISE_TRUNCATED_LINEAR_ENVELOPE_H_ */ 55 | -------------------------------------------------------------------------------- /mapmap/header/optimizer_instances/envelope_instances/pairwise_truncated_quadratic_envelope.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_PAIRWISE_TRUNCATED_QUADRATIC_ENVELOPE_H_ 11 | #define __MAPMAP_PAIRWISE_TRUNCATED_QUADRATIC_ENVELOPE_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | NS_MAPMAP_BEGIN 18 | 19 | template 20 | class PairwiseTruncatedQuadraticEnvelope : 21 | public PairwiseCostsEnvelope 22 | { 23 | public: 24 | PairwiseTruncatedQuadraticEnvelope(const PairwiseTruncatedQuadratic * base); 26 | ~PairwiseTruncatedQuadraticEnvelope(); 27 | 28 | virtual void compute_m_primes( 29 | DPNode * node, 30 | const _s_t * icosts, 31 | const _iv_st * lbl_union, 32 | const _iv_st lbl_union_size, 33 | _s_t * m_prime, 34 | _iv_st * m_prime_ix, 35 | _s_t * scratch); 36 | virtual _s_t cost_bound_d(); 37 | virtual luint_t scratch_bytes_needed( 38 | DPNode * node); 39 | 40 | protected: 41 | _s_t m_label_diff_cap = (_s_t) 2; 42 | }; 43 | 44 | template 45 | using PairwiseTruncatedQuadraticEnvelope_ptr = 46 | std::unique_ptr>; 48 | 49 | NS_MAPMAP_END 50 | 51 | /* include function implementations */ 52 | #include 53 | 54 | #endif /* __MAPMAP_PAIRWISE_TRUNCATED_QUADRATIC_ENVELOPE_H_ */ 55 | -------------------------------------------------------------------------------- /mapmap/header/cost_instances/pairwise_truncated_linear.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_PAIRWISE_TRUNCATED_LINEAR_H_ 11 | #define __MAPMAP_PAIRWISE_TRUNCATED_LINEAR_H_ 12 | 13 | #include 14 | #include 15 | 16 | NS_MAPMAP_BEGIN 17 | 18 | template 19 | class PairwiseTruncatedLinear : public PairwiseCosts 20 | { 21 | public: 22 | PairwiseTruncatedLinear(); 23 | PairwiseTruncatedLinear(const _s_t& c, 24 | const _s_t& label_diff_cap); 25 | PairwiseTruncatedLinear(const std::initializer_list<_s_t>& ps); 27 | ~PairwiseTruncatedLinear(); 28 | 29 | _s_t get_label_diff_cap() const; 30 | _s_t get_c() const; 31 | 32 | virtual std::unique_ptr> copy() const; 33 | 34 | virtual bool supports_enumerable_costs() const; 35 | virtual bool eq(const PairwiseCosts * costs) const; 36 | 37 | virtual _v_t get_pairwise_costs( 38 | const _iv_t& label_vec_1, 39 | const _iv_t& label_vec_2) const; 40 | virtual _v_t get_pairwise_costs_enum_offsets( 41 | const _iv_t& label_ix_vec_1, 42 | const _iv_t& label_ix_vec_2) const; 43 | 44 | protected: 45 | _s_t m_c = (_s_t) 1; 46 | _s_t m_label_diff_cap = (_s_t) 2; 47 | }; 48 | 49 | template 50 | using PairwiseTruncatedLinear_ptr = std::shared_ptr>; 52 | 53 | NS_MAPMAP_END 54 | 55 | /* include function implementations */ 56 | #include 57 | 58 | #endif /* __MAPMAP_PAIRWISE_TRUNCATED_LINEAR_H_ */ 59 | -------------------------------------------------------------------------------- /mapmap/header/cost_instances/pairwise_truncated_quadratic.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_PAIRWISE_TRUNCATED_QUADRATIC_H_ 11 | #define __MAPMAP_PAIRWISE_TRUNCATED_QUADRATIC_H_ 12 | 13 | #include 14 | #include 15 | 16 | NS_MAPMAP_BEGIN 17 | 18 | template 19 | class PairwiseTruncatedQuadratic : public PairwiseCosts 20 | { 21 | public: 22 | PairwiseTruncatedQuadratic(); 23 | PairwiseTruncatedQuadratic(const _s_t& c, 24 | const _s_t& label_diff_cap); 25 | PairwiseTruncatedQuadratic(const std::initializer_list< 26 | _s_t>& ps); 27 | ~PairwiseTruncatedQuadratic(); 28 | 29 | _s_t get_label_diff_cap() const; 30 | _s_t get_c() const; 31 | 32 | virtual std::unique_ptr> copy() const; 33 | 34 | virtual bool supports_enumerable_costs() const; 35 | virtual bool eq(const PairwiseCosts * costs) const; 36 | 37 | virtual _v_t get_pairwise_costs( 38 | const _iv_t& label_vec_1, 39 | const _iv_t& label_vec_2) const; 40 | virtual _v_t get_pairwise_costs_enum_offsets( 41 | const _iv_t& label_ix_vec_1, 42 | const _iv_t& label_ix_vec_2) const; 43 | 44 | protected: 45 | _s_t m_c = (_s_t) 1; 46 | _s_t m_label_diff_cap = (_s_t) 9; 47 | }; 48 | 49 | template 50 | using PairwiseTruncatedQuadratic_ptr = std::shared_ptr< 51 | PairwiseTruncatedQuadratic>; 52 | 53 | NS_MAPMAP_END 54 | 55 | /* include function implementations */ 56 | #include 57 | 58 | #endif /* __MAPMAP_PAIRWISE_TRUNCATED_QUADRATIC_H_ */ 59 | -------------------------------------------------------------------------------- /mapmap/header/graph.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_GRAPH_H_ 11 | #define __MAPMAP_GRAPH_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | NS_MAPMAP_BEGIN 21 | 22 | struct GraphNode 23 | { 24 | std::vector incident_edges; 25 | }; 26 | 27 | template 28 | struct GraphEdge 29 | { 30 | luint_t node_a; 31 | luint_t node_b; 32 | scalar_t weight; 33 | }; 34 | 35 | template 36 | class Graph 37 | { 38 | public: 39 | Graph(const luint_t num_nodes); 40 | ~Graph(); 41 | 42 | void add_edge(const luint_t node_a, const luint_t node_b, 43 | const scalar_t weight); 44 | const std::vector& nodes() const; 45 | const luint_t num_nodes() const; 46 | const std::vector& inc_edges(const luint_t node) const; 47 | const std::vector>& edges() const; 48 | const luint_t num_edges() const; 49 | 50 | void update_components(); 51 | const std::vector& components() const; 52 | const luint_t num_components() const; 53 | 54 | /* store and use coloring information */ 55 | void set_coloring(const std::vector& coloring); 56 | const std::vector& get_coloring(); 57 | bool was_colored(); 58 | 59 | /* necessary for deterministic processing */ 60 | void sort_incidence_lists(); 61 | 62 | protected: 63 | #if defined(BUILD_FOR_TEST) 64 | #include 65 | 66 | FRIEND_TEST(mapMAPTestGraph, TestInternalValues); 67 | FRIEND_TEST(mapMAPTestGraph, TestComponentSearch); 68 | #endif 69 | luint_t m_num_nodes; 70 | std::vector m_nodes; 71 | std::vector>> m_edges; 72 | std::vector m_components; 73 | luint_t m_num_components; 74 | 75 | std::vector m_coloring; 76 | bool m_was_colored; 77 | }; 78 | 79 | NS_MAPMAP_END 80 | 81 | #include 82 | 83 | #endif /* __MAPMAP_GRAPH_H_ */ -------------------------------------------------------------------------------- /mapmap/header/tree_optimizer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_TREE_OPTIMIZER_H_ 11 | #define __MAPMAP_TREE_OPTIMIZER_H_ 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | NS_MAPMAP_BEGIN 24 | 25 | template 26 | class TreeOptimizer 27 | { 28 | public: 29 | TreeOptimizer(); 30 | ~TreeOptimizer(); 31 | 32 | /* prerequisites for optimization */ 33 | void set_graph(const Graph * graph); 34 | void set_tree(const Tree * tree); 35 | void set_label_set(const LabelSet * label_set); 36 | void set_costs(const CostBundle * cbundle); 37 | void use_dependencies(const std::vector<_iv_st>& 38 | current_solution); 39 | 40 | /* evaluate objective for a solution */ 41 | _s_t objective( 42 | const std::vector<_iv_st>& solution); 43 | 44 | /* optimization procedure - returns new objective value and solution */ 45 | virtual _s_t optimize( 46 | std::vector<_iv_st>& solution) = 0; 47 | 48 | protected: 49 | bool data_complete(); 50 | 51 | protected: 52 | /* optimization input data */ 53 | const Graph * m_graph; 54 | const Tree * m_tree; 55 | const LabelSet * m_label_set; 56 | const CostBundle * m_cbundle; 57 | std::vector<_iv_st> m_current_assignment; 58 | 59 | /* status bits - check for data completeness */ 60 | bool m_has_graph; 61 | bool m_has_tree; 62 | bool m_has_label_set; 63 | bool m_has_costs; 64 | bool m_uses_dependencies; 65 | }; 66 | 67 | NS_MAPMAP_END 68 | 69 | /* include function implementations */ 70 | #include 71 | 72 | #endif /* __MAPMAP_TREE_OPTIMIZER_H_ */ 73 | -------------------------------------------------------------------------------- /mapmap/source/termination_instances/stop_when_returns_diminish.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_HEADER_TERMINATION_INSTANCES_STOP_WHEN_RETURNS_DIMINISH_IMPL_H_ 11 | #define __MAPMAP_HEADER_TERMINATION_INSTANCES_STOP_WHEN_RETURNS_DIMINISH_IMPL_H_ 12 | 13 | #include 14 | 15 | #include 16 | 17 | NS_MAPMAP_BEGIN 18 | 19 | template 20 | StopWhenReturnsDiminish:: 21 | StopWhenReturnsDiminish( 22 | const luint_t iteration_span, 23 | const _s_t improv_threshold) 24 | : m_iteration_span(iteration_span), 25 | m_improv_threshold(improv_threshold) 26 | { 27 | 28 | } 29 | 30 | /* ************************************************************************** */ 31 | 32 | template 33 | StopWhenReturnsDiminish:: 34 | ~StopWhenReturnsDiminish() 35 | { 36 | 37 | } 38 | 39 | /* ************************************************************************** */ 40 | 41 | template 42 | bool 43 | StopWhenReturnsDiminish:: 44 | check_termination( 45 | const SolverHistory * history) 46 | { 47 | _s_t oldest_val, newest_val; 48 | const luint_t hist_size = history->energy_history->size(); 49 | 50 | /* have at least the minimum number of iterations done */ 51 | if(hist_size < m_iteration_span) 52 | return false; 53 | 54 | /* determine improvement in the last couple of iterations */ 55 | newest_val = history->energy_history->back(); 56 | 57 | luint_t oldest_pos = 0; 58 | if(hist_size > m_iteration_span) 59 | oldest_pos = (hist_size - 1) - m_iteration_span; 60 | 61 | oldest_val = (*history->energy_history)[oldest_pos]; 62 | 63 | const _s_t improv = 64 | (oldest_val - newest_val) / oldest_val; 65 | 66 | return (improv < m_improv_threshold); 67 | } 68 | 69 | NS_MAPMAP_END 70 | 71 | #endif 72 | /* __MAPMAP_HEADER_TERMINATION_INSTANCES_STOP_WHEN_RETURNS_DIMINISH_IMPL_H_ */ -------------------------------------------------------------------------------- /mapmap/full.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_FULL_H_ 11 | #if defined(_WIN32) 12 | #define WIN32_LEAN_AND_MEAN 13 | #define NOMINMAX 14 | #endif 15 | #define __MAPMAP_FULL_H_ 16 | 17 | /* basic classes */ 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | /* cost functions */ 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | /* multilevel instances */ 43 | #include 44 | 45 | /* optimizer instances */ 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | 52 | /* termination criteria */ 53 | #include 54 | #include 55 | #include 56 | #include 57 | 58 | /* tree sampler instances */ 59 | #include 60 | #include 61 | 62 | #endif /* __MAPMAP_FULL_H_ */ -------------------------------------------------------------------------------- /mapmap/source/optimizer_instances/envelope_instances/pairwise_potts_envelope.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Nick Heppert, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | 12 | NS_MAPMAP_BEGIN 13 | 14 | template 15 | FORCEINLINE 16 | PairwisePottsEnvelope:: 17 | PairwisePottsEnvelope( 18 | const PairwisePotts * base) 19 | : m_c(base->get_c()) 20 | { 21 | 22 | } 23 | 24 | /* ************************************************************************** */ 25 | 26 | template 27 | FORCEINLINE 28 | PairwisePottsEnvelope:: 29 | ~PairwisePottsEnvelope() 30 | { 31 | 32 | } 33 | 34 | /* ************************************************************************** */ 35 | 36 | template 37 | FORCEINLINE 38 | void 39 | PairwisePottsEnvelope:: 40 | compute_m_primes( 41 | DPNode * node, 42 | const _s_t * icosts, 43 | const _iv_st * lbl_union, 44 | const _iv_st lbl_union_size, 45 | _s_t * m_prime, 46 | _iv_st * m_prime_ix, 47 | _s_t * scratch) 48 | { 49 | /* for Potts: just copy for parent's labels, i.e. m' = identity */ 50 | return; 51 | } 52 | 53 | /* ************************************************************************** */ 54 | 55 | template 56 | FORCEINLINE 57 | _s_t 58 | PairwisePottsEnvelope:: 59 | cost_bound_d() 60 | { 61 | return m_c; 62 | } 63 | 64 | /* ************************************************************************** */ 65 | 66 | template 67 | FORCEINLINE 68 | luint_t 69 | PairwisePottsEnvelope:: 70 | scratch_bytes_needed( 71 | DPNode * node) 72 | { 73 | return 0; 74 | } 75 | 76 | NS_MAPMAP_END 77 | -------------------------------------------------------------------------------- /mapmap/header/cost_instances/pairwise_table.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_PAIRWISE_TABLE_H_ 11 | #define __MAPMAP_PAIRWISE_TABLE_H_ 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | NS_MAPMAP_BEGIN 23 | 24 | template 25 | class PairwiseTable : public PairwiseCosts 26 | { 27 | public: 28 | /* these two constructors allocate memory */ 29 | PairwiseTable( 30 | const luint_t node_a, 31 | const luint_t node_b, 32 | const LabelSet * lbl_set); 33 | PairwiseTable( 34 | const luint_t node_a, 35 | const luint_t node_b, 36 | const LabelSet * lbl_set, 37 | const std::vector<_s_t>& packed_table); 38 | 39 | /* this - third - constructor only saves a raw pointer */ 40 | PairwiseTable( 41 | const luint_t node_a, 42 | const luint_t node_b, 43 | const LabelSet * lbl_set, 44 | _s_t * packed_table); 45 | ~PairwiseTable(); 46 | 47 | void set_costs(const std::vector<_s_t>& packed_table); 48 | _s_t * get_raw_costs(); 49 | 50 | virtual std::unique_ptr> copy() const; 51 | 52 | virtual bool supports_enumerable_costs() const; 53 | virtual bool eq(const PairwiseCosts * costs) const; 54 | 55 | virtual _v_t get_pairwise_costs( 56 | const _iv_t& label_vec_1, 57 | const _iv_t& label_vec_2) const; 58 | virtual _v_t get_pairwise_costs_enum_offsets( 59 | const _iv_t& label_ix_vec_1, 60 | const _iv_t& label_ix_vec_2) const; 61 | 62 | protected: 63 | const luint_t m_node_a; 64 | const luint_t m_node_b; 65 | const LabelSet * m_lbl_set; 66 | 67 | _s_t * m_packed_table; 68 | std::unique_ptr<_s_t[]> m_packed_table_storage; 69 | }; 70 | 71 | NS_MAPMAP_END 72 | 73 | /* include function implementations */ 74 | #include 75 | 76 | #endif /* __MAPMAP_PAIRWISE_TABLE_H_ */ 77 | -------------------------------------------------------------------------------- /test/util_test.impl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | #include "test/util_test.h" 14 | 15 | NS_MAPMAP_BEGIN 16 | 17 | template 18 | std::unique_ptr> 19 | createComponentGrid( 20 | const uint_t num_components, 21 | const uint_t component_dim) 22 | { 23 | using cost_t = scalar_t; 24 | 25 | const luint_t num_nodes = num_components * (component_dim * 26 | component_dim); 27 | std::unique_ptr> graph(new Graph(num_nodes)); 28 | const cost_t w = (cost_t) 1.0; 29 | 30 | uint_t offset = 0; 31 | for (uint_t c_id = 0; c_id < num_components; ++c_id) 32 | { 33 | for (uint_t y = 0; y < component_dim; ++y) 34 | { 35 | for (uint_t x = 0; x < component_dim; ++x) 36 | { 37 | if (x < component_dim - 1) 38 | graph->add_edge( 39 | offset + y * component_dim + x, 40 | offset + y * component_dim + x + 1, 41 | w); 42 | 43 | if (y < component_dim - 1) 44 | graph->add_edge( 45 | offset + y * component_dim + x, 46 | offset + (y + 1) * component_dim + x, 47 | w); 48 | } 49 | } 50 | 51 | offset += component_dim * component_dim; 52 | } 53 | 54 | return graph; 55 | } 56 | 57 | template 58 | void 59 | BFSWithCustomFunc( 60 | Tree * tree, 61 | const luint_t& root_id, 62 | std::function*, const luint_t)> 63 | per_node_func) 64 | { 65 | std::queue qu; 66 | qu.push(root_id); 67 | 68 | while(!qu.empty()) 69 | { 70 | const luint_t cur_node_id = qu.front(); 71 | qu.pop(); 72 | 73 | /* if available, execute function on each visited node */ 74 | if (per_node_func) 75 | per_node_func(tree, cur_node_id); 76 | 77 | const TreeNode cur_node = tree->node(cur_node_id); 78 | for(luint_t i = 0; i < cur_node.degree; ++i) 79 | qu.push(cur_node.children_ids[i]); 80 | } 81 | } 82 | 83 | template 84 | bool 85 | cmp_vector( 86 | const std::vector& a, 87 | const std::vector& b, 88 | const size_t len) 89 | { 90 | bool result = true; 91 | 92 | /* no length specified: compare full vectors, size must be the same */ 93 | if(len == 0) 94 | result &= (a.size() == b.size()); 95 | 96 | const luint_t size = (len == 0 ? a.size() : len); 97 | 98 | for(luint_t i = 0; result && i < size; ++i) 99 | result &= (a[i] == b[i]); 100 | 101 | return result; 102 | } 103 | 104 | NS_MAPMAP_END -------------------------------------------------------------------------------- /mapmap/source/cost_bundle.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | 12 | NS_MAPMAP_BEGIN 13 | 14 | template 15 | CostBundle:: 16 | CostBundle( 17 | const Graph * graph) 18 | : m_graph(graph), 19 | m_unary(graph->num_nodes(), nullptr), 20 | m_pairwise(graph->num_edges(), nullptr) 21 | { 22 | 23 | } 24 | 25 | /* ************************************************************************** */ 26 | 27 | template 28 | CostBundle:: 29 | ~CostBundle() 30 | { 31 | } 32 | 33 | /* ************************************************************************** */ 34 | 35 | template 36 | FORCEINLINE 37 | void 38 | CostBundle:: 39 | set_unary_costs( 40 | const UnaryCosts * costs) 41 | { 42 | std::fill(m_unary.begin(), m_unary.end(), costs); 43 | } 44 | 45 | /* ************************************************************************** */ 46 | 47 | template 48 | FORCEINLINE 49 | void 50 | CostBundle:: 51 | set_pairwise_costs( 52 | const PairwiseCosts * costs) 53 | { 54 | std::fill(m_pairwise.begin(), m_pairwise.end(), costs); 55 | } 56 | 57 | /* ************************************************************************** */ 58 | 59 | template 60 | FORCEINLINE 61 | void 62 | CostBundle:: 63 | set_unary_costs( 64 | const luint_t node_id, 65 | const UnaryCosts * costs) 66 | { 67 | if(node_id < m_graph->num_nodes()) 68 | m_unary[node_id] = costs; 69 | } 70 | 71 | /* ************************************************************************** */ 72 | 73 | template 74 | FORCEINLINE 75 | void 76 | CostBundle:: 77 | set_pairwise_costs( 78 | const luint_t edge_id, 79 | const PairwiseCosts * costs) 80 | { 81 | if(edge_id < m_graph->num_edges()) 82 | m_pairwise[edge_id] = costs; 83 | } 84 | 85 | /* ************************************************************************** */ 86 | 87 | template 88 | FORCEINLINE 89 | const UnaryCosts * 90 | CostBundle:: 91 | get_unary_costs( 92 | const luint_t node_id) 93 | const 94 | { 95 | return (node_id < m_graph->num_nodes() ? m_unary[node_id] : nullptr); 96 | } 97 | 98 | /* ************************************************************************** */ 99 | 100 | template 101 | FORCEINLINE 102 | const PairwiseCosts * 103 | CostBundle:: 104 | get_pairwise_costs( 105 | const luint_t edge_id) 106 | const 107 | { 108 | return (edge_id < m_graph->num_edges() ? m_pairwise[edge_id] : nullptr); 109 | } 110 | 111 | NS_MAPMAP_END -------------------------------------------------------------------------------- /mapmap/header/parallel_templates.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_PARALLEL_TEMPLATES_H_ 11 | #define __MAPMAP_PARALLEL_TEMPLATES_H_ 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | NS_MAPMAP_BEGIN 25 | 26 | /** 27 | * Reduction body (operator: +) for tbb::parallel_reduce. 28 | */ 29 | template 30 | class PlusReduction 31 | { 32 | public: 33 | PlusReduction(VALTYPE* in); 34 | PlusReduction(PlusReduction& lhs, tbb::split); 35 | ~PlusReduction(); 36 | 37 | VALTYPE get_sum(); 38 | void operator()(const tbb::blocked_range& r); 39 | void join(const PlusReduction& rhs); 40 | 41 | public: 42 | VALTYPE m_sum; 43 | VALTYPE* m_in; 44 | }; 45 | 46 | /** 47 | * Reduction body (operator: max) for tbb::parallel_reduce. 48 | */ 49 | template 50 | class MaxReduction 51 | { 52 | public: 53 | MaxReduction(VALTYPE * in); 54 | MaxReduction(MaxReduction& lhs, tbb::split); 55 | ~MaxReduction(); 56 | 57 | VALTYPE get_max(); 58 | void operator()(const tbb::blocked_range& r); 59 | void join(const MaxReduction& rhs); 60 | 61 | public: 62 | VALTYPE m_max; 63 | VALTYPE * m_in; 64 | }; 65 | 66 | /** 67 | * Exclusive scan body (operator: +) for tbb::parallel_scan. 68 | */ 69 | template 70 | class PlusScan 71 | { 72 | public: 73 | PlusScan(VALTYPE* in, VALTYPE* out); 74 | PlusScan(PlusScan& lhs, tbb::split); 75 | ~PlusScan(); 76 | 77 | void operator()(const tbb::blocked_range& r, tbb::pre_scan_tag); 78 | void operator()(const tbb::blocked_range& r, 79 | tbb::final_scan_tag); 80 | void assign(PlusScan& rhs); 81 | void reverse_join(PlusScan& rhs); 82 | 83 | public: 84 | VALTYPE m_sum; 85 | VALTYPE* m_in; 86 | VALTYPE* m_out; 87 | }; 88 | 89 | /** 90 | * Histogram helper (count how many times each number occurs). 91 | * 92 | * Results in a list for values (must be discrete type) [0, length). 93 | */ 94 | template 95 | class Histogram 96 | { 97 | public: 98 | Histogram(VALTYPE* in, const VALTYPE max_val); 99 | ~Histogram(); 100 | 101 | std::vector& operator()(const tbb::blocked_range& r); 102 | 103 | protected: 104 | VALTYPE* m_in; 105 | VALTYPE m_max_val; 106 | INDEXTYPE m_length; 107 | 108 | std::vector> m_histogram; 109 | std::vector m_final_histogram; 110 | }; 111 | 112 | NS_MAPMAP_END 113 | 114 | /* include templated implementation */ 115 | #include 116 | 117 | #endif /* __MAPMAP_PARALLEL_TEMPLATES_H_ */ 118 | -------------------------------------------------------------------------------- /mapmap/source/tree_sampler.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | 12 | NS_MAPMAP_BEGIN 13 | 14 | template 15 | TreeSampler:: 16 | TreeSampler( 17 | Graph * graph) 18 | : TreeSampler(graph, false, 0) 19 | { 20 | 21 | } 22 | 23 | /* ************************************************************************** */ 24 | 25 | template 26 | TreeSampler:: 27 | TreeSampler( 28 | Graph * graph, 29 | const bool deterministic, 30 | const uint_t initial_seed) 31 | : m_graph(graph), 32 | m_rnd_dev(), 33 | m_deterministic(deterministic), 34 | m_initial_seed(initial_seed) 35 | { 36 | 37 | } 38 | 39 | /* ************************************************************************** */ 40 | 41 | template 42 | TreeSampler:: 43 | ~TreeSampler() 44 | { 45 | 46 | } 47 | 48 | /* ************************************************************************** */ 49 | 50 | template 51 | void 52 | TreeSampler:: 53 | build_component_lists() 54 | { 55 | const luint_t num_nodes = m_graph->num_nodes(); 56 | const luint_t num_components = m_graph->num_components(); 57 | const std::vector& components = m_graph->components(); 58 | 59 | m_component_lists.clear(); 60 | m_component_lists.resize(num_components); 61 | 62 | for(luint_t i = 0; i < num_components; ++i) 63 | m_component_lists[i].reserve(num_nodes / num_components); 64 | 65 | for(luint_t n = 0; n < num_nodes; ++n) 66 | m_component_lists[components[n]].push_back(n); 67 | } 68 | 69 | /* ************************************************************************** */ 70 | 71 | template 72 | void 73 | TreeSampler:: 74 | create_adj_acc() 75 | { 76 | /* make private copy of nodes' adjacency list */ 77 | std::vector m_adj_size(m_graph->num_nodes()); 78 | m_adj_offsets.resize(m_graph->num_nodes()); 79 | tbb::blocked_range node_range(0, m_graph->num_nodes(), 128u); 80 | 81 | tbb::parallel_for(node_range, 82 | [&](const tbb::blocked_range& r) 83 | { 84 | for(luint_t i = r.begin(); i != r.end(); ++i) 85 | m_adj_size[i] = m_graph->inc_edges(i).size(); 86 | }); 87 | 88 | PlusScan ex_scan(&m_adj_size[0], &m_adj_offsets[0]); 89 | tbb::parallel_scan(node_range, ex_scan); 90 | 91 | const luint_t adj_size = 2 * m_graph->edges().size(); 92 | m_adj.resize(adj_size); 93 | 94 | tbb::parallel_for(node_range, 95 | [&](const tbb::blocked_range& r) 96 | { 97 | for(luint_t i = r.begin(); i != r.end(); ++i) 98 | { 99 | const std::vector& edges = m_graph->inc_edges(i); 100 | std::memcpy(&m_adj[m_adj_offsets[i]], 101 | &edges[0], edges.size() * sizeof(luint_t)); 102 | } 103 | }); 104 | } 105 | 106 | NS_MAPMAP_END -------------------------------------------------------------------------------- /mapmap/header/tree_sampler_instances/optimistic_tree_sampler.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_HEADER_OPTIMISTIC_TREE_SAMPLER_H_ 11 | #define __MAPMAP_HEADER_OPTIMISTIC_TREE_SAMPLER_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | NS_MAPMAP_BEGIN 26 | 27 | template 28 | class OptimisticTreeSampler : public TreeSampler 29 | { 30 | public: 31 | OptimisticTreeSampler(Graph * graph); 32 | OptimisticTreeSampler(Graph * graph, const bool 33 | deterministic, const uint_t initial_seed); 34 | ~OptimisticTreeSampler(); 35 | 36 | /** 37 | * Select around k roots, satisfying the following conditions: 38 | * - each component is covered by at least one root, 39 | * - number of components <= number of roots <= number of nodes. 40 | * 41 | * After each component is covered, the remaining nodes 42 | * are sampled according to the components' size. 43 | * 44 | * Conflict checking is deferred to a later stage. 45 | */ 46 | void select_random_roots(const luint_t k, std::vector& roots); 47 | 48 | /** 49 | * Samples a maximal (acyclic) coordinate set, given a set 50 | * of roots to grow from. To achieve maximality, additional roots 51 | * may be included. 52 | * 53 | * Note: If a component is not covered by the root set, 54 | * it is also left out of the tree. 55 | * 56 | * Transfers ownership to the caller. 57 | */ 58 | std::unique_ptr> sample(std::vector& roots, 59 | bool record_dependencies, bool relax = true); 60 | 61 | public: 62 | const uint_t p_chunk_size = 16; 63 | 64 | protected: 65 | void sample_phase_I(); 66 | void sample_phase_II(); 67 | void sample_phase_III(); 68 | void sample_rescue(); 69 | void compute_dependencies(); 70 | 71 | protected: 72 | #if defined(BUILD_FOR_TEST) 73 | #include 74 | 75 | FRIEND_TEST(mapMAPTestCoordinateSet, TestIsAcyclic); 76 | FRIEND_TEST(mapMAPTestCoordinateSet, TestIsMaximal); 77 | #endif 78 | 79 | /* iteration counter for seed generation */ 80 | uint_t m_it; 81 | 82 | tbb::concurrent_vector* m_w_in; 83 | tbb::concurrent_vector* m_w_out; 84 | 85 | tbb::concurrent_vector m_w_a; 86 | tbb::concurrent_vector m_w_b; 87 | 88 | tbb::concurrent_vector m_w_new; 89 | tbb::concurrent_vector> m_w_conflict; 90 | 91 | std::unique_ptr> m_tree; 92 | std::vector m_rem_degrees; 93 | std::vector> m_markers; 94 | std::vector> m_node_locks; 95 | std::vector> m_in_queue; 96 | std::atomic m_rem_nodes; 97 | }; 98 | 99 | template 100 | using OptimisticTreeSampler_ptr = 101 | std::shared_ptr>; 102 | 103 | NS_MAPMAP_END 104 | 105 | /* include function implementations */ 106 | #include 107 | 108 | #endif /* __MAPMAP_HEADER_OPTIMISTIC_TREE_SAMPLER_H_ */ 109 | -------------------------------------------------------------------------------- /mapmap/header/optimizer_instances/dp_node_solver.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_HEADER_DP_NODE_SOLVER_H_ 11 | #define __MAPMAP_HEADER_DP_NODE_SOLVER_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | NS_MAPMAP_BEGIN 18 | 19 | template 20 | class DPNodeSolver 21 | { 22 | public: 23 | virtual ~DPNodeSolver() {}; 24 | 25 | virtual void optimize_node() = 0; 26 | virtual luint_t scratch_bytes_needed() = 0; 27 | }; 28 | 29 | template 30 | using DPNodeSolver_ptr = std::unique_ptr>; 31 | 32 | /* ************************************************************************** */ 33 | 34 | template 35 | class GeneralDPNodeSolver : 36 | public DPNodeSolver 37 | { 38 | public: 39 | GeneralDPNodeSolver( 40 | DPNode * node); 41 | virtual ~GeneralDPNodeSolver(); 42 | 43 | virtual void optimize_node(); 44 | virtual luint_t scratch_bytes_needed(); 45 | 46 | protected: 47 | _v_t get_independent_of_parent_costs( 48 | const _iv_st l_i); 49 | 50 | protected: 51 | DPNode * m_node; 52 | 53 | _s_t * m_icost_table; 54 | }; 55 | 56 | /* ************************************************************************** */ 57 | 58 | template 59 | class SubmodularDPNodeSolver : 60 | public GeneralDPNodeSolver 61 | { 62 | public: 63 | SubmodularDPNodeSolver( 64 | DPNode * node, 65 | PairwiseCostsEnvelope_ptr& env); 66 | virtual ~SubmodularDPNodeSolver(); 67 | 68 | virtual void optimize_node(); 69 | virtual luint_t scratch_bytes_needed(); 70 | 71 | protected: 72 | virtual void fill_icost_cache(); 73 | void compute_mp(); 74 | void label_union(); 75 | 76 | protected: 77 | PairwiseCostsEnvelope_ptr m_env; 78 | 79 | _iv_st * m_label_union; 80 | _iv_st m_label_union_size; 81 | 82 | _s_t * m_mprime; 83 | _iv_st * m_mprime_ix; 84 | _s_t * m_icost_cache; 85 | 86 | _s_t m_min_fp_cost; 87 | _iv_st m_min_fp; 88 | }; 89 | 90 | /* ************************************************************************** */ 91 | 92 | template 93 | class SupermodularDPNodeSolver : 94 | public SubmodularDPNodeSolver 95 | { 96 | public: 97 | SupermodularDPNodeSolver( 98 | DPNode * node, 99 | PairwiseCostsEnvelope_ptr& env); 100 | virtual ~SupermodularDPNodeSolver(); 101 | 102 | virtual void optimize_node(); 103 | virtual luint_t scratch_bytes_needed(); 104 | 105 | protected: 106 | void fill_icost_cache(); 107 | }; 108 | 109 | NS_MAPMAP_END 110 | 111 | /* include function implementations */ 112 | #include 113 | 114 | #endif /* __MAPMAP_HEADER_DP_NODE_SOLVER_H_ */ -------------------------------------------------------------------------------- /mapmap/header/optimizer_instances/dynamic_programming.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_DYNAMIC_PROGRAMMING_H_ 11 | #define __MAPMAP_DYNAMIC_PROGRAMMING_H_ 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | NS_MAPMAP_BEGIN 31 | 32 | template 33 | using tbb_allocator_ptr = std::shared_ptr>; 34 | 35 | /* ************************************************************************** */ 36 | 37 | template 38 | class DynamicProgrammingTableEntry 39 | { 40 | public: 41 | DynamicProgrammingTableEntry( 42 | DPNode * node, 43 | tbb_allocator_ptr<_s_t> allocator); 44 | ~DynamicProgrammingTableEntry(); 45 | 46 | const luint_t& node_id(); 47 | const luint_t& parent_id(); 48 | 49 | void optimize_entry(); 50 | 51 | const _s_t * optimal_value(); 52 | const _iv_st * optimal_labels(); 53 | 54 | public: 55 | DPNode * m_node; 56 | tbb_allocator_ptr<_s_t> m_allocator; 57 | }; 58 | 59 | /* ************************************************************************** */ 60 | 61 | template 62 | class CombinatorialDynamicProgramming : 63 | public TreeOptimizer 64 | { 65 | public: 66 | CombinatorialDynamicProgramming(); 67 | ~CombinatorialDynamicProgramming(); 68 | 69 | _s_t optimize( 70 | std::vector<_iv_st>& solution); 71 | 72 | protected: 73 | void discover_leaves(); 74 | void allocate_memory(); 75 | 76 | void node_memory_allocate(const luint_t node_id); 77 | void node_memory_clean_children(const luint_t node_id); 78 | 79 | void bottom_up_opt(); 80 | void top_down_opt(std::vector<_iv_st>& solution); 81 | 82 | _s_t * value_ptr(); 83 | _iv_st * index_ptr(); 84 | std::vector * current_level_queue_ptr(); 85 | std::vector * next_level_queue_ptr(); 86 | 87 | void next_level(); 88 | 89 | protected: 90 | luint_t m_level; 91 | luint_t m_level_size; 92 | 93 | tbb_allocator_ptr<_s_t> m_value_allocator; 94 | 95 | std::vector<_iv_st> m_opt_labels; 96 | std::vector<_s_t> m_opt_values; 97 | 98 | std::vector<_s_t*> m_opt_value_nodes; 99 | std::vector<_iv_st> m_opt_value_sizes; 100 | std::vector<_iv_st*> m_opt_label_nodes; 101 | 102 | std::vector m_queue_a; 103 | std::vector m_queue_b; 104 | 105 | std::vector m_leaf_ids; 106 | tbb::concurrent_vector m_root_ids; 107 | }; 108 | 109 | NS_MAPMAP_END 110 | 111 | /* include function implementations */ 112 | #include 113 | 114 | #endif /* __MAPMAP_DYNAMIC_PROGRAMMING_H_ */ 115 | -------------------------------------------------------------------------------- /mapmap/header/tree.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_TREE_H_ 11 | #define __MAPMAP_TREE_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | NS_MAPMAP_BEGIN 22 | 23 | template 24 | struct TreeNode 25 | { 26 | bool is_in_tree; 27 | 28 | luint_t parent_id; 29 | luint_t to_parent_edge_id; 30 | scalar_t to_parent_weight; 31 | 32 | luint_t node_id; 33 | luint_t degree; 34 | luint_t dependency_degree; 35 | 36 | const luint_t * children_ids; 37 | const luint_t * dependency_ids; 38 | const luint_t * dependency_edge_ids; 39 | const COSTTYPE * dependency_weights; 40 | }; 41 | 42 | /** 43 | * Represents a directed tree. All data is saved in SoA format, but returned 44 | * to the reader as AoS. 45 | * While building, access to the raw members is allowed (until finalize()) 46 | * called, which gathers children per node and disables modification. 47 | * 48 | * This tree is supposed to be a layer above an undirected graph, thus 49 | * it allocates space for one tree node per graph node. 50 | * 51 | * Assumes that number of nodes < INVALID. 52 | */ 53 | template 54 | class Tree 55 | { 56 | public: 57 | Tree(const luint_t graph_num_nodes, 58 | const luint_t graph_num_edges); 59 | ~Tree(); 60 | 61 | /** 62 | * Get a struct representation of a node (not necessarily in the tree!). 63 | */ 64 | const TreeNode node(const luint_t& node_id) const; 65 | 66 | /* Determine number of nodes in the tree */ 67 | const luint_t num_nodes() const; 68 | 69 | /* Determine number of nodes in the underlying graph */ 70 | const luint_t num_graph_nodes() const; 71 | 72 | /** 73 | * Deactivates access to the internal structures and assembles a 74 | * list of children for each node. 75 | */ 76 | void finalize(const bool compute_dependencies, 77 | const Graph * graph); 78 | 79 | /** 80 | * Accessors to raw data structures. 81 | */ 82 | std::vector& raw_parent_ids(); 83 | std::vector& raw_to_parent_edge_ids(); 84 | std::vector& raw_weights(); 85 | 86 | /* these will be generated by finalize() */ 87 | std::vector& raw_degrees(); 88 | std::vector& raw_children_offsets(); 89 | std::vector& raw_children_list(); 90 | std::vector& raw_dependency_offsets(); 91 | std::vector& raw_dependency_list(); 92 | std::vector& raw_dependency_edge_id_list(); 93 | std::vector& raw_dependency_degrees(); 94 | 95 | protected: 96 | luint_t m_num_nodes; 97 | luint_t m_graph_nodes; 98 | bool m_enable_modify; 99 | 100 | /** 101 | * Convention: 102 | * - parent_id == node_id <=> node is root 103 | * - parent_id == INVALID <=> node is not in tree 104 | */ 105 | std::vector m_parent_id; 106 | std::vector m_parent_edge_id; 107 | std::vector m_degree; 108 | std::vector m_children_offset; 109 | std::vector m_children_list; 110 | std::vector m_weight; 111 | 112 | std::vector m_dependency_degree; 113 | std::vector m_dependency_offset; 114 | std::vector m_dependency_list; 115 | std::vector m_dependency_edge_id_list; 116 | std::vector m_dependency_weight; 117 | }; 118 | 119 | NS_MAPMAP_END 120 | 121 | #include 122 | 123 | #endif /* __MAPMAP_TREE_H_ */ -------------------------------------------------------------------------------- /mapmap/source/optimizer_instances/envelope_instances/pairwise_truncated_linear_envelope.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Nick Heppert, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | 12 | NS_MAPMAP_BEGIN 13 | 14 | template 15 | FORCEINLINE 16 | PairwiseTruncatedLinearEnvelope:: 17 | PairwiseTruncatedLinearEnvelope( 18 | const PairwiseTruncatedLinear * base) 19 | : m_label_diff_cap(base->get_label_diff_cap()) 20 | { 21 | 22 | } 23 | 24 | /* ************************************************************************** */ 25 | 26 | template 27 | FORCEINLINE 28 | PairwiseTruncatedLinearEnvelope:: 29 | ~PairwiseTruncatedLinearEnvelope() 30 | { 31 | 32 | } 33 | 34 | /* ************************************************************************** */ 35 | 36 | template 37 | FORCEINLINE 38 | void 39 | PairwiseTruncatedLinearEnvelope:: 40 | compute_m_primes( 41 | DPNode * node, 42 | const _s_t * icosts, 43 | const _iv_st * lbl_union, 44 | const _iv_st lbl_union_size, 45 | _s_t * m_prime, 46 | _iv_st * m_prime_ix, 47 | _s_t * scratch) 48 | { 49 | /* Foward pass */ 50 | const _s_t c = node->c_node.to_parent_weight * 51 | ((PAIRWISE *) node->c_pairwise)->get_c(); 52 | 53 | _iv_st last_label = lbl_union[0]; 54 | for(_iv_st l_i = 1; l_i < lbl_union_size; ++l_i) 55 | { 56 | const _iv_st this_label = lbl_union[l_i]; 57 | const _s_t accum_c = _s_t( 58 | this_label - last_label) * c; 59 | 60 | if(m_prime[l_i - 1] + accum_c < m_prime[l_i]) 61 | { 62 | m_prime[l_i] = m_prime[l_i - 1] + accum_c; 63 | m_prime_ix[l_i] = m_prime_ix[l_i - 1]; 64 | } 65 | 66 | last_label = this_label; 67 | } 68 | 69 | /* Backward pass */ 70 | for(_iv_st l_i = lbl_union_size - 2; l_i >= 0; --l_i) 71 | { 72 | const _iv_st this_label = lbl_union[l_i]; 73 | const _s_t accum_c = _s_t( 74 | last_label - this_label) * c; 75 | 76 | if(m_prime[l_i + 1] + accum_c < m_prime[l_i]) 77 | { 78 | m_prime[l_i] = m_prime[l_i + 1] + accum_c; 79 | m_prime_ix[l_i] = m_prime_ix[l_i + 1]; 80 | } 81 | 82 | last_label = this_label; 83 | } 84 | } 85 | 86 | /* ************************************************************************** */ 87 | 88 | template 89 | FORCEINLINE 90 | _s_t 91 | PairwiseTruncatedLinearEnvelope:: 92 | cost_bound_d() 93 | { 94 | return m_label_diff_cap; 95 | } 96 | 97 | /* ************************************************************************** */ 98 | 99 | template 100 | FORCEINLINE 101 | luint_t 102 | PairwiseTruncatedLinearEnvelope:: 103 | scratch_bytes_needed( 104 | DPNode * node) 105 | { 106 | return 0; 107 | } 108 | 109 | NS_MAPMAP_END 110 | -------------------------------------------------------------------------------- /mapmap/source/cost_instances/unary_table.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | NS_MAPMAP_BEGIN 18 | 19 | template 20 | FORCEINLINE 21 | UnaryTable:: 22 | UnaryTable( 23 | const luint_t node_id, 24 | const LabelSet * label_set) 25 | : m_node_id(node_id), 26 | m_label_set(label_set), 27 | m_cost_table(label_set->label_set_size(node_id) + SIMDWIDTH, 0) 28 | { 29 | 30 | } 31 | 32 | /* ************************************************************************** */ 33 | 34 | template 35 | FORCEINLINE 36 | UnaryTable:: 37 | ~UnaryTable() 38 | { 39 | 40 | } 41 | 42 | /* ************************************************************************** */ 43 | 44 | template 45 | FORCEINLINE 46 | void 47 | UnaryTable:: 48 | set_costs( 49 | const std::vector<_s_t>& costs) 50 | { 51 | std::copy(costs.begin(), costs.end(), m_cost_table.begin()); 52 | } 53 | 54 | /* ************************************************************************** */ 55 | 56 | template 57 | FORCEINLINE 58 | _s_t * 59 | UnaryTable:: 60 | get_raw_costs() 61 | { 62 | return m_cost_table.data(); 63 | } 64 | 65 | /* ************************************************************************** */ 66 | 67 | template 68 | FORCEINLINE 69 | bool 70 | UnaryTable:: 71 | supports_enumerable_costs() 72 | const 73 | { 74 | return true; 75 | } 76 | 77 | /* ************************************************************************** */ 78 | 79 | template 80 | FORCEINLINE 81 | _v_t 82 | UnaryTable:: 83 | get_unary_costs( 84 | const _iv_t& label_vec) 85 | const 86 | { 87 | /* use stack array to access parts of the SSE register */ 88 | _s_t result[SIMDWIDTH]; 89 | _iv_st label_vec_d[SIMDWIDTH]; 90 | 91 | iv_store(label_vec, label_vec_d); 92 | 93 | for(uint_t i = 0; i < SIMDWIDTH; ++i) 94 | result[i] = (COSTTYPE) 0; 95 | 96 | /* find all labels in the list and assemble in new vector */ 97 | const _iv_st lset_size = 98 | m_label_set->label_set_size(m_node_id); 99 | 100 | uint_t done = 0; 101 | for(_iv_st l_id = 0; l_id < lset_size; ++l_id) 102 | { 103 | /* stop searching if all labels have been found */ 104 | if(done == SIMDWIDTH) 105 | break; 106 | 107 | const _iv_st l_id_label = 108 | m_label_set->label_from_offset(m_node_id, l_id); 109 | 110 | for(uint_t j = 0; j < SIMDWIDTH; ++j) 111 | { 112 | if(l_id_label == label_vec_d[j]) 113 | { 114 | result[j] = m_cost_table[l_id]; 115 | ++done; 116 | } 117 | } 118 | } 119 | 120 | return v_load(result); 121 | } 122 | 123 | /* ************************************************************************** */ 124 | 125 | template 126 | FORCEINLINE 127 | _v_t 128 | UnaryTable:: 129 | get_unary_costs_enum_offset( 130 | const _iv_st& offset) 131 | const 132 | { 133 | const _s_t * ptr = &m_cost_table[offset]; 134 | return v_load(ptr); 135 | } 136 | 137 | NS_MAPMAP_END 138 | -------------------------------------------------------------------------------- /mapmap/header/dynamic_programming.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_DYNAMIC_PROGRAMMING_H_ 11 | #define __MAPMAP_DYNAMIC_PROGRAMMING_H_ 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | NS_MAPMAP_BEGIN 29 | 30 | template 31 | using tbb_allocator_ptr = std::shared_ptr>; 32 | 33 | template 34 | struct DPBundle 35 | { 36 | const LabelSet * c_labels; 37 | 38 | const UNARY * c_unary; 39 | const PAIRWISE * c_binary; 40 | 41 | const std::vector<_s_t*> * c_child_values; 42 | const std::vector<_iv_st*> * c_child_labels; 43 | 44 | const std::vector<_iv_st> * c_assignment; 45 | bool respect_dependencies; 46 | }; 47 | 48 | template 49 | class DynamicProgrammingTableEntry 50 | { 51 | public: 52 | DynamicProgrammingTableEntry( 53 | const TreeNode& node, 54 | _s_t * tbl_opt_values, 55 | _iv_st * tbl_opt_labels); 56 | ~DynamicProgrammingTableEntry(); 57 | 58 | const luint_t& node_id(); 59 | const luint_t& parent_id(); 60 | 61 | void optimize_entry( 62 | const DPBundle& costs); 63 | const _s_t * optimal_value(); 64 | const _iv_st * optimal_labels(); 65 | 66 | protected: 67 | TreeNode m_node; 68 | _s_t * m_opt_values; 69 | _iv_st * m_opt_labels; 70 | }; 71 | 72 | template 73 | class CombinatorialDynamicProgramming : 74 | public TreeOptimizer 75 | { 76 | public: 77 | CombinatorialDynamicProgramming(); 78 | ~CombinatorialDynamicProgramming(); 79 | 80 | _s_t optimize( 81 | std::vector<_iv_st>& solution); 82 | 83 | protected: 84 | void discover_leaves(); 85 | void allocate_memory(); 86 | 87 | void node_memory_allocate(const luint_t node_id); 88 | void node_memory_clean_children(const luint_t node_id); 89 | 90 | void bottom_up_opt(); 91 | void top_down_opt(std::vector<_iv_st>& solution); 92 | 93 | _s_t * value_ptr(); 94 | _iv_st * index_ptr(); 95 | std::vector * current_level_queue_ptr(); 96 | std::vector * next_level_queue_ptr(); 97 | 98 | void next_level(); 99 | 100 | protected: 101 | luint_t m_level; 102 | luint_t m_level_size; 103 | 104 | tbb_allocator_ptr<_s_t> m_value_allocator; 105 | 106 | std::vector<_iv_st> m_opt_labels; 107 | std::vector<_s_t> m_opt_values; 108 | 109 | std::vector<_s_t*> m_opt_value_nodes; 110 | std::vector<_iv_st> m_opt_value_sizes; 111 | std::vector<_iv_st*> m_opt_label_nodes; 112 | 113 | std::vector m_queue_a; 114 | std::vector m_queue_b; 115 | 116 | std::vector m_leaf_ids; 117 | tbb::concurrent_vector m_root_ids; 118 | }; 119 | 120 | NS_MAPMAP_END 121 | 122 | #include 123 | 124 | #endif /* __MAPMAP_DYNAMIC_PROGRAMMING_H_ */ -------------------------------------------------------------------------------- /mapmap/source/optimizer_instances/envelope_instances/pairwise_antipotts_envelope.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | 12 | NS_MAPMAP_BEGIN 13 | 14 | template 15 | FORCEINLINE 16 | PairwiseAntipottsEnvelope:: 17 | PairwiseAntipottsEnvelope( 18 | const PairwiseAntipotts * base) 19 | : m_c(base->get_c()) 20 | { 21 | 22 | } 23 | 24 | /* ************************************************************************** */ 25 | 26 | template 27 | FORCEINLINE 28 | PairwiseAntipottsEnvelope:: 29 | ~PairwiseAntipottsEnvelope() 30 | { 31 | 32 | } 33 | 34 | /* ************************************************************************** */ 35 | 36 | template 37 | FORCEINLINE 38 | void 39 | PairwiseAntipottsEnvelope:: 40 | compute_m_primes( 41 | DPNode * node, 42 | const _s_t * icosts, 43 | const _iv_st * lbl_union, 44 | const _iv_st lbl_union_size, 45 | _s_t * m_prime, 46 | _iv_st * m_prime_ix, 47 | _s_t * scratch) 48 | { 49 | const _s_t c = node->c_node.to_parent_weight * 50 | ((PAIRWISE *) node->c_pairwise)->get_c(); 51 | 52 | /* compute minimum cost and its alternate */ 53 | _s_t min_fp_cost = 54 | std::numeric_limits::max(); 55 | _s_t alt_min_fp_cost = 56 | std::numeric_limits::max(); 57 | 58 | _iv_st min_fp = 0; 59 | _iv_st alt_min_fp = 0; 60 | 61 | /* assume invalid costs are FLT_MAX */ 62 | for(_iv_st l_i = 0; l_i < lbl_union_size; ++l_i) 63 | { 64 | const _s_t cost = m_prime[l_i]; 65 | 66 | if(cost < min_fp_cost) 67 | { 68 | /* move to second minimum */ 69 | alt_min_fp_cost = min_fp_cost; 70 | alt_min_fp = min_fp; 71 | 72 | min_fp_cost = cost; 73 | min_fp = l_i; 74 | } 75 | else if(cost < alt_min_fp_cost) 76 | { 77 | alt_min_fp_cost = cost; 78 | alt_min_fp = l_i; 79 | } 80 | } 81 | 82 | /* fill m_prime */ 83 | for(_iv_st l_i = 0; l_i < lbl_union_size; ++l_i) 84 | { 85 | if(l_i == min_fp) 86 | { 87 | m_prime[l_i] = (m_prime[l_i] + c < alt_min_fp_cost) ? 88 | m_prime[l_i] + c : alt_min_fp_cost; 89 | m_prime_ix[l_i] = (m_prime[l_i] + c < alt_min_fp_cost) ? 90 | m_prime_ix[l_i] : alt_min_fp; 91 | } 92 | else 93 | { 94 | m_prime[l_i] = (m_prime[l_i] + c < min_fp_cost) ? 95 | m_prime[l_i] + c : min_fp_cost; 96 | m_prime_ix[l_i] = (m_prime[l_i] + c < min_fp_cost) ? 97 | m_prime_ix[l_i] : min_fp; 98 | } 99 | } 100 | } 101 | 102 | /* ************************************************************************** */ 103 | 104 | template 105 | FORCEINLINE 106 | _s_t 107 | PairwiseAntipottsEnvelope:: 108 | cost_bound_d() 109 | { 110 | return m_c; 111 | } 112 | 113 | /* ************************************************************************** */ 114 | 115 | template 116 | FORCEINLINE 117 | luint_t 118 | PairwiseAntipottsEnvelope:: 119 | scratch_bytes_needed( 120 | DPNode * node) 121 | { 122 | return 0; 123 | } 124 | 125 | NS_MAPMAP_END 126 | -------------------------------------------------------------------------------- /mapmap/source/cost_instances/pairwise_potts.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | 12 | NS_MAPMAP_BEGIN 13 | 14 | template 15 | FORCEINLINE 16 | PairwisePotts:: 17 | PairwisePotts() 18 | { 19 | 20 | } 21 | 22 | /* ************************************************************************** */ 23 | 24 | template 25 | FORCEINLINE 26 | PairwisePotts:: 27 | PairwisePotts( 28 | const _s_t& c) 29 | : m_c(c) 30 | { 31 | 32 | } 33 | 34 | /* ************************************************************************** */ 35 | 36 | template 37 | FORCEINLINE 38 | PairwisePotts:: 39 | PairwisePotts( 40 | const std::initializer_list<_s_t>& ps) 41 | { 42 | if(ps.size() > 0) 43 | m_c = ps.begin()[0]; 44 | } 45 | 46 | /* ************************************************************************** */ 47 | 48 | template 49 | FORCEINLINE 50 | PairwisePotts:: 51 | ~PairwisePotts() 52 | { 53 | 54 | } 55 | 56 | /* ************************************************************************** */ 57 | 58 | template 59 | FORCEINLINE 60 | _s_t 61 | PairwisePotts:: 62 | get_c() 63 | const 64 | { 65 | return m_c; 66 | } 67 | 68 | /* ************************************************************************** */ 69 | 70 | template 71 | FORCEINLINE 72 | bool 73 | PairwisePotts:: 74 | supports_enumerable_costs() 75 | const 76 | { 77 | return false; 78 | } 79 | 80 | /* ************************************************************************** */ 81 | 82 | template 83 | FORCEINLINE 84 | std::unique_ptr> 85 | PairwisePotts:: 86 | copy() 87 | const 88 | { 89 | std::unique_ptr> uptr(new 90 | PairwisePotts(m_c)); 91 | return uptr; 92 | } 93 | 94 | /* ************************************************************************** */ 95 | 96 | template 97 | FORCEINLINE 98 | bool 99 | PairwisePotts:: 100 | eq( 101 | const PairwiseCosts * costs) 102 | const 103 | { 104 | if(typeid(*costs) != typeid(PairwisePotts)) 106 | return false; 107 | 108 | const PairwisePotts * oth = 109 | dynamic_cast*>( 110 | costs); 111 | 112 | return (m_c == oth->get_c()); 113 | } 114 | 115 | /* ************************************************************************** */ 116 | 117 | template 118 | FORCEINLINE 119 | _v_t 120 | PairwisePotts:: 121 | get_pairwise_costs( 122 | const _iv_t& label_vec_1, 123 | const _iv_t& label_vec_2) 124 | const 125 | { 126 | _v_t lv1 = iv_reinterpret_v( 127 | label_vec_1); 128 | _v_t lv2 = iv_reinterpret_v( 129 | label_vec_2); 130 | _v_t neq = v_eq(lv1, lv2); 131 | neq = v_not(neq); 132 | 133 | return v_and(v_init(m_c), neq); 134 | } 135 | 136 | /* ************************************************************************** */ 137 | 138 | template 139 | _v_t 140 | PairwisePotts:: 141 | get_pairwise_costs_enum_offsets( 142 | const _iv_t& label_ix_vec_1, 143 | const _iv_t& label_ix_vec_2) 144 | const 145 | { 146 | throw new ModeNotSupportedException("PairwisePotts does not support " \ 147 | "enumerable costs"); 148 | } 149 | 150 | NS_MAPMAP_END 151 | -------------------------------------------------------------------------------- /mapmap/header/tree_sampler_instances/lock_free_tree_sampler.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_LOCK_FREE_TREE_SAMPLER_H_ 11 | #define __MAPMAP_LOCK_FREE_TREE_SAMPLER_H_ 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | NS_MAPMAP_BEGIN 23 | 24 | /** 25 | * ***************************************************************************** 26 | * **************************** ColoredQueueBunch ****************************** 27 | * ***************************************************************************** 28 | */ 29 | 30 | template 31 | class ColoredQueueBunch 32 | { 33 | public: 34 | ColoredQueueBunch(Graph * graph); 35 | ColoredQueueBunch(Graph * graph, const bool deterministic); 36 | ~ColoredQueueBunch(); 37 | 38 | void push_to(const luint_t qu, const luint_t elem); 39 | void replace_queue(const luint_t qu, const luint_t * new_qu, 40 | const luint_t new_size); 41 | 42 | luint_t queue_size(const luint_t qu); 43 | luint_t queue_capacity(const luint_t qu); 44 | luint_t * queue(const luint_t qu); 45 | luint_t num_queues(); 46 | luint_t size(); 47 | 48 | void reset(); 49 | 50 | protected: 51 | void init(); 52 | 53 | protected: 54 | Graph * m_graph; 55 | 56 | luint_t m_num_qu; 57 | std::vector m_data; 58 | std::vector m_qu_start; 59 | std::vector> m_qu_pos; 60 | 61 | std::atomic m_size; 62 | }; 63 | 64 | /** 65 | * ***************************************************************************** 66 | * *************************** LockFreeTreeSampler ***************************** 67 | * ***************************************************************************** 68 | */ 69 | 70 | /** 71 | * Note: assumes the input graph has previously been colored. 72 | */ 73 | template 74 | class LockFreeTreeSampler : public TreeSampler 75 | { 76 | public: 77 | LockFreeTreeSampler(Graph * graph); 78 | LockFreeTreeSampler(Graph * graph, const bool 79 | deterministic, const uint_t initial_seed); 80 | ~LockFreeTreeSampler(); 81 | 82 | void select_random_roots(const luint_t k, std::vector& roots); 83 | std::unique_ptr> sample(std::vector& roots, 84 | bool record_dependencies, bool relax = true); 85 | 86 | public: 87 | const uint_t p_chunk_size = 16; 88 | 89 | protected: 90 | void sample_phase_I(); 91 | void sample_phase_II(); 92 | void sample_rescue(); 93 | 94 | protected: 95 | /* colored queue for input data */ 96 | ColoredQueueBunch m_qu; 97 | 98 | /* use iteration count as deterministic seed */ 99 | uint_t m_it; 100 | 101 | /* save this rounds' active color */ 102 | luint_t m_cur_col; 103 | 104 | /* markers for acyclic growing */ 105 | std::vector> m_markers; 106 | 107 | /* determine which nodes have been added to the respective queue */ 108 | std::vector> m_queued; 109 | 110 | /* saves nodes added in last iteration */ 111 | std::vector m_new; 112 | std::atomic m_new_size; 113 | 114 | /* temporary single-color ouput queue */ 115 | std::vector m_qu_out; 116 | std::atomic m_qu_out_pos; 117 | 118 | /* counter: nodes remaining */ 119 | std::atomic m_rem_nodes; 120 | 121 | /* counter: remaining degree per node */ 122 | std::vector m_rem_degrees; 123 | 124 | /* save resulting tree */ 125 | std::unique_ptr> m_tree; 126 | 127 | /* how many potential tree-edges to save per vertex */ 128 | const luint_t m_buf_edges = 4; 129 | 130 | /* limit for rescue roots */ 131 | const luint_t m_max_rescue = 4; 132 | }; 133 | 134 | NS_MAPMAP_END 135 | 136 | /* include function implementations */ 137 | #include 138 | 139 | #endif /* __MAPMAP_LOCK_FREE_TREE_SAMPLER_H_ */ -------------------------------------------------------------------------------- /mapmap/source/cost_instances/pairwise_antipotts.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | 12 | NS_MAPMAP_BEGIN 13 | 14 | template 15 | PairwiseAntipotts:: 16 | PairwiseAntipotts() 17 | { 18 | 19 | } 20 | 21 | /* ************************************************************************** */ 22 | 23 | template 24 | PairwiseAntipotts:: 25 | PairwiseAntipotts( 26 | const _s_t& c) 27 | : m_c(c) 28 | { 29 | 30 | } 31 | 32 | /* ************************************************************************** */ 33 | 34 | template 35 | FORCEINLINE 36 | PairwiseAntipotts:: 37 | PairwiseAntipotts( 38 | const std::initializer_list<_s_t>& ps) 39 | { 40 | if(ps.size() > 0) 41 | m_c = ps.begin()[0]; 42 | } 43 | 44 | /* ************************************************************************** */ 45 | 46 | template 47 | PairwiseAntipotts:: 48 | ~PairwiseAntipotts() 49 | { 50 | 51 | } 52 | 53 | /* ************************************************************************** */ 54 | 55 | template 56 | FORCEINLINE 57 | _s_t 58 | PairwiseAntipotts:: 59 | get_c() 60 | const 61 | { 62 | return m_c; 63 | } 64 | 65 | /* ************************************************************************** */ 66 | 67 | template 68 | FORCEINLINE 69 | _s_t 70 | PairwiseAntipotts:: 71 | get_label_diff_cap() 72 | const 73 | { 74 | return 0; 75 | } 76 | 77 | /* ************************************************************************** */ 78 | 79 | template 80 | FORCEINLINE 81 | std::unique_ptr> 82 | PairwiseAntipotts:: 83 | copy() 84 | const 85 | { 86 | std::unique_ptr> uptr(new 87 | PairwiseAntipotts(m_c)); 88 | return uptr; 89 | } 90 | 91 | /* ************************************************************************** */ 92 | 93 | template 94 | FORCEINLINE 95 | bool 96 | PairwiseAntipotts:: 97 | supports_enumerable_costs() 98 | const 99 | { 100 | return false; 101 | } 102 | 103 | /* ************************************************************************** */ 104 | 105 | template 106 | FORCEINLINE 107 | bool 108 | PairwiseAntipotts:: 109 | eq( 110 | const PairwiseCosts * costs) 111 | const 112 | { 113 | if(typeid(*costs) != typeid(PairwiseAntipotts)) 115 | return false; 116 | 117 | const PairwiseAntipotts * oth = 118 | dynamic_cast*>( 119 | costs); 120 | 121 | return (m_c == oth->get_c()); 122 | } 123 | 124 | /* ************************************************************************** */ 125 | 126 | template 127 | _v_t 128 | PairwiseAntipotts:: 129 | get_pairwise_costs( 130 | const _iv_t& label_vec_1, 131 | const _iv_t& label_vec_2) 132 | const 133 | { 134 | _v_t lv1 = iv_reinterpret_v( 135 | label_vec_1); 136 | _v_t lv2 = iv_reinterpret_v( 137 | label_vec_2); 138 | _v_t eq = v_eq(lv1, lv2); 139 | 140 | return v_and(v_init(m_c), eq); 141 | } 142 | 143 | /* ************************************************************************** */ 144 | 145 | template 146 | _v_t 147 | PairwiseAntipotts:: 148 | get_pairwise_costs_enum_offsets( 149 | const _iv_t& label_ix_vec_1, 150 | const _iv_t& label_ix_vec_2) 151 | const 152 | { 153 | throw new ModeNotSupportedException("PairwiseAntipotts does not support " \ 154 | "enumerable costs"); 155 | } 156 | 157 | NS_MAPMAP_END -------------------------------------------------------------------------------- /mapmap/source/multilevel_instances/group_same_label.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | NS_MAPMAP_BEGIN 21 | 22 | template 23 | FORCEINLINE 24 | GroupSameLabel:: 25 | GroupSameLabel() 26 | { 27 | 28 | } 29 | 30 | /* ************************************************************************** */ 31 | 32 | template 33 | FORCEINLINE 34 | GroupSameLabel:: 35 | ~GroupSameLabel() 36 | { 37 | 38 | } 39 | 40 | /* ************************************************************************** */ 41 | 42 | template 43 | FORCEINLINE 44 | void 45 | GroupSameLabel:: 46 | group_nodes( 47 | std::vector& node_in_group, 48 | const LevelSet * current_level, 49 | const std::vector<_iv_st>& current_solution, 50 | std::vector<_iv_st>& projected_solution) 51 | { 52 | const Graph * graph = current_level->level_graph; 53 | const luint_t num_nodes = graph->num_nodes(); 54 | 55 | tbb::blocked_range node_range(0, num_nodes); 56 | 57 | /* use atomic locks for synchronizing access to nodes */ 58 | std::vector> node_locks(num_nodes); 59 | std::fill(node_locks.begin(), node_locks.end(), 0); 60 | node_in_group.resize(num_nodes); 61 | std::fill(node_in_group.begin(), node_in_group.end(), invalid_luint_t); 62 | 63 | /* create seed "queue" */ 64 | std::vector qu(num_nodes); 65 | std::iota(std::begin(qu), std::end(qu), 0); 66 | #if __cplusplus > 201100L 67 | std::random_device rd; 68 | std::mt19937 g(rd()); 69 | std::shuffle(qu.begin(), qu.end(), g); 70 | #else 71 | std::random_shuffle(qu.begin(), qu.end()); 72 | #endif 73 | 74 | /* do BFSes from randomly selected seeds */ 75 | tbb::parallel_for_each(qu.begin(), qu.end(), 76 | [&](const luint_t& seed) 77 | { 78 | /* retrieve label common to this group */ 79 | const _iv_st seed_lbl = 80 | current_level->level_label_set->label_from_offset(seed, 81 | current_solution[seed]); 82 | 83 | std::queue bfs; 84 | bfs.push(seed); 85 | 86 | bool skip_neighbors; 87 | while(!bfs.empty()) 88 | { 89 | skip_neighbors = false; 90 | 91 | const luint_t cur = bfs.front(); 92 | bfs.pop(); 93 | 94 | /* lock node */ 95 | char atomic_lock = 0; 96 | while(!node_locks[cur].compare_exchange_strong(atomic_lock, 1u)) 97 | { 98 | atomic_lock = 0; 99 | }; 100 | 101 | /** 102 | * smaller marker: another thread is already here or this 103 | * thread already saw this node, so stop 104 | */ 105 | if(node_in_group[cur] <= seed) 106 | skip_neighbors = true; 107 | else 108 | node_in_group[cur] = seed; 109 | 110 | /* free node */ 111 | node_locks[cur] = 0u; 112 | 113 | /* traverse neighbors if they have the same label */ 114 | if(!skip_neighbors) 115 | { 116 | for(const luint_t& e_id : 117 | current_level->level_graph->inc_edges(cur)) 118 | { 119 | const GraphEdge& e = 120 | current_level->level_graph->edges()[e_id]; 121 | const luint_t neighbor = (e.node_a == cur) ? 122 | e.node_b : e.node_a; 123 | 124 | /* retrieve other node's label */ 125 | const _iv_st other_label = 126 | current_level->level_label_set->label_from_offset( 127 | neighbor, current_solution[neighbor]); 128 | 129 | if(other_label == seed_lbl) 130 | { 131 | bfs.push(neighbor); 132 | } 133 | } 134 | } 135 | } 136 | }); 137 | 138 | /* just copy old solution, all locations are correct, then */ 139 | projected_solution.assign(current_solution.begin(), current_solution.end()); 140 | } 141 | 142 | NS_MAPMAP_END -------------------------------------------------------------------------------- /mapmap/header/costs.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_COSTS_H_ 11 | #define __MAPMAP_COSTS_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | NS_MAPMAP_BEGIN 26 | 27 | /** 28 | * Represents sparse label tables, independent from costs. Each node 29 | * has its assigned label set (can be shared between nodes), represented 30 | * by two lists with label IDs and actual labels. 31 | */ 32 | template 33 | class LabelSet 34 | { 35 | public: 36 | LabelSet(const luint_t& num_graph_nodes, const bool compress); 37 | ~LabelSet(); 38 | 39 | /** 40 | * Retrieval functions for optimization 41 | */ 42 | const _iv_st max_label_set_size() const; 43 | const _iv_st max_label() const; 44 | const _iv_st label_set_size(const luint_t& node_id) 45 | const; 46 | _iv_t labels_from_offset(const luint_t& node_id, 47 | const _iv_st& offset) const; 48 | _iv_st label_from_offset(const luint_t& node_id, 49 | const _iv_st& offset) const; 50 | const _iv_st offset_for_label(const luint_t& node_id, 51 | const _iv_st& offset) const; 52 | const _iv_t offsets_for_labels(const luint_t& node_id, 53 | const _iv_t& offset) const; 54 | 55 | /** 56 | * Label set construction functions. 57 | */ 58 | void set_label_set_for_node(const luint_t& node_id, 59 | const std::vector<_iv_st>& label_set); 60 | 61 | protected: 62 | const uint_t hash( 63 | const std::vector<_iv_st>& label_set); 64 | 65 | protected: 66 | luint_t m_graph_num_nodes; 67 | _iv_st m_max_label_set_size; 68 | _iv_st m_max_label; 69 | 70 | /** 71 | * Note: for aligned vector access, all addresses must 72 | * be aligned. 73 | * 74 | * - For most compilers, all std::vectors are aligned. 75 | */ 76 | std::vector>> m_label_sets; 77 | std::vector m_label_set_ids; 78 | std::vector m_label_set_hashes; 79 | std::vector<_iv_st> m_label_set_sizes; 80 | std::vector m_is_ordered; 81 | 82 | bool m_compress = false; 83 | bool m_mutable = true; 84 | }; 85 | 86 | /* ************************************************************************** */ 87 | 88 | template 89 | class UnaryCosts 90 | { 91 | public: 92 | virtual ~UnaryCosts() {}; 93 | 94 | /* enumerable: offers _enum_offset funstion for indices */ 95 | virtual bool supports_enumerable_costs() const = 0; 96 | 97 | virtual _v_t get_unary_costs( 98 | const _iv_t& label_vec) const = 0; 99 | virtual _v_t get_unary_costs_enum_offset( 100 | const _iv_st& offset) const = 0; 101 | }; 102 | 103 | 104 | /* ************************************************************************** */ 105 | 106 | template 107 | class PairwiseCosts 108 | { 109 | public: 110 | virtual ~PairwiseCosts() {}; 111 | 112 | virtual std::unique_ptr> copy() const 113 | = 0; 114 | 115 | virtual bool supports_enumerable_costs() const = 0; 116 | virtual bool eq(const PairwiseCosts * costs) const = 0; 117 | 118 | virtual _v_t get_pairwise_costs( 119 | const _iv_t& label_vec_1, 120 | const _iv_t& label_vec_2) const = 0; 121 | virtual _v_t get_pairwise_costs_enum_offsets( 122 | const _iv_t& label_ix_vec_1, 123 | const _iv_t& label_ix_vec_2) const = 0; 124 | }; 125 | 126 | /* ************************************************************************** */ 127 | 128 | class ModeNotSupportedException : public std::exception 129 | { 130 | public: 131 | ModeNotSupportedException(const char* err_msg); 132 | ModeNotSupportedException(const std::string& err_msg); 133 | ~ModeNotSupportedException(); 134 | 135 | const char* what() const noexcept; 136 | 137 | protected: 138 | std::string m_err_msg; 139 | }; 140 | 141 | NS_MAPMAP_END 142 | 143 | #include 144 | 145 | #endif /* __MAPMAP_COSTS_H_ */ 146 | -------------------------------------------------------------------------------- /mapmap/source/cost_instances/pairwise_linear_peak.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | 12 | NS_MAPMAP_BEGIN 13 | 14 | template 15 | FORCEINLINE 16 | PairwiseLinearPeak:: 17 | PairwiseLinearPeak() 18 | { 19 | 20 | } 21 | 22 | /* ************************************************************************** */ 23 | 24 | template 25 | FORCEINLINE 26 | PairwiseLinearPeak:: 27 | PairwiseLinearPeak( 28 | const _s_t& c, 29 | const _s_t& label_diff_cap) 30 | : m_c(c), 31 | m_label_diff_cap(label_diff_cap) 32 | { 33 | 34 | } 35 | 36 | /* ************************************************************************** */ 37 | 38 | template 39 | FORCEINLINE 40 | PairwiseLinearPeak:: 41 | PairwiseLinearPeak( 42 | const std::initializer_list<_s_t>& ps) 43 | { 44 | if(ps.size() > 0) 45 | m_c = ps.begin()[0]; 46 | 47 | if(ps.size() > 1) 48 | m_label_diff_cap = ps.begin()[1]; 49 | } 50 | 51 | /* ************************************************************************** */ 52 | 53 | template 54 | FORCEINLINE 55 | PairwiseLinearPeak:: 56 | ~PairwiseLinearPeak() 57 | { 58 | 59 | } 60 | 61 | /* ************************************************************************** */ 62 | 63 | template 64 | FORCEINLINE 65 | _s_t 66 | PairwiseLinearPeak:: 67 | get_c() 68 | const 69 | { 70 | return m_c; 71 | } 72 | 73 | /* ************************************************************************** */ 74 | 75 | template 76 | FORCEINLINE 77 | _s_t 78 | PairwiseLinearPeak:: 79 | get_label_diff_cap() 80 | const 81 | { 82 | return m_label_diff_cap; 83 | } 84 | 85 | /* ************************************************************************** */ 86 | 87 | template 88 | FORCEINLINE 89 | std::unique_ptr> 90 | PairwiseLinearPeak:: 91 | copy() 92 | const 93 | { 94 | std::unique_ptr> uptr(new 95 | PairwiseLinearPeak(m_c, m_label_diff_cap)); 96 | return uptr; 97 | } 98 | 99 | /* ************************************************************************** */ 100 | 101 | template 102 | FORCEINLINE 103 | bool 104 | PairwiseLinearPeak:: 105 | supports_enumerable_costs() 106 | const 107 | { 108 | return false; 109 | } 110 | 111 | /* ************************************************************************** */ 112 | 113 | template 114 | FORCEINLINE 115 | bool 116 | PairwiseLinearPeak:: 117 | eq( 118 | const PairwiseCosts * costs) 119 | const 120 | { 121 | if(typeid(*costs) != typeid(PairwiseLinearPeak)) 123 | return false; 124 | 125 | const PairwiseLinearPeak * oth = 126 | dynamic_cast*>( 127 | costs); 128 | 129 | return (m_c == oth->get_c() && 130 | m_label_diff_cap == oth->get_label_diff_cap()); 131 | } 132 | 133 | /* ************************************************************************** */ 134 | 135 | template 136 | FORCEINLINE 137 | _v_t 138 | PairwiseLinearPeak:: 139 | get_pairwise_costs( 140 | const _iv_t& label_vec_1, 141 | const _iv_t& label_vec_2) 142 | const 143 | { 144 | _iv_t diff = iv_sub(label_vec_1, 145 | label_vec_2); 146 | diff = iv_abs(diff); 147 | 148 | _v_t vdiff = v_sub( 149 | v_init(m_label_diff_cap), 150 | iv_convert_v(diff)); 151 | vdiff = v_mult(vdiff, 152 | v_init(m_c)); 153 | return v_max(vdiff, v_init(0)); 154 | } 155 | 156 | /* ************************************************************************** */ 157 | 158 | template 159 | _v_t 160 | PairwiseLinearPeak:: 161 | get_pairwise_costs_enum_offsets( 162 | const _iv_t& label_ix_vec_1, 163 | const _iv_t& label_ix_vec_2) 164 | const 165 | { 166 | throw new ModeNotSupportedException("PairwiseLinearPeak does not support " \ 167 | "enumerable costs"); 168 | } 169 | 170 | NS_MAPMAP_END 171 | -------------------------------------------------------------------------------- /mapmap/source/cost_instances/pairwise_truncated_linear.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | 12 | NS_MAPMAP_BEGIN 13 | 14 | template 15 | FORCEINLINE 16 | PairwiseTruncatedLinear:: 17 | PairwiseTruncatedLinear() 18 | { 19 | 20 | } 21 | 22 | /* ************************************************************************** */ 23 | 24 | template 25 | FORCEINLINE 26 | PairwiseTruncatedLinear:: 27 | PairwiseTruncatedLinear( 28 | const _s_t& c, 29 | const _s_t& label_diff_cap) 30 | : m_c(c), 31 | m_label_diff_cap(label_diff_cap) 32 | { 33 | 34 | } 35 | 36 | /* ************************************************************************** */ 37 | 38 | template 39 | FORCEINLINE 40 | PairwiseTruncatedLinear:: 41 | PairwiseTruncatedLinear( 42 | const std::initializer_list<_s_t>& ps) 43 | { 44 | if(ps.size() > 0) 45 | m_c = ps.begin()[0]; 46 | 47 | if(ps.size() > 1) 48 | m_label_diff_cap = ps.begin()[1]; 49 | } 50 | 51 | /* ************************************************************************** */ 52 | 53 | template 54 | FORCEINLINE 55 | PairwiseTruncatedLinear:: 56 | ~PairwiseTruncatedLinear() 57 | { 58 | 59 | } 60 | 61 | /* ************************************************************************** */ 62 | 63 | template 64 | FORCEINLINE 65 | _s_t 66 | PairwiseTruncatedLinear:: 67 | get_c() 68 | const 69 | { 70 | return m_c; 71 | } 72 | 73 | /* ************************************************************************** */ 74 | 75 | template 76 | FORCEINLINE 77 | _s_t 78 | PairwiseTruncatedLinear:: 79 | get_label_diff_cap() 80 | const 81 | { 82 | return m_label_diff_cap; 83 | } 84 | 85 | /* ************************************************************************** */ 86 | 87 | template 88 | FORCEINLINE 89 | std::unique_ptr> 90 | PairwiseTruncatedLinear:: 91 | copy() 92 | const 93 | { 94 | std::unique_ptr> uptr(new 95 | PairwiseTruncatedLinear(m_c, m_label_diff_cap)); 96 | return uptr; 97 | } 98 | 99 | /* ************************************************************************** */ 100 | 101 | template 102 | FORCEINLINE 103 | bool 104 | PairwiseTruncatedLinear:: 105 | supports_enumerable_costs() 106 | const 107 | { 108 | return false; 109 | } 110 | 111 | /* ************************************************************************** */ 112 | 113 | template 114 | FORCEINLINE 115 | bool 116 | PairwiseTruncatedLinear:: 117 | eq( 118 | const PairwiseCosts * costs) 119 | const 120 | { 121 | if(typeid(*costs) != typeid(PairwiseTruncatedLinear)) 123 | return false; 124 | 125 | const PairwiseTruncatedLinear * oth = 126 | dynamic_cast*>( 127 | costs); 128 | 129 | return (m_c == oth->get_c() && 130 | m_label_diff_cap == oth->get_label_diff_cap()); 131 | } 132 | 133 | /* ************************************************************************** */ 134 | 135 | template 136 | FORCEINLINE 137 | _v_t 138 | PairwiseTruncatedLinear:: 139 | get_pairwise_costs( 140 | const _iv_t& label_vec_1, 141 | const _iv_t& label_vec_2) 142 | const 143 | { 144 | _iv_t diff = iv_sub(label_vec_1, 145 | label_vec_2); 146 | diff = iv_abs(diff); 147 | 148 | const _v_t vdiff = v_mult( 149 | iv_convert_v(diff), v_init( 150 | m_c)); 151 | return v_min(vdiff, v_init( 152 | m_label_diff_cap)); 153 | } 154 | 155 | /* ************************************************************************** */ 156 | 157 | template 158 | _v_t 159 | PairwiseTruncatedLinear:: 160 | get_pairwise_costs_enum_offsets( 161 | const _iv_t& label_ix_vec_1, 162 | const _iv_t& label_ix_vec_2) 163 | const 164 | { 165 | throw new ModeNotSupportedException("PairwiseTruncatedLinear does not " \ 166 | "support enumerable costs"); 167 | } 168 | 169 | NS_MAPMAP_END 170 | -------------------------------------------------------------------------------- /mapmap/source/cost_instances/pairwise_truncated_quadratic.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | 12 | NS_MAPMAP_BEGIN 13 | 14 | template 15 | FORCEINLINE 16 | PairwiseTruncatedQuadratic:: 17 | PairwiseTruncatedQuadratic() 18 | { 19 | 20 | } 21 | 22 | /* ************************************************************************** */ 23 | 24 | template 25 | FORCEINLINE 26 | PairwiseTruncatedQuadratic:: 27 | PairwiseTruncatedQuadratic( 28 | const _s_t& c, 29 | const _s_t& label_diff_cap) 30 | : m_c(c), 31 | m_label_diff_cap(label_diff_cap) 32 | { 33 | 34 | } 35 | 36 | /* ************************************************************************** */ 37 | 38 | template 39 | FORCEINLINE 40 | PairwiseTruncatedQuadratic:: 41 | PairwiseTruncatedQuadratic( 42 | const std::initializer_list<_s_t>& ps) 43 | { 44 | if(ps.size() > 0) 45 | m_c = ps.begin()[0]; 46 | 47 | if(ps.size() > 1) 48 | m_label_diff_cap = ps.begin()[1]; 49 | } 50 | 51 | /* ************************************************************************** */ 52 | 53 | template 54 | FORCEINLINE 55 | PairwiseTruncatedQuadratic:: 56 | ~PairwiseTruncatedQuadratic() 57 | { 58 | 59 | } 60 | 61 | /* ************************************************************************** */ 62 | 63 | template 64 | FORCEINLINE 65 | _s_t 66 | PairwiseTruncatedQuadratic:: 67 | get_c() 68 | const 69 | { 70 | return m_c; 71 | } 72 | 73 | /* ************************************************************************** */ 74 | 75 | template 76 | FORCEINLINE 77 | _s_t 78 | PairwiseTruncatedQuadratic:: 79 | get_label_diff_cap() 80 | const 81 | { 82 | return m_label_diff_cap; 83 | } 84 | 85 | /* ************************************************************************** */ 86 | 87 | template 88 | FORCEINLINE 89 | std::unique_ptr> 90 | PairwiseTruncatedQuadratic:: 91 | copy() 92 | const 93 | { 94 | std::unique_ptr> uptr(new 95 | PairwiseTruncatedQuadratic(m_c, m_label_diff_cap)); 96 | return uptr; 97 | } 98 | 99 | /* ************************************************************************** */ 100 | 101 | 102 | template 103 | FORCEINLINE 104 | bool 105 | PairwiseTruncatedQuadratic:: 106 | supports_enumerable_costs() 107 | const 108 | { 109 | return false; 110 | } 111 | 112 | /* ************************************************************************** */ 113 | 114 | template 115 | FORCEINLINE 116 | bool 117 | PairwiseTruncatedQuadratic:: 118 | eq( 119 | const PairwiseCosts * costs) 120 | const 121 | { 122 | if(typeid(*costs) != typeid(PairwiseTruncatedQuadratic)) 124 | return false; 125 | 126 | const PairwiseTruncatedQuadratic * oth = 127 | dynamic_cast*>( 128 | costs); 129 | 130 | return (m_c == oth->get_c() && 131 | m_label_diff_cap == oth->get_label_diff_cap()); 132 | } 133 | 134 | /* ************************************************************************** */ 135 | 136 | template 137 | FORCEINLINE 138 | _v_t 139 | PairwiseTruncatedQuadratic:: 140 | get_pairwise_costs( 141 | const _iv_t& label_vec_1, 142 | const _iv_t& label_vec_2) 143 | const 144 | { 145 | _iv_t diff = iv_sub(label_vec_1, 146 | label_vec_2); 147 | diff = iv_abs(diff); 148 | 149 | const _v_t qdiff = v_mult( 150 | v_mult( 151 | iv_convert_v(diff), 152 | iv_convert_v(diff)), 153 | v_init(m_c)); 154 | return v_min(qdiff, v_init( 155 | m_label_diff_cap)); 156 | } 157 | 158 | /* ************************************************************************** */ 159 | 160 | template 161 | _v_t 162 | PairwiseTruncatedQuadratic:: 163 | get_pairwise_costs_enum_offsets( 164 | const _iv_t& label_ix_vec_1, 165 | const _iv_t& label_ix_vec_2) 166 | const 167 | { 168 | throw new ModeNotSupportedException("PairwiseTruncatedQuadratic does " \ 169 | "not support enumerable costs"); 170 | } 171 | 172 | NS_MAPMAP_END 173 | -------------------------------------------------------------------------------- /ext/dset/dset.h: -------------------------------------------------------------------------------- 1 | #if !defined(__UNIONFIND_H) 2 | #define __UNIONFIND_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /** 9 | * Lock-free parallel disjoint set data structure (aka UNION-FIND) 10 | * with path compression and union by rank 11 | * 12 | * Supports concurrent find(), same() and unite() calls as described 13 | * in the paper 14 | * 15 | * "Wait-free Parallel Algorithms for the Union-Find Problem" 16 | * by Richard J. Anderson and Heather Woll 17 | * 18 | * In addition, this class supports optimistic locking (try_lock/unlock) 19 | * of disjoint sets and a combined unite+unlock operation. 20 | * 21 | * \author Wenzel Jakob 22 | */ 23 | class DisjointSets { 24 | public: 25 | DisjointSets(uint32_t size) : mData(size) { 26 | for (uint32_t i=0; i r2 || (r1 == r2 && id1 < id2)) { 66 | std::swap(r1, r2); 67 | std::swap(id1, id2); 68 | } 69 | 70 | uint64_t oldEntry = ((uint64_t) r1 << 32) | id1; 71 | uint64_t newEntry = ((uint64_t) r1 << 32) | id2; 72 | 73 | if (!mData[id1].compare_exchange_strong(oldEntry, newEntry)) 74 | continue; 75 | 76 | if (r1 == r2) { 77 | oldEntry = ((uint64_t) r2 << 32) | id2; 78 | newEntry = ((uint64_t) (r2+1) << 32) | id2; 79 | /* Try to update the rank (may fail, that's ok) */ 80 | mData[id2].compare_exchange_weak(oldEntry, newEntry); 81 | } 82 | 83 | break; 84 | } 85 | return id2; 86 | } 87 | 88 | /** 89 | * Try to lock the a disjoint union identified by one 90 | * of its elements (this can occasionally fail when there 91 | * are concurrent operations). The parameter 'id' will be 92 | * updated to store the current representative ID of the 93 | * union 94 | */ 95 | bool try_lock(uint32_t &id) { 96 | const uint64_t lock_flag = 1ULL << 63; 97 | id = find(id); 98 | uint64_t value = mData[id]; 99 | if ((value & lock_flag) || (uint32_t) value != id) 100 | return false; 101 | // On IA32/x64, a PAUSE instruction is recommended for CAS busy loops 102 | #if defined(__i386__) || defined(__amd64__) 103 | __asm__ __volatile__ ("pause\n"); 104 | #endif 105 | return mData[id].compare_exchange_strong(value, value | lock_flag); 106 | } 107 | 108 | void unlock(uint32_t id) { 109 | const uint64_t lock_flag = 1ULL << 63; 110 | mData[id] &= ~lock_flag; 111 | } 112 | 113 | /** 114 | * Return the representative index of the set that results from merging 115 | * locked disjoint sets 'id1' and 'id2' 116 | */ 117 | uint32_t unite_index_locked(uint32_t id1, uint32_t id2) const { 118 | uint32_t r1 = rank(id1), r2 = rank(id2); 119 | return (r1 > r2 || (r1 == r2 && id1 < id2)) ? id1 : id2; 120 | } 121 | 122 | /** 123 | * Atomically unite two locked disjoint sets and unlock them. Assumes 124 | * that here are no other concurrent unite() involving the same sets 125 | */ 126 | uint32_t unite_unlock(uint32_t id1, uint32_t id2) { 127 | uint32_t r1 = rank(id1), r2 = rank(id2); 128 | 129 | if (r1 > r2 || (r1 == r2 && id1 < id2)) { 130 | std::swap(r1, r2); 131 | std::swap(id1, id2); 132 | } 133 | 134 | mData[id1] = ((uint64_t) r1 << 32) | id2; 135 | mData[id2] = ((uint64_t) (r2 + ((r1 == r2) ? 1 : 0)) << 32) | id2; 136 | 137 | return id2; 138 | } 139 | 140 | uint32_t size() const { return (uint32_t) mData.size(); } 141 | 142 | uint32_t rank(uint32_t id) const { 143 | return ((uint32_t) (mData[id] >> 32)) & 0x7FFFFFFFu; 144 | } 145 | 146 | uint32_t parent(uint32_t id) const { 147 | return (uint32_t) mData[id]; 148 | } 149 | 150 | friend std::ostream &operator<<(std::ostream &os, const DisjointSets &f) { 151 | for (size_t i=0; i 30 | { 31 | public: 32 | using cost_t = float; 33 | 34 | const uint_t num_components = 2; 35 | const uint_t component_dim = 100; 36 | 37 | public: 38 | mapMAPTestCoordinateSet() 39 | { 40 | 41 | } 42 | 43 | ~mapMAPTestCoordinateSet() 44 | { 45 | 46 | } 47 | 48 | void 49 | SetUp() 50 | { 51 | /* create a grid graph with a given number of connected components */ 52 | m_graph = createComponentGrid(num_components, component_dim); 53 | 54 | /* select one root per component */ 55 | for (uint_t c = 0; c < num_components; ++c) 56 | m_roots.push_back(c * component_dim * component_dim); 57 | 58 | m_sampler = InstanceFactory::get_sampler_instance( 59 | GetParam(), m_graph.get(), true, 0); 60 | 61 | m_tree = m_sampler->sample(m_roots, true, false); 62 | 63 | /* retrieve tree's nodes */ 64 | const luint_t num_nodes = m_graph->num_nodes(); 65 | for(luint_t n = 0; n < num_nodes; ++n) 66 | { 67 | const TreeNode node = m_tree->node(n); 68 | if(node.parent_id == node.node_id) 69 | m_actual_roots.push_back(n); 70 | } 71 | } 72 | 73 | void 74 | TearDown() 75 | { 76 | 77 | } 78 | 79 | std::unique_ptr> m_graph; 80 | std::unique_ptr> m_sampler; 81 | std::vector m_roots; 82 | std::vector m_actual_roots; 83 | 84 | std::unique_ptr> m_tree; 85 | }; 86 | 87 | TEST_P(mapMAPTestCoordinateSet, TestIsAcyclic) 88 | { 89 | /* 90 | * Test acyclicity locally: for each graph node in the tree, each 91 | * neighboured node that is in the tree must be either parent or 92 | * child of the node under test. 93 | */ 94 | 95 | /* Phase I : mark all nodes included in the tree */ 96 | const luint_t num_nodes = m_graph->num_nodes(); 97 | std::vector in_tree(num_nodes, 0); 98 | for(luint_t i = 0; i < num_nodes; ++i) 99 | { 100 | TreeNode node = m_tree->node(i); 101 | in_tree[i] = (node.is_in_tree ? 1u : 0u); 102 | } 103 | 104 | /* Phase II : check the mentioned criterion */ 105 | for(luint_t i = 0; i < num_nodes; ++i) 106 | { 107 | TreeNode node = m_tree->node(i); 108 | 109 | if(in_tree[i] == 0) 110 | continue; 111 | 112 | /* Retrieve all adjacent nodes in the tree */ 113 | std::vector adjacent_in_tree; 114 | for(const luint_t& e_id : m_graph->inc_edges(i)) 115 | { 116 | const GraphEdge& e = m_graph->edges()[e_id]; 117 | const luint_t other_node = (e.node_a == 118 | i ? e.node_b : e.node_a); 119 | 120 | if(in_tree[other_node] > 0u) 121 | adjacent_in_tree.push_back(other_node); 122 | } 123 | 124 | /* Check if retrieved nodes are parent or children */ 125 | for(const luint_t& o_n : adjacent_in_tree) 126 | { 127 | auto found = std::find(&node.children_ids[0], 128 | &node.children_ids[node.degree], o_n); 129 | 130 | ASSERT_TRUE(node.parent_id == o_n || found != 131 | &node.children_ids[node.degree]); 132 | } 133 | } 134 | } 135 | 136 | TEST_P(mapMAPTestCoordinateSet, TestIsMaximal) 137 | { 138 | /* Phase I : mark all nodes included in the tree */ 139 | const luint_t num_nodes = m_graph->num_nodes(); 140 | std::vector in_tree(num_nodes, 0); 141 | for(luint_t i = 0; i < num_nodes; ++i) 142 | { 143 | TreeNode node = m_tree->node(i); 144 | in_tree[i] = (node.is_in_tree ? 1u : 0u); 145 | } 146 | 147 | /* 148 | * Phase II : count neighboring nodes in tree for free nodes and 149 | * test that marker is >= 2 (otherwise the node could have been added 150 | * as coordinate. 151 | */ 152 | for(luint_t i = 0; i < num_nodes; ++i) 153 | { 154 | TreeNode node = m_tree->node(i); 155 | 156 | if (node.is_in_tree) 157 | continue; 158 | 159 | /* Count neighboring nodes which are in the tree */ 160 | luint_t marker = 0; 161 | for (const luint_t& e_id : m_graph->inc_edges(i)) 162 | { 163 | const GraphEdge& e = m_graph->edges()[e_id]; 164 | const luint_t other_node = (e.node_a == 165 | i ? e.node_b : e.node_a); 166 | TreeNode o_node = m_tree->node(other_node); 167 | 168 | if (o_node.is_in_tree) 169 | ++marker; 170 | } 171 | 172 | ASSERT_GE(marker, 2u); 173 | } 174 | } 175 | 176 | INSTANTIATE_TEST_CASE_P(AcyclicTest, 177 | mapMAPTestCoordinateSet, 178 | ::testing::Values(OPTIMISTIC_TREE_SAMPLER, LOCK_FREE_TREE_SAMPLER)); 179 | 180 | NS_MAPMAP_END 181 | -------------------------------------------------------------------------------- /mapmap/source/color.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2017, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | NS_MAPMAP_BEGIN 19 | 20 | template 21 | Color:: 22 | Color( 23 | Graph& graph) 24 | : Color(graph, false) 25 | { 26 | 27 | } 28 | 29 | /* ************************************************************************** */ 30 | 31 | template 32 | Color:: 33 | Color( 34 | Graph& graph, 35 | const bool deterministic) 36 | : m_graph(graph), 37 | m_deterministic(deterministic), 38 | m_conf_a(), 39 | m_conf_b() 40 | { 41 | 42 | } 43 | 44 | /* ************************************************************************** */ 45 | template 46 | Color:: 47 | ~Color() 48 | { 49 | 50 | } 51 | 52 | /* ************************************************************************** */ 53 | 54 | template 55 | void 56 | Color:: 57 | color_graph( 58 | std::vector& coloring) 59 | { 60 | const luint_t n = m_graph.num_nodes(); 61 | 62 | /* pointers for in/out queue in every iteration */ 63 | tbb::concurrent_vector * conf_in = &m_conf_a; 64 | tbb::concurrent_vector * conf_out = &m_conf_b; 65 | 66 | /* record all nodes as conflicts */ 67 | conf_in->resize(n); 68 | std::iota(conf_in->begin(), conf_in->end(), 0); 69 | 70 | /* acc: use max_d as initial number of colors */ 71 | std::atomic k(1); 72 | 73 | /* use atomics for colors */ 74 | std::vector> atom_colors(n); 75 | std::fill(atom_colors.begin(), atom_colors.end(), 0); 76 | 77 | std::vector conf_arrays((k + 1) * conf_in->size()); 78 | while(!conf_in->empty()) 79 | { 80 | const luint_t old_k = k; 81 | 82 | /* clear output arrays */ 83 | conf_out->clear(); 84 | 85 | /* compute necessary memory for forbidden arrays */ 86 | const luint_t mem_size = conf_in->size() * (k + 1); 87 | if(conf_arrays.size() < mem_size) 88 | conf_arrays.resize(mem_size); 89 | 90 | /* resolve detected conflicts */ 91 | tbb::blocked_range conf_range(0, conf_in->size(), 64u); 92 | const auto fun_resolve = [&](const tbb::blocked_range& r) 93 | { 94 | for(luint_t ix = r.begin(); ix != r.end(); ++ix) 95 | { 96 | const luint_t conf_node = (*conf_in)[ix]; 97 | 98 | /* clear forbidden array */ 99 | char * forbidden = conf_arrays.data() + ix * old_k; 100 | std::memset(forbidden, 0, old_k); 101 | 102 | /* collect neighboring colors */ 103 | const luint_t degree = m_graph.inc_edges(conf_node).size(); 104 | for(luint_t j = 0; j < degree; ++j) 105 | { 106 | const luint_t e_id = 107 | m_graph.inc_edges(conf_node)[j]; 108 | const GraphEdge& e = m_graph.edges()[e_id]; 109 | const luint_t o_node = (e.node_a == conf_node) ? 110 | e.node_b : e.node_a; 111 | 112 | forbidden[atom_colors[o_node]] = 1u; 113 | } 114 | 115 | /* find minimum non-conflicting color */ 116 | luint_t new_color = atom_colors[conf_node]; 117 | for(luint_t i = 0; i < old_k && 118 | forbidden[new_color]; ++i) 119 | new_color = i; 120 | 121 | /* still not conflict-free? need to add one color */ 122 | if(forbidden[new_color]) 123 | { 124 | luint_t atomic_k = old_k; 125 | k.compare_exchange_strong(atomic_k, old_k + 1); 126 | new_color = old_k + 1; 127 | } 128 | 129 | /* set color atomically */ 130 | atom_colors[conf_node] = new_color; 131 | } 132 | }; 133 | 134 | /* for deterministic coloring, run function serially */ 135 | if(m_deterministic) 136 | fun_resolve(conf_range); 137 | else 138 | tbb::parallel_for(conf_range, fun_resolve); 139 | 140 | /* detect remaining conflicts */ 141 | const auto fun_detect = [&](const tbb::blocked_range& r) 142 | { 143 | for(luint_t ix = r.begin(); ix != r.end(); ++ix) 144 | { 145 | const luint_t conf_node = (*conf_in)[ix]; 146 | 147 | /* detect conflicts */ 148 | bool recorded_node = false; 149 | const luint_t degree = m_graph.inc_edges(conf_node).size(); 150 | for(luint_t j = 0; j < degree && !recorded_node; ++j) 151 | { 152 | const luint_t e_id = 153 | m_graph.inc_edges(conf_node)[j]; 154 | const GraphEdge& e = m_graph.edges()[e_id]; 155 | const luint_t o_node = (e.node_a == conf_node) ? 156 | e.node_b : e.node_a; 157 | 158 | if(atom_colors[conf_node] == atom_colors[o_node] && 159 | conf_node < o_node) 160 | { 161 | conf_out->push_back(conf_node); 162 | recorded_node = true; 163 | } 164 | } 165 | } 166 | }; 167 | 168 | /* for deterministic coloring, run function serially */ 169 | if(m_deterministic) 170 | fun_detect(conf_range); 171 | else 172 | tbb::parallel_for(conf_range, fun_detect); 173 | 174 | /* exchange input/output queues */ 175 | std::swap(conf_in, conf_out); 176 | } 177 | 178 | /* copy coloring from atomics */ 179 | coloring.resize(n); 180 | std::copy(atom_colors.begin(), atom_colors.end(), coloring.begin()); 181 | } 182 | 183 | NS_MAPMAP_END -------------------------------------------------------------------------------- /mapmap/header/multilevel.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_MULTILEVEL_H_ 11 | #define __MAPMAP_MULTILEVEL_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | NS_MAPMAP_BEGIN 26 | 27 | template 28 | struct LevelSet 29 | { 30 | /* might be modified by coloring */ 31 | Graph * level_graph; 32 | const LabelSet * level_label_set; 33 | CostBundle * level_cost_bundle; 34 | 35 | /* associate nodes from previous level with nodes in this level */ 36 | std::vector prev_node_in_group; 37 | }; 38 | 39 | /* ************************************************************************** */ 40 | 41 | /** 42 | * Given a level set (graph and costs) and a labelling, groups nodes 43 | * into supernodes. Does not require a contiguous ID range for supernodes. 44 | * That will be handled in the multilevel master class. 45 | * 46 | * Class must also be able to project the old solution to the 47 | * upper level (by choosing one label in each supernode e.g.), use 48 | * place of representative node in projected_solution. 49 | */ 50 | template 51 | class MultilevelCriterion 52 | { 53 | public: 54 | virtual ~MultilevelCriterion() {} 55 | 56 | virtual void group_nodes(std::vector& node_in_group, 57 | const LevelSet * current_level, 58 | const std::vector<_iv_st>& current_solution, 59 | std::vector<_iv_st>& projected_solution) = 0; 60 | }; 61 | 62 | /* ************************************************************************** */ 63 | 64 | /** 65 | * A customizable multilevel solver. Starting from a given MRF, it coarsens (and 66 | * possibly refines) the graph and costs iteratively by grouping nodes 67 | * according to some criterion. The coarsened graph is another MRF to be 68 | * solved; its solution may i.e. be reprojected onto the original MRF. 69 | * 70 | * The criterion/algorithm for grouping nodes must be specified as an instance 71 | * of MultilevelCriterion. 72 | */ 73 | 74 | template 75 | class Multilevel 76 | { 77 | public: 78 | Multilevel(Graph * original_graph, 79 | const LabelSet * original_label_set, 80 | const CostBundle * original_cost_bundle, 81 | MultilevelCriterion * criterion); 82 | Multilevel(Graph * original_graph, 83 | const LabelSet * original_label_set, 84 | const CostBundle * original_cost_bundle, 85 | MultilevelCriterion * criterion, 86 | const bool deterministic); 87 | ~Multilevel(); 88 | 89 | const CostBundle * get_level_cost_bundle() const; 90 | Graph * get_level_graph() const; 91 | const LabelSet * get_level_label_set() const; 92 | 93 | bool prev_level(); 94 | bool next_level(const std::vector<_iv_st>& 95 | current_solution, std::vector<_iv_st>& 96 | projected_solution); 97 | void reproject_solution(const std::vector<_iv_st>& 98 | level_solution, std::vector<_iv_st>& 99 | original_solution); 100 | 101 | protected: 102 | 103 | /* common functionalities */ 104 | void compute_contiguous_ids(const 105 | std::vector<_iv_st>& projected_solution); 106 | void compute_level_label_set(); 107 | void compute_level_cost_bundle(); 108 | void compute_level_unaries(); 109 | void compute_level_pairwise(); 110 | void compute_level_graph_from_node_groups(); 111 | 112 | protected: 113 | /* switch on/off determinism in graph creation */ 114 | const bool m_deterministic; 115 | 116 | /* node grouping algorithm/criterion */ 117 | MultilevelCriterion * 118 | m_criterion; 119 | 120 | /* all levels - [0] is the original */ 121 | std::vector> m_levels; 122 | 123 | /* current level */ 124 | luint_t m_level; 125 | 126 | /* pointers for quick access to important levels */ 127 | LevelSet * m_previous; 128 | LevelSet * m_current; 129 | 130 | /* data storage for the level structures */ 131 | std::vector>> m_storage_graph; 132 | std::vector>> 133 | m_storage_label_set; 134 | std::vector>> 135 | m_storage_cbundle; 136 | std::vector>> 137 | m_storage_unaries; 138 | std::vector>> 139 | m_storage_pairwise; 140 | 141 | /** 142 | * temporary data for the construction of the next level - 143 | * creeated from scratch for every level 144 | */ 145 | 146 | /* node grouping data */ 147 | luint_t m_num_supernodes; 148 | 149 | /* record which nodes are contained in which supernodes */ 150 | std::vector m_supernode_sizes; 151 | std::vector m_supernode_offsets; 152 | std::vector m_supernode_list; 153 | 154 | /* record which original edges are incident with which supernode */ 155 | std::vector m_superedge_sizes; 156 | std::vector m_superedge_offsets; 157 | std::vector m_superedge_list; 158 | 159 | /* save chosen labels for supernodes (-> dependencies lateron) */ 160 | std::vector<_iv_st> m_labels; 161 | 162 | /* mutex for writing access to the graph */ 163 | std::mutex m_graph_write_mutex; 164 | 165 | /* allocator for working tables */ 166 | std::unique_ptr>> 167 | m_value_allocator; 168 | 169 | /* debug */ 170 | std::vector<_iv_st> m_solution; 171 | }; 172 | 173 | NS_MAPMAP_END 174 | 175 | #include 176 | 177 | #endif /* __MAPMAP_MULTILEVEL_H_ */ 178 | -------------------------------------------------------------------------------- /mapmap/header/mapmap.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | 10 | #ifndef __MAPMAP_MAPMAP_H_ 11 | #define __MAPMAP_MAPMAP_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | NS_MAPMAP_BEGIN 35 | 36 | /* constants for printing */ 37 | const char * const UNIX_COLOR_BLACK = "\033[0;30m"; 38 | const char * const UNIX_COLOR_DARKBLUE = "\033[0;34m"; 39 | const char * const UNIX_COLOR_DARKGREEN = "\033[0;32m"; 40 | const char * const UNIX_COLOR_DARKTEAL = "\033[0;36m"; 41 | const char * const UNIX_COLOR_DARKRED = "\033[0;31m"; 42 | const char * const UNIX_COLOR_DARKPINK = "\033[0;35m"; 43 | const char * const UNIX_COLOR_DARKYELLOW = "\033[0;33m"; 44 | const char * const UNIX_COLOR_GRAY = "\033[0;37m"; 45 | const char * const UNIX_COLOR_DARKGRAY = "\033[1;30m"; 46 | const char * const UNIX_COLOR_BLUE = "\033[1;34m"; 47 | const char * const UNIX_COLOR_GREEN = "\033[1;32m"; 48 | const char * const UNIX_COLOR_TEAL = "\033[1;36m"; 49 | const char * const UNIX_COLOR_RED = "\033[1;31m"; 50 | const char * const UNIX_COLOR_PINK = "\033[1;35m"; 51 | const char * const UNIX_COLOR_YELLOW = "\033[1;33m"; 52 | const char * const UNIX_COLOR_WHITE = "\033[1;37m"; 53 | const char * const UNIX_COLOR_RESET = "\033[0m"; 54 | 55 | /* MAPMAP main class */ 56 | template 57 | class mapMAP 58 | { 59 | public: 60 | /* constructor for passing all components as ready-made objects */ 61 | mapMAP(); 62 | /* constructor for allowing manual construction of graph and label set */ 63 | mapMAP(const luint_t num_nodes, const luint_t num_labels); 64 | ~mapMAP(); 65 | 66 | /* set graph and label set */ 67 | void set_graph(Graph * graph); 68 | void set_label_set(const LabelSet * label_set); 69 | 70 | /* alternatively - construct graph and label set */ 71 | void add_edge(const luint_t node_a, const luint_t node_b, 72 | const _s_t weight = 1.0); 73 | void set_node_label_set(const luint_t node_id, const 74 | std::vector<_iv_st>& label_set); 75 | 76 | /* set MRF cost functions (compatibility mode) */ 77 | void set_unaries(const UnaryCosts * unaries); 78 | void set_pairwise(const PairwiseCosts * pairwise); 79 | 80 | /* set MRF cost functions (individual mode) */ 81 | void set_unary(const luint_t node_id, 82 | const UnaryCosts * unary); 83 | void set_pairwise(const luint_t edge_id, 84 | const PairwiseCosts * pairwise); 85 | 86 | /* configuration */ 87 | void set_multilevel_criterion(MultilevelCriterion * 88 | criterion); 89 | void set_termination_criterion(TerminationCriterion * criterion); 91 | 92 | /** 93 | * callback for external logging - outputs time in ms and energy after 94 | */ 95 | void set_logging_callback(const std::function)>& callback); 97 | 98 | /* start optimization */ 99 | _s_t optimize(std::vector<_iv_st>& 100 | solution); 101 | 102 | /* start optimization with customized control flow */ 103 | _s_t optimize(std::vector<_iv_st>& 104 | solution, const mapMAP_control& control_flow); 105 | 106 | protected: 107 | /* setup, sanity checks and tools */ 108 | void create_std_modules(); 109 | bool check_data_complete(); 110 | void record_time_from_start(); 111 | void print_status(); 112 | 113 | /* encapsule optimization steps */ 114 | _s_t initial_labelling(); 115 | _s_t opt_step_spanning_tree(); 116 | _s_t opt_step_multilevel(); 117 | _s_t opt_step_acyclic(bool relax_maximality); 118 | bool check_termination(); 119 | 120 | protected: 121 | /* status flags */ 122 | bool m_construct_graph; 123 | 124 | bool m_set_graph; 125 | bool m_set_label_set; 126 | bool m_set_unaries; 127 | bool m_set_pairwise; 128 | bool m_set_multilevel_criterion; 129 | bool m_set_termination_criterion; 130 | 131 | /* graph statistics for construction */ 132 | luint_t m_num_nodes; 133 | luint_t m_num_labels; 134 | 135 | /* cost functions */ 136 | std::unique_ptr> m_cbundle; 137 | 138 | /* underlying graph (may be augmented by coloring) */ 139 | Graph * m_graph; 140 | const LabelSet * m_label_set; 141 | 142 | /* configuration */ 143 | MultilevelCriterion * 144 | m_multilevel_criterion; 145 | TerminationCriterion * 146 | m_termination_criterion; 147 | 148 | /* algorithms */ 149 | TREE_SAMPLER_ALGORITHM m_tree_sampler_algo; 150 | bool m_sample_deterministic; 151 | std::mt19937 m_seeder; 152 | 153 | luint_t m_num_roots = 64u; 154 | 155 | /* storage for functional modules */ 156 | std::unique_ptr> 157 | m_multilevel; 158 | std::unique_ptr> 159 | m_storage_multilevel_criterion; 160 | std::unique_ptr> 161 | m_storage_termination_criterion; 162 | 163 | /* utilities */ 164 | std::set m_label_set_check; 165 | std::chrono::system_clock::time_point m_time_start; 166 | 167 | /* current solution */ 168 | std::vector<_iv_st> m_solution; 169 | _s_t m_objective; 170 | 171 | /* solver history data */ 172 | std::vector<_s_t> m_hist_energy; 173 | std::vector m_hist_time; 174 | std::vector m_hist_mode; 175 | 176 | luint_t m_hist_acyclic_iterations; 177 | luint_t m_hist_spanningtree_iterations; 178 | luint_t m_hist_multilevel_iterations; 179 | 180 | /* callback data */ 181 | bool m_use_callback; 182 | std::function)> 183 | m_callback; 184 | }; 185 | 186 | NS_MAPMAP_END 187 | 188 | #include 189 | 190 | #endif /* __MAPMAP_MAPMAP_H_ */ 191 | -------------------------------------------------------------------------------- /mapmap/source/tree_optimizer.impl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016, Daniel Thuerck 3 | * TU Darmstadt - Graphics, Capture and Massively Parallel Computing 4 | * All rights reserved. 5 | * 6 | * This software may be modified and distributed under the terms 7 | * of the BSD license. See the LICENSE file for details. 8 | */ 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | NS_MAPMAP_BEGIN 17 | 18 | template 19 | TreeOptimizer:: 20 | TreeOptimizer() 21 | : m_has_tree(false), 22 | m_has_label_set(false), 23 | m_has_costs(false), 24 | m_uses_dependencies(false) 25 | { 26 | 27 | } 28 | 29 | /* ************************************************************************** */ 30 | 31 | template 32 | TreeOptimizer:: 33 | ~TreeOptimizer() 34 | { 35 | 36 | } 37 | 38 | /* ************************************************************************** */ 39 | 40 | template 41 | void 42 | TreeOptimizer:: 43 | set_graph( 44 | const Graph * graph) 45 | { 46 | m_graph = graph; 47 | m_has_graph = true; 48 | } 49 | 50 | /* ************************************************************************** */ 51 | 52 | template 53 | void 54 | TreeOptimizer:: 55 | set_tree( 56 | const Tree * tree) 57 | { 58 | m_tree = tree; 59 | m_has_tree = true; 60 | } 61 | 62 | /* ************************************************************************** */ 63 | 64 | template 65 | void 66 | TreeOptimizer:: 67 | set_label_set( 68 | const LabelSet * label_set) 69 | { 70 | m_label_set = label_set; 71 | m_has_label_set = true; 72 | } 73 | 74 | /* ************************************************************************** */ 75 | 76 | template 77 | void 78 | TreeOptimizer:: 79 | set_costs( 80 | const CostBundle * cbundle) 81 | { 82 | m_cbundle = cbundle; 83 | m_has_costs = true; 84 | } 85 | 86 | /* ************************************************************************** */ 87 | 88 | template 89 | void 90 | TreeOptimizer:: 91 | use_dependencies( 92 | const std::vector<_iv_st>& current_solution) 93 | { 94 | m_current_assignment = current_solution; 95 | m_uses_dependencies = true; 96 | } 97 | 98 | /* ************************************************************************** */ 99 | 100 | template 101 | _s_t 102 | TreeOptimizer:: 103 | objective( 104 | const std::vector<_iv_st>& solution) 105 | { 106 | _s_t objective = (COSTTYPE) 0; 107 | tbb::blocked_range node_range(0, m_graph->num_nodes()); 108 | tbb::blocked_range edge_range(0, m_graph->edges().size()); 109 | 110 | /* unary costs */ 111 | objective += tbb::parallel_deterministic_reduce(node_range, (COSTTYPE) 0, 112 | [&](const tbb::blocked_range& r, COSTTYPE reduced) 113 | { 114 | _s_t tmp[SIMDWIDTH]; 115 | _s_t my_chunk = reduced; 116 | 117 | for(luint_t n = r.begin(); n != r.end(); ++n) 118 | { 119 | const UnaryCosts * ucosts = 120 | m_cbundle->get_unary_costs(n); 121 | 122 | /* determine label index for node n */ 123 | const uint_t n_l = solution[n]; 124 | 125 | _v_t u_costs; 126 | if(ucosts->supports_enumerable_costs()) 127 | { 128 | u_costs = ucosts->get_unary_costs_enum_offset(n_l); 129 | } 130 | else 131 | { 132 | /* translate to label */ 133 | const _iv_st l = 134 | m_label_set->label_from_offset(n, n_l); 135 | 136 | /* get cost vector */ 137 | u_costs = ucosts-> 138 | get_unary_costs(iv_init(l)); 139 | } 140 | 141 | v_store(u_costs, tmp); 142 | my_chunk += tmp[0]; 143 | } 144 | 145 | return my_chunk; 146 | }, 147 | std::plus()); 148 | 149 | /* pairwise costs */ 150 | objective += tbb::parallel_deterministic_reduce(edge_range, (COSTTYPE) 0, 151 | [&](const tbb::blocked_range& r, COSTTYPE reduced) 152 | { 153 | _s_t tmp[SIMDWIDTH]; 154 | _s_t my_chunk = reduced; 155 | 156 | for(luint_t e = r.begin(); e != r.end(); ++e) 157 | { 158 | const PairwiseCosts * pcosts = 159 | m_cbundle->get_pairwise_costs(e); 160 | 161 | /* determine label (indices) for both nodes */ 162 | const luint_t n_a = m_graph->edges()[e].node_a; 163 | const luint_t n_b = m_graph->edges()[e].node_b; 164 | const _s_t e_weight = 165 | m_graph->edges()[e].weight; 166 | 167 | const _iv_st n_a_l_i = solution[n_a]; 168 | const _iv_st n_b_l_i = solution[n_b]; 169 | 170 | /* translate to labels */ 171 | const _iv_st n_a_l = 172 | m_label_set->label_from_offset(n_a, n_a_l_i); 173 | const _iv_st n_b_l = 174 | m_label_set->label_from_offset(n_b, n_b_l_i); 175 | 176 | /* get cost vector */ 177 | _v_t p_costs = 178 | v_init(); 179 | 180 | p_costs = pcosts->get_pairwise_costs( 181 | iv_init(n_a_l), 182 | iv_init(n_b_l)); 183 | 184 | /* multiply with edge weight */ 185 | p_costs = v_mult(p_costs, 186 | v_init(e_weight)); 187 | 188 | 189 | /* extract first element of vector */ 190 | v_store(p_costs, tmp); 191 | 192 | my_chunk += tmp[0]; 193 | } 194 | 195 | return my_chunk; 196 | }, 197 | std::plus()); 198 | 199 | return objective; 200 | } 201 | 202 | /* ************************************************************************** */ 203 | 204 | template 205 | bool 206 | TreeOptimizer:: 207 | data_complete() 208 | { 209 | return (m_has_graph && m_has_tree && m_has_label_set && m_has_costs); 210 | } 211 | 212 | NS_MAPMAP_END 213 | --------------------------------------------------------------------------------