<commit_before>//
// PROJECT CHRONO - http://projectchrono.org
//
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file at the top level of the distribution
// and at http://projectchrono.org/license-chrono.txt.
//
///////////////////////////////////////////////////
//
//   A tracked vehicle, M113, built and simulated using the trackedVehicle library.
//   Build the vehicle using a hierarchy of subsystems.
//   Simulate by GUI input to an irrlicht EventReceiver.
//   Y-up, X-forward, Z-lateral global c-sys
//    - similar to demo_tracks:
//     - model track shoes with simple or complex collision geometry
//     - using clones of collision shapes
//     - use  SetFamilyMaskNoCollisionWithFamily, SetFamily etc., to avoid collisions between different families of bodies.
//
//	 Author: Justin Madsen, 2014
///////////////////////////////////////////////////

#include "physics/ChSystem.h"
// #include "particlefactory/ChParticleEmitter.h"

#include "core/ChFileutils.h"
#include "core/ChStream.h"
#include "core/ChRealtimeStep.h"
#include "physics/ChSystem.h"
#include "physics/ChLinkDistance.h"
#include "physics/ChBodyEasy.h"

#include "utils/ChUtilsInputOutput.h"
#include "utils/ChUtilsData.h"
#include "assets/ChTexture.h"
#include "assets/ChColorAsset.h"
/*
#if IRRLICHT_ENABLED
*/
#include "unit_IRRLICHT/ChIrrApp.h"
#include "subsys/driver/ChIrrGuiTrack.h"
 /*
 # define USE_IRRLICHT
#endif
 */
#include "subsys/trackVehicle/trackVehicle.h"
#include "ModelDefs.h"
// Use the main namespace of Chrono
using namespace chrono;

// Use the main namespaces of Irrlicht
using namespace irr;
using namespace core;

// =============================================================================
// User Settings
// =============================================================================
// display the 1) system heirarchy, 2) a set of subsystem hardpoints, 3) constraint violations
// #define DEBUG_LOG

// Initial vehicle position and heading. Defines the REF frame for the hull body
ChVector<> initLoc(0, 1.0, 0);
ChQuaternion<> initRot(1, 0, 0, 0);

// flat ground size and COG location
ChVector<> groundSize(60.0, 1.0, 100.0);
ChVector<> groundPos(0, -1.0, 0);
double mu = 0.8;  // dry friction coef.

// Simulation step size
double step_size = 0.001;

// Time interval between two render frames
int FPS = 50;
double render_step_size = 1.0 / FPS;   // FPS = 50
// Time interval between two output frames
double output_step_size = 1.0 / 1;    // once a second

// #ifdef USE_IRRLICHT
  // Point on chassis tracked by the camera
ChVector<> chaseDist(2.0, 0, 3.0);
ChVector<> trackPoint(0, 0, 0);
  /*
#else
  double tend = 20.0;

  const std::string out_dir = "../HMMWV9";
  const std::string pov_dir = out_dir + "/POVRAY";
#endif
  */

/// the ground body, visual assets and collision shape.
ChSharedPtr<ChBody> Add_FlatGround(TrackVehicle* vehicle,
                    const ChVector<>& size,
                    const ChVector<>& pos,
                    double friction_mu)
{
  // body, visual and collision all in one.
  ChSharedPtr<ChBody> ground(new ChBodyEasyBox(size.x, size.y, size.z, 1000.0, true, true));
  ground->SetPos(pos);
	// ground->SetIdentifier(-1);
  ground->SetName("ground");
  ground->SetFriction(friction_mu);

  // Don't forget to set this collision family!
  ground->GetCollisionModel()->SetFamily((int)CollisionFam::GROUND);

  // color asset for the ground
  ChSharedPtr<ChColorAsset> groundColor(new ChColorAsset);
  groundColor->SetColor(ChColor(0.2f, 0.4f, 0.6f));
  ground->AddAsset(groundColor);

  vehicle->Add(ground);  // add this body to the system, which is the vehicle

  return ground;
}

int main(int argc, char* argv[])
{
  // --------------------------
  // Create the tracked vehicle and the ground/environment

  // The vehicle inherits ChSystem. Input chassis visual and collision type
	TrackVehicle vehicle("Justins M113 model",
    VisualizationType::MESH,
    CollisionType::PRIMITIVES);

  // set the chassis REF at the specified initial config.
  vehicle.Initialize(ChCoordsys<>(initLoc, initRot));

  // ground is a large flat plate
  // TODO: superimposed obstacles using ChParticleEmitter class.
  ChSharedPtr<ChBody> ground = Add_FlatGround(&vehicle, groundSize, groundPos, mu);

  // --------------------------
  // Setup the Irrlicht GUI

/*
#ifdef USE_IRRLICHT
*/
	// Create the Irrlicht visualization applicaiton
  ChIrrApp application(&vehicle,
                      L"M113 tracked vehicle demo",
                      dimension2d<u32>(1000, 800),
                      false,
                      true);
  // assumes Y-up
  application.AddTypicalSky();
  /*
  // a skybox that has Z pointing up (default application.AddTypicalSky() makes Y up)
  std::string mtexturedir = GetChronoDataFile("skybox/");
  std::string str_lf = mtexturedir + "sky_lf.jpg";
  std::string str_up = mtexturedir + "sky_up.jpg";
  std::string str_dn = mtexturedir + "sky_dn.jpg";
  irr::video::ITexture* map_skybox_side =
      application.GetVideoDriver()->getTexture(str_lf.c_str());
  irr::scene::ISceneNode* mbox = application.GetSceneManager()->addSkyBoxSceneNode(
      application.GetVideoDriver()->getTexture(str_up.c_str()),
      application.GetVideoDriver()->getTexture(str_dn.c_str()),
      map_skybox_side,
      map_skybox_side,
      map_skybox_side,
      map_skybox_side);
  mbox->setRotation( irr::core::vector3df(90,0,0));  // rotate skybox for z-up
  */

  bool do_shadows = true; // shadow map is experimental
  irr::scene::ILightSceneNode* mlight = 0;

  if (do_shadows)
  {
    mlight = application.AddLightWithShadow(
      irr::core::vector3df(10.f, 60.f, 30.f),
      irr::core::vector3df(0.f, 0.f, 0.f),
      150, 60, 80, 15, 512, irr::video::SColorf(1, 1, 1), false, false);
  }
  else
  {
    application.AddTypicalLights(
      irr::core::vector3df(30.f, 100.f, 30.f),
      irr::core::vector3df(30.f, 100.f, 50.f),
      250, 130);
  }

  application.SetTimestep(step_size);

  // the GUI driver
  ChIrrGuiTrack driver(application, vehicle, trackPoint, chaseDist.x, chaseDist.y, chaseDist.z);

  // Set the time response for steering and throttle keyboard inputs.
  // NOTE: this is not exact, since we do not render quite at the specified FPS.
  double steering_time = 1.0;  // time to go from 0 to +1 (or from 0 to -1)
  double throttle_time = 1.0;  // time to go from 0 to +1
  double braking_time = 0.3;  // time to go from 0 to +1
  driver.SetSteeringDelta(render_step_size / steering_time);
  driver.SetThrottleDelta(render_step_size / throttle_time);
  driver.SetBrakingDelta(render_step_size / braking_time);

  // Set up the assets for rendering
  application.AssetBindAll();
  application.AssetUpdateAll();
  if (do_shadows)
  {
    application.AddShadowAll();
  }

  // ---------------------
  // GUI and render settings

  // GUI driver inputs
  std::vector<double> throttle_input;
  std::vector<double> braking_input;
  double steering_input;

  // Number of simulation steps between two 3D view render frames
  int render_steps = (int)std::ceil(render_step_size / step_size);

  // Number of simulation steps between two output frames
  int output_steps = (int)std::ceil(output_step_size / step_size);

  // ---------------------
  // Simulation loop
#ifdef DEBUG_LOG
  GetLog() << "\n\n============ System Configuration ============\n";
  vehicle.ShowHierarchy(GetLog() );
#endif

  // Initialize simulation frame counter and simulation time
  int step_number = 0;
  double time = 0;
  ChRealtimeStepTimer realtime_timer;
  while (application.GetDevice()->run())
	{
		// keep track of the time spent calculating each sim step
    ChTimer<double> step_time;
    step_time.start();

    // Render scene
    if (step_number % render_steps == 0) {
      application.GetVideoDriver()->beginScene(true, true, irr::video::SColor(255, 140, 161, 192));
      driver.DrawAll();
      application.GetVideoDriver()->endScene();
    }

    // Collect output data from modules (for inter-module communication)
    throttle_input = driver.GetThrottle();
    steering_input = driver.GetSteering();
    braking_input = driver.GetBraking();

    // Update
    time = vehicle.GetChTime();

    driver.Update(time);

    vehicle.Update(time, throttle_input, braking_input);
    // Advance simulation for one timestep for all modules
    double step = realtime_timer.SuggestSimulationStep(step_size);

    driver.Advance(step);

    vehicle.Advance(step);

	}

	return 0;
}

<commit_msg>stick to primitives for the hull geometry visuals<commit_after>//
// PROJECT CHRONO - http://projectchrono.org
//
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file at the top level of the distribution
// and at http://projectchrono.org/license-chrono.txt.
//
///////////////////////////////////////////////////
//
//   A tracked vehicle, M113, built and simulated using the trackedVehicle library.
//   Build the vehicle using a hierarchy of subsystems.
//   Simulate by GUI input to an irrlicht EventReceiver.
//   Y-up, X-forward, Z-lateral global c-sys
//    - similar to demo_tracks:
//     - model track shoes with simple or complex collision geometry
//     - using clones of collision shapes
//     - use  SetFamilyMaskNoCollisionWithFamily, SetFamily etc., to avoid collisions between different families of bodies.
//
//	 Author: Justin Madsen, 2014
///////////////////////////////////////////////////

#include "physics/ChSystem.h"
// #include "particlefactory/ChParticleEmitter.h"

#include "core/ChFileutils.h"
#include "core/ChStream.h"
#include "core/ChRealtimeStep.h"
#include "physics/ChSystem.h"
#include "physics/ChLinkDistance.h"
#include "physics/ChBodyEasy.h"

#include "utils/ChUtilsInputOutput.h"
#include "utils/ChUtilsData.h"
#include "assets/ChTexture.h"
#include "assets/ChColorAsset.h"
/*
#if IRRLICHT_ENABLED
*/
#include "unit_IRRLICHT/ChIrrApp.h"
#include "subsys/driver/ChIrrGuiTrack.h"
 /*
 # define USE_IRRLICHT
#endif
 */
#include "subsys/trackVehicle/trackVehicle.h"
#include "ModelDefs.h"
// Use the main namespace of Chrono
using namespace chrono;

// Use the main namespaces of Irrlicht
using namespace irr;
using namespace core;

// =============================================================================
// User Settings
// =============================================================================
// display the 1) system heirarchy, 2) a set of subsystem hardpoints, 3) constraint violations
// #define DEBUG_LOG

// Initial vehicle position and heading. Defines the REF frame for the hull body
ChVector<> initLoc(0, 1.0, 0);
ChQuaternion<> initRot(1, 0, 0, 0);

