<commit_before>// ------------------------------------------------------------------------------------------------
#include "Core.hpp"
#include "Base/Shared.hpp"
#include "Base/Color3.hpp"
#include "Base/Vector2.hpp"
#include "Base/Vector3.hpp"
#include "Entity/Player.hpp"
#include "Library/Numeric/LongInt.hpp"

// ------------------------------------------------------------------------------------------------
#include "Misc/Functions.hpp"
#include "Misc/Model.hpp"
#include "Misc/Player.hpp"
#include "Misc/Vehicle.hpp"
#include "Misc/Weapon.hpp"

// ------------------------------------------------------------------------------------------------
namespace SqMod {

// ------------------------------------------------------------------------------------------------
static const Object & FindPlayer(Object & by)
{
    switch (by.GetType())
    {
        case OT_INTEGER:
        {
            return Core::Get().GetPlayer(by.Cast< Int32 >()).mObj;
        } break;
        case OT_FLOAT:
        {
            return Core::Get().GetPlayer(std::round(by.Cast< Float32 >())).mObj;
        } break;
        case OT_STRING:
        {
            // Obtain the argument as a string
            String str(by.Cast< String >());
            // Attempt to locate the player with this name
            Int32 id = _Func->GetPlayerIdFromName(&str[0]);
            // Was there a player with this name?
            if (VALID_ENTITYEX(id, SQMOD_PLAYER_POOL))
            {
                Core::Get().GetPlayer(id).mObj;
            }
        } break;
        default: STHROWF("Unsupported search identifier");
    }
    // Default to a null object
    return NullObject();
}

// ------------------------------------------------------------------------------------------------
extern void Register_Broadcast(HSQUIRRELVM vm);

// ================================================================================================
void Register_Misc(HSQUIRRELVM vm)
{
    Table srvns(vm);

    srvns.SquirrelFunc(_SC("SendLogMessage"), &SendLogMessage)
    .Func(_SC("GetVersion"), &GetServerVersion)
    .Func(_SC("GetSettings"), &GetServerSettings)
    .Func(_SC("GetNumberOfPlugins"), &GetNumberOfPlugins)
    .Func(_SC("GetPluginInfo"), &GetPluginInfo)
    .Func(_SC("FindPlugin"), &FindPlugin)
    .Func(_SC("SendPluginCommand"), &SendPluginCommand)
    .Func(_SC("GetTime"), &GetTime)
    .Func(_SC("GetLastError"), &GetLastError)
    .Func(_SC("GetPluginVersion"), &GetPluginVersion)
    .Func(_SC("GetPluginVersionStr"), &GetPluginVersionStr)
    .Func(_SC("GetPluginName"), &GetPluginName)
    .Func(_SC("GetPluginAuthor"), &GetPluginAuthor)
    .Func(_SC("GetPluginID"), &GetPluginID)
    .Func(_SC("GetServerPort"), &GetServerPort)
    .Func(_SC("GetServerFlags"), &GetServerFlags)
    .Func(_SC("GetMaxPlayers"), &GetMaxPlayers)
    .Func(_SC("SetMaxPlayers"), &SetMaxPlayers)
    .Func(_SC("GetServerName"), &GetServerName)
    .Func(_SC("SetServerName"), &SetServerName)
    .Func(_SC("GetPassword"), &GetServerPassword)
    .Func(_SC("SetPassword"), &SetServerPassword)
    .Func(_SC("GetGameModeText"), &GetGameModeText)
    .Func(_SC("SetGameModeText"), &SetGameModeText)
    .Func(_SC("CreateRadioStream"), &CreateRadioStream)
    .Func(_SC("CreateRadioStreamEx"), &CreateRadioStreamEx)
    .Func(_SC("RemoveRadioStream"), &RemoveRadioStream)
    .Func(_SC("Shutdown"), &ShutdownServer)
    .Func(_SC("GetOption"), &GetServerOption)
    .Func(_SC("SetOption"), &SetServerOption)
    .Func(_SC("SetOptionEx"), &SetServerOptionEx)
    .Func(_SC("GetWorldBounds"), &GetWorldBounds)
    .Func(_SC("SetWorldBounds"), &SetWorldBounds)
    .Func(_SC("SetWorldBoundsEx"), &SetWorldBoundsEx)
    .Func(_SC("GetWastedSettings"), &GetWastedSettings)
    .Func(_SC("SetWastedSettings"), &SetWastedSettings)
    .Func(_SC("GetTimeRate"), &GetTimeRate)
    .Func(_SC("SetTimeRate"), &SetTimeRate)
    .Func(_SC("GetHour"), &GetHour)
    .Func(_SC("SetHour"), &SetHour)
    .Func(_SC("GetMinute"), &GetMinute)
    .Func(_SC("SetMinute"), &SetMinute)
    .Func(_SC("GetWeather"), &GetWeather)
    .Func(_SC("SetWeather"), &SetWeather)
    .Func(_SC("GetGravity"), &GetGravity)
    .Func(_SC("SetGravity"), &SetGravity)
    .Func(_SC("GetGameSpeed"), &GetGameSpeed)
    .Func(_SC("SetGameSpeed"), &SetGameSpeed)
    .Func(_SC("GetWaterLevel"), &GetWaterLevel)
    .Func(_SC("SetWaterLevel"), &SetWaterLevel)
    .Func(_SC("GetMaximumFlightAltitude"), &GetMaximumFlightAltitude)
    .Func(_SC("SetMaximumFlightAltitude"), &SetMaximumFlightAltitude)
    .Func(_SC("GetKillCommandDelay"), &GetKillCommandDelay)
    .Func(_SC("SetKillCommandDelay"), &SetKillCommandDelay)
    .Func(_SC("GetVehiclesForcedRespawnHeight"), &GetVehiclesForcedRespawnHeight)
    .Func(_SC("SetVehiclesForcedRespawnHeight"), &SetVehiclesForcedRespawnHeight)
    .Func(_SC("CreateExplosion"), &CreateExplosion)
    .Func(_SC("CreateExplosionEx"), &CreateExplosionEx)
    .Func(_SC("PlaySound"), &PlaySound)
    .Func(_SC("PlaySoundEx"), &PlaySoundEx)
    .Func(_SC("HideMapObject"), &HideMapObject)
    .Func(_SC("HideMapObjectEx"), &SetKeyCodeName)
    .Func(_SC("HideMapObjectRaw"), &HideMapObjectRaw)
    .Func(_SC("ShowMapObject"), &ShowMapObject)
    .Func(_SC("ShowMapObjectEx"), &ShowMapObjectEx)
    .Func(_SC("ShowMapObjectRaw"), &ShowMapObjectRaw)
    .Func(_SC("ShowAllMapObjects"), &ShowAllMapObjects)
    .Func(_SC("GetWeaponDataValue"), &GetWeaponDataValue)
    .Func(_SC("SetWeaponDataValue"), &SetWeaponDataValue)
    .Func(_SC("ResetWeaponDataValue"), &ResetWeaponDataValue)
    .Func(_SC("IsWeaponDataValueModified"), &IsWeaponDataValueModified)
    .Func(_SC("ResetWeaponData"), &ResetWeaponData)
    .Func(_SC("ResetAllWeaponData"), &ResetAllWeaponData)
    .Func(_SC("AddPlayerClass"), &AddPlayerClass)
    .Func(_SC("SetSpawnPlayerPosition"), &SetSpawnPlayerPosition)
    .Func(_SC("SetSpawnCameraPosition"), &SetSpawnCameraPosition)
    .Func(_SC("SetSpawnCameraLookAt"), &SetSpawnCameraLookAt)
    .Func(_SC("SetSpawnPlayerPositionEx"), &SetSpawnPlayerPositionEx)
    .Func(_SC("SetSpawnCameraPositionEx"), &SetSpawnCameraPositionEx)
    .Func(_SC("SetSpawnCameraLookAtEx"), &SetSpawnCameraLookAtEx)
    .Func(_SC("BanIP"), &BanIP)
    .Func(_SC("UnbanIP"), &UnbanIP)
    .Func(_SC("IsIPBanned"), &IsIPBanned)
    .Func(_SC("GetPlayerIdFromName"), &GetPlayerIdFromName)
    .Func(_SC("IsPlayerConnected"), &IsPlayerConnected)
    .Func(_SC("ForceAllSelect"), &ForceAllSelect)
    .Func(_SC("CheckEntityExists"), &SetKeyCodeName)
    .Func(_SC("GetDistrictName"), &GetDistrictName)
    .Func(_SC("GetDistrictNameEx"), &GetDistrictNameEx);

    RootTable(vm).Bind(_SC("SqServer"), srvns);

    RootTable(vm)
    .Func(_SC("FindPlayer"), &FindPlayer)
    .Func(_SC("GetKeyCodeName"), &GetKeyCodeName)
    .Func(_SC("SetKeyCodeName"), &SetKeyCodeName)
    .Func(_SC("GetModelName"), &GetModelName)
    .Func(_SC("SetModelName"), &SetModelName)
    .Func(_SC("IsModelWeapon"), &IsModelWeapon)
    .Func(_SC("IsModelActuallyWeapon"), &IsModelActuallyWeapon)
    .Func(_SC("GetSkinName"), &GetSkinName)
    .Func(_SC("SetSkinName"), &SetSkinName)
    .Func(_SC("GetSkinID"), &GetSkinID)
    .Func(_SC("IsSkinValid"), &IsSkinValid)
    .Func(_SC("GetAutomobileName"), &GetAutomobileName)
    .Func(_SC("SetAutomobileName"), &SetAutomobileName)
    .Func(_SC("GetAutomobileID"), &GetAutomobileID)
    .Func(_SC("IsAutomobileValid"), &IsAutomobileValid)
    .Func(_SC("GetWeaponName"), &GetWeaponName)
    .Func(_SC("SetWeaponName"), &SetWeaponName)
    .Func(_SC("GetWeaponID"), &GetWeaponID)
    .Func(_SC("IsWeaponValid"), &IsWeaponValid)
    .Func(_SC("WeaponToModel"), &WeaponToModel)
    .Func(_SC("IsWeaponNatural"), &IsWeaponNatural)
    .Func(_SC("PlaySound"), &PlaySound)
    .Func(_SC("PlaySoundEx"), &PlaySoundEx)
    .Func(_SC("CreateExplosion"), &CreateExplosion)
    .Func(_SC("CreateExplosionEx"), &CreateExplosionEx);

    Register_Broadcast(vm);
}

} // Namespace:: SqMod
<commit_msg>Fix wrong function registered under the wrong name.<commit_after>// ------------------------------------------------------------------------------------------------
#include "Core.hpp"
#include "Base/Shared.hpp"
#include "Base/Color3.hpp"
#include "Base/Vector2.hpp"
#include "Base/Vector3.hpp"
#include "Entity/Player.hpp"
#include "Library/Numeric/LongInt.hpp"

// ------------------------------------------------------------------------------------------------
#include "Misc/Functions.hpp"
#include "Misc/Model.hpp"
#include "Misc/Player.hpp"
#include "Misc/Vehicle.hpp"
#include "Misc/Weapon.hpp"

