Author Topic: OMP support for BuildRHS in ResidualBasedEliminationBuilderAndSolver  (Read 946 times)

Ignasi de Pouplana

  • Newbie
  • *
  • Posts: 21
I often use BuildRHS method in ResidualBasedEliminationBuilderAndSolver and I noticed that there was no parallel loop in that method.

I've just modified BuildRHS to give omp support following the same structure as in the Build method, making sure that CalculateReactions also worked properly.

If there is no inconvenience I would like to commit these changes.

Miguel Angel Celigueta

  • Administrator
  • Newbie
  • *****
  • Posts: 38
Re: OMP support for BuildRHS in ResidualBasedEliminationBuilderAndSolver
« Reply #1 on: June 01, 2016, 07:39:36 PM »
Hi Ignasi!
I hope you are doing well!
About this change you propose, you could share the changes here in the forum. I don't know if Pooyan or Riccardo contacted you, but (if not) you could paste the changes you made here for fast approval. I am afraid someone would answer 'you can commit, but it is a change in the core, so I would like to see the code first'.
Best regards,
Miguel Angel

Ignasi de Pouplana

  • Newbie
  • *
  • Posts: 21
Re: OMP support for BuildRHS in ResidualBasedEliminationBuilderAndSolver
« Reply #2 on: June 02, 2016, 06:17:51 AM »
Hi Miguel Angel, I am very well :)

Thanks for removing the warnings I introduced in the BuildRHS. I had not seen them because right now I am working in Windows and I do not know how to make Visual Studio show more warnings... Next time I will compile kratos with Clang in my Mac with the flag -wextra, just in case...

By the way, I copy here the method BuildRHS I modified and the method ParallelAssembleRHS:

