<commit_before>#include <iostream>
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>

#include "boxedcpp.hpp"

struct Test
{
  Test()
    : md(0)
  {
  }

  Test(const std::string &s)
    : message(s), md(0)
  {
    std::cout << "Test class constructed with value: " << s << std::endl;
  }

  void show_message()
  {
    std::cout << "Constructed Message: " << message << std::endl;
  }

  std::string &get_message()
  {
    return message;
  }

  int method(double d)
  {
    md += d;
    std::cout << "Method called " << md << std::endl;
    return int(md);
  }

  std::string message;
  double md;
};

void print(const std::string &s)
{
  std::cout << "Printed: " << s << std::endl;
}

//Test main
int main()
{
  BoxedCPP_System ss;
  bootstrap(ss);
  dump_system(ss);

  //Calling a function by name and allowing the built in dispatch mechanism to
  //choose the most appropriate version of the function
  Boxed_Value addresult = dispatch(ss.get_function("+"), Param_List_Builder() << double(5.1) << double(10.3));

  //Using the Cast_Helper to unbox the resultant value and output it
  std::cout << Cast_Helper<double>()(addresult) << std::endl;

  //Using the Boxed_Value as input to another function, again with automatic dispatch.
  //This time we will not bother saving the result and will instead send it straight out
  std::cout << Cast_Helper<double>()(
      dispatch(ss.get_function("*"), Param_List_Builder() << 2 << addresult)
      ) << std::endl;

  //Register a new function, this one with typing for us, so we don't have to ubox anything
  //right here
  //JDT: Was giving me compiler errors (not sure why)
  //ss.register_function(boost::function<void (const std::string &)>(&print), "print");

  //Now we have a print method, let's try to print out the earlier example:
  //so, we dispatch the to_string and pass its result as a param to "print"
  //In this example we don't bother with temporaries and we don't have to know
  //anything about types
  dispatch(ss.get_function("print"),
      Param_List_Builder() << dispatch(ss.get_function("to_string"), Param_List_Builder() << addresult));

  //
  //
  /* Older tests
  ss.register_type<Test>("Test");
  ss.register_function(boost::function<int (Test*, double)>(&Test::method), "method");
  ss.register_function(boost::function<std::string (const std::string &)>(&testprint), "print");
  ss.register_function(boost::function<void ()>(&print), "voidfunc");
  ss.register_function(build_constructor<Test, const std::string &>(), "Test");
  ss.register_function(boost::function<void (Test*)>(&Test::show_message), "show_message");
  ss.register_function(boost::function<std::string &(Test*)>(&Test::get_message), "get_message");

  ss.add_object("testobj", boost::shared_ptr<Test>(new Test()));
  ss.add_object("d", boost::shared_ptr<double>(new double(10.2)));
  ss.add_object("str", std::string("Hello World"));

  std::vector<Boxed_Value> sos;
  sos.push_back(ss.get_object("testobj"));
  sos.push_back(ss.get_object("d"));

  boost::shared_ptr<Proxy_Function> method1(ss.get_function("method").front().second);
  (*method1)(sos);
  (*method1)(sos);
  Boxed_Value o = (*method1)(sos);

  dispatch(ss.get_function("print"), Param_List_Builder() << ss.get_object("str"));

  //Add new dynamically created object from registered "Test" constructor
  ss.add_object("testobj2", dispatch(ss.get_function("Test"), Param_List_Builder() << std::string("Yo")));

  std::cout << Cast_Helper<int>()(o) << std::endl;

  dispatch(ss.get_function("voidfunc"), Param_List_Builder());

  std::vector<Boxed_Value> sos3;
  sos3.push_back(ss.get_object("testobj2"));
  dispatch(ss.get_function("show_message"), sos3);

  Boxed_Value stringref = dispatch(ss.get_function("get_message"), sos3);

  std::string &sr = Cast_Helper<std::string &>()(stringref);
  sr = "Bob Updated The message";

  dispatch(ss.get_function("show_message"), sos3);
  */
}

<commit_msg>Try and fix jon's print problem<commit_after>#include <iostream>
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>

#include "boxedcpp.hpp"

struct Test
{
  Test()
    : md(0)
  {
  }

  Test(const std::string &s)
    : message(s), md(0)
  {
    std::cout << "Test class constructed with value: " << s << std::endl;
  }

  void show_message()
  {
    std::cout << "Constructed Message: " << message << std::endl;
  }

  std::string &get_message()
  {
    return message;
  }

  int method(double d)
  {
    md += d;
    std::cout << "Method called " << md << std::endl;
    return int(md);
  }

  std::string message;
  double md;
};

void print_out(const std::string &s)
{
  std::cout << "Printed: " << s << std::endl;
}

//Test main
int main()
{
  BoxedCPP_System ss;
  bootstrap(ss);
  dump_system(ss);

  //Calling a function by name and allowing the built in dispatch mechanism to
  //choose the most appropriate version of the function
  Boxed_Value addresult = dispatch(ss.get_function("+"), Param_List_Builder() << double(5.1) << double(10.3));

  //Using the Cast_Helper to unbox the resultant value and output it
  std::cout << Cast_Helper<double>()(addresult) << std::endl;

  //Using the Boxed_Value as input to another function, again with automatic dispatch.
  //This time we will not bother saving the result and will instead send it straight out
  std::cout << Cast_Helper<double>()(
      dispatch(ss.get_function("*"), Param_List_Builder() << 2 << addresult)
      ) << std::endl;

  //Register a new function, this one with typing for us, so we don't have to ubox anything
  //right here
  //JDT: Was giving me compiler errors (not sure why)
  ss.register_function(boost::function<void (const std::string &)>(&print_out), "print");

  //Now we have a print method, let's try to print out the earlier example:
  //so, we dispatch the to_string and pass its result as a param to "print"
  //In this example we don't bother with temporaries and we don't have to know
  //anything about types
  dispatch(ss.get_function("print"),
      Param_List_Builder() << dispatch(ss.get_function("to_string"), Param_List_Builder() << addresult));

  //
  //
  /* Older tests
  ss.register_type<Test>("Test");
  ss.register_function(boost::function<int (Test*, double)>(&Test::method), "method");
  ss.register_function(boost::function<std::string (const std::string &)>(&testprint), "print");
  ss.register_function(boost::function<void ()>(&print), "voidfunc");
  ss.register_function(build_constructor<Test, const std::string &>(), "Test");
  ss.register_function(boost::function<void (Test*)>(&Test::show_message), "show_message");
  ss.register_function(boost::function<std::string &(Test*)>(&Test::get_message), "get_message");

  ss.add_object("testobj", boost::shared_ptr<Test>(new Test()));
  ss.add_object("d", boost::shared_ptr<double>(new double(10.2)));
  ss.add_object("str", std::string("Hello World"));

  std::vector<Boxed_Value> sos;
  sos.push_back(ss.get_object("testobj"));
  sos.push_back(ss.get_object("d"));

  boost::shared_ptr<Proxy_Function> method1(ss.get_function("method").front().second);
  (*method1)(sos);
  (*method1)(sos);
  Boxed_Value o = (*method1)(sos);

  dispatch(ss.get_function("print"), Param_List_Builder() << ss.get_object("str"));

  //Add new dynamically created object from registered "Test" constructor
  ss.add_object("testobj2", dispatch(ss.get_function("Test"), Param_List_Builder() << std::string("Yo")));

  std::cout << Cast_Helper<int>()(o) << std::endl;

  dispatch(ss.get_function("voidfunc"), Param_List_Builder());

  std::vector<Boxed_Value> sos3;
  sos3.push_back(ss.get_object("testobj2"));
  dispatch(ss.get_function("show_message"), sos3);

  Boxed_Value stringref = dispatch(ss.get_function("get_message"), sos3);

  std::string &sr = Cast_Helper<std::string &>()(stringref);
  sr = "Bob Updated The message";

  dispatch(ss.get_function("show_message"), sos3);
  */
}

<|endoftext|>


<commit_before>#include "Platform.hpp"
#include "Synapse.hpp"
#include "Neuron.hpp"
#include "genome.pb.h"
#include "ActivityStats.hpp"
#include "Brain.hpp"
#include "SpatialSearch.hpp"
//Takes care of disconnecting DendriteTip. Should be called in destructor

namespace Elysia {
	class Neuron;

Synapse::Synapse(CellComponent * parent){
	mParentBranch = parent;
	mBrain=parent->getParentNeuron()->getBrain();
	mRecipientNeuron = NULL;
	mFiringWindow = 10;		//How long a neuron will fire for. FIXME: This needs to be passed from the gene someday
	mFiringCounter = 0;
    mWhere=mBrain->activeSynapseListSentinel();
}

bool Synapse::detach(){
    if (mRecipientNeuron) {
        mRecipientNeuron->removeSynapse(this);
        mRecipientNeuron = NULL;
        return true;
    }
    return false;
}

void Synapse::connect(){
    if(mRecipientNeuron){this->detach();}
    Neuron * parentNeuron = mParentBranch->getParentNeuron();
    Brain *parentBrain = parentNeuron->getBrain();
    float age = parentBrain->getAge();
    Vector3f targetLocation = parentNeuron->getProteinDensityStructure().getRandomTargetPoint(age);
    mRecipientNeuron = parentBrain->getSpatialSearch()->findNearestNeighbor(targetLocation, parentNeuron);
    if (mRecipientNeuron) {
      //Nearest neighbor target
      mConnectionStrength = 1.0f;
      mRecipientNeuron->attachSynapse(this);
    }
}

bool pickrandomlocaton(Elysia::Genome::Gene gene, float age, Vector3f& retval){
    int numregions;
    numregions = gene.target_region_size();
    std::vector<BoundingBox3f3f> activeRegions;
    for(int i=0;i<numregions;i++){
        Elysia::Genome::TemporalBoundingBox boundingbox;
        boundingbox = gene.target_region(i);
        if((boundingbox.has_mint()==false||age>=boundingbox.mint()) && (boundingbox.has_maxt()==false||age<=boundingbox.maxt())) {
            activeRegions.push_back(BoundingBox3f3f(Vector3f(boundingbox.minx(),boundingbox.miny(),boundingbox.has_minz()?boundingbox.minz():0.0f),
                                                    Vector3f(boundingbox.maxx(),boundingbox.maxy(),boundingbox.has_maxz()?boundingbox.maxz():0.0f)));
        }
        //active regions

    }
    if (activeRegions.empty()) {
      return false;
    }
    unsigned int randomchoice = rand()%activeRegions.size();

    BoundingBox3f3f desiredregion = activeRegions[randomchoice];
    Vector3f delta =desiredregion.max() - desiredregion.min();
    Vector3f coord = Vector3f(delta.x*rand()/(float)RAND_MAX,
                              delta.y*rand()/(float)RAND_MAX,
                              delta.z*rand()/(float)RAND_MAX)+desiredregion.min();
    retval=coord;
    return true;
}

void Synapse::fireSynapse(){

	if(mFiringCounter == 0){
	  //assert(mWhere= mBrain->activeSynapseListSentinel()); //Wait, why is this here?
	mWhere = mBrain->activateSynapse(this);
	}
	mFiringCounter = mFiringWindow;
    //Tick function determines when to fire the synapses from the neurons
}

void Synapse::residualFire(){
	if(mFiringCounter > 0){
		mFiringCounter--;
		if(mFiringCounter == 0){
			mBrain->inactivateSynapse(this);
		}
		mParentBranch->activateComponent(*mBrain, mSignalWeight);
	}
	else{
		assert(this);
	}
}

void Synapse::develop(const ActivityStats& stats){
	float strengthenAmount=0.0f;
	int earlyDevelopmentWindow = 40;	//How many concurrent synapses firing is required to move to "mid-development"
	float initialStrengthen = 0.04f;		//How much to strengthen a firing synapse in early development
	float initialWeaken = -0.01f;
	float changeSize = 0.1f;				//Controls how quickly strengthening and weakening happen in mid-development
	float maxStrengthen = 0.1f;			//Maximum amount to strengthen in mid-development
	float maxWeaken = -0.04f;			//Maximum amount to weaken in mid-development
	float strengthenRange = 2.0f;		//The multiplier to the level of signal that determines how much and whether to strengthen the synapse

    if(mRecipientNeuron){
    	if(stats.mBestDevelopmentSignal < earlyDevelopmentWindow){				//Neuron still in early state
	    	if(mFiringCounter > 0){							//If the synapse is active and not helping the neuron, weaken. If it is active and is helping, strengthen
	    		mConnectionStrength += initialStrengthen;					//Strengthen weakly in beginning
	    	}
	    	else{
	    		mConnectionStrength += initialWeaken;
	    	}
	    }
	    else{
	    	if(stats.mBestDevelopmentSignal >= earlyDevelopmentWindow ){
	    		if(mFiringCounter > 0){
	    			strengthenAmount = changeSize*(strengthenRange*stats.mDevelopmentSignal - stats.mBestDevelopmentSignal)/(stats.mDevelopmentSignal+0.001f);
	    			if(strengthenAmount > maxStrengthen){strengthenAmount = maxStrengthen;}
	    			if(strengthenAmount < maxWeaken){strengthenAmount = maxWeaken;}
	    			mConnectionStrength += strengthenAmount;
	    		}
	    		else{
	    			strengthenAmount = stats.mDevelopmentSignal/(10*stats.mBestDevelopmentSignal);
	    			if(strengthenAmount < maxWeaken){strengthenAmount = maxWeaken;}
	    			mConnectionStrength += strengthenAmount;
	    		}
	    	}
	    	else{ assert(0);}
	    }
    }
    else{
        this->connect();
    }
}

void Synapse::visualizeSynapse(FILE *dendriteTree, size_t parent){
    size_t self;
	size_t recipient;
    self = size_t(this);
	recipient = size_t(mRecipientNeuron);
	fprintf(dendriteTree,"%lu [style=\"filled\" fillcolor=\"#00FF00\"];\n",self);
	fprintf(dendriteTree,"%lu -- %lu;\n",parent,self);
	fprintf(dendriteTree,"%lu [style=\"filled\" fillcolor=\"#FF0000\"];\n",recipient);
	fprintf(dendriteTree,"%lu -- %lu;\n",self,recipient);
}

}