// ------------------------------------------------------------------------------------------------
namespace SqMod {

// ------------------------------------------------------------------------------------------------
static const Object & FindPlayer(Object & by)
{
    switch (by.GetType())
    {
        case OT_INTEGER:
        {
            return Core::Get().GetPlayer(by.Cast< Int32 >()).mObj;
        } break;
        case OT_FLOAT:
        {
            return Core::Get().GetPlayer(std::round(by.Cast< Float32 >())).mObj;
        } break;
        case OT_STRING:
        {
            // Obtain the argument as a string
            String str(by.Cast< String >());
            // Attempt to locate the player with this name
            Int32 id = _Func->GetPlayerIdFromName(&str[0]);
            // Was there a player with this name?
            if (VALID_ENTITYEX(id, SQMOD_PLAYER_POOL))
            {
                Core::Get().GetPlayer(id).mObj;
            }
        } break;
        default: STHROWF("Unsupported search identifier");
    }
    // Default to a null object
    return NullObject();
}

// ------------------------------------------------------------------------------------------------
extern void Register_Broadcast(HSQUIRRELVM vm);

// ================================================================================================
void Register_Misc(HSQUIRRELVM vm)
{
    Table srvns(vm);

    srvns.SquirrelFunc(_SC("SendLogMessage"), &SendLogMessage)
    .Func(_SC("GetVersion"), &GetServerVersion)
    .Func(_SC("GetSettings"), &GetServerSettings)
    .Func(_SC("GetNumberOfPlugins"), &GetNumberOfPlugins)
    .Func(_SC("GetPluginInfo"), &GetPluginInfo)
    .Func(_SC("FindPlugin"), &FindPlugin)
    .Func(_SC("SendPluginCommand"), &SendPluginCommand)
    .Func(_SC("GetTime"), &GetTime)
    .Func(_SC("GetLastError"), &GetLastError)
    .Func(_SC("GetPluginVersion"), &GetPluginVersion)
    .Func(_SC("GetPluginVersionStr"), &GetPluginVersionStr)
    .Func(_SC("GetPluginName"), &GetPluginName)
    .Func(_SC("GetPluginAuthor"), &GetPluginAuthor)
    .Func(_SC("GetPluginID"), &GetPluginID)
    .Func(_SC("GetServerPort"), &GetServerPort)
    .Func(_SC("GetServerFlags"), &GetServerFlags)
    .Func(_SC("GetMaxPlayers"), &GetMaxPlayers)
    .Func(_SC("SetMaxPlayers"), &SetMaxPlayers)
    .Func(_SC("GetServerName"), &GetServerName)
    .Func(_SC("SetServerName"), &SetServerName)
    .Func(_SC("GetPassword"), &GetServerPassword)
    .Func(_SC("SetPassword"), &SetServerPassword)
    .Func(_SC("GetGameModeText"), &GetGameModeText)
    .Func(_SC("SetGameModeText"), &SetGameModeText)
    .Func(_SC("CreateRadioStream"), &CreateRadioStream)
    .Func(_SC("CreateRadioStreamEx"), &CreateRadioStreamEx)
    .Func(_SC("RemoveRadioStream"), &RemoveRadioStream)
    .Func(_SC("Shutdown"), &ShutdownServer)
    .Func(_SC("GetOption"), &GetServerOption)
    .Func(_SC("SetOption"), &SetServerOption)
    .Func(_SC("SetOptionEx"), &SetServerOptionEx)
    .Func(_SC("GetWorldBounds"), &GetWorldBounds)
    .Func(_SC("SetWorldBounds"), &SetWorldBounds)
    .Func(_SC("SetWorldBoundsEx"), &SetWorldBoundsEx)
    .Func(_SC("GetWastedSettings"), &GetWastedSettings)
    .Func(_SC("SetWastedSettings"), &SetWastedSettings)
    .Func(_SC("GetTimeRate"), &GetTimeRate)
    .Func(_SC("SetTimeRate"), &SetTimeRate)
    .Func(_SC("GetHour"), &GetHour)
    .Func(_SC("SetHour"), &SetHour)
    .Func(_SC("GetMinute"), &GetMinute)
    .Func(_SC("SetMinute"), &SetMinute)
    .Func(_SC("GetWeather"), &GetWeather)
    .Func(_SC("SetWeather"), &SetWeather)
    .Func(_SC("GetGravity"), &GetGravity)
    .Func(_SC("SetGravity"), &SetGravity)
    .Func(_SC("GetGameSpeed"), &GetGameSpeed)
    .Func(_SC("SetGameSpeed"), &SetGameSpeed)
    .Func(_SC("GetWaterLevel"), &GetWaterLevel)
    .Func(_SC("SetWaterLevel"), &SetWaterLevel)
    .Func(_SC("GetMaximumFlightAltitude"), &GetMaximumFlightAltitude)
    .Func(_SC("SetMaximumFlightAltitude"), &SetMaximumFlightAltitude)
    .Func(_SC("GetKillCommandDelay"), &GetKillCommandDelay)
    .Func(_SC("SetKillCommandDelay"), &SetKillCommandDelay)
    .Func(_SC("GetVehiclesForcedRespawnHeight"), &GetVehiclesForcedRespawnHeight)
    .Func(_SC("SetVehiclesForcedRespawnHeight"), &SetVehiclesForcedRespawnHeight)
    .Func(_SC("CreateExplosion"), &CreateExplosion)
    .Func(_SC("CreateExplosionEx"), &CreateExplosionEx)
    .Func(_SC("PlaySound"), &PlaySound)
    .Func(_SC("PlaySoundEx"), &PlaySoundEx)
    .Func(_SC("HideMapObject"), &HideMapObject)
    .Func(_SC("HideMapObjectEx"), &SetKeyCodeName)
    .Func(_SC("HideMapObjectRaw"), &HideMapObjectRaw)
    .Func(_SC("ShowMapObject"), &ShowMapObject)
    .Func(_SC("ShowMapObjectEx"), &ShowMapObjectEx)
    .Func(_SC("ShowMapObjectRaw"), &ShowMapObjectRaw)
    .Func(_SC("ShowAllMapObjects"), &ShowAllMapObjects)
    .Func(_SC("GetWeaponDataValue"), &GetWeaponDataValue)
    .Func(_SC("SetWeaponDataValue"), &SetWeaponDataValue)
    .Func(_SC("ResetWeaponDataValue"), &ResetWeaponDataValue)
    .Func(_SC("IsWeaponDataValueModified"), &IsWeaponDataValueModified)
    .Func(_SC("ResetWeaponData"), &ResetWeaponData)
    .Func(_SC("ResetAllWeaponData"), &ResetAllWeaponData)
    .Func(_SC("AddPlayerClass"), &AddPlayerClass)
    .Func(_SC("SetSpawnPlayerPosition"), &SetSpawnPlayerPosition)
    .Func(_SC("SetSpawnCameraPosition"), &SetSpawnCameraPosition)
    .Func(_SC("SetSpawnCameraLookAt"), &SetSpawnCameraLookAt)
    .Func(_SC("SetSpawnPlayerPositionEx"), &SetSpawnPlayerPositionEx)
    .Func(_SC("SetSpawnCameraPositionEx"), &SetSpawnCameraPositionEx)
    .Func(_SC("SetSpawnCameraLookAtEx"), &SetSpawnCameraLookAtEx)
    .Func(_SC("BanIP"), &BanIP)
    .Func(_SC("UnbanIP"), &UnbanIP)
    .Func(_SC("IsIPBanned"), &IsIPBanned)
    .Func(_SC("GetPlayerIdFromName"), &GetPlayerIdFromName)
    .Func(_SC("IsPlayerConnected"), &IsPlayerConnected)
    .Func(_SC("ForceAllSelect"), &ForceAllSelect)
    .Func(_SC("CheckEntityExists"), &CheckEntityExists)
    .Func(_SC("GetDistrictName"), &GetDistrictName)
    .Func(_SC("GetDistrictNameEx"), &GetDistrictNameEx);

    RootTable(vm).Bind(_SC("SqServer"), srvns);

    RootTable(vm)
    .Func(_SC("FindPlayer"), &FindPlayer)
    .Func(_SC("GetKeyCodeName"), &GetKeyCodeName)
    .Func(_SC("SetKeyCodeName"), &SetKeyCodeName)
    .Func(_SC("GetModelName"), &GetModelName)
    .Func(_SC("SetModelName"), &SetModelName)
    .Func(_SC("IsModelWeapon"), &IsModelWeapon)
    .Func(_SC("IsModelActuallyWeapon"), &IsModelActuallyWeapon)
    .Func(_SC("GetSkinName"), &GetSkinName)
    .Func(_SC("SetSkinName"), &SetSkinName)
    .Func(_SC("GetSkinID"), &GetSkinID)
    .Func(_SC("IsSkinValid"), &IsSkinValid)
    .Func(_SC("GetAutomobileName"), &GetAutomobileName)
    .Func(_SC("SetAutomobileName"), &SetAutomobileName)
    .Func(_SC("GetAutomobileID"), &GetAutomobileID)
    .Func(_SC("IsAutomobileValid"), &IsAutomobileValid)
    .Func(_SC("GetWeaponName"), &GetWeaponName)
    .Func(_SC("SetWeaponName"), &SetWeaponName)
    .Func(_SC("GetWeaponID"), &GetWeaponID)
    .Func(_SC("IsWeaponValid"), &IsWeaponValid)
    .Func(_SC("WeaponToModel"), &WeaponToModel)
    .Func(_SC("IsWeaponNatural"), &IsWeaponNatural)
    .Func(_SC("PlaySound"), &PlaySound)
    .Func(_SC("PlaySoundEx"), &PlaySoundEx)
    .Func(_SC("CreateExplosion"), &CreateExplosion)
    .Func(_SC("CreateExplosionEx"), &CreateExplosionEx);

    Register_Broadcast(vm);
}

} // Namespace:: SqMod
<|endoftext|>


<commit_before>
#include <mandy/function_tools.h>

#include <fstream>
#include <iostream>

#include <algorithm>    // std::transform
#include <functional>   // std::plus

namespace mandy
{

  /**
   * Class constructor.
   */
  template <int dim>
  FunctionTools<dim>::FunctionTools (dealii::parallel::distributed::Triangulation<dim> &triangulation,
				     const std::string                                 &prm)
    :
    mpi_communicator (MPI_COMM_WORLD),
    triangulation (&triangulation),
    dof_handler (triangulation),
    fe (dealii::FE_Q<dim> (2), 1),
    // ---
    pcout (std::cout, (dealii::Utilities::MPI::this_mpi_process (mpi_communicator) == 0)),
    timer (mpi_communicator, pcout,
     	   dealii::TimerOutput::summary,
     	   dealii::TimerOutput::wall_times)
  {
    parameters.declare_entry ("Global mesh refinement steps", "5",
                              dealii::Patterns::Integer (0, 20),
                              "The number of times the 1-cell coarse mesh should "
                              "be refined globally for our computations.");

    parameters.declare_entry ("MaterialFunction", "0",
                              dealii::Patterns::Anything (),
                              "A functional description of the inclusion material.");

    parameters.parse_input (prm);
  }

  /**
   * Class destructor.
   */
  template <int dim>
  FunctionTools<dim>::~FunctionTools ()
  {
    // Wipe DoF handlers.
    dof_handler.clear ();
  }

  /**
   * Setup system matrices and vectors.
   */
  template <int dim>
  void FunctionTools<dim>::setup_system ()
  {
    dealii::TimerOutput::Scope time (timer, "setup system");

    // Determine locally relevant DoFs.
    dof_handler.distribute_dofs (fe);
    locally_owned_dofs = dof_handler.locally_owned_dofs ();
    dealii::DoFTools::extract_locally_relevant_dofs (dof_handler, locally_relevant_dofs);

    // Initialise distributed vectors.
    locally_relevant_solution.reinit (locally_owned_dofs, locally_relevant_dofs,
				      mpi_communicator);
    system_rhs.reinit (locally_owned_dofs,
		       mpi_communicator);

    // Setup hanging node constraints.
    constraints.clear ();
    constraints.reinit (locally_relevant_dofs);
    dealii::DoFTools::make_hanging_node_constraints (dof_handler, constraints);
    constraints.close ();

    // Finally, create a distributed sparsity pattern and initialise
    // the system matrix from that.
    dealii::DynamicSparsityPattern dsp (locally_relevant_dofs);
    dealii::DoFTools::make_sparsity_pattern (dof_handler, dsp, constraints, false);
    dealii::SparsityTools::distribute_sparsity_pattern (dsp,
							dof_handler.n_locally_owned_dofs_per_processor (),
							mpi_communicator,
							locally_relevant_dofs);

    system_matrix.reinit (locally_owned_dofs, locally_owned_dofs,
                          dsp, mpi_communicator);

  }

  /**
   * Assemble system matrices and vectors.
   *
   * TODO Ideally, we would use a function like this:
   *
   * dealii::MatrixCreator::create_mass_matrix (dof_handler, quadrature_rule, system_matrix, 1, constraints);
   *
   * however no such thing currently exists in the deal.II library for
   * parallel matrices and vectors. Instead, the mass matrix and right
   * hand side vector are assembled by hand in functions defined in
   * the namepsaces, mandy::MatrixCreator and mandy::VectorCreator,
   * respectively.
   */
  template <int dim>
  void
  FunctionTools<dim>::assemble_system ()
  {
    dealii::TimerOutput::Scope time (timer, "assemble system");

    // Define quadrature rule to be used.
    const dealii::QGauss<dim> quadrature_formula (3);

    // Initialise the function parser.
    dealii::FunctionParser<dim> material_identification;
    material_identification.initialize (dealii::FunctionParser<dim>::default_variable_names (),
					parameters.get ("MaterialFunction"),
					typename dealii::FunctionParser<dim>::ConstMap ());

    mandy::MatrixCreator::create_mass_matrix<dim> (fe, dof_handler, quadrature_formula,
						   system_matrix, constraints,
						   mpi_communicator);

    mandy::VectorCreator::create_right_hand_side_vector<dim> (fe, dof_handler, quadrature_formula,
     							      system_rhs, constraints,
							      material_identification,
							      mpi_communicator);
  }

