<commit_before>/*
 * Copyright (C) 2009-2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

#ifndef SCHED_COROUTINE_CORO_HXX
# define SCHED_COROUTINE_CORO_HXX

# include <libport/local-data.hh>
# include <libport/thread-data.hh>

typedef ::libport::LocalSingleton<Coro*, ::libport::localdata::Thread>
  LocalCoroPtr;

// Hook stuff for uclibc-workaround
SCHED_API extern LocalCoroPtr coroutine_current_;
SCHED_API extern Coro* coroutine_main_;
SCHED_API extern void (*coroutine_free_hook)(Coro*);
SCHED_API extern void (*coroutine_new_hook) (Coro*);
// Hack to force inclusion of hook object when the user links against a static
// libsched
SCHED_API void coroutine_force_hook_linkage();

inline Coro*
coroutine_current()
{
  return coroutine_current_;
}

inline Coro*
coroutine_main()
{
  return coroutine_main_;
}

inline Coro*
coroutine_new(size_t stack_size)
{
  Coro* res = Coro_new();
  Coro_setStackSize_(res,
                     (stack_size
                      ? stack_size
                      : sched::configuration.default_stack_size));
  if (coroutine_new_hook)
    coroutine_new_hook(res);
  return res;
}

inline void
coroutine_free(Coro* coro)
{
  if (coroutine_free_hook)
    coroutine_free_hook(coro);
  Coro_free(coro);
}

inline void*
coroutine_current_stack_pointer(Coro*)
{
  return Coro_CurrentStackPointer();
}

inline void*
coroutine_stack_addr(Coro* self)
{
  return self->stack;
}

inline size_t
coroutine_stack_size(Coro* self)
{
  return self->requestedStackSize;
}

inline void
coroutine_initialize_main(Coro* coro)
{
  coroutine_main_ = coro;
  coroutine_current_ = coro;
  Coro_initializeMainCoro(coro);
  coroutine_force_hook_linkage();
}

template<typename T>
inline void
coroutine_start(Coro* self, Coro* other, void (*callback)(T*), T* context)
{
  coroutine_current_ = other;
  Coro_startCoro_(self, other, context,
		  reinterpret_cast<CoroStartCallback*>(callback));
  coroutine_current_ = self;
}

inline void
coroutine_switch_to(Coro* self, Coro* next)
{
  coroutine_current_ = next;
  Coro_switchTo_(self, next);
  coroutine_current_ = self;
}

#endif // SCHED_COROUTINE_CORO_HXX
<commit_msg>coroutine: Do not make current coroutine thread-safe under uclibc.<commit_after>/*
 * Copyright (C) 2009-2010, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */

#ifndef SCHED_COROUTINE_CORO_HXX
# define SCHED_COROUTINE_CORO_HXX

# include <libport/local-data.hh>
# include <libport/thread-data.hh>

# ifndef __UCLIBC__
typedef ::libport::LocalSingleton<Coro*, ::libport::localdata::Thread>
  LocalCoroPtr;
# else
 /* Under uclibc, we need pthread local data to be coroutine-specific for proper
  * exception handling. So current_coro ptr cannot be a pthread local.
  */
typedef Coro* LocalCoroPtr;
# endif

// Hook stuff for uclibc-workaround
SCHED_API extern LocalCoroPtr coroutine_current_;
SCHED_API extern Coro* coroutine_main_;
SCHED_API extern void (*coroutine_free_hook)(Coro*);
SCHED_API extern void (*coroutine_new_hook) (Coro*);
// Hack to force inclusion of hook object when the user links against a static
// libsched
SCHED_API void coroutine_force_hook_linkage();

inline Coro*
coroutine_current()
{
  return coroutine_current_;
}

inline Coro*
coroutine_main()
{
  return coroutine_main_;
}

inline Coro*
coroutine_new(size_t stack_size)
{
  Coro* res = Coro_new();
  Coro_setStackSize_(res,
                     (stack_size
                      ? stack_size
                      : sched::configuration.default_stack_size));
  if (coroutine_new_hook)
    coroutine_new_hook(res);
  return res;
}

inline void
coroutine_free(Coro* coro)
{
  if (coroutine_free_hook)
    coroutine_free_hook(coro);
  Coro_free(coro);
}

inline void*
coroutine_current_stack_pointer(Coro*)
{
  return Coro_CurrentStackPointer();
}

inline void*
coroutine_stack_addr(Coro* self)
{
  return self->stack;
}

inline size_t
coroutine_stack_size(Coro* self)
{
  return self->requestedStackSize;
}

inline void
coroutine_initialize_main(Coro* coro)
{
  coroutine_main_ = coro;
  coroutine_current_ = coro;
  Coro_initializeMainCoro(coro);
  coroutine_force_hook_linkage();
}

template<typename T>
inline void
coroutine_start(Coro* self, Coro* other, void (*callback)(T*), T* context)
{
  coroutine_current_ = other;
  Coro_startCoro_(self, other, context,
		  reinterpret_cast<CoroStartCallback*>(callback));
  coroutine_current_ = self;
}

inline void
coroutine_switch_to(Coro* self, Coro* next)
{
  coroutine_current_ = next;
  Coro_switchTo_(self, next);
  coroutine_current_ = self;
}

#endif // SCHED_COROUTINE_CORO_HXX
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>

#include <list>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

/*
 D := Tamanho do quadrado.
 d := tamanho das subdivisões
 n := Tamanho da matriz;

*/

typedef struct ponto{
	int x;
	int y;
	int i; // INDICE NO VETOR DE VERTICES
} *Ponto;

int pontoVertice(Ponto p);
int** alocaMatrizQuadrada(int n);
void criaGrafo();
void criaArestas(Ponto);
void novaAresta(int, int);
float distCircular(Ponto, Ponto);
void indepSet1();

float d, D;
int n, N, maxTamanho;
int** A;

vector< vector<int> > madj;

vector< list<int> > adj;
Ponto* vertices;

int main(int argc, char* argv[])
{

	D = strtof(argv[1], NULL);
	d = strtof(argv[2], NULL);
	n = D/d; /* cuidado com arredondamento */
    int N = n*n;

    madj.resize(N);

	//adj = new list<int>[n];

	A = alocaMatrizQuadrada(n);
	N = n*n;

	//adj = new vector<int>[n];
	adj.resize(N);
	vertices = new Ponto[n*n];

	Ponto pteste;

	for(int i = 0; i < n; i++)
		for( int j = 0; j < n; j++)
		{
			//A[i][j] = 1;
			Ponto p = (Ponto) malloc(sizeof(ponto));
			p->x = j; p->y = i; p->i = pontoVertice(p);
			if(i == n/2 && j == n/2) pteste = p;
			vertices[p->i] = p;
		}

	criaGrafo();
    indepSet1();

	for(int i = 0; i < n; i++)
	{
		for(int j = 0; j < n; j++)
			if(!A[i][j])printf("\033[1;31m[%d]\033[0m",A[i][j]);
			else printf("[%d]",A[i][j]);
		printf("\n");
	}

	return 0;
}

/*
	Numero os quadrados da matriz de forma crescente,
	da esquerda para a direita
*/

int pontoVertice(Ponto p)
{
	return n*p->y + p->x;
}

/*****************

	Retorna a menor distancia entre dois quadradinhos
	no quadrado, dentre todas as distâncias possiveis.

	Ou seja, trata a malha coo algo "circular"

*********************/

float distCircular(Ponto p1, Ponto p2)
{
	int x1 = p1->x, y1 = p1->y, x2 = p2->x, y2 = p2->y;
	float dx = x1 -x2, dy = y1 - y2;
	float dist1;

	if(dx < 0) dx*=-1;
	if(dy < 0) dy*=-1;

	if(dx > n/2 ) // Certeza?
		dx = n - dx;
	if(dy > n/2) // Certeza?
		dy = n - dy;

	//printf("Dist: %f\n", (dx*dx + dy*dy)*d);
	return sqrt(dx*dx + dy*dy)*d;
}

/* Vai criar o grafo onde dois pontos são
	adjacentes <=> dist = 1 (com margem de erro
	devido a aproximação)

	Obs: Ordem n^4, MELHORAR.
*/

void criaGrafo()
{
	for(int i = 0; i < N; i++)
		criaArestas(vertices[i]);
}

void criaArestas(Ponto p)
{

	A[p->x][p->y] = 0;
	for(int i = 0; i < N; i++)
	{
		Ponto p2 = vertices[i];
		float dist = distCircular(p,p2);
		if(dist >= 1-d && dist <= 1+d){ // REVER
			novaAresta(p->i,p2->i);
			A[p2->x][p2->y] = 0;
		}
			// Cria aresta entre p1 e p2
	}

}

void novoArco(int v1, int v2)
{

    madj[v1][v2] = 1;
	for (list<int>::iterator it = adj[v1].begin() ; it != adj[v1].end(); ++it)
	{
		if(*it == v2) return;
	}
	//if(find(adj[v1].begin(), adj[v1].end(), v2) != adj[v1].end())
	adj[v1].push_back(v2);
}

void novaAresta(int v1, int v2)
{
	novoArco(v1,v2);
	novoArco(v2,v1);
}

int** alocaMatrizQuadrada(int n)
{
	int** m;

	m =(int**) malloc(n*sizeof(int*));
	for(int i = 0; i < n; i++)
		m[i] =(int*) malloc(n*sizeof(int));

	return m;
}

/***************************************************
 *
 * Algoritimos para achar conjuntos independentes
 *
 *
 *
 *
 * Feitos:
 *  - Força bruta (indepSet1())
 ****************************************************/

//Supomos que v1 e v2 são do mesmo tamanho
// ---> Função usada em indepSet1()
int disjuntos(vector<int> v1, vector<int> v2)
{
    int tam = v1.size();

    for(int i = 0; i < tam; i++)
        if(v1[i] && v1[i] == v2[i]) return 0;
    return 1;
}

void indepSet1()
{
    int tam;
    Ponto p;

    p = vertices[0];
    A[p->x][p->y] = 1;
    vector<int> s(n*n);
    vector<int> maxS(n*n);
    int j;
    for(int i = 0; i < n; i++)
        s[i] = 0;
    int N = n*n;
    maxS[0] = s[0] = 1;
    maxTamanho = 1;
    j = 1;
    while(1)
    {
        printf("j = %d\n", j);

        if(j >= N)
        {
            while(j!=0 && !s[--j]);
            if(!j) break; // ACABOU!
            p = vertices[j];
            A[p->x][p->y] = 0;
            s[j++] = 0;
            tam--;
            continue;
        }
        p = vertices[j];
        A[p->x][p->y] = s[j] = 1;

        tam++;

        // Se não é mais conjunto indep, continue

        if(!disjuntos(madj[j], s))
        {
            p = vertices[j];
            A[p->x][p->y] = s[j++] = 0;

            tam--;
            continue;
        }

        // Se ainda é conj indep, frita

        if(tam > maxTamanho)
        {
            maxTamanho = tam;
            maxS = s;
        }
        j++;

    }

}

<commit_msg>Mudanças feitas na ree linux q eu n devia ter feito sem ter commitado no pc de casa<commit_after>#include <cstdio>
#include <cstdlib>

#include <list>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

/*
 D := Tamanho do quadrado.
 d := tamanho das subdivisões
 n := Tamanho da matriz;

*/

typedef struct ponto{
	int x;
	int y;
	int i; // INDICE NO VETOR DE VERTICES
} *Ponto;

int pontoVertice(Ponto p);
int** alocaMatrizQuadrada(int n);
void criaGrafo();
void criaArestas(Ponto);
void novaAresta(int, int);
float distCircular(Ponto, Ponto);
void indepSet1();

float d, D;
int n, N, maxTamanho;
//int** A;

vector< vector<int> > A;

vector< vector<int> > madj;