// flat ground size and COG location
ChVector<> groundSize(60.0, 1.0, 100.0);
ChVector<> groundPos(0, -1.0, 0);
double mu = 0.8;  // dry friction coef.

// Simulation step size
double step_size = 0.001;

// Time interval between two render frames
int FPS = 50;
double render_step_size = 1.0 / FPS;   // FPS = 50
// Time interval between two output frames
double output_step_size = 1.0 / 1;    // once a second

// #ifdef USE_IRRLICHT
  // Point on chassis tracked by the camera
ChVector<> chaseDist(2.0, 0, 3.0);
ChVector<> trackPoint(0, 0, 0);
  /*
#else
  double tend = 20.0;

  const std::string out_dir = "../HMMWV9";
  const std::string pov_dir = out_dir + "/POVRAY";
#endif
  */

/// the ground body, visual assets and collision shape.
ChSharedPtr<ChBody> Add_FlatGround(TrackVehicle* vehicle,
                    const ChVector<>& size,
                    const ChVector<>& pos,
                    double friction_mu)
{
  // body, visual and collision all in one.
  ChSharedPtr<ChBody> ground(new ChBodyEasyBox(size.x, size.y, size.z, 1000.0, true, true));
  ground->SetPos(pos);
	// ground->SetIdentifier(-1);
  ground->SetName("ground");
  ground->SetFriction(friction_mu);

  // Don't forget to set this collision family!
  ground->GetCollisionModel()->SetFamily((int)CollisionFam::GROUND);

  // color asset for the ground
  ChSharedPtr<ChColorAsset> groundColor(new ChColorAsset);
  groundColor->SetColor(ChColor(0.2f, 0.4f, 0.6f));
  ground->AddAsset(groundColor);

  vehicle->Add(ground);  // add this body to the system, which is the vehicle

  return ground;
}

int main(int argc, char* argv[])
{
  // --------------------------
  // Create the tracked vehicle and the ground/environment

  // The vehicle inherits ChSystem. Input chassis visual and collision type
	TrackVehicle vehicle("Justins M113 model",
    VisualizationType::PRIMITIVES,
    CollisionType::PRIMITIVES);

  // set the chassis REF at the specified initial config.
  vehicle.Initialize(ChCoordsys<>(initLoc, initRot));

  // ground is a large flat plate
  // TODO: superimposed obstacles using ChParticleEmitter class.
  ChSharedPtr<ChBody> ground = Add_FlatGround(&vehicle, groundSize, groundPos, mu);

  // --------------------------
  // Setup the Irrlicht GUI

/*
#ifdef USE_IRRLICHT
*/
	// Create the Irrlicht visualization applicaiton
  ChIrrApp application(&vehicle,
                      L"M113 tracked vehicle demo",
                      dimension2d<u32>(1000, 800),
                      false,
                      true);
  // assumes Y-up
  application.AddTypicalSky();
  /*
  // a skybox that has Z pointing up (default application.AddTypicalSky() makes Y up)
  std::string mtexturedir = GetChronoDataFile("skybox/");
  std::string str_lf = mtexturedir + "sky_lf.jpg";
  std::string str_up = mtexturedir + "sky_up.jpg";
  std::string str_dn = mtexturedir + "sky_dn.jpg";
  irr::video::ITexture* map_skybox_side =
      application.GetVideoDriver()->getTexture(str_lf.c_str());
  irr::scene::ISceneNode* mbox = application.GetSceneManager()->addSkyBoxSceneNode(
      application.GetVideoDriver()->getTexture(str_up.c_str()),
      application.GetVideoDriver()->getTexture(str_dn.c_str()),
      map_skybox_side,
      map_skybox_side,
      map_skybox_side,
      map_skybox_side);
  mbox->setRotation( irr::core::vector3df(90,0,0));  // rotate skybox for z-up
  */

  bool do_shadows = true; // shadow map is experimental
  irr::scene::ILightSceneNode* mlight = 0;

  if (do_shadows)
  {
    mlight = application.AddLightWithShadow(
      irr::core::vector3df(10.f, 60.f, 30.f),
      irr::core::vector3df(0.f, 0.f, 0.f),
      150, 60, 80, 15, 512, irr::video::SColorf(1, 1, 1), false, false);
  }
  else
  {
    application.AddTypicalLights(
      irr::core::vector3df(30.f, 100.f, 30.f),
      irr::core::vector3df(30.f, 100.f, 50.f),
      250, 130);
  }

  application.SetTimestep(step_size);

  // the GUI driver
  ChIrrGuiTrack driver(application, vehicle, trackPoint, chaseDist.x, chaseDist.y, chaseDist.z);

  // Set the time response for steering and throttle keyboard inputs.
  // NOTE: this is not exact, since we do not render quite at the specified FPS.
  double steering_time = 1.0;  // time to go from 0 to +1 (or from 0 to -1)
  double throttle_time = 1.0;  // time to go from 0 to +1
  double braking_time = 0.3;  // time to go from 0 to +1
  driver.SetSteeringDelta(render_step_size / steering_time);
  driver.SetThrottleDelta(render_step_size / throttle_time);
  driver.SetBrakingDelta(render_step_size / braking_time);

  // Set up the assets for rendering
  application.AssetBindAll();
  application.AssetUpdateAll();
  if (do_shadows)
  {
    application.AddShadowAll();
  }

  // ---------------------
  // GUI and render settings

  // GUI driver inputs
  std::vector<double> throttle_input;
  std::vector<double> braking_input;
  double steering_input;

  // Number of simulation steps between two 3D view render frames
  int render_steps = (int)std::ceil(render_step_size / step_size);

  // Number of simulation steps between two output frames
  int output_steps = (int)std::ceil(output_step_size / step_size);

  // ---------------------
  // Simulation loop
#ifdef DEBUG_LOG
  GetLog() << "\n\n============ System Configuration ============\n";
  vehicle.ShowHierarchy(GetLog() );
#endif

  // Initialize simulation frame counter and simulation time
  int step_number = 0;
  double time = 0;
  ChRealtimeStepTimer realtime_timer;
  while (application.GetDevice()->run())
	{
		// keep track of the time spent calculating each sim step
    ChTimer<double> step_time;
    step_time.start();

    // Render scene
    if (step_number % render_steps == 0) {
      application.GetVideoDriver()->beginScene(true, true, irr::video::SColor(255, 140, 161, 192));
      driver.DrawAll();
      application.GetVideoDriver()->endScene();
    }

    // Collect output data from modules (for inter-module communication)
    throttle_input = driver.GetThrottle();
    steering_input = driver.GetSteering();
    braking_input = driver.GetBraking();

    // Update
    time = vehicle.GetChTime();

    driver.Update(time);

    vehicle.Update(time, throttle_input, braking_input);
    // Advance simulation for one timestep for all modules
    double step = realtime_timer.SuggestSimulationStep(step_size);

    driver.Advance(step);

    vehicle.Advance(step);

	}

	return 0;
}

<|endoftext|>