  /**
   * Solve the linear algebra system.
   */
  template <int dim>
  unsigned int
  FunctionTools<dim>::solve ()
  {
    dealii::TimerOutput::Scope time (timer, "solve");

    dealii::PETScWrappers::MPI::Vector completely_distributed_solution (locally_owned_dofs, mpi_communicator);

    // Solve using conjugate gradient method with no preconditioner
    // (ie., system_matrix is ignored).
    dealii::SolverControl solver_control (dof_handler.n_dofs (), 1e-06);
    dealii::PETScWrappers::SolverCG solver (solver_control, mpi_communicator);
    dealii::PETScWrappers::PreconditionNone preconditioner (system_matrix);

    solver.solve (system_matrix, completely_distributed_solution, system_rhs,
		  preconditioner);

    // Ensure that all ghost elements are also copied as necessary.
    constraints.distribute (completely_distributed_solution);
    locally_relevant_solution = completely_distributed_solution;

    // Return the number of iterations (last step) of the solve.
    return solver_control.last_step ();
  }

  /**
   * Output results, ie., finite element functions and derived
   * quantitites for this cycle..
   */
  template <int dim>
  void
  FunctionTools<dim>::output_results (const unsigned int cycle)
  {
    dealii::TimerOutput::Scope time (timer, "output_results");

    dealii::DataOut<dim> data_out;
    data_out.attach_dof_handler (dof_handler);
    data_out.add_data_vector (locally_relevant_solution, "material");

    dealii::Vector<float> subdomain ((*triangulation).n_active_cells ());
    for (unsigned int i=0; i<subdomain.size(); ++i)
      subdomain (i) = (*triangulation).locally_owned_subdomain ();
    data_out.add_data_vector (subdomain, "subdomain");

    data_out.build_patches ();

    const std::string filename = ("material-" +
                                  dealii::Utilities::int_to_string (cycle, 2) +
                                  "." +
                                  dealii::Utilities::int_to_string
                                  ((*triangulation).locally_owned_subdomain (), 4));

    std::ofstream output ((filename + ".vtu").c_str ());
    data_out.write_vtu (output);

    if (dealii::Utilities::MPI::this_mpi_process(mpi_communicator) == 1)
      {
	std::vector<std::string> filenames;

	for (unsigned int i=0;
	     i<dealii::Utilities::MPI::n_mpi_processes (mpi_communicator);
	     ++i)
	  filenames.push_back ("material-" +
			       dealii::Utilities::int_to_string (cycle, 2) +
			       "." +
			       dealii::Utilities::int_to_string (i, 4) +
			       ".vtu");
	std::ofstream master_output (("material-" +
				      dealii::Utilities::int_to_string (cycle, 2) +
				      ".pvtu").c_str ());

	data_out.write_pvtu_record (master_output, filenames);
      }
  }

  /**
   * Refine grid based on Kelly's error estimator working on the
   * material id (solution vector).
   */
  template <int dim>
  void FunctionTools<dim>::refine_grid ()
  {
    dealii::TimerOutput::Scope time (timer, "refine grid");

    dealii::Vector<float> estimated_error_per_cell ((*triangulation).n_active_cells());

    dealii::KellyErrorEstimator<dim>::estimate (dof_handler, dealii::QGauss<dim-1>(4),
						typename dealii::FunctionMap<dim>::type (),
						locally_relevant_solution,
						estimated_error_per_cell);

    dealii::parallel::distributed::GridRefinement::
      refine_and_coarsen_fixed_number ((*triangulation),
				       estimated_error_per_cell,
				       0.250, 0.025);

    (*triangulation).execute_coarsening_and_refinement ();
  }

  /**
   * Run the application in the order specified.
   */
  template <int dim>
  void
  FunctionTools<dim>::run ()
  {
    const unsigned int n_cycles = 3;

    for (unsigned int cycle=0; cycle<n_cycles; ++cycle)
      {
        pcout << "FunctionTools:: Cycle " << cycle << ':'
	      << std::endl;

	if (cycle!=0)
	  refine_grid ();

	pcout << "   Number of active cells:       "
	      << (*triangulation).n_global_active_cells ()
	      << std::endl;

	setup_system ();

	pcout << "   Number of degrees of freedom: "
	      << dof_handler.n_dofs ()
	      << std::endl;

	assemble_system ();

	const unsigned int n_iterations = solve ();

	pcout << "   Solved in " << n_iterations
	      << " iterations."
	      << std::endl;

	pcout << "   Linfty-norm:                  "
	      << locally_relevant_solution.linfty_norm ()
	      << std::endl;

	// Output results if the number of processes is less than or
	// equal to 32.
	if (dealii::Utilities::MPI::n_mpi_processes (mpi_communicator) <= 32)
	  output_results (cycle);

	// timer.print_summary ();
        pcout << std::endl;

      } // for cycle<n_cycles
  }

} // namespace mandy

template class mandy::FunctionTools<3>;
<commit_msg>Remove coarsen.<commit_after>
#include <mandy/function_tools.h>

#include <fstream>
#include <iostream>

#include <algorithm>    // std::transform
#include <functional>   // std::plus

namespace mandy
{

  /**
   * Class constructor.
   */
  template <int dim>
  FunctionTools<dim>::FunctionTools (dealii::parallel::distributed::Triangulation<dim> &triangulation,
				     const std::string                                 &prm)
    :
    mpi_communicator (MPI_COMM_WORLD),
    triangulation (&triangulation),
    dof_handler (triangulation),
    fe (dealii::FE_Q<dim> (2), 1),
    // ---
    pcout (std::cout, (dealii::Utilities::MPI::this_mpi_process (mpi_communicator) == 0)),
    timer (mpi_communicator, pcout,
     	   dealii::TimerOutput::summary,
     	   dealii::TimerOutput::wall_times)
  {
    parameters.declare_entry ("Global mesh refinement steps", "5",
                              dealii::Patterns::Integer (0, 20),
                              "The number of times the 1-cell coarse mesh should "
                              "be refined globally for our computations.");

    parameters.declare_entry ("MaterialFunction", "0",
                              dealii::Patterns::Anything (),
                              "A functional description of the inclusion material.");

    parameters.parse_input (prm);
  }

  /**
   * Class destructor.
   */
  template <int dim>
  FunctionTools<dim>::~FunctionTools ()
  {
    // Wipe DoF handlers.
    dof_handler.clear ();
  }

  /**
   * Setup system matrices and vectors.
   */
  template <int dim>
  void FunctionTools<dim>::setup_system ()
  {
    dealii::TimerOutput::Scope time (timer, "setup system");

    // Determine locally relevant DoFs.
    dof_handler.distribute_dofs (fe);
    locally_owned_dofs = dof_handler.locally_owned_dofs ();
    dealii::DoFTools::extract_locally_relevant_dofs (dof_handler, locally_relevant_dofs);

    // Initialise distributed vectors.
    locally_relevant_solution.reinit (locally_owned_dofs, locally_relevant_dofs,
				      mpi_communicator);
    system_rhs.reinit (locally_owned_dofs,
		       mpi_communicator);

    // Setup hanging node constraints.
    constraints.clear ();
    constraints.reinit (locally_relevant_dofs);
    dealii::DoFTools::make_hanging_node_constraints (dof_handler, constraints);
    constraints.close ();

    // Finally, create a distributed sparsity pattern and initialise
    // the system matrix from that.
    dealii::DynamicSparsityPattern dsp (locally_relevant_dofs);
    dealii::DoFTools::make_sparsity_pattern (dof_handler, dsp, constraints, false);
    dealii::SparsityTools::distribute_sparsity_pattern (dsp,
							dof_handler.n_locally_owned_dofs_per_processor (),
							mpi_communicator,
							locally_relevant_dofs);

    system_matrix.reinit (locally_owned_dofs, locally_owned_dofs,
                          dsp, mpi_communicator);

  }

  /**
   * Assemble system matrices and vectors.
   *
   * TODO Ideally, we would use a function like this:
   *
   * dealii::MatrixCreator::create_mass_matrix (dof_handler, quadrature_rule, system_matrix, 1, constraints);
   *
   * however no such thing currently exists in the deal.II library for
   * parallel matrices and vectors. Instead, the mass matrix and right
   * hand side vector are assembled by hand in functions defined in
   * the namepsaces, mandy::MatrixCreator and mandy::VectorCreator,
   * respectively.
   */
  template <int dim>
  void
  FunctionTools<dim>::assemble_system ()
  {
    dealii::TimerOutput::Scope time (timer, "assemble system");

    // Define quadrature rule to be used.
    const dealii::QGauss<dim> quadrature_formula (3);

    // Initialise the function parser.
    dealii::FunctionParser<dim> material_identification;
    material_identification.initialize (dealii::FunctionParser<dim>::default_variable_names (),
					parameters.get ("MaterialFunction"),
					typename dealii::FunctionParser<dim>::ConstMap ());

    mandy::MatrixCreator::create_mass_matrix<dim> (fe, dof_handler, quadrature_formula,
						   system_matrix, constraints,
						   mpi_communicator);

    mandy::VectorCreator::create_right_hand_side_vector<dim> (fe, dof_handler, quadrature_formula,
     							      system_rhs, constraints,
							      material_identification,
							      mpi_communicator);
  }

  /**
   * Solve the linear algebra system.
   */
  template <int dim>
  unsigned int
  FunctionTools<dim>::solve ()
  {
    dealii::TimerOutput::Scope time (timer, "solve");

    dealii::PETScWrappers::MPI::Vector completely_distributed_solution (locally_owned_dofs, mpi_communicator);

    // Solve using conjugate gradient method with no preconditioner
    // (ie., system_matrix is ignored).
    dealii::SolverControl solver_control (dof_handler.n_dofs (), 1e-06);
    dealii::PETScWrappers::SolverCG solver (solver_control, mpi_communicator);
    dealii::PETScWrappers::PreconditionNone preconditioner (system_matrix);

    solver.solve (system_matrix, completely_distributed_solution, system_rhs,
		  preconditioner);

    // Ensure that all ghost elements are also copied as necessary.
    constraints.distribute (completely_distributed_solution);
    locally_relevant_solution = completely_distributed_solution;

    // Return the number of iterations (last step) of the solve.
    return solver_control.last_step ();
  }

  /**
   * Output results, ie., finite element functions and derived
   * quantitites for this cycle..
   */
  template <int dim>
  void
  FunctionTools<dim>::output_results (const unsigned int cycle)
  {
    dealii::TimerOutput::Scope time (timer, "output_results");

    dealii::DataOut<dim> data_out;
    data_out.attach_dof_handler (dof_handler);
    data_out.add_data_vector (locally_relevant_solution, "material");

    dealii::Vector<float> subdomain ((*triangulation).n_active_cells ());
    for (unsigned int i=0; i<subdomain.size(); ++i)
      subdomain (i) = (*triangulation).locally_owned_subdomain ();
    data_out.add_data_vector (subdomain, "subdomain");

    data_out.build_patches ();

    const std::string filename = ("material-" +
                                  dealii::Utilities::int_to_string (cycle, 2) +
                                  "." +
                                  dealii::Utilities::int_to_string
                                  ((*triangulation).locally_owned_subdomain (), 4));

    std::ofstream output ((filename + ".vtu").c_str ());
    data_out.write_vtu (output);

    if (dealii::Utilities::MPI::this_mpi_process(mpi_communicator) == 1)
      {
	std::vector<std::string> filenames;

	for (unsigned int i=0;
	     i<dealii::Utilities::MPI::n_mpi_processes (mpi_communicator);
	     ++i)
	  filenames.push_back ("material-" +
			       dealii::Utilities::int_to_string (cycle, 2) +
			       "." +
			       dealii::Utilities::int_to_string (i, 4) +
			       ".vtu");
	std::ofstream master_output (("material-" +
				      dealii::Utilities::int_to_string (cycle, 2) +
				      ".pvtu").c_str ());

	data_out.write_pvtu_record (master_output, filenames);
      }
  }