<commit_msg>Initialized signal weight<commit_after>#include "Platform.hpp"
#include "Synapse.hpp"
#include "Neuron.hpp"
#include "genome.pb.h"
#include "ActivityStats.hpp"
#include "Brain.hpp"
#include "SpatialSearch.hpp"
//Takes care of disconnecting DendriteTip. Should be called in destructor

namespace Elysia {
	class Neuron;

Synapse::Synapse(CellComponent * parent){
	mParentBranch = parent;
	mBrain=parent->getParentNeuron()->getBrain();
	mRecipientNeuron = NULL;
	mSignalWeight = 1.0f;	//This is the strength of the signal passed to activated branches. In the future, we may want to make it dynamic to allow certain synapses to have more force.
	mFiringWindow = 10;		//How long a neuron will fire for. FIXME: This needs to be passed from the gene someday
	mFiringCounter = 0;
    mWhere=mBrain->activeSynapseListSentinel();
}

bool Synapse::detach(){
    if (mRecipientNeuron) {
        mRecipientNeuron->removeSynapse(this);
        mRecipientNeuron = NULL;
        return true;
    }
    return false;
}

void Synapse::connect(){
    if(mRecipientNeuron){this->detach();}
    Neuron * parentNeuron = mParentBranch->getParentNeuron();
    Brain *parentBrain = parentNeuron->getBrain();
    float age = parentBrain->getAge();
    Vector3f targetLocation = parentNeuron->getProteinDensityStructure().getRandomTargetPoint(age);
    mRecipientNeuron = parentBrain->getSpatialSearch()->findNearestNeighbor(targetLocation, parentNeuron);
    if (mRecipientNeuron) {
      //Nearest neighbor target
      mConnectionStrength = 1.0f;
      mRecipientNeuron->attachSynapse(this);
    }
}

bool pickrandomlocaton(Elysia::Genome::Gene gene, float age, Vector3f& retval){
    int numregions;
    numregions = gene.target_region_size();
    std::vector<BoundingBox3f3f> activeRegions;
    for(int i=0;i<numregions;i++){
        Elysia::Genome::TemporalBoundingBox boundingbox;
        boundingbox = gene.target_region(i);
        if((boundingbox.has_mint()==false||age>=boundingbox.mint()) && (boundingbox.has_maxt()==false||age<=boundingbox.maxt())) {
            activeRegions.push_back(BoundingBox3f3f(Vector3f(boundingbox.minx(),boundingbox.miny(),boundingbox.has_minz()?boundingbox.minz():0.0f),
                                                    Vector3f(boundingbox.maxx(),boundingbox.maxy(),boundingbox.has_maxz()?boundingbox.maxz():0.0f)));
        }
        //active regions

    }
    if (activeRegions.empty()) {
      return false;
    }
    unsigned int randomchoice = rand()%activeRegions.size();

    BoundingBox3f3f desiredregion = activeRegions[randomchoice];
    Vector3f delta =desiredregion.max() - desiredregion.min();
    Vector3f coord = Vector3f(delta.x*rand()/(float)RAND_MAX,
                              delta.y*rand()/(float)RAND_MAX,
                              delta.z*rand()/(float)RAND_MAX)+desiredregion.min();
    retval=coord;
    return true;
}

void Synapse::fireSynapse(){

	if(mFiringCounter == 0){
	  //assert(mWhere= mBrain->activeSynapseListSentinel()); //Wait, why is this here?
	mWhere = mBrain->activateSynapse(this);
	}
	mFiringCounter = mFiringWindow;
    //Tick function determines when to fire the synapses from the neurons
}

void Synapse::residualFire(){
	if(mFiringCounter > 0){
		mFiringCounter--;
		if(mFiringCounter == 0){
			mBrain->inactivateSynapse(this);
		}
		mParentBranch->activateComponent(*mBrain, mSignalWeight);
	}
	else{
		assert(this);
	}
}

void Synapse::develop(const ActivityStats& stats){
	float strengthenAmount=0.0f;
	int earlyDevelopmentWindow = 40;	//How many concurrent synapses firing is required to move to "mid-development"
	float initialStrengthen = 0.04f;		//How much to strengthen a firing synapse in early development
	float initialWeaken = -0.01f;
	float changeSize = 0.1f;				//Controls how quickly strengthening and weakening happen in mid-development
	float maxStrengthen = 0.1f;			//Maximum amount to strengthen in mid-development
	float maxWeaken = -0.04f;			//Maximum amount to weaken in mid-development
	float strengthenRange = 2.0f;		//The multiplier to the level of signal that determines how much and whether to strengthen the synapse

    if(mRecipientNeuron){
    	if(stats.mBestDevelopmentSignal < earlyDevelopmentWindow){				//Neuron still in early state
	    	if(mFiringCounter > 0){							//If the synapse is active and not helping the neuron, weaken. If it is active and is helping, strengthen
	    		mConnectionStrength += initialStrengthen;					//Strengthen weakly in beginning
	    	}
	    	else{
	    		mConnectionStrength += initialWeaken;
	    	}
	    }
	    else{
	    	if(stats.mBestDevelopmentSignal >= earlyDevelopmentWindow ){
	    		if(mFiringCounter > 0){
	    			strengthenAmount = changeSize*(strengthenRange*stats.mDevelopmentSignal - stats.mBestDevelopmentSignal)/(stats.mDevelopmentSignal+0.001f);
	    			if(strengthenAmount > maxStrengthen){strengthenAmount = maxStrengthen;}
	    			if(strengthenAmount < maxWeaken){strengthenAmount = maxWeaken;}
	    			mConnectionStrength += strengthenAmount;
	    		}
	    		else{
	    			strengthenAmount = stats.mDevelopmentSignal/(10*stats.mBestDevelopmentSignal);
	    			if(strengthenAmount < maxWeaken){strengthenAmount = maxWeaken;}
	    			mConnectionStrength += strengthenAmount;
	    		}
	    	}
	    	else{ assert(0);}
	    }
    }
    else{
        this->connect();
    }
}

void Synapse::visualizeSynapse(FILE *dendriteTree, size_t parent){
    size_t self;
	size_t recipient;
    self = size_t(this);
	recipient = size_t(mRecipientNeuron);
	fprintf(dendriteTree,"%lu [style=\"filled\" fillcolor=\"#00FF00\"];\n",self);
	fprintf(dendriteTree,"%lu -- %lu;\n",parent,self);
	fprintf(dendriteTree,"%lu [style=\"filled\" fillcolor=\"#FF0000\"];\n",recipient);
	fprintf(dendriteTree,"%lu -- %lu;\n",self,recipient);
}

}

<|endoftext|>


<commit_before>/*
 * Copyright 2015 Lu LIU
 * =====================================================================================
 *
 *       Filename:  bridge-finder.cpp
 *
 *    Description:  A C++ program to find the single bridge in an undirected
 *                  graph. The problem is from MapBox directions team's hiring
 *                  page. Please refer to
 *                  http://www.mapbox.com/blog/directions-hiring/
 *
 *        Version:  1.0
 *        Created:  2015/01/10 16时35分46秒
 *       Revision:  none
 *       Compiler:  gcc
 *             OS:  Mac OS X 10.10.1
 *
 *         Author:  Lu LIU (lliu), nudtlliu@gmail.com
 *   Organization:  higis@dbrg
 *
 * =====================================================================================
 */

#include <stdlib.h>
#include <sys/time.h>
#include <iostream>
#include <list>
#include <ctime>
#include <cstdint>
#include <algorithm>
#define NIL -1
#define MAX_DEGREE 7
#define MIN_DEGREE 3

using std::cout;
using std::cin;
using std::endl;
using std::fixed;
using std::list;
using std::min;

typedef uint64_t uint64;
typedef unsigned int uint;

/*
 * =====================================================================================
 *        Class:  SingleBridgeGraph
 *  Description:  A class that represents a single-bridge undirected graph
 * =====================================================================================
 */
class SingleBridgeGraph {
  // number of vertices and edges
  int V, E;
  // A dynamic array of adjacency lists
  list<int> *adj;
  void bridgeProbe(int v, bool visited[], int disc[], int low[], int parent[]);
  uint64 getCurrentTimeMs();

public:
  explicit SingleBridgeGraph(int V);
  void addEdge(int v, int w);
  void findBridges();
};

/*
 *--------------------------------------------------------------------------------------
 *       Class:  SingleBridgeGraph
 *      Method:  SingleBridgeGraph :: SingleBridgeGraph
 * Description:  Create a graph with following attributes:
 *               1. the number of vertex is given by user input;
 *               2. for each vertex, random number (between MIN_DEGREE and
 *                  MAX_DEGREE) of neighbors will be attached;
 *               3. there must be ONLY one bridge in the graph.
 *--------------------------------------------------------------------------------------
 */