vector< list<int> > adj;
Ponto* vertices;

int main(int argc, char* argv[])
{

	D = strtof(argv[1], NULL);
	d = strtof(argv[2], NULL);
	n = D/d; /* cuidado com arredondamento */
    	N = n*n;

    madj.resize(N);
    for(int i = 0; i < N; i++) madj[i].resize(N);

	//adj = new list<int>[n];

	//A = alocaMatrizQuadrada(n);

    A.resize(n);
	for(int i = 0; i < n; i++) A[i].resize(n);

	N = n*n;

	//adj = new vector<int>[n];
	adj.resize(N);
	vertices = new Ponto[n*n];

	Ponto pteste;

	for(int i = 0; i < n; i++)
		for( int j = 0; j < n; j++)
		{
			A[i][j] = 0;
			Ponto p = new ponto();
			p->x = j; p->y = i; p->i = pontoVertice(p);
			if(i == n-1 && j == 0) pteste = p;
			vertices[p->i] = p;
		}

//	criaGrafo();
    //indepSet1();
	criaArestas(pteste);

	for(int i = 0; i < n; i++)
	{
		for(int j = 0; j < n; j++)
			if(!A[i][j])printf("\033[1;31m[%d]\033[0m",A[i][j]);
			else printf("[%d]",A[i][j]);
		printf("\n");
	}

	return 0;
}

/*
	Numero os quadrados da matriz de forma crescente,
	da esquerda para a direita
*/

int pontoVertice(Ponto p)
{
	return n*p->y + p->x;
	Ponto pteste;

	for(int i = 0; i < n; i++)
		for( int j = 0; j < n; j++)
		{
			A[i][j] = 0;
			Ponto p = new ponto();
			p->x = j; p->y = i; p->i = pontoVertice(p);
			if(i == n-1 && j == 0) pteste = p;
			vertices[p->i] = p;
		}
}

float dist(Ponto p1, Ponto p2)
{
	int x1 = p1->x, y1 = p1->y, x2 = p2->x, y2 = p2->y;
	float dx = x1 -x2, dy = y1 - y2;

	return sqrt(dx*dx + dy*dy)*d;
}

void grafoR1(Ponto p)
{

}

void criaCircR1(float d)
{
	D = 2;
	n = D/d;
	N = n << 1;

	madj.resize(N);
    for(int i = 0; i < N; i++) madj[i].resize(N);
	vertices = new Ponto[N];
 	A.resize(n);
	for(int i = 0; i < n; i++) A[i].resize(n);

	for(int i = 0; i < n; i++)
		for( int j = 0; j < n; j++)
		{
			A[i][j] = 0;
			Ponto p = new ponto();
			p->x = j; p->y = i; p->i = pontoVertice(p);
			if(i == n/2 && j == n/2) pteste = p;
			vertices[p->i] = p;
		}

}

/*****************

	Retorna a menor distancia entre dois quadradinhos
	no quadrado, dentre todas as distâncias possiveis.

	Ou seja, trata a malha coo algo "circular"

*********************/

float distCircular(Ponto p1, Ponto p2)
{
	int x1 = p1->x, y1 = p1->y, x2 = p2->x, y2 = p2->y;
	float dx = x1 -x2, dy = y1 - y2;
	float dist1;

	if(dx < 0) dx*=-1;
	if(dy < 0) dy*=-1;

	if(dx > n/2 ) // Certeza?
		dx = n - dx;
	if(dy > n/2) // Certeza?
		dy = n - dy;

	//printf("Dist: %f\n", (dx*dx + dy*dy)*d);
	return sqrt(dx*dx + dy*dy)*d;
}

/* Vai criar o grafo onde dois pontos são
	adjacentes <=> dist = 1 (com margem de erro
	devido a aproximação)

	Obs: Ordem n^4, MELHORAR.
*/

void criaGrafo()
{
	for(int i = 0; i < N; i++)
		criaArestas(vertices[i]);
}

void criaArestas(Ponto p)
{

	A[p->x][p->y] = 1;
	for(int i = 0; i < N; i++)
	{
		Ponto p2 = vertices[i];
		float dist = distCircular(p,p2);

		if(dist >= 1-d && dist <= 1+d){ // REVER
			novaAresta(p->i,p2->i);
			A[p2->x][p2->y] = 1;
		}

			// Cria aresta entre p1 e p2
	}

}

void novoArco(int v1, int v2)
{

    madj[v1][v2] = 1;
	for (list<int>::iterator it = adj[v1].begin() ; it != adj[v1].end(); ++it)
	{
		if(*it == v2) return;
	}
	//if(find(adj[v1].begin(), adj[v1].end(), v2) != adj[v1].end())
	adj[v1].push_back(v2);
}

void novaAresta(int v1, int v2)
{
	novoArco(v1,v2);
	novoArco(v2,v1);
}

int** alocaMatrizQuadrada(int n)
{
	int** m;

	m =(int**) malloc(n*sizeof(int*));
	for(int i = 0; i < n; i++)
		m[i] =(int*) malloc(n*sizeof(int));

	return m;
}

/***************************************************
 *
 * Algoritimos para achar conjuntos independentes
 *
 *
 *
 *
 * Feitos:
 *  - Força bruta (indepSet1())
 ****************************************************/

//Supomos que v1 e v2 são do mesmo tamanho
// ---> Função usada em indepSet1()
int disjuntos(vector<int> v1, vector<int> v2)
{
    int tam = v1.size();

    for(int i = 0; i < tam; i++)
        if(v1[i] && v1[i] == v2[i]) return 0;
    return 1;
}

void indepSet1()
{
    int tam;
    Ponto p;

    p = vertices[0];
    A[p->x][p->y] = 1;
    vector<int> s(n*n);
    vector<int> maxS(n*n);
    int j;
    for(int i = 0; i < n; i++)
        s[i] = 0;
    int N = n*n;
    maxS[0] = s[0] = 1;
    maxTamanho = 1;
    j = 1;
    while(1)
    {
        printf("j = %d\n", j);

        if(j >= N)
        {
            while(j!=0 && !s[--j]);
            if(!j) break; // ACABOU!
            p = vertices[j];
            A[p->x][p->y] = 0;
            s[j++] = 0;
            tam--;
            continue;
        }
        p = vertices[j];
        A[p->x][p->y] = s[j] = 1;

        tam++;

        // Se não é mais conjunto indep, continue

        if(!disjuntos(madj[j], s))
        {
            p = vertices[j];
            A[p->x][p->y] = s[j++] = 0;

            tam--;
            continue;
        }

        // Se ainda é conj indep, frita

        if(tam > maxTamanho)
        {
            maxTamanho = tam;
            maxS = s;
        }
        j++;

    }

}

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkContextScene.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkContextScene.h"

#include "vtkContextItem.h"
#include "vtkContext2D.h"
#include "vtkTransform2D.h"
#include "vtkMatrix3x3.h"

// Get my new commands
#include "vtkCommand.h"

#include "vtkAnnotationLink.h"
#include "vtkInteractorStyle.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderWindow.h"
#include "vtkInteractorStyleRubberBand2D.h"
#include "vtkObjectFactory.h"

// My STL containers
#include <vtkstd/vector>

//-----------------------------------------------------------------------------
// Minimal command class to handle callbacks.
class vtkContextScene::Command : public vtkCommand
{
public:
  Command(vtkContextScene *scene) { this->Target = scene; }

  virtual void Execute(vtkObject *caller, unsigned long eventId, void *callData)
    {
    if (this->Target)
      {
      vtkInteractorStyle *style = vtkInteractorStyle::SafeDownCast(caller);
      vtkRenderWindowInteractor *interactor;
      if (style)
        {
        interactor = vtkRenderWindowInteractor::SafeDownCast(style->GetInteractor());
        }

      int x = -1;
      int y = -1;
      if (interactor)
        {
        x = interactor->GetEventPosition()[0];
        y = interactor->GetEventPosition()[1];
        }

      switch (eventId)
        {
        case vtkCommand::MouseMoveEvent :
          this->Target->MouseMoveEvent(x, y);
          break;
        case vtkCommand::LeftButtonPressEvent :
          this->Target->ButtonPressEvent(0, x, y);
          break;
        case vtkCommand::MiddleButtonPressEvent :
          this->Target->ButtonPressEvent(1, x, y);
          break;
        case vtkCommand::RightButtonPressEvent :
          this->Target->ButtonPressEvent(2, x, y);
          break;
        case vtkCommand::LeftButtonReleaseEvent :
          this->Target->ButtonReleaseEvent(0, x, y);
          break;
        case vtkCommand::MiddleButtonReleaseEvent :
          this->Target->ButtonReleaseEvent(1, x, y);
          break;
        case vtkCommand::RightButtonReleaseEvent :
          this->Target->ButtonReleaseEvent(2, x, y);
          break;
        case vtkCommand::SelectionChangedEvent :
          this->Target->ProcessSelectionEvent(caller, callData);
          break;
        default:
          this->Target->ProcessEvents(caller, eventId, callData);
        }
      }
    }

  void SetTarget(vtkContextScene* t) { this->Target = t; }

  vtkContextScene *Target;
};

//-----------------------------------------------------------------------------
// Minimal storage class for STL containers etc.
class vtkContextScene::Private
{
public:
  vtkstd::vector<vtkContextItem *> items;
  vtkstd::vector<bool> itemState;
  int itemMousePressCurrent; // Index of the item with a current mouse down
  vtkContextMouseEvent Event; // Mouse event structure
};

//-----------------------------------------------------------------------------
vtkCxxRevisionMacro(vtkContextScene, "1.6");
vtkStandardNewMacro(vtkContextScene);
vtkCxxSetObjectMacro(vtkContextScene, AnnotationLink, vtkAnnotationLink);
vtkCxxSetObjectMacro(vtkContextScene, Window, vtkRenderWindow);

//-----------------------------------------------------------------------------
vtkContextScene::vtkContextScene()
{
  this->Observer = new vtkContextScene::Command(this);
  this->Storage = new Private;
  this->Storage->itemMousePressCurrent = -1;
  this->Storage->Event.Button = -1;
  this->AnnotationLink = NULL;
  this->Window = NULL;
  this->Geometry[0] = 0;
  this->Geometry[1] = 0;
}

//-----------------------------------------------------------------------------
vtkContextScene::~vtkContextScene()
{
  this->Observer->Delete();
  this->Observer = NULL;
  this->SetWindow(NULL);
  size_t size = this->Storage->items.size();
  for (size_t i = 0; i < size; ++i)
    {
    this->Storage->items[i]->UnRegister(this);
    }
  delete this->Storage;
  this->Storage = NULL;
}

//-----------------------------------------------------------------------------
bool vtkContextScene::Paint(vtkContext2D *painter)
{
  vtkDebugMacro("Paint event called.");
  size_t size = this->Storage->items.size();
  for (size_t i = 0; i < size; ++i)
    {
    painter->SetTransform(this->Storage->items[i]->GetTransform());
    this->Storage->items[i]->Paint(painter);
    }
  return true;
}

//-----------------------------------------------------------------------------
void vtkContextScene::AddItem(vtkContextItem *item)
{
  item->Register(this);
  this->Storage->items.push_back(item);
  this->Storage->itemState.push_back(false);
}

//-----------------------------------------------------------------------------
int vtkContextScene::NumberOfItems()
{
  return static_cast<int>(this->Storage->items.size());
}

//-----------------------------------------------------------------------------
vtkContextItem * vtkContextScene::GetItem(int index)
{
  if (index < this->NumberOfItems())
    {
    return this->Storage->items[index];
    }
  else
    {
    return NULL;
    }
}

//-----------------------------------------------------------------------------
void vtkContextScene::SetInteractorStyle(vtkInteractorStyle *interactor)
{
  //cout << "Interactor style " << interactor << " " << interactor->GetClassName() << endl;
  interactor->AddObserver(vtkCommand::SelectionChangedEvent, this->Observer);
  interactor->AddObserver(vtkCommand::AnyEvent, this->Observer);
}