  /**
   * Refine grid based on Kelly's error estimator working on the
   * material id (solution vector).
   */
  template <int dim>
  void FunctionTools<dim>::refine_grid ()
  {
    dealii::TimerOutput::Scope time (timer, "refine grid");

    dealii::Vector<float> estimated_error_per_cell ((*triangulation).n_active_cells());

    dealii::KellyErrorEstimator<dim>::estimate (dof_handler, dealii::QGauss<dim-1>(4),
						typename dealii::FunctionMap<dim>::type (),
						locally_relevant_solution,
						estimated_error_per_cell);

    dealii::parallel::distributed::GridRefinement::
      refine_and_coarsen_fixed_number ((*triangulation),
				       estimated_error_per_cell,
				       0.250, 0.000);

    (*triangulation).execute_coarsening_and_refinement ();
  }

  /**
   * Run the application in the order specified.
   */
  template <int dim>
  void
  FunctionTools<dim>::run ()
  {
    const unsigned int n_cycles = 3;

    for (unsigned int cycle=0; cycle<n_cycles; ++cycle)
      {
        pcout << "FunctionTools:: Cycle " << cycle << ':'
	      << std::endl;

	if (cycle!=0)
	  refine_grid ();

	pcout << "   Number of active cells:       "
	      << (*triangulation).n_global_active_cells ()
	      << std::endl;

	setup_system ();

	pcout << "   Number of degrees of freedom: "
	      << dof_handler.n_dofs ()
	      << std::endl;

	assemble_system ();

	const unsigned int n_iterations = solve ();

	pcout << "   Solved in " << n_iterations
	      << " iterations."
	      << std::endl;

	pcout << "   Linfty-norm:                  "
	      << locally_relevant_solution.linfty_norm ()
	      << std::endl;

	// Output results if the number of processes is less than or
	// equal to 32.
	if (dealii::Utilities::MPI::n_mpi_processes (mpi_communicator) <= 32)
	  output_results (cycle);

	// timer.print_summary ();
        pcout << std::endl;

      } // for cycle<n_cycles
  }

} // namespace mandy

template class mandy::FunctionTools<3>;
<|endoftext|>


