dthuerck / mapmap_cpu

A high-performance general-purpose MRF MAP solver, heavily exploiting SIMD instructions.
BSD 3-Clause "New" or "Revised" License
101 stars 51 forks source link

<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. #16

Open KeoChi opened 5 years ago

KeoChi commented 5 years ago

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!

h00shi commented 5 years ago

Can you post a minimal working example maybe?

dthuerck commented 5 years ago

Hi,

thanks, I'll look into it. In the meantime, can you scan opencv2.hpp for typedefs? Are they typedef'ing stuff that I do, such as luint_t, for example?

KeoChi commented 5 years ago

I am sorry to reply so late. There are not any typedefs in opencv. In addition, I use opencv3.4 to instead of opencv3.2, and the calculation is normal.

dthuerck commented 5 years ago

Are linking any other libraries as well? Just by including opencv.hpp, the mapmap_demo build process fails:

/tmp/ccAPiZJb.ltrans4.ltrans.o: In function `cvflann::anyimpl::big_any_policy<cv::String>::static_delete(void**)':
<artificial>:(.text+0xfe5): undefined reference to `cv::String::deallocate()'
/tmp/ccAPiZJb.ltrans4.ltrans.o: In function `cvflann::anyimpl::big_any_policy<cv::String>::move(void* const*, void**)':
<artificial>:(.text+0x1010): undefined reference to `cv::String::deallocate()'
<artificial>:(.text+0x1024): undefined reference to `cv::String::deallocate()'
collect2: error: ld returned 1 exit status
CMakeFiles/mapmap_demo.dir/build.make:97: recipe for target 'mapmap_demo' failed
make[2]: *** [mapmap_demo] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/mapmap_demo.dir/all' failed
make[1]: *** [CMakeFiles/mapmap_demo.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

So I'm guessing there might be other problems involved than just a header file?

KeoChi commented 5 years ago

I don't link other libraries. And I have not tested the mapmap_demo. I use directly the open source code mvs-texturing.