//-----------------------------------------------------------------------------
void vtkContextScene::ProcessEvents(vtkObject* caller, unsigned long eventId,
                             void*)
{
  vtkDebugMacro("ProcessEvents called! " << caller->GetClassName() << "\t"
      << vtkCommand::GetStringFromEventId(eventId)
      << "\n\t" << vtkInteractorStyleRubberBand2D::SafeDownCast(caller)->GetInteraction());
}

//-----------------------------------------------------------------------------
void vtkContextScene::ProcessSelectionEvent(vtkObject* caller, void* callData)
{
  cout << "ProcessSelectionEvent called! " << caller << "\t" << callData << endl;
  unsigned int *rect = reinterpret_cast<unsigned int *>(callData);
  cout << "Rect:";
  for (int i = 0; i < 5; ++i)
    {
    cout << "\t" << rect[i];
    }
  cout << endl;
}

//-----------------------------------------------------------------------------
void vtkContextScene::MouseMoveEvent(int x, int y)
{
  int size = static_cast<int>(this->Storage->items.size());
  vtkContextMouseEvent &event = this->Storage->Event;
  event.ScreenPos[0] = x;
  event.ScreenPos[1] = y;
  event.ScenePos[0] = x;
  event.ScenePos[1] = y;

  // Check if there is a selected item that needs to receive a move event
  if (this->Storage->itemMousePressCurrent >= 0)
    {
    this->PerformTransform(
        this->Storage->items[this->Storage->itemMousePressCurrent]->GetTransform(),
        event);
    this->Storage->items[this->Storage->itemMousePressCurrent]->MouseMoveEvent(event);
    }
  for (int i = size-1; i >= 0; --i)
    {
    if (this->Storage->itemMousePressCurrent == i)
      {
      // Don't send the mouse move event twice...
      continue;
      }
    this->PerformTransform(this->Storage->items[i]->GetTransform(), event);
    if (this->Storage->items[i]->Hit(event))
      {
      if (!this->Storage->itemState[i] && this->Storage->itemMousePressCurrent < 0)
        {
        this->Storage->itemState[i] = true;
        this->Storage->items[i]->MouseEnterEvent(event);
        }
      }
    else
      {
      if (this->Storage->itemState[i])
        {
        this->Storage->itemState[i] = false;
        this->Storage->items[i]->MouseLeaveEvent(event);
        }
      }
    }

  // Update the last positions now
  event.LastScreenPos[0] = event.ScreenPos[0];
  event.LastScreenPos[1] = event.ScreenPos[1];
  event.LastScenePos[0] = event.ScenePos[0];
  event.LastScenePos[1] = event.ScenePos[1];

  if (this->Window)
    {
    this->Window->Render();
    }
}

//-----------------------------------------------------------------------------
void vtkContextScene::ButtonPressEvent(int button, int x, int y)
{
  int size = static_cast<int>(this->Storage->items.size());
  vtkContextMouseEvent &event = this->Storage->Event;
  event.ScreenPos[0] = event.LastScreenPos[0] = x;
  event.ScreenPos[1] = event.LastScreenPos[1] = y;
  event.ScenePos[0] = event.LastScenePos[0] = x;
  event.ScenePos[1] = event.LastScenePos[1] = y;
  event.Button = button;
  for (int i = size-1; i >= 0; --i)
    {
    this->PerformTransform(this->Storage->items[i]->GetTransform(), event);
    if (this->Storage->items[i]->Hit(event))
      {
      if (this->Storage->items[i]->MouseButtonPressEvent(event))
        {
        // The event was accepted - stop propagating
        this->Storage->itemMousePressCurrent = i;
        return;
        }
      }
    }
}

//-----------------------------------------------------------------------------
void vtkContextScene::ButtonReleaseEvent(int button, int x, int y)
{
  if (this->Storage->itemMousePressCurrent >= 0)
    {
    vtkContextMouseEvent &event = this->Storage->Event;
    event.ScreenPos[0] = x;
    event.ScreenPos[1] = y;
    event.ScenePos[0] = x;
    event.ScenePos[1] = y;
    event.Button = button;
    this->PerformTransform(
        this->Storage->items[this->Storage->itemMousePressCurrent]->GetTransform(),
        event);
    this->Storage->items[this->Storage->itemMousePressCurrent]->MouseButtonReleaseEvent(event);
    this->Storage->itemMousePressCurrent = -1;
    event.Button = -1;
    }
}

//-----------------------------------------------------------------------------
inline void vtkContextScene::PerformTransform(vtkTransform2D *transform,
                                              vtkContextMouseEvent &mouse)
{
  if (transform)
    {
    transform->InverseTransformPoints(&mouse.ScenePos[0], &mouse.Pos[0], 1);
    }
  else
    {
    mouse.Pos[0] = mouse.ScenePos[0];
    mouse.Pos[1] = mouse.ScenePos[1];
    }
}

//-----------------------------------------------------------------------------
void vtkContextScene::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  // Print out the chart's geometry if it has been set
  os << indent << "Widthxheight: " << this->Geometry[0] << "\t" << this->Geometry[1]
     << endl;
}
<commit_msg>COMP: Fixed warning about potentially uninitialized variable.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkContextScene.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkContextScene.h"

#include "vtkContextItem.h"
#include "vtkContext2D.h"
#include "vtkTransform2D.h"
#include "vtkMatrix3x3.h"

// Get my new commands
#include "vtkCommand.h"

#include "vtkAnnotationLink.h"
#include "vtkInteractorStyle.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderWindow.h"
#include "vtkInteractorStyleRubberBand2D.h"
#include "vtkObjectFactory.h"

// My STL containers
#include <vtkstd/vector>

//-----------------------------------------------------------------------------
// Minimal command class to handle callbacks.
class vtkContextScene::Command : public vtkCommand
{
public:
  Command(vtkContextScene *scene) { this->Target = scene; }

  virtual void Execute(vtkObject *caller, unsigned long eventId, void *callData)
    {
    if (this->Target)
      {
      vtkInteractorStyle *style = vtkInteractorStyle::SafeDownCast(caller);
      vtkRenderWindowInteractor *interactor = NULL;
      if (style)
        {
        interactor = vtkRenderWindowInteractor::SafeDownCast(style->GetInteractor());
        }

      int x = -1;
      int y = -1;
      if (interactor)
        {
        x = interactor->GetEventPosition()[0];
        y = interactor->GetEventPosition()[1];
        }

      switch (eventId)
        {
        case vtkCommand::MouseMoveEvent :
          this->Target->MouseMoveEvent(x, y);
          break;
        case vtkCommand::LeftButtonPressEvent :
          this->Target->ButtonPressEvent(0, x, y);
          break;
        case vtkCommand::MiddleButtonPressEvent :
          this->Target->ButtonPressEvent(1, x, y);
          break;
        case vtkCommand::RightButtonPressEvent :
          this->Target->ButtonPressEvent(2, x, y);
          break;
        case vtkCommand::LeftButtonReleaseEvent :
          this->Target->ButtonReleaseEvent(0, x, y);
          break;
        case vtkCommand::MiddleButtonReleaseEvent :
          this->Target->ButtonReleaseEvent(1, x, y);
          break;
        case vtkCommand::RightButtonReleaseEvent :
          this->Target->ButtonReleaseEvent(2, x, y);
          break;
        case vtkCommand::SelectionChangedEvent :
          this->Target->ProcessSelectionEvent(caller, callData);
          break;
        default:
          this->Target->ProcessEvents(caller, eventId, callData);
        }
      }
    }

  void SetTarget(vtkContextScene* t) { this->Target = t; }

  vtkContextScene *Target;
};

//-----------------------------------------------------------------------------
// Minimal storage class for STL containers etc.
class vtkContextScene::Private
{
public:
  vtkstd::vector<vtkContextItem *> items;
  vtkstd::vector<bool> itemState;
  int itemMousePressCurrent; // Index of the item with a current mouse down
  vtkContextMouseEvent Event; // Mouse event structure
};

//-----------------------------------------------------------------------------
vtkCxxRevisionMacro(vtkContextScene, "1.7");
vtkStandardNewMacro(vtkContextScene);
vtkCxxSetObjectMacro(vtkContextScene, AnnotationLink, vtkAnnotationLink);
vtkCxxSetObjectMacro(vtkContextScene, Window, vtkRenderWindow);

//-----------------------------------------------------------------------------
vtkContextScene::vtkContextScene()
{
  this->Observer = new vtkContextScene::Command(this);
  this->Storage = new Private;
  this->Storage->itemMousePressCurrent = -1;
  this->Storage->Event.Button = -1;
  this->AnnotationLink = NULL;
  this->Window = NULL;
  this->Geometry[0] = 0;
  this->Geometry[1] = 0;
}

//-----------------------------------------------------------------------------
vtkContextScene::~vtkContextScene()
{
  this->Observer->Delete();
  this->Observer = NULL;
  this->SetWindow(NULL);
  size_t size = this->Storage->items.size();
  for (size_t i = 0; i < size; ++i)
    {
    this->Storage->items[i]->UnRegister(this);
    }
  delete this->Storage;
  this->Storage = NULL;
}

//-----------------------------------------------------------------------------
bool vtkContextScene::Paint(vtkContext2D *painter)
{
  vtkDebugMacro("Paint event called.");
  size_t size = this->Storage->items.size();
  for (size_t i = 0; i < size; ++i)
    {
    painter->SetTransform(this->Storage->items[i]->GetTransform());
    this->Storage->items[i]->Paint(painter);
    }
  return true;
}

//-----------------------------------------------------------------------------
void vtkContextScene::AddItem(vtkContextItem *item)
{
  item->Register(this);
  this->Storage->items.push_back(item);
  this->Storage->itemState.push_back(false);
}

//-----------------------------------------------------------------------------
int vtkContextScene::NumberOfItems()
{
  return static_cast<int>(this->Storage->items.size());
}

//-----------------------------------------------------------------------------
vtkContextItem * vtkContextScene::GetItem(int index)
{
  if (index < this->NumberOfItems())
    {
    return this->Storage->items[index];
    }
  else
    {
    return NULL;
    }
}

//-----------------------------------------------------------------------------
void vtkContextScene::SetInteractorStyle(vtkInteractorStyle *interactor)
{
  //cout << "Interactor style " << interactor << " " << interactor->GetClassName() << endl;
  interactor->AddObserver(vtkCommand::SelectionChangedEvent, this->Observer);
  interactor->AddObserver(vtkCommand::AnyEvent, this->Observer);
}

//-----------------------------------------------------------------------------
void vtkContextScene::ProcessEvents(vtkObject* caller, unsigned long eventId,
                             void*)
{
  vtkDebugMacro("ProcessEvents called! " << caller->GetClassName() << "\t"
      << vtkCommand::GetStringFromEventId(eventId)
      << "\n\t" << vtkInteractorStyleRubberBand2D::SafeDownCast(caller)->GetInteraction());
}

//-----------------------------------------------------------------------------
void vtkContextScene::ProcessSelectionEvent(vtkObject* caller, void* callData)
{
  cout << "ProcessSelectionEvent called! " << caller << "\t" << callData << endl;
  unsigned int *rect = reinterpret_cast<unsigned int *>(callData);
  cout << "Rect:";
  for (int i = 0; i < 5; ++i)
    {
    cout << "\t" << rect[i];
    }
  cout << endl;
}