<commit_before>/*!
@file

@copyright Edouard Alligand and Joel Falcou 2015-2017
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_BRIGAND_TYPES_VOIDP_HPP
#define BOOST_BRIGAND_TYPES_VOIDP_HPP

namespace brigand
{
  template<typename T> struct voidp { using type = void const *; };
}
#endif
<commit_msg>Delete voidp.hpp<commit_after><|endoftext|>


<commit_before>#ifndef _PITO_INTERCEPTOR_LOG_HELPER_
#define _PITO_INTERCEPTOR_LOG_HELPER_

#include <pito/interceptor/SystemCall.hpp>
#include <pito/interceptor/lib/traits.hpp>

#include <iostream>

namespace pito { namespace interceptor { namespace log {

template <class... Args> struct PrintArgs;
template <class... Args> struct PrintTailArgs;

template <>
struct PrintArgs<> {
    static void exec() {
    }
};

template <>
struct PrintTailArgs<> {
    static void exec() {
    }
};

template <class Arg, class... Args>
struct PrintTailArgs<Arg, Args...> {
    static void exec(Arg const& arg, Args... args) {
        std::cerr << ", " << arg;
        PrintTailArgs<Args...>::exec(args...);
    }
};

template <class Arg, class... Args>
struct PrintArgs<Arg, Args...> {
    static void exec(Arg const& arg, Args... args) {
        std::cerr << arg;
        PrintTailArgs<Args...>::exec(args...);
    }
};

template <class Tag>
struct SystemCall;

template <class Tag>
struct SystemCall : SystemCallBase<Tag> {
    typedef SystemCallBase<Tag> base_t;

    // to handle variadic c argument lists
    template <class... OtherArgs>
    typename base_t::return_type operator()(OtherArgs... args) {
        std::cerr << "calling " << system_call::traits<Tag>::name << "(";
        PrintArgs<OtherArgs...>::exec(args...);
        std::cerr << ")" << std::endl;
        return base_t::operator()(args...);
    }
};

} } }

#endif
<commit_msg>shorten<commit_after>#ifndef _PITO_INTERCEPTOR_LOG_HELPER_
#define _PITO_INTERCEPTOR_LOG_HELPER_

#include <pito/interceptor/SystemCall.hpp>
#include <pito/interceptor/lib/traits.hpp>

#include <iostream>

namespace pito { namespace interceptor { namespace log {

template <class... Args> struct PrintArgs;
template <class... Args> struct PrintTailArgs;

template <>
struct PrintArgs<> {
    static void exec() {
    }
};

template <>
struct PrintTailArgs<> {
    static void exec() {
    }
};

template <class Arg, class... Args>
struct PrintTailArgs<Arg, Args...> {
    static void exec(Arg const& arg, Args... args) {
        std::cerr << ", " << arg;
        PrintTailArgs<Args...>::exec(args...);
    }
};

template <class Arg, class... Args>
struct PrintArgs<Arg, Args...> {
    static void exec(Arg const& arg, Args... args) {
        std::cerr << arg;
        PrintTailArgs<Args...>::exec(args...);
    }
};

template <class Tag>
struct SystemCall;

template <class Tag>
struct SystemCall : SystemCallBase<Tag> {
    typedef SystemCallBase<Tag> base_t;

    // to handle variadic c argument lists
    template <class... OtherArgs>
    typename base_t::return_type operator()(OtherArgs... args) {
        std::cerr << "calling " << base_t::name << "(";
        PrintArgs<OtherArgs...>::exec(args...);
        std::cerr << ")" << std::endl;
        return base_t::operator()(args...);
    }
};

} } }

#endif
<|endoftext|>


<commit_before>#include "Elf.h"
#include "Matrix.h"
#include "MatrixElf.h"
#include "MatrixOnlineScheduler.h"
#include "MatrixSlice.h"
#include "MatrixSlicer.h"
#include "MatrixSlicerOnline.h"
#include "MatrixOnlineSchedulingStrategyFactory.h"
#include "common/ProblemStatement.h"
#include "common/MpiGuard.h"

#include <algorithm>
#include <iterator>
#include <stdexcept>
#include <condition_variable>
#include <utility>

using namespace std;
using MatrixHelper::MatrixPair;

vector<MatrixSlice> MatrixOnlineScheduler::sliceDefinitions = std::vector<MatrixSlice>();
vector<SliceContainer> MatrixOnlineScheduler::sliceContainers = std::vector<SliceContainer>();
vector<SliceContainer>::iterator MatrixOnlineScheduler::currentSliceContainer = MatrixOnlineScheduler::sliceContainers.begin();
mutex MatrixOnlineScheduler::schedulingMutex;
int MatrixOnlineScheduler::sliceNodeIdNone = -1;

MatrixOnlineScheduler::MatrixOnlineScheduler(const Communicator& communicator, const function<ElfPointer()>& factory) :
    MatrixScheduler(communicator, factory)
{
    receivedAllWork = false;
    processedAllWork = false;
}

MatrixOnlineScheduler::~MatrixOnlineScheduler()
{
}

void MatrixOnlineScheduler::configureWith(const Configuration& config)
{
    schedulingStrategy = MatrixOnlineSchedulingStrategyFactory::getStrategy(config.schedulingStrategy());
    maxWorkQueueSize = schedulingStrategy->getWorkQueueSize();
}

void MatrixOnlineScheduler::generateData(const DataGenerationParameters& params)
{
    MatrixScheduler::generateData(params);
}

void MatrixOnlineScheduler::doDispatch()
{
    if (MpiGuard::getThreadSupport() == MPI_THREAD_MULTIPLE)
        MatrixScheduler::doDispatch();
    else
        throw runtime_error("\
MatrixOnlineScheduler needs MPI with MPI_THREAD_MULTIPLE support.\n\
Please use --mpi_thread_multiple and/or rebuild MPI with enabled multiple thread support.");
}

void MatrixOnlineScheduler::orchestrateCalculation()
{
    sliceInput();
    generateSlicePairs();
    schedule();
}

void MatrixOnlineScheduler::sliceInput()
{
    result = Matrix<float>(left.rows(), right.columns());
    sliceDefinitions = schedulingStrategy->getSliceDefinitions(
        result, communicator.nodeSet());
}

void MatrixOnlineScheduler::generateSlicePairs()
{
    for (auto& sliceDefinition : sliceDefinitions)
    {
        SliceContainer container;
        container.slicePair = sliceMatrices(sliceDefinition);
        container.sliceDefinition = sliceDefinition;
        sliceContainers.push_back(container);
    }
    currentSliceContainer = sliceContainers.begin();
}

void MatrixOnlineScheduler::schedule()
{
    vector<future<void>> futures;
    for (size_t i = 1; i < communicator.nodeSet().size(); ++i)
        futures.push_back(async(launch::async, [&, i] () {
            MatrixHelper::sendWorkQueueSize(communicator, int(i), maxWorkQueueSize, int(Tags::workQueueSize)); }));
    futures.push_back(async(launch::async, [&]() { scheduleWork(); }));
    futures.push_back(async(launch::async, [&]() { receiveResults(); }));
    calculateOnSlave();
    waitFor(futures);
}

void MatrixOnlineScheduler::scheduleWork()
{
    vector<future<void>> futures;
    size_t sentWork = 0;
    while (sentWork != amountOfWork())
    {
        const int requestingNode = MatrixHelper::waitForTransactionRequest(
            communicator, int(Tags::workRequest));
        futures.push_back(async(launch::async, [&, requestingNode]() {
            sendNextWorkTo(requestingNode); }));
        sentWork++;
    }
    waitFor(futures);
}

void MatrixOnlineScheduler::receiveResults()
{
    vector<future<void>> futures;
    size_t receivedResults = 0;
    while (receivedResults != amountOfResults())
    {
        const int requestingNode = MatrixHelper::waitForTransactionRequest(
            communicator, int(Tags::resultRequest));
        futures.push_back(async(launch::async, [&, requestingNode]() {
            receiveResultFrom(requestingNode); }));
        receivedResults++;
    }
    waitFor(futures);
}

void MatrixOnlineScheduler::sendNextWorkTo(const int node)
{
    vector<SliceContainer>::iterator workDefinition = getNextWorkDefinition();
    if (workDefinition != sliceContainers.end())
    {
        (*workDefinition).sliceDefinition.setNodeId(node);
        MatrixHelper::isendNextWork(communicator, workDefinition->slicePair, node, int(Tags::exchangeWork));
    }
    else
        MatrixHelper::isendNextWork(communicator, MatrixPair(Matrix<float>(), Matrix<float>()), node, int(Tags::exchangeWork));
}

vector<SliceContainer>::iterator MatrixOnlineScheduler::getNextWorkDefinition()
{
    vector<SliceContainer>::iterator workDefinition;
    schedulingMutex.lock();
    workDefinition = currentSliceContainer;
    if (currentSliceContainer != sliceContainers.end())
        currentSliceContainer++;
    schedulingMutex.unlock();
    return move(workDefinition);
}

void MatrixOnlineScheduler::receiveResultFrom(const int node)
{
    Matrix<float> nodeResult = MatrixHelper::receiveMatrixFrom(communicator, node, int(Tags::exchangeResult));
    MatrixSlice& slice = getNextSliceDefinitionFor(node);
    slice.injectSlice(nodeResult, result);
    slice.setNodeId(sliceNodeIdNone);
}

MatrixSlice& MatrixOnlineScheduler::getNextSliceDefinitionFor(const int node)
{
    for (auto& slice : sliceDefinitions)
        if (slice.getNodeId() == node)
            return slice;
    throw runtime_error("No next slice definition found.");
}

size_t MatrixOnlineScheduler::amountOfWork() const
{
    return sliceDefinitions.size() + communicator.nodeSet().size();
}

size_t MatrixOnlineScheduler::amountOfResults() const
{
    return sliceDefinitions.size();
}

void MatrixOnlineScheduler::calculateOnSlave()
{
    vector<future<void>> futures;
    if (!communicator.isMaster())
        getWorkQueueSize();
    futures.push_back(async(launch::async, [&]() { receiveWork(); }));
    futures.push_back(async(launch::async, [&]() { sendResults(); }));
    while (hasToWork())
        doWork();
    waitFor(futures);
}

void MatrixOnlineScheduler::getWorkQueueSize()
{
    maxWorkQueueSize = MatrixHelper::receiveWorkQueueSize(communicator, Communicator::MASTER_RANK, int(Tags::workQueueSize));
}

void MatrixOnlineScheduler::doWork()
{
    Matrix<float> result = calculateNextResult();
    if (result.empty())
        processedAllWork = true;
    else
    {
        resultMutex.lock();
        resultQueue.push_back(result);
        resultMutex.unlock();
    }
    sendResultsState.notify_one();
}

Matrix<float> MatrixOnlineScheduler::calculateNextResult()
{
    unique_lock<mutex> workLock(workMutex);
    while (workQueue.empty())
        doWorkState.wait(workLock);
    MatrixPair work = move(workQueue.front());
    workQueue.pop_front();
    workMutex.unlock();
    receiveWorkState.notify_one();
    return move(elf().multiply(work.first, work.second));
}

void MatrixOnlineScheduler::receiveWork()
{
    unique_lock<mutex> workLock(workMutex);
    while (hasToReceiveWork())
    {
        while (workQueue.size() >= maxWorkQueueSize)
            receiveWorkState.wait(workLock);
        MatrixPair receivedWork = getNextWork();
        workQueue.push_back(move(receivedWork));
        if (receivedWork.first.empty() || receivedWork.second.empty())
            receivedAllWork = true;
        workMutex.unlock();
        doWorkState.notify_one();
    }
}

void MatrixOnlineScheduler::sendResults()
{
    unique_lock<mutex> resultLock(resultMutex);
    while (hasToSendResults())
    {
        while (resultQueue.empty())
        {
            sendResultsState.wait(resultLock);
            if (resultQueue.empty() && processedAllWork)
            {
                resultMutex.unlock();
                return;
            }
        }
        Matrix<float> result = move(resultQueue.front());
        resultQueue.pop_front();
        resultMutex.unlock();
        sendResult(result);
    }
}

MatrixPair MatrixOnlineScheduler::getNextWork()
{
    initiateWorkReceiving();
    return MatrixHelper::getNextWork(communicator, Communicator::MASTER_RANK, int(Tags::exchangeWork));
}

void MatrixOnlineScheduler::sendResult(const Matrix<float>& result)
{
    initiateResultSending();
    MatrixHelper::sendMatrixTo(
        communicator,
        result,
        Communicator::MASTER_RANK,
        int(Tags::exchangeResult));
}

void MatrixOnlineScheduler::initiateWorkReceiving() const
{
    initiateTransaction(int(Tags::workRequest));
}

void MatrixOnlineScheduler::initiateResultSending() const
{
    initiateTransaction(int(Tags::resultRequest));
}

void MatrixOnlineScheduler::initiateTransaction(const int tag) const
{
    MatrixHelper::requestTransaction(
        communicator,
        communicator.rank(),
        Communicator::MASTER_RANK,
        tag);
}

bool MatrixOnlineScheduler::hasToReceiveWork()
{
    return !receivedAllWork;
}

bool MatrixOnlineScheduler::hasToSendResults()
{
    return !resultQueue.empty() || !processedAllWork;
}

bool MatrixOnlineScheduler::hasToWork()
{
    return !workQueue.empty() || !receivedAllWork;
}

void MatrixOnlineScheduler::waitFor(vector<future<void>>& futures)
{
    #pragma omp parallel for
    for (size_t i = 0; i < futures.size(); ++i)
    {
        futures[i].wait();
        if (!futures[i].valid())
            throw future_error(future_errc::no_state);
    }
}

<commit_msg>Minor code improvements<commit_after>#include "Elf.h"
#include "Matrix.h"
#include "MatrixElf.h"
#include "MatrixOnlineScheduler.h"
#include "MatrixSlice.h"
#include "MatrixSlicer.h"
#include "MatrixSlicerOnline.h"
#include "MatrixOnlineSchedulingStrategyFactory.h"
#include "common/ProblemStatement.h"
#include "common/MpiGuard.h"

#include <algorithm>
#include <iterator>
#include <stdexcept>
#include <condition_variable>
#include <utility>

using namespace std;
using MatrixHelper::MatrixPair;

vector<MatrixSlice> MatrixOnlineScheduler::sliceDefinitions = std::vector<MatrixSlice>();
vector<SliceContainer> MatrixOnlineScheduler::sliceContainers = std::vector<SliceContainer>();
vector<SliceContainer>::iterator MatrixOnlineScheduler::currentSliceContainer = MatrixOnlineScheduler::sliceContainers.begin();
mutex MatrixOnlineScheduler::schedulingMutex;
int MatrixOnlineScheduler::sliceNodeIdNone = -1;

MatrixOnlineScheduler::MatrixOnlineScheduler(const Communicator& communicator, const function<ElfPointer()>& factory) :
    MatrixScheduler(communicator, factory)
{
    receivedAllWork = false;
    processedAllWork = false;
}

MatrixOnlineScheduler::~MatrixOnlineScheduler()
{
}

void MatrixOnlineScheduler::configureWith(const Configuration& config)
{
    schedulingStrategy = MatrixOnlineSchedulingStrategyFactory::getStrategy(config.schedulingStrategy());
    maxWorkQueueSize = schedulingStrategy->getWorkQueueSize();
}

void MatrixOnlineScheduler::generateData(const DataGenerationParameters& params)
{
    MatrixScheduler::generateData(params);
}

void MatrixOnlineScheduler::doDispatch()
{
    if (MpiGuard::getThreadSupport() == MPI_THREAD_MULTIPLE)
        MatrixScheduler::doDispatch();
    else
        throw runtime_error("\
MatrixOnlineScheduler needs MPI with MPI_THREAD_MULTIPLE support.\n\
Please use --mpi_thread_multiple and/or rebuild MPI with enabled multiple thread support.");
}

void MatrixOnlineScheduler::orchestrateCalculation()
{
    sliceInput();
    generateSlicePairs();
    schedule();
}

void MatrixOnlineScheduler::sliceInput()
{
    result = Matrix<float>(left.rows(), right.columns());
    sliceDefinitions = schedulingStrategy->getSliceDefinitions(
        result, communicator.nodeSet());
}

void MatrixOnlineScheduler::generateSlicePairs()
{
    SliceContainer container;
    for (auto& sliceDefinition : sliceDefinitions)
    {
        container.slicePair = sliceMatrices(sliceDefinition);
        container.sliceDefinition = sliceDefinition;
        sliceContainers.push_back(container);
    }
    currentSliceContainer = sliceContainers.begin();
}

void MatrixOnlineScheduler::schedule()
{
    vector<future<void>> futures;
    futures.push_back(async(launch::async, [&]() { scheduleWork(); }));
    futures.push_back(async(launch::async, [&]() { receiveResults(); }));
    for (size_t i = 1; i < communicator.nodeSet().size(); ++i)
        futures.push_back(async(launch::async, [&, i] () {
            MatrixHelper::sendWorkQueueSize(communicator, int(i), maxWorkQueueSize, int(Tags::workQueueSize)); }));
    calculateOnSlave();
    waitFor(futures);
}

void MatrixOnlineScheduler::scheduleWork()
{
    vector<future<void>> futures;
    size_t sentWork = 0;
    while (sentWork != amountOfWork())
    {
        const int requestingNode = MatrixHelper::waitForTransactionRequest(
            communicator, int(Tags::workRequest));
        futures.push_back(async(launch::async, [&, requestingNode]() {
            sendNextWorkTo(requestingNode); }));
        sentWork++;
    }
    waitFor(futures);
}

void MatrixOnlineScheduler::receiveResults()
{
    vector<future<void>> futures;
    size_t receivedResults = 0;
    while (receivedResults != amountOfResults())
    {
        const int requestingNode = MatrixHelper::waitForTransactionRequest(
            communicator, int(Tags::resultRequest));
        futures.push_back(async(launch::async, [&, requestingNode]() {
            receiveResultFrom(requestingNode); }));
        receivedResults++;
    }
    waitFor(futures);
}

void MatrixOnlineScheduler::sendNextWorkTo(const int node)
{
    vector<SliceContainer>::iterator workDefinition = getNextWorkDefinition();
    if (workDefinition != sliceContainers.end())
    {
        (*workDefinition).sliceDefinition.setNodeId(node);
        MatrixHelper::isendNextWork(communicator, workDefinition->slicePair, node, int(Tags::exchangeWork));
    }
    else
        MatrixHelper::isendNextWork(communicator, MatrixPair(Matrix<float>(), Matrix<float>()), node, int(Tags::exchangeWork));
}

vector<SliceContainer>::iterator MatrixOnlineScheduler::getNextWorkDefinition()
{
    vector<SliceContainer>::iterator workDefinition;
    schedulingMutex.lock();
    workDefinition = currentSliceContainer;
    if (currentSliceContainer != sliceContainers.end())
        currentSliceContainer++;
    schedulingMutex.unlock();
    return move(workDefinition);
}

void MatrixOnlineScheduler::receiveResultFrom(const int node)
{
    Matrix<float> nodeResult = MatrixHelper::receiveMatrixFrom(communicator, node, int(Tags::exchangeResult));
    MatrixSlice& slice = getNextSliceDefinitionFor(node);
    slice.injectSlice(nodeResult, result);
    slice.setNodeId(sliceNodeIdNone);
}

MatrixSlice& MatrixOnlineScheduler::getNextSliceDefinitionFor(const int node)
{
    for (auto& slice : sliceContainers)
        if (slice.sliceDefinition.getNodeId() == node)
            return slice.sliceDefinition;
    throw runtime_error("No next slice definition found.");
}

size_t MatrixOnlineScheduler::amountOfWork() const
{
    return sliceDefinitions.size() + communicator.nodeSet().size();
}

size_t MatrixOnlineScheduler::amountOfResults() const
{
    return sliceDefinitions.size();
}

void MatrixOnlineScheduler::calculateOnSlave()
{
    vector<future<void>> futures;
    if (!communicator.isMaster())
        getWorkQueueSize();
    futures.push_back(async(launch::async, [&]() { receiveWork(); }));
    futures.push_back(async(launch::async, [&]() { sendResults(); }));
    while (hasToWork())
        doWork();
    waitFor(futures);
}

void MatrixOnlineScheduler::getWorkQueueSize()
{
    maxWorkQueueSize = MatrixHelper::receiveWorkQueueSize(communicator, Communicator::MASTER_RANK, int(Tags::workQueueSize));
}

void MatrixOnlineScheduler::doWork()
{
    Matrix<float> result = calculateNextResult();
    if (result.empty())
        processedAllWork = true;
    else
    {
        resultMutex.lock();
        resultQueue.push_back(result);
        resultMutex.unlock();
    }
    sendResultsState.notify_one();
}

Matrix<float> MatrixOnlineScheduler::calculateNextResult()
{
    unique_lock<mutex> workLock(workMutex);
    while (workQueue.empty())
        doWorkState.wait(workLock);
    MatrixPair work = move(workQueue.front());
    workQueue.pop_front();
    workMutex.unlock();
    receiveWorkState.notify_one();
    return move(elf().multiply(work.first, work.second));
}

void MatrixOnlineScheduler::receiveWork()
{
    unique_lock<mutex> workLock(workMutex);
    while (hasToReceiveWork())
    {
        while (workQueue.size() >= maxWorkQueueSize)
            receiveWorkState.wait(workLock);
        MatrixPair receivedWork = getNextWork();
        workQueue.push_back(move(receivedWork));
        if (receivedWork.first.empty() || receivedWork.second.empty())
            receivedAllWork = true;
        workMutex.unlock();
        doWorkState.notify_one();
    }
}

void MatrixOnlineScheduler::sendResults()
{
    unique_lock<mutex> resultLock(resultMutex);
    while (hasToSendResults())
    {
        while (resultQueue.empty())
        {
            sendResultsState.wait(resultLock);
            if (resultQueue.empty() && processedAllWork)
            {
                resultMutex.unlock();
                return;
            }
        }
        Matrix<float> result = move(resultQueue.front());
        resultQueue.pop_front();
        resultMutex.unlock();
        sendResult(result);
    }
}

MatrixPair MatrixOnlineScheduler::getNextWork()
{
    initiateWorkReceiving();
    return MatrixHelper::getNextWork(communicator, Communicator::MASTER_RANK, int(Tags::exchangeWork));
}

void MatrixOnlineScheduler::sendResult(const Matrix<float>& result)
{
    initiateResultSending();
    MatrixHelper::sendMatrixTo(
        communicator,
        result,
        Communicator::MASTER_RANK,
        int(Tags::exchangeResult));
}

void MatrixOnlineScheduler::initiateWorkReceiving() const
{
    initiateTransaction(int(Tags::workRequest));
}

void MatrixOnlineScheduler::initiateResultSending() const
{
    initiateTransaction(int(Tags::resultRequest));
}

void MatrixOnlineScheduler::initiateTransaction(const int tag) const
{
    MatrixHelper::requestTransaction(
        communicator,
        communicator.rank(),
        Communicator::MASTER_RANK,
        tag);
}

bool MatrixOnlineScheduler::hasToReceiveWork()
{
    return !receivedAllWork;
}

bool MatrixOnlineScheduler::hasToSendResults()
{
    return !resultQueue.empty() || !processedAllWork;
}

bool MatrixOnlineScheduler::hasToWork()
{
    return !workQueue.empty() || !receivedAllWork;
}

void MatrixOnlineScheduler::waitFor(vector<future<void>>& futures)
{
    #pragma omp parallel for
    for (size_t i = 0; i < futures.size(); ++i)
    {
        futures[i].wait();
        if (!futures[i].valid())
            throw future_error(future_errc::no_state);
    }
}

<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>
#include <vector>

#include "base/callback.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/test_launcher_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/browser/gpu/gpu_data_manager.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/gpu/gpu_info.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/gl_switches.h"
#include "ui/gfx/size.h"

namespace {

// Command line flag for forcing the machine's GPU to be used instead of OSMesa.
const char kUseGpuInTests[] = "use-gpu-in-tests";

// Command line flag for overriding the default location for putting generated
// test images that do not match references.
const char kGeneratedDir[] = "generated-dir";

// Reads and decodes a PNG image to a bitmap. Returns true on success. The PNG
// should have been encoded using |gfx::PNGCodec::Encode|.
bool ReadPNGFile(const FilePath& file_path, SkBitmap* bitmap) {
  DCHECK(bitmap);
  std::string png_data;
  return file_util::ReadFileToString(file_path, &png_data) &&
         gfx::PNGCodec::Decode(reinterpret_cast<unsigned char*>(&png_data[0]),
                               png_data.length(),
                               bitmap);
}

// Encodes a bitmap into a PNG and write to disk. Returns true on success. The
// parent directory does not have to exist.
bool WritePNGFile(const SkBitmap& bitmap, const FilePath& file_path) {
  std::vector<unsigned char> png_data;
  if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &png_data) &&
      file_util::CreateDirectory(file_path.DirName())) {
    int bytes_written = file_util::WriteFile(
        file_path, reinterpret_cast<char*>(&png_data[0]), png_data.size());
    if (bytes_written == static_cast<int>(png_data.size()))
      return true;
  }
  return false;
}

// Resizes the browser window so that the tab's contents are at a given size.
void ResizeTabContainer(Browser* browser, const gfx::Size& desired_size) {
  gfx::Rect container_rect;
  browser->GetSelectedTabContents()->GetContainerBounds(&container_rect);
  // Size cannot be negative, so use a point.
  gfx::Point correction(desired_size.width() - container_rect.size().width(),
                        desired_size.height() - container_rect.size().height());

  gfx::Rect window_rect = browser->window()->GetRestoredBounds();
  gfx::Size new_size = window_rect.size();
  new_size.Enlarge(correction.x(), correction.y());
  window_rect.set_size(new_size);
  browser->window()->SetBounds(window_rect);
}

// Obtains info about the GPU. Iff the info is collected, |client_info| will be
// set and true will be returned. Here we only need vendor_id and device_id,
// which should be always collected during browser startup, so no need to run
// GPU information collection here.
// This will return false if we are running in a virtualized environment.
bool GetGPUInfo(GPUInfo* client_info) {
  CHECK(client_info);
  const GPUInfo& info = GpuDataManager::GetInstance()->gpu_info();
  if (info.vendor_id == 0 || info.device_id == 0)
    return false;
  *client_info = info;
  return true;
}

}  // namespace

// Test fixture for GPU image comparison tests.
// TODO(kkania): Document how to add to/modify these tests.
class GpuPixelBrowserTest : public InProcessBrowserTest {
 public:
  GpuPixelBrowserTest() {}

  virtual void SetUpCommandLine(CommandLine* command_line) {
    // This enables DOM automation for tab contents.
    EnableDOMAutomation();

    // These tests by default use OSMesa. This can be changed if the |kUseGL|
    // switch is explicitly set to something else or if |kUseGpuInTests| is
    // present.
    if (command_line->HasSwitch(switches::kUseGL)) {
      using_gpu_ = command_line->GetSwitchValueASCII(switches::kUseGL) !=
          gfx::kGLImplementationOSMesaName;
    } else if (command_line->HasSwitch(kUseGpuInTests)) {
      using_gpu_ = true;
    } else {
      // OSMesa will be used by default.
      EXPECT_TRUE(test_launcher_utils::OverrideGLImplementation(
          command_line,
          gfx::kGLImplementationOSMesaName));
#if defined(OS_MACOSX)
      // Accelerated compositing does not work with OSMesa. AcceleratedSurface
      // assumes GL contexts are native.
      command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
#endif
      using_gpu_ = false;
    }
    // Allow file access from "file://" protocol. Otherwise, test fails with
    // "Uncaught Error: SECURITY_ERR: DOM Exception 18."
    command_line->AppendSwitch(switches::kAllowFileAccessFromFiles);
  }

  virtual void SetUpInProcessBrowserTestFixture() {
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_));
    test_data_dir_ = test_data_dir_.AppendASCII("gpu");

    CommandLine* command_line = CommandLine::ForCurrentProcess();
    if (command_line->HasSwitch(kGeneratedDir))
      generated_img_dir_ = command_line->GetSwitchValuePath(kGeneratedDir);
    else
      generated_img_dir_ = test_data_dir_.AppendASCII("generated");

    if (using_gpu_)
      reference_img_dir_ = test_data_dir_.AppendASCII("gpu_reference");
    else
      reference_img_dir_ = test_data_dir_.AppendASCII("sw_reference");

    test_name_ = testing::UnitTest::GetInstance()->current_test_info()->name();
    const char* test_status_prefixes[] = {"DISABLED_", "FLAKY_", "FAILS_"};
    for (size_t i = 0; i < arraysize(test_status_prefixes); ++i) {
      ReplaceFirstSubstringAfterOffset(
          &test_name_, 0, test_status_prefixes[i], "");
    }
  }

  // Compares the generated bitmap with the appropriate reference image on disk.
  // The reference image is determined by the name of the test, the |postfix|,
  // and the vendor and device ID. Returns true iff the images were the same.
  //
  // |postfix|, is an optional name that can be appended onto the images name to
  // distinguish between images from a single test.
  //
  // On failure, the image will be written to disk, and can be collected as a
  // baseline. The image format is:
  //     <test_name>_<postfix>_<os>_<vendor_id>-<device_id>.png
  // E.g.,
  //     WebGLFishTank_FirstTab_120981-1201.png
  bool CompareImages(const SkBitmap& gen_bmp, const std::string& postfix) {
    // Determine the name of the image.
    std::string img_name = test_name_;
    if (postfix.length())
      img_name += "_" + postfix;
#if defined(OS_WIN)
      const char* os_label = "win";
#elif defined(OS_MACOSX)
      const char* os_label = "mac";
#elif defined(OS_LINUX)
      const char* os_label = "linux";
#else
#error "Not implemented for this platform"
#endif
    if (using_gpu_) {
      GPUInfo info;
      if (!GetGPUInfo(&info)) {
        LOG(ERROR) << "Could not get gpu info";
        return false;
      }
      img_name = base::StringPrintf("%s_%s_%04x-%04x.png",
          img_name.c_str(), os_label, info.vendor_id, info.device_id);
    } else {
      img_name = base::StringPrintf("%s_%s_mesa.png",
          img_name.c_str(), os_label);
    }

    // Read the reference image and verify the images' dimensions are equal.
    FilePath ref_img_path = reference_img_dir_.AppendASCII(img_name);
    SkBitmap ref_bmp;
    bool should_compare = true;
    if (!ReadPNGFile(ref_img_path, &ref_bmp)) {
      LOG(ERROR) << "Cannot read reference image: " << ref_img_path.value();
      should_compare = false;
    }
    if (should_compare &&
        (ref_bmp.width() != gen_bmp.width() ||
         ref_bmp.height() != gen_bmp.height())) {
      LOG(ERROR)
          << "Dimensions do not match (Expected) vs (Actual):"
          << "(" << ref_bmp.width() << "x" << ref_bmp.height()
              << ") vs. "
          << "(" << gen_bmp.width() << "x" << gen_bmp.height() << ")";
      should_compare = false;
    }

    // Compare pixels and create a simple diff image.
    int diff_pixels_count = 0;
    SkBitmap diff_bmp;
    if (should_compare) {
      diff_bmp.setConfig(SkBitmap::kARGB_8888_Config,
                         gen_bmp.width(), gen_bmp.height());
      diff_bmp.allocPixels();
      diff_bmp.eraseColor(SK_ColorWHITE);
      SkAutoLockPixels lock_bmp(gen_bmp);
      SkAutoLockPixels lock_ref_bmp(ref_bmp);
      SkAutoLockPixels lock_diff_bmp(diff_bmp);
      // The reference images were saved with no alpha channel. Use the mask to
      // set alpha to 0.
      uint32_t kAlphaMask = 0x00FFFFFF;
      for (int x = 0; x < gen_bmp.width(); ++x) {
        for (int y = 0; y < gen_bmp.height(); ++y) {
          if ((*gen_bmp.getAddr32(x, y) & kAlphaMask) !=
              (*ref_bmp.getAddr32(x, y) & kAlphaMask)) {
            ++diff_pixels_count;
            *diff_bmp.getAddr32(x, y) = 192 << 16;  // red
          }
        }
      }
    }

    // Write the generated and diff images if the comparison failed.
    if (!should_compare || diff_pixels_count != 0) {
      FilePath gen_img_path = generated_img_dir_.AppendASCII(img_name);
      if (WritePNGFile(gen_bmp, gen_img_path)) {
        // Output the generated image path to the log for easy parsing later.
        std::cout << "*GEN_IMG=" << gen_img_path.value() << std::endl;
      } else {
        LOG(WARNING) << "Could not write generated image: "
                     << gen_img_path.value();
      }
      if (should_compare) {
        WritePNGFile(diff_bmp,
                     generated_img_dir_.AppendASCII("diff-" + img_name));
        LOG(ERROR) << "Images differ by pixel count: " << diff_pixels_count;
      }
      return false;
    }
    return true;
  }

 protected:
  FilePath test_data_dir_;

 private:
  FilePath reference_img_dir_;
  FilePath generated_img_dir_;
  // The name of the test, with any special prefixes dropped.
  std::string test_name_;
  // Whether the gpu, or OSMesa is being used for rendering.
  bool using_gpu_;

  DISALLOW_COPY_AND_ASSIGN(GpuPixelBrowserTest);
};

// Currently fails on linux due to a NOTIMPLEMENTED() statement.
// (http://crbug.com/89964)
#if defined(OS_LINUX)
#define MAYBE_WebGLTeapot FAILS_WebGLTeapot
#else
#define MAYBE_WebGLTeapot WebGLTeapot
#endif

IN_PROC_BROWSER_TEST_F(GpuPixelBrowserTest, MAYBE_WebGLTeapot) {
  ui_test_utils::DOMMessageQueue message_queue;
  ui_test_utils::NavigateToURL(
      browser(),
      net::FilePathToFileURL(test_data_dir_.AppendASCII("webgl_teapot").
          AppendASCII("teapot.html")));

  // Wait for message from teapot page indicating the GL calls have been issued.
  ASSERT_TRUE(message_queue.WaitForMessage(NULL));

  SkBitmap bitmap;
  gfx::Size container_size(500, 500);
  ResizeTabContainer(browser(), container_size);
  ASSERT_TRUE(ui_test_utils::TakeRenderWidgetSnapshot(
      browser()->GetSelectedTabContents()->render_view_host(),
      container_size, &bitmap));
  ASSERT_TRUE(CompareImages(bitmap, ""));
}
<commit_msg>Switch GpuPixelBrowserTest from FAILS to DISABLED.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>
#include <vector>

#include "base/callback.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/test_launcher_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/browser/gpu/gpu_data_manager.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/gpu/gpu_info.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/gl_switches.h"
#include "ui/gfx/size.h"

namespace {

// Command line flag for forcing the machine's GPU to be used instead of OSMesa.
const char kUseGpuInTests[] = "use-gpu-in-tests";

// Command line flag for overriding the default location for putting generated
// test images that do not match references.
const char kGeneratedDir[] = "generated-dir";

// Reads and decodes a PNG image to a bitmap. Returns true on success. The PNG
// should have been encoded using |gfx::PNGCodec::Encode|.
bool ReadPNGFile(const FilePath& file_path, SkBitmap* bitmap) {
  DCHECK(bitmap);
  std::string png_data;
  return file_util::ReadFileToString(file_path, &png_data) &&
         gfx::PNGCodec::Decode(reinterpret_cast<unsigned char*>(&png_data[0]),
                               png_data.length(),
                               bitmap);
}

// Encodes a bitmap into a PNG and write to disk. Returns true on success. The
// parent directory does not have to exist.
bool WritePNGFile(const SkBitmap& bitmap, const FilePath& file_path) {
  std::vector<unsigned char> png_data;
  if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &png_data) &&
      file_util::CreateDirectory(file_path.DirName())) {
    int bytes_written = file_util::WriteFile(
        file_path, reinterpret_cast<char*>(&png_data[0]), png_data.size());
    if (bytes_written == static_cast<int>(png_data.size()))
      return true;
  }
  return false;
}

// Resizes the browser window so that the tab's contents are at a given size.
void ResizeTabContainer(Browser* browser, const gfx::Size& desired_size) {
  gfx::Rect container_rect;
  browser->GetSelectedTabContents()->GetContainerBounds(&container_rect);
  // Size cannot be negative, so use a point.
  gfx::Point correction(desired_size.width() - container_rect.size().width(),
                        desired_size.height() - container_rect.size().height());

  gfx::Rect window_rect = browser->window()->GetRestoredBounds();
  gfx::Size new_size = window_rect.size();
  new_size.Enlarge(correction.x(), correction.y());
  window_rect.set_size(new_size);
  browser->window()->SetBounds(window_rect);
}

// Obtains info about the GPU. Iff the info is collected, |client_info| will be
// set and true will be returned. Here we only need vendor_id and device_id,
// which should be always collected during browser startup, so no need to run
// GPU information collection here.
// This will return false if we are running in a virtualized environment.
bool GetGPUInfo(GPUInfo* client_info) {
  CHECK(client_info);
  const GPUInfo& info = GpuDataManager::GetInstance()->gpu_info();
  if (info.vendor_id == 0 || info.device_id == 0)
    return false;
  *client_info = info;
  return true;
}

}  // namespace

// Test fixture for GPU image comparison tests.
// TODO(kkania): Document how to add to/modify these tests.
class GpuPixelBrowserTest : public InProcessBrowserTest {
 public:
  GpuPixelBrowserTest() {}

  virtual void SetUpCommandLine(CommandLine* command_line) {
    // This enables DOM automation for tab contents.
    EnableDOMAutomation();

    // These tests by default use OSMesa. This can be changed if the |kUseGL|
    // switch is explicitly set to something else or if |kUseGpuInTests| is
    // present.
    if (command_line->HasSwitch(switches::kUseGL)) {
      using_gpu_ = command_line->GetSwitchValueASCII(switches::kUseGL) !=
          gfx::kGLImplementationOSMesaName;
    } else if (command_line->HasSwitch(kUseGpuInTests)) {
      using_gpu_ = true;
    } else {
      // OSMesa will be used by default.
      EXPECT_TRUE(test_launcher_utils::OverrideGLImplementation(
          command_line,
          gfx::kGLImplementationOSMesaName));
#if defined(OS_MACOSX)
      // Accelerated compositing does not work with OSMesa. AcceleratedSurface
      // assumes GL contexts are native.
      command_line->AppendSwitch(switches::kDisableAcceleratedCompositing);
#endif
      using_gpu_ = false;
    }
    // Allow file access from "file://" protocol. Otherwise, test fails with
    // "Uncaught Error: SECURITY_ERR: DOM Exception 18."
    command_line->AppendSwitch(switches::kAllowFileAccessFromFiles);
  }

  virtual void SetUpInProcessBrowserTestFixture() {
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_));
    test_data_dir_ = test_data_dir_.AppendASCII("gpu");

    CommandLine* command_line = CommandLine::ForCurrentProcess();
    if (command_line->HasSwitch(kGeneratedDir))
      generated_img_dir_ = command_line->GetSwitchValuePath(kGeneratedDir);
    else
      generated_img_dir_ = test_data_dir_.AppendASCII("generated");

    if (using_gpu_)
      reference_img_dir_ = test_data_dir_.AppendASCII("gpu_reference");
    else
      reference_img_dir_ = test_data_dir_.AppendASCII("sw_reference");

    test_name_ = testing::UnitTest::GetInstance()->current_test_info()->name();
    const char* test_status_prefixes[] = {"DISABLED_", "FLAKY_", "FAILS_"};
    for (size_t i = 0; i < arraysize(test_status_prefixes); ++i) {
      ReplaceFirstSubstringAfterOffset(
          &test_name_, 0, test_status_prefixes[i], "");
    }
  }

  // Compares the generated bitmap with the appropriate reference image on disk.
  // The reference image is determined by the name of the test, the |postfix|,
  // and the vendor and device ID. Returns true iff the images were the same.
  //
  // |postfix|, is an optional name that can be appended onto the images name to
  // distinguish between images from a single test.
  //
  // On failure, the image will be written to disk, and can be collected as a
  // baseline. The image format is:
  //     <test_name>_<postfix>_<os>_<vendor_id>-<device_id>.png
  // E.g.,
  //     WebGLFishTank_FirstTab_120981-1201.png
  bool CompareImages(const SkBitmap& gen_bmp, const std::string& postfix) {
    // Determine the name of the image.
    std::string img_name = test_name_;
    if (postfix.length())
      img_name += "_" + postfix;
#if defined(OS_WIN)
      const char* os_label = "win";
#elif defined(OS_MACOSX)
      const char* os_label = "mac";
#elif defined(OS_LINUX)
      const char* os_label = "linux";
#else
#error "Not implemented for this platform"
#endif
    if (using_gpu_) {
      GPUInfo info;
      if (!GetGPUInfo(&info)) {
        LOG(ERROR) << "Could not get gpu info";
        return false;
      }
      img_name = base::StringPrintf("%s_%s_%04x-%04x.png",
          img_name.c_str(), os_label, info.vendor_id, info.device_id);
    } else {
      img_name = base::StringPrintf("%s_%s_mesa.png",
          img_name.c_str(), os_label);
    }

    // Read the reference image and verify the images' dimensions are equal.
    FilePath ref_img_path = reference_img_dir_.AppendASCII(img_name);
    SkBitmap ref_bmp;
    bool should_compare = true;
    if (!ReadPNGFile(ref_img_path, &ref_bmp)) {
      LOG(ERROR) << "Cannot read reference image: " << ref_img_path.value();
      should_compare = false;
    }
    if (should_compare &&
        (ref_bmp.width() != gen_bmp.width() ||
         ref_bmp.height() != gen_bmp.height())) {
      LOG(ERROR)
          << "Dimensions do not match (Expected) vs (Actual):"
          << "(" << ref_bmp.width() << "x" << ref_bmp.height()
              << ") vs. "
          << "(" << gen_bmp.width() << "x" << gen_bmp.height() << ")";
      should_compare = false;
    }

    // Compare pixels and create a simple diff image.
    int diff_pixels_count = 0;
    SkBitmap diff_bmp;
    if (should_compare) {
      diff_bmp.setConfig(SkBitmap::kARGB_8888_Config,
                         gen_bmp.width(), gen_bmp.height());
      diff_bmp.allocPixels();
      diff_bmp.eraseColor(SK_ColorWHITE);
      SkAutoLockPixels lock_bmp(gen_bmp);
      SkAutoLockPixels lock_ref_bmp(ref_bmp);
      SkAutoLockPixels lock_diff_bmp(diff_bmp);
      // The reference images were saved with no alpha channel. Use the mask to
      // set alpha to 0.
      uint32_t kAlphaMask = 0x00FFFFFF;
      for (int x = 0; x < gen_bmp.width(); ++x) {
        for (int y = 0; y < gen_bmp.height(); ++y) {
          if ((*gen_bmp.getAddr32(x, y) & kAlphaMask) !=
              (*ref_bmp.getAddr32(x, y) & kAlphaMask)) {
            ++diff_pixels_count;
            *diff_bmp.getAddr32(x, y) = 192 << 16;  // red
          }
        }
      }
    }

    // Write the generated and diff images if the comparison failed.
    if (!should_compare || diff_pixels_count != 0) {
      FilePath gen_img_path = generated_img_dir_.AppendASCII(img_name);
      if (WritePNGFile(gen_bmp, gen_img_path)) {
        // Output the generated image path to the log for easy parsing later.
        std::cout << "*GEN_IMG=" << gen_img_path.value() << std::endl;
      } else {
        LOG(WARNING) << "Could not write generated image: "
                     << gen_img_path.value();
      }
      if (should_compare) {
        WritePNGFile(diff_bmp,
                     generated_img_dir_.AppendASCII("diff-" + img_name));
        LOG(ERROR) << "Images differ by pixel count: " << diff_pixels_count;
      }
      return false;
    }
    return true;
  }

 protected:
  FilePath test_data_dir_;

 private:
  FilePath reference_img_dir_;
  FilePath generated_img_dir_;
  // The name of the test, with any special prefixes dropped.
  std::string test_name_;
  // Whether the gpu, or OSMesa is being used for rendering.
  bool using_gpu_;

  DISALLOW_COPY_AND_ASSIGN(GpuPixelBrowserTest);
};

// Currently fails (and times out) on linux due to a NOTIMPLEMENTED() statement.
// (http://crbug.com/89964)
#if defined(OS_LINUX)
#define MAYBE_WebGLTeapot DISABLED_WebGLTeapot
#else
#define MAYBE_WebGLTeapot WebGLTeapot
#endif

IN_PROC_BROWSER_TEST_F(GpuPixelBrowserTest, MAYBE_WebGLTeapot) {
  ui_test_utils::DOMMessageQueue message_queue;
  ui_test_utils::NavigateToURL(
      browser(),
      net::FilePathToFileURL(test_data_dir_.AppendASCII("webgl_teapot").
          AppendASCII("teapot.html")));

  // Wait for message from teapot page indicating the GL calls have been issued.
  ASSERT_TRUE(message_queue.WaitForMessage(NULL));

  SkBitmap bitmap;
  gfx::Size container_size(500, 500);
  ResizeTabContainer(browser(), container_size);
  ASSERT_TRUE(ui_test_utils::TakeRenderWidgetSnapshot(
      browser()->GetSelectedTabContents()->render_view_host(),
      container_size, &bitmap));
  ASSERT_TRUE(CompareImages(bitmap, ""));
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/jsmessage_box_handler.h"

#include "build/build_config.h"
#include "chrome/browser/app_modal_dialog_queue.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/common/gfx/text_elider.h"
#include "chrome/common/l10n_util.h"
#include "chrome/common/message_box_flags.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "googleurl/src/gurl.h"
#include "grit/generated_resources.h"

namespace {

std::wstring GetWindowTitle(WebContents* web_contents, const GURL& frame_url,
                            int dialog_flags) {
  bool is_alert = (dialog_flags == MessageBox::kIsJavascriptAlert);
  if (!frame_url.has_host())
    return l10n_util::GetString(
        is_alert ? IDS_JAVASCRIPT_ALERT_DEFAULT_TITLE
                 : IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE);

  // We really only want the scheme, hostname, and port.
  GURL::Replacements replacements;
  replacements.ClearUsername();
  replacements.ClearPassword();
  replacements.ClearPath();
  replacements.ClearQuery();
  replacements.ClearRef();
  GURL clean_url = frame_url.ReplaceComponents(replacements);

  // TODO(brettw) it should be easier than this to do the correct language
  // handling without getting the accept language from the profile.
  std::wstring base_address = gfx::ElideUrl(clean_url, ChromeFont(), 0,
      web_contents->profile()->GetPrefs()->GetString(prefs::kAcceptLanguages));
  // Force URL to have LTR directionality.
  if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT)
    l10n_util::WrapStringWithLTRFormatting(&base_address);
  return l10n_util::GetStringF(
      is_alert ? IDS_JAVASCRIPT_ALERT_TITLE : IDS_JAVASCRIPT_MESSAGEBOX_TITLE,
      base_address);
}

}

void RunJavascriptMessageBox(WebContents* web_contents,
                             const GURL& frame_url,
                             int dialog_flags,
                             const std::wstring& message_text,
                             const std::wstring& default_prompt_text,
                             bool display_suppress_checkbox,
                             IPC::Message* reply_msg) {
  std::wstring title = GetWindowTitle(web_contents, frame_url, dialog_flags);

#if defined(OS_WIN) || defined(OS_LINUX)
  AppModalDialogQueue::AddDialog(new AppModalDialog(web_contents, title,
      dialog_flags, message_text, default_prompt_text,
      display_suppress_checkbox, false, reply_msg));
#else
  NOTIMPLEMENTED();
#endif
}

void RunBeforeUnloadDialog(WebContents* web_contents,
                           const std::wstring& message_text,
                           IPC::Message* reply_msg) {
  std::wstring full_message =
      message_text + L"\n\n" +
      l10n_util::GetString(IDS_BEFOREUNLOAD_MESSAGEBOX_FOOTER);
#if defined(OS_WIN) || defined(OS_LINUX)
  AppModalDialogQueue::AddDialog(new AppModalDialog(
      web_contents, l10n_util::GetString(IDS_BEFOREUNLOAD_MESSAGEBOX_TITLE),
      MessageBox::kIsJavascriptConfirm, message_text, std::wstring(), false,
      true, reply_msg));
#else
  NOTIMPLEMENTED();
#endif
}
<commit_msg>Clamp text size in js message box dialogs - Long text peg cpu at 100% for a couple of minutes for the UI thread - Now with extra protection for OnUnload()<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/jsmessage_box_handler.h"

#include "build/build_config.h"
#include "chrome/browser/app_modal_dialog_queue.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/common/gfx/text_elider.h"
#include "chrome/common/l10n_util.h"
#include "chrome/common/message_box_flags.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "googleurl/src/gurl.h"
#include "grit/generated_resources.h"

namespace {

const size_t kMaxReasonableTextLength = 2048;

// In some platforms, the underlying processing of humongous strings takes too
// long and thus make the UI thread unresponsive.
std::wstring MakeTextSafe(const std::wstring& text) {
  if (text.size() > kMaxReasonableTextLength)
    return text.substr(0, kMaxReasonableTextLength) + L"\x2026";
  return text;
}

std::wstring GetWindowTitle(WebContents* web_contents, const GURL& frame_url,
                            int dialog_flags) {
  bool is_alert = (dialog_flags == MessageBox::kIsJavascriptAlert);
  if (!frame_url.has_host())
    return l10n_util::GetString(
        is_alert ? IDS_JAVASCRIPT_ALERT_DEFAULT_TITLE
                 : IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE);

  // We really only want the scheme, hostname, and port.
  GURL::Replacements replacements;
  replacements.ClearUsername();
  replacements.ClearPassword();
  replacements.ClearPath();
  replacements.ClearQuery();
  replacements.ClearRef();
  GURL clean_url = frame_url.ReplaceComponents(replacements);

  // TODO(brettw) it should be easier than this to do the correct language
  // handling without getting the accept language from the profile.
  std::wstring base_address = gfx::ElideUrl(clean_url, ChromeFont(), 0,
      web_contents->profile()->GetPrefs()->GetString(prefs::kAcceptLanguages));
  // Force URL to have LTR directionality.
  if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT)
    l10n_util::WrapStringWithLTRFormatting(&base_address);
  return l10n_util::GetStringF(
      is_alert ? IDS_JAVASCRIPT_ALERT_TITLE : IDS_JAVASCRIPT_MESSAGEBOX_TITLE,
      base_address);
}

}

void RunJavascriptMessageBox(WebContents* web_contents,
                             const GURL& frame_url,
                             int dialog_flags,
                             const std::wstring& message_text,
                             const std::wstring& default_prompt_text,
                             bool display_suppress_checkbox,
                             IPC::Message* reply_msg) {
  std::wstring title = GetWindowTitle(web_contents, frame_url, dialog_flags);

#if defined(OS_WIN) || defined(OS_LINUX)
  AppModalDialogQueue::AddDialog(new AppModalDialog(web_contents, title,
      dialog_flags, MakeTextSafe(message_text), default_prompt_text,
      display_suppress_checkbox, false, reply_msg));
#else
  NOTIMPLEMENTED();
#endif
}

void RunBeforeUnloadDialog(WebContents* web_contents,
                           const std::wstring& message_text,
                           IPC::Message* reply_msg) {
  std::wstring full_message =
      message_text + L"\n\n" +
      l10n_util::GetString(IDS_BEFOREUNLOAD_MESSAGEBOX_FOOTER);
#if defined(OS_WIN) || defined(OS_LINUX)
  AppModalDialogQueue::AddDialog(new AppModalDialog(
      web_contents, l10n_util::GetString(IDS_BEFOREUNLOAD_MESSAGEBOX_TITLE),
      MessageBox::kIsJavascriptConfirm, MakeTextSafe(message_text),
      std::wstring(), false, true, reply_msg));
#else
  NOTIMPLEMENTED();
#endif
}
<|endoftext|>


<commit_before>#include "stdafx.h"

int main()
{
    return 0;
}

<commit_msg>Removed stdafx<commit_after>int main()
{
    return 0;
}

<|endoftext|>


<commit_before>
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "BenchSysTimer_mach.h"

//Time
#include <mach/mach.h>
#include <mach/mach_time.h>

static time_value_t macCpuTime() {
    mach_port_t task = mach_task_self();
    if (task == MACH_PORT_NULL) {
        time_value_t none = {0, 0};
        return none;
    }

    task_thread_times_info thread_info_data;
    mach_msg_type_number_t thread_info_count = TASK_THREAD_TIMES_INFO_COUNT;
    if (KERN_SUCCESS != task_info(task,
                 TASK_THREAD_TIMES_INFO,
                 reinterpret_cast<task_info_t>(&thread_info_data),
                 &thread_info_count))
    {
        time_value_t none = {0, 0};
        return none;
    }

    time_value_add(&thread_info_data.user_time, &thread_info_data.system_time)
    return thread_info_data.user_time;
}

static double intervalInMSec(const time_value_t start_clock
                           , const time_value_t end_clock)
{
    double duration_clock;
    if ((end_clock.microseconds - start_clock.microseconds) < 0) {
        duration_clock = (end_clock.seconds - start_clock.seconds-1)*1000;
        duration_clock += (1000000
                           + end_clock.microseconds
                           - start_clock.microseconds) / 1000.0;
    } else {
        duration_clock = (end_clock.seconds - start_clock.seconds)*1000;
        duration_clock += (end_clock.microseconds - start_clock.microseconds)
                           / 1000.0;
    }
    return duration_clock;
}

void BenchSysTimer::startWall() {
    this->fStartWall = mach_absolute_time();
}
void BenchSysTimer::startCpu() {
    this->fStartCpu = macCpuTime();
}

double BenchSysTimer::endCpu() {
    time_value_t end_cpu = macCpuTime();
    return intervalInMSec(this->fStartCpu, end_cpu);
}
double BenchSysTimer::endWall() {
    uint64_t end_wall = mach_absolute_time();

    uint64_t elapsed = end_wall - this->fStartWall;
    mach_timebase_info_data_t sTimebaseInfo;
    if (KERN_SUCCESS != mach_timebase_info(&sTimebaseInfo)) {
        return 0;
    } else {
        uint64_t elapsedNano = elapsed * sTimebaseInfo.numer
                               / sTimebaseInfo.denom;
        return elapsedNano / 1000000;
    }
}
<commit_msg>BenchSysTimer_mach drops all sub-ms precision.  Fix that!<commit_after>
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "BenchSysTimer_mach.h"

//Time
#include <mach/mach.h>
#include <mach/mach_time.h>

static time_value_t macCpuTime() {
    mach_port_t task = mach_task_self();
    if (task == MACH_PORT_NULL) {
        time_value_t none = {0, 0};
        return none;
    }

    task_thread_times_info thread_info_data;
    mach_msg_type_number_t thread_info_count = TASK_THREAD_TIMES_INFO_COUNT;
    if (KERN_SUCCESS != task_info(task,
                 TASK_THREAD_TIMES_INFO,
                 reinterpret_cast<task_info_t>(&thread_info_data),
                 &thread_info_count))
    {
        time_value_t none = {0, 0};
        return none;
    }

    time_value_add(&thread_info_data.user_time, &thread_info_data.system_time)
    return thread_info_data.user_time;
}

static double intervalInMSec(const time_value_t start_clock
                           , const time_value_t end_clock)
{
    double duration_clock;
    if ((end_clock.microseconds - start_clock.microseconds) < 0) {
        duration_clock = (end_clock.seconds - start_clock.seconds-1)*1000;
        duration_clock += (1000000
                           + end_clock.microseconds
                           - start_clock.microseconds) / 1000.0;
    } else {
        duration_clock = (end_clock.seconds - start_clock.seconds)*1000;
        duration_clock += (end_clock.microseconds - start_clock.microseconds)
                           / 1000.0;
    }
    return duration_clock;
}

void BenchSysTimer::startWall() {
    this->fStartWall = mach_absolute_time();
}
void BenchSysTimer::startCpu() {
    this->fStartCpu = macCpuTime();
}

double BenchSysTimer::endCpu() {
    time_value_t end_cpu = macCpuTime();
    return intervalInMSec(this->fStartCpu, end_cpu);
}
double BenchSysTimer::endWall() {
    uint64_t end_wall = mach_absolute_time();

    uint64_t elapsed = end_wall - this->fStartWall;
    mach_timebase_info_data_t sTimebaseInfo;
    if (KERN_SUCCESS != mach_timebase_info(&sTimebaseInfo)) {
        return 0;
    } else {
        uint64_t elapsedNano = elapsed * sTimebaseInfo.numer
                               / sTimebaseInfo.denom;
        return elapsedNano / 1000000.0;
    }
}
<|endoftext|>


<commit_before>// -*- mode: c++; coding: utf-8 -*-
#pragma once

#include <thread>
#include <mutex>
#include <future>
#include <condition_variable>
#include <algorithm>

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////
namespace wtl {
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////

inline unsigned int num_threads() {
    size_t n = std::thread::hardware_concurrency();
    n = std::min(n, 12ul); // do not want to use HT in ilp15
    return std::max(n, 1ul);
}

class Semaphore {
  public:
    Semaphore() = default;
    explicit Semaphore(const size_t n): count_(n) {}

    void lock() {
        std::unique_lock<std::mutex> lck(mutex_);
        condition_.wait(lck, [this](){return count_ > 0;});
        --count_;
    }

    bool try_unlock() {
        std::lock_guard<std::mutex> lck(mutex_);
        if (count_ > 0) {
            --count_;
            return true;
        } else {
            return false;
        }
    }

    void unlock() {
        std::lock_guard<std::mutex> lck(mutex_);
        ++count_;
        condition_.notify_one();
    }

  private:
    std::mutex mutex_;
    std::condition_variable condition_;
    size_t count_ = num_threads();
};

class Pool {
  public:
    explicit Pool(const size_t n=num_threads())
        : semaphore_(n) {}

    ~Pool() {join();}

    template <class Func> inline
    auto async_future (Func&& func) -> std::future<decltype(func())> {
        semaphore_.lock();
        return std::async(std::launch::async, [&] {
            auto result = func();
            semaphore_.unlock();
            return result;
        });
    }

    template <class Func, class... Args> inline
    void async_thread (Func&& func, Args&&... args) {
        semaphore_.lock();
        // TODO: move capture
        workers_.emplace_back([&] {
            func(args...);
            semaphore_.unlock();
        });
    }

    void join() {
        for (auto& x: workers_) {x.join();}
        workers_.clear();
    }

  private:
    Semaphore semaphore_;
    std::vector<std::thread> workers_;
};

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////
} // namespace wtl
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////
<commit_msg>minor fix for unsigned type in multiprocessing.hpp<commit_after>// -*- mode: c++; coding: utf-8 -*-
#pragma once

#include <thread>
#include <mutex>
#include <future>
#include <condition_variable>
#include <algorithm>

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////
namespace wtl {
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////

inline unsigned int num_threads() {
    unsigned int n = std::thread::hardware_concurrency();
    n = std::min(n, 12u); // do not want to use HT in ilp15
    return std::max(n, 1u);
}

class Semaphore {
  public:
    Semaphore() = default;
    explicit Semaphore(const size_t n): count_(n) {}

    void lock() {
        std::unique_lock<std::mutex> lck(mutex_);
        condition_.wait(lck, [this](){return count_ > 0;});
        --count_;
    }

    bool try_unlock() {
        std::lock_guard<std::mutex> lck(mutex_);
        if (count_ > 0) {
            --count_;
            return true;
        } else {
            return false;
        }
    }

    void unlock() {
        std::lock_guard<std::mutex> lck(mutex_);
        ++count_;
        condition_.notify_one();
    }

  private:
    std::mutex mutex_;
    std::condition_variable condition_;
    size_t count_ = num_threads();
};

class Pool {
  public:
    explicit Pool(const size_t n=num_threads())
        : semaphore_(n) {}

    ~Pool() {join();}

    template <class Func> inline
    auto async_future (Func&& func) -> std::future<decltype(func())> {
        semaphore_.lock();
        return std::async(std::launch::async, [&] {
            auto result = func();
            semaphore_.unlock();
            return result;
        });
    }

    template <class Func, class... Args> inline
    void async_thread (Func&& func, Args&&... args) {
        semaphore_.lock();
        // TODO: move capture
        workers_.emplace_back([&] {
            func(args...);
            semaphore_.unlock();
        });
    }

    void join() {
        for (auto& x: workers_) {x.join();}
        workers_.clear();
    }

  private:
    Semaphore semaphore_;
    std::vector<std::thread> workers_;
};

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////
} // namespace wtl
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////
<|endoftext|>


<commit_before>#include "engine/debug/floating_points.h"
#include <float.h>

namespace Lumix
{

void enableFloatingPointTraps(bool enable)
{
	ASSERT(false);
}

} // namespace Lumix<commit_msg>linux - floating point traps - #655<commit_after>#include "engine/debug/floating_points.h"
#include <fenv.h>
#include <float.h>

namespace Lumix
{

void enableFloatingPointTraps(bool enable)
{
	static const int FLAGS = FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW;
	if(enable)
	{
			feenableexcept(FLAGS);
	}
	else
	{
			fedisableexcept(FLAGS);
	}
}

} // namespace Lumix<|endoftext|>


<commit_before>#include "epiphansdk_video_source.h"

namespace gg
{

VideoSourceEpiphanSDK::VideoSourceEpiphanSDK(
    const std::string device_id, V2U_INT32 colour_space)
    : IVideoSource(),
      _frame_grabber(nullptr),
      _flags(0)
{
    FrmGrab_Init();

    _frame_grabber = FrmGrabLocal_OpenSN(device_id.c_str());
    if (not _frame_grabber)
    {
        // TODO - exception GiftGrab#42
        std::cerr << "Could not open " << device_id << std::endl;
        return;
    }

    if (colour_space != V2U_GRABFRAME_FORMAT_I420 and colour_space != V2U_GRABFRAME_FORMAT_BGR24)
    {
        // TODO - exception GiftGrab#42
        std::cerr << "Colour space " << colour_space << " not supported" << std::endl;
        return;
    }
    _flags |= colour_space;

    VideoFrame_I420 frame;
    _full.x = 0;
    _full.y = 0;
    /* TODO - e.g. EpiphanSDK_MAX_RES_X and
     * EpiphanSDK_MAX_RES_Y after
     * EpiphanSDK#6
     */
    _full.width = 1920;
    _full.height = 1080;
    get_full_frame();
    // TODO - exception GiftGrab#42
    if (not get_frame(frame)) return;
}