<commit_before>/*
 * Matcha Robotics Application Framework
 *
 * Copyright (C) 2011 Yusuke Suzuki
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
#ifndef MATCHA_MATH_MATRIX_HPP__
#define MATCHA_MATH_MATRIX_HPP__

#include <matcha/core/exception.hpp>

#include <matcha/math/types.hpp>
#include <matcha/math/scalar.hpp>

#include <cassert>
#include <memory>
#include <type_traits>
#include <typeinfo>
#include <utility>

namespace matcha { namespace math {

template<typename T>
T* ptr_cast_from_int8_t(void* ptr, size_t offset)
{
	return static_cast<T*> (
		static_cast<void*> ( static_cast<int8_t*>(ptr) + offset) );
}

struct matrix_header
{
	uint32_t rows;
	uint32_t cols;
	int32_t type;      ///< matcha::math::typeid
	uint32_t channels;
	uint32_t alignment; ///< data alignment. typically 0, 4, 8, 16.
	uint32_t row_size;
	uint64_t data_size;
};

inline bool operator==(const matrix_header& a, const matrix_header& b)
{
	return
		a.rows == b.rows &&
		a.cols == b.cols &&
		a.type == b.type &&
		a.channels == b.channels &&
		a.alignment == b.alignment &&
		a.row_size == b.row_size &&
		a.data_size == b.data_size;
}

inline bool operator!=(const matrix_header& a, const matrix_header& b)
{
	return !(a == b);
}

matrix_header create_matrix_header(
	uint32_t rows, uint32_t cols, type_id_t type, uint32_t channels);

typedef struct matrix_data
{
	matrix_header header;
	void* data;
}matrix_data;

class matrix_base
{
public:
	matrix_base(const matcha::math::matrix_header& header);
	matrix_base(matrix_base&& matrixBase);

	virtual ~matrix_base() noexcept;

	uint32_t rows() const noexcept;
	uint32_t cols() const noexcept;
	uint32_t channels() const noexcept;
	int32_t type() const noexcept;

	const matcha::math::matrix_header& header() const noexcept;
	matcha::math::matrix_header& header() noexcept;

	std::shared_ptr<matrix_data> data_;

private:
	matrix_base(const matrix_base& matrix_base_a);
	matrix_base& operator=(const matrix_base& matrix_base_a);
};

template<typename T>
class matrix
{
public:
	typedef T type;

	std::shared_ptr<matcha::math::matrix_data> matrix_data()
	{
		return base.data_;
	}

	const std::shared_ptr<matcha::math::matrix_data> matrix_data() const
	{
		return base.data_;
	}

public:
	matrix(uint32_t rows, uint32_t cols) :
		base_( create_matrix_header(rows, cols, type_id<T>(), 1) )
	{
	}

	matrix(uint32_t rows, uint32_t cols, uint32_t channels) :
		base_( create_matrix_header(rows, cols, type_id<T>(), channels) )
	{
	}

	~matrix() noexcept
	{
	};

	matrix(const matrix& m);

	matrix(matrix&& m) :
		base_( std::forward<matrix_base>(m.base_) )
	{
	}

	matrix(const matrix_base& base) :
		base_(base)
	{
	}

	matrix(matrix_base&& base) :
		base_( std::forward<matrix_base>(base) )
	{
	}

	matrix& operator=(const matrix& m);
	matrix& operator=(matrix&& m);

public:
	uint32_t rows() const noexcept
	{
		return base_.rows();
	}

	uint32_t cols() const noexcept
	{
		return base_.cols();
	}

	uint32_t channels() const noexcept
	{
		return base_.channels();
	}

	uint32_t width() const noexcept
	{
		return cols();
	}

	uint32_t height() const noexcept
	{
		return rows();
	}

	type get(uint32_t row, uint32_t col, uint32_t channel)
	{
		assert( (row < base_.data_->header.rows) && "row, out of range" );
		assert( (col < base_.data_->header.cols) && "col, out of range" );
		assert( (channel < base_.data_->header.channels) && "channel, out of range" );

		type* ptr =
			static_cast<type*>(
				static_cast<void*>(
					static_cast<int8_t*>(base_.data_->data) + base_.data_->header.row_size  * row +
					sizeof(type) * (base_.data_->header.channels * col + channel) ) );
		return *ptr;
	}

	void set(uint32_t row, uint32_t col, uint32_t channel, type value)
	{
		assert( (row < base_.data_->header.rows) && "row, out of range" );
		assert( (col < base_.data_->header.cols) && "col, out of range" );
		assert( (channel < base_.data_->header.channels) && "channel, out of range" );

		type* ptr =
			static_cast<type*>(
				static_cast<void*>(
					static_cast<int8_t*>(base_.data_->data) + base_.data_->header.row_size  * row +
					sizeof(type) * (base_.data_->header.channels * col + channel) ) );
		*ptr = value;
	}

	type& operator()(uint32_t row, uint32_t col, uint32_t channel = 0)
	{
		assert( (row < base_.data_->header.rows) && "row, out of range" );
		assert( (col < base_.data_->header.cols) && "col, out of range" );
		assert( (channel < base_.data_->header.channels) && "channel, out of range" );

		type* ptr =
			static_cast<type*>(
				static_cast<void*>(
					static_cast<int8_t*>(base_.data_->data) + base_.data_->header.row_size  * row +
					sizeof(type) * (base_.data_->header.channels * col + channel) ) );
		return *ptr;
	}

	const type& operator()(uint32_t row, uint32_t col, uint32_t channel = 0) const
	{
		assert( (row < base_.data_->header.rows) && "row, out of range" );
		assert( (col < base_.data_->header.cols) && "col, out of range" );
		assert( (channel < base_.data_->header.channels) && "channel, out of range" );

		type* ptr =
			static_cast<type*>(
				static_cast<void*>(
					static_cast<int8_t*>(base_.data_->data) + base_.data_->header.row_size  * row +
					sizeof(type) * (base_.data_->header.channels * col + channel) ) );
		return *ptr;
	}

	matrix<T>& swap_row(uint32_t row1, uint32_t row2)
	{
		assert( (row1 < base_.data_->header.rows) && "row, out of range" );
		assert( (row2 < base_.data_->header.rows) && "row, out of range" );

		const size_t row1_offset = base_.data_->header.row_size  * row1;
		const size_t row2_offset = base_.data_->header.row_size  * row2;

		for(uint32_t i = 0; i < base_.data_->header.cols; ++i)
		{
			for(uint32_t j = 0; j < base_.data_->header.channels; ++j)
			{
				const size_t col_offset =
					sizeof(type) * (base_.data_->header.channels * i + j);

				type* const ptr1 = ptr_cast_from_int8_t<type>(
						base_.data_->data, row1_offset + col_offset);
				type* const ptr2 = ptr_cast_from_int8_t<type>(
						base_.data_->data, row2_offset + col_offset);

				type temp = *ptr1;
				*ptr1 = *ptr2;
				*ptr2 = temp;

			}
		}

		return *this;
	}

	matrix<T>& swap_col(uint32_t col1, uint32_t col2)
	{
		assert( (col1 < base_.data_->header.cols) && "col, out of range" );
		assert( (col2 < base_.data_->header.cols) && "col, out of range" );

		const size_t col1_offset = sizeof(type) * base_.data_->header.channels * col1;
		const size_t col2_offset = sizeof(type) * base_.data_->header.channels * col2;
		const size_t row_size = sizeof(type) * base_.data_->header.rows;

		for(uint32_t i = 0; i < base_.data_->header.rows; ++i)
		{
			type* ptr1 = ptr_cast_from_int8_t<type>(
				base_.data_->data, row_size * i + col1_offset);
			type* ptr2 = ptr_cast_from_int8_t<type>(
				base_.data_->data, row_size * i + col2_offset);

			for(uint32_t j = 0; j < base_.data_->header.channels; ++j)
			{
				type temp = *(ptr1 + j);
				*(ptr1 + j) = *(ptr2 + j);
				*(ptr2 + j) = temp;

			}
		}

		return *this;
	}

	const matrix_base& base() const
	{
		return this->base_;
	}

	matrix_base& base()
	{
		return this->base_;
	}

private:
	matrix();

	matrix_base base_;
};

} // end of namespace math
} // end of namespace matcha

#endif
<commit_msg>add copy constructor<commit_after>/*
 * Matcha Robotics Application Framework
 *
 * Copyright (C) 2011 Yusuke Suzuki
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
#ifndef MATCHA_MATH_MATRIX_HPP__
#define MATCHA_MATH_MATRIX_HPP__

#include <matcha/core/exception.hpp>

#include <matcha/math/types.hpp>
#include <matcha/math/scalar.hpp>

#include <cassert>
#include <memory>
#include <type_traits>
#include <typeinfo>
#include <utility>

namespace matcha { namespace math {

template<typename T>
T* ptr_cast_from_int8_t(void* ptr, size_t offset)
{
	return static_cast<T*> (
		static_cast<void*> ( static_cast<int8_t*>(ptr) + offset) );
}

struct matrix_header
{
	uint32_t rows;
	uint32_t cols;
	int32_t type;      ///< matcha::math::typeid
	uint32_t channels;
	uint32_t alignment; ///< data alignment. typically 0, 4, 8, 16.
	uint32_t row_size;
	uint64_t data_size;
};

inline bool operator==(const matrix_header& a, const matrix_header& b)
{
	return
		a.rows == b.rows &&
		a.cols == b.cols &&
		a.type == b.type &&
		a.channels == b.channels &&
		a.alignment == b.alignment &&
		a.row_size == b.row_size &&
		a.data_size == b.data_size;
}

inline bool operator!=(const matrix_header& a, const matrix_header& b)
{
	return !(a == b);
}

matrix_header create_matrix_header(
	uint32_t rows, uint32_t cols, type_id_t type, uint32_t channels);

typedef struct matrix_data
{
	matrix_header header;
	void* data;
}matrix_data;

class matrix_base
{
public:
	matrix_base(const matcha::math::matrix_header& header);
	matrix_base(matrix_base&& matrixBase);
	matrix_base(const matrix_base& matrix_base_a);
	matrix_base& operator=(const matrix_base& matrix_base_a);

	virtual ~matrix_base() noexcept;

	uint32_t rows() const noexcept;
	uint32_t cols() const noexcept;
	uint32_t channels() const noexcept;
	int32_t type() const noexcept;

	const matcha::math::matrix_header& header() const noexcept;
	matcha::math::matrix_header& header() noexcept;

	std::shared_ptr<matrix_data> data_;

private:
};

template<typename T>
class matrix
{
public:
	typedef T type;

	std::shared_ptr<matcha::math::matrix_data> matrix_data()
	{
		return base.data_;
	}

	const std::shared_ptr<matcha::math::matrix_data> matrix_data() const
	{
		return base.data_;
	}

public:
	matrix(uint32_t rows, uint32_t cols) :
		base_( create_matrix_header(rows, cols, type_id<T>(), 1) )
	{
	}

	matrix(uint32_t rows, uint32_t cols, uint32_t channels) :
		base_( create_matrix_header(rows, cols, type_id<T>(), channels) )
	{
	}

	~matrix() noexcept
	{
	};

	matrix(const matrix& m) :
		base_(m.base_)
	{
	}

	matrix(matrix&& m) :
		base_( std::forward<matrix_base>(m.base_) )
	{
	}

	matrix(const matrix_base& base) :
		base_(base)
	{
	}

	matrix(matrix_base&& base) :
		base_( std::forward<matrix_base>(base) )
	{
	}

	matrix& operator=(const matrix& m);
	matrix& operator=(matrix&& m);

public:
	uint32_t rows() const noexcept
	{
		return base_.rows();
	}

	uint32_t cols() const noexcept
	{
		return base_.cols();
	}

	uint32_t channels() const noexcept
	{
		return base_.channels();
	}

	uint32_t width() const noexcept
	{
		return cols();
	}

	uint32_t height() const noexcept
	{
		return rows();
	}

	type get(uint32_t row, uint32_t col, uint32_t channel)
	{
		assert( (row < base_.data_->header.rows) && "row, out of range" );
		assert( (col < base_.data_->header.cols) && "col, out of range" );
		assert( (channel < base_.data_->header.channels) && "channel, out of range" );

		type* ptr =
			static_cast<type*>(
				static_cast<void*>(
					static_cast<int8_t*>(base_.data_->data) + base_.data_->header.row_size  * row +
					sizeof(type) * (base_.data_->header.channels * col + channel) ) );
		return *ptr;
	}

	void set(uint32_t row, uint32_t col, uint32_t channel, type value)
	{
		assert( (row < base_.data_->header.rows) && "row, out of range" );
		assert( (col < base_.data_->header.cols) && "col, out of range" );
		assert( (channel < base_.data_->header.channels) && "channel, out of range" );

		type* ptr =
			static_cast<type*>(
				static_cast<void*>(
					static_cast<int8_t*>(base_.data_->data) + base_.data_->header.row_size  * row +
					sizeof(type) * (base_.data_->header.channels * col + channel) ) );
		*ptr = value;
	}

	type& operator()(uint32_t row, uint32_t col, uint32_t channel = 0)
	{
		assert( (row < base_.data_->header.rows) && "row, out of range" );
		assert( (col < base_.data_->header.cols) && "col, out of range" );
		assert( (channel < base_.data_->header.channels) && "channel, out of range" );

		type* ptr =
			static_cast<type*>(
				static_cast<void*>(
					static_cast<int8_t*>(base_.data_->data) + base_.data_->header.row_size  * row +
					sizeof(type) * (base_.data_->header.channels * col + channel) ) );
		return *ptr;
	}

	const type& operator()(uint32_t row, uint32_t col, uint32_t channel = 0) const
	{
		assert( (row < base_.data_->header.rows) && "row, out of range" );
		assert( (col < base_.data_->header.cols) && "col, out of range" );
		assert( (channel < base_.data_->header.channels) && "channel, out of range" );

		type* ptr =
			static_cast<type*>(
				static_cast<void*>(
					static_cast<int8_t*>(base_.data_->data) + base_.data_->header.row_size  * row +
					sizeof(type) * (base_.data_->header.channels * col + channel) ) );
		return *ptr;
	}

	matrix<T>& swap_row(uint32_t row1, uint32_t row2)
	{
		assert( (row1 < base_.data_->header.rows) && "row, out of range" );
		assert( (row2 < base_.data_->header.rows) && "row, out of range" );

		const size_t row1_offset = base_.data_->header.row_size  * row1;
		const size_t row2_offset = base_.data_->header.row_size  * row2;

		for(uint32_t i = 0; i < base_.data_->header.cols; ++i)
		{
			for(uint32_t j = 0; j < base_.data_->header.channels; ++j)
			{
				const size_t col_offset =
					sizeof(type) * (base_.data_->header.channels * i + j);

				type* const ptr1 = ptr_cast_from_int8_t<type>(
						base_.data_->data, row1_offset + col_offset);
				type* const ptr2 = ptr_cast_from_int8_t<type>(
						base_.data_->data, row2_offset + col_offset);

				type temp = *ptr1;
				*ptr1 = *ptr2;
				*ptr2 = temp;

			}
		}

		return *this;
	}

	matrix<T>& swap_col(uint32_t col1, uint32_t col2)
	{
		assert( (col1 < base_.data_->header.cols) && "col, out of range" );
		assert( (col2 < base_.data_->header.cols) && "col, out of range" );

		const size_t col1_offset = sizeof(type) * base_.data_->header.channels * col1;
		const size_t col2_offset = sizeof(type) * base_.data_->header.channels * col2;
		const size_t row_size = sizeof(type) * base_.data_->header.rows;

		for(uint32_t i = 0; i < base_.data_->header.rows; ++i)
		{
			type* ptr1 = ptr_cast_from_int8_t<type>(
				base_.data_->data, row_size * i + col1_offset);
			type* ptr2 = ptr_cast_from_int8_t<type>(
				base_.data_->data, row_size * i + col2_offset);

			for(uint32_t j = 0; j < base_.data_->header.channels; ++j)
			{
				type temp = *(ptr1 + j);
				*(ptr1 + j) = *(ptr2 + j);
				*(ptr2 + j) = temp;

			}
		}

		return *this;
	}

	const matrix_base& base() const
	{
		return this->base_;
	}

	matrix_base& base()
	{
		return this->base_;
	}

private:
	matrix();

	matrix_base base_;
};

} // end of namespace math
} // end of namespace matcha

#endif
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/
#include <memory>

#include "gflags/gflags.h"
#include "gtest/gtest.h"

#include "cybertron/cybertron.h"

#include "modules/canbus/proto/chassis.pb.h"
#include "modules/localization/proto/localization.pb.h"
#include "modules/perception/proto/traffic_light_detection.pb.h"
#include "modules/prediction/proto/prediction_obstacle.pb.h"
#include "modules/routing/proto/routing.pb.h"

#include "modules/common/adapters/adapter_gflags.h"
#include "modules/common/util/file.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/planning_component.h"

namespace apollo {
namespace planning {

using apollo::cybertron::ComponentConfig;
using apollo::cybertron::Reader;
using apollo::cybertron::Writer;

using apollo::canbus::Chassis;
using apollo::common::time::Clock;
using apollo::localization::LocalizationEstimate;
using apollo::perception::TrafficLightDetection;
using apollo::planning::PlanningComponent;
using apollo::prediction::PredictionObstacles;
using apollo::routing::RoutingResponse;

DEFINE_string(test_data_dir, "", "the test data folder");
DEFINE_bool(test_update_golden_log, false,
            "true to update decision golden log file.");
DEFINE_string(test_routing_response_file, "", "The routing file used in test");
DEFINE_string(test_localization_file, "", "The localization test file");
DEFINE_string(test_chassis_file, "", "The chassis test file");
DEFINE_string(test_prediction_file, "", "The prediction module test file");
DEFINE_string(test_traffic_light_file, "", "The traffic light test file");

class PlanningComponentTest : public ::testing::Test {
 public:
  virtual void SetUp() {
    FLAGS_use_multi_thread_to_add_obstacles = false;
    FLAGS_enable_multi_thread_in_dp_poly_path = false;
    FLAGS_enable_multi_thread_in_dp_st_graph = false;
    FLAGS_planning_config_file =
        "/apollo/modules/planning/conf/planning_config.pb.txt";
    FLAGS_align_prediction_time = false;
    FLAGS_estimate_current_vehicle_state = false;
    FLAGS_enable_reference_line_provider_thread = false;
    FLAGS_planning_test_mode = true;
    // FLAGS_enable_lag_prediction = false;

    SetupCybertron();
  }

 protected:
  bool FeedTestData(LocalView* local_view);
  void SetupCybertron();
  bool RunPlanning(const std::string& test_case_name);
  void TrimPlanning(ADCTrajectory* origin);

 protected:
  bool is_cybertron_initialized_ = false;
  std::mutex mutex_;
  cybertron::ComponentConfig component_config_;

  // cybertron readers/writers
  std::shared_ptr<Writer<Chassis>> chassis_writer_;
  std::shared_ptr<Writer<LocalizationEstimate>> localization_writer_;
  std::shared_ptr<Writer<PredictionObstacles>> prediction_writer_;
  std::shared_ptr<Writer<RoutingResponse>> routing_response_writer_;
  std::shared_ptr<Writer<TrafficLightDetection>>
      traffic_light_detection_writer_;
  std::shared_ptr<Reader<ADCTrajectory>> planning_reader_;

  std::shared_ptr<PlanningComponent> planning_component_ = nullptr;
  ADCTrajectory adc_trajectory_;
};

void PlanningComponentTest::SetupCybertron() {
  if (is_cybertron_initialized_) {
    return;
  }

  // init cybertron framework
  apollo::cybertron::Init("planning_test");

  Clock::SetMode(Clock::CYBERTRON);

  component_config_.set_name("planning_test");
  // note: the sequence to add_readers() must be the same
  //       as what's in PlanningComponent::Proc()
  component_config_.add_readers()->set_channel(FLAGS_prediction_topic);
  component_config_.add_readers()->set_channel(FLAGS_chassis_topic);
  component_config_.add_readers()->set_channel(FLAGS_localization_topic);

  std::shared_ptr<apollo::cybertron::Node> node(
      apollo::cybertron::CreateNode("planning_test"));

  chassis_writer_ = node->CreateWriter<Chassis>(FLAGS_chassis_topic);
  localization_writer_ =
      node->CreateWriter<LocalizationEstimate>(FLAGS_localization_topic);
  prediction_writer_ =
      node->CreateWriter<PredictionObstacles>(FLAGS_prediction_topic);
  routing_response_writer_ =
      node->CreateWriter<RoutingResponse>(FLAGS_routing_response_topic);
  traffic_light_detection_writer_ = node->CreateWriter<TrafficLightDetection>(
      FLAGS_traffic_light_detection_topic);

  planning_reader_ = node->CreateReader<ADCTrajectory>(
      FLAGS_planning_trajectory_topic,
      [this](const std::shared_ptr<ADCTrajectory>& adc_trajectory) {
        ADEBUG << "Received planning data: run planning callback.";
        std::lock_guard<std::mutex> lock(mutex_);
        adc_trajectory_.CopyFrom(*adc_trajectory);
      });

  is_cybertron_initialized_ = true;
}

bool PlanningComponentTest::FeedTestData(LocalView* local_view) {
  // chassis
  Chassis chassis;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_chassis_file, &chassis)) {
    AERROR << "failed to load file: " << FLAGS_test_chassis_file;
    return false;
  }

  // localization
  LocalizationEstimate localization;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_localization_file,
          &localization)) {
    AERROR << "failed to load file: " << FLAGS_test_localization_file;
    return false;
  }

  // prediction
  PredictionObstacles prediction;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_prediction_file,
          &prediction)) {
    AERROR << "failed to load file: " << FLAGS_test_prediction_file;
    return false;
  }

  // routing_response
  RoutingResponse routing_response;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_routing_response_file,
          &routing_response)) {
    AERROR << "failed to load file: " << FLAGS_test_routing_response_file;
    return false;
  }

  // traffic_light_detection
  TrafficLightDetection traffic_light_detection;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_traffic_light_file,
          &traffic_light_detection)) {
    AERROR << "failed to load file: " << FLAGS_test_traffic_light_file;
    // return false;
  }

  local_view->chassis = std::make_shared<Chassis>(chassis);
  local_view->localization_estimate =
      std::make_shared<LocalizationEstimate>(localization);
  local_view->prediction_obstacles =
      std::make_shared<PredictionObstacles>(prediction);
  local_view->routing = std::make_shared<RoutingResponse>(routing_response);
  local_view->traffic_light =
      std::make_shared<TrafficLightDetection>(traffic_light_detection);

  AINFO << "Successfully feed proto files.";
  return true;
}

bool PlanningComponentTest::RunPlanning(const std::string& test_case_name) {
  LocalView local_view;
  CHECK(FeedTestData(&local_view)) << "Failed to feed test data";

  planning_component_.reset(new PlanningComponent());
  planning_component_->Initialize(component_config_);

  usleep(1000);  // sleep 1ms

  // feed topics
  routing_response_writer_->Write(local_view.routing);
  traffic_light_detection_writer_->Write(local_view.traffic_light);
  chassis_writer_->Write(local_view.chassis);
  localization_writer_->Write(local_view.localization_estimate);

  usleep(1000);  // sleep 1ms to resolve race condition

  // note: main channel must be written last
  prediction_writer_->Write(local_view.prediction_obstacles);

  usleep(200000);  // sleep 200ms

  TrimPlanning(&adc_trajectory_);

  const std::string golden_result_file =
      apollo::common::util::StrCat("result_", test_case_name, "_0.pb.txt");
  std::string full_golden_path = FLAGS_test_data_dir + "/" + golden_result_file;
  if (FLAGS_test_update_golden_log) {
    AINFO << "The golden file is regenerated:" << full_golden_path;
    common::util::SetProtoToASCIIFile(adc_trajectory_, full_golden_path);
  } else {
    ADCTrajectory golden_result;
    bool load_success =
        common::util::GetProtoFromASCIIFile(full_golden_path, &golden_result);
    TrimPlanning(&golden_result);
    if (!load_success ||
        !common::util::IsProtoEqual(golden_result, adc_trajectory_)) {
      char tmp_fname[100] = "/tmp/XXXXXX";
      int fd = mkstemp(tmp_fname);
      if (!common::util::SetProtoToASCIIFile(adc_trajectory_, fd)) {
        AERROR << "Failed to write to file " << tmp_fname;
      }
      AERROR << "found\ndiff " << tmp_fname << " " << full_golden_path;
      AERROR << "visualize diff\n/usr/bin/python "
                "modules/tools/plot_trace/plot_planning_result.py "
             << tmp_fname << " " << full_golden_path;
      return false;
    }
  }
  return true;
}

void PlanningComponentTest::TrimPlanning(ADCTrajectory* origin) {
  origin->clear_latency_stats();
  origin->clear_debug();
  origin->mutable_header()->clear_radar_timestamp();
  origin->mutable_header()->clear_lidar_timestamp();
  origin->mutable_header()->clear_timestamp_sec();
  origin->mutable_header()->clear_camera_timestamp();
  origin->mutable_header()->clear_sequence_num();
}

/*
 * test garage_test/stop_obstacle case, using the exact same test data
 */