//-----------------------------------------------------------------------------
void vtkContextScene::MouseMoveEvent(int x, int y)
{
  int size = static_cast<int>(this->Storage->items.size());
  vtkContextMouseEvent &event = this->Storage->Event;
  event.ScreenPos[0] = x;
  event.ScreenPos[1] = y;
  event.ScenePos[0] = x;
  event.ScenePos[1] = y;

  // Check if there is a selected item that needs to receive a move event
  if (this->Storage->itemMousePressCurrent >= 0)
    {
    this->PerformTransform(
        this->Storage->items[this->Storage->itemMousePressCurrent]->GetTransform(),
        event);
    this->Storage->items[this->Storage->itemMousePressCurrent]->MouseMoveEvent(event);
    }
  for (int i = size-1; i >= 0; --i)
    {
    if (this->Storage->itemMousePressCurrent == i)
      {
      // Don't send the mouse move event twice...
      continue;
      }
    this->PerformTransform(this->Storage->items[i]->GetTransform(), event);
    if (this->Storage->items[i]->Hit(event))
      {
      if (!this->Storage->itemState[i] && this->Storage->itemMousePressCurrent < 0)
        {
        this->Storage->itemState[i] = true;
        this->Storage->items[i]->MouseEnterEvent(event);
        }
      }
    else
      {
      if (this->Storage->itemState[i])
        {
        this->Storage->itemState[i] = false;
        this->Storage->items[i]->MouseLeaveEvent(event);
        }
      }
    }

  // Update the last positions now
  event.LastScreenPos[0] = event.ScreenPos[0];
  event.LastScreenPos[1] = event.ScreenPos[1];
  event.LastScenePos[0] = event.ScenePos[0];
  event.LastScenePos[1] = event.ScenePos[1];

  if (this->Window)
    {
    this->Window->Render();
    }
}

//-----------------------------------------------------------------------------
void vtkContextScene::ButtonPressEvent(int button, int x, int y)
{
  int size = static_cast<int>(this->Storage->items.size());
  vtkContextMouseEvent &event = this->Storage->Event;
  event.ScreenPos[0] = event.LastScreenPos[0] = x;
  event.ScreenPos[1] = event.LastScreenPos[1] = y;
  event.ScenePos[0] = event.LastScenePos[0] = x;
  event.ScenePos[1] = event.LastScenePos[1] = y;
  event.Button = button;
  for (int i = size-1; i >= 0; --i)
    {
    this->PerformTransform(this->Storage->items[i]->GetTransform(), event);
    if (this->Storage->items[i]->Hit(event))
      {
      if (this->Storage->items[i]->MouseButtonPressEvent(event))
        {
        // The event was accepted - stop propagating
        this->Storage->itemMousePressCurrent = i;
        return;
        }
      }
    }
}

//-----------------------------------------------------------------------------
void vtkContextScene::ButtonReleaseEvent(int button, int x, int y)
{
  if (this->Storage->itemMousePressCurrent >= 0)
    {
    vtkContextMouseEvent &event = this->Storage->Event;
    event.ScreenPos[0] = x;
    event.ScreenPos[1] = y;
    event.ScenePos[0] = x;
    event.ScenePos[1] = y;
    event.Button = button;
    this->PerformTransform(
        this->Storage->items[this->Storage->itemMousePressCurrent]->GetTransform(),
        event);
    this->Storage->items[this->Storage->itemMousePressCurrent]->MouseButtonReleaseEvent(event);
    this->Storage->itemMousePressCurrent = -1;
    event.Button = -1;
    }
}

//-----------------------------------------------------------------------------
inline void vtkContextScene::PerformTransform(vtkTransform2D *transform,
                                              vtkContextMouseEvent &mouse)
{
  if (transform)
    {
    transform->InverseTransformPoints(&mouse.ScenePos[0], &mouse.Pos[0], 1);
    }
  else
    {
    mouse.Pos[0] = mouse.ScenePos[0];
    mouse.Pos[1] = mouse.ScenePos[1];
    }
}

//-----------------------------------------------------------------------------
void vtkContextScene::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  // Print out the chart's geometry if it has been set
  os << indent << "Widthxheight: " << this->Geometry[0] << "\t" << this->Geometry[1]
     << endl;
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016-2017 Los Alamos National Security, LLC
 *                         All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions 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.
 *
 * 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 COPYRIGHT OWNER 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.
 *
 * LA-CC 10-123
 */

//@HEADER
// ***************************************************
//
// HPCG: High Performance Conjugate Gradient Benchmark
//
// Contact:
// Michael A. Heroux ( maherou@sandia.gov)
// Jack Dongarra     (dongarra@eecs.utk.edu)
// Piotr Luszczek    (luszczek@eecs.utk.edu)
//
// ***************************************************
//@HEADER

/*!
    @file CG.hpp

    HPCG routine
 */

#pragma once

#include "hpcg.hpp"
#include "mytimer.hpp"

#include "LegionArrays.hpp"
#include "LegionMatrices.hpp"
#include "LegionCGData.hpp"
#include "VectorOps.hpp"

#include "ComputeSPMV.hpp"
#include "ComputeWAXPBY.hpp"
#include "ComputeDotProduct.hpp"
#include "ComputeMG.hpp"
#include "FutureMath.hpp"

#include <fstream>
#include <cmath>
#include <unistd.h>

// Use TICK and TOCK to time a code section in MATLAB-like fashion.
//!< record current time in 't0'
#define TICK()  t0 = mytimer()
//!< store time difference in 't' using time in 't0'
#define TOCK(t) t += mytimer() - t0

/*!
    Reference routine to compute an approximate solution to Ax = b

    @param[inout] A    The known system matrix.

    @param[inout] data The data structure with all necessary CG vectors
                  preallocated.

    @param[in]    b    The known right hand side vector.

    @param[inout] x    On entry: the initial guess; on exit: the new approximate
                       solution.

    @param[in]    maxIter  The maximum number of iterations to perform, even if
                  tolerance is not met.

    @param[in]    tolerance The stopping criterion to assert convergence: if norm
                  of residual is <= to tolerance.

    @param[out]   niters    The number of iterations actually performed.

    @param[out]   normr     The 2-norm of the residual vector after the last
                            iteration.

    @param[out]   normr0    The 2-norm of the residual vector before the first
                            iteration.

    @param[out]   times     The 7-element vector of the timing information
                            accumulated during all of the iterations.

    @param[in]    doPreconditioning The flag to indicate whether the
                  preconditioner should be invoked at each iteration.

    @return Returns zero on success and a non-zero value otherwise.

    @see CG()
*/
inline int
CG(
    SparseMatrix     &A,
    CGData           &data,
    Array<floatType> &b,
    Array<floatType> &x,
    const int        maxIter,
    const floatType  tolerance,
    int              &niters,
    floatType        &normr,
    floatType        &normr0,
    double           *times,
    bool             doPreconditioning,
    Context          ctx,
    Runtime          *lrt
) {
    using namespace std;
    // Start timing right away.
    double t_begin = mytimer();
    //
    const int print_freq = 10;
    const int rank = A.geom->data()->rank;
    const local_int_t nrow = A.sclrs->data()->localNumberOfRows;
    //
    Future normrFuture, pApFuture, rtzFuture, oldrtzFuture;
    floatType alpha = 0.0, beta = 0.0;
    double t0 = 0.0, t1 = 0.0, t2 = 0.0, t3 = 0.0, t4 = 0.0, t5 = 0.0, t6 = 0.0;
    //
    normr = 0.0;
    //
    Array<floatType> &r  = *(data.r); // Residual vector.
    Array<floatType> &z  = *(data.z); // Preconditioned residual vector.
    Array<floatType> &p  = *(data.p); // Direction vector (ncol >= nrow).
    Array<floatType> &Ap = *(data.Ap);// Holds result from A * p.
    //
    Item< DynColl<floatType> > &dcarsFT = *A.dcAllRedSumFT;
    //
    if (!doPreconditioning && rank == 0) {
        cout << "WARNING: PERFORMING UNPRECONDITIONED ITERATIONS" << endl;
    }
    // p is of length ncols, copy x to p for sparse MV operation
    CopyVector(x, p, ctx, lrt);
    //
    TICK(); // Ap = A*p
    ComputeSPMV(A, p, Ap, ctx, lrt);
    TOCK(t3);
    //
    TICK(); // r = b - Ax (x stored in p)
    ComputeWAXPBY(nrow, 1.0, b, -1.0, Ap, r, ctx, lrt);
    TOCK(t2);
    //
    TICK();
    ComputeDotProduct(nrow, r, r, normrFuture, t4, dcarsFT, ctx, lrt);
    TOCK(t1);
    //
    normr = ComputeFuture(
                &normrFuture, FMO_SQRT,
                NULL, ctx, lrt
            ).get<floatType>();
    //
    if (rank == 0) std::cout << "Initial Residual = "<< normr << std::endl;
    // Record initial residual for convergence testing.
    normr0 = normr;
    // Start iterations.
    for (int k = 1; k <= maxIter && normr / normr0 > tolerance; k++ ) {
        TICK();
        if (doPreconditioning) {
            // Apply preconditioner.
            ComputeMG(A, r, z, ctx, lrt);
        }
        else {
            // Copy r to z (no preconditioning).
            CopyVector(r, z, ctx, lrt);
        }
        TOCK(t5); // Preconditioner apply time.
        //
        if (k == 1) {
            TICK(); // Copy Mr to p.
            ComputeWAXPBY(nrow, 1.0, z, 0.0, z, p, ctx, lrt);
            TOCK(t2);
            //
            TICK(); // rtz = r' * z
            ComputeDotProduct(nrow, r, z, rtzFuture, t4, dcarsFT, ctx, lrt);
            TOCK(t1);
        }
        else {
            oldrtzFuture = rtzFuture;
            //
            TICK(); // rtz = r' * z
            ComputeDotProduct(nrow, r, z, rtzFuture, t4, dcarsFT, ctx, lrt);
            TOCK(t1);
            //
            beta = ComputeFuture(
                       &rtzFuture,
                       FMO_DIV,
                       &oldrtzFuture,
                       ctx, lrt
                   ).get<floatType>();
            //
            TICK(); // p = beta * p + z
            ComputeWAXPBY(nrow, 1.0, z, beta, p, p, ctx, lrt);
            TOCK(t2);
        }
        TICK(); // Ap = A * p
        ComputeSPMV(A, p, Ap, ctx, lrt);
        TOCK(t3);
        //
        TICK(); // alpha = p' * Ap
        ComputeDotProduct(nrow, p, Ap, pApFuture, t4, dcarsFT, ctx, lrt);
        TOCK(t1);
        //
        alpha = ComputeFuture(
                    &rtzFuture,
                    FMO_DIV,
                    &pApFuture,
                    ctx, lrt
                ).get<floatType>();
        //
        TICK(); // x = x + alpha * p
        ComputeWAXPBY(nrow, 1.0, x, alpha, p, x, ctx, lrt);
        // r = r - alpha * Ap
        ComputeWAXPBY(nrow, 1.0, r, -alpha, Ap, r, ctx, lrt);
        TOCK(t2);
        //
        TICK();
        ComputeDotProduct(nrow, r, r, normrFuture, t4, dcarsFT, ctx, lrt);
        TOCK(t1);
        //
        normr = ComputeFuture(
                    &normrFuture, FMO_SQRT,
                    NULL, ctx, lrt
                ).get<floatType>();
        //
        if (rank == 0 && ( k % print_freq == 0 || k == maxIter)) {
            cout << "Iteration = "<< k << "   Scaled Residual = "
                 << normr / normr0 << std::endl;
        }
        //
        niters = k;
  }
    // Store times.
    times[1] += t1; // Dot product time.
    times[2] += t2; // WAXPBY time.
    times[3] += t3; // SPMV time.
    times[4] += t4; // AllReduce time.
    times[5] += t5; // Preconditioner apply time.
    times[6] += t6; // Exchange halo time.
    times[0] += mytimer() - t_begin;  // Total time. All done...
    //
    return 0;
}
<commit_msg>Add TODO and style.<commit_after>/**
 * Copyright (c) 2016-2017 Los Alamos National Security, LLC
 *                         All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions 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.
 *
 * 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 COPYRIGHT OWNER 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.
 *
 * LA-CC 10-123
 */