Code: [Select]
    void BuildRHS(
        typename TSchemeType::Pointer pScheme,
        ModelPart& r_model_part,
        TSystemVectorType& b)
    {
        KRATOS_TRY

        //Getting the Elements
        ElementsArrayType& pElements = r_model_part.Elements();

        //getting the array of the conditions
        ConditionsArrayType& ConditionsArray = r_model_part.Conditions();

        //resetting to zero the vector of reactions
        TSparseSpace::SetToZero(*(BaseType::mpReactionsVector));

#ifndef _OPENMP

        //contributions to the system
        LocalSystemVectorType RHS_Contribution = LocalSystemVectorType(0);

        //vector containing the localization in the system of the different
        //terms
        Element::EquationIdVectorType EquationId;

        ProcessInfo& CurrentProcessInfo = r_model_part.GetProcessInfo();
       
        // assemble all elements
        for (typename ElementsArrayType::ptr_iterator it = pElements.ptr_begin(); it != pElements.ptr_end(); ++it)
        {
            //calculate elemental Right Hand Side Contribution
            pScheme->Calculate_RHS_Contribution(*it, RHS_Contribution, EquationId, CurrentProcessInfo);

            //assemble the elemental contribution
            AssembleRHS(b, RHS_Contribution, EquationId);
        }

        RHS_Contribution.resize(0, false);

        // assemble all conditions
        for (typename ConditionsArrayType::ptr_iterator it = ConditionsArray.ptr_begin(); it != ConditionsArray.ptr_end(); ++it)
        {
            //calculate elemental contribution
            pScheme->Condition_Calculate_RHS_Contribution(*it, RHS_Contribution, EquationId, CurrentProcessInfo);

            //assemble the elemental contribution
            AssembleRHS(b, RHS_Contribution, EquationId);
        }

#else
        //creating an array of lock variables of the size of the system vector
        unsigned int b_size = b.size();
        std::vector< omp_lock_t > lock_array(b_size);
        for (unsigned int i = 0; i < b_size; i++)
            omp_init_lock(&lock_array[i]);
       
        //creating an array of lock variables of the size of the reactions vector
        unsigned int reactions_size = (*(BaseType::mpReactionsVector)).size();
        std::vector< omp_lock_t > lock_array_reactions(reactions_size);
        for (unsigned int i = 0; i < reactions_size; i++)
            omp_init_lock(&lock_array_reactions[i]);

        //create a partition of the element array
        int number_of_threads = omp_get_max_threads();

        vector<unsigned int> element_partition;
        CreatePartition(number_of_threads, pElements.size(), element_partition);
       
        if( this->GetEchoLevel() > 2 && r_model_part.GetCommunicator().MyPID() == 0)
        {
            KRATOS_WATCH(number_of_threads);
            KRATOS_WATCH(element_partition);
        }

        double start_prod = omp_get_wtime();

        #pragma omp parallel for
        for (int k = 0; k < number_of_threads; k++)
        {
            //contributions to the system
            LocalSystemVectorType RHS_Contribution = LocalSystemVectorType(0);

            //vector containing the localization in the system of the different
            //terms
            Element::EquationIdVectorType EquationId;
            ProcessInfo& CurrentProcessInfo = r_model_part.GetProcessInfo();
            typename ElementsArrayType::ptr_iterator it_begin = pElements.ptr_begin() + element_partition[k];
            typename ElementsArrayType::ptr_iterator it_end = pElements.ptr_begin() + element_partition[k + 1];

            // assemble all elements
            for (typename ElementsArrayType::ptr_iterator it = it_begin; it != it_end; ++it)
            {
                //calculate elemental contribution
                pScheme->Calculate_RHS_Contribution(*it, RHS_Contribution, EquationId, CurrentProcessInfo);

                //assemble the elemental contribution
                ParallelAssembleRHS(b, RHS_Contribution, EquationId, lock_array, lock_array_reactions);
            }
        }

        vector<unsigned int> condition_partition;
        CreatePartition(number_of_threads, ConditionsArray.size(), condition_partition);

        #pragma omp parallel for
        for (int k = 0; k < number_of_threads; k++)
        {
            //contributions to the system
            LocalSystemVectorType RHS_Contribution = LocalSystemVectorType(0);

            Condition::EquationIdVectorType EquationId;

            ProcessInfo& CurrentProcessInfo = r_model_part.GetProcessInfo();

            typename ConditionsArrayType::ptr_iterator it_begin = ConditionsArray.ptr_begin() + condition_partition[k];
            typename ConditionsArrayType::ptr_iterator it_end = ConditionsArray.ptr_begin() + condition_partition[k + 1];

            // assemble all elements
            for (typename ConditionsArrayType::ptr_iterator it = it_begin; it != it_end; ++it)
            {
                //calculate elemental contribution
                pScheme->Condition_Calculate_RHS_Contribution(*it, RHS_Contribution, EquationId, CurrentProcessInfo);

                //assemble the elemental contribution
                ParallelAssembleRHS(b, RHS_Contribution, EquationId, lock_array, lock_array_reactions);
            }
        }

        double stop_prod = omp_get_wtime();
        if (this->GetEchoLevel() > 2 && r_model_part.GetCommunicator().MyPID() == 0)
            std::cout << "time: " << stop_prod - start_prod << std::endl;

        for (unsigned int i = 0; i < b_size; i++)
            omp_destroy_lock(&lock_array[i]);

        for (unsigned int i = 0; i < reactions_size; i++)
            omp_destroy_lock(&lock_array_reactions[i]);
       
        if( this->GetEchoLevel() > 2 && r_model_part.GetCommunicator().MyPID() == 0)
        {
            KRATOS_WATCH("finished parallel building");
        }

#endif

        KRATOS_CATCH("")
    }