SingleBridgeGraph::SingleBridgeGraph(int V) {
  uint64 startTime = getCurrentTimeMs();
  this->V = V;
  this->E = 0;
  adj = new list<int>[V];
  // Two seperated sub-graphs will be constructed respectively.
  // Their number of vertices (V1 and V2) are randomly determined, but the sum
  // is V.
  int V1, V2;
  uint seed = static_cast<uint>(time(0));
  V1 = rand_r(&seed) % V;
  V2 = V - V1;
  // According to the "each vertex has at least 3 neighbors" request, there
  // should be at least 8 vertices in the graph (4 for each sub-graph).
  while (V1 < 4 || V2 < 4) {
    seed = static_cast<uint>(time(0));
    V1 = rand_r(&seed) % V;
    V2 = V - V1;
  }
  cout << endl << " " << V1
       << " vertices are randomly selected to construct the 1st sub-graph"
       << endl;
  cout << endl << " " << V2
       << " vertices are randomly selected to construct the 2nd sub-graph"
       << endl;
  // vertex id list for the two sub-graphs: [0..V1-1] and [V1, V-1]
  int degree = 0;
  cout << endl << " Generating the single-bridge graph... " << endl;
  double progress = 0.0;
  for (int i = 0; i < V; i++) {
    // randomly determine the number of neighbors for the current vertex
    progress = static_cast<double>(i + 1) / static_cast<double>(V) * 100.0;
    cout.precision(1);
    cout << fixed << progress << "%\r";
    cout.flush();
    seed = static_cast<uint>(time(0));
    degree = rand_r(&seed) % (MAX_DEGREE - MIN_DEGREE + 1) + MIN_DEGREE;
    int n = degree - adj[i].size();
    for (int j = 0; j < n; j++) {
      // randomly determine these neighbors
      // they should be unique, and not be the current vertex (otherwise there
      // will be a cycle)
      int randomNeighbor =
          i < V1 ? rand_r(&seed) % V1 : rand_r(&seed) % V2 + V1;
      bool found =
          (find(adj[i].begin(), adj[i].end(), randomNeighbor) != adj[i].end());
      while (randomNeighbor == i || found == true) {
        seed = static_cast<uint>(time(0));
        randomNeighbor = i < V1 ? rand_r(&seed) % V1 : rand_r(&seed) % V2 + V1;
        found = (find(adj[i].begin(), adj[i].end(), randomNeighbor) !=
                 adj[i].end());
      }
      addEdge(i, randomNeighbor);
    }
  }
  cout << " done!" << endl;
  cout << endl << " Randomly build a bridge between the two sub-graphs... ";
  seed = static_cast<uint>(time(0));
  int bridgeVertex1 = rand_r(&seed) % V1;
  int bridgeVertex2 = rand_r(&seed) % V2 + V1;
  addEdge(bridgeVertex1, bridgeVertex2);
  uint64 elapsedTime = getCurrentTimeMs() - startTime;
  cout << " done!" << endl;
  cout << endl << " The built bridge is (" << bridgeVertex1 << ", "
       << bridgeVertex2 << ")." << endl;
  cout << endl << " A graph with " << V << " vertices and " << this->E
       << " undirected edges has been constructed." << endl;
  cout << " Time consumed for graph construction: " << elapsedTime << " ms"
       << endl;
}

/*
 *--------------------------------------------------------------------------------------
 *       Class:  SingleBridgeGraph
 *      Method:  SingleBridgeGraph :: addEdge
 * Description:  add forward and backward edges to the graph between u and v
 *--------------------------------------------------------------------------------------
 */
void SingleBridgeGraph::addEdge(int u, int v) {
  adj[u].push_back(v);
  adj[v].push_back(u);
  E++;
}

/*
 *--------------------------------------------------------------------------------------
 *       Class:  SingleBridgeGraph
 *      Method:  SingleBridgeGraph :: getCurrentTimeMs
 * Description:  Get current time in milliseconds
 *--------------------------------------------------------------------------------------
 */
uint64 SingleBridgeGraph::getCurrentTimeMs() {
  struct timeval tv;
  gettimeofday(&tv, NULL);
  uint64 ret = tv.tv_usec;
  ret /= 1000;
  ret += (tv.tv_sec * 1000);
  return ret;
}

/*
 *--------------------------------------------------------------------------------------
 *       Class:  SingleBridgeGraph
 *      Method:  SingleBridgeGraph :: bridgeProbe
 * Description:  A recursive function that finds and prints bridges using DFS
 *               traversal.
 *               u --> The vertex to be visited next
 *               visited[] --> keeps track of visited vertices
 *               disc[] --> Stores discovery times of visited vertices
 *               parent[] --> Stores parent vertices in DFS tree
 *--------------------------------------------------------------------------------------
 */
void SingleBridgeGraph::bridgeProbe(int u, bool visited[], int disc[],
                                    int low[], int parent[]) {
  static int time = 0;
  // Mark the current node as visited
  visited[u] = true;
  // Initialize discovery time and low value
  disc[u] = low[u] = ++time;
  // Go through all vertices adjacent to this
  list<int>::iterator i;
  for (i = adj[u].begin(); i != adj[u].end(); ++i) {
    int v = *i;
    // If v is not visited yet, then recur for it
    if (!visited[v]) {
      parent[v] = u;
      bridgeProbe(v, visited, disc, low, parent);
      // Check if the subtree rooted with v has a connection to
      // one of the ancestors of u
      low[u] = min(low[u], low[v]);
      // If the lowest vertex reachable from subtree under v is
      // below u in DFS tree, then u-v is a bridge
      if (low[v] > disc[u])
        cout << endl << " Found it! The bridge is (" << u << ", " << v << ")."
             << endl;
    } else if (v != parent[u]) {
      // Update low value of u for parent function calls.
      low[u] = min(low[u], disc[v]);
    }
  }
}

/*
 *--------------------------------------------------------------------------------------
 *       Class:  SingleBridgeGraph
 *      Method:  SingleBridgeGraph :: findBridges
 * Description:  DFS based function to find all bridges. It uses recursive
 *               function bridgeProbe(). Please note that the method is not
 *               invented by me. The findBridges() and bridgeProbe() functions
 *               are modified from that on
 *               [geeksforgeeks.org](http://www.geeksforgeeks.org/bridge-in-a-graph/)
 *--------------------------------------------------------------------------------------
 */
void SingleBridgeGraph::findBridges() {
  // Mark all the vertices as not visited
  bool *visited = new bool[V];
  int *disc = new int[V];
  int *low = new int[V];
  int *parent = new int[V];

  uint64 startTime = getCurrentTimeMs();
  // Initialize parent and visited arrays
  for (int i = 0; i < V; i++) {
    parent[i] = NIL;
    visited[i] = false;
  }

  // Call the recursive helper function to find Bridges
  // in DFS tree rooted with vertex 'i'
  for (int i = 0; i < V; i++)
    if (visited[i] == false)
      bridgeProbe(i, visited, disc, low, parent);
  uint64 elapsedTime = getCurrentTimeMs() - startTime;
  cout << " Time consumed for finding the bridge: " << elapsedTime << " ms"
       << endl;
}

int main() {
  int V;
  cout << endl << " # Find the single bridge in a graph " << endl << endl;
  cout << " This is an interesting problem posted by MapBox directions team. "
          "[ref](http://www.mapbox.com/blog/directions-hiring/)" << endl
       << endl;
  cout << " My solution contains two steps: " << endl << endl;
  cout << " 1. Randomly generate a single-bridge graph with a given number of "
          "vertex. " << endl;
  cout << " 2. Find the bridge with DFS traversal of the graph. " << endl
       << endl;
  cout << " Here we go. " << endl;
  cout << endl << " ## Step 1" << endl << endl;
  cout << " Please input the number of vertex (at least 8) in the graph: ";
  cin >> V;
  while (V < 8) {
    cout << " Please input a number larger or equal to 8: ";
    cin >> V;
  }

  SingleBridgeGraph g(V);
  cout << endl << " ## Step 2" << endl << endl;
  cout << " Searching for the bridge..." << endl;
  g.findBridges();
  cout << endl << " Finished, thanks." << endl << endl;
  cout << " The codes are available at "
          "[github](https://github.com/tumluliu/mapbox-directions-hiring)."
       << endl;
  cout << " For any question or suggestion, please contact with Lu LIU "
          "(nudtlliu@gmail.com). " << endl;

  return 0;
}
<commit_msg>fix memory leaks problem<commit_after>/*
 * Copyright 2015 Lu LIU
 * =====================================================================================
 *
 *       Filename:  bridge-finder.cpp
 *
 *    Description:  A C++ program to find the single bridge in an undirected
 *                  graph. The problem is from MapBox directions team's hiring
 *                  page. Please refer to
 *                  http://www.mapbox.com/blog/directions-hiring/
 *
 *        Version:  1.0
 *        Created:  2015/01/10 16时35分46秒
 *       Revision:  none
 *       Compiler:  gcc
 *             OS:  Mac OS X 10.10.1
 *
 *         Author:  Lu LIU (lliu), nudtlliu@gmail.com
 *   Organization:  higis@dbrg
 *
 * =====================================================================================
 */

#include <stdlib.h>
#include <sys/time.h>
#include <iostream>
#include <list>
#include <ctime>
#include <cstdint>
#include <algorithm>
#define NIL -1
#define MAX_DEGREE 7
#define MIN_DEGREE 3

using std::cout;
using std::cin;
using std::endl;
using std::fixed;
using std::list;
using std::min;

typedef uint64_t uint64;
typedef unsigned int uint;

/*
 * =====================================================================================
 *        Class:  SingleBridgeGraph
 *  Description:  A class that represents a single-bridge undirected graph
 * =====================================================================================
 */
class SingleBridgeGraph {
  // number of vertices and edges
  int V, E;
  // A dynamic array of adjacency lists
  list<int> *adj;
  void bridgeProbe(int v, bool visited[], int disc[], int low[], int parent[]);
  uint64 getCurrentTimeMs();

public:
  explicit SingleBridgeGraph(int V);
  ~SingleBridgeGraph();
  void addEdge(int v, int w);
  void findBridges();
};

/*
 *--------------------------------------------------------------------------------------
 *       Class:  SingleBridgeGraph
 *      Method:  SingleBridgeGraph :: SingleBridgeGraph
 * Description:  Create a graph with following attributes:
 *               1. the number of vertex is given by user input;
 *               2. for each vertex, random number (between MIN_DEGREE and
 *                  MAX_DEGREE) of neighbors will be attached;
 *               3. there must be ONLY one bridge in the graph.
 *--------------------------------------------------------------------------------------
 */
SingleBridgeGraph::SingleBridgeGraph(int V) {
  uint64 startTime = getCurrentTimeMs();
  this->V = V;
  this->E = 0;
  adj = new list<int>[V];
  // Two seperated sub-graphs will be constructed respectively.
  // Their number of vertices (V1 and V2) are randomly determined, but the sum
  // is V.
  int V1, V2;
  uint seed = static_cast<uint>(time(0));
  V1 = rand_r(&seed) % V;
  V2 = V - V1;
  // According to the "each vertex has at least 3 neighbors" request, there
  // should be at least 8 vertices in the graph (4 for each sub-graph).
  while (V1 < 4 || V2 < 4) {
    seed = static_cast<uint>(time(0));
    V1 = rand_r(&seed) % V;
    V2 = V - V1;
  }
  cout << endl << " " << V1
       << " vertices are randomly selected to construct the 1st sub-graph"
       << endl;
  cout << endl << " " << V2
       << " vertices are randomly selected to construct the 2nd sub-graph"
       << endl;
  // vertex id list for the two sub-graphs: [0..V1-1] and [V1, V-1]
  int degree = 0;
  cout << endl << " Generating the single-bridge graph... " << endl;
  double progress = 0.0;
  for (int i = 0; i < V; i++) {
    // randomly determine the number of neighbors for the current vertex
    progress = static_cast<double>(i + 1) / static_cast<double>(V) * 100.0;
    cout.precision(1);
    cout << fixed << progress << "%\r";
    cout.flush();
    seed = static_cast<uint>(time(0));
    degree = rand_r(&seed) % (MAX_DEGREE - MIN_DEGREE + 1) + MIN_DEGREE;
    int n = degree - adj[i].size();
    for (int j = 0; j < n; j++) {
      // randomly determine these neighbors
      // they should be unique, and not be the current vertex (otherwise there
      // will be a cycle)
      int randomNeighbor =
          i < V1 ? rand_r(&seed) % V1 : rand_r(&seed) % V2 + V1;
      bool found =
          (find(adj[i].begin(), adj[i].end(), randomNeighbor) != adj[i].end());
      while (randomNeighbor == i || found == true) {
        seed = static_cast<uint>(time(0));
        randomNeighbor = i < V1 ? rand_r(&seed) % V1 : rand_r(&seed) % V2 + V1;
        found = (find(adj[i].begin(), adj[i].end(), randomNeighbor) !=
                 adj[i].end());
      }
      addEdge(i, randomNeighbor);
    }
  }
  cout << " done!" << endl;
  cout << endl << " Randomly build a bridge between the two sub-graphs... ";
  seed = static_cast<uint>(time(0));
  int bridgeVertex1 = rand_r(&seed) % V1;
  int bridgeVertex2 = rand_r(&seed) % V2 + V1;
  addEdge(bridgeVertex1, bridgeVertex2);
  uint64 elapsedTime = getCurrentTimeMs() - startTime;
  cout << " done!" << endl;
  cout << endl << " The built bridge is (" << bridgeVertex1 << ", "
       << bridgeVertex2 << ")." << endl;
  cout << endl << " A graph with " << V << " vertices and " << this->E
       << " undirected edges has been constructed." << endl;
  cout << " Time consumed for graph construction: " << elapsedTime << " ms"
       << endl;
}