TEST_F(PlanningComponentTest, garage_stop_obstacle) {
  FLAGS_test_data_dir = "modules/planning/testdata/garage_test";
  FLAGS_map_dir = "modules/planning/testdata/garage_map";
  FLAGS_base_map_filename = "base_map.txt";
  FLAGS_test_routing_response_file = "garage_routing.pb.txt";
  FLAGS_test_prediction_file = "stop_obstacle_prediction.pb.txt";
  FLAGS_test_localization_file = "stop_obstacle_localization.pb.txt";
  FLAGS_test_chassis_file = "stop_obstacle_chassis.pb.txt";
  FLAGS_enable_multi_thread_in_dp_poly_path = true;
  FLAGS_enable_multi_thread_in_dp_st_graph = true;

  bool run_planning_success = RunPlanning("planning_componnet_stop_obstacle");
  EXPECT_TRUE(run_planning_success);
}

}  // namespace planning
}  // namespace apollo
<commit_msg>planning: trivial fix in test<commit_after>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/
#include <memory>

#include "gflags/gflags.h"
#include "gtest/gtest.h"

#include "cybertron/cybertron.h"

#include "modules/canbus/proto/chassis.pb.h"
#include "modules/localization/proto/localization.pb.h"
#include "modules/perception/proto/traffic_light_detection.pb.h"
#include "modules/prediction/proto/prediction_obstacle.pb.h"
#include "modules/routing/proto/routing.pb.h"

#include "modules/common/adapters/adapter_gflags.h"
#include "modules/common/util/file.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/planning_component.h"

namespace apollo {
namespace planning {

using apollo::cybertron::ComponentConfig;
using apollo::cybertron::Reader;
using apollo::cybertron::Writer;

using apollo::canbus::Chassis;
using apollo::common::time::Clock;
using apollo::localization::LocalizationEstimate;
using apollo::perception::TrafficLightDetection;
using apollo::planning::PlanningComponent;
using apollo::prediction::PredictionObstacles;
using apollo::routing::RoutingResponse;

DEFINE_string(test_data_dir, "", "the test data folder");
DEFINE_bool(test_update_golden_log, false,
            "true to update decision golden log file.");
DEFINE_string(test_routing_response_file, "", "The routing file used in test");
DEFINE_string(test_localization_file, "", "The localization test file");
DEFINE_string(test_chassis_file, "", "The chassis test file");
DEFINE_string(test_prediction_file, "", "The prediction module test file");
DEFINE_string(test_traffic_light_file, "", "The traffic light test file");

class PlanningComponentTest : public ::testing::Test {
 public:
  virtual void SetUp() {
    FLAGS_use_multi_thread_to_add_obstacles = false;
    FLAGS_enable_multi_thread_in_dp_poly_path = false;
    FLAGS_enable_multi_thread_in_dp_st_graph = false;
    FLAGS_planning_config_file =
        "/apollo/modules/planning/conf/planning_config.pb.txt";
    FLAGS_align_prediction_time = false;
    FLAGS_estimate_current_vehicle_state = false;
    FLAGS_enable_reference_line_provider_thread = false;
    FLAGS_planning_test_mode = true;
    // FLAGS_enable_lag_prediction = false;

    SetupCybertron();
  }

 protected:
  bool FeedTestData(LocalView* local_view);
  void SetupCybertron();
  bool RunPlanning(const std::string& test_case_name);
  void TrimPlanning(ADCTrajectory* origin);

 protected:
  bool is_cybertron_initialized_ = false;
  std::mutex mutex_;
  cybertron::ComponentConfig component_config_;

  // cybertron readers/writers
  std::shared_ptr<Writer<Chassis>> chassis_writer_;
  std::shared_ptr<Writer<LocalizationEstimate>> localization_writer_;
  std::shared_ptr<Writer<PredictionObstacles>> prediction_writer_;
  std::shared_ptr<Writer<RoutingResponse>> routing_response_writer_;
  std::shared_ptr<Writer<TrafficLightDetection>>
      traffic_light_detection_writer_;
  std::shared_ptr<Reader<ADCTrajectory>> planning_reader_;

  std::shared_ptr<PlanningComponent> planning_component_ = nullptr;
  ADCTrajectory adc_trajectory_;
};

void PlanningComponentTest::SetupCybertron() {
  if (is_cybertron_initialized_) {
    return;
  }

  // init cybertron framework
  apollo::cybertron::Init("planning_test");

  Clock::SetMode(Clock::CYBERTRON);

  component_config_.set_name("planning_test");
  // note: the sequence to add_readers() must be the same
  //       as what's in PlanningComponent::Proc()
  component_config_.add_readers()->set_channel(FLAGS_prediction_topic);
  component_config_.add_readers()->set_channel(FLAGS_chassis_topic);
  component_config_.add_readers()->set_channel(FLAGS_localization_topic);

  std::shared_ptr<apollo::cybertron::Node> node(
      apollo::cybertron::CreateNode("planning_test"));

  chassis_writer_ = node->CreateWriter<Chassis>(FLAGS_chassis_topic);
  localization_writer_ =
      node->CreateWriter<LocalizationEstimate>(FLAGS_localization_topic);
  prediction_writer_ =
      node->CreateWriter<PredictionObstacles>(FLAGS_prediction_topic);
  routing_response_writer_ =
      node->CreateWriter<RoutingResponse>(FLAGS_routing_response_topic);
  traffic_light_detection_writer_ = node->CreateWriter<TrafficLightDetection>(
      FLAGS_traffic_light_detection_topic);

  planning_reader_ = node->CreateReader<ADCTrajectory>(
      FLAGS_planning_trajectory_topic,
      [this](const std::shared_ptr<ADCTrajectory>& adc_trajectory) {
        ADEBUG << "Received planning data: run planning callback.";
        std::lock_guard<std::mutex> lock(mutex_);
        adc_trajectory_.CopyFrom(*adc_trajectory);
      });

  is_cybertron_initialized_ = true;
}

bool PlanningComponentTest::FeedTestData(LocalView* local_view) {
  // chassis
  Chassis chassis;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_chassis_file, &chassis)) {
    AERROR << "failed to load file: " << FLAGS_test_chassis_file;
    return false;
  }

  // localization
  LocalizationEstimate localization;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_localization_file,
          &localization)) {
    AERROR << "failed to load file: " << FLAGS_test_localization_file;
    return false;
  }

  // prediction
  PredictionObstacles prediction;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_prediction_file,
          &prediction)) {
    AERROR << "failed to load file: " << FLAGS_test_prediction_file;
    return false;
  }

  // routing_response
  RoutingResponse routing_response;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_routing_response_file,
          &routing_response)) {
    AERROR << "failed to load file: " << FLAGS_test_routing_response_file;
    return false;
  }

  // traffic_light_detection
  TrafficLightDetection traffic_light_detection;
  if (!apollo::common::util::GetProtoFromFile(
          FLAGS_test_data_dir + "/" + FLAGS_test_traffic_light_file,
          &traffic_light_detection)) {
    AERROR << "failed to load file: " << FLAGS_test_traffic_light_file;
    return false;
  }

  local_view->chassis = std::make_shared<Chassis>(chassis);
  local_view->localization_estimate =
      std::make_shared<LocalizationEstimate>(localization);
  local_view->prediction_obstacles =
      std::make_shared<PredictionObstacles>(prediction);
  local_view->routing = std::make_shared<RoutingResponse>(routing_response);
  local_view->traffic_light =
      std::make_shared<TrafficLightDetection>(traffic_light_detection);

  AINFO << "Successfully feed proto files.";
  return true;
}

bool PlanningComponentTest::RunPlanning(const std::string& test_case_name) {
  LocalView local_view;
  CHECK(FeedTestData(&local_view)) << "Failed to feed test data";

  planning_component_.reset(new PlanningComponent());
  planning_component_->Initialize(component_config_);

  usleep(1000);  // sleep 1ms

  // feed topics
  routing_response_writer_->Write(local_view.routing);
  traffic_light_detection_writer_->Write(local_view.traffic_light);
  chassis_writer_->Write(local_view.chassis);
  localization_writer_->Write(local_view.localization_estimate);

  usleep(1000);  // sleep 1ms to resolve race condition

  // note: main channel must be written last
  prediction_writer_->Write(local_view.prediction_obstacles);

  usleep(200000);  // sleep 200ms

  TrimPlanning(&adc_trajectory_);

  const std::string golden_result_file =
      apollo::common::util::StrCat("result_", test_case_name, "_0.pb.txt");
  std::string full_golden_path = FLAGS_test_data_dir + "/" + golden_result_file;
  if (FLAGS_test_update_golden_log) {
    AINFO << "The golden file is regenerated:" << full_golden_path;
    common::util::SetProtoToASCIIFile(adc_trajectory_, full_golden_path);
  } else {
    ADCTrajectory golden_result;
    bool load_success =
        common::util::GetProtoFromASCIIFile(full_golden_path, &golden_result);
    TrimPlanning(&golden_result);
    if (!load_success ||
        !common::util::IsProtoEqual(golden_result, adc_trajectory_)) {
      char tmp_fname[100] = "/tmp/XXXXXX";
      int fd = mkstemp(tmp_fname);
      if (!common::util::SetProtoToASCIIFile(adc_trajectory_, fd)) {
        AERROR << "Failed to write to file " << tmp_fname;
      }
      AERROR << "found\ndiff " << tmp_fname << " " << full_golden_path;
      AERROR << "visualize diff\n/usr/bin/python "
                "modules/tools/plot_trace/plot_planning_result.py "
             << tmp_fname << " " << full_golden_path;
      return false;
    }
  }
  return true;
}