VideoSourceEpiphanSDK::~VideoSourceEpiphanSDK()
{
    if (_frame_grabber)
    {
        FrmGrab_Release(_frame_grabber, _buffer);
        FrmGrab_Close(_frame_grabber);
    }
    FrmGrab_Deinit();
}

bool VideoSourceEpiphanSDK::get_frame_dimensions(int & width, int & height)
{
    width = _roi.width;
    height = _roi.height;
    return true;
}

bool VideoSourceEpiphanSDK::get_frame(VideoFrame_BGRA & frame)
{
    // TODO - exception GiftGrab#42
    return false;
}

bool VideoSourceEpiphanSDK::get_frame(VideoFrame_I420 & frame)
{
    _buffer = FrmGrab_Frame(_frame_grabber, _flags, &_roi);
    if (_buffer)
    {
        frame = VideoFrame_I420(
                    static_cast<unsigned char*>(_buffer->pixbuf),
                    _buffer->imagelen,
                    /* TODO #54 specified _roi not always
                     * respected by FrmGrab_Frame, hence
                     * constructing with _buffer->crop
                     * instead of _roi to avoid alignment
                     * problems when saving to video files
                     */
                    _buffer->crop.width, _buffer->crop.height,
                    false
                    );
        return true;
    }
    else
        return false;
}