SingleBridgeGraph::~SingleBridgeGraph() {
    delete[] adj;
}

/*
 *--------------------------------------------------------------------------------------
 *       Class:  SingleBridgeGraph
 *      Method:  SingleBridgeGraph :: addEdge
 * Description:  add forward and backward edges to the graph between u and v
 *--------------------------------------------------------------------------------------
 */
void SingleBridgeGraph::addEdge(int u, int v) {
  adj[u].push_back(v);
  adj[v].push_back(u);
  E++;
}

/*
 *--------------------------------------------------------------------------------------
 *       Class:  SingleBridgeGraph
 *      Method:  SingleBridgeGraph :: getCurrentTimeMs
 * Description:  Get current time in milliseconds
 *--------------------------------------------------------------------------------------
 */
uint64 SingleBridgeGraph::getCurrentTimeMs() {
  struct timeval tv;
  gettimeofday(&tv, NULL);
  uint64 ret = tv.tv_usec;
  ret /= 1000;
  ret += (tv.tv_sec * 1000);
  return ret;
}

/*
 *--------------------------------------------------------------------------------------
 *       Class:  SingleBridgeGraph
 *      Method:  SingleBridgeGraph :: bridgeProbe
 * Description:  A recursive function that finds and prints bridges using DFS
 *               traversal.
 *               u --> The vertex to be visited next
 *               visited[] --> keeps track of visited vertices
 *               disc[] --> Stores discovery times of visited vertices
 *               parent[] --> Stores parent vertices in DFS tree
 *--------------------------------------------------------------------------------------
 */
void SingleBridgeGraph::bridgeProbe(int u, bool visited[], int disc[],
                                    int low[], int parent[]) {
  static int time = 0;
  // Mark the current node as visited
  visited[u] = true;
  // Initialize discovery time and low value
  disc[u] = low[u] = ++time;
  // Go through all vertices adjacent to this
  list<int>::iterator i;
  for (i = adj[u].begin(); i != adj[u].end(); ++i) {
    int v = *i;
    // If v is not visited yet, then recur for it
    if (!visited[v]) {
      parent[v] = u;
      bridgeProbe(v, visited, disc, low, parent);
      // Check if the subtree rooted with v has a connection to
      // one of the ancestors of u
      low[u] = min(low[u], low[v]);
      // If the lowest vertex reachable from subtree under v is
      // below u in DFS tree, then u-v is a bridge
      if (low[v] > disc[u])
        cout << endl << " Found it! The bridge is (" << u << ", " << v << ")."
             << endl;
    } else if (v != parent[u]) {
      // Update low value of u for parent function calls.
      low[u] = min(low[u], disc[v]);
    }
  }
}

/*
 *--------------------------------------------------------------------------------------
 *       Class:  SingleBridgeGraph
 *      Method:  SingleBridgeGraph :: findBridges
 * Description:  DFS based function to find all bridges. It uses recursive
 *               function bridgeProbe(). Please note that the method is not
 *               invented by me. The findBridges() and bridgeProbe() functions
 *               are modified from that on
 *               [geeksforgeeks.org](http://www.geeksforgeeks.org/bridge-in-a-graph/)
 *--------------------------------------------------------------------------------------
 */
void SingleBridgeGraph::findBridges() {
  // Mark all the vertices as not visited
  bool *visited = new bool[V];
  int *disc = new int[V];
  int *low = new int[V];
  int *parent = new int[V];

  uint64 startTime = getCurrentTimeMs();
  // Initialize parent and visited arrays
  for (int i = 0; i < V; i++) {
    parent[i] = NIL;
    visited[i] = false;
  }

  // Call the recursive helper function to find Bridges
  // in DFS tree rooted with vertex 'i'
  for (int i = 0; i < V; i++)
    if (visited[i] == false)
      bridgeProbe(i, visited, disc, low, parent);
  uint64 elapsedTime = getCurrentTimeMs() - startTime;
  cout << " Time consumed for finding the bridge: " << elapsedTime << " ms"
       << endl;
  delete visited;
  delete disc;
  delete low;
  delete parent;
}

int main() {
  int V;
  cout << endl << " # Find the single bridge in a graph " << endl << endl;
  cout << " This is an interesting problem posted by MapBox directions team. "
          "[ref](http://www.mapbox.com/blog/directions-hiring/)" << endl
       << endl;
  cout << " My solution contains two steps: " << endl << endl;
  cout << " 1. Randomly generate a single-bridge graph with a given number of "
          "vertex. " << endl;
  cout << " 2. Find the bridge with DFS traversal of the graph. " << endl
       << endl;
  cout << " Here we go. " << endl;
  cout << endl << " ## Step 1" << endl << endl;
  cout << " Please input the number of vertex (at least 8) in the graph: ";
  cin >> V;
  while (V < 8) {
    cout << " Please input a number larger or equal to 8: ";
    cin >> V;
  }

  SingleBridgeGraph g(V);
  cout << endl << " ## Step 2" << endl << endl;
  cout << " Searching for the bridge..." << endl;
  g.findBridges();
  cout << endl << " Finished, thanks." << endl << endl;
  cout << " The codes are available at "
          "[github](https://github.com/tumluliu/mapbox-directions-hiring)."
       << endl;
  cout << " For any question or suggestion, please contact with Lu LIU "
          "(nudtlliu@gmail.com). " << endl;

  return 0;
}
<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#ifndef __OPENCV_DNN_CAFFE_GLOG_EMULATOR_HPP__
#define __OPENCV_DNN_CAFFE_GLOG_EMULATOR_HPP__
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <opencv2/core.hpp>

#define CHECK(cond)     for(cv::dnn::GLogWrapper _logger(__FILE__, CV_Func, __LINE__, "CHECK", #cond, cond); _logger.exit(); _logger.check()) _logger.stream()
#define CHECK_EQ(a, b)  for(cv::dnn::GLogWrapper _logger(__FILE__, CV_Func, __LINE__, "CHECK", #a"="#b, ((a) == (b))); _logger.exit(); _logger.check()) _logger.stream()
#define LOG(TYPE)       for(cv::dnn::GLogWrapper _logger(__FILE__, CV_Func, __LINE__, #TYPE); _logger.exit(); _logger.check()) _logger.stream()

namespace cv
{
namespace dnn
{

class GLogWrapper
{
    const char *file, *func, *type, *cond_str;
    int line;
    bool cond_staus, exit_loop;
    std::stringstream sstream;

public:

    GLogWrapper(const char *_file, const char *_func, int _line,
          const char *_type,
          const char *_cond_str = NULL, bool _cond_status = true
    ) :
        file(_file), func(_func), type(_type), cond_str(_cond_str),
        line(_line), cond_staus(_cond_status), exit_loop(true) {}

    std::iostream &stream()
    {
        return sstream;
    }

    bool exit()
    {
        return exit_loop;
    }

    void check()
    {
        exit_loop = false;

        if (cond_str && !cond_staus)
        {
            cv::error(cv::Error::StsError, "FAILED: " + String(cond_str) + ". " + sstream.str(), func, file, line);
        }
        else if (!cond_str && strcmp(type, "CHECK"))
        {
            if (!std::strcmp(type, "INFO"))
                std::cout << sstream.str() << std::endl;
            else
                std::cerr << sstream.str() << std::endl;
        }
    }
};

}
}
#endif
<commit_msg>Disabled logging in caffe parser in release<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#ifndef __OPENCV_DNN_CAFFE_GLOG_EMULATOR_HPP__
#define __OPENCV_DNN_CAFFE_GLOG_EMULATOR_HPP__
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <opencv2/core.hpp>

#define CHECK(cond)     for(cv::dnn::GLogWrapper _logger(__FILE__, CV_Func, __LINE__, "CHECK", #cond, cond); _logger.exit(); _logger.check()) _logger.stream()
#define CHECK_EQ(a, b)  for(cv::dnn::GLogWrapper _logger(__FILE__, CV_Func, __LINE__, "CHECK", #a"="#b, ((a) == (b))); _logger.exit(); _logger.check()) _logger.stream()
#define LOG(TYPE)       for(cv::dnn::GLogWrapper _logger(__FILE__, CV_Func, __LINE__, #TYPE); _logger.exit(); _logger.check()) _logger.stream()

namespace cv
{
namespace dnn
{

class GLogWrapper
{
    const char *file, *func, *type, *cond_str;
    int line;
    bool cond_status, exit_loop;
    std::stringstream sstream;

public:

    GLogWrapper(const char *_file, const char *_func, int _line,
          const char *_type,
          const char *_cond_str = NULL, bool _cond_status = true
    ) :
        file(_file), func(_func), type(_type), cond_str(_cond_str),
        line(_line), cond_status(_cond_status), exit_loop(true) {}

    std::iostream &stream()
    {
        return sstream;
    }

    bool exit()
    {
        return exit_loop;
    }

    void check()
    {
        exit_loop = false;

        if (cond_str && !cond_status)
        {
            cv::error(cv::Error::StsError, "FAILED: " + String(cond_str) + ". " + sstream.str(), func, file, line);
        }
        else if (!cond_str && strcmp(type, "CHECK"))
        {
            #ifndef NDEBUG
            if (!std::strcmp(type, "INFO"))
                std::cout << sstream.str() << std::endl;
            else
                std::cerr << sstream.str() << std::endl;
            #endif
        }
    }
};

}
}
#endif
<|endoftext|>