void PlanningComponentTest::TrimPlanning(ADCTrajectory* origin) {
  origin->clear_latency_stats();
  origin->clear_debug();
  origin->mutable_header()->clear_radar_timestamp();
  origin->mutable_header()->clear_lidar_timestamp();
  origin->mutable_header()->clear_timestamp_sec();
  origin->mutable_header()->clear_camera_timestamp();
  origin->mutable_header()->clear_sequence_num();
}

/*
 * test garage_test/stop_obstacle case, using the exact same test data
 */
TEST_F(PlanningComponentTest, garage_stop_obstacle) {
  FLAGS_test_data_dir = "modules/planning/testdata/garage_test";
  FLAGS_map_dir = "modules/planning/testdata/garage_map";
  FLAGS_base_map_filename = "base_map.txt";
  FLAGS_test_routing_response_file = "garage_routing.pb.txt";
  FLAGS_test_prediction_file = "stop_obstacle_prediction.pb.txt";
  FLAGS_test_localization_file = "stop_obstacle_localization.pb.txt";
  FLAGS_test_chassis_file = "stop_obstacle_chassis.pb.txt";
  FLAGS_enable_multi_thread_in_dp_poly_path = true;
  FLAGS_enable_multi_thread_in_dp_st_graph = true;

  bool run_planning_success = RunPlanning("planning_componnet_stop_obstacle");
  EXPECT_TRUE(run_planning_success);
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before>// Copyright 2013 Mirus Project

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//
// kernel.cpp - main source file + kernel entry point
//              we all have to begin somewhere, right?
//

#include <stdafx.hpp>
#include <boot/multiboot.hpp>
#include <boot/ramdisk.hpp>
#include <cpu/gdt.hpp>
#include <cpu/idt.hpp>
#include <cpu/isr.hpp>
#include <cpu/irq.hpp>
#include <system/process/task.hpp>
#include <system/syscall.hpp>
#include <hardware/serial.hpp>

namespace mirus
{
    extern "C" void test_func();

    // Memory size
    uint32_t memory_size = 0;
    uint32_t memory_size_m = 0;
    uint32_t min_mem = 512;

    // Memory map
    memory_map_t* mmap = nullptr;

    // Modules
    uint32_t mod_count = 0;
    module_t* mods = nullptr;

    //
    // kernel_main - our kernel entry point
    //
    extern "C" void kernel_main(multiboot_info_t* mbd, unsigned int magic)
    {
        // Print debug stub
        ktrace(trace_level::msg, "Mirus 0.3.6-dev\n\n");

        // Get avalible memory
        if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
            ktrace(trace_level::error,
                "Multiboot bootloader magic doesn't match!\n");

        // Retrieve number of multiboot modules
        mod_count = mbd->mods_count;

        // Verify if multiboot flags are ok to go
        if (mbd->flags & 1)
        {
            // Read header and assign
            ktrace(trace_level::msg, "Reading multiboot header\n");
            mmap = (memory_map_t*)mbd->mmap_addr;

            // Parse entries
            while ((unsigned int)mmap < (unsigned int)(mbd->mmap_addr) + mbd->mmap_length)
            {
                memory_size += mmap->length_low;
                mmap = (memory_map_t*)((unsigned int)mmap + mmap->size + sizeof(unsigned int));
            }

            // Get memory size in megabytes
            memory_size_m = ((memory_size / 1024) / 1024);

            ktrace(trace_level::msg,
                "Avalible memory: %dm\n",
                memory_size_m);
        }

        // Check for any modules, the only of which should be the ramdisk
        ktrace(trace_level::msg, "Trying to get ramdisk...\n");

        if (mod_count > 0)
        {
            kprintf("Loading ramdisk...");

            ktrace(trace_level::msg,
                "Modules found: %d\n",
                mod_count);

            uint32_t i = 0;
            for (i = 0, mods = (module_t*)mbd->mods_addr;
                i < mod_count;
                i++, mods++)
            {
                ktrace(trace_level::none, "==========\n");
                ktrace(trace_level::msg, "Module found: [%d:%d]\n",
                    mods->mod_start,
                    mods->mod_end);

                // load the ramdisk
                boot::parse_tar(mods->mod_start);
                kprintf("[ OK ]\n");

                ktrace(trace_level::none, "==========\n");
            }
        }
        else
        {
            ktrace(trace_level::msg, "No modules found.\n");
            kprintf("[ERROR]\n");
        }

        // Check for minimum memory size
        if (memory_size_m < min_mem)
            ktrace(trace_level::warn,
                "Memory is less than expected minimum\n");

        // Setup CPU
        cpu::gdt::install();
        cpu::idt::install();
        cpu::isr::install();
        cpu::irq::install();

        // Setup hardware
        screen::terminal::install();
        hardware::serial::install();

        // Print kernel information
        kprintf("Mirus [%d.%d.%d-dev]\n\n", BUILD_MAJOR, BUILD_MINOR, BUILD_REV);

        // Set up system calls
        system::init_syscalls();
        ktrace(trace_level::msg, "Installed system calls\n");
        kprintf("Installed system calls\n");

        // Enable interrupts
        asm volatile("sti");

        // Enter usermode
        system::enter_userspace();
        ktrace(trace_level::notice, "Entered usermode...\n");

        // Test system calls
        asm volatile("mov $0, %eax");
        asm volatile("mov $0, %ebx");
        asm volatile("mov $0, %ecx");
        asm volatile("mov $0, %edx");
        asm volatile("mov $0, %esi");
        asm volatile("mov $0, %edi");
        asm volatile("int $0x7F");
        // test_func();

        // YOU SHALL NOT PASS!!!!
        while (true);
    }
} // !namespace<commit_msg>Cleaned up kernel_main()<commit_after>// Copyright 2013 Mirus Project

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//
// kernel.cpp - main source file + kernel entry point
//              we all have to begin somewhere, right?
//

#include <stdafx.hpp>
#include <boot/multiboot.hpp>
#include <boot/ramdisk.hpp>
#include <cpu/gdt.hpp>
#include <cpu/idt.hpp>
#include <cpu/isr.hpp>
#include <cpu/irq.hpp>
#include <system/process/task.hpp>
#include <system/syscall.hpp>
#include <hardware/serial.hpp>

namespace mirus
{
    extern "C" void test_func();

    // Memory size
    uint32_t memory_size = 0;
    uint32_t memory_size_m = 0;
    uint32_t min_mem = 512;

    // Memory map
    memory_map_t* mmap = nullptr;

    // Modules
    uint32_t mod_count = 0;
    module_t* mods = nullptr;

    //
    // kernel_main - our kernel entry point
    //
    extern "C" void kernel_main(multiboot_info_t* mbd, unsigned int magic)
    {
        // Print debug stub
        ktrace(trace_level::msg, "Mirus 0.3.6-dev\n\n");

        // Get avalible memory
        if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
            ktrace(trace_level::error,
                "Multiboot bootloader magic doesn't match!\n");

        // Retrieve number of multiboot modules
        mod_count = mbd->mods_count;

        // Verify if multiboot flags are ok to go
        if (mbd->flags & 1)
        {
            // Read header and assign
            ktrace(trace_level::msg, "Reading multiboot header\n");
            mmap = (memory_map_t*)mbd->mmap_addr;

            // Parse entries
            while ((unsigned int)mmap < (unsigned int)(mbd->mmap_addr)
                + mbd->mmap_length)
            {
                memory_size += mmap->length_low;
                mmap = (memory_map_t*)((unsigned int)mmap + mmap->size
                    + sizeof(unsigned int));
            }

            // Get memory size in megabytes
            memory_size_m = ((memory_size / 1024) / 1024);
            ktrace(trace_level::msg, "Avalible memory: %dm\n", memory_size_m);
        }

        // Check for any modules, the only of which should be the ramdisk
        ktrace(trace_level::msg, "Trying to get ramdisk...\n");

        if (mod_count > 0)
        {
            kprintf("Loading ramdisk...");

            ktrace(trace_level::msg, "Modules found: %d\n", mod_count);

            uint32_t i = 0;
            for (i = 0, mods = (module_t*)mbd->mods_addr;
                i < mod_count;
                i++, mods++)
            {
                ktrace(trace_level::none, "==========\n");
                ktrace(trace_level::msg, "Module found: [%d:%d]\n",
                    mods->mod_start,
                    mods->mod_end);

                // load the ramdisk
                boot::parse_tar(mods->mod_start);
                kprintf("[ OK ]\n");

                ktrace(trace_level::none, "==========\n");
            }
        }
        else
        {
            ktrace(trace_level::msg, "No modules found.\n");
            kprintf("[ERROR]\n");
        }

        // Check for minimum memory size
        if (memory_size_m < min_mem)
            ktrace(trace_level::warn, "Memory is less than expected minimum\n");

        // Setup CPU
        cpu::gdt::install();
        cpu::idt::install();
        cpu::isr::install();
        cpu::irq::install();

        // Setup hardware
        screen::terminal::install();
        hardware::serial::install();

        // Print kernel information
        kprintf("Mirus [%d.%d.%d-dev]\n\n", BUILD_MAJOR, BUILD_MINOR, BUILD_REV);

        // Set up system calls
        system::init_syscalls();
        ktrace(trace_level::msg, "Installed system calls\n");
        kprintf("Installed system calls\n");

        // Enable interrupts
        asm volatile("sti");

        // Enter usermode
        system::enter_userspace();
        ktrace(trace_level::notice, "Entered usermode...\n");

        // Test system calls
        asm volatile("mov $0, %eax");
        asm volatile("mov $0, %ebx");
        asm volatile("mov $0, %ecx");
        asm volatile("mov $0, %edx");
        asm volatile("mov $0, %esi");
        asm volatile("mov $0, %edi");
        asm volatile("int $0x7F");
        // test_func();

        // YOU SHALL NOT PASS!!!!
        while (true);
    }
} // !namespace<|endoftext|>


<commit_before>/****************** <VPR heading BEGIN do not edit this line> *****************
 *
 * VR Juggler Portable Runtime
 *
 * Original Authors:
 *   Allen Bierbaum, Patrick Hartling, Kevin Meinert, Carolina Cruz-Neira
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 ****************** <VPR heading END do not edit this line> ******************/

/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998-2003 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

#include <vpr/vprConfig.h>

#include <iomanip>
#include <algorithm>
#include <boost/filesystem/exception.hpp>
#include <boost/filesystem/operations.hpp>

#include <vpr/Util/Debug.h>
#include <vpr/Util/Assert.h>
#include <vpr/DynLoad/Library.h>

#include <vpr/DynLoad/LibraryLoader.h>

namespace vpr
{

#ifdef VPR_DEBUG
static const std::string DSO_NAME_EXT("_d");
#else
static const std::string DSO_NAME_EXT("");
#endif

#if defined(VPR_OS_Win32)
static const std::string PATH_SEP("\\");
static const std::string DSO_FILE_EXT(".dll");
#else
static const std::string PATH_SEP("/");

#  if defined(VPR_OS_Darwin)
static const std::string DSO_FILE_EXT(".dylib");
#  else
static const std::string DSO_FILE_EXT(".so");
#  endif
#endif

LibraryLoader::~LibraryLoader()
{
   for ( dso_list_t::iterator i = mLoadedLibs.begin(); i != mLoadedLibs.end(); ++i )
   {
      (*i)->unload();
   }
}

vpr::ReturnStatus LibraryLoader::findAndInitDSO(const std::string& dsoBaseName,
                                                const std::vector<std::string>& searchPath,
                                                const std::string& initFuncName,
                                                boost::function1<bool, void*> initFunc)
{
   vpr::ReturnStatus status;
   bool load_attempted(false);

   const std::string dso_name = dsoBaseName + DSO_NAME_EXT + DSO_FILE_EXT;

   for ( std::vector<std::string>::const_iterator i = searchPath.begin();
         i != searchPath.end();
         ++i )
   {
      std::string temp_name = *i + PATH_SEP + dso_name;

      vprDEBUG(vprDBG_ALL, vprDBG_VERB_LVL)
         << "vpr::LibraryLoader::findAndInitDSO(): Looking for '"
         << temp_name << "'\n" << vprDEBUG_FLUSH;

      try
      {
         if ( boost::filesystem::exists(temp_name) )
         {
            // If any part of the driver loading fails, the object
            // dsowill go out of scope at the end of this block, thereby
            // freeing the allocated memory.
            vpr::LibraryPtr dso =
               vpr::LibraryPtr(new vpr::Library(temp_name));
            status = this->loadAndInitDSO(dso, initFuncName, initFunc);
            load_attempted = true;
            break;
         }
      }
      catch (boost::filesystem::filesystem_error& fsEx)
      {
         vprDEBUG(vprDBG_ERROR, vprDBG_CRITICAL_LVL)
            << clrOutNORM(clrRED, "ERROR:")
            << " File system exception caught: " << fsEx.what()
            << std::endl << vprDEBUG_FLUSH;
      }
   }

   // If no load was attempted, that means that dso_name does not exist
   // in searchPath.  We'll give it one last shot here using whatever
   // features the run-time loader has for searching on its own.
   if ( ! load_attempted )
   {
      vprDEBUG(vprDBG_ALL, vprDBG_STATE_LVL)
         << "vpr::LibraryLoader::findAndInitDSO(): Falling back on run-time loader search for '"
         << dso_name << "'\n" << vprDEBUG_FLUSH;
      vpr::LibraryPtr dso = vpr::LibraryPtr(new vpr::Library(dso_name));
      status = this->loadAndInitDSO(dso, initFuncName, initFunc);
   }

   return status;
}

vpr::ReturnStatus LibraryLoader::loadAndInitDSO(vpr::LibraryPtr dso,
                                                const std::string& initFuncName,
                                                boost::function1<bool, void*> initFunc)
{
   vprASSERT(dso.get() != NULL && "Invalid vpr::LibraryPtr object");

   const int lib_name_width(50);

   vprDEBUG(vprDBG_ALL, vprDBG_CONFIG_STATUS_LVL)
      << "Loading library: " << std::setiosflags(std::ios::right)
      << std::setfill(' ') << std::setw(lib_name_width) << dso->getName()
      << std::resetiosflags(std::ios::right) << "     " << vprDEBUG_FLUSH;

   // Load the DSO.
   vpr::ReturnStatus status = dso->load();

   if ( status.success() )
   {
      vprDEBUG(vprDBG_ALL, vprDBG_STATE_LVL)
         << "Loaded DSO successfully.\n" << vprDEBUG_FLUSH;

      // Look up the DSO's init function and store it in the pointer
      // called "creator."
      void* creator = dso->findSymbol(initFuncName);

      if ( NULL != creator )
      {
         vprDEBUG_CONT(vprDBG_ALL, vprDBG_CONFIG_STATUS_LVL)
            << "[ " << clrSetNORM(clrGREEN) << "OK" << clrRESET << " ]\n"
            << vprDEBUG_FLUSH;
         vprDEBUG(vprDBG_ALL, vprDBG_STATE_LVL)
            << "Got pointer to DSO initialization function.\n"
            << vprDEBUG_FLUSH;

         // XXX: This is a pretty lame way of managing the loaded DSOs.
         mLoadedLibs.push_back(dso);

         // Use the caller-provided callback function to initialize the
         // DSO.  It is up to this function to cast creator to the
         // desired type and do the cool stuff with it.
         if ( ! initFunc(creator) )
         {
            status.setCode(vpr::ReturnStatus::Fail);
         }
      }
      else
      {
         vprDEBUG_CONT(vprDBG_ALL, vprDBG_CONFIG_LVL)
            << "[ " << clrSetNORM(clrRED) << "FAILED lookup" << clrRESET
            << " ]\n" << vprDEBUG_FLUSH;
         vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
            << clrOutNORM(clrYELLOW, "WARNING")
            << ": Failed to look up initialization function '"
            << initFuncName << "' in DSO '" << dso << "'\n"
            << vprDEBUG_FLUSH;
         status.setCode(vpr::ReturnStatus::Fail);
      }
   }
   else
   {
      vprDEBUG_CONT(vprDBG_ALL, vprDBG_CONFIG_LVL)
         << "[ " << clrSetNORM(clrRED) << "FAILED" << clrRESET << " ]\n"
         << vprDEBUG_FLUSH;
   }

   return status;
}

vpr::ReturnStatus LibraryLoader::unloadDSO(vpr::LibraryPtr dso)
{
   vpr::ReturnStatus status = dso->unload();

   if ( status.success() )
   {
      dso_list_t::iterator i =
         std::find(mLoadedLibs.begin(), mLoadedLibs.end(), dso);

      if ( i != mLoadedLibs.end() )
      {
         mLoadedLibs.erase(i);
      }
   }

   return status;
}

}
<commit_msg>When searching for plug-ins, use a boost::filesystem::path object to hold the temporary plug-in name.  This allows the use of native paths, which is particularly important on Windows where the Boost FS path grammar does not allow drive letters in path names by default.<commit_after>/****************** <VPR heading BEGIN do not edit this line> *****************
 *
 * VR Juggler Portable Runtime
 *
 * Original Authors:
 *   Allen Bierbaum, Patrick Hartling, Kevin Meinert, Carolina Cruz-Neira
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 ****************** <VPR heading END do not edit this line> ******************/

/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998-2003 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

#include <vpr/vprConfig.h>

#include <iomanip>
#include <algorithm>
#include <boost/filesystem/exception.hpp>
#include <boost/filesystem/operations.hpp>

#include <vpr/Util/Debug.h>
#include <vpr/Util/Assert.h>
#include <vpr/DynLoad/Library.h>

#include <vpr/DynLoad/LibraryLoader.h>

namespace vpr
{

#ifdef VPR_DEBUG
static const std::string DSO_NAME_EXT("_d");
#else
static const std::string DSO_NAME_EXT("");
#endif

#if defined(VPR_OS_Win32)
static const std::string PATH_SEP("\\");
static const std::string DSO_FILE_EXT(".dll");
#else
static const std::string PATH_SEP("/");

#  if defined(VPR_OS_Darwin)
static const std::string DSO_FILE_EXT(".dylib");
#  else
static const std::string DSO_FILE_EXT(".so");
#  endif
#endif

LibraryLoader::~LibraryLoader()
{
   for ( dso_list_t::iterator i = mLoadedLibs.begin(); i != mLoadedLibs.end(); ++i )
   {
      (*i)->unload();
   }
}

vpr::ReturnStatus LibraryLoader::findAndInitDSO(const std::string& dsoBaseName,
                                                const std::vector<std::string>& searchPath,
                                                const std::string& initFuncName,
                                                boost::function1<bool, void*> initFunc)
{
   vpr::ReturnStatus status;
   bool load_attempted(false);

   const std::string dso_name = dsoBaseName + DSO_NAME_EXT + DSO_FILE_EXT;

   for ( std::vector<std::string>::const_iterator i = searchPath.begin();
         i != searchPath.end();
         ++i )
   {
      std::string temp_name = *i + PATH_SEP + dso_name;

      vprDEBUG(vprDBG_ALL, vprDBG_VERB_LVL)
         << "vpr::LibraryLoader::findAndInitDSO(): Looking for '"
         << temp_name << "'\n" << vprDEBUG_FLUSH;

      try
      {
         // Use a Boost FS path object here so that we can indicate that
         // native path names are allowed.
         boost::filesystem::path temp_path =
            boost::filesystem::path(temp_name, boost::filesystem::native);

         if ( boost::filesystem::exists(temp_path) )
         {
            // If any part of the driver loading fails, the object
            // dsowill go out of scope at the end of this block, thereby
            // freeing the allocated memory.
            vpr::LibraryPtr dso =
               vpr::LibraryPtr(new vpr::Library(temp_name));
            status = this->loadAndInitDSO(dso, initFuncName, initFunc);
            load_attempted = true;
            break;
         }
      }
      catch (boost::filesystem::filesystem_error& fsEx)
      {
         vprDEBUG(vprDBG_ERROR, vprDBG_CRITICAL_LVL)
            << clrOutNORM(clrRED, "ERROR:")
            << " File system exception caught: " << fsEx.what()
            << std::endl << vprDEBUG_FLUSH;
      }
   }

   // If no load was attempted, that means that dso_name does not exist
   // in searchPath.  We'll give it one last shot here using whatever
   // features the run-time loader has for searching on its own.
   if ( ! load_attempted )
   {
      vprDEBUG(vprDBG_ALL, vprDBG_STATE_LVL)
         << "vpr::LibraryLoader::findAndInitDSO(): Falling back on run-time loader search for '"
         << dso_name << "'\n" << vprDEBUG_FLUSH;
      vpr::LibraryPtr dso = vpr::LibraryPtr(new vpr::Library(dso_name));
      status = this->loadAndInitDSO(dso, initFuncName, initFunc);
   }

   return status;
}

vpr::ReturnStatus LibraryLoader::loadAndInitDSO(vpr::LibraryPtr dso,
                                                const std::string& initFuncName,
                                                boost::function1<bool, void*> initFunc)
{
   vprASSERT(dso.get() != NULL && "Invalid vpr::LibraryPtr object");

   const int lib_name_width(50);

   vprDEBUG(vprDBG_ALL, vprDBG_CONFIG_STATUS_LVL)
      << "Loading library: " << std::setiosflags(std::ios::right)
      << std::setfill(' ') << std::setw(lib_name_width) << dso->getName()
      << std::resetiosflags(std::ios::right) << "     " << vprDEBUG_FLUSH;

   // Load the DSO.
   vpr::ReturnStatus status = dso->load();

   if ( status.success() )
   {
      vprDEBUG(vprDBG_ALL, vprDBG_STATE_LVL)
         << "Loaded DSO successfully.\n" << vprDEBUG_FLUSH;

      // Look up the DSO's init function and store it in the pointer
      // called "creator."
      void* creator = dso->findSymbol(initFuncName);

      if ( NULL != creator )
      {
         vprDEBUG_CONT(vprDBG_ALL, vprDBG_CONFIG_STATUS_LVL)
            << "[ " << clrSetNORM(clrGREEN) << "OK" << clrRESET << " ]\n"
            << vprDEBUG_FLUSH;
         vprDEBUG(vprDBG_ALL, vprDBG_STATE_LVL)
            << "Got pointer to DSO initialization function.\n"
            << vprDEBUG_FLUSH;

         // XXX: This is a pretty lame way of managing the loaded DSOs.
         mLoadedLibs.push_back(dso);

         // Use the caller-provided callback function to initialize the
         // DSO.  It is up to this function to cast creator to the
         // desired type and do the cool stuff with it.
         if ( ! initFunc(creator) )
         {
            status.setCode(vpr::ReturnStatus::Fail);
         }
      }
      else
      {
         vprDEBUG_CONT(vprDBG_ALL, vprDBG_CONFIG_LVL)
            << "[ " << clrSetNORM(clrRED) << "FAILED lookup" << clrRESET
            << " ]\n" << vprDEBUG_FLUSH;
         vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
            << clrOutNORM(clrYELLOW, "WARNING")
            << ": Failed to look up initialization function '"
            << initFuncName << "' in DSO '" << dso << "'\n"
            << vprDEBUG_FLUSH;
         status.setCode(vpr::ReturnStatus::Fail);
      }
   }
   else
   {
      vprDEBUG_CONT(vprDBG_ALL, vprDBG_CONFIG_LVL)
         << "[ " << clrSetNORM(clrRED) << "FAILED" << clrRESET << " ]\n"
         << vprDEBUG_FLUSH;
   }

   return status;
}

vpr::ReturnStatus LibraryLoader::unloadDSO(vpr::LibraryPtr dso)
{
   vpr::ReturnStatus status = dso->unload();

   if ( status.success() )
   {
      dso_list_t::iterator i =
         std::find(mLoadedLibs.begin(), mLoadedLibs.end(), dso);

      if ( i != mLoadedLibs.end() )
      {
         mLoadedLibs.erase(i);
      }
   }

   return status;
}

}
<|endoftext|>