double VideoSourceEpiphanSDK::get_frame_rate()
{
    if (_frame_grabber)
    {
#if defined(EpiphanSDK_DVI) and \
    defined(EpiphanSDK_SDI) and \
    defined(EpiphanSDK_DVI_MAX_FRAME_RATE) and \
    defined(EpiphanSDK_SDI_MAX_FRAME_RATE)
        std::string port_id = FrmGrab_GetId(_frame_grabber);
        if (port_id == EpiphanSDK_DVI)
            return EpiphanSDK_DVI_MAX_FRAME_RATE;
        else if (port_id == EpiphanSDK_SDI)
            return EpiphanSDK_SDI_MAX_FRAME_RATE;
#endif
    }

    // TODO - exception GiftGrab#42
    return 0;
}

void VideoSourceEpiphanSDK::set_sub_frame(int x, int y, int width, int height)
{
    if (x >= _full.x and x + width <= _full.x + _full.width and
        y >= _full.y and y + height <= _full.y + _full.height)
    {
        _roi.x = x;
        _roi.y = y;
        _roi.width = width;
        _roi.height = height;
    }
    // TODO - exception GiftGrab#42
//    else
//        throw VideoSourceError("ROI " + std::to_string(x) + ", " +
//                               std::to_string(y) + ", " +
//                               std::to_string(width) + ", " +
//                               std::to_string(height) + ", " +
//                               "not within full frame");
}