<commit_before>/*****************************************************************************
 * xmlparser.cpp
 *****************************************************************************
 * Copyright (C) 2004 the VideoLAN team
 * $Id$
 *
 * Authors: Cyril Deguet     <asmax@via.ecp.fr>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "xmlparser.hpp"
#include "../src/os_factory.hpp"
#include <vlc_url.h>

#include <sys/stat.h>

XMLParser::XMLParser( intf_thread_t *pIntf, const string &rFileName )
    : SkinObject( pIntf ), m_pXML( NULL ), m_pReader( NULL ), m_pStream( NULL )
{
    m_pXML = xml_Create( pIntf );
    if( !m_pXML )
    {
        msg_Err( getIntf(), "cannot initialize xml" );
        return;
    }

    LoadCatalog();

    char *psz_uri = vlc_path2uri( rFileName.c_str(), NULL );
    m_pStream = stream_UrlNew( pIntf, psz_uri );
    free( psz_uri );
    if( !m_pStream )
    {
        msg_Err( getIntf(), "failed to open %s for reading",
                 rFileName.c_str() );
        return;
    }

    m_pReader = xml_ReaderCreate( m_pXML, m_pStream );
    if( !m_pReader )
    {
        msg_Err( getIntf(), "failed to open %s for parsing",
                 rFileName.c_str() );
        return;
    }

    xml_ReaderUseDTD( m_pReader );
}

XMLParser::~XMLParser()
{
    if( m_pReader ) xml_ReaderDelete( m_pReader );
    if( m_pXML ) xml_Delete( m_pXML );
    if( m_pStream ) stream_Delete( m_pStream );
}

void XMLParser::LoadCatalog()
{
    // Get the resource path and look for the DTD
    OSFactory *pOSFactory = OSFactory::instance( getIntf() );
    const list<string> &resPath = pOSFactory->getResourcePath();
    const string &sep = pOSFactory->getDirSeparator();
    list<string>::const_iterator it;

    struct stat statBuf;

    // Try to load the catalog first (needed at least on win32 where
    // we don't have a default catalog)
    for( it = resPath.begin(); it != resPath.end(); ++it )
    {
        string catalog_path = (*it) + sep + "skin.catalog";
        if( !stat( catalog_path.c_str(), &statBuf ) )
        {
            msg_Dbg( getIntf(), "Using catalog %s", catalog_path.c_str() );
            xml_CatalogLoad( m_pXML, catalog_path.c_str() );
            break;
        }
    }
    if( it == resPath.end() )
    {
        // Ok, try the default one
        xml_CatalogLoad( m_pXML, NULL );
    }

    for( it = resPath.begin(); it != resPath.end(); ++it )
    {
        string path = (*it) + sep + "skin.dtd";
        if( !stat( path.c_str(), &statBuf ) )
        {
            // DTD found
            msg_Dbg( getIntf(), "using DTD %s", path.c_str() );

            // Add an entry in the default catalog
            xml_CatalogAdd( m_pXML, "public",
                            "-//VideoLAN//DTD VLC Skins V"
                            SKINS_DTD_VERSION "//EN", path.c_str() );
            break;
        }
    }
    if( it == resPath.end() )
    {
        msg_Err( getIntf(), "cannot find the skins DTD");
    }
}

bool XMLParser::parse()
{
    const char *node;
    int type;

    if( !m_pReader ) return false;

    m_errors = false;

    while( (type = xml_ReaderNextNode( m_pReader, &node )) > 0 )
    {
        if( m_errors ) return false;

        switch( type )
        {
            case XML_READER_STARTELEM:
            {
                // Read the attributes
                AttrList_t attributes;
                const char *name, *value;
                while( (name = xml_ReaderNextAttr( m_pReader, &value )) != NULL )
                    attributes[strdup(name)] = strdup(value);

                handleBeginElement( node, attributes );

                map<const char*, const char*, ltstr> ::iterator it =
                    attributes.begin();
                while( it != attributes.end() )
                {
                    free( (char *)it->first );
                    free( (char *)it->second );
                    ++it;
                }
                break;
            }

            // End element
            case XML_READER_ENDELEM:
            {
                handleEndElement( node );
                break;
            }
        }
    }
    return (type == 0 && !m_errors );
}
<commit_msg>skins2: replace all stat() with vlc_stat()<commit_after>/*****************************************************************************
 * xmlparser.cpp
 *****************************************************************************
 * Copyright (C) 2004 the VideoLAN team
 * $Id$
 *
 * Authors: Cyril Deguet     <asmax@via.ecp.fr>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "xmlparser.hpp"
#include "../src/os_factory.hpp"
#include <vlc_url.h>

#include <sys/stat.h>
#include <vlc_fs.h>

XMLParser::XMLParser( intf_thread_t *pIntf, const string &rFileName )
    : SkinObject( pIntf ), m_pXML( NULL ), m_pReader( NULL ), m_pStream( NULL )
{
    m_pXML = xml_Create( pIntf );
    if( !m_pXML )
    {
        msg_Err( getIntf(), "cannot initialize xml" );
        return;
    }

    LoadCatalog();

    char *psz_uri = vlc_path2uri( rFileName.c_str(), NULL );
    m_pStream = stream_UrlNew( pIntf, psz_uri );
    free( psz_uri );
    if( !m_pStream )
    {
        msg_Err( getIntf(), "failed to open %s for reading",
                 rFileName.c_str() );
        return;
    }

    m_pReader = xml_ReaderCreate( m_pXML, m_pStream );
    if( !m_pReader )
    {
        msg_Err( getIntf(), "failed to open %s for parsing",
                 rFileName.c_str() );
        return;
    }

    xml_ReaderUseDTD( m_pReader );
}

XMLParser::~XMLParser()
{
    if( m_pReader ) xml_ReaderDelete( m_pReader );
    if( m_pXML ) xml_Delete( m_pXML );
    if( m_pStream ) stream_Delete( m_pStream );
}

void XMLParser::LoadCatalog()
{
    // Get the resource path and look for the DTD
    OSFactory *pOSFactory = OSFactory::instance( getIntf() );
    const list<string> &resPath = pOSFactory->getResourcePath();
    const string &sep = pOSFactory->getDirSeparator();
    list<string>::const_iterator it;

    struct stat statBuf;

    // Try to load the catalog first (needed at least on win32 where
    // we don't have a default catalog)
    for( it = resPath.begin(); it != resPath.end(); ++it )
    {
        string catalog_path = (*it) + sep + "skin.catalog";
        if( !vlc_stat( catalog_path.c_str(), &statBuf ) )
        {
            msg_Dbg( getIntf(), "Using catalog %s", catalog_path.c_str() );
            xml_CatalogLoad( m_pXML, catalog_path.c_str() );
            break;
        }
    }
    if( it == resPath.end() )
    {
        // Ok, try the default one
        xml_CatalogLoad( m_pXML, NULL );
    }

    for( it = resPath.begin(); it != resPath.end(); ++it )
    {
        string path = (*it) + sep + "skin.dtd";
        if( !vlc_stat( path.c_str(), &statBuf ) )
        {
            // DTD found
            msg_Dbg( getIntf(), "using DTD %s", path.c_str() );

            // Add an entry in the default catalog
            xml_CatalogAdd( m_pXML, "public",
                            "-//VideoLAN//DTD VLC Skins V"
                            SKINS_DTD_VERSION "//EN", path.c_str() );
            break;
        }
    }
    if( it == resPath.end() )
    {
        msg_Err( getIntf(), "cannot find the skins DTD");
    }
}

bool XMLParser::parse()
{
    const char *node;
    int type;

    if( !m_pReader ) return false;

    m_errors = false;

    while( (type = xml_ReaderNextNode( m_pReader, &node )) > 0 )
    {
        if( m_errors ) return false;

        switch( type )
        {
            case XML_READER_STARTELEM:
            {
                // Read the attributes
                AttrList_t attributes;
                const char *name, *value;
                while( (name = xml_ReaderNextAttr( m_pReader, &value )) != NULL )
                    attributes[strdup(name)] = strdup(value);

                handleBeginElement( node, attributes );

                map<const char*, const char*, ltstr> ::iterator it =
                    attributes.begin();
                while( it != attributes.end() )
                {
                    free( (char *)it->first );
                    free( (char *)it->second );
                    ++it;
                }
                break;
            }

            // End element
            case XML_READER_ENDELEM:
            {
                handleEndElement( node );
                break;
            }
        }
    }
    return (type == 0 && !m_errors );
}
<|endoftext|>


<commit_before>// $Id$
// vim:tabstop=2
/***********************************************************************
 Moses - factored phrase-based language decoder
 Copyright (C) 2010 Hieu Hoang

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 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
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 ***********************************************************************/

#include "PhraseDictionarySCFG.h"
#include "FactorCollection.h"
#include "InputType.h"
#include "ChartTranslationOptionList.h"
#include "CellCollection.h"
#include "DotChart.h"
#include "StaticData.h"
#include "TreeInput.h"

using namespace std;
using namespace Moses;

Word PhraseDictionarySCFG::CreateCoveredWord(const Word &origSourceLabel, const InputType &src, const WordsRange &range) const
{
	string coveredWordsString = origSourceLabel.GetFactor(0)->GetString();

	for (size_t pos = range.GetStartPos(); pos <= range.GetEndPos(); ++pos)
	{
		const Word &word = src.GetWord(pos);
		coveredWordsString += "_" + word.GetFactor(0)->GetString();
	}

	FactorCollection &factorCollection = FactorCollection::Instance();

	Word ret;

	const Factor *factor = factorCollection.AddFactor(Input, 0, coveredWordsString);
	ret.SetFactor(0, factor);

	return ret;
}

void PhraseDictionarySCFG::GetChartRuleCollection(ChartTranslationOptionList &outColl
																								 ,InputType const& src
																								 ,WordsRange const& range
																								 ,bool adhereTableLimit
																								 ,const CellCollection &cellColl) const
{
	size_t relEndPos = range.GetEndPos() - range.GetStartPos();
	size_t absEndPos = range.GetEndPos();

	// MAIN LOOP. create list of nodes of target phrases

	ProcessedRuleColl &processedRuleCol = *m_processedRuleColls[range.GetStartPos()];
	const ProcessedRuleList &runningNodes = processedRuleCol.GetRunningNodes();
    // Note that runningNodes can be expanded as the loop runs (through calls to processedRuleCol::Add())
	for (size_t ind = 0; ind < runningNodes.size(); ++ind)
	{
		const ProcessedRule &prevProcessedRule = *runningNodes[ind];
		const PhraseDictionaryNodeSCFG &prevNode = prevProcessedRule.GetLastNode();
		const WordConsumed *prevWordConsumed = prevProcessedRule.GetLastWordConsumed();
		size_t startPos = (prevWordConsumed == NULL) ? range.GetStartPos() : prevWordConsumed->GetWordsRange().GetEndPos() + 1;

		// search for terminal symbol
		if (startPos == absEndPos)
		{
			const Word &sourceWord = src.GetWord(absEndPos);
			const PhraseDictionaryNodeSCFG *node = prevNode.GetChild(sourceWord);
			if (node != NULL)
			{
				WordConsumed *newWordConsumed = new WordConsumed(absEndPos, absEndPos
																												 , sourceWord
																												 , prevWordConsumed);
				ProcessedRule *processedRule = new ProcessedRule(*node, newWordConsumed);
				processedRuleCol.Add(relEndPos+1, processedRule);
			}
		}

		// search for non-terminals
		size_t endPos, stackInd;
		if (startPos > absEndPos)
			continue;
		else if (startPos == range.GetStartPos() && range.GetEndPos() > range.GetStartPos())
		{ // start.
			endPos = absEndPos - 1;
			stackInd = relEndPos;
		}
		else
		{
			endPos = absEndPos;
			stackInd = relEndPos + 1;
		}

		// get headwords in this span from chart
		const vector<Word> &headWords = cellColl.GetHeadwords(WordsRange(startPos, endPos));

		// go thru each source span
		const LabelList &labelList = src.GetLabelList(startPos, endPos);

		LabelList::const_iterator iterLabelList;
		for (iterLabelList = labelList.begin(); iterLabelList != labelList.end(); ++iterLabelList)
		{
			const Word &sourceLabel = *iterLabelList;

			// go thru each headword & see if in phrase table
			vector<Word>::const_iterator iterHeadWords;
			for (iterHeadWords = headWords.begin(); iterHeadWords != headWords.end(); ++iterHeadWords)
			{
				const Word &headWord = *iterHeadWords;

				const PhraseDictionaryNodeSCFG *node = prevNode.GetChild(sourceLabel, headWord);
				if (node != NULL)
				{
					WordConsumed *newWordConsumed = new WordConsumed(startPos, endPos
																													 , headWord
																													 , prevWordConsumed);

					ProcessedRule *processedRule = new ProcessedRule(*node, newWordConsumed);
					processedRuleCol.Add(stackInd, processedRule);
				}
			} // for (iterHeadWords
		} // for (iterLabelList
	}

	// return list of target phrases
	ProcessedRuleList &nodes = processedRuleCol.Get(relEndPos + 1);

	size_t rulesLimit = StaticData::Instance().GetRuleLimit();
	ProcessedRuleList::const_iterator iterNode;
	for (iterNode = nodes.begin(); iterNode != nodes.end(); ++iterNode)
	{
		const ProcessedRule &processedRule = **iterNode;
		const PhraseDictionaryNodeSCFG &node = processedRule.GetLastNode();
		const WordConsumed *wordConsumed = processedRule.GetLastWordConsumed();
		assert(wordConsumed);

		const TargetPhraseCollection *targetPhraseCollection = node.GetTargetPhraseCollection();

		if (targetPhraseCollection != NULL)
		{
			outColl.Add(*targetPhraseCollection, *wordConsumed, adhereTableLimit, rulesLimit);
		}
	}
	outColl.CreateChartRules(rulesLimit);
}
<commit_msg>delete unused function<commit_after>// $Id$
// vim:tabstop=2
/***********************************************************************
 Moses - factored phrase-based language decoder
 Copyright (C) 2010 Hieu Hoang

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 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
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 ***********************************************************************/