Code: [Select]
    void ParallelAssembleRHS(
        TSystemVectorType& b,
        const LocalSystemVectorType& RHS_Contribution,
        Element::EquationIdVectorType& EquationId,
        std::vector< omp_lock_t >& lock_array,
        std::vector< omp_lock_t >& lock_array_reactions
    )
    {   
        unsigned int local_size = RHS_Contribution.size();

        if (BaseType::mCalculateReactionsFlag == false) //if we don't need to calculate reactions
        {
            for (unsigned int i_local = 0; i_local < local_size; i_local++)
            {
                unsigned int i_global = EquationId[i_local];
                if (i_global < BaseType::mEquationSystemSize) //on "free" DOFs
                {
                    omp_set_lock(&lock_array[i_global]);
                   
                    // ASSEMBLING THE SYSTEM VECTOR
                    b[i_global] += RHS_Contribution[i_local];
                   
                    omp_unset_lock(&lock_array[i_global]);
                }
            }
        }
        else   //when the calculation of reactions is needed
        {
            TSystemVectorType& ReactionsVector = *BaseType::mpReactionsVector;
            for (unsigned int i_local = 0; i_local < local_size; i_local++)
            {
                unsigned int i_global = EquationId[i_local];
                if (i_global < BaseType::mEquationSystemSize) //on "free" DOFs
                {
                    omp_set_lock(&lock_array[i_global]);
                   
                    // ASSEMBLING THE SYSTEM VECTOR
                    b[i_global] += RHS_Contribution[i_local];
                   
                    omp_unset_lock(&lock_array[i_global]);
                }
                else   //on "fixed" DOFs
                {
                    omp_set_lock(&lock_array_reactions[i_global - BaseType::mEquationSystemSize]);
                   
                    // Assembling the Vector of REACTIONS
                    ReactionsVector[i_global - BaseType::mEquationSystemSize] -= RHS_Contribution[i_local];
                   
                    omp_unset_lock(&lock_array_reactions[i_global - BaseType::mEquationSystemSize]);
                }
            }
        }
       
    }

ParallelAssembleRHS is inside #ifdef _OPENMP, just after Assemble.

Regards,

Ignasi

riccardo

  • Global Moderator
  • Newbie
  • *****
  • Posts: 47
Re: OMP support for BuildRHS in ResidualBasedEliminationBuilderAndSolver
« Reply #3 on: June 02, 2016, 09:59:40 PM »
Hi Ignasi,

please do not commit that. I also have a revised version, which uses atomics instead of locks. This shall be more effective.

I also did some pretty major changes in the SetupDofSet and in the ConstructMatrixStructure which make them parallel and shall provide some sustantial speedup.

i'll send an email to you so that you can take a look. Tell me if it does work for you

cheers
Riccardo

Ignasi de Pouplana

  • Newbie
  • *
  • Posts: 21
Re: OMP support for BuildRHS in ResidualBasedEliminationBuilderAndSolver
« Reply #4 on: June 03, 2016, 06:01:08 AM »
Ok, I reverted the changes in ResidualBasedEliminationBuilderAndSolver.

I've also tried the new version of ResidualBasedBlockBuilderAndSolver you sent me.

In Windows it worked without an error.

And in Mac, I tried to compile it with the default Apple's clang and it failed. Here I paste the error:

Code: [Select]
[ 49%] Building CXX object kratos/CMakeFiles/Kratos.dir/python/add_coordinate_matrix_to_python.cpp.o
Scanning dependencies of target KratosConvectionDiffusionApplication
[ 49%] Building CXX object applications/convection_diffusion_application/CMakeFiles/KratosConvectionDiffusionApplication.dir/convection_diffusion_application.cpp.o
In file included from /Users/ignasi/kratos/kratos/python/add_processes_to_python.cpp:41:
In file included from /Users/ignasi/kratos/kratos/processes/variational_distance_calculation_process.h:58:
/Users/ignasi/kratos/kratos/solving_strategies/builder_and_solvers/residualbased_block_builder_and_solver.h:1029:18: error:
      use of undeclared identifier 'omp_lock_t'
    std::vector< omp_lock_t > mlock_array;
                 ^
/Users/ignasi/kratos/kratos/solving_strategies/builder_and_solvers/residualbased_block_builder_and_solver.h:179:13: error:
      exception specification of overriding function is more lax than base version
    virtual ~ResidualBasedBlockBuilderAndSolver()
            ^