//@HEADER
// ***************************************************
//
// HPCG: High Performance Conjugate Gradient Benchmark
//
// Contact:
// Michael A. Heroux ( maherou@sandia.gov)
// Jack Dongarra     (dongarra@eecs.utk.edu)
// Piotr Luszczek    (luszczek@eecs.utk.edu)
//
// ***************************************************
//@HEADER

/*!
    @file CG.hpp

    HPCG routine
 */

#pragma once

#include "hpcg.hpp"
#include "mytimer.hpp"

#include "LegionArrays.hpp"
#include "LegionMatrices.hpp"
#include "LegionCGData.hpp"
#include "VectorOps.hpp"

#include "ComputeSPMV.hpp"
#include "ComputeWAXPBY.hpp"
#include "ComputeDotProduct.hpp"
#include "ComputeMG.hpp"
#include "FutureMath.hpp"

#include <fstream>
#include <cmath>
#include <unistd.h>

// Use TICK and TOCK to time a code section in MATLAB-like fashion.
//!< record current time in 't0'
#define TICK()  t0 = mytimer()
//!< store time difference in 't' using time in 't0'
#define TOCK(t) t += mytimer() - t0

/*!
    Reference routine to compute an approximate solution to Ax = b

    @param[inout] A    The known system matrix.

    @param[inout] data The data structure with all necessary CG vectors
                  preallocated.

    @param[in]    b    The known right hand side vector.

    @param[inout] x    On entry: the initial guess; on exit: the new approximate
                       solution.

    @param[in]    maxIter  The maximum number of iterations to perform, even if
                  tolerance is not met.

    @param[in]    tolerance The stopping criterion to assert convergence: if norm
                  of residual is <= to tolerance.

    @param[out]   niters    The number of iterations actually performed.

    @param[out]   normr     The 2-norm of the residual vector after the last
                            iteration.

    @param[out]   normr0    The 2-norm of the residual vector before the first
                            iteration.

    @param[out]   times     The 7-element vector of the timing information
                            accumulated during all of the iterations.

    @param[in]    doPreconditioning The flag to indicate whether the
                  preconditioner should be invoked at each iteration.

    @return Returns zero on success and a non-zero value otherwise.

    @see CG()
*/
inline int
CG(
    SparseMatrix     &A,
    CGData           &data,
    Array<floatType> &b,
    Array<floatType> &x,
    const int        maxIter,
    const floatType  tolerance,
    int              &niters,
    floatType        &normr,
    floatType        &normr0,
    double           *times,
    bool             doPreconditioning,
    Context          ctx,
    Runtime          *lrt
) {
    using namespace std;
    // Start timing right away.
    double t_begin = mytimer();
    //
    const int print_freq = 10;
    const int rank = A.geom->data()->rank;
    const local_int_t nrow = A.sclrs->data()->localNumberOfRows;
    //
    Future normrFuture, pApFuture, rtzFuture, oldrtzFuture;
    floatType alpha = 0.0, beta = 0.0;
    double t0 = 0.0, t1 = 0.0, t2 = 0.0, t3 = 0.0, t4 = 0.0, t5 = 0.0, t6 = 0.0;
    //
    normr = 0.0;
    //
    Array<floatType> &r  = *(data.r); // Residual vector.
    Array<floatType> &z  = *(data.z); // Preconditioned residual vector.
    Array<floatType> &p  = *(data.p); // Direction vector (ncol >= nrow).
    Array<floatType> &Ap = *(data.Ap);// Holds result from A * p.
    //
    Item< DynColl<floatType> > &dcarsFT = *A.dcAllRedSumFT;
    //
    if (!doPreconditioning && rank == 0) {
        cout << "WARNING: PERFORMING UNPRECONDITIONED ITERATIONS" << endl;
    }
    // p is of length ncols, copy x to p for sparse MV operation
    CopyVector(x, p, ctx, lrt);
    //
    TICK(); // Ap = A*p
    ComputeSPMV(A, p, Ap, ctx, lrt);
    TOCK(t3);
    //
    TICK(); // r = b - Ax (x stored in p)
    ComputeWAXPBY(nrow, 1.0, b, -1.0, Ap, r, ctx, lrt);
    TOCK(t2);
    //
    TICK();
    ComputeDotProduct(nrow, r, r, normrFuture, t4, dcarsFT, ctx, lrt);
    TOCK(t1);
    //
    normr = ComputeFuture(
                &normrFuture, FMO_SQRT, NULL, ctx, lrt
            ).get<floatType>();
    //
    if (rank == 0) std::cout << "Initial Residual = "<< normr << std::endl;
    // Record initial residual for convergence testing.
    normr0 = normr;
    // Start iterations.
    for (int k = 1; k <= maxIter && normr / normr0 > tolerance; k++ ) {
        TICK();
        if (doPreconditioning) {
            // Apply preconditioner.
            ComputeMG(A, r, z, ctx, lrt);
        }
        else {
            // Copy r to z (no preconditioning).
            CopyVector(r, z, ctx, lrt);
        }
        TOCK(t5); // Preconditioner apply time.
        //
        if (k == 1) {
            TICK(); // Copy Mr to p.
            ComputeWAXPBY(nrow, 1.0, z, 0.0, z, p, ctx, lrt);
            TOCK(t2);
            //
            TICK(); // rtz = r' * z
            ComputeDotProduct(nrow, r, z, rtzFuture, t4, dcarsFT, ctx, lrt);
            TOCK(t1);
        }
        else {
            oldrtzFuture = rtzFuture;
            //
            TICK(); // rtz = r' * z
            ComputeDotProduct(nrow, r, z, rtzFuture, t4, dcarsFT, ctx, lrt);
            TOCK(t1);
            //
            beta = ComputeFuture(
                       &rtzFuture, FMO_DIV, &oldrtzFuture, ctx, lrt
                   ).get<floatType>();
            //
            TICK(); // p = beta * p + z
            ComputeWAXPBY(nrow, 1.0, z, beta, p, p, ctx, lrt);
            TOCK(t2);
        }
        TICK(); // Ap = A * p
        ComputeSPMV(A, p, Ap, ctx, lrt);
        TOCK(t3);
        //
        TICK(); // alpha = p' * Ap
        ComputeDotProduct(nrow, p, Ap, pApFuture, t4, dcarsFT, ctx, lrt);
        TOCK(t1);
        //
        alpha = ComputeFuture(
                    &rtzFuture, FMO_DIV, &pApFuture, ctx, lrt
                ).get<floatType>();
        //
        TICK(); // x = x + alpha * p
        ComputeWAXPBY(nrow, 1.0, x, alpha, p, x, ctx, lrt);
        // r = r - alpha * Ap
        ComputeWAXPBY(nrow, 1.0, r, -alpha, Ap, r, ctx, lrt);
        TOCK(t2);
        //
        TICK();
        ComputeDotProduct(nrow, r, r, normrFuture, t4, dcarsFT, ctx, lrt);
        TOCK(t1);
        //
        normr = ComputeFuture(
                    &normrFuture, FMO_SQRT, NULL, ctx, lrt
                ).get<floatType>();
        //
        if (rank == 0 && ( k % print_freq == 0 || k == maxIter)) {
            cout << "Iteration = "<< k << "   Scaled Residual = "
                 << normr / normr0 << std::endl;
        }
        //
        niters = k;
  }
    // TODO pass future to WAXPBY instead of future result.
    // Store times.
    times[1] += t1; // Dot product time.
    times[2] += t2; // WAXPBY time.
    times[3] += t3; // SPMV time.
    times[4] += t4; // AllReduce time.
    times[5] += t5; // Preconditioner apply time.
    times[6] += t6; // Exchange halo time.
    times[0] += mytimer() - t_begin;  // Total time. All done...
    //
    return 0;
}
<|endoftext|>


<commit_before>//===-- BuildSystemFrontend.cpp -------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "llbuild/BuildSystem/BuildSystemFrontend.h"

#include "llbuild/Basic/FileSystem.h"
#include "llbuild/Basic/LLVM.h"
#include "llbuild/Basic/PlatformUtility.h"
#include "llbuild/BuildSystem/BuildDescription.h"
#include "llbuild/BuildSystem/BuildExecutionQueue.h"
#include "llbuild/BuildSystem/BuildFile.h"

#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"

#include <atomic>
#include <memory>
#include <thread>

using namespace llbuild;
using namespace llbuild::basic;
using namespace llbuild::buildsystem;

#pragma mark - BuildSystemInvocation implementation

void BuildSystemInvocation::getUsage(int optionWidth, raw_ostream& os) {
  const struct Options {
    llvm::StringRef option, helpText;
  } options[] = {
    { "--help", "show this help message and exit" },
    { "--version", "show the tool version" },
    { "-C <PATH>, --chdir <PATH>", "change directory to PATH before building" },
    { "--no-db", "disable use of a build database" },
    { "--db <PATH>", "enable building against the database at PATH" },
    { "-f <PATH>", "load the build task file at PATH" },
    { "--serial", "do not build in parallel" },
    { "-v, --verbose", "show verbose status information" },
    { "--trace <PATH>", "trace build engine operation to PATH" },
  };

  for (const auto& entry: options) {
    os << "  " << llvm::format("%-*s", optionWidth, entry.option) << " "
       << entry.helpText << "\n";
  }
}

void BuildSystemInvocation::parse(llvm::ArrayRef<std::string> args,
                                  llvm::SourceMgr& sourceMgr) {
  auto error = [&](const Twine &message) {
    sourceMgr.PrintMessage(llvm::SMLoc{}, llvm::SourceMgr::DK_Error, message);
    hadErrors = true;
  };

  while (!args.empty()) {
    const auto& option = args.front();
    args = args.slice(1);

    if (option == "-") {
      for (const auto& arg: args) {
        positionalArgs.push_back(arg);
      }
      break;
    }

    if (!option.empty() && option[0] != '-') {
      positionalArgs.push_back(option);
      continue;
    }

    if (option == "--help") {
      showUsage = true;
      break;
    } else if (option == "--version") {
      showVersion = true;
      break;
    } else if (option == "--no-db") {
      dbPath = "";
    } else if (option == "--db") {
      if (args.empty()) {
        error("missing argument to '" + option + "'");
        break;
      }
      dbPath = args[0];
      args = args.slice(1);
    } else if (option == "-C" || option == "--chdir") {
      if (args.empty()) {
        error("missing argument to '" + option + "'");
        break;
      }
      chdirPath = args[0];
      args = args.slice(1);
    } else if (option == "-f") {
      if (args.empty()) {
        error("missing argument to '" + option + "'");
        break;
      }
      buildFilePath = args[0];
      args = args.slice(1);
    } else if (option == "--serial") {
      useSerialBuild = true;
    } else if (option == "-v" || option == "--verbose") {
      showVerboseStatus = true;
    } else if (option == "--trace") {
      if (args.empty()) {
        error("missing argument to '" + option + "'");
        break;
      }
      traceFilePath = args[0];
      args = args.slice(1);
    } else {
      error("invalid option '" + option + "'");
      break;
    }
  }
}

#pragma mark - BuildSystemFrontendDelegate implementation