#include "PhraseDictionarySCFG.h"
#include "FactorCollection.h"
#include "InputType.h"
#include "ChartTranslationOptionList.h"
#include "CellCollection.h"
#include "DotChart.h"
#include "StaticData.h"
#include "TreeInput.h"

using namespace std;
using namespace Moses;

void PhraseDictionarySCFG::GetChartRuleCollection(ChartTranslationOptionList &outColl
																								 ,InputType const& src
																								 ,WordsRange const& range
																								 ,bool adhereTableLimit
																								 ,const CellCollection &cellColl) const
{
	size_t relEndPos = range.GetEndPos() - range.GetStartPos();
	size_t absEndPos = range.GetEndPos();

	// MAIN LOOP. create list of nodes of target phrases

	ProcessedRuleColl &processedRuleCol = *m_processedRuleColls[range.GetStartPos()];
	const ProcessedRuleList &runningNodes = processedRuleCol.GetRunningNodes();
    // Note that runningNodes can be expanded as the loop runs (through calls to processedRuleCol::Add())
	for (size_t ind = 0; ind < runningNodes.size(); ++ind)
	{
		const ProcessedRule &prevProcessedRule = *runningNodes[ind];
		const PhraseDictionaryNodeSCFG &prevNode = prevProcessedRule.GetLastNode();
		const WordConsumed *prevWordConsumed = prevProcessedRule.GetLastWordConsumed();
		size_t startPos = (prevWordConsumed == NULL) ? range.GetStartPos() : prevWordConsumed->GetWordsRange().GetEndPos() + 1;

		// search for terminal symbol
		if (startPos == absEndPos)
		{
			const Word &sourceWord = src.GetWord(absEndPos);
			const PhraseDictionaryNodeSCFG *node = prevNode.GetChild(sourceWord);
			if (node != NULL)
			{
				WordConsumed *newWordConsumed = new WordConsumed(absEndPos, absEndPos
																												 , sourceWord
																												 , prevWordConsumed);
				ProcessedRule *processedRule = new ProcessedRule(*node, newWordConsumed);
				processedRuleCol.Add(relEndPos+1, processedRule);
			}
		}

		// search for non-terminals
		size_t endPos, stackInd;
		if (startPos > absEndPos)
			continue;
		else if (startPos == range.GetStartPos() && range.GetEndPos() > range.GetStartPos())
		{ // start.
			endPos = absEndPos - 1;
			stackInd = relEndPos;
		}
		else
		{
			endPos = absEndPos;
			stackInd = relEndPos + 1;
		}

		// get headwords in this span from chart
		const vector<Word> &headWords = cellColl.GetHeadwords(WordsRange(startPos, endPos));

		// go thru each source span
		const LabelList &labelList = src.GetLabelList(startPos, endPos);

		LabelList::const_iterator iterLabelList;
		for (iterLabelList = labelList.begin(); iterLabelList != labelList.end(); ++iterLabelList)
		{
			const Word &sourceLabel = *iterLabelList;

			// go thru each headword & see if in phrase table
			vector<Word>::const_iterator iterHeadWords;
			for (iterHeadWords = headWords.begin(); iterHeadWords != headWords.end(); ++iterHeadWords)
			{
				const Word &headWord = *iterHeadWords;

				const PhraseDictionaryNodeSCFG *node = prevNode.GetChild(sourceLabel, headWord);
				if (node != NULL)
				{
					WordConsumed *newWordConsumed = new WordConsumed(startPos, endPos
																													 , headWord
																													 , prevWordConsumed);

					ProcessedRule *processedRule = new ProcessedRule(*node, newWordConsumed);
					processedRuleCol.Add(stackInd, processedRule);
				}
			} // for (iterHeadWords
		} // for (iterLabelList
	}

	// return list of target phrases
	ProcessedRuleList &nodes = processedRuleCol.Get(relEndPos + 1);

	size_t rulesLimit = StaticData::Instance().GetRuleLimit();
	ProcessedRuleList::const_iterator iterNode;
	for (iterNode = nodes.begin(); iterNode != nodes.end(); ++iterNode)
	{
		const ProcessedRule &processedRule = **iterNode;
		const PhraseDictionaryNodeSCFG &node = processedRule.GetLastNode();
		const WordConsumed *wordConsumed = processedRule.GetLastWordConsumed();
		assert(wordConsumed);

		const TargetPhraseCollection *targetPhraseCollection = node.GetTargetPhraseCollection();

		if (targetPhraseCollection != NULL)
		{
			outColl.Add(*targetPhraseCollection, *wordConsumed, adhereTableLimit, rulesLimit);
		}
	}
	outColl.CreateChartRules(rulesLimit);
}
<|endoftext|>


<commit_before>#include <cassert>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <ctime>
#include <chrono>
using namespace std;

typedef chrono::system_clock Clock;
typedef chrono::nanoseconds ClockResolution;

#include <boost/format.hpp>
boost::format log_fmt;

#include <mpi.h>

#define WITH_MPI
#include "../logging.hpp"

#include "simple_comm_config.hpp"

enum class PState : int {
  // overall state
  CONVERGED        =  0,
  FAILED           =  1,
  // iterating states
  PREDICT          = 10,
  PRE_ITER_COARSE  = 20,
  ITER_COARSE      = 21,
  POST_ITER_COARSE = 22,
  PRE_ITER_FINE    = 30,
  ITER_FINE        = 31,
  POST_ITER_FINE   = 32,

  // last
  UNKNOWN          = 99,
};

struct ProcessState
{
  PState state= PState::UNKNOWN;
  int iter = -1;
  double residual = numeric_limits<double>::max();
};

int block_length[3] = {1, 1, 1};
MPI_Aint block_displace[3] = {
  0,
  sizeof(int),
  sizeof(int) + sizeof(int)
};
MPI_Datatype block_types[3] = {
  MPI_INT, MPI_INT, MPI_DOUBLE
};

MPI_Datatype process_state_type;
int process_state_type_size;

struct ProcessData
{
  int size = -1;
  int rank = -1;
  bool iam_first;
  bool iam_last;
  int prev = -1;
  int next = -1;

  double coarse_val_in, coarse_val_out;
  double fine_val_in, fine_val_out;

  double mpi_start;

  ProcessState state;

  MPI_Win coarse_win;
  MPI_Win fine_win;
  MPI_Win state_win;

  void init(const double start_time) {
    assert(rank >= 0 && size > 0);
    this->mpi_start = start_time;
    this->iam_first = (rank == 0);
    this->iam_last = (rank == size - 1);
    if (!this->iam_first) { this->prev = this->rank - 1; }
    if (!this->iam_last) { this->next = this->rank + 1; }
  }

  void create_windows()
  {
    if (this->size > 1) {
      VLOG(6) << "creating windows";
      MPI_Win_create(&fine_val_out, sizeof(double), MPI_DOUBLE, MPI_INFO_NULL, MPI_COMM_WORLD, &fine_win);
      MPI_Win_create(&coarse_val_out, sizeof(double), MPI_DOUBLE, MPI_INFO_NULL, MPI_COMM_WORLD, &coarse_win);
      MPI_Win_create(&state, 1, process_state_type_size, MPI_INFO_NULL, MPI_COMM_WORLD, &state_win);
    } else {
      VLOG(6) << "no need for communication";
    }
  }

  void free_windows()
  {
    if (this->size > 1) {
      VLOG(6) << "freeing windows";
      MPI_Win_free(&fine_win);
      MPI_Win_free(&coarse_win);
      MPI_Win_free(&state_win);
    } else {
      VLOG(6) << "no need for communication";
    }
  }
};

static int fine_tag(const int iter)   { return (iter + 1) * FINE_MULTIPLIER; }
static int coarse_tag(const int iter) { return (iter + 1) * COARSE_MULTIPLIER; }
static int state_tag(const int iter)  { return (iter + 1) * STATE_MULTIPLIER; }

void doing_fine(ProcessData &data, const int iter) {
  int mpi_err = MPI_SUCCESS;

  if (data.size > 1 && !data.iam_first && iter > 0) {
    VLOG(5) << "locking fine window to rank " << data.prev;
    mpi_err = MPI_Win_lock(MPI_LOCK_EXCLUSIVE, data.prev, 0, data.fine_win);
    assert(mpi_err == MPI_SUCCESS);

    VLOG(4) << "getting fine value from " << data.prev;
    mpi_err = MPI_Get(&(data.fine_val_in), 1, MPI_DOUBLE, data.prev, 0, 1, MPI_DOUBLE, data.fine_win);
    assert(mpi_err == MPI_SUCCESS);

    mpi_err = MPI_Win_unlock(data.prev, data.fine_win);
    assert(mpi_err == MPI_SUCCESS);
    VLOG(5) << "unlocked fine window to rank " << data.prev;
  }

  if (data.size > 1) {
    VLOG(5) << "locking local fine window";
    mpi_err = MPI_Win_lock(MPI_LOCK_EXCLUSIVE, data.rank, 0, data.fine_win);
    assert(mpi_err == MPI_SUCCESS);
  }

  VLOG(2) << "start computation";
  data.fine_val_out = data.fine_val_in + (data.state.iter + 1) * FINE_MULTIPLIER + iter * 0.001;
  VLOG(3) << data.fine_val_out << " = " << data.fine_val_in << " + " << ((data.state.iter + 1) * FINE_MULTIPLIER) << " + " << (iter * 0.001);

  chrono::time_point<Clock> start, end;
  ClockResolution duration;
  start = Clock::now();
  do {
    end = Clock::now();
    duration = end - start;
  } while(duration.count() < BASE_DELAY * FINE_MULTIPLIER);
  VLOG(2) << "done computation";

  if (data.size > 1) {
    mpi_err = MPI_Win_unlock(data.rank, data.fine_win);
    assert(mpi_err == MPI_SUCCESS);
    VLOG(5) << "unlocked local fine window";
  }
}

void doing_coarse(ProcessData &data, const int iter) {
  int mpi_err = MPI_SUCCESS;

  if (data.size > 1 && !data.iam_first && iter > 0) {
    VLOG(5) << "locking coarse window to rank " << data.prev;
    mpi_err = MPI_Win_lock(MPI_LOCK_EXCLUSIVE, data.prev, 0, data.coarse_win);
    assert(mpi_err == MPI_SUCCESS);

    VLOG(4) << "getting coarse value from " << data.prev;
    mpi_err = MPI_Get(&(data.coarse_val_in), 1, MPI_DOUBLE, data.prev, 0, 1, MPI_DOUBLE, data.coarse_win);
    assert(mpi_err == MPI_SUCCESS);

    mpi_err = MPI_Win_unlock(data.prev, data.coarse_win);
    assert(mpi_err == MPI_SUCCESS);
    VLOG(5) << "unlocked coarse window to rank " << data.prev;
  }

  if (data.size > 1) {
    VLOG(5) << "locking local coarse window";
    mpi_err = MPI_Win_lock(MPI_LOCK_EXCLUSIVE, data.rank, 0, data.coarse_win);
    assert(mpi_err == MPI_SUCCESS);
  }

  VLOG(2) << "start computation";
  data.coarse_val_out = data.coarse_val_in + (data.state.iter + 1) * COARSE_MULTIPLIER + iter * 0.001;
  VLOG(3) << data.coarse_val_out << " = " << data.coarse_val_in << " + " << ((data.rank + 1) * COARSE_MULTIPLIER) << " + " << (iter * 0.001);

  chrono::time_point<Clock> start, end;
  ClockResolution duration;
  start = Clock::now();
  do {
    end = Clock::now();
    duration = end - start;
  } while(duration.count() < BASE_DELAY * COARSE_MULTIPLIER);
  VLOG(2) << "done computation";

  if (data.size > 1) {
    mpi_err = MPI_Win_unlock(data.rank, data.coarse_win);
    assert(mpi_err == MPI_SUCCESS);
    VLOG(5) << "unlocked local coarse window";
  }
}

