Git Product home page Git Product logo

mapmap_cpu's Introduction

mapMAP MRF MAP Solver Build Status tipi.build

Overview

CPU-implementation of out massively-parallel, generic, MRF MAP solver named mapMAP posing minimal assumptions to the input, allowing rapid solution of a large class of MRF problems.

mapMAP's algorithmic foundation and parallelization concept has been presented at High Performance Graphics 2016 in Dublin, Ireland. For a reprint and further information, please refer to our project page (see below).

Currently, this code implements the following modules and features:

  • Customizable (parallel) performance
    • Change cost type between float and double
    • Templated SIMD width (1, 4, 8 for float; 1, 2, 4 for double)
    • Automatically setting SIMD width at compile time
    • Supports SSE4/AVX/AVX2, autodetected during build
    • Automatically using linear-time optimization for certain submodular cost functions
    • Novel linear-time optimization for certain supermodular cost functions
    • Two algorithms for parallel tree sampling
  • Extensible interfaces for all components, providing user hooks
    • Cost functions (unary and pairwise)
    • Termination criteria
    • Node grouping criteria for the multilevel module
    • Choice of two (parallel) coordinate selection algorithms
    • Use of heuristics, thereby modifying the solver's structure.
    • User hooks for logging intermediate results.
  • Solver modules
    • Acyclic (BCD) descent
    • Spanning tree descent
    • Multilevel solving
  • Finding and exploiting connected components in the topology
  • Test suite for each individual module

What it lacks:

  • Capability to process label costs as outlined in the paper

For the license and terms of usage, please see "License, Terms of usage & Reference".

In addition to a "classical", CMake-based workflow, the great folks at tipi.build contributed (optional) support for their C++ build and dependency manager. With tipi, building mapmap or using it as a library in your own projects just happens by a snap of your finger.

Prerequisites

The code has been tested (and compiles without issues) on an Ubuntu 16.04 system with an AVX2-compliant Intel CPU using gcc/g++ 9.3.0 and Intel OneTBB (2021.5.0). The latter is licensed under the 3BSD-compatible Apache 2.0 licence (see ASF legal FAQ). Please make sure to use an C++11-comptabile compiler and activate the necessary options. If you are a Ubuntu user, please click on APT on the OneTBB page linked above. Google Test will automatically be downloaded and built.

The provided FindTBB.cmake is taken from justusc and licensed under the MIT license.

Quickstart

The following instructions are provided for linux; the Windows workflow should be somewhat similar, though GUI-based.

The classical way

Step-by-step instructions:

  1. git clone https://github.com/dthuerck/mapmap_cpu
  2. cd mapmap_cpu && mkdir build && cd build && cmake ..
  3. ccmake . and configure the following options (if you want to...):
  • CMAKE_C_COMPILER - command for your C-compiler, e.g. gcc-5
  • CMAKE_CXX_COMPILER - command for your C++-compiler, e.g. g++-5
  • TBB_DIR - path containing TBBConfig.cmake
  • BUILD_MEMSAVE - determines if the dynamic programming should allocate memory as needed (ON), saving memory but causing slightly longer execution times or preallocate the whole table (OFF)
  • BUILD_DEMO - decides whether the demo from the wiki is built as mapmap_demo
  • BUILD_TEST - decides whether the test suite is built as mapmap_test
  1. Configure and generate the Makefile (press c and g from ccmake).
  2. Build the project using make (or make -j for parallel build).
  3. Depending on your configuration, you can now run mapmap_test and/or mapmap_demo (assuming you activated BUILD_TEST and BUILD_DEMO).

Using tipi.build

All prerequisites are provided by tipi.build and the .tipi/deps file, to compile this project simply run :

tipi . -t <platform>

Where platform is either one of linux, windows, macos or any of the supported environments.

Using mapMAP as a library in your own projects

The classical way

mapMAP is implemented as a templated, header only library. A simple

#include "mapmap/full.h"

will do the trick. Remember that in order to work you need to compile your whole project with C++11 support. All functions and classes are organized in the namespace mapmap.

For the users of GCC, we recommend the following options for the best performance:

-std=c++11 -Wall -march=native -O2 -flto -mfpmath=sse -funroll-loops

As a good starting point, we recommend studying mapmap_demo.cc closely, which is mostly self-explanatory.

Using tipi.build

mapMAP can be easily used with the tipi.build dependency manager, by adding the following to a .tipi/deps:

{
    "dthuerck/mapmap_cpu": { }
}

Documentation

For extended documentation on building, using and extending mapMAP, please see the integrated wiki.