namespace {

struct BuildSystemFrontendDelegateImpl;

class BuildSystemFrontendExecutionQueueDelegate
      : public BuildExecutionQueueDelegate {
  BuildSystemFrontendDelegateImpl &delegateImpl;

  bool showVerboseOutput() const;

  BuildSystem& getSystem() const;

public:
  BuildSystemFrontendExecutionQueueDelegate(
          BuildSystemFrontendDelegateImpl& delegateImpl)
      : delegateImpl(delegateImpl) { }

  virtual void commandJobStarted(Command* command) override {
    static_cast<BuildSystemFrontendDelegate*>(&getSystem().getDelegate())->
      commandJobStarted(command);
  }

  virtual void commandJobFinished(Command* command) override {
    static_cast<BuildSystemFrontendDelegate*>(&getSystem().getDelegate())->
      commandJobFinished(command);
  }

  virtual void commandProcessStarted(Command* command,
                                     ProcessHandle handle) override {
    static_cast<BuildSystemFrontendDelegate*>(&getSystem().getDelegate())->
      commandProcessStarted(
          command, BuildSystemFrontendDelegate::ProcessHandle { handle.id });
  }

  virtual void commandProcessHadError(Command* command, ProcessHandle handle,
                                      const Twine& message) override {
    static_cast<BuildSystemFrontendDelegate*>(&getSystem().getDelegate())->
      commandProcessHadError(
          command, BuildSystemFrontendDelegate::ProcessHandle { handle.id },
          message);
  }

  virtual void commandProcessHadOutput(Command* command, ProcessHandle handle,
                                       StringRef data) override {
    static_cast<BuildSystemFrontendDelegate*>(&getSystem().getDelegate())->
      commandProcessHadOutput(
          command, BuildSystemFrontendDelegate::ProcessHandle { handle.id },
          data);
  }

  virtual void commandProcessFinished(Command* command, ProcessHandle handle,
                                      CommandResult result,
                                      int exitStatus) override {
    static_cast<BuildSystemFrontendDelegate*>(&getSystem().getDelegate())->
      commandProcessFinished(
          command, BuildSystemFrontendDelegate::ProcessHandle { handle.id },
          result, exitStatus);
  }
};

struct BuildSystemFrontendDelegateImpl {
  llvm::SourceMgr& sourceMgr;
  const BuildSystemInvocation& invocation;

  StringRef bufferBeingParsed;
  std::atomic<unsigned> numErrors{0};
  std::atomic<unsigned> numFailedCommands{0};

  BuildSystemFrontendExecutionQueueDelegate executionQueueDelegate;

  BuildSystemFrontend* frontend = nullptr;
  BuildSystem* system = nullptr;

  BuildSystemFrontendDelegateImpl(llvm::SourceMgr& sourceMgr,
                                  const BuildSystemInvocation& invocation)
      : sourceMgr(sourceMgr), invocation(invocation),
        executionQueueDelegate(*this) {}
};

bool BuildSystemFrontendExecutionQueueDelegate::showVerboseOutput() const {
  return delegateImpl.invocation.showVerboseStatus;
}

BuildSystem& BuildSystemFrontendExecutionQueueDelegate::getSystem() const {
  assert(delegateImpl.system);
  return *delegateImpl.system;
}

}

BuildSystemFrontendDelegate::
BuildSystemFrontendDelegate(llvm::SourceMgr& sourceMgr,
                            const BuildSystemInvocation& invocation,
                            StringRef name,
                            uint32_t version)
    : BuildSystemDelegate(name, version),
      impl(new BuildSystemFrontendDelegateImpl(sourceMgr, invocation)), isCancelled_(false)
{

}

BuildSystemFrontendDelegate::~BuildSystemFrontendDelegate() {
  delete static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);
}

void
BuildSystemFrontendDelegate::setFileContentsBeingParsed(StringRef buffer) {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  impl->bufferBeingParsed = buffer;
}

BuildSystemFrontend& BuildSystemFrontendDelegate::getFrontend() {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  return *impl->frontend;
}

llvm::SourceMgr& BuildSystemFrontendDelegate::getSourceMgr() {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  return impl->sourceMgr;
}

unsigned BuildSystemFrontendDelegate::getNumErrors() {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  return impl->numErrors;
}

unsigned BuildSystemFrontendDelegate::getNumFailedCommands() {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  return impl->numFailedCommands;
}

void
BuildSystemFrontendDelegate::error(const Twine& message) {
  error("", {}, message.str());
}

void
BuildSystemFrontendDelegate::error(StringRef filename,
                                   const Token& at,
                                   const Twine& message) {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  ++impl->numErrors;

  // If we have a file and token, resolve the location and range to one
  // accessible by the source manager.
  //
  // FIXME: We shouldn't need to do this, but should switch llbuild to using
  // SourceMgr natively.
  llvm::SMLoc loc{};
  llvm::SMRange range{};
  if (!filename.empty() && at.start) {
    // FIXME: We ignore errors here, for now, this will be resolved when we move
    // to SourceMgr completely.
    auto buffer = getFileSystem().getFileContents(filename);
    if (buffer) {
      unsigned offset = at.start - impl->bufferBeingParsed.data();
      if (offset + at.length < buffer->getBufferSize()) {
        range.Start = loc = llvm::SMLoc::getFromPointer(
            buffer->getBufferStart() + offset);
        range.End = llvm::SMLoc::getFromPointer(
            buffer->getBufferStart() + (offset + at.length));
        getSourceMgr().AddNewSourceBuffer(std::move(buffer), llvm::SMLoc{});
      }
    }
  }

  if (range.Start.isValid()) {
    getSourceMgr().PrintMessage(loc, llvm::SourceMgr::DK_Error, message, range);
  } else {
    getSourceMgr().PrintMessage(loc, llvm::SourceMgr::DK_Error, message);
  }
  fflush(stderr);
}

std::unique_ptr<BuildExecutionQueue>
BuildSystemFrontendDelegate::createExecutionQueue() {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  if (impl->invocation.useSerialBuild) {
    return std::unique_ptr<BuildExecutionQueue>(
        createLaneBasedExecutionQueue(impl->executionQueueDelegate, 1,
                                      impl->invocation.environment));
  }

  // Get the number of CPUs to use.
  unsigned numCPUs = std::thread::hardware_concurrency();
  unsigned numLanes;
  if (numCPUs == 0) {
    error("<unknown>", {}, "unable to detect number of CPUs");
    numLanes = 1;
  } else {
    numLanes = numCPUs + 2;
  }

  return std::unique_ptr<BuildExecutionQueue>(
      createLaneBasedExecutionQueue(impl->executionQueueDelegate, numLanes,
                                    impl->invocation.environment));
}

bool BuildSystemFrontendDelegate::isCancelled() {
  // Stop the build after any command failures.
  return getNumFailedCommands() > 0 || isCancelled_;
}

void BuildSystemFrontendDelegate::cancel() {
  // FIXME: We should audit that a build is happening.
  isCancelled_ = true;

  auto delegateImpl = static_cast<BuildSystemFrontendDelegateImpl*>(impl);
  delegateImpl->system->cancel();
}

void BuildSystemFrontendDelegate::resetForBuild() {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  isCancelled_ = false;
  impl->numFailedCommands = 0;
}

void BuildSystemFrontendDelegate::hadCommandFailure() {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  // Increment the failed command count.
  ++impl->numFailedCommands;
}

void BuildSystemFrontendDelegate::commandStatusChanged(Command*,
                                                       CommandStatusKind) {
}

void BuildSystemFrontendDelegate::commandPreparing(Command*) {
}

bool BuildSystemFrontendDelegate::shouldCommandStart(Command*) {
  return true;
}

void BuildSystemFrontendDelegate::commandStarted(Command* command) {
  // Don't report status if opted out by the command.
  if (!command->shouldShowStatus()) {
    return;
  }

  // Log the command.
  //
  // FIXME: Design the logging and status output APIs.
  SmallString<64> description;
  if (getFrontend().getInvocation().showVerboseStatus) {
    command->getVerboseDescription(description);
  } else {
    command->getShortDescription(description);

    // If the short description is empty, always show the verbose one.
    if (description.empty()) {
      command->getVerboseDescription(description);
    }
  }
  fprintf(stdout, "%s\n", description.c_str());
  fflush(stdout);
}

void BuildSystemFrontendDelegate::commandFinished(Command*) {
}

void BuildSystemFrontendDelegate::commandJobStarted(Command*) {
}

void BuildSystemFrontendDelegate::commandJobFinished(Command*) {
}

void BuildSystemFrontendDelegate::commandProcessStarted(Command*,
                                                        ProcessHandle) {
}

void BuildSystemFrontendDelegate::
commandProcessHadError(Command* command, ProcessHandle handle,
                       const Twine& message) {
  SmallString<256> buffer;
  auto str = message.toStringRef(buffer);

  // FIXME: Design the logging and status output APIs.
  fwrite(str.data(), str.size(), 1, stderr);
  fputc('\n', stderr);
  fflush(stderr);
}

void BuildSystemFrontendDelegate::
commandProcessHadOutput(Command* command, ProcessHandle handle,
                        StringRef data) {
  // FIXME: Design the logging and status output APIs.
  fwrite(data.data(), data.size(), 1, stdout);
  fflush(stdout);
}

void BuildSystemFrontendDelegate::
commandProcessFinished(Command*, ProcessHandle handle,
                       CommandResult result,
                       int exitStatus) {
}

#pragma mark - BuildSystemFrontend implementation

BuildSystemFrontend::
BuildSystemFrontend(BuildSystemFrontendDelegate& delegate,
                    const BuildSystemInvocation& invocation)
    : delegate(delegate), invocation(invocation)
{
  auto delegateImpl =
    static_cast<BuildSystemFrontendDelegateImpl*>(delegate.impl);

  delegateImpl->frontend = this;
}

bool BuildSystemFrontend::initialize() {
  if (!invocation.chdirPath.empty()) {
    if (!sys::chdir(invocation.chdirPath.c_str())) {
      getDelegate().error(Twine("unable to honor --chdir: ") + strerror(errno));
      return false;
    }
  }

  // Create the build system.
  buildSystem.emplace(delegate);

  // Load the build file.
  if (!buildSystem->loadDescription(invocation.buildFilePath))
    return false;

  // Register the system back pointer.
  //
  // FIXME: Eliminate this.
  auto delegateImpl =
    static_cast<BuildSystemFrontendDelegateImpl*>(delegate.impl);
  delegateImpl->system = buildSystem.getPointer();

  // Enable tracing, if requested.
  if (!invocation.traceFilePath.empty()) {
    std::string error;
    if (!buildSystem->enableTracing(invocation.traceFilePath, &error)) {
      getDelegate().error(Twine("unable to enable tracing: ") + error);
      return false;
    }
  }

  // Attach the database.
  if (!invocation.dbPath.empty()) {
    // If the database path is relative, always make it relative to the input
    // file.
    SmallString<256> tmp;
    StringRef dbPath = invocation.dbPath;
    if (llvm::sys::path::is_relative(invocation.dbPath) &&
        dbPath.find("://") == StringRef::npos && !dbPath.startswith(":")) {
      llvm::sys::path::append(
          tmp, llvm::sys::path::parent_path(invocation.buildFilePath),
          invocation.dbPath);
      dbPath = tmp.str();
    }

    std::string error;
    if (!buildSystem->attachDB(dbPath, &error)) {
      getDelegate().error(Twine("unable to attach DB: ") + error);
      return false;
    }
  }

  return true;
}

bool BuildSystemFrontend::build(StringRef targetToBuild) {
  // Initialize the build system, if necessary
  if (!buildSystem.hasValue()) {
    if (!initialize())
      return false;
  }

  // Build the target; if something unspecified failed about the build, return
  // an error.
  if (!buildSystem->build(targetToBuild))
    return false;

  // If there were failed commands, report the count and return an error.
  if (delegate.getNumFailedCommands()) {
    getDelegate().error("build had " + Twine(delegate.getNumFailedCommands()) +
                        " command failures");
    return false;
  }

  // Otherwise, return an error only if there were unspecified errors.
  return delegate.getNumErrors() == 0;
}
<commit_msg>Increase cancellation robustness<commit_after>//===-- BuildSystemFrontend.cpp -------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "llbuild/BuildSystem/BuildSystemFrontend.h"