void check_finished(ProcessData &data, const int iter) {
  int mpi_err = MPI_SUCCESS;
  ProcessState other_state;

  if (data.size > 1 && !data.iam_first) {
    VLOG(5) << "locking state window to rank " << data.prev;
    mpi_err = MPI_Win_lock(MPI_LOCK_EXCLUSIVE, data.prev, 0, data.state_win);
    assert(mpi_err == MPI_SUCCESS);

    VLOG(4) << "getting state from " << data.prev;
    mpi_err = MPI_Get(&other_state, 1, process_state_type, data.prev, 0, 1, process_state_type, data.state_win);
    assert(mpi_err == MPI_SUCCESS);

    mpi_err = MPI_Win_unlock(data.prev, data.state_win);
    assert(mpi_err == MPI_SUCCESS);
    VLOG(5) << "unlocked state window to rank " << data.prev;
  } else {
    other_state.state = PState::CONVERGED;
  }

  if (data.size > 1) {
    VLOG(5) << "locking local state window";
    mpi_err = MPI_Win_lock(MPI_LOCK_EXCLUSIVE, data.rank, 0, data.state_win);
    assert(mpi_err == MPI_SUCCESS);
  }

  double curr_time = MPI_Wtime();
  data.state.residual = curr_time - data.mpi_start;

  if (other_state.state == PState::FAILED) {
      data.state.state = PState::FAILED;
  } else if (other_state.state == PState::CONVERGED && data.state.residual > RESIDUAL_TOL) {
    data.state.state = PState::CONVERGED;
  }

  if (data.size > 1) {
    mpi_err = MPI_Win_unlock(data.rank, data.state_win);
    assert(mpi_err == MPI_SUCCESS);
    VLOG(5) << "unlocked local state window";
  }
}

int main(int argn, char** argv) {
//                         iter      residual   coarse     fine
  log_fmt = boost::format("%4.d      %12.3f      %12.3f      %12.3f");

  MPI_Init(&argn, &argv);

  init_log(argn, argv);

  int size = -1;
  int rank = -1;
  MPI_Comm_size(MPI_COMM_WORLD, &size);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

  MPI_Type_create_struct(3, block_length, block_displace, block_types, &process_state_type);
  MPI_Type_commit(&process_state_type);
  MPI_Type_size(process_state_type, &process_state_type_size);

  int curr_step_start = 0;
  double initial_value = 1.0;

  do {
    double mpi_start = MPI_Wtime();

    int mpi_err = MPI_SUCCESS;

    ProcessData myself;

    myself.rank = rank;
    int working_size = (curr_step_start + size - 1 < TOTAL_STEPS) ? size : TOTAL_STEPS % size;
    LOG(INFO) << working_size << " processes will work now";

    myself.size = working_size;
    if (rank < working_size) {
      LOG(INFO) << "doing step " << (curr_step_start + rank);
      myself.init(mpi_start);
      myself.create_windows();

      myself.fine_val_in = initial_value;
      myself.coarse_val_in = initial_value / FINE_MULTIPLIER;
      LOG(INFO) << "inital values:\tcoarse=" << std::fixed << std::setprecision(3) << myself.coarse_val_in << "\tfine=" << myself.fine_val_in;

      for(int iter = 0; myself.state.state > PState::FAILED; ++iter) {
        myself.state.iter = iter;
        doing_coarse(myself, iter);
        doing_fine(myself, iter);
        check_finished(myself, iter);
        log_fmt % iter % myself.state.residual % myself.coarse_val_out % myself.fine_val_out;
        LOG(INFO) << log_fmt;
      }

      myself.free_windows();
    } else {
      // this rank hasn't to do anything anymore
      LOG(WARNING) << "hasn't work anymore";
    }

    VLOG(4) << "broadcasting final value to all";
    MPI_Bcast(&(myself.fine_val_out), 1, MPI_DOUBLE, working_size - 1, MPI_COMM_WORLD);
    initial_value = myself.fine_val_out;

    curr_step_start += size;
  } while (curr_step_start < TOTAL_STEPS);

  MPI_Type_free(&process_state_type);
  VLOG(6) << "finalizing";
  MPI_Finalize();
}
<commit_msg>simple comm rma get<commit_after>#include "simple_comm_config.hpp"

struct ProcessData
{
  int size = -1;
  int rank = -1;
  bool iam_first;
  bool iam_last;
  int prev = -1;
  int next = -1;

  double coarse_val_in, coarse_val_out;
  double fine_val_in, fine_val_out;

  double mpi_start;

  ProcessState state;

  MPI_Win coarse_win;
  MPI_Win fine_win;
  MPI_Win state_win;

  void init(const double start_time) {
    assert(rank >= 0 && size > 0);
    this->mpi_start = start_time;
    this->iam_first = (rank == 0);
    this->iam_last = (rank == size - 1);
    if (!this->iam_first) { this->prev = this->rank - 1; }
    if (!this->iam_last) { this->next = this->rank + 1; }
  }

  void create_windows()
  {
    if (this->size > 1) {
      VLOG(6) << "creating windows";
      MPI_Win_create(&fine_val_out, sizeof(double), MPI_DOUBLE, MPI_INFO_NULL, MPI_COMM_WORLD, &fine_win);
      MPI_Win_create(&coarse_val_out, sizeof(double), MPI_DOUBLE, MPI_INFO_NULL, MPI_COMM_WORLD, &coarse_win);
      MPI_Win_create(&state, 1, process_state_type_size, MPI_INFO_NULL, MPI_COMM_WORLD, &state_win);
    } else {
      VLOG(6) << "no need for communication";
    }
  }

  void free_windows()
  {
    if (this->size > 1) {
      VLOG(6) << "freeing windows";
      MPI_Win_free(&fine_win);
      MPI_Win_free(&coarse_win);
      MPI_Win_free(&state_win);
    } else {
      VLOG(6) << "no need for communication";
    }
  }
};

static int fine_tag(const int iter)   { return (iter + 1) * FINE_MULTIPLIER; }
static int coarse_tag(const int iter) { return (iter + 1) * COARSE_MULTIPLIER; }
static int state_tag(const int iter)  { return (iter + 1) * STATE_MULTIPLIER; }

void doing_fine(ProcessData &data, const int iter) {
  int mpi_err = MPI_SUCCESS;

  if (data.size > 1 && !data.iam_first && iter > 0) {
    VLOG(5) << "locking fine window to rank " << data.prev;
    mpi_err = MPI_Win_lock(MPI_LOCK_EXCLUSIVE, data.prev, 0, data.fine_win);
    assert(mpi_err == MPI_SUCCESS);

    VLOG(4) << "getting fine value from " << data.prev;
    mpi_err = MPI_Get(&(data.fine_val_in), 1, MPI_DOUBLE, data.prev, 0, 1, MPI_DOUBLE, data.fine_win);
    assert(mpi_err == MPI_SUCCESS);

    mpi_err = MPI_Win_unlock(data.prev, data.fine_win);
    assert(mpi_err == MPI_SUCCESS);
    VLOG(5) << "unlocked fine window to rank " << data.prev;
  }

  if (data.size > 1) {
    VLOG(5) << "locking local fine window";
    mpi_err = MPI_Win_lock(MPI_LOCK_EXCLUSIVE, data.rank, 0, data.fine_win);
    assert(mpi_err == MPI_SUCCESS);
  }

  VLOG(2) << "start computation";
  data.fine_val_out = data.fine_val_in + (data.state.iter + 1) * FINE_MULTIPLIER + iter * 0.001;
  VLOG(3) << data.fine_val_out << " = " << data.fine_val_in << " + " << ((data.state.iter + 1) * FINE_MULTIPLIER) << " + " << (iter * 0.001);

  chrono::time_point<Clock> start, end;
  ClockResolution duration;
  start = Clock::now();
  do {
    end = Clock::now();
    duration = end - start;
  } while(duration.count() < BASE_DELAY * FINE_MULTIPLIER);
  VLOG(2) << "done computation";

  if (data.size > 1) {
    mpi_err = MPI_Win_unlock(data.rank, data.fine_win);
    assert(mpi_err == MPI_SUCCESS);
    VLOG(5) << "unlocked local fine window";
  }
}

void doing_coarse(ProcessData &data, const int iter) {
  int mpi_err = MPI_SUCCESS;

  if (data.size > 1 && !data.iam_first && iter > 0) {
    VLOG(5) << "locking coarse window to rank " << data.prev;
    mpi_err = MPI_Win_lock(MPI_LOCK_EXCLUSIVE, data.prev, 0, data.coarse_win);
    assert(mpi_err == MPI_SUCCESS);

    VLOG(4) << "getting coarse value from " << data.prev;
    mpi_err = MPI_Get(&(data.coarse_val_in), 1, MPI_DOUBLE, data.prev, 0, 1, MPI_DOUBLE, data.coarse_win);
    assert(mpi_err == MPI_SUCCESS);

    mpi_err = MPI_Win_unlock(data.prev, data.coarse_win);
    assert(mpi_err == MPI_SUCCESS);
    VLOG(5) << "unlocked coarse window to rank " << data.prev;
  }

  if (data.size > 1) {
    VLOG(5) << "locking local coarse window";
    mpi_err = MPI_Win_lock(MPI_LOCK_EXCLUSIVE, data.rank, 0, data.coarse_win);
    assert(mpi_err == MPI_SUCCESS);
  }

  VLOG(2) << "start computation";
  data.coarse_val_out = data.coarse_val_in + (data.state.iter + 1) * COARSE_MULTIPLIER + iter * 0.001;
  VLOG(3) << data.coarse_val_out << " = " << data.coarse_val_in << " + " << ((data.state.iter + 1) * COARSE_MULTIPLIER) << " + " << (iter * 0.001);

  chrono::time_point<Clock> start, end;
  ClockResolution duration;
  start = Clock::now();
  do {
    end = Clock::now();
    duration = end - start;
  } while(duration.count() < BASE_DELAY * COARSE_MULTIPLIER);
  VLOG(2) << "done computation";

  if (data.size > 1) {
    mpi_err = MPI_Win_unlock(data.rank, data.coarse_win);
    assert(mpi_err == MPI_SUCCESS);
    VLOG(5) << "unlocked local coarse window";
  }
}

void check_finished(ProcessData &data, const int iter) {
  int mpi_err = MPI_SUCCESS;
  ProcessState other_state;

  if (data.size > 1 && !data.iam_first) {
    VLOG(5) << "locking state window to rank " << data.prev;
    mpi_err = MPI_Win_lock(MPI_LOCK_EXCLUSIVE, data.prev, 0, data.state_win);
    assert(mpi_err == MPI_SUCCESS);

    VLOG(4) << "getting state from " << data.prev;
    mpi_err = MPI_Get(&other_state, 1, process_state_type, data.prev, 0, 1, process_state_type, data.state_win);
    assert(mpi_err == MPI_SUCCESS);

    mpi_err = MPI_Win_unlock(data.prev, data.state_win);
    assert(mpi_err == MPI_SUCCESS);
    VLOG(5) << "unlocked state window to rank " << data.prev;
  } else {
    other_state.state = PState::CONVERGED;
  }

  if (data.size > 1) {
    VLOG(5) << "locking local state window";
    mpi_err = MPI_Win_lock(MPI_LOCK_EXCLUSIVE, data.rank, 0, data.state_win);
    assert(mpi_err == MPI_SUCCESS);
  }

  double curr_time = MPI_Wtime();
  data.state.residual = curr_time - data.mpi_start;

  if (other_state.state == PState::FAILED) {
      data.state.state = PState::FAILED;
  } else if (other_state.state == PState::CONVERGED) {
    VLOG(2) << "previous converged";
    if (data.state.residual > RESIDUAL_TOL) {
      VLOG(2) << "and I'm done as well";
      data.state.state = PState::CONVERGED;
    } else {
      VLOG(2) << "but I'm not yet done";
    }
  }

  if (data.size > 1) {
    mpi_err = MPI_Win_unlock(data.rank, data.state_win);
    assert(mpi_err == MPI_SUCCESS);
    VLOG(5) << "unlocked local state window";
  }
}