/Users/ignasi/kratos/kratos/processes/levelset_convection_process.h:159:80: note: in instantiation of
      template class 'Kratos::ResidualBasedBlockBuilderAndSolver<Kratos::UblasSpace<double,
      boost::numeric::ublas::compressed_matrix<double,
      boost::numeric::ublas::basic_row_major<unsigned long, long>, 0,
      boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator<unsigned long> >,
      boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::UblasSpace<double,
      boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long,
      long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::LinearSolver<Kratos::UblasSpace<double,
      boost::numeric::ublas::compressed_matrix<double,
      boost::numeric::ublas::basic_row_major<unsigned long, long>, 0,
      boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator<unsigned long> >,
      boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::UblasSpace<double,
      boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long,
      long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::Reorderer<Kratos::UblasSpace<double,
      boost::numeric::ublas::compressed_matrix<double,
      boost::numeric::ublas::basic_row_major<unsigned long, long>, 0,
      boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator<unsigned long> >,
      boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::UblasSpace<double,
      boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long,
      long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > > > > >' requested here
        BuilderSolverTypePointer pBuilderSolver = BuilderSolverTypePointer(new ResidualBasedB...
                                                                               ^
/Users/ignasi/kratos/kratos/solving_strategies/builder_and_solvers/builder_and_solver.h:229:13: note:
      overridden virtual function is here
    virtual ~BuilderAndSolver()
            ^
In file included from /Users/ignasi/kratos/kratos/python/add_processes_to_python.cpp:41:
In file included from /Users/ignasi/kratos/kratos/processes/variational_distance_calculation_process.h:58:
/Users/ignasi/kratos/kratos/solving_strategies/builder_and_solvers/residualbased_block_builder_and_solver.h:277:13: error:
      cannot initialize object parameter of type 'Kratos::BuilderAndSolver<Kratos::UblasSpace<double,
      boost::numeric::ublas::compressed_matrix<double,
      boost::numeric::ublas::basic_row_major<unsigned long, long>, 0,
      boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator<unsigned long> >,
      boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::UblasSpace<double,
      boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long,
      long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::LinearSolver<Kratos::UblasSpace<double,
      boost::numeric::ublas::compressed_matrix<double,
      boost::numeric::ublas::basic_row_major<unsigned long, long>, 0,
      boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator<unsigned long> >,
      boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::UblasSpace<double,
      boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long,
      long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::Reorderer<Kratos::UblasSpace<double,
      boost::numeric::ublas::compressed_matrix<double,
      boost::numeric::ublas::basic_row_major<unsigned long, long>, 0,
      boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator<unsigned long> >,
      boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::UblasSpace<double,
      boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long,
      long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > > > > >' with an expression of type
      'Kratos::ResidualBasedBlockBuilderAndSolver<Kratos::UblasSpace<double,
      boost::numeric::ublas::compressed_matrix<double,
      boost::numeric::ublas::basic_row_major<unsigned long, long>, 0,
      boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator<unsigned long> >,
      boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::UblasSpace<double,
      boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long,
      long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::LinearSolver<Kratos::UblasSpace<double,
      boost::numeric::ublas::compressed_matrix<double,
      boost::numeric::ublas::basic_row_major<unsigned long, long>, 0,
      boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator<unsigned long> >,
      boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::UblasSpace<double,
      boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long,
      long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::Reorderer<Kratos::UblasSpace<double,
      boost::numeric::ublas::compressed_matrix<double,
      boost::numeric::ublas::basic_row_major<unsigned long, long>, 0,
      boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator<unsigned long> >,
      boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::UblasSpace<double,
      boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long,
      long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > > > > >'
        if (this->GetEchoLevel() >= 1 && r_model_part.GetCommunicator().MyPID() == 0)
            ^~~~
/Users/ignasi/kratos/kratos/solving_strategies/builder_and_solvers/residualbased_block_builder_and_solver.h:168:5: note:
      in instantiation of member function
      'Kratos::ResidualBasedBlockBuilderAndSolver<Kratos::UblasSpace<double,
      boost::numeric::ublas::compressed_matrix<double,
      boost::numeric::ublas::basic_row_major<unsigned long, long>, 0,
      boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator<unsigned long> >,
      boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::UblasSpace<double,
      boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long,
      long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::LinearSolver<Kratos::UblasSpace<double,
      boost::numeric::ublas::compressed_matrix<double,
      boost::numeric::ublas::basic_row_major<unsigned long, long>, 0,
      boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator<unsigned long> >,
      boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::UblasSpace<double,
      boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long,
      long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::Reorderer<Kratos::UblasSpace<double,
      boost::numeric::ublas::compressed_matrix<double,
      boost::numeric::ublas::basic_row_major<unsigned long, long>, 0,
      boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator<unsigned long> >,
      boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::UblasSpace<double,
      boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long,
      long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > > > > >::Build' requested here
    ResidualBasedBlockBuilderAndSolver(
    ^
/Users/ignasi/kratos/kratos/processes/variational_distance_calculation_process.h:194:80: note: in
      instantiation of member function
      'Kratos::ResidualBasedBlockBuilderAndSolver<Kratos::UblasSpace<double,
      boost::numeric::ublas::compressed_matrix<double,
      boost::numeric::ublas::basic_row_major<unsigned long, long>, 0,

...

/Users/ignasi/kratos/external_libraries/boost_1_59_0/boost/smart_ptr/shared_ptr.hpp:611:5: note: candidate template ignored: could not match 'shared_ptr<type-parameter-0-0>' against
      'Kratos::ResidualBasedBlockBuilderAndSolver<Kratos::UblasSpace<double, boost::numeric::ublas::compressed_matrix<double, boost::numeric::ublas::basic_row_major<unsigned long, long>, 0,
      boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator<unsigned long> >, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > > >, Kratos::UblasSpace<double, boost::numeric::ublas::matrix<double,
      boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >, boost::numeric::ublas::vector<double,
      boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > > >, Kratos::LinearSolver<Kratos::UblasSpace<double, boost::numeric::ublas::compressed_matrix<double,
      boost::numeric::ublas::basic_row_major<unsigned long, long>, 0, boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator<unsigned long> >,
      boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >, boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::UblasSpace<double, boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long, long>,
      boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >, boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double,
      std::__1::allocator<double> > > >, Kratos::Reorderer<Kratos::UblasSpace<double, boost::numeric::ublas::compressed_matrix<double, boost::numeric::ublas::basic_row_major<unsigned long,
      long>, 0, boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator<unsigned long> >, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >,
      boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > > >, Kratos::UblasSpace<double, boost::numeric::ublas::matrix<double,
      boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >, boost::numeric::ublas::vector<double,
      boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > > > > > > *'
    shared_ptr( shared_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
    ^
/Users/ignasi/kratos/external_libraries/boost_1_59_0/boost/smart_ptr/shared_ptr.hpp:365:32: note: candidate constructor template not viable: requires 2 arguments, but 1 was provided
    template<class Y, class D> shared_ptr( Y * p, D d ): px( p ), pn( p, d )
                               ^
/Users/ignasi/kratos/external_libraries/boost_1_59_0/boost/smart_ptr/shared_ptr.hpp:372:23: note: candidate constructor template not viable: requires 2 arguments, but 1 was provided
    template<class D> shared_ptr( boost::detail::sp_nullptr_t p, D d ): px( p ), pn( p, d )
                      ^
/Users/ignasi/kratos/external_libraries/boost_1_59_0/boost/smart_ptr/shared_ptr.hpp:380:41: note: candidate constructor template not viable: requires 3 arguments, but 1 was provided
    template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
                                        ^
/Users/ignasi/kratos/external_libraries/boost_1_59_0/boost/smart_ptr/shared_ptr.hpp:387:32: note: candidate constructor template not viable: requires 3 arguments, but 1 was provided
    template<class D, class A> shared_ptr( boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( p, d, a )
                               ^
/Users/ignasi/kratos/external_libraries/boost_1_59_0/boost/smart_ptr/shared_ptr.hpp:415:5: note: candidate constructor template not viable: requires 2 arguments, but 1 was provided
    shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag )
    ^
/Users/ignasi/kratos/external_libraries/boost_1_59_0/boost/smart_ptr/shared_ptr.hpp:441:5: note: candidate constructor template not viable: requires 2 arguments, but 1 was provided
    shared_ptr( shared_ptr<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
    ^
/Users/ignasi/kratos/external_libraries/boost_1_59_0/boost/smart_ptr/shared_ptr.hpp:341:5: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
    shared_ptr() BOOST_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+
    ^
15 errors generated.
make[2]: *** [kratos/CMakeFiles/Kratos.dir/python/add_processes_to_python.cpp.o] Error 1
make[1]: *** [kratos/CMakeFiles/Kratos.dir/all] Error 2
make: *** [all] Error 2

Then I tried compiling it with a "normal" clang (with omp suport) and it compiled without problems...

By the way, I guess you also plan to introduce these changes for the BuildRHS in ResidualBasedEliminationBuilderAndSolver, which was the subject of this post...

Regards,

Ignasi