#include "llbuild/Basic/FileSystem.h"
#include "llbuild/Basic/LLVM.h"
#include "llbuild/Basic/PlatformUtility.h"
#include "llbuild/BuildSystem/BuildDescription.h"
#include "llbuild/BuildSystem/BuildExecutionQueue.h"
#include "llbuild/BuildSystem/BuildFile.h"

#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"

#include <atomic>
#include <memory>
#include <thread>

using namespace llbuild;
using namespace llbuild::basic;
using namespace llbuild::buildsystem;

#pragma mark - BuildSystemInvocation implementation

void BuildSystemInvocation::getUsage(int optionWidth, raw_ostream& os) {
  const struct Options {
    llvm::StringRef option, helpText;
  } options[] = {
    { "--help", "show this help message and exit" },
    { "--version", "show the tool version" },
    { "-C <PATH>, --chdir <PATH>", "change directory to PATH before building" },
    { "--no-db", "disable use of a build database" },
    { "--db <PATH>", "enable building against the database at PATH" },
    { "-f <PATH>", "load the build task file at PATH" },
    { "--serial", "do not build in parallel" },
    { "-v, --verbose", "show verbose status information" },
    { "--trace <PATH>", "trace build engine operation to PATH" },
  };

  for (const auto& entry: options) {
    os << "  " << llvm::format("%-*s", optionWidth, entry.option) << " "
       << entry.helpText << "\n";
  }
}

void BuildSystemInvocation::parse(llvm::ArrayRef<std::string> args,
                                  llvm::SourceMgr& sourceMgr) {
  auto error = [&](const Twine &message) {
    sourceMgr.PrintMessage(llvm::SMLoc{}, llvm::SourceMgr::DK_Error, message);
    hadErrors = true;
  };

  while (!args.empty()) {
    const auto& option = args.front();
    args = args.slice(1);

    if (option == "-") {
      for (const auto& arg: args) {
        positionalArgs.push_back(arg);
      }
      break;
    }

    if (!option.empty() && option[0] != '-') {
      positionalArgs.push_back(option);
      continue;
    }

    if (option == "--help") {
      showUsage = true;
      break;
    } else if (option == "--version") {
      showVersion = true;
      break;
    } else if (option == "--no-db") {
      dbPath = "";
    } else if (option == "--db") {
      if (args.empty()) {
        error("missing argument to '" + option + "'");
        break;
      }
      dbPath = args[0];
      args = args.slice(1);
    } else if (option == "-C" || option == "--chdir") {
      if (args.empty()) {
        error("missing argument to '" + option + "'");
        break;
      }
      chdirPath = args[0];
      args = args.slice(1);
    } else if (option == "-f") {
      if (args.empty()) {
        error("missing argument to '" + option + "'");
        break;
      }
      buildFilePath = args[0];
      args = args.slice(1);
    } else if (option == "--serial") {
      useSerialBuild = true;
    } else if (option == "-v" || option == "--verbose") {
      showVerboseStatus = true;
    } else if (option == "--trace") {
      if (args.empty()) {
        error("missing argument to '" + option + "'");
        break;
      }
      traceFilePath = args[0];
      args = args.slice(1);
    } else {
      error("invalid option '" + option + "'");
      break;
    }
  }
}

#pragma mark - BuildSystemFrontendDelegate implementation

namespace {

struct BuildSystemFrontendDelegateImpl;

class BuildSystemFrontendExecutionQueueDelegate
      : public BuildExecutionQueueDelegate {
  BuildSystemFrontendDelegateImpl &delegateImpl;

  bool showVerboseOutput() const;

  BuildSystem& getSystem() const;

public:
  BuildSystemFrontendExecutionQueueDelegate(
          BuildSystemFrontendDelegateImpl& delegateImpl)
      : delegateImpl(delegateImpl) { }

  virtual void commandJobStarted(Command* command) override {
    static_cast<BuildSystemFrontendDelegate*>(&getSystem().getDelegate())->
      commandJobStarted(command);
  }

  virtual void commandJobFinished(Command* command) override {
    static_cast<BuildSystemFrontendDelegate*>(&getSystem().getDelegate())->
      commandJobFinished(command);
  }

  virtual void commandProcessStarted(Command* command,
                                     ProcessHandle handle) override {
    static_cast<BuildSystemFrontendDelegate*>(&getSystem().getDelegate())->
      commandProcessStarted(
          command, BuildSystemFrontendDelegate::ProcessHandle { handle.id });
  }

  virtual void commandProcessHadError(Command* command, ProcessHandle handle,
                                      const Twine& message) override {
    static_cast<BuildSystemFrontendDelegate*>(&getSystem().getDelegate())->
      commandProcessHadError(
          command, BuildSystemFrontendDelegate::ProcessHandle { handle.id },
          message);
  }

  virtual void commandProcessHadOutput(Command* command, ProcessHandle handle,
                                       StringRef data) override {
    static_cast<BuildSystemFrontendDelegate*>(&getSystem().getDelegate())->
      commandProcessHadOutput(
          command, BuildSystemFrontendDelegate::ProcessHandle { handle.id },
          data);
  }

  virtual void commandProcessFinished(Command* command, ProcessHandle handle,
                                      CommandResult result,
                                      int exitStatus) override {
    static_cast<BuildSystemFrontendDelegate*>(&getSystem().getDelegate())->
      commandProcessFinished(
          command, BuildSystemFrontendDelegate::ProcessHandle { handle.id },
          result, exitStatus);
  }
};

struct BuildSystemFrontendDelegateImpl {
  llvm::SourceMgr& sourceMgr;
  const BuildSystemInvocation& invocation;

  StringRef bufferBeingParsed;
  std::atomic<unsigned> numErrors{0};
  std::atomic<unsigned> numFailedCommands{0};

  BuildSystemFrontendExecutionQueueDelegate executionQueueDelegate;

  BuildSystemFrontend* frontend = nullptr;
  BuildSystem* system = nullptr;

  BuildSystemFrontendDelegateImpl(llvm::SourceMgr& sourceMgr,
                                  const BuildSystemInvocation& invocation)
      : sourceMgr(sourceMgr), invocation(invocation),
        executionQueueDelegate(*this) {}
};

bool BuildSystemFrontendExecutionQueueDelegate::showVerboseOutput() const {
  return delegateImpl.invocation.showVerboseStatus;
}

BuildSystem& BuildSystemFrontendExecutionQueueDelegate::getSystem() const {
  assert(delegateImpl.system);
  return *delegateImpl.system;
}

}

BuildSystemFrontendDelegate::
BuildSystemFrontendDelegate(llvm::SourceMgr& sourceMgr,
                            const BuildSystemInvocation& invocation,
                            StringRef name,
                            uint32_t version)
    : BuildSystemDelegate(name, version),
      impl(new BuildSystemFrontendDelegateImpl(sourceMgr, invocation)), isCancelled_(false)
{

}

BuildSystemFrontendDelegate::~BuildSystemFrontendDelegate() {
  delete static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);
}

void
BuildSystemFrontendDelegate::setFileContentsBeingParsed(StringRef buffer) {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  impl->bufferBeingParsed = buffer;
}

BuildSystemFrontend& BuildSystemFrontendDelegate::getFrontend() {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  return *impl->frontend;
}

llvm::SourceMgr& BuildSystemFrontendDelegate::getSourceMgr() {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  return impl->sourceMgr;
}

unsigned BuildSystemFrontendDelegate::getNumErrors() {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  return impl->numErrors;
}

unsigned BuildSystemFrontendDelegate::getNumFailedCommands() {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  return impl->numFailedCommands;
}

void
BuildSystemFrontendDelegate::error(const Twine& message) {
  error("", {}, message.str());
}

void
BuildSystemFrontendDelegate::error(StringRef filename,
                                   const Token& at,
                                   const Twine& message) {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  ++impl->numErrors;

  // If we have a file and token, resolve the location and range to one
  // accessible by the source manager.
  //
  // FIXME: We shouldn't need to do this, but should switch llbuild to using
  // SourceMgr natively.
  llvm::SMLoc loc{};
  llvm::SMRange range{};
  if (!filename.empty() && at.start) {
    // FIXME: We ignore errors here, for now, this will be resolved when we move
    // to SourceMgr completely.
    auto buffer = getFileSystem().getFileContents(filename);
    if (buffer) {
      unsigned offset = at.start - impl->bufferBeingParsed.data();
      if (offset + at.length < buffer->getBufferSize()) {
        range.Start = loc = llvm::SMLoc::getFromPointer(
            buffer->getBufferStart() + offset);
        range.End = llvm::SMLoc::getFromPointer(
            buffer->getBufferStart() + (offset + at.length));
        getSourceMgr().AddNewSourceBuffer(std::move(buffer), llvm::SMLoc{});
      }
    }
  }

  if (range.Start.isValid()) {
    getSourceMgr().PrintMessage(loc, llvm::SourceMgr::DK_Error, message, range);
  } else {
    getSourceMgr().PrintMessage(loc, llvm::SourceMgr::DK_Error, message);
  }
  fflush(stderr);
}

std::unique_ptr<BuildExecutionQueue>
BuildSystemFrontendDelegate::createExecutionQueue() {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  if (impl->invocation.useSerialBuild) {
    return std::unique_ptr<BuildExecutionQueue>(
        createLaneBasedExecutionQueue(impl->executionQueueDelegate, 1,
                                      impl->invocation.environment));
  }

  // Get the number of CPUs to use.
  unsigned numCPUs = std::thread::hardware_concurrency();
  unsigned numLanes;
  if (numCPUs == 0) {
    error("<unknown>", {}, "unable to detect number of CPUs");
    numLanes = 1;
  } else {
    numLanes = numCPUs + 2;
  }

  return std::unique_ptr<BuildExecutionQueue>(
      createLaneBasedExecutionQueue(impl->executionQueueDelegate, numLanes,
                                    impl->invocation.environment));
}

bool BuildSystemFrontendDelegate::isCancelled() {
  // Stop the build after any command failures.
  return getNumFailedCommands() > 0 || isCancelled_;
}

void BuildSystemFrontendDelegate::cancel() {
  // FIXME: We should audit that a build is happening.
  if (isCancelled_) {
    return;
  }
  isCancelled_ = true;

  auto delegateImpl = static_cast<BuildSystemFrontendDelegateImpl*>(impl);
  auto system = delegateImpl->system;
  if (system) {
    system->cancel();
  }
}

void BuildSystemFrontendDelegate::resetForBuild() {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  isCancelled_ = false;
  impl->numFailedCommands = 0;
}

void BuildSystemFrontendDelegate::hadCommandFailure() {
  auto impl = static_cast<BuildSystemFrontendDelegateImpl*>(this->impl);

  // Increment the failed command count.
  ++impl->numFailedCommands;
}

void BuildSystemFrontendDelegate::commandStatusChanged(Command*,
                                                       CommandStatusKind) {
}

void BuildSystemFrontendDelegate::commandPreparing(Command*) {
}

bool BuildSystemFrontendDelegate::shouldCommandStart(Command*) {
  return true;
}

void BuildSystemFrontendDelegate::commandStarted(Command* command) {
  // Don't report status if opted out by the command.
  if (!command->shouldShowStatus()) {
    return;
  }

  // Log the command.
  //
  // FIXME: Design the logging and status output APIs.
  SmallString<64> description;
  if (getFrontend().getInvocation().showVerboseStatus) {
    command->getVerboseDescription(description);
  } else {
    command->getShortDescription(description);

    // If the short description is empty, always show the verbose one.
    if (description.empty()) {
      command->getVerboseDescription(description);
    }
  }
  fprintf(stdout, "%s\n", description.c_str());
  fflush(stdout);
}

void BuildSystemFrontendDelegate::commandFinished(Command*) {
}