int main(int argn, char** argv) {
//                         iter      residual   coarse     fine
  log_fmt = boost::format("%4.d      %12.3f      %12.3f      %12.3f");

  MPI_Init(&argn, &argv);

  init_log(argn, argv);

  int size = -1;
  int rank = -1;
  MPI_Comm_size(MPI_COMM_WORLD, &size);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

  MPI_Type_create_struct(3, block_length, block_displace, block_types, &process_state_type);
  MPI_Type_commit(&process_state_type);
  MPI_Type_size(process_state_type, &process_state_type_size);

  int curr_step_start = 0;
  double initial_value = 1.0;

  do {
    double mpi_start = MPI_Wtime();

    int mpi_err = MPI_SUCCESS;

    ProcessData myself;

    myself.rank = rank;
    int working_size = (curr_step_start + size - 1 < TOTAL_STEPS) ? size : TOTAL_STEPS % size;
    LOG(INFO) << working_size << " processes will work now";

    myself.size = working_size;
    if (rank < working_size) {
      LOG(INFO) << "doing step " << (curr_step_start + rank);
      myself.init(mpi_start);
      myself.create_windows();

      myself.fine_val_in = initial_value;
      myself.coarse_val_in = initial_value / FINE_MULTIPLIER;
      LOG(INFO) << "inital values:\tcoarse=" << std::fixed << std::setprecision(3) << myself.coarse_val_in << "\tfine=" << myself.fine_val_in;

      for(int iter = 0; myself.state.state > PState::FAILED; ++iter) {
        myself.state.iter = iter;

        if (iter == 0) {
          for (int proc = - myself.rank; proc <= 0; ++proc) {
            VLOG(2) << "predict " << proc;
            doing_coarse(myself, proc);
          }
        } else {
          doing_coarse(myself, iter);
        }

        doing_fine(myself, iter);

        check_finished(myself, iter);
        log_fmt % iter % myself.state.residual % myself.coarse_val_out % myself.fine_val_out;
        LOG(INFO) << log_fmt;
      }

      myself.free_windows();
    } else {
      // this rank hasn't to do anything anymore
      LOG(WARNING) << "hasn't work anymore";
    }

    VLOG(4) << "broadcasting final value to all";
    MPI_Bcast(&(myself.fine_val_out), 1, MPI_DOUBLE, working_size - 1, MPI_COMM_WORLD);
    initial_value = myself.fine_val_out;

    curr_step_start += size;
  } while (curr_step_start < TOTAL_STEPS);

  MPI_Type_free(&process_state_type);
  VLOG(6) << "finalizing";
  MPI_Finalize();
}
<|endoftext|>


<commit_before>/*  This file is part of the KDE project
    Copyright (C) 2005-2006 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

    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; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

*/

#include "backendcapabilities.h"
#include "backendcapabilities_p.h"

#include "phonondefs_p.h"
#include "backendinterface.h"
#include "factory.h"
#include "globalconfig.h"
#include "globalstatic_p.h"
#include "objectdescription.h"

#include <QtCore/QList>
#include <QtCore/QSet>
#include <QtCore/QStringList>

QT_BEGIN_NAMESPACE

PHONON_GLOBAL_STATIC(Phonon::BackendCapabilitiesPrivate, globalBCPrivate)

template<class T>
static inline bool sortByInitialPreference(const T &o1, const T &o2)
{
    // QVariant::toInt() returns 0 if the type() is not convertable to int
    const int initialPreference1 = o1.property("initialPreference").toInt();
    const int initialPreference2 = o2.property("initialPreference").toInt();
    // the higher the number the higher it should appear in the list
    return initialPreference1 > initialPreference2;
}

namespace Phonon
{

BackendCapabilities::Notifier *BackendCapabilities::notifier()
{
    return globalBCPrivate;
}

/*
#define SUPPORTS(foo) \
bool BackendCapabilities::supports ## foo() \
{ \
    if (BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend())) \
        return backendIface->supports ## foo(); \
    else \
        return false; \
}

SUPPORTS(Video)
SUPPORTS(OSD)
SUPPORTS(Subtitles)
*/

QStringList BackendCapabilities::availableMimeTypes()
{
    if (BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend()))
        return backendIface->availableMimeTypes();
    else
        return QStringList();
}

bool BackendCapabilities::isMimeTypeAvailable(const QString &mimeType)
{
    QObject *m_backendObject = Factory::backend(false);
    if (!m_backendObject) {
        if (!Factory::isMimeTypeAvailable(mimeType)) {
            return false;
        }
        // without loading the backend we found out that the MIME type might be supported, now we
        // want to know for certain. For that we need to load the backend.
        m_backendObject = Factory::backend(true);
    }
    if (!m_backendObject) {
        // no backend == no MIME type supported at all
        return false;
    }
    return availableMimeTypes().contains(mimeType);
}

#define availableDevicesImpl(T) \
QList<T> BackendCapabilities::available ## T ## s() \
{ \
    BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend()); \
    QList<T> ret; \
    if (backendIface) { \
        QList<int> deviceIndexes = backendIface->objectDescriptionIndexes(Phonon::T ## Type); \
        foreach (int i, deviceIndexes) \
            ret.append(T::fromIndex(i)); \
    } \
    qSort(ret.begin(), ret.end(), sortByInitialPreference<T>); \
    return ret; \
}

#define availableDevicesImpl2(T) \
QList<T ## Description> BackendCapabilities::available ## T ## s() \
{ \
    BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend()); \
    QList<T ## Description> ret; \
    if (backendIface) { \
        QList<int> deviceIndexes = backendIface->objectDescriptionIndexes(Phonon::T ## Type); \
        foreach (int i, deviceIndexes) \
            ret.append(T ## Description::fromIndex(i)); \
    } \
    qSort(ret.begin(), ret.end(), sortByInitialPreference<T ## Description>); \
    return ret; \
}

QList<AudioOutputDevice> BackendCapabilities::availableAudioOutputDevices()
{
    QList<AudioOutputDevice> ret;
    const QList<int> deviceIndexes = GlobalConfig().audioOutputDeviceListFor(Phonon::NoCategory);
    foreach (int i, deviceIndexes) {
        ret.append(AudioOutputDevice::fromIndex(i));
    }
    return ret;
}

/*availableDevicesImpl(AudioCaptureDevice)
availableDevicesImpl(VideoOutputDevice)
availableDevicesImpl(VideoCaptureDevice)
availableDevicesImpl2(Visualization)
availableDevicesImpl2(AudioCodec)
availableDevicesImpl2(VideoCodec)
availableDevicesImpl2(ContainerFormat)*/

QList<EffectDescription> BackendCapabilities::availableAudioEffects()
{
    BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend());
    QList<EffectDescription> ret;
    if (backendIface) {
        QList<int> deviceIndexes = backendIface->objectDescriptionIndexes(Phonon::EffectType);
        foreach (int i, deviceIndexes) {
            ret.append(EffectDescription::fromIndex(i));
        }
    }
    return ret;
}

} // namespace Phonon

QT_END_NAMESPACE

#include "moc_backendcapabilities.cpp"
#include "moc_backendcapabilities_p.cpp"

// vim: sw=4 ts=4<commit_msg>Remove no empty line at end warning<commit_after>/*  This file is part of the KDE project
    Copyright (C) 2005-2006 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

    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; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

*/

#include "backendcapabilities.h"
#include "backendcapabilities_p.h"

#include "phonondefs_p.h"
#include "backendinterface.h"
#include "factory.h"
#include "globalconfig.h"
#include "globalstatic_p.h"
#include "objectdescription.h"

#include <QtCore/QList>
#include <QtCore/QSet>
#include <QtCore/QStringList>

QT_BEGIN_NAMESPACE

PHONON_GLOBAL_STATIC(Phonon::BackendCapabilitiesPrivate, globalBCPrivate)

template<class T>
static inline bool sortByInitialPreference(const T &o1, const T &o2)
{
    // QVariant::toInt() returns 0 if the type() is not convertable to int
    const int initialPreference1 = o1.property("initialPreference").toInt();
    const int initialPreference2 = o2.property("initialPreference").toInt();
    // the higher the number the higher it should appear in the list
    return initialPreference1 > initialPreference2;
}

namespace Phonon
{

BackendCapabilities::Notifier *BackendCapabilities::notifier()
{
    return globalBCPrivate;
}

/*
#define SUPPORTS(foo) \
bool BackendCapabilities::supports ## foo() \
{ \
    if (BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend())) \
        return backendIface->supports ## foo(); \
    else \
        return false; \
}

SUPPORTS(Video)
SUPPORTS(OSD)
SUPPORTS(Subtitles)
*/

QStringList BackendCapabilities::availableMimeTypes()
{
    if (BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend()))
        return backendIface->availableMimeTypes();
    else
        return QStringList();
}

bool BackendCapabilities::isMimeTypeAvailable(const QString &mimeType)
{
    QObject *m_backendObject = Factory::backend(false);
    if (!m_backendObject) {
        if (!Factory::isMimeTypeAvailable(mimeType)) {
            return false;
        }
        // without loading the backend we found out that the MIME type might be supported, now we
        // want to know for certain. For that we need to load the backend.
        m_backendObject = Factory::backend(true);
    }
    if (!m_backendObject) {
        // no backend == no MIME type supported at all
        return false;
    }
    return availableMimeTypes().contains(mimeType);
}

#define availableDevicesImpl(T) \
QList<T> BackendCapabilities::available ## T ## s() \
{ \
    BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend()); \
    QList<T> ret; \
    if (backendIface) { \
        QList<int> deviceIndexes = backendIface->objectDescriptionIndexes(Phonon::T ## Type); \
        foreach (int i, deviceIndexes) \
            ret.append(T::fromIndex(i)); \
    } \
    qSort(ret.begin(), ret.end(), sortByInitialPreference<T>); \
    return ret; \
}

#define availableDevicesImpl2(T) \
QList<T ## Description> BackendCapabilities::available ## T ## s() \
{ \
    BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend()); \
    QList<T ## Description> ret; \
    if (backendIface) { \
        QList<int> deviceIndexes = backendIface->objectDescriptionIndexes(Phonon::T ## Type); \
        foreach (int i, deviceIndexes) \
            ret.append(T ## Description::fromIndex(i)); \
    } \
    qSort(ret.begin(), ret.end(), sortByInitialPreference<T ## Description>); \
    return ret; \
}

QList<AudioOutputDevice> BackendCapabilities::availableAudioOutputDevices()
{
    QList<AudioOutputDevice> ret;
    const QList<int> deviceIndexes = GlobalConfig().audioOutputDeviceListFor(Phonon::NoCategory);
    foreach (int i, deviceIndexes) {
        ret.append(AudioOutputDevice::fromIndex(i));
    }
    return ret;
}

/*availableDevicesImpl(AudioCaptureDevice)
availableDevicesImpl(VideoOutputDevice)
availableDevicesImpl(VideoCaptureDevice)
availableDevicesImpl2(Visualization)
availableDevicesImpl2(AudioCodec)
availableDevicesImpl2(VideoCodec)
availableDevicesImpl2(ContainerFormat)*/

QList<EffectDescription> BackendCapabilities::availableAudioEffects()
{
    BackendInterface *backendIface = qobject_cast<BackendInterface *>(Factory::backend());
    QList<EffectDescription> ret;
    if (backendIface) {
        QList<int> deviceIndexes = backendIface->objectDescriptionIndexes(Phonon::EffectType);
        foreach (int i, deviceIndexes) {
            ret.append(EffectDescription::fromIndex(i));
        }
    }
    return ret;
}

} // namespace Phonon

QT_END_NAMESPACE

#include "moc_backendcapabilities.cpp"
#include "moc_backendcapabilities_p.cpp"

// vim: sw=4 ts=4

<|endoftext|>


<commit_before><commit_msg>On Linux, look in $HOME/.icons for mime icons as well for backwards compatibility.<commit_after><|endoftext|>