An example to start with is available in [example-mapmap_cpu](https://github.com/tipi-deps/example-mapmap_cpu) (change the target name appropriately to `linux` or `macos` or `windows`):

```bash
tipi . -t <target>

License, Terms of Usage & Reference

Our program is licensed under the liberal BSD 3-Clause license included as LICENSE.txt file.

If you decide to use our code or code based on this project in your application, please make sure to cite our HPG 2016 paper:

@inproceedings{Thuerck2016MRF,
    title = {A Fast, Massively Parallel Solver for Large, Irregular Pairwise {M}arkov Random Fields},
    author = {Thuerck, Daniel and Waechter, Michael and Widmer, Sven and von Buelow, Max and Seemann, Patrick and Pfetsch, Marc E. and Goesele, Michael},
    booktitle = {Proceedings of High Performance Graphics 2016},
    year = {2016},
}

A PDF reprint is available here: PDF reprint and PDF Supplementary Material.

Contact

For any trouble with building, using or extending this software, please use the project's integrated issue tracker. We'll be happy to help you there or discuss feature requests.

Change Log

Compared with the development version from our HPG paper (cf. below).

  • v1.5 (6/25/2018):
    • Added tech report for new tree selection algorithm (from v1.2) in doc/.
    • Added novel envelopes for supermodular cost function types ("Antipotts", "LinearPeak"). A tech report may follow.
    • Several bugfixes.
  • v1.4 (1/10/2018):
    • Deterministic solver path with user-provided seed.
    • Several bugfixes and smaller improvements.
  • v1.3 (10/18/2017):
    • Envelope optimization for Potts, TruncatedLinear, TruncatedQuadratic.
    • Ability to have individual cost functions per edge.
    • Removed UNARY/PAIRWISE template parameters from solver, hiding these internally.
    • Improved multilevel performance, even in the case of individual costs.
    • Added GTest for automatic built instead of a hard dependency.
  • v1.2 (5/29/2017):
    • Introduced a new, multicoloring-based tree selection algorithm - lock-free.
  • v1.1 (4/12/2017):
    • Tuned the tree growing implementation for early termination and
    • option for relaxing the maximality requirement.
  • v1.0 (2/8/2017):
    • Stable release.
    • Logging callbacks for use as library.
    • Clean, documented interface and documentation.
    • Added a demo for correct usage.
  • beta (12/6/2016):
    • Initial release, mirrors functionality outlined in the paper.
    • Automated vectorization (compile-time detection) for float/double.
    • Supporting scalar/SSE2-4/AVX/AVX2.
    • Added cost function instances.
    • Added unit tests.

mapmap_cpu's People

Contributors

daminetreg avatar dthuerck avatar krahenbuhl avatar maxvonbuelow avatar meekersx avatar mitjap avatar namibj avatar nmoehrle avatar oleg-alexandrov avatar xubury avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mapmap_cpu's Issues

Illegal instruction crashes on mac

I was debugging the same issue as #13, but noticed the problem persisted if I used non-apple clang. As I was building, I noticed several warnings that look like:

delete called on 'mapmap::MultilevelCriterion<float, 8>' that is abstract but has non-virtual
      destructor

By making those destructors all virtual, the crash went away. The changes were:

diff --git a/mapmap/header/multilevel.h b/mapmap/header/multilevel.h
index 5914956..24db754 100755
--- a/mapmap/header/multilevel.h
+++ b/mapmap/header/multilevel.h
@@ -52,7 +52,7 @@ template<typename COSTTYPE, uint_t SIMDWIDTH>
 class MultilevelCriterion
 {
 public:
-    ~MultilevelCriterion() {}
+    virtual ~MultilevelCriterion() {}
 
     virtual void group_nodes(std::vector<luint_t>& node_in_group,
         const LevelSet<COSTTYPE, SIMDWIDTH> * current_level,
diff --git a/mapmap/header/optimizer_instances/dp_node_solver.h b/mapmap/header/optimizer_instances/dp_node_solver.h
index 1deb1cd..9d1c888 100644
--- a/mapmap/header/optimizer_instances/dp_node_solver.h
+++ b/mapmap/header/optimizer_instances/dp_node_solver.h
@@ -20,7 +20,7 @@ template<typename COSTTYPE, uint_t SIMDWIDTH>
 class DPNodeSolver
 {
 public:
-    ~DPNodeSolver() {};
+    virtual ~DPNodeSolver() {};
 
     virtual void optimize_node() = 0;
     virtual luint_t scratch_bytes_needed() = 0;
@@ -111,4 +111,4 @@ NS_MAPMAP_END
 /* include function implementations */
 #include "source/optimizer_instances/dp_node_solver.impl.h"
 
-#endif /* __MAPMAP_HEADER_DP_NODE_SOLVER_H_ */
\ No newline at end of file
+#endif /* __MAPMAP_HEADER_DP_NODE_SOLVER_H_ */
diff --git a/mapmap/header/termination_criterion.h b/mapmap/header/termination_criterion.h
index 840a244..de0a949 100755
--- a/mapmap/header/termination_criterion.h
+++ b/mapmap/header/termination_criterion.h
@@ -55,7 +55,7 @@ class TerminationCriterion
 {
 public:
     TerminationCriterion();
-    ~TerminationCriterion();
+    virtual ~TerminationCriterion();
 
     virtual bool check_termination(const SolverHistory<COSTTYPE,
         SIMDWIDTH> * history) = 0;

Theoretical Questions about Unary and Pairwise Costs

Hello, Daniel.
I have got to know about mapmap_cpu from two mesh-texturing papers: specifically, MVSTexturing (https://github.com/nmoehrle/mvs-texturing) and Seamless Texturing (https://github.com/fdp0525/SeamlessTex).
The usage of "mapmap_cpu" is to select the most optimal image to texture each and every possible faces of a mesh through MRF processes. I am still learning about MRF so I am here to ask if you can help me guide my thought processes and correct myself.

I get the intuitions behind setting unaries costs. Let us assume that the criterion to select the most optimal image for texturing for each face, is its clarity (<--> blurry). Then for a unary cost table, set a low cost for this pair of face and image in order to lead the selection of an image with low cost (clearest) for that specific face. At the same time, set a high value to a blurry image or even infinite for an image onto which this face is not projected.

For the pairwise costs, I see that many papers for texturing use "potts" or "orgPotts" model and I understood it being a method that penalize when two faces, that are neighboring, are labeled differently (for the texturing context, it would be, texturing two neighboring faces with different images, causing undesired seams).

So this is so far all background infos. I am wondering if my intuition is correct. Using a method like superpixels (https://www.epfl.ch/labs/ivrl/research/slic-superpixels/) that are "segmentation" methods, I set a low pairwise costs (I think "high" and "low" might be a bit ambiguous. For me, setting low costs mean, I want this choice to be eventually selected by the MRF optimization processes) for two neighboring faces ONLY when they land on same segmented areas for a certain image. Unlike Potts model that sets a constant penality for any neighboring faces that are projected onto a same image, I only penalize them by setting low pairwise costs when 1) two faces are neighboring 2) they are projected onto the same image 3) they land on the same segmented regions. So Criterion #3 is an additional consideration.

The reason behind this setup is to enforce assignments of a same image to faces that belong to the same group of segmented region I do not want to penalize if other neighboring faces belong to different segmented region.

I am self-teaching myself right now so I would appreciate any possible inputs from anyone!
Thank you!

crashed at runtime when linked to tbb 2018_U5

hi, Daniel
I'm not sure if this is the right place to open this issue. forgive me if wrong.
I have tried to compile in xcode 9.4 mvs-texturing which depends on master branch of mapmap_cpu , but mvs-texturing's demo app(namely texrecon) crashed at runtime. The call trace show that it crashes at mapmap's DynamicProgramming Solver, like this:(each time it crashes at line 99)
image
It crashes when DynamicProgrammingTableEntry<COSTTYPE, SIMDWIDTH>::optimize_entry() is ready to return, releasing the local variable named solver which is an unique_ptr instance.
The wierd thing is: when i switch to xcode 9.2 and compile and run it, it turns out everything is fine.
Do you figure out why did that crash happen?

Customizing pairwise costs

Hello, thank you for the great library!

I want to implement a custom pairwise cost functor, which takes labels and maps the labels to something else to calculate the costs. For example, if the labels are indices of some set of n-dimensional points, I want to define the pairwise costs as the distance between the points which the labels point to. Is this possible?

I have tried implementing a class derived from mapmap::PairwiseCosts, and override the get_pairwise_costs method. When I try to output the labels vector in get_pairwise_costs, sometimes it outputs undefined values (i.e. not labels). Could you please give some instructions on how to define custom pairwise costs? I would be very appreciated.

Setting Pairwise costs table from a std::vector fails

When trying to set pairwise costs table from a std::vector as opposed to an array, the call fails. The problem is on this line: https://github.com/dthuerck/mapmap_cpu/blob/master/mapmap/source/cost_instances/pairwise_table.impl.h#L100

With the very last l_a, the expression (li_a + 1) * len_b indexes beyond the end of the vector, and taking a pointer to that is an illegal operation.

A fix would be either passing iterators instead of pointers to std::copy (i.e. packed_table.begin()+(li_a * len_b)) or taking the data pointer of the vector and then using pointer arithmetic on that (i.e. packed_table.data()+(li_a * len_b)).

Compile error: internal compiler error: Segmentation fault

When I include mapmap into my project, it report internal compiler error: Segmentation fault.
The detail error information:
"
In file included from /usr/local/include/opencv2/core.hpp:3281:0,
from /usr/local/include/opencv2/opencv.hpp:52,
from /mnt/dev/myproject/src/test_mapmap.h:11,
from /mnt/dev/myproject/src/test_mapmap.cc:13:
/usr/local/include/opencv2/core/utility.hpp: In instantiation of 'class cv::TLSDatacv::instr::NodeDataTls':
/usr/local/include/opencv2/core/utility.hpp:1247:26: required from here
/usr/local/include/opencv2/core/utility.hpp:764:17: internal compiler error: Segmentation fault

    inline void gather(std::vector<T*> &data) const
             ^

Please submit a full bug report,
with preprocessed source if appropriate.
See file:///usr/share/doc/gcc-5/README.Bugs for instructions.
"
While the error missing when I comment the reference to mapmap.
I try to change the opencv version to 4.1, unfortunately it report the same error!

The gcc version:
gcc (Ubuntu 5.5.0-12ubuntu1) 5.5.0 20171010
opencv: 3.4.0

Looking forward to your reply!

<opencv2/opencv.hpp> can influence the optimize( std::vector<_iv_st<COSTTYPE, SIMDWIDTH>>& solution,const mapMAP_control& control_flow) in mapmap/source/mapmap.impl.h.

Hello! I use the open source code mvs-texturing, and it can use this code mapmap_cpu. I found a very strange question! I only add #include <opencv2/opencv.hpp> in texrecon.cpp, and I haven't used any functions about opencv yet. It would influence the result of solver.optimize(solution, ctr) in "view_selection.cpp". I found it can call optimize( std::vector<_iv_st<COSTTYPE, SIMDWIDTH>>& solution,const mapMAP_control& control_flow) in mapmap/source/mapmap.impl.h. And I add a print log message. Like this:

template<typename COSTTYPE, uint_t SIMDWIDTH>
FORCEINLINE
_s_t<COSTTYPE, SIMDWIDTH>
mapMAP<COSTTYPE, SIMDWIDTH>::
optimize(
    std::vector<_iv_st<COSTTYPE, SIMDWIDTH>>& solution,
    const mapMAP_control& control_flow)
throw()
{
    _s_t<COSTTYPE, SIMDWIDTH> obj;


    /* copy some options from control structure */
    m_tree_sampler_algo = control_flow.tree_algorithm;
    m_sample_deterministic = control_flow.sample_deterministic;

    /* initialize seed generator */
    m_seeder.seed(control_flow.initial_seed);

    /* create std modules for uninitialized fields */
    create_std_modules();

    /* check inputs for completeness and various sanity checks */
    if(!check_data_complete())
        throw std::runtime_error("Input data for optimization "
            "incomplete or not sane.");

    /* report on starting the optimization process */
    if(!m_use_callback)
        std::cout << "[mapMAP] "
                << UNIX_COLOR_GREEN
                << "Starting optimization..."
                << UNIX_COLOR_RESET
                << std::endl;

    /* start timer */
    m_time_start = std::chrono::system_clock::now();

    /* initialize current solution */
    const luint_t num_nodes = m_graph->num_nodes();
    m_solution.resize(num_nodes);
    std::fill(m_solution.begin(), m_solution.end(), 0);

    /* find initial solution by tree-optimization w/o dependencies */
    m_objective = initial_labelling();
    record_time_from_start();
    std::cout << "first print" << std::endl;
    print_status();

    /* check for termination */
    if(check_termination())
    {
        solution.assign(m_solution.begin(), m_solution.end());

        return m_objective;
    }

    /* rapid initial descent by multilevel */
    if(control_flow.use_multilevel)
    {
        m_objective = opt_step_multilevel();
        record_time_from_start();
        std::cout << "second print" << std::endl;
        print_status();
    }

    /* take spanning tree steps until no more improvements occur */
    luint_t sp_it = 0;

    _s_t<COSTTYPE, SIMDWIDTH> old_objective = m_objective;
    while(control_flow.use_spanning_tree)
    {
        ++sp_it;
        std::cout << "control_flow.use_spanning_tree: " << control_flow.use_spanning_tree << std::endl;
        /* check if algorithm needs to terminate this mode */
        if(check_termination())
            break;
        std::cout << "check_termin" << std::endl;
        /* execute spanning tree step */
        obj = opt_step_spanning_tree();
        record_time_from_start();
        std::cout << "old_objective: " << old_objective << std::endl;
        std::cout << "obj: " << obj << std::endl;
        if(obj < old_objective)
            old_objective = obj;
        else
            break;
        std::cout << "third print" << std::endl;
        print_status();

        if(control_flow.use_multilevel && sp_it %
            control_flow.spanning_tree_multilevel_after_n_iterations == 0)
        {
            m_objective = opt_step_multilevel();
            record_time_from_start();
            std::cout << "forth print" << std::endl;
            print_status();
        }
    }

    /* lastly, execute (forced) acyclic steps until termination */
    luint_t ac_it = 0;
    while(control_flow.use_acyclic &&
        (!check_termination() || (control_flow.force_acyclic &&
        ac_it < control_flow.min_acyclic_iterations)))
    {
        ++ac_it;

        m_objective = opt_step_acyclic(control_flow.relax_acyclic_maximal);

        record_time_from_start();
        std::cout << "fifth print" << std::endl;
        print_status();
    }

    /* output solution */
    solution.assign(m_solution.begin(), m_solution.end());

    /* report on starting the optimization process */
    if(!m_use_callback)
        std::cout << "[mapMAP] "
                << UNIX_COLOR_GREEN
                << "Finished optimization."
                << UNIX_COLOR_RESET
                << std::endl;

    return m_objective;
}

When I don't add #include <opencv2/opencv.hpp> , result of texturing is good. Like this:
texture1
And the log message:

m_num_nodes: 198131
	Optimizing:
		Time[s]	Energy
first print
		0	175136
second print
		0	173408
control_flow.use_spanning_tree: 1
check_termin
old_objective: 173408
obj: 171636
third print
		0	171636
control_flow.use_spanning_tree: 1
check_termin
old_objective: 171636
obj: 170673
third print
		0	170672
control_flow.use_spanning_tree: 1
check_termin
old_objective: 170673
obj: 170211
third print
		1	170211
control_flow.use_spanning_tree: 1
check_termin
old_objective: 170211
obj: 169933
third print
		1	169932
control_flow.use_spanning_tree: 1
check_termin
old_objective: 169933
obj: 169738
third print
		1	169737
forth print
		1	169678
control_flow.use_spanning_tree: 1
check_termin
old_objective: 169738
obj: 169586
third print
		1	169586
control_flow.use_spanning_tree: 1
fifth print
		2	169527
fifth print
		2	169480
fifth print
		2	169435
fifth print
		2	169401
fifth print
		2	169367
	6008 faces have not been seen

When I add #include <opencv2/opencv.hpp> , result of texturing is bad. Like this:
texture2
The log message:

m_num_nodes: 198131
	Optimizing:
		Time[s]	Energy
first print
		0	163685
second print
		0	163685
control_flow.use_spanning_tree: 1
check_termin
old_objective: 163686
obj: 163668
third print
		0	163668
control_flow.use_spanning_tree: 1
check_termin
old_objective: 163668
obj: 163661
third print
		0	163660
control_flow.use_spanning_tree: 1
check_termin
old_objective: 163661
obj: 163671
fifth print
		1	163670
fifth print
		1	163670
fifth print
		1	163670
fifth print
		1	163670
fifth print
		1	163670
	6008 faces have not been seen

Comparison of the two log information, I found that it reduce the number of optimization iterations when add #include <opencv2/opencv.hpp>, and it doesn't jump into

if(control_flow.use_multilevel && sp_it %
            control_flow.spanning_tree_multilevel_after_n_iterations == 0)
        {
            m_objective = opt_step_multilevel();
            record_time_from_start();
            std::cout << "forth print" << std::endl;
            print_status();
        }

I don't know why the head file <opencv2/opencv.hpp> can influence the optimize( std::vector<_iv_st<COSTTYPE, SIMDWIDTH>>& solution,const mapMAP_control& control_flow) in mapmap/source/mapmap.impl.h. Can you explain the reason? Thank you!

crash when used as face-view labeling

I tried to use it as demonstrated in mvs_texturing, but for some meshes it crashes:

image

I can send the mesh, but I do not see an easy way to dump the mapmap problem to a file to send you the problem.

why only set pairwise once?

/* cost types /
using unary_t = UnaryTable<cost_t, simd_w>;
using pairwise_t = PairwiseTruncatedLinear<cost_t, simd_w>;
.......
/
construct pairwise costs */
pairwise = std::unique_ptr<pairwise_t>(new pairwise_t({1.0, 2.0}));
.....

for(luint_t n = 0; n < num_nodes; ++n)
mapmap.set_unary(n, unaries[n].get());
mapmap.set_pairwise(pairwise.get());

why only set pairwise once? what dose "new pairwise_t({1.0, 2.0})" mean ?

Look forward to your reply. Thanks!

how to use it with tbb?

hi,
i want to know how can i use it with tbb and where should i add the path of tbb.i tryed many time but appear the same error.
thank you very much if you can answer me.

Variable length array causes issues when compiling with MSVC

Hi,

In the file mapmap_cpu/mapmap/source/tree_sampler_instances/lock_free_tree_sampler.impl.h line 475 a variable length array has been defined:
luint_t buf[m_buf_edges];
This is fine when compiling with gcc, but on MSVC it seems to cause compilation errors.

Maybe changing const luint_t m_buf_edges = 4; to static constexpr luint_t m_buf_edges = 4; in lock_free_tree_sampler.h can help.

Thanks

Invalid write

There is an invalid write in multilevel.impl.h:819.

The vector costs has only size num_labels * num_labels_chunk but is addressed at i * num_labels + j where both i and j are in [0, num_labels_chunk).

==24050== Invalid write of size 8
==24050==    at 0x4BFDF0: _mm_storeu_ps (xmmintrin.h:980)
==24050==    by 0x4BFDF0: v_store<float, 4u> (vector_math.impl.h:851)
==24050==    by 0x4BFDF0: compute_level_pairwise (multilevel.impl.h:819)
==24050==    by 0x4BFDF0: next_level (multilevel.impl.h:211)
==24050==    by 0x4BFDF0: opt_step_multilevel (mapmap.impl.h:527)
==24050==    by 0x4BFDF0: optimize (mapmap.impl.h:260)
==24050==    by 0x4BFDF0: tex::view_selection(SparseTable<unsigned int, unsigned short, float> const&, UniGraph*, tex::Settings const&) (view_selection.cpp:90)
==24050==    by 0x457C5B: main (texrecon.cpp:98)

FORCEINLINE macro is not clang compatible

I think the FORCEINLINE macro is not clang compatible, while it appears to work with gcc I think the proper way to specify the always inline is __attribute__((always_inline)) instead of __always_inline. Further I think that it should be decided based on the compiler rather than the operating system which macro to use.

So I would suggest something like mentioned here:

#ifdef __MSVC__
#define FORCEDINLINE __forceinline
#else
#define FORCEDINLINE __attribute__((always_inline))
#endif

I think this the cause for nmoehrle/mvs-texturing#98.

SSE2

Maybe more of a question
I get this error when compile opendronemap 0.7.0
SuperBuild/src/mvstexturing/elibs/mapmap/mapmap/source/vector_math.impl.h:1057:33: error: ‘_mm_extract_epi64’ was not declared in this scope
a1.i = _mm_extract_epi64(aa, 0);

os system is
Ubuntu 16.04 LTS 32-bit
memmory 7,8 GiB
processor Intel(R) Core(TM) i7-2670QM CPU @ 2.20GHz
Grapic Intel® Sandybridge Mobile x86/MMX/SSE2

maybe mapmap not supports this configuration?

How can I change the weight of unary costs and pairwise costs?

Sorry, it is my mistake. I Failed to add edge to mapsolver, so the pairwise didn't work.

================================================================
Hi,

I want to have a more continuous labels' result, so I think I should increase the weight of pairwise costs (smooth term in energy function) to weaken the impact of unary costs (data term in energy function).

However, I tried to change parameter of 'PairwisePotts' or the costs set to unaries, but both them didn't work.

Even I set the pairwise to be 0, the results were binary same.
Does the pairwise really work?

I wonder how can I adjust the weights.

Possible memory leak in pairwise_table.impl.h

Hi,

In my application I have been running your solver multiple times in a single run, and I noticed a large memory build up. I also use the PairwiseTable object for assigning binary costs. Running the code in valgrind, I got the following warning.

==9218== Mismatched free() / delete / delete []
==9218==    at 0x4C2F24B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9218==    by 0x8FEC2F: std::default_delete<double>::operator()(double*) const (unique_ptr.h:76)
==9218==    by 0x8F7428: std::unique_ptr<double, std::default_delete<double> >::~unique_ptr() (unique_ptr.h:236)
==9218==    by 0x8EE71F: ~PairwiseTable (pairwise_table.impl.h:81)
==9218==    by 0x8EE71F: mapmap::PairwiseTable<double, 1u>::~PairwiseTable() (pairwise_table.impl.h:81)
==9218==    by 0x915285: std::default_delete<mapmap::PairwiseCosts<double, 1u> >::operator()(mapmap::PairwiseCosts<double, 1u>*) const (unique_ptr.h:76)
==9218==    by 0x90D4E8: std::unique_ptr<mapmap::PairwiseCosts<double, 1u>, std::default_delete<mapmap::PairwiseCosts<double, 1u> > >::~unique_ptr() (unique_ptr.h:236)
==9218==    by 0x91BFBA: void std::_Destroy<std::unique_ptr<mapmap::PairwiseCosts<double, 1u>, std::default_delete<mapmap::PairwiseCosts<double, 1u> > > >(std::unique_ptr<mapmap::PairwiseCosts<double, 1u>, std::default_delete<mapmap::PairwiseCosts<double, 1u> > >*) (stl_construct.h:93)
==9218==    by 0x9169AE: void std::_Destroy_aux<false>::__destroy<std::unique_ptr<mapmap::PairwiseCosts<double, 1u>, std::default_delete<mapmap::PairwiseCosts<double, 1u> > >*>(std::unique_ptr<mapmap::PairwiseCosts<double, 1u>, std::default_delete<mapmap::PairwiseCosts<double, 1u> > >*, std::unique_ptr<mapmap::PairwiseCosts<double, 1u>, std::default_delete<mapmap::PairwiseCosts<double, 1u> > >*) (stl_construct.h:103)
==9218==    by 0x90FAEB: void std::_Destroy<std::unique_ptr<mapmap::PairwiseCosts<double, 1u>, std::default_delete<mapmap::PairwiseCosts<double, 1u> > >*>(std::unique_ptr<mapmap::PairwiseCosts<double, 1u>, std::default_delete<mapmap::PairwiseCosts<double, 1u> > >*, std::unique_ptr<mapmap::PairwiseCosts<double, 1u>, std::default_delete<mapmap::PairwiseCosts<double, 1u> > >*) (stl_construct.h:126)
==9218==    by 0x9097D6: void std::_Destroy<std::unique_ptr<mapmap::PairwiseCosts<double, 1u>, std::default_delete<mapmap::PairwiseCosts<double, 1u> > >*, std::unique_ptr<mapmap::PairwiseCosts<double, 1u>, std::default_delete<mapmap::PairwiseCosts<double, 1u> > > >(std::unique_ptr<mapmap::PairwiseCosts<double, 1u>, std::default_delete<mapmap::PairwiseCosts<double, 1u> > >*, std::unique_ptr<mapmap::PairwiseCosts<double, 1u>, std::default_delete<mapmap::PairwiseCosts<double, 1u> > >*, std::allocator<std::unique_ptr<mapmap::PairwiseCosts<double, 1u>, std::default_delete<mapmap::PairwiseCosts<double, 1u> > > >&) (stl_construct.h:151)
==9218==    by 0x8FF784: std::vector<std::unique_ptr<mapmap::PairwiseCosts<double, 1u>, std::default_delete<mapmap::PairwiseCosts<double, 1u> > >, std::allocator<std::unique_ptr<mapmap::PairwiseCosts<double, 1u>, std::default_delete<mapmap::PairwiseCosts<double, 1u> > > > >::~vector() (stl_vector.h:424)
==9218==    by 0x8F792F: ~Multilevel (multilevel.impl.h:99)
==9218==    by 0x8F792F: std::default_delete<mapmap::Multilevel<double, 1u> >::operator()(mapmap::Multilevel<double, 1u>*) const (unique_ptr.h:76)

==9218==  Address 0x88ff640 is 0 bytes inside a block of size 288 alloc'd
==9218==    at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9218==    by 0x90539F: PairwiseTable (pairwise_table.impl.h:33)
==9218==    by 0x90539F: mapmap::Multilevel<double, 1u>::compute_level_pairwise()::{lambda(tbb::blocked_range<unsigned long> const&)#1}::operator()(tbb::blocked_range<unsigned long> const&) const (multilevel.impl.h:898)
==9218==    by 0x9479A6: tbb::interface9::internal::start_for<tbb::blocked_range<unsigned long>, mapmap::Multilevel<double, 1u>::compute_level_pairwise()::{lambda(tbb::blocked_range<unsigned long> const&)#1}, tbb::auto_partitioner const>::run_body(tbb::blocked_range<unsigned long>&) (parallel_for.h:102)
==9218==    by 0x94187B: void tbb::interface9::internal::balancing_partition_type<tbb::interface9::internal::adaptive_mode<tbb::interface9::internal::auto_partition_type> >::work_balance<tbb::interface9::internal::start_for<tbb::blocked_range<unsigned long>, mapmap::Multilevel<double, 1u>::compute_level_pairwise()::{lambda(tbb::blocked_range<unsigned long> const&)#1}, tbb::auto_partitioner const>, tbb::blocked_range<unsigned long> >(tbb::interface9::internal::start_for<tbb::blocked_range<unsigned long>, mapmap::Multilevel<double, 1u>::compute_level_pairwise()::{lambda(tbb::blocked_range<unsigned long> const&)#1}, tbb::auto_partitioner const>&, tbb::blocked_range<unsigned long>&) (partitioner.h:446)
==9218==    by 0x9384B7: void tbb::interface9::internal::partition_type_base<tbb::interface9::internal::auto_partition_type>::execute<tbb::interface9::internal::start_for<tbb::blocked_range<unsigned long>, mapmap::Multilevel<double, 1u>::compute_level_pairwise()::{lambda(tbb::blocked_range<unsigned long> const&)#1}, tbb::auto_partitioner const>, tbb::blocked_range<unsigned long> >(tbb::interface9::internal::start_for<tbb::blocked_range<unsigned long>, mapmap::Multilevel<double, 1u>::compute_level_pairwise()::{lambda(tbb::blocked_range<unsigned long> const&)#1}, tbb::auto_partitioner const>&, tbb::blocked_range<unsigned long>&) (partitioner.h:257)
==9218==    by 0x92C8D7: tbb::interface9::internal::start_for<tbb::blocked_range<unsigned long>, mapmap::Multilevel<double, 1u>::compute_level_pairwise()::{lambda(tbb::blocked_range<unsigned long> const&)#1}, tbb::auto_partitioner const>::execute() (parallel_for.h:127)
==9218==    by 0x4E60FDC: tbb::internal::custom_scheduler<tbb::internal::IntelSchedulerTraits>::local_wait_for_all(tbb::task&, tbb::task*) (in /usr/lib/x86_64-linux-gnu/libtbb.so.2)
==9218==    by 0x4E5E1EF: tbb::internal::generic_scheduler::local_spawn_root_and_wait(tbb::task&, tbb::task*&) (in /usr/lib/x86_64-linux-gnu/libtbb.so.2)
==9218==    by 0x8DFBFA: tbb::task::spawn_root_and_wait(tbb::task&) (task.h:736)
==9218==    by 0x9153E4: tbb::interface9::internal::start_for<tbb::blocked_range<unsigned long>, mapmap::Multilevel<double, 1u>::compute_level_pairwise()::{lambda(tbb::blocked_range<unsigned long> const&)#1}, tbb::auto_partitioner const>::run(tbb::blocked_range<unsigned long> const&, {lambda(tbb::blocked_range<unsigned long> const&)#1} const&, tbb::auto_partitioner&) (parallel_for.h:90)
==9218==    by 0x90D79E: void tbb::parallel_for<tbb::blocked_range<unsigned long>, mapmap::Multilevel<double, 1u>::compute_level_pairwise()::{lambda(tbb::blocked_range<unsigned long> const&)#1}>(tbb::blocked_range<unsigned long> const&, mapmap::Multilevel<double, 1u>::compute_level_pairwise()::{lambda(tbb::blocked_range<unsigned long> const&)#1} const&) (parallel_for.h:186)
==9218==    by 0x8D48D3: compute_level_pairwise (multilevel.impl.h:860)
==9218==    by 0x8D48D3: next_level (multilevel.impl.h:214)
==9218==    by 0x8D48D3: opt_step_multilevel (mapmap.impl.h:645)
==9218==    by 0x8D48D3: optimize (mapmap.impl.h:359)
==9218==    by 0x8D48D3: DGP::mrf::MRF_solver_mapmap::solve(std::vector<int, std::allocator<int> >&, double&) (mrf_solvers.cxx:496)

My guess is that the issue is the following. It seems that in pairwisetable.impl.h in line 34 a dynamic array is created via new[], which needs to be deleted via delete[]. However, the resutls are saved in a std::unique_ptr:

m_packed_table_storage = std::unique_ptr<_s_t<COSTTYPE, SIMDWIDTH>>(new
        _s_t<COSTTYPE, SIMDWIDTH>[padded_size]);

std::unique_ptr, on the other hand, will call delete rather than delete[], which causes this memory leak.

Is arm linux supported?

I have test the demo under ubuntu x64, but I don't have a arm linux system right now, so I was wondering, is this system also work under arm linux?

hope to receive you advice.

MSVC debug mode assertion in void PairwiseTable<COSTTYPE, SIMDWIDTH>:: set_costs

Hi folks:

I'm trying to get this working in debug mode on MSVC 2017. Inside of void
PairwiseTable<COSTTYPE, SIMDWIDTH>::set_costs(), an assert is being triggered in debug mode claiming an out of bounds operation from these lines here:

/* expand table into aligned storage */
for(_iv_st<COSTTYPE, SIMDWIDTH> li_a = 0; li_a < len_a; ++li_a)
    std::copy(&packed_table[li_a * len_b], 
        &packed_table[(li_a + 1) * len_b],
        &m_packed_table[li_a * padded_b]);

in Release mode, or even RelWithDebugInfo, this works fine.

Possible memory leak in TreeSampler

In tree_sample.h at line 27 the destructor is not defined as virtual:
~TreeSampler();

This will prevent the destructors of the child classes, i.e., LockFreeTreeSample and OptimisticTreeSampler, to be called, when they are stored in something such as std::unique_ptr<TreeSampler>. Which I am quite sure that causes memory leaks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.