void BuildSystemFrontendDelegate::commandJobStarted(Command*) {
}

void BuildSystemFrontendDelegate::commandJobFinished(Command*) {
}

void BuildSystemFrontendDelegate::commandProcessStarted(Command*,
                                                        ProcessHandle) {
}

void BuildSystemFrontendDelegate::
commandProcessHadError(Command* command, ProcessHandle handle,
                       const Twine& message) {
  SmallString<256> buffer;
  auto str = message.toStringRef(buffer);

  // FIXME: Design the logging and status output APIs.
  fwrite(str.data(), str.size(), 1, stderr);
  fputc('\n', stderr);
  fflush(stderr);
}

void BuildSystemFrontendDelegate::
commandProcessHadOutput(Command* command, ProcessHandle handle,
                        StringRef data) {
  // FIXME: Design the logging and status output APIs.
  fwrite(data.data(), data.size(), 1, stdout);
  fflush(stdout);
}

void BuildSystemFrontendDelegate::
commandProcessFinished(Command*, ProcessHandle handle,
                       CommandResult result,
                       int exitStatus) {
}

#pragma mark - BuildSystemFrontend implementation

BuildSystemFrontend::
BuildSystemFrontend(BuildSystemFrontendDelegate& delegate,
                    const BuildSystemInvocation& invocation)
    : delegate(delegate), invocation(invocation)
{
  auto delegateImpl =
    static_cast<BuildSystemFrontendDelegateImpl*>(delegate.impl);

  delegateImpl->frontend = this;
}

bool BuildSystemFrontend::initialize() {
  if (!invocation.chdirPath.empty()) {
    if (!sys::chdir(invocation.chdirPath.c_str())) {
      getDelegate().error(Twine("unable to honor --chdir: ") + strerror(errno));
      return false;
    }
  }

  // Create the build system.
  buildSystem.emplace(delegate);

  // Load the build file.
  if (!buildSystem->loadDescription(invocation.buildFilePath))
    return false;

  // Register the system back pointer.
  //
  // FIXME: Eliminate this.
  auto delegateImpl =
    static_cast<BuildSystemFrontendDelegateImpl*>(delegate.impl);
  delegateImpl->system = buildSystem.getPointer();

  // Enable tracing, if requested.
  if (!invocation.traceFilePath.empty()) {
    std::string error;
    if (!buildSystem->enableTracing(invocation.traceFilePath, &error)) {
      getDelegate().error(Twine("unable to enable tracing: ") + error);
      return false;
    }
  }

  // Attach the database.
  if (!invocation.dbPath.empty()) {
    // If the database path is relative, always make it relative to the input
    // file.
    SmallString<256> tmp;
    StringRef dbPath = invocation.dbPath;
    if (llvm::sys::path::is_relative(invocation.dbPath) &&
        dbPath.find("://") == StringRef::npos && !dbPath.startswith(":")) {
      llvm::sys::path::append(
          tmp, llvm::sys::path::parent_path(invocation.buildFilePath),
          invocation.dbPath);
      dbPath = tmp.str();
    }

    std::string error;
    if (!buildSystem->attachDB(dbPath, &error)) {
      getDelegate().error(Twine("unable to attach DB: ") + error);
      return false;
    }
  }

  return true;
}

bool BuildSystemFrontend::build(StringRef targetToBuild) {
  // Initialize the build system, if necessary
  if (!buildSystem.hasValue()) {
    if (!initialize())
      return false;
  }

  // Build the target; if something unspecified failed about the build, return
  // an error.
  if (!buildSystem->build(targetToBuild))
    return false;

  // If there were failed commands, report the count and return an error.
  if (delegate.getNumFailedCommands()) {
    getDelegate().error("build had " + Twine(delegate.getNumFailedCommands()) +
                        " command failures");
    return false;
  }

  // Otherwise, return an error only if there were unspecified errors.
  return delegate.getNumErrors() == 0;
}
<|endoftext|>


<commit_before>#include "MinTorqueError.h"

#include <algorithm>
using std::begin;
using std::end;
using std::find;

#include <vector>
using std::vector;

namespace CEINMS {

    void MinTorqueError::setDofsToCalibrate(const std::vector<std::string>& dofsToCalibrate) {

        dofsToCalibrate_ = dofsToCalibrate;
        updDofsToCalibrateIdx();
    }

    void MinTorqueError::setTrials(const std::vector<TrialData>& trials) {

        trials_ = trials;
        computeVariance();
        updDofsToCalibrateIdx();
    }

    void MinTorqueError::updDofsToCalibrateIdx() {
        dofsToCalibrateIdx_.clear();
        for (auto& trial : trials_) {
            vector<unsigned> indeces;
            for (auto& dof : dofsToCalibrate_){
                auto it(find(begin(trial.dofNames), end(trial.dofNames), dof));
                if (it != end(trial.dofNames))
                    indeces.emplace_back(std::distance(begin(trial.dofNames), it));
            }
            dofsToCalibrateIdx_.emplace_back(indeces);
        }
    }

    void MinTorqueError::computeVariance() {

        auto getVariance([](const std::vector<double>& v) {
            double ans(0);
            for (auto& e : v)
                ans += e;
            double avg(ans/v.size());
            double var(0), ep(0);
            for (auto& e : v) {
                var += (e - avg)*(e - avg);
                ep += (e - avg);
            }
            return ((var - ep*ep / v.size()) / (v.size() - 1)); //adjust roundoff error.. apparently
        });

        torqueVariance_.clear();
        //trialDataVariance: first dimension is the trial, second dimension is the DoF
        for (auto& trial : trials_) {
            auto dofNamesFromTrial = trial.dofNames;
            std::vector<double> trialVariance;
            for (auto& name : dofsToCalibrate_) {
                auto i(std::distance(dofNamesFromTrial.begin(),(std::find(dofNamesFromTrial.begin(), dofNamesFromTrial.end(), name))));
                trialVariance.emplace_back(getVariance(trial.torqueData.getColumn(i)));
            }
            torqueVariance_.emplace_back(trialVariance);
        }

    }

    void MinTorqueError::calculate(const std::vector<Result>& results) {
        //reset f
        f_ = 0;

        using TrialDataIt = std::vector<TrialData>::const_iterator;
        using ResultIt = std::vector<Result>::const_iterator;

        class TrialCost {
        public:
            vector<double> torqueError;
            double penalty;
            TrialCost(size_t nDofs) :
                torqueError(nDofs, 0.),
                penalty(0.) {}
;
        };

        std::vector<TrialCost> trialCosts;
        auto tIt(trials_.cbegin());
        auto rIt(results.cbegin());
        for (tIt; tIt != trials_.cend(); ++tIt, ++rIt) {
            auto trialIndex(std::distance(trials_.cbegin(), tIt));
            auto diff(tIt->torqueData - rIt->torques);
            auto squaredDiff(diff*diff);

            TrialCost trialCost(tIt->noDoF);
            for (size_t r(0); r < squaredDiff.getNRows(); ++r)
                for (auto& c : dofsToCalibrateIdx_.at(trialIndex))
                    trialCost.torqueError.at(c) += squaredDiff.at(r, c);

            for (size_t r(0); r < rIt->penalties.getNRows(); ++r)
                for (size_t c(0); c < rIt->penalties.getNColumns(); ++c)
                    trialCost.penalty += rIt->penalties.at(r, c);

            trialCosts.emplace_back(trialCost);
        }

        for (size_t trialIndex(0); trialIndex < trials_.size(); ++trialIndex) {
            for (auto& dofIdx : dofsToCalibrateIdx_.at(trialIndex))
                f_ += (trialCosts.at(trialIndex).torqueError.at(dofIdx) / torqueVariance_.at(trialIndex).at(dofIdx) +
                       trialCosts.at(trialIndex).penalty) / results.at(trialIndex).torques.getNRows();
            }

    }

}
<commit_msg>Fix bug: calibration crashes when calibrating dofs different than the subject xml<commit_after>#include "MinTorqueError.h"

#include <algorithm>
using std::begin;
using std::end;
using std::find;

#include <vector>
using std::vector;

namespace CEINMS {

    void MinTorqueError::setDofsToCalibrate(const std::vector<std::string>& dofsToCalibrate) {

        dofsToCalibrate_ = dofsToCalibrate;
        updDofsToCalibrateIdx();
    }

    void MinTorqueError::setTrials(const std::vector<TrialData>& trials) {

        trials_ = trials;
        computeVariance();
        updDofsToCalibrateIdx();
    }

    void MinTorqueError::updDofsToCalibrateIdx() {
        dofsToCalibrateIdx_.clear();
        for (auto& trial : trials_) {
            vector<unsigned> indeces;
            for (auto& dof : dofsToCalibrate_){
                auto it(find(begin(trial.dofNames), end(trial.dofNames), dof));
                if (it != end(trial.dofNames))
                    indeces.emplace_back(std::distance(begin(trial.dofNames), it));
            }
            dofsToCalibrateIdx_.emplace_back(indeces);
        }
    }

    void MinTorqueError::computeVariance() {

        auto getVariance([](const std::vector<double>& v) {
            double ans(0);
            for (auto& e : v)
                ans += e;
            double avg(ans/v.size());
            double var(0), ep(0);
            for (auto& e : v) {
                var += (e - avg)*(e - avg);
                ep += (e - avg);
            }
            return ((var - ep*ep / v.size()) / (v.size() - 1)); //adjust roundoff error.. apparently
        });

        torqueVariance_.clear();
        //trialDataVariance: first dimension is the trial, second dimension is the DoF
        for (auto& trial : trials_) {
            auto dofNamesFromTrial = trial.dofNames;
            std::vector<double> trialVariance(trial.noDoF, .0);
            for (auto& name : dofsToCalibrate_) {
                auto i(std::distance(dofNamesFromTrial.begin(),(std::find(dofNamesFromTrial.begin(), dofNamesFromTrial.end(), name))));
                trialVariance.at(i) = getVariance(trial.torqueData.getColumn(i));
            }
            torqueVariance_.emplace_back(trialVariance);
        }

    }

    void MinTorqueError::calculate(const std::vector<Result>& results) {
        //reset f
        f_ = 0;

        using TrialDataIt = std::vector<TrialData>::const_iterator;
        using ResultIt = std::vector<Result>::const_iterator;

        class TrialCost {
        public:
            vector<double> torqueError;
            double penalty;
            TrialCost(size_t nDofs) :
                torqueError(nDofs, 0.),
                penalty(0.) {}
;
        };

        std::vector<TrialCost> trialCosts;
        auto tIt(trials_.cbegin());
        auto rIt(results.cbegin());
        for (tIt; tIt != trials_.cend(); ++tIt, ++rIt) {
            auto trialIndex(std::distance(trials_.cbegin(), tIt));
            auto diff(tIt->torqueData - rIt->torques);
            auto squaredDiff(diff*diff);

            TrialCost trialCost(tIt->noDoF);
            for (size_t r(0); r < squaredDiff.getNRows(); ++r)
                for (auto& c : dofsToCalibrateIdx_.at(trialIndex))
                    trialCost.torqueError.at(c) += squaredDiff.at(r, c);

            for (size_t r(0); r < rIt->penalties.getNRows(); ++r)
                for (size_t c(0); c < rIt->penalties.getNColumns(); ++c)
                    trialCost.penalty += rIt->penalties.at(r, c);

            trialCosts.emplace_back(trialCost);
        }

        for (size_t trialIndex(0); trialIndex < trials_.size(); ++trialIndex) {
            for (auto& dofIdx : dofsToCalibrateIdx_.at(trialIndex))
                f_ += (trialCosts.at(trialIndex).torqueError.at(dofIdx) / torqueVariance_.at(trialIndex).at(dofIdx) +
                       trialCosts.at(trialIndex).penalty) / results.at(trialIndex).torques.getNRows();
            }

    }

}
<|endoftext|>