void VideoSourceEpiphanSDK::get_full_frame()
{
    _roi.x = _full.x;
    _roi.y = _full.y;
    _roi.width = _full.width;
    _roi.height = _full.height;
}

}
<commit_msg>Issue #43: releasing _buffer after capture to avoid memory leak<commit_after>#include "epiphansdk_video_source.h"

namespace gg
{

VideoSourceEpiphanSDK::VideoSourceEpiphanSDK(
    const std::string device_id, V2U_INT32 colour_space)
    : IVideoSource(),
      _frame_grabber(nullptr),
      _flags(0)
{
    FrmGrab_Init();

    _frame_grabber = FrmGrabLocal_OpenSN(device_id.c_str());
    if (not _frame_grabber)
    {
        // TODO - exception GiftGrab#42
        std::cerr << "Could not open " << device_id << std::endl;
        return;
    }

    if (colour_space != V2U_GRABFRAME_FORMAT_I420 and colour_space != V2U_GRABFRAME_FORMAT_BGR24)
    {
        // TODO - exception GiftGrab#42
        std::cerr << "Colour space " << colour_space << " not supported" << std::endl;
        return;
    }
    _flags |= colour_space;

    VideoFrame_I420 frame;
    _full.x = 0;
    _full.y = 0;
    /* TODO - e.g. EpiphanSDK_MAX_RES_X and
     * EpiphanSDK_MAX_RES_Y after
     * EpiphanSDK#6
     */
    _full.width = 1920;
    _full.height = 1080;
    get_full_frame();
    // TODO - exception GiftGrab#42
    if (not get_frame(frame)) return;
}

VideoSourceEpiphanSDK::~VideoSourceEpiphanSDK()
{
    if (_frame_grabber)
    {
        if (_buffer) FrmGrab_Release(_frame_grabber, _buffer);
        FrmGrab_Close(_frame_grabber);
    }
    FrmGrab_Deinit();
}

bool VideoSourceEpiphanSDK::get_frame_dimensions(int & width, int & height)
{
    width = _roi.width;
    height = _roi.height;
    return true;
}

bool VideoSourceEpiphanSDK::get_frame(VideoFrame_BGRA & frame)
{
    // TODO - exception GiftGrab#42
    return false;
}

bool VideoSourceEpiphanSDK::get_frame(VideoFrame_I420 & frame)
{
    _buffer = FrmGrab_Frame(_frame_grabber, _flags, &_roi);
    if (_buffer)
    {
        frame = VideoFrame_I420(
                    static_cast<unsigned char*>(_buffer->pixbuf),
                    _buffer->imagelen,
                    /* TODO #54 specified _roi not always
                     * respected by FrmGrab_Frame, hence
                     * constructing with _buffer->crop
                     * instead of _roi to avoid alignment
                     * problems when saving to video files
                     */
                    _buffer->crop.width, _buffer->crop.height,
                    false
                    );
        FrmGrab_Release(_frame_grabber, _buffer);
        return true;
    }
    else
        return false;
}

double VideoSourceEpiphanSDK::get_frame_rate()
{
    if (_frame_grabber)
    {
#if defined(EpiphanSDK_DVI) and \
    defined(EpiphanSDK_SDI) and \
    defined(EpiphanSDK_DVI_MAX_FRAME_RATE) and \
    defined(EpiphanSDK_SDI_MAX_FRAME_RATE)
        std::string port_id = FrmGrab_GetId(_frame_grabber);
        if (port_id == EpiphanSDK_DVI)
            return EpiphanSDK_DVI_MAX_FRAME_RATE;
        else if (port_id == EpiphanSDK_SDI)
            return EpiphanSDK_SDI_MAX_FRAME_RATE;
#endif
    }

    // TODO - exception GiftGrab#42
    return 0;
}

void VideoSourceEpiphanSDK::set_sub_frame(int x, int y, int width, int height)
{
    if (x >= _full.x and x + width <= _full.x + _full.width and
        y >= _full.y and y + height <= _full.y + _full.height)
    {
        _roi.x = x;
        _roi.y = y;
        _roi.width = width;
        _roi.height = height;
    }
    // TODO - exception GiftGrab#42
//    else
//        throw VideoSourceError("ROI " + std::to_string(x) + ", " +
//                               std::to_string(y) + ", " +
//                               std::to_string(width) + ", " +
//                               std::to_string(height) + ", " +
//                               "not within full frame");
}

void VideoSourceEpiphanSDK::get_full_frame()
{
    _roi.x = _full.x;
    _roi.y = _full.y;
    _roi.width = _full.width;
    _roi.height = _full.height;
}

}
<|endoftext|>


<commit_before><commit_msg>Don't strip scheme from parameter when running external protocol handler<commit_after><|endoftext|>