<commit_before>/*************************************************************************
* Copyright(c) 1998-2008, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

/* $Id: AliTRDarrayDictionary.cxx 25392 2008-04-23 19:40:29Z cblume $ */

/////////////////////////////////////////////////////////
//                                                     //
// Container Class for Dictionary Info                 //
//                                                     //
// Author:                                             //
//   Hermes Leon Vargas (hleon@ikf.uni-frankfurt.de)   //
//                                                     //
/////////////////////////////////////////////////////////

#include <TArray.h>

#include "AliTRDarrayDictionary.h"
#include "AliTRDfeeParam.h"
#include "AliLog.h"

ClassImp(AliTRDarrayDictionary)

Short_t *AliTRDarrayDictionary::fgLutPadNumbering = 0x0;

//________________________________________________________________________________
AliTRDarrayDictionary::AliTRDarrayDictionary()
                      :TObject()
                      ,fNdet(0)
                      ,fNrow(0)
                      ,fNcol(0)
	              ,fNumberOfChannels(0)
                      ,fNtime(0)
                      ,fNDdim(0)
                      ,fDictionary(0)
                      ,fFlag(kFALSE)
{
  //
  // AliTRDarrayDictionary default contructor
  //

  CreateLut();

}

//________________________________________________________________________________
AliTRDarrayDictionary::AliTRDarrayDictionary(Int_t nrow, Int_t ncol, Int_t ntime)
                      :TObject()
		      ,fNdet(0)
                      ,fNrow(0)
                      ,fNcol(0)
          	      ,fNumberOfChannels(0)
                      ,fNtime(0)
		      ,fNDdim(0)
		      ,fDictionary(0)
                      ,fFlag(kFALSE)
{
  //
  // AliTRDarrayDictionary contructor
  //

  CreateLut();
  Allocate(nrow,ncol,ntime);

}

//________________________________________________________________________________
AliTRDarrayDictionary::AliTRDarrayDictionary(const AliTRDarrayDictionary &a)
                      :TObject()
		      ,fNdet(a.fNdet)
                      ,fNrow(a.fNrow)
                      ,fNcol(a.fNcol)
	              ,fNumberOfChannels(a.fNumberOfChannels)
                      ,fNtime(a.fNtime)
		      ,fNDdim(a.fNDdim)
		      ,fDictionary(0)
                      ,fFlag(a.fFlag)
{
  //
  // AliTRDarrayDictionary copy constructor
  //

  fDictionary = new Int_t[fNDdim];
  for(Int_t i=0; i<fNDdim; i++)
    {
      fDictionary[i]=a.fDictionary[i];
    }

}

//________________________________________________________________________________
AliTRDarrayDictionary::~AliTRDarrayDictionary()
{
  //
  //   AliTRDarrayDictionary destructor
  //

  if(fDictionary)
    {
      delete [] fDictionary;
      fDictionary=0;
    }

}

//________________________________________________________________________________
AliTRDarrayDictionary &AliTRDarrayDictionary::operator=(const AliTRDarrayDictionary &a)
{
  //
  // Assignment operator
  //

  if(this==&a)
    {
      return *this;
    }

  if(fDictionary)
    {
      delete [] fDictionary;
    }
  fNdet=a.fNdet;
  fNDdim=a.fNDdim;
  fNrow=a.fNrow;
  fNcol=a.fNcol;
  fNumberOfChannels = a.fNumberOfChannels;
  fNtime=a.fNtime;
  fDictionary = new Int_t[fNDdim];
  for(Int_t i=0; i<fNDdim; i++)
    {
      fDictionary[i]=a.fDictionary[i];
    }
  fFlag=a.fFlag;
  return *this;

}

//________________________________________________________________________________
void AliTRDarrayDictionary::Allocate(Int_t nrow, Int_t ncol, Int_t ntime)
{
  //
  // Allocates memory for the dictionary array with dimensions
  // Row*NumberOfNecessaryMCMs*ADCchannelsInMCM*Time
  // To be consistent with AliTRDarrayADC
  // Object initialized to -1
  //

  fNrow=nrow;
  fNcol=ncol;
  fNtime=ntime;
  Int_t adcchannelspermcm = AliTRDfeeParam::GetNadcMcm();
  Int_t padspermcm = AliTRDfeeParam::GetNcolMcm();
  Int_t numberofmcms = fNcol/padspermcm;
  fNumberOfChannels = numberofmcms*adcchannelspermcm;
  fNDdim=nrow*fNumberOfChannels*ntime;
  if(fDictionary)
    {
      delete [] fDictionary;
      fDictionary=0;
    }
  fDictionary = new Int_t[fNDdim];
  memset(fDictionary,-1,sizeof(Int_t)*fNDdim);

}

//________________________________________________________________________________
void AliTRDarrayDictionary::Compress()
{
  //
  // Compress the array
  //

  //  AliDebug(1,"Compressing");
  Int_t counter=0;
  Int_t newDim=0;
  Int_t j;
  Int_t r=0;
  Int_t k=0;

  Int_t *longArr = new Int_t[fNDdim];

  if(longArr)
    {

      memset(longArr,0,sizeof(Int_t)*fNDdim);

      for(Int_t i=0;i<fNDdim; i++)
        {
          j=0;
          if(fDictionary[i]==-1)
   	    {
	      for(k=i;k<fNDdim;k++)
	        {
	          if(fDictionary[k]==-1)
		    {
		      j=j+1;
		      longArr[r]=j;
		    }
	          else
		    {
		      break;
		    }
	        }
	      r=r+1;
	    }
          i=i+j;
        }

      //Calculate the size of the compressed array
      for(Int_t i=0; i<fNDdim;i++)
        {
          if(longArr[i]!=0)
	    {
	      counter=counter+longArr[i]-1;
	    }
        }
      newDim=fNDdim-counter;   //Size of the compressed array

      //Fill the buffer of the compressed array
      Int_t* buffer = new Int_t[newDim];
      Int_t counterTwo=0;
      Int_t g=0;
      if(buffer)
        {
          for(Int_t i=0; i<newDim; i++)
            {
              if(counterTwo<fNDdim)
	        {
	          if(fDictionary[counterTwo]!=-1)
	            {
	              buffer[i]=fDictionary[counterTwo];
	            }
	          if(fDictionary[counterTwo]==-1)
	            {
	              buffer[i]=-(longArr[g]);
	              counterTwo=counterTwo+longArr[g]-1;
	              g++;
	            }
	          counterTwo++;
	        }
            }

          //Copy the buffer
          if(fDictionary)
            {
              delete [] fDictionary;
              fDictionary=0;
            }
	  fDictionary = buffer;
          fNDdim = newDim;
        }

      delete [] longArr;
      longArr=0;
    }
  fFlag=kFALSE; // This way it can be expanded afterwards
}

//________________________________________________________________________________
void AliTRDarrayDictionary::Expand()
{
  //
  //  Expand the array
  //

  if(fNDdim==0)
    {
      AliError("Called expand with dimension zero");
      return;
    }

  Int_t dimexp=0;

  if(WasExpandCalled())
    return;

  if(fDictionary&&fNDdim==1)
    {
      dimexp = -fDictionary[0];
      delete [] fDictionary;
      fDictionary=0;
      fDictionary = new Int_t[dimexp];
      fNDdim = dimexp;
      // Re-initialize the array
      memset(fDictionary,-1,sizeof(Int_t)*dimexp);
      fFlag=kTRUE; // Not expand again
      return;
    }

  Int_t *longArr = new Int_t[fNDdim];
  if(longArr && fDictionary)
    {
      //Initialize the array
      memset(longArr,0,sizeof(Int_t)*fNDdim);

      Int_t r2=0;
      for(Int_t i=0; i<fNDdim;i++)
        {
          if((fDictionary[i]<0)&&(fDictionary[i]!=-1))
	    {
	      longArr[r2]=-fDictionary[i];
	      r2++;
	    }
        }

      //Calculate new dimensions
      for(Int_t i=0; i<fNDdim;i++)
        {
          if(longArr[i]!=0)
	    dimexp=dimexp+longArr[i]-1;
	  if(longArr[i]==0)
	    break;
        }
      dimexp=dimexp+fNDdim;

      //Write in the buffer the new array
      Int_t contaexp =0;
      Int_t h=0;
      Int_t* bufferE = new Int_t[dimexp];
      memset(bufferE,-1,sizeof(Int_t)*dimexp);

      if(bufferE)
	{

          for(Int_t i=0; i<dimexp; i++)
            {
              if(fDictionary[contaexp]>=-1)
	        {
	          bufferE[i]=fDictionary[contaexp];
	        }
              if(fDictionary[contaexp]<-1)
	        {
	          i=i+longArr[h]-1;
	          h++;
	        }
              contaexp++;
            }

          //Copy the buffer
          delete [] fDictionary;
          fDictionary=bufferE;
          fNDdim = dimexp;
	}
    }
  if (longArr)
    {
      delete [] longArr;
    }
  fFlag=kTRUE; // Not expand again

}
//________________________________________________________________________________
void AliTRDarrayDictionary::Reset()
{
  //
  // Reset the array, the old contents are deleted
  // and the data array elements are set to zero.
  //

  memset(fDictionary,0,sizeof(Int_t)*fNDdim);

}
//________________________________________________________________________________
Int_t AliTRDarrayDictionary::GetData(Int_t nrow, Int_t ncol, Int_t ntime) const
{
  //
  // Get the data using the pad numbering.
  // To access data using the mcm scheme use instead
  // the method GetDataByAdcCol
  //

  Int_t corrcolumn = fgLutPadNumbering[ncol];

  return fDictionary[(nrow*fNumberOfChannels+corrcolumn)*fNtime+ntime];

}
//________________________________________________________________________________
void AliTRDarrayDictionary::SetData(Int_t nrow, Int_t ncol, Int_t ntime, Int_t value)
{
  //
  // Set the data using the pad numbering.
  // To write data using the mcm scheme use instead
  // the method SetDataByAdcCol
  //

  Int_t colnumb = fgLutPadNumbering[ncol];

  fDictionary[(nrow*fNumberOfChannels+colnumb)*fNtime+ntime]=value;

}

//________________________________________________________________________________
void AliTRDarrayDictionary::CreateLut()
{
  //
  // Initializes the Look Up Table to relate
  // pad numbering and mcm channel numbering
  //

  if(fgLutPadNumbering)  return;

   fgLutPadNumbering = new Short_t[AliTRDfeeParam::GetNcol()];
   memset(fgLutPadNumbering,0,sizeof(Short_t)*AliTRDfeeParam::GetNcol());

  for(Int_t mcm=0; mcm<8; mcm++)
    {
      Int_t lowerlimit=0+mcm*18;
      Int_t upperlimit=18+mcm*18;
      Int_t shiftposition = 1+3*mcm;
      for(Int_t index=lowerlimit;index<upperlimit;index++)
	{
	  fgLutPadNumbering[index]= index+shiftposition;
	}
    }
}
<commit_msg>Fix an issue with the expand flag and one coverity defect (Hermes)<commit_after>/*************************************************************************
* Copyright(c) 1998-2008, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

/* $Id: AliTRDarrayDictionary.cxx 25392 2008-04-23 19:40:29Z cblume $ */

/////////////////////////////////////////////////////////
//                                                     //
// Container Class for Dictionary Info                 //
//                                                     //
// Author:                                             //
//   Hermes Leon Vargas (hleon@ikf.uni-frankfurt.de)   //
//                                                     //
/////////////////////////////////////////////////////////

#include <TArray.h>

#include "AliTRDarrayDictionary.h"
#include "AliTRDfeeParam.h"
#include "AliLog.h"

ClassImp(AliTRDarrayDictionary)

Short_t *AliTRDarrayDictionary::fgLutPadNumbering = 0x0;

//________________________________________________________________________________
AliTRDarrayDictionary::AliTRDarrayDictionary()
                      :TObject()
                      ,fNdet(0)
                      ,fNrow(0)
                      ,fNcol(0)
	              ,fNumberOfChannels(0)
                      ,fNtime(0)
                      ,fNDdim(0)
                      ,fDictionary(0)
                      ,fFlag(kFALSE)
{
  //
  // AliTRDarrayDictionary default contructor
  //

  CreateLut();

}

//________________________________________________________________________________
AliTRDarrayDictionary::AliTRDarrayDictionary(Int_t nrow, Int_t ncol, Int_t ntime)
                      :TObject()
		      ,fNdet(0)
                      ,fNrow(0)
                      ,fNcol(0)
          	      ,fNumberOfChannels(0)
                      ,fNtime(0)
		      ,fNDdim(0)
		      ,fDictionary(0)
                      ,fFlag(kFALSE)
{
  //
  // AliTRDarrayDictionary contructor
  //

  CreateLut();
  Allocate(nrow,ncol,ntime);

}

//________________________________________________________________________________
AliTRDarrayDictionary::AliTRDarrayDictionary(const AliTRDarrayDictionary &a)
                      :TObject()
		      ,fNdet(a.fNdet)
                      ,fNrow(a.fNrow)
                      ,fNcol(a.fNcol)
	              ,fNumberOfChannels(a.fNumberOfChannels)
                      ,fNtime(a.fNtime)
		      ,fNDdim(a.fNDdim)
		      ,fDictionary(0)
                      ,fFlag(a.fFlag)
{
  //
  // AliTRDarrayDictionary copy constructor
  //

  fDictionary = new Int_t[fNDdim];
  for(Int_t i=0; i<fNDdim; i++)
    {
      fDictionary[i]=a.fDictionary[i];
    }

}

//________________________________________________________________________________
AliTRDarrayDictionary::~AliTRDarrayDictionary()
{
  //
  //   AliTRDarrayDictionary destructor
  //

  if(fDictionary)
    {
      delete [] fDictionary;
      fDictionary=0;
    }

}

//________________________________________________________________________________
AliTRDarrayDictionary &AliTRDarrayDictionary::operator=(const AliTRDarrayDictionary &a)
{
  //
  // Assignment operator
  //

  if(this==&a)
    {
      return *this;
    }

  if(fDictionary)
    {
      delete [] fDictionary;
    }
  fNdet=a.fNdet;
  fNDdim=a.fNDdim;
  fNrow=a.fNrow;
  fNcol=a.fNcol;
  fNumberOfChannels = a.fNumberOfChannels;
  fNtime=a.fNtime;
  fDictionary = new Int_t[fNDdim];
  for(Int_t i=0; i<fNDdim; i++)
    {
      fDictionary[i]=a.fDictionary[i];
    }
  fFlag=a.fFlag;
  return *this;

}

//________________________________________________________________________________
void AliTRDarrayDictionary::Allocate(Int_t nrow, Int_t ncol, Int_t ntime)
{
  //
  // Allocates memory for the dictionary array with dimensions
  // Row*NumberOfNecessaryMCMs*ADCchannelsInMCM*Time
  // To be consistent with AliTRDarrayADC
  // Object initialized to -1
  //

  fNrow=nrow;
  fNcol=ncol;
  fNtime=ntime;
  Int_t adcchannelspermcm = AliTRDfeeParam::GetNadcMcm();
  Int_t padspermcm = AliTRDfeeParam::GetNcolMcm();
  Int_t numberofmcms = fNcol/padspermcm;
  fNumberOfChannels = numberofmcms*adcchannelspermcm;
  fNDdim=nrow*fNumberOfChannels*ntime;
  if(fDictionary)
    {
      delete [] fDictionary;
      fDictionary=0;
    }
  fDictionary = new Int_t[fNDdim];
  memset(fDictionary,-1,sizeof(Int_t)*fNDdim);

}

//________________________________________________________________________________
void AliTRDarrayDictionary::Compress()
{
  //
  // Compress the array
  //

  //  AliDebug(1,"Compressing");
  Int_t counter=0;
  Int_t newDim=0;
  Int_t j;
  Int_t r=0;
  Int_t k=0;

  Int_t *longArr = new Int_t[fNDdim];

  if(longArr)
    {

      memset(longArr,0,sizeof(Int_t)*fNDdim);

      for(Int_t i=0;i<fNDdim; i++)
        {
          j=0;
          if(fDictionary[i]==-1)
   	    {
	      for(k=i;k<fNDdim;k++)
	        {
	          if(fDictionary[k]==-1)
		    {
		      j=j+1;
		      longArr[r]=j;
		    }
	          else
		    {
		      break;
		    }
	        }
	      r=r+1;
	    }
          i=i+j;
        }

      //Calculate the size of the compressed array
      for(Int_t i=0; i<fNDdim;i++)
        {
          if(longArr[i]!=0)
	    {
	      counter=counter+longArr[i]-1;
	    }
        }
      newDim=fNDdim-counter;   //Size of the compressed array

      //Fill the buffer of the compressed array
      Int_t* buffer = new Int_t[newDim];
      Int_t counterTwo=0;
      Int_t g=0;
      if(buffer)
        {
          for(Int_t i=0; i<newDim; i++)
            {
              if(counterTwo<fNDdim)
	        {
	          if(fDictionary[counterTwo]!=-1)
	            {
	              buffer[i]=fDictionary[counterTwo];
	            }
	          if(fDictionary[counterTwo]==-1)
	            {
	              buffer[i]=-(longArr[g]);
	              counterTwo=counterTwo+longArr[g]-1;
	              g++;
	            }
	          counterTwo++;
	        }
            }

          //Copy the buffer
          if(fDictionary)
            {
              delete [] fDictionary;
              fDictionary=0;
            }
	  fDictionary = buffer;
          fNDdim = newDim;
        }

      delete [] longArr;
      longArr=0;
    }
  fFlag=kFALSE; // This way it can be expanded afterwards
}

//________________________________________________________________________________
void AliTRDarrayDictionary::Expand()
{
  //
  //  Expand the array
  //

  if(fNDdim==0)
    {
      AliError("Called expand with dimension zero");
      return;
    }

  Int_t dimexp=0;

//   if(WasExpandCalled())
//     return;

  if(fNDdim==fNrow*fNumberOfChannels*fNtime)
    return;

  if(fDictionary&&fNDdim==1)
    {
      dimexp = -fDictionary[0];
      delete [] fDictionary;
      fDictionary=0;
      fDictionary = new Int_t[dimexp];
      fNDdim = dimexp;
      // Re-initialize the array
      memset(fDictionary,-1,sizeof(Int_t)*dimexp);
      fFlag=kTRUE; // Not expand again
      return;
    }

  Int_t *longArr = new Int_t[fNDdim];
  if(longArr && fDictionary)
    {
      //Initialize the array
      memset(longArr,0,sizeof(Int_t)*fNDdim);

      Int_t r2=0;
      for(Int_t i=0; i<fNDdim;i++)
        {
          if((fDictionary[i]<0)&&(fDictionary[i]!=-1))
	    {
	      longArr[r2]=-fDictionary[i];
	      r2++;
	    }
        }

      //Calculate new dimensions
      for(Int_t i=0; i<fNDdim;i++)
        {
          if(longArr[i]!=0)
	    dimexp=dimexp+longArr[i]-1;
	  if(longArr[i]==0)
	    break;
        }
      dimexp=dimexp+fNDdim;

      //Write in the buffer the new array
      Int_t contaexp =0;
      Int_t h=0;
      Int_t* bufferE = new Int_t[dimexp];

      if(bufferE)
	{
	  memset(bufferE,-1,sizeof(Int_t)*dimexp);
          for(Int_t i=0; i<dimexp; i++)
            {
              if(fDictionary[contaexp]>=-1)
	        {
	          bufferE[i]=fDictionary[contaexp];
	        }
              if(fDictionary[contaexp]<-1)
	        {
	          i=i+longArr[h]-1;
	          h++;
	        }
              contaexp++;
            }

          //Copy the buffer
          delete [] fDictionary;
          fDictionary=bufferE;
          fNDdim = dimexp;
	}
    }
  if (longArr)
    {
      delete [] longArr;
    }
  fFlag=kTRUE; // Not expand again

}
//________________________________________________________________________________
void AliTRDarrayDictionary::Reset()
{
  //
  // Reset the array, the old contents are deleted
  // and the data array elements are set to zero.
  //

  memset(fDictionary,0,sizeof(Int_t)*fNDdim);

}
//________________________________________________________________________________
Int_t AliTRDarrayDictionary::GetData(Int_t nrow, Int_t ncol, Int_t ntime) const
{
  //
  // Get the data using the pad numbering.
  // To access data using the mcm scheme use instead
  // the method GetDataByAdcCol
  //

  Int_t corrcolumn = fgLutPadNumbering[ncol];

  return fDictionary[(nrow*fNumberOfChannels+corrcolumn)*fNtime+ntime];

}
//________________________________________________________________________________
void AliTRDarrayDictionary::SetData(Int_t nrow, Int_t ncol, Int_t ntime, Int_t value)
{
  //
  // Set the data using the pad numbering.
  // To write data using the mcm scheme use instead
  // the method SetDataByAdcCol
  //

  Int_t colnumb = fgLutPadNumbering[ncol];

  fDictionary[(nrow*fNumberOfChannels+colnumb)*fNtime+ntime]=value;

}

//________________________________________________________________________________
void AliTRDarrayDictionary::CreateLut()
{
  //
  // Initializes the Look Up Table to relate
  // pad numbering and mcm channel numbering
  //

  if(fgLutPadNumbering)  return;

   fgLutPadNumbering = new Short_t[AliTRDfeeParam::GetNcol()];
   memset(fgLutPadNumbering,0,sizeof(Short_t)*AliTRDfeeParam::GetNcol());

  for(Int_t mcm=0; mcm<8; mcm++)
    {
      Int_t lowerlimit=0+mcm*18;
      Int_t upperlimit=18+mcm*18;
      Int_t shiftposition = 1+3*mcm;
      for(Int_t index=lowerlimit;index<upperlimit;index++)
	{
	  fgLutPadNumbering[index]= index+shiftposition;
	}
    }
}
<|endoftext|>


<commit_before>//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This tablegen backend is responsible for emitting a description of the target
// instruction set for the code generator.
//
//===----------------------------------------------------------------------===//

#include "InstrInfoEmitter.h"
#include "CodeGenTarget.h"
#include "Record.h"
#include <algorithm>
using namespace llvm;

// runEnums - Print out enum values for all of the instructions.
void InstrInfoEmitter::runEnums(std::ostream &OS) {
  EmitSourceFileHeader("Target Instruction Enum Values", OS);
  OS << "namespace llvm {\n\n";

  CodeGenTarget Target;

  // We must emit the PHI opcode first...
  Record *InstrInfo = Target.getInstructionSet();

  std::string Namespace = Target.inst_begin()->second.Namespace;

  if (!Namespace.empty())
    OS << "namespace " << Namespace << " {\n";
  OS << "  enum {\n";

  std::vector<const CodeGenInstruction*> NumberedInstructions;
  Target.getInstructionsByEnumValue(NumberedInstructions);

  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
    OS << "    " << NumberedInstructions[i]->TheDef->getName()
       << ", \t// " << i << "\n";
  }
  OS << "    INSTRUCTION_LIST_END\n";
  OS << "  };\n";
  if (!Namespace.empty())
    OS << "}\n";
  OS << "} // End llvm namespace \n";
}

void InstrInfoEmitter::printDefList(const std::vector<Record*> &Uses,
                                    unsigned Num, std::ostream &OS) const {
  OS << "static const unsigned ImplicitList" << Num << "[] = { ";
  for (unsigned i = 0, e = Uses.size(); i != e; ++i)
    OS << getQualifiedName(Uses[i]) << ", ";
  OS << "0 };\n";
}

static std::vector<Record*> GetOperandInfo(const CodeGenInstruction &Inst) {
  std::vector<Record*> Result;
  if (Inst.hasVariableNumberOfOperands)
    return Result;  // No info for variable operand instrs.

  for (unsigned i = 0, e = Inst.OperandList.size(); i != e; ++i) {
    if (Inst.OperandList[i].Rec->isSubClassOf("RegisterClass")) {
      Result.push_back(Inst.OperandList[i].Rec);
    } else {
      // This might be a multiple operand thing.
      // Targets like X86 have registers in their multi-operand operands.
      DagInit *MIOI = Inst.OperandList[i].MIOperandInfo;
      unsigned NumDefs = MIOI->getNumArgs();
      for (unsigned j = 0, e = Inst.OperandList[i].MINumOperands; j != e; ++j) {
        if (NumDefs <= j) {
          Result.push_back(0);
        } else {
          DefInit *Def = dynamic_cast<DefInit*>(MIOI->getArg(j));
          Result.push_back(Def ? Def->getDef() : 0);
        }
      }
    }
  }
  return Result;
}

// run - Emit the main instruction description records for the target...
void InstrInfoEmitter::run(std::ostream &OS) {
  GatherItinClasses();

  EmitSourceFileHeader("Target Instruction Descriptors", OS);
  OS << "namespace llvm {\n\n";

  CodeGenTarget Target;
  const std::string &TargetName = Target.getName();
  Record *InstrInfo = Target.getInstructionSet();
  Record *PHI = InstrInfo->getValueAsDef("PHIInst");

  // Emit empty implicit uses and defs lists
  OS << "static const unsigned EmptyImpList[] = { 0 };\n";

  // Keep track of all of the def lists we have emitted already.
  std::map<std::vector<Record*>, unsigned> EmittedLists;
  unsigned ListNumber = 0;

  // Emit all of the instruction's implicit uses and defs.
  for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
         E = Target.inst_end(); II != E; ++II) {
    Record *Inst = II->second.TheDef;
    std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses");
    if (!Uses.empty()) {
      unsigned &IL = EmittedLists[Uses];
      if (!IL) printDefList(Uses, IL = ++ListNumber, OS);
    }
    std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs");
    if (!Defs.empty()) {
      unsigned &IL = EmittedLists[Defs];
      if (!IL) printDefList(Defs, IL = ++ListNumber, OS);
    }
  }

  std::map<std::vector<Record*>, unsigned> OperandInfosEmitted;
  unsigned OperandListNum = 0;
  OperandInfosEmitted[std::vector<Record*>()] = ++OperandListNum;

  // Emit all of the operand info records.
  OS << "\n";
  for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
       E = Target.inst_end(); II != E; ++II) {
    std::vector<Record*> OperandInfo = GetOperandInfo(II->second);
    unsigned &N = OperandInfosEmitted[OperandInfo];
    if (N == 0) {
      N = ++OperandListNum;
      OS << "static const TargetOperandInfo OperandInfo" << N << "[] = { ";
      for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) {
        Record *RC = OperandInfo[i];
        // FIXME: We only care about register operands for now.
        if (RC && RC->isSubClassOf("RegisterClass")) {
          OS << "{ &" << getQualifiedName(RC) << "RegClass }, ";
        } else {
          OS << "{ 0 }, ";
        }
      }
      OS << "};\n";
    }
  }

  // Emit all of the TargetInstrDescriptor records.
  //
  OS << "\nstatic const TargetInstrDescriptor " << TargetName
     << "Insts[] = {\n";
  emitRecord(Target.getPHIInstruction(), 0, InstrInfo, EmittedLists,
             OperandInfosEmitted, OS);

  unsigned i = 0;
  for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
         E = Target.inst_end(); II != E; ++II)
    if (II->second.TheDef != PHI)
      emitRecord(II->second, ++i, InstrInfo, EmittedLists,
                 OperandInfosEmitted, OS);
  OS << "};\n";
  OS << "} // End llvm namespace \n";
}

void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
                                  Record *InstrInfo,
                         std::map<std::vector<Record*>, unsigned> &EmittedLists,
                               std::map<std::vector<Record*>, unsigned> &OpInfo,
                                  std::ostream &OS) {
  int NumOperands;
  if (Inst.hasVariableNumberOfOperands)
    NumOperands = -1;
  else if (!Inst.OperandList.empty())
    // Each logical operand can be multiple MI operands.
    NumOperands = Inst.OperandList.back().MIOperandNo +
                  Inst.OperandList.back().MINumOperands;
  else
    NumOperands = 0;

  OS << "  { \"";
  if (Inst.Name.empty())
    OS << Inst.TheDef->getName();
  else
    OS << Inst.Name;

  unsigned ItinClass = !IsItineraries ? 0 :
            ItinClassNumber(Inst.TheDef->getValueAsDef("Itinerary")->getName());

  OS << "\",\t" << NumOperands << ", -1, 0, false, 0, 0, "
     << ItinClass
     << ", 0";

  // Emit all of the target indepedent flags...
  if (Inst.isReturn)     OS << "|M_RET_FLAG";
  if (Inst.isBranch)     OS << "|M_BRANCH_FLAG";
  if (Inst.isBarrier)    OS << "|M_BARRIER_FLAG";
  if (Inst.hasDelaySlot) OS << "|M_DELAY_SLOT_FLAG";
  if (Inst.isCall)       OS << "|M_CALL_FLAG";
  if (Inst.isLoad)       OS << "|M_LOAD_FLAG";
  if (Inst.isStore)      OS << "|M_STORE_FLAG";
  if (Inst.isTwoAddress) OS << "|M_2_ADDR_FLAG";
  if (Inst.isConvertibleToThreeAddress) OS << "|M_CONVERTIBLE_TO_3_ADDR";
  if (Inst.isCommutable) OS << "|M_COMMUTABLE";
  if (Inst.isTerminator) OS << "|M_TERMINATOR_FLAG";
  if (Inst.usesCustomDAGSchedInserter)
    OS << "|M_USES_CUSTOM_DAG_SCHED_INSERTION";
  OS << ", 0";

  // Emit all of the target-specific flags...
  ListInit *LI    = InstrInfo->getValueAsListInit("TSFlagsFields");
  ListInit *Shift = InstrInfo->getValueAsListInit("TSFlagsShifts");
  if (LI->getSize() != Shift->getSize())
    throw "Lengths of " + InstrInfo->getName() +
          ":(TargetInfoFields, TargetInfoPositions) must be equal!";

  for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
    emitShiftedValue(Inst.TheDef, dynamic_cast<StringInit*>(LI->getElement(i)),
                     dynamic_cast<IntInit*>(Shift->getElement(i)), OS);

  OS << ", ";

  // Emit the implicit uses and defs lists...
  std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses");
  if (UseList.empty())
    OS << "EmptyImpList, ";
  else
    OS << "ImplicitList" << EmittedLists[UseList] << ", ";

  std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs");
  if (DefList.empty())
    OS << "EmptyImpList, ";
  else
    OS << "ImplicitList" << EmittedLists[DefList] << ", ";

  // Emit the operand info.
  std::vector<Record*> OperandInfo = GetOperandInfo(Inst);
  if (OperandInfo.empty())
    OS << "0";
  else
    OS << "OperandInfo" << OpInfo[OperandInfo];

  OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
}

struct LessRecord {
  bool operator()(const Record *Rec1, const Record *Rec2) const {
    return Rec1->getName() < Rec2->getName();
  }
};
void InstrInfoEmitter::GatherItinClasses() {
  std::vector<Record*> DefList =
                          Records.getAllDerivedDefinitions("InstrItinClass");
  IsItineraries = !DefList.empty();

  if (!IsItineraries) return;

  std::sort(DefList.begin(), DefList.end(), LessRecord());

  for (unsigned i = 0, N = DefList.size(); i < N; i++) {
    Record *Def = DefList[i];
    ItinClassMap[Def->getName()] = i;
  }
}

unsigned InstrInfoEmitter::ItinClassNumber(std::string ItinName) {
  return ItinClassMap[ItinName];
}

void InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val,
                                        IntInit *ShiftInt, std::ostream &OS) {
  if (Val == 0 || ShiftInt == 0)
    throw std::string("Illegal value or shift amount in TargetInfo*!");
  RecordVal *RV = R->getValue(Val->getValue());
  int Shift = ShiftInt->getValue();

  if (RV == 0 || RV->getValue() == 0)
    throw R->getName() + " doesn't have a field named '" + Val->getValue()+"'!";

  Init *Value = RV->getValue();
  if (BitInit *BI = dynamic_cast<BitInit*>(Value)) {
    if (BI->getValue()) OS << "|(1<<" << Shift << ")";
    return;
  } else if (BitsInit *BI = dynamic_cast<BitsInit*>(Value)) {
    // Convert the Bits to an integer to print...
    Init *I = BI->convertInitializerTo(new IntRecTy());
    if (I)
      if (IntInit *II = dynamic_cast<IntInit*>(I)) {
        if (II->getValue())
          OS << "|(" << II->getValue() << "<<" << Shift << ")";
        return;
      }

  } else if (IntInit *II = dynamic_cast<IntInit*>(Value)) {
    if (II->getValue()) OS << "|(" << II->getValue() << "<<" << Shift << ")";
    return;
  }

  std::cerr << "Unhandled initializer: " << *Val << "\n";
  throw "In record '" + R->getName() + "' for TSFlag emission.";
}

<commit_msg>If we want to emit things in enum order, use getInstructionsByEnumValue to get the order, don't compute it ourselves.<commit_after>//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This tablegen backend is responsible for emitting a description of the target
// instruction set for the code generator.
//
//===----------------------------------------------------------------------===//

#include "InstrInfoEmitter.h"
#include "CodeGenTarget.h"
#include "Record.h"
#include <algorithm>
using namespace llvm;

// runEnums - Print out enum values for all of the instructions.
void InstrInfoEmitter::runEnums(std::ostream &OS) {
  EmitSourceFileHeader("Target Instruction Enum Values", OS);
  OS << "namespace llvm {\n\n";

  CodeGenTarget Target;

  // We must emit the PHI opcode first...
  Record *InstrInfo = Target.getInstructionSet();

  std::string Namespace = Target.inst_begin()->second.Namespace;

  if (!Namespace.empty())
    OS << "namespace " << Namespace << " {\n";
  OS << "  enum {\n";

  std::vector<const CodeGenInstruction*> NumberedInstructions;
  Target.getInstructionsByEnumValue(NumberedInstructions);

  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
    OS << "    " << NumberedInstructions[i]->TheDef->getName()
       << ", \t// " << i << "\n";
  }
  OS << "    INSTRUCTION_LIST_END\n";
  OS << "  };\n";
  if (!Namespace.empty())
    OS << "}\n";
  OS << "} // End llvm namespace \n";
}

void InstrInfoEmitter::printDefList(const std::vector<Record*> &Uses,
                                    unsigned Num, std::ostream &OS) const {
  OS << "static const unsigned ImplicitList" << Num << "[] = { ";
  for (unsigned i = 0, e = Uses.size(); i != e; ++i)
    OS << getQualifiedName(Uses[i]) << ", ";
  OS << "0 };\n";
}

static std::vector<Record*> GetOperandInfo(const CodeGenInstruction &Inst) {
  std::vector<Record*> Result;
  if (Inst.hasVariableNumberOfOperands)
    return Result;  // No info for variable operand instrs.

  for (unsigned i = 0, e = Inst.OperandList.size(); i != e; ++i) {
    if (Inst.OperandList[i].Rec->isSubClassOf("RegisterClass")) {
      Result.push_back(Inst.OperandList[i].Rec);
    } else {
      // This might be a multiple operand thing.
      // Targets like X86 have registers in their multi-operand operands.
      DagInit *MIOI = Inst.OperandList[i].MIOperandInfo;
      unsigned NumDefs = MIOI->getNumArgs();
      for (unsigned j = 0, e = Inst.OperandList[i].MINumOperands; j != e; ++j) {
        if (NumDefs <= j) {
          Result.push_back(0);
        } else {
          DefInit *Def = dynamic_cast<DefInit*>(MIOI->getArg(j));
          Result.push_back(Def ? Def->getDef() : 0);
        }
      }
    }
  }
  return Result;
}

// run - Emit the main instruction description records for the target...
void InstrInfoEmitter::run(std::ostream &OS) {
  GatherItinClasses();

  EmitSourceFileHeader("Target Instruction Descriptors", OS);
  OS << "namespace llvm {\n\n";

  CodeGenTarget Target;
  const std::string &TargetName = Target.getName();
  Record *InstrInfo = Target.getInstructionSet();

  // Emit empty implicit uses and defs lists
  OS << "static const unsigned EmptyImpList[] = { 0 };\n";

  // Keep track of all of the def lists we have emitted already.
  std::map<std::vector<Record*>, unsigned> EmittedLists;
  unsigned ListNumber = 0;

  // Emit all of the instruction's implicit uses and defs.
  for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
         E = Target.inst_end(); II != E; ++II) {
    Record *Inst = II->second.TheDef;
    std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses");
    if (!Uses.empty()) {
      unsigned &IL = EmittedLists[Uses];
      if (!IL) printDefList(Uses, IL = ++ListNumber, OS);
    }
    std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs");
    if (!Defs.empty()) {
      unsigned &IL = EmittedLists[Defs];
      if (!IL) printDefList(Defs, IL = ++ListNumber, OS);
    }
  }

  std::map<std::vector<Record*>, unsigned> OperandInfosEmitted;
  unsigned OperandListNum = 0;
  OperandInfosEmitted[std::vector<Record*>()] = ++OperandListNum;

  // Emit all of the operand info records.
  OS << "\n";
  for (CodeGenTarget::inst_iterator II = Target.inst_begin(),
       E = Target.inst_end(); II != E; ++II) {
    std::vector<Record*> OperandInfo = GetOperandInfo(II->second);
    unsigned &N = OperandInfosEmitted[OperandInfo];
    if (N == 0) {
      N = ++OperandListNum;
      OS << "static const TargetOperandInfo OperandInfo" << N << "[] = { ";
      for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) {
        Record *RC = OperandInfo[i];
        // FIXME: We only care about register operands for now.
        if (RC && RC->isSubClassOf("RegisterClass")) {
          OS << "{ &" << getQualifiedName(RC) << "RegClass }, ";
        } else {
          OS << "{ 0 }, ";
        }
      }
      OS << "};\n";
    }
  }

  // Emit all of the TargetInstrDescriptor records in their ENUM ordering.
  //
  OS << "\nstatic const TargetInstrDescriptor " << TargetName
     << "Insts[] = {\n";
  std::vector<const CodeGenInstruction*> NumberedInstructions;
  Target.getInstructionsByEnumValue(NumberedInstructions);

  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i)
    emitRecord(*NumberedInstructions[i], i, InstrInfo, EmittedLists,
               OperandInfosEmitted, OS);
  OS << "};\n";
  OS << "} // End llvm namespace \n";
}

void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
                                  Record *InstrInfo,
                         std::map<std::vector<Record*>, unsigned> &EmittedLists,
                               std::map<std::vector<Record*>, unsigned> &OpInfo,
                                  std::ostream &OS) {
  int NumOperands;
  if (Inst.hasVariableNumberOfOperands)
    NumOperands = -1;
  else if (!Inst.OperandList.empty())
    // Each logical operand can be multiple MI operands.
    NumOperands = Inst.OperandList.back().MIOperandNo +
                  Inst.OperandList.back().MINumOperands;
  else
    NumOperands = 0;

  OS << "  { \"";
  if (Inst.Name.empty())
    OS << Inst.TheDef->getName();
  else
    OS << Inst.Name;

  unsigned ItinClass = !IsItineraries ? 0 :
            ItinClassNumber(Inst.TheDef->getValueAsDef("Itinerary")->getName());

  OS << "\",\t" << NumOperands << ", -1, 0, false, 0, 0, "
     << ItinClass
     << ", 0";

  // Emit all of the target indepedent flags...
  if (Inst.isReturn)     OS << "|M_RET_FLAG";
  if (Inst.isBranch)     OS << "|M_BRANCH_FLAG";
  if (Inst.isBarrier)    OS << "|M_BARRIER_FLAG";
  if (Inst.hasDelaySlot) OS << "|M_DELAY_SLOT_FLAG";
  if (Inst.isCall)       OS << "|M_CALL_FLAG";
  if (Inst.isLoad)       OS << "|M_LOAD_FLAG";
  if (Inst.isStore)      OS << "|M_STORE_FLAG";
  if (Inst.isTwoAddress) OS << "|M_2_ADDR_FLAG";
  if (Inst.isConvertibleToThreeAddress) OS << "|M_CONVERTIBLE_TO_3_ADDR";
  if (Inst.isCommutable) OS << "|M_COMMUTABLE";
  if (Inst.isTerminator) OS << "|M_TERMINATOR_FLAG";
  if (Inst.usesCustomDAGSchedInserter)
    OS << "|M_USES_CUSTOM_DAG_SCHED_INSERTION";
  OS << ", 0";

  // Emit all of the target-specific flags...
  ListInit *LI    = InstrInfo->getValueAsListInit("TSFlagsFields");
  ListInit *Shift = InstrInfo->getValueAsListInit("TSFlagsShifts");
  if (LI->getSize() != Shift->getSize())
    throw "Lengths of " + InstrInfo->getName() +
          ":(TargetInfoFields, TargetInfoPositions) must be equal!";

  for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
    emitShiftedValue(Inst.TheDef, dynamic_cast<StringInit*>(LI->getElement(i)),
                     dynamic_cast<IntInit*>(Shift->getElement(i)), OS);

  OS << ", ";

  // Emit the implicit uses and defs lists...
  std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses");
  if (UseList.empty())
    OS << "EmptyImpList, ";
  else
    OS << "ImplicitList" << EmittedLists[UseList] << ", ";

  std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs");
  if (DefList.empty())
    OS << "EmptyImpList, ";
  else
    OS << "ImplicitList" << EmittedLists[DefList] << ", ";

  // Emit the operand info.
  std::vector<Record*> OperandInfo = GetOperandInfo(Inst);
  if (OperandInfo.empty())
    OS << "0";
  else
    OS << "OperandInfo" << OpInfo[OperandInfo];

  OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
}

struct LessRecord {
  bool operator()(const Record *Rec1, const Record *Rec2) const {
    return Rec1->getName() < Rec2->getName();
  }
};
void InstrInfoEmitter::GatherItinClasses() {
  std::vector<Record*> DefList =
                          Records.getAllDerivedDefinitions("InstrItinClass");
  IsItineraries = !DefList.empty();

  if (!IsItineraries) return;

  std::sort(DefList.begin(), DefList.end(), LessRecord());

  for (unsigned i = 0, N = DefList.size(); i < N; i++) {
    Record *Def = DefList[i];
    ItinClassMap[Def->getName()] = i;
  }
}

unsigned InstrInfoEmitter::ItinClassNumber(std::string ItinName) {
  return ItinClassMap[ItinName];
}

void InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val,
                                        IntInit *ShiftInt, std::ostream &OS) {
  if (Val == 0 || ShiftInt == 0)
    throw std::string("Illegal value or shift amount in TargetInfo*!");
  RecordVal *RV = R->getValue(Val->getValue());
  int Shift = ShiftInt->getValue();

  if (RV == 0 || RV->getValue() == 0) {
    // This isn't an error if this is a builtin instruction.
    if (R->getName() != "PHI" && R->getName() != "INLINEASM")
      throw R->getName() + " doesn't have a field named '" +
            Val->getValue() + "'!";
    return;
  }

  Init *Value = RV->getValue();
  if (BitInit *BI = dynamic_cast<BitInit*>(Value)) {
    if (BI->getValue()) OS << "|(1<<" << Shift << ")";
    return;
  } else if (BitsInit *BI = dynamic_cast<BitsInit*>(Value)) {
    // Convert the Bits to an integer to print...
    Init *I = BI->convertInitializerTo(new IntRecTy());
    if (I)
      if (IntInit *II = dynamic_cast<IntInit*>(I)) {
        if (II->getValue()) {
          if (Shift)
            OS << "|(" << II->getValue() << "<<" << Shift << ")";
          else
            OS << "|" << II->getValue();
        }
        return;
      }

  } else if (IntInit *II = dynamic_cast<IntInit*>(Value)) {
    if (II->getValue()) {
      if (Shift)
        OS << "|(" << II->getValue() << "<<" << Shift << ")";
      else
        OS << II->getValue();
    }
    return;
  }

  std::cerr << "Unhandled initializer: " << *Val << "\n";
  throw "In record '" + R->getName() + "' for TSFlag emission.";
}

<|endoftext|>


<commit_before>#include <algorithm>
#include <cstring>
#include <limits>

#include "body_parts_recognizer.h"
#include "rgbd_image.h"

const Depth BACKGROUND_DEPTH = std::numeric_limits<Depth>::max();

struct DepthImage
{
private:

  unsigned width, height;
  std::vector<Depth> depths;

public:

  DepthImage(const RGBDImage & image)
    : width(image.width), height(image.height), depths(width * height)
  {
    for (std::size_t i = 0; i < depths.size(); ++i)
      depths[i] = image.pixels[i].d == 0 ? BACKGROUND_DEPTH : image.pixels[i].d; // we consider 0 to be invalid depth
  }

  void
  applyThreshold(int threshold)
  {
    Depth min_depth = *std::min_element(depths.begin (), depths.end ());

    for (std::size_t i = 0; i < depths.size (); ++i)
      depths[i] = depths[i] <= min_depth + threshold ? depths[i] : BACKGROUND_DEPTH;
  }

  Depth
  getDepth(float x, float y) const
  {
    int intx = int (x), inty = int (y);

    if (intx < 0 || intx >= width || inty < 0 || inty >= height)
      return BACKGROUND_DEPTH;

    return depths[intx + width * inty];
  }
};

struct DecisionTree
{
  struct Offsets
  {
    boost::int16_t du1, dv1, du2, dv2;
  };

  struct Node
  {
    Offsets offsets;
    boost::int16_t threshold;
  };

  boost::uint16_t depth;
  std::vector<Node> nodes;
  std::vector<Label> leaves;

  DecisionTree(const char * data)
  {
    std::memcpy (&depth, data, sizeof depth);
    data += sizeof depth;

    nodes.resize ((1 << depth) - 1);
    std::memcpy (&nodes.front (), data, nodes.size () * sizeof (DecisionTree::Node));
    data += nodes.size () * sizeof (DecisionTree::Node);

    leaves.resize (1 << depth);
    std::memcpy (&leaves.front (), data, leaves.size () * sizeof (Label));
    data += leaves.size () * sizeof (Label);
  }

  Label
  walk(const DepthImage & image, int x, int y) const
  {
    unsigned nid = 0;
    Depth d0 = image.getDepth(x, y);
    float scale = 1000.0f / d0;

    for(int node_depth = 0; node_depth < depth; ++node_depth)
    {
      const Node & node = nodes[nid];

      Depth d1 = image.getDepth (x + node.offsets.du1 * scale, y + node.offsets.dv1 * scale);
      Depth d2 = image.getDepth (x + node.offsets.du2 * scale, y + node.offsets.dv2 * scale);

      int feature = int (d1) - int (d2);

      if (feature > node.threshold)
        nid = nid * 2 + 2;
      else
        nid = nid * 2 + 1;
    }

    return leaves[nid - nodes.size()];
  }
};

BodyPartsRecognizer::BodyPartsRecognizer(std::size_t num_trees, const char * trees[])
{
  this->trees.resize(num_trees);

  for (std::size_t i = 0; i < num_trees; ++i)
    this->trees[i].reset(new DecisionTree(trees[i]));
}

void
BodyPartsRecognizer::recognize(const RGBDImage & image, std::vector<Label> & labels)
{
  labels.clear ();
  labels.resize (image.width * image.height);

  DepthImage depth_image(image);
  depth_image.applyThreshold(500);

  for (std::size_t i = 0; i < labels.size (); ++i)
  {
    unsigned x = i % image.width, y = i / image.width;

    if (depth_image.getDepth(x, y) != BACKGROUND_DEPTH)
    {
      unsigned bins[Labels::NUM_LABELS] = {0};

      for (std::size_t ti = 0; ti < trees.size(); ++ti)
        ++bins[trees[ti]->walk(depth_image, x, y)];

      labels[i] = std::max_element(bins, bins + Labels::NUM_LABELS) - bins;
    }
    else
    {
      labels[i] = Labels::Background;
    }
  }
}
<commit_msg>Reimplemented the consensus finder as it is in PCL.<commit_after>#include <algorithm>
#include <cstring>
#include <limits>

#include <boost/multi_array.hpp>

#include "body_parts_recognizer.h"
#include "rgbd_image.h"

const Depth BACKGROUND_DEPTH = std::numeric_limits<Depth>::max();

struct DepthImage
{
private:

  unsigned width, height;
  std::vector<Depth> depths;

public:

  DepthImage(const RGBDImage & image)
    : width(image.width), height(image.height), depths(width * height)
  {
    for (std::size_t i = 0; i < depths.size(); ++i)
      depths[i] = image.pixels[i].d == 0 ? BACKGROUND_DEPTH : image.pixels[i].d; // we consider 0 to be invalid depth
  }

  void
  applyThreshold(int threshold)
  {
    Depth min_depth = *std::min_element(depths.begin (), depths.end ());

    for (std::size_t i = 0; i < depths.size (); ++i)
      depths[i] = depths[i] <= min_depth + threshold ? depths[i] : BACKGROUND_DEPTH;
  }

  Depth
  getDepth(float x, float y) const
  {
    int intx = int (x), inty = int (y);

    if (intx < 0 || intx >= width || inty < 0 || inty >= height)
      return BACKGROUND_DEPTH;

    return depths[intx + width * inty];
  }
};

struct DecisionTree
{
  struct Offsets
  {
    boost::int16_t du1, dv1, du2, dv2;
  };

  struct Node
  {
    Offsets offsets;
    boost::int16_t threshold;
  };

  boost::uint16_t depth;
  std::vector<Node> nodes;
  std::vector<Label> leaves;

  DecisionTree(const char * data)
  {
    std::memcpy (&depth, data, sizeof depth);
    data += sizeof depth;

    nodes.resize ((1 << depth) - 1);
    std::memcpy (&nodes.front (), data, nodes.size () * sizeof (DecisionTree::Node));
    data += nodes.size () * sizeof (DecisionTree::Node);

    leaves.resize (1 << depth);
    std::memcpy (&leaves.front (), data, leaves.size () * sizeof (Label));
    data += leaves.size () * sizeof (Label);
  }

  Label
  walk(const DepthImage & image, int x, int y) const
  {
    unsigned nid = 0;
    Depth d0 = image.getDepth(x, y);
    float scale = 1000.0f / d0;

    for(int node_depth = 0; node_depth < depth; ++node_depth)
    {
      const Node & node = nodes[nid];

      Depth d1 = image.getDepth (x + node.offsets.du1 * scale, y + node.offsets.dv1 * scale);
      Depth d2 = image.getDepth (x + node.offsets.du2 * scale, y + node.offsets.dv2 * scale);

      int feature = int (d1) - int (d2);

      if (feature > node.threshold)
        nid = nid * 2 + 2;
      else
        nid = nid * 2 + 1;
    }

    return leaves[nid - nodes.size()];
  }
};

BodyPartsRecognizer::BodyPartsRecognizer(std::size_t num_trees, const char * trees[])
{
  this->trees.resize(num_trees);

  for (std::size_t i = 0; i < num_trees; ++i)
    this->trees[i].reset(new DecisionTree(trees[i]));
}

void
BodyPartsRecognizer::recognize(const RGBDImage & image, std::vector<Label> & labels)
{
  labels.clear ();
  labels.resize (image.width * image.height);

  DepthImage depth_image (image);
  depth_image.applyThreshold (500);

  boost::multi_array<Label, 2> multi_labels (boost::extents[trees.size ()][labels.size ()]);

  for (std::size_t ti = 0; ti < trees.size (); ++ti)
  {
    for (std::size_t i = 0; i < labels.size (); ++i)
    {
      int x = i % image.width, y = i / image.width;
      multi_labels[ti][i] = depth_image.getDepth (x, y) != BACKGROUND_DEPTH
          ? trees[ti]->walk (depth_image, x, y) : Labels::Background;
    }
  }

  for (std::size_t i = 0; i < labels.size (); ++i)
  {
    int bins[Labels::NUM_LABELS] = { 0 };

    for (std::size_t ti = 0; ti < trees.size (); ++ti)
      ++bins[multi_labels[ti][i]];

    labels[i] = std::max_element (bins, bins + Labels::NUM_LABELS) - bins;

    if (std::count (bins, bins + Labels::NUM_LABELS, bins[labels[i]]) > 1)
    {
      std::fill (bins, bins + Labels::NUM_LABELS, 0);
      unsigned x = i % image.width, y = i / image.width;
      Depth d = depth_image.getDepth (x, y);

      for (int off_x = -1; off_x <= 1; ++off_x)
        for (int off_y = -1; off_y <= 1; ++off_y)
        {
          Depth off_d = depth_image.getDepth (x + off_x, y + off_y);

          if (std::abs (d - off_d) < 50)
            for (std::size_t ti = 0; ti < trees.size (); ++ti)
              ++bins[multi_labels[ti][i]];
        }

      labels[i] = std::max_element (bins, bins + Labels::NUM_LABELS) - bins;
    }
  }
}
<|endoftext|>


<commit_before>/*  This file is part of the Vc library.

    Copyright (C) 2009 Matthias Kretz <kretz@kde.org>

    Vc is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
    published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    Vc is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with Vc.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <Vc/Vc>
#include "benchmark.h"
#include "random.h"
#include "cpuid.h"
#include <cstdio>
#include <cstdlib>

using namespace Vc;

template<typename T> static inline void keepResults(const T &tmp0)
{
#if VC_IMPL_SSE
    asm volatile(""::"x"(reinterpret_cast<const __m128 &>(tmp0)));
    if (sizeof(T) == 32) {
        asm volatile(""::"x"(reinterpret_cast<const __m128 *>(&tmp0)[1]));
    }
#else
    asm volatile(""::"r"(tmp0));
#endif
}
template<typename Vector> class DoCompares
{
    enum {
        Factor2 = 128
    };
    public:
        static void run(const int Repetitions)
        {
            const int Factor = CpuId::L1Data() / (sizeof(Vector) * 4); // quarter L1
            Vector *a = new Vector[Factor + 3];
            for (int i = 0; i < Factor + 3; ++i) {
                a[i] = PseudoRandom<Vector>::next();
            }

#ifdef VC_IMPL_Scalar
            typedef bool M;
#else
            typedef typename Vector::Mask M;
#endif

            {
                Benchmark timer("operator==", Vector::Size * Factor * Factor2 * 6.0, "Op");
                for (int repetitions = 0; repetitions < Repetitions; ++repetitions) {
                    timer.Start();
                    M tmp;
                    Vector a0 = a[0];
                    Vector a1 = a[1];
                    Vector a2 = a[2];
                    Vector a3 = a[3];
                    for (int j = 0; j < Factor2; ++j) {
                        for (int i = 0; i < Factor; ++i) {
                            tmp = a0 == a1; keepResults(tmp);
                            tmp = a0 == a2; keepResults(tmp);
                            tmp = a0 == a3; keepResults(tmp);
                            tmp = a1 == a2; keepResults(tmp);
                            tmp = a1 == a3; keepResults(tmp);
                            tmp = a2 == a3; keepResults(tmp);
                            a1 = a2; a2 = a3; a3 = a[i + 3];
                        }
                    }
                    timer.Stop();
                }
                timer.Print(Benchmark::PrintAverage);
            }
            {
                Benchmark timer("operator<", Vector::Size * Factor * Factor2 * 6.0, "Op");
                for (int repetitions = 0; repetitions < Repetitions; ++repetitions) {
                    timer.Start();
                    M tmp;
                    Vector a0 = a[0];
                    Vector a1 = a[1];
                    Vector a2 = a[2];
                    Vector a3 = a[3];
                    for (int j = 0; j < Factor2; ++j) {
                        for (int i = 0; i < Factor; ++i) {
                            tmp = a0 < a1; keepResults(tmp);
                            tmp = a0 < a2; keepResults(tmp);
                            tmp = a0 < a3; keepResults(tmp);
                            tmp = a1 < a2; keepResults(tmp);
                            tmp = a1 < a3; keepResults(tmp);
                            tmp = a2 < a3; keepResults(tmp);
                            a1 = a2; a2 = a3; a3 = a[i + 3];
                        }
                    }
                    timer.Stop();
                }
                timer.Print(Benchmark::PrintAverage);
            }
            {
                Benchmark timer("(operator<).isFull()", Vector::Size * Factor * Factor2 * 6.0, "Op");
                for (int repetitions = 0; repetitions < Repetitions; ++repetitions) {
                    timer.Start();
                    Vector a0 = a[0];
                    Vector a1 = a[1];
                    Vector a2 = a[2];
                    Vector a3 = a[3];
                    for (int j = 0; j < Factor2; ++j) {
                        for (int i = 0; i < Factor; ++i) {
                            if ((a0 < a1).isFull()) asm volatile("");
                            if ((a0 < a2).isFull()) asm volatile("");
                            if ((a0 < a3).isFull()) asm volatile("");
                            if ((a1 < a2).isFull()) asm volatile("");
                            if ((a1 < a3).isFull()) asm volatile("");
                            if ((a2 < a3).isFull()) asm volatile("");
                            a1 = a2; a2 = a3; a3 = a[i + 3];
                        }
                    }
                    timer.Stop();
                }
                timer.Print(Benchmark::PrintAverage);
            }
            {
                Benchmark timer("!(operator<).isEmpty()", Vector::Size * Factor * Factor2 * 6.0, "Op");
                for (int repetitions = 0; repetitions < Repetitions; ++repetitions) {
                    timer.Start();
                    Vector a0 = a[0];
                    Vector a1 = a[1];
                    Vector a2 = a[2];
                    Vector a3 = a[3];
                    for (int j = 0; j < Factor2; ++j) {
                        for (int i = 0; i < Factor; ++i) {
                            if (!(a0 < a1).isEmpty()) asm volatile("");
                            if (!(a0 < a2).isEmpty()) asm volatile("");
                            if (!(a0 < a3).isEmpty()) asm volatile("");
                            if (!(a1 < a2).isEmpty()) asm volatile("");
                            if (!(a1 < a3).isEmpty()) asm volatile("");
                            if (!(a2 < a3).isEmpty()) asm volatile("");
                            a1 = a2; a2 = a3; a3 = a[i + 3];
                        }
                    }
                    timer.Stop();
                }
                timer.Print(Benchmark::PrintAverage);
            }
            delete[] a;
        }
};

int bmain(Benchmark::OutputMode out)
{
    const int Repetitions = out == Benchmark::Stdout ? 10 : g_Repetitions > 0 ? g_Repetitions : 200;

    Benchmark::addColumn("datatype");

    Benchmark::setColumnData("datatype", "double_v");
    DoCompares<double_v>::run(Repetitions);
    Benchmark::setColumnData("datatype", "float_v");
    DoCompares<float_v>::run(Repetitions);
    Benchmark::setColumnData("datatype", "int_v");
    DoCompares<int_v>::run(Repetitions);
    Benchmark::setColumnData("datatype", "uint_v");
    DoCompares<uint_v>::run(Repetitions);
    Benchmark::setColumnData("datatype", "short_v");
    DoCompares<short_v>::run(Repetitions);
    Benchmark::setColumnData("datatype", "ushort_v");
    DoCompares<ushort_v>::run(Repetitions);
    Benchmark::setColumnData("datatype", "sfloat_v");
    DoCompares<sfloat_v>::run(Repetitions);

    return 0;
}
<commit_msg>and again a different benchmark; do more memory reads in 0.5*L1<commit_after>/*  This file is part of the Vc library.

    Copyright (C) 2009 Matthias Kretz <kretz@kde.org>

    Vc is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
    published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    Vc is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with Vc.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <Vc/Vc>
#include "benchmark.h"
#include "random.h"
#include "cpuid.h"
#include <cstdio>
#include <cstdlib>

using namespace Vc;

template<typename T> static inline void keepResults(const T &tmp0)
{
#if VC_IMPL_SSE
    asm volatile(""::"x"(reinterpret_cast<const __m128 &>(tmp0)));
    if (sizeof(T) == 32) {
        asm volatile(""::"x"(reinterpret_cast<const __m128 *>(&tmp0)[1]));
    }
#else
    asm volatile(""::"r"(tmp0));
#endif
}
template<typename Vector> class DoCompares
{
    enum {
        Factor2 = 128
    };
    public:
        static void run(const int Repetitions)
        {
            const int Factor = CpuId::L1Data() / (sizeof(Vector) * 2); // half L1
            Vector *a = new Vector[Factor + 3];
            for (int i = 0; i < Factor + 3; ++i) {
                a[i] = PseudoRandom<Vector>::next();
            }

#ifdef VC_IMPL_Scalar
            typedef bool M;
#else
            typedef typename Vector::Mask M;
#endif

            {
                Benchmark timer("operator==", Vector::Size * Factor * Factor2 * 6.0, "Op");
                for (int repetitions = 0; repetitions < Repetitions; ++repetitions) {
                    timer.Start();
                    for (int j = 0; j < Factor2; ++j) {
                        for (int i = 0; i < Factor; ++i) {
                            const M &tmp0 = a[i + 0] == a[i + 1]; keepResults(tmp0);
                            const M &tmp1 = a[i + 0] == a[i + 2]; keepResults(tmp1);
                            const M &tmp2 = a[i + 0] == a[i + 3]; keepResults(tmp2);
                            const M &tmp3 = a[i + 1] == a[i + 2]; keepResults(tmp3);
                            const M &tmp4 = a[i + 1] == a[i + 3]; keepResults(tmp4);
                            const M &tmp5 = a[i + 2] == a[i + 3]; keepResults(tmp5);
                        }
                    }
                    timer.Stop();
                }
                timer.Print(Benchmark::PrintAverage);
            }
            {
                Benchmark timer("operator<", Vector::Size * Factor * Factor2 * 6.0, "Op");
                for (int repetitions = 0; repetitions < Repetitions; ++repetitions) {
                    timer.Start();
                    for (int j = 0; j < Factor2; ++j) {
                        for (int i = 0; i < Factor; ++i) {
                            const M &tmp0 = a[i + 0] < a[i + 1]; keepResults(tmp0);
                            const M &tmp1 = a[i + 0] < a[i + 2]; keepResults(tmp1);
                            const M &tmp2 = a[i + 0] < a[i + 3]; keepResults(tmp2);
                            const M &tmp3 = a[i + 1] < a[i + 2]; keepResults(tmp3);
                            const M &tmp4 = a[i + 1] < a[i + 3]; keepResults(tmp4);
                            const M &tmp5 = a[i + 2] < a[i + 3]; keepResults(tmp5);
                        }
                    }
                    timer.Stop();
                }
                timer.Print(Benchmark::PrintAverage);
            }
            {
                Benchmark timer("(operator<).isFull()", Vector::Size * Factor * Factor2 * 6.0, "Op");
                for (int repetitions = 0; repetitions < Repetitions; ++repetitions) {
                    timer.Start();
                    Vector a0 = a[0];
                    Vector a1 = a[1];
                    Vector a2 = a[2];
                    Vector a3 = a[3];
                    for (int j = 0; j < Factor2; ++j) {
                        for (int i = 0; i < Factor; ++i) {
                            if ((a[i + 0] < a[i + 1]).isFull()) asm volatile("");
                            if ((a[i + 0] < a[i + 2]).isFull()) asm volatile("");
                            if ((a[i + 0] < a[i + 3]).isFull()) asm volatile("");
                            if ((a[i + 1] < a[i + 2]).isFull()) asm volatile("");
                            if ((a[i + 1] < a[i + 3]).isFull()) asm volatile("");
                            if ((a[i + 2] < a[i + 3]).isFull()) asm volatile("");
                            a1 = a2; a2 = a3; a3 = a[i + 3];
                        }
                    }
                    timer.Stop();
                }
                timer.Print(Benchmark::PrintAverage);
            }
            {
                Benchmark timer("!(operator<).isEmpty()", Vector::Size * Factor * Factor2 * 6.0, "Op");
                for (int repetitions = 0; repetitions < Repetitions; ++repetitions) {
                    timer.Start();
                    Vector a0 = a[0];
                    Vector a1 = a[1];
                    Vector a2 = a[2];
                    Vector a3 = a[3];
                    for (int j = 0; j < Factor2; ++j) {
                        for (int i = 0; i < Factor; ++i) {
                            if (!(a[i + 0] < a[i + 1]).isEmpty()) asm volatile("");
                            if (!(a[i + 0] < a[i + 2]).isEmpty()) asm volatile("");
                            if (!(a[i + 0] < a[i + 3]).isEmpty()) asm volatile("");
                            if (!(a[i + 1] < a[i + 2]).isEmpty()) asm volatile("");
                            if (!(a[i + 1] < a[i + 3]).isEmpty()) asm volatile("");
                            if (!(a[i + 2] < a[i + 3]).isEmpty()) asm volatile("");
                            a1 = a2; a2 = a3; a3 = a[i + 3];
                        }
                    }
                    timer.Stop();
                }
                timer.Print(Benchmark::PrintAverage);
            }
            delete[] a;
        }
};

int bmain(Benchmark::OutputMode out)
{
    const int Repetitions = out == Benchmark::Stdout ? 10 : g_Repetitions > 0 ? g_Repetitions : 200;

    Benchmark::addColumn("datatype");

    Benchmark::setColumnData("datatype", "double_v");
    DoCompares<double_v>::run(Repetitions);
    Benchmark::setColumnData("datatype", "float_v");
    DoCompares<float_v>::run(Repetitions);
    Benchmark::setColumnData("datatype", "int_v");
    DoCompares<int_v>::run(Repetitions);
    Benchmark::setColumnData("datatype", "uint_v");
    DoCompares<uint_v>::run(Repetitions);
    Benchmark::setColumnData("datatype", "short_v");
    DoCompares<short_v>::run(Repetitions);
    Benchmark::setColumnData("datatype", "ushort_v");
    DoCompares<ushort_v>::run(Repetitions);
    Benchmark::setColumnData("datatype", "sfloat_v");
    DoCompares<sfloat_v>::run(Repetitions);

    return 0;
}
<|endoftext|>


<commit_before>//----------------------------  tria_boundary.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  tria_boundary.cc  ---------------------------

#include <base/tensor.h>
#include <grid/tria_boundary.h>
#include <grid/tria.h>
#include <grid/tria_iterator.h>
#include <grid/tria_accessor.h>
#include <cmath>

/* -------------------------- Boundary --------------------- */

template <int dim>
Boundary<dim>::~Boundary ()
{}

template <int dim>
Point<dim>
Boundary<dim>::get_new_point_on_quad (const typename Triangulation<dim>::quad_iterator &) const
{
  Assert (false, ExcPureVirtualFunctionCalled());
  return Point<dim>();
}

template <int dim>
void
Boundary<dim>::
get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterator &,
				 std::vector<Point<dim> > &) const
{
  Assert (false, ExcPureVirtualFunctionCalled());
}

template <int dim>
void
Boundary<dim>::
get_intermediate_points_on_quad (const typename Triangulation<dim>::quad_iterator &,
				 std::vector<Point<dim> > &) const
{
  Assert (false, ExcPureVirtualFunctionCalled());
}

template <int dim>
void
Boundary<dim>::
get_normals_at_vertices (const typename Triangulation<dim>::face_iterator &,
			 FaceVertexNormals                                &) const
{
  Assert (false, ExcPureVirtualFunctionCalled());
}

/* -------------------------- StraightBoundary --------------------- */

template <int dim>
StraightBoundary<dim>::StraightBoundary ()
{}

template <int dim>
Point<dim>
StraightBoundary<dim>::get_new_point_on_line (const typename Triangulation<dim>::line_iterator &line) const
{
  return (line->vertex(0) + line->vertex(1)) / 2;
}

#if deal_II_dimension < 3

template <int dim>
Point<dim>
StraightBoundary<dim>::get_new_point_on_quad (const typename Triangulation<dim>::quad_iterator &) const
{
  Assert (false, typename Boundary<dim>::ExcFunctionNotUseful(dim));
  return Point<dim>();
}

#else

template <>
Point<3>
StraightBoundary<3>::
get_new_point_on_quad (const Triangulation<3>::quad_iterator &quad) const
{
  return (quad->vertex(0) + quad->vertex(1) +
	  quad->vertex(2) + quad->vertex(3) +
	  quad->line(0)->child(0)->vertex(1) +
	  quad->line(1)->child(0)->vertex(1) +
  	  quad->line(2)->child(0)->vertex(1) +
  	  quad->line(3)->child(0)->vertex(1)) / 8;
}

#endif

#if deal_II_dimension == 1

template <>
void
StraightBoundary<1>::
get_intermediate_points_on_line (const Triangulation<1>::line_iterator &,
				 std::vector<Point<1> > &) const
{
  Assert(false, Boundary<1>::ExcFunctionNotUseful(1));
}

#else

template <int dim>
void
StraightBoundary<dim>::
get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterator &line,
				 std::vector<Point<dim> > &points) const
{
  const unsigned int n=points.size();
  Assert(n>0, ExcInternalError());

  const double dx=1./(n+1);
  double x=dx;

  const Point<dim> vertices[2] = { line->vertex(0),
				   line->vertex(1) };

  for (unsigned int i=0; i<n; ++i, x+=dx)
    points[i] = (1-x)*vertices[0] + x*vertices[1];
}

#endif

#if deal_II_dimension < 3

template <int dim>
void
StraightBoundary<dim>::
get_intermediate_points_on_quad (const typename Triangulation<dim>::quad_iterator &,
				 std::vector<Point<dim> > &) const
{
  Assert(false, typename Boundary<dim>::ExcFunctionNotUseful(dim));
}

#else

template <>
void
StraightBoundary<3>::
get_intermediate_points_on_quad (const Triangulation<3>::quad_iterator &quad,
				 std::vector<Point<3> > &points) const
{
  const unsigned int dim = 3;

  const unsigned int n=points.size(),
		     m=static_cast<unsigned int>(std::sqrt(static_cast<double>(n)));
				   // is n a square number
  Assert(m*m==n, ExcInternalError());

  const double ds=1./(m+1);
  double y=ds;

  const Point<dim> vertices[4] = { quad->vertex(0),
				   quad->vertex(1),
				   quad->vertex(2),
				   quad->vertex(3) };

  for (unsigned int i=0; i<m; ++i, y+=ds)
    {
      double x=ds;
      for (unsigned int j=0; j<m; ++j, x+=ds)
	points[i*m+j]=((1-x) * vertices[0] +
		       x     * vertices[1]) * (1-y) +
		      ((1-x) * vertices[3] +
		       x     * vertices[2]) * y;
    }
}

#endif

#if deal_II_dimension == 1

template <>
void
StraightBoundary<1>::
get_normals_at_vertices (const Triangulation<1>::face_iterator &,
			 Boundary<1>::FaceVertexNormals &) const
{
  Assert (false, Boundary<1>::ExcFunctionNotUseful(1));
}

#endif

#if deal_II_dimension == 2

template <>
void
StraightBoundary<2>::
get_normals_at_vertices (const Triangulation<2>::face_iterator &face,
			 Boundary<2>::FaceVertexNormals &face_vertex_normals) const
{
  const Tensor<1,2> tangent = face->vertex(1) - face->vertex(0);
  for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_face; ++vertex)
				     // compute normals from tangent
    face_vertex_normals[vertex] = Point<2>(tangent[1],
                                           -tangent[0]);
}

#endif

#if deal_II_dimension == 3

template <>
void
StraightBoundary<3>::
get_normals_at_vertices (const Triangulation<3>::face_iterator &face,
			 Boundary<3>::FaceVertexNormals &face_vertex_normals) const
{
  const unsigned int vertices_per_face = GeometryInfo<3>::vertices_per_face;

  for (unsigned int vertex=0; vertex<vertices_per_face; ++vertex)
    {
				       // first define the two tangent
				       // vectors at the vertex by
				       // using the two lines
				       // radiating away from this
				       // vertex
      const Tensor<1,3> tangents[2]
	= { face->vertex((vertex+1) % vertices_per_face)
	      - face->vertex(vertex),
	    face->vertex((vertex+vertices_per_face-1) % vertices_per_face)
	      - face->vertex(vertex)      };

				       // then compute the normal by
				       // taking the cross
				       // product. since the normal is
				       // not required to be
				       // normalized, no problem here
      cross_product (face_vertex_normals[vertex],
		     tangents[0], tangents[1]);
    };
}

#endif

// explicit instantiations
template class Boundary<deal_II_dimension>;
template class StraightBoundary<deal_II_dimension>;
<commit_msg>Bug fix: the StraightBoundary<3>::get_new_point_on_quad requested for children of lines of the quad which in general do not exist. Get around this by using the centers of the lines.<commit_after>//----------------------------  tria_boundary.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  tria_boundary.cc  ---------------------------

#include <base/tensor.h>
#include <grid/tria_boundary.h>
#include <grid/tria.h>
#include <grid/tria_iterator.h>
#include <grid/tria_accessor.h>
#include <cmath>

/* -------------------------- Boundary --------------------- */

template <int dim>
Boundary<dim>::~Boundary ()
{}

template <int dim>
Point<dim>
Boundary<dim>::get_new_point_on_quad (const typename Triangulation<dim>::quad_iterator &) const
{
  Assert (false, ExcPureVirtualFunctionCalled());
  return Point<dim>();
}

template <int dim>
void
Boundary<dim>::
get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterator &,
				 std::vector<Point<dim> > &) const
{
  Assert (false, ExcPureVirtualFunctionCalled());
}

template <int dim>
void
Boundary<dim>::
get_intermediate_points_on_quad (const typename Triangulation<dim>::quad_iterator &,
				 std::vector<Point<dim> > &) const
{
  Assert (false, ExcPureVirtualFunctionCalled());
}

template <int dim>
void
Boundary<dim>::
get_normals_at_vertices (const typename Triangulation<dim>::face_iterator &,
			 FaceVertexNormals                                &) const
{
  Assert (false, ExcPureVirtualFunctionCalled());
}

/* -------------------------- StraightBoundary --------------------- */

template <int dim>
StraightBoundary<dim>::StraightBoundary ()
{}

template <int dim>
Point<dim>
StraightBoundary<dim>::get_new_point_on_line (const typename Triangulation<dim>::line_iterator &line) const
{
  return (line->vertex(0) + line->vertex(1)) / 2;
}

#if deal_II_dimension < 3

template <int dim>
Point<dim>
StraightBoundary<dim>::get_new_point_on_quad (const typename Triangulation<dim>::quad_iterator &) const
{
  Assert (false, typename Boundary<dim>::ExcFunctionNotUseful(dim));
  return Point<dim>();
}

#else

template <>
Point<3>
StraightBoundary<3>::
get_new_point_on_quad (const Triangulation<3>::quad_iterator &quad) const
{
  return (quad->vertex(0) + quad->vertex(1) +
	  quad->vertex(2) + quad->vertex(3) +
	  quad->line(0)->center() +
	  quad->line(1)->center() +
  	  quad->line(2)->center() +
  	  quad->line(3)->center()) / 8;
}

#endif

#if deal_II_dimension == 1

template <>
void
StraightBoundary<1>::
get_intermediate_points_on_line (const Triangulation<1>::line_iterator &,
				 std::vector<Point<1> > &) const
{
  Assert(false, Boundary<1>::ExcFunctionNotUseful(1));
}

#else

template <int dim>
void
StraightBoundary<dim>::
get_intermediate_points_on_line (const typename Triangulation<dim>::line_iterator &line,
				 std::vector<Point<dim> > &points) const
{
  const unsigned int n=points.size();
  Assert(n>0, ExcInternalError());

  const double dx=1./(n+1);
  double x=dx;

  const Point<dim> vertices[2] = { line->vertex(0),
				   line->vertex(1) };

  for (unsigned int i=0; i<n; ++i, x+=dx)
    points[i] = (1-x)*vertices[0] + x*vertices[1];
}

#endif

#if deal_II_dimension < 3

template <int dim>
void
StraightBoundary<dim>::
get_intermediate_points_on_quad (const typename Triangulation<dim>::quad_iterator &,
				 std::vector<Point<dim> > &) const
{
  Assert(false, typename Boundary<dim>::ExcFunctionNotUseful(dim));
}

#else

template <>
void
StraightBoundary<3>::
get_intermediate_points_on_quad (const Triangulation<3>::quad_iterator &quad,
				 std::vector<Point<3> > &points) const
{
  const unsigned int dim = 3;

  const unsigned int n=points.size(),
		     m=static_cast<unsigned int>(std::sqrt(static_cast<double>(n)));
				   // is n a square number
  Assert(m*m==n, ExcInternalError());

  const double ds=1./(m+1);
  double y=ds;

  const Point<dim> vertices[4] = { quad->vertex(0),
				   quad->vertex(1),
				   quad->vertex(2),
				   quad->vertex(3) };

  for (unsigned int i=0; i<m; ++i, y+=ds)
    {
      double x=ds;
      for (unsigned int j=0; j<m; ++j, x+=ds)
	points[i*m+j]=((1-x) * vertices[0] +
		       x     * vertices[1]) * (1-y) +
		      ((1-x) * vertices[3] +
		       x     * vertices[2]) * y;
    }
}

#endif

#if deal_II_dimension == 1

template <>
void
StraightBoundary<1>::
get_normals_at_vertices (const Triangulation<1>::face_iterator &,
			 Boundary<1>::FaceVertexNormals &) const
{
  Assert (false, Boundary<1>::ExcFunctionNotUseful(1));
}

#endif

#if deal_II_dimension == 2

template <>
void
StraightBoundary<2>::
get_normals_at_vertices (const Triangulation<2>::face_iterator &face,
			 Boundary<2>::FaceVertexNormals &face_vertex_normals) const
{
  const Tensor<1,2> tangent = face->vertex(1) - face->vertex(0);
  for (unsigned int vertex=0; vertex<GeometryInfo<2>::vertices_per_face; ++vertex)
				     // compute normals from tangent
    face_vertex_normals[vertex] = Point<2>(tangent[1],
                                           -tangent[0]);
}

#endif

#if deal_II_dimension == 3

template <>
void
StraightBoundary<3>::
get_normals_at_vertices (const Triangulation<3>::face_iterator &face,
			 Boundary<3>::FaceVertexNormals &face_vertex_normals) const
{
  const unsigned int vertices_per_face = GeometryInfo<3>::vertices_per_face;

  for (unsigned int vertex=0; vertex<vertices_per_face; ++vertex)
    {
				       // first define the two tangent
				       // vectors at the vertex by
				       // using the two lines
				       // radiating away from this
				       // vertex
      const Tensor<1,3> tangents[2]
	= { face->vertex((vertex+1) % vertices_per_face)
	      - face->vertex(vertex),
	    face->vertex((vertex+vertices_per_face-1) % vertices_per_face)
	      - face->vertex(vertex)      };

				       // then compute the normal by
				       // taking the cross
				       // product. since the normal is
				       // not required to be
				       // normalized, no problem here
      cross_product (face_vertex_normals[vertex],
		     tangents[0], tangents[1]);
    };
}

#endif

// explicit instantiations
template class Boundary<deal_II_dimension>;
template class StraightBoundary<deal_II_dimension>;
<|endoftext|>


<commit_before>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2011,2012 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License version 2.1 as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#ifndef JUBATUS_SERVER_FRAMEWORK_SERVER_HELPER_HPP_
#define JUBATUS_SERVER_FRAMEWORK_SERVER_HELPER_HPP_

#include <sys/types.h>
#include <unistd.h>

#include <map>
#include <string>
#include <glog/logging.h>
#include <pficommon/lang/shared_ptr.h>
#include <pficommon/system/sysstat.h>

#include "jubatus/core/common/jsonconfig.hpp"
#include "mixer/mixer.hpp"
#include "server_util.hpp"
#include "../../config.hpp"
#include "../common/lock_service.hpp"
#include "../common/mprpc/rpc_server.hpp"
#include "../common/config.hpp"

namespace jubatus {
namespace server {
namespace framework {

class server_helper_impl {
 public:
  explicit server_helper_impl(const server_argv& a);
  void prepare_for_start(const server_argv& a, bool use_cht);
  void prepare_for_run(const server_argv& a, bool use_cht);
  void get_config_lock(const server_argv& a, int retry);

  pfi::lang::shared_ptr<common::lock_service> zk() const {
    return zk_;
  }

 private:
  pfi::lang::shared_ptr<common::lock_service> zk_;
  pfi::lang::shared_ptr<common::try_lockable> zk_config_lock_;
};

template<typename Server>
class server_helper {
 public:
  typedef typename Server::status_t status_t;

  explicit server_helper(const server_argv& a, bool use_cht = false)
      : impl_(a),
        use_cht_(use_cht) {
    impl_.prepare_for_start(a, use_cht);
    server_.reset(new Server(a, impl_.zk()));

    impl_.get_config_lock(a, 3);

    try {
      server_->set_config(get_conf(a));
    } catch (const core::common::jsonconfig::cast_check_error& e) {
      core::common::config_exception config_error;
      const core::common::jsonconfig::config_error_list& errors = e.errors();
      for (core::common::jsonconfig::config_error_list::const_iterator
          it = errors.begin(), end = errors.end(); it != end; ++it) {
        config_error << core::common::exception::error_message((*it)->what());
      }
      // send error message to caller
      throw JUBATUS_EXCEPTION(config_error);
    } catch (const pfi::lang::parse_error& e) {
      // exit immediately on JSON parse error with exit-code 1
      std::string msg =
          std::string("syntax error in configuration: ") +
          (a.is_standalone() ?
           a.configpath :
           std::string("<zookeeper>")) + ":" +
          pfi::lang::lexical_cast<std::string>(e.lineno()) + ":" +
          pfi::lang::lexical_cast<std::string>(e.pos()) + " " +
          e.msg();

      LOG(ERROR) << msg;
      exit(1);
    }
  }

  std::map<std::string, std::string> get_loads() const {
    std::map<std::string, std::string> result;
    {
      pfi::system::sysstat::sysstat_ret sys;
      get_sysstat(sys);
      result["loadavg"] = pfi::lang::lexical_cast<std::string>(sys.loadavg);
      result["total_memory"] = pfi::lang::lexical_cast<std::string>(
          sys.total_memory);
      result["free_memory"] = pfi::lang::lexical_cast<std::string>(
          sys.free_memory);
    }
    return result;
  }

  std::map<std::string, status_t> get_status() const {
    std::map<std::string, status_t> status;
    const server_argv& a = server_->argv();
    status_t& data = status[get_server_identifier(a)];

    common::util::machine_status_t mt;
    common::util::get_machine_status(mt);
    data["VIRT"] = pfi::lang::lexical_cast<std::string>(mt.vm_size);
    data["RSS"] = pfi::lang::lexical_cast<std::string>(mt.vm_resident);
    data["SHR"] = pfi::lang::lexical_cast<std::string>(mt.vm_share);

    // TBD: running_time, epoch_time
    // TBD: type(server type), name(instance name: when zookeeper enabled), eth
    data["timeout"] = pfi::lang::lexical_cast<std::string>(a.timeout);
    data["threadnum"] = pfi::lang::lexical_cast<std::string>(a.threadnum);
    data["datadir"] = a.datadir;
    data["interval_sec"] = pfi::lang::lexical_cast<std::string>(a.interval_sec);
    data["interval_count"] = pfi::lang::lexical_cast<std::string>(
        a.interval_count);
    data["is_standalone"] = pfi::lang::lexical_cast<std::string>(
        a.is_standalone());
    data["VERSION"] = JUBATUS_VERSION;
    data["PROGNAME"] = a.program_name;

    data["update_count"] = pfi::lang::lexical_cast<std::string>(
        server_->update_count());

    server_->get_status(data);

    server_->get_mixer()->get_status(data);
    data["zk"] = a.z;
    data["use_cht"] = pfi::lang::lexical_cast<std::string>(use_cht_);

    return status;
  }

  int start(common::mprpc::rpc_server& serv) {
    const server_argv& a = server_->argv();

    if (!a.is_standalone()) {
      server_->get_mixer()->start();
    }

    try {
      serv.listen(a.port, a.bind_address);
      LOG(INFO) << "start listening at port " << a.port;
      serv.start(a.threadnum, true);
      // RPC server started, then register group membership
      impl_.prepare_for_run(a, use_cht_);
      LOG(INFO) << common::util::get_program_name() << " RPC server startup";
      serv.join();
      return 0;
    } catch (const mp::system_error& e) {
      if (e.code == EADDRINUSE) {
        LOG(FATAL) << "server failed to start: any process using port "
            << a.port << "?";
      } else {
        LOG(FATAL) << "server failed to start: " << e.what();
      }
    } catch (jubatus::core::common::exception::jubatus_exception&) {
      throw;
    } catch (const std::exception& e) {
      LOG(FATAL) << "server failed to start: " << e.what();
    }
    return -1;
  }

    pfi::lang::shared_ptr<Server> server() const {
    return server_;
  }

  pfi::concurrent::rw_mutex& rw_mutex() {
    return server_->rw_mutex();
  }

 private:
  pfi::lang::shared_ptr<Server> server_;
  server_helper_impl impl_;
  const bool use_cht_;
};

}  // namespace framework
}  // namespace server
}  // namespace jubatus

#define JRLOCK_(p) \
  ::pfi::concurrent::scoped_rlock lk((p)->rw_mutex())

#define JWLOCK_(p) \
  ::pfi::concurrent::scoped_wlock lk((p)->rw_mutex()); \
  (p)->server()->event_model_updated()

#define NOLOCK_(p)

#endif  // JUBATUS_SERVER_FRAMEWORK_SERVER_HELPER_HPP_
<commit_msg>Stop mixer when terminated<commit_after>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2011,2012 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License version 2.1 as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#ifndef JUBATUS_SERVER_FRAMEWORK_SERVER_HELPER_HPP_
#define JUBATUS_SERVER_FRAMEWORK_SERVER_HELPER_HPP_

#include <sys/types.h>
#include <unistd.h>

#include <map>
#include <string>
#include <glog/logging.h>
#include <pficommon/lang/shared_ptr.h>
#include <pficommon/system/sysstat.h>

#include "jubatus/core/common/jsonconfig.hpp"
#include "mixer/mixer.hpp"
#include "server_util.hpp"
#include "../../config.hpp"
#include "../common/lock_service.hpp"
#include "../common/mprpc/rpc_server.hpp"
#include "../common/config.hpp"

namespace jubatus {
namespace server {
namespace framework {

class server_helper_impl {
 public:
  explicit server_helper_impl(const server_argv& a);
  void prepare_for_start(const server_argv& a, bool use_cht);
  void prepare_for_run(const server_argv& a, bool use_cht);
  void get_config_lock(const server_argv& a, int retry);

  pfi::lang::shared_ptr<common::lock_service> zk() const {
    return zk_;
  }

 private:
  pfi::lang::shared_ptr<common::lock_service> zk_;
  pfi::lang::shared_ptr<common::try_lockable> zk_config_lock_;
};

template<typename Server>
class server_helper {
 public:
  typedef typename Server::status_t status_t;

  explicit server_helper(const server_argv& a, bool use_cht = false)
      : impl_(a),
        use_cht_(use_cht) {
    impl_.prepare_for_start(a, use_cht);
    server_.reset(new Server(a, impl_.zk()));

    impl_.get_config_lock(a, 3);

    try {
      server_->set_config(get_conf(a));
    } catch (const core::common::jsonconfig::cast_check_error& e) {
      core::common::config_exception config_error;
      const core::common::jsonconfig::config_error_list& errors = e.errors();
      for (core::common::jsonconfig::config_error_list::const_iterator
          it = errors.begin(), end = errors.end(); it != end; ++it) {
        config_error << core::common::exception::error_message((*it)->what());
      }
      // send error message to caller
      throw JUBATUS_EXCEPTION(config_error);
    } catch (const pfi::lang::parse_error& e) {
      // exit immediately on JSON parse error with exit-code 1
      std::string msg =
          std::string("syntax error in configuration: ") +
          (a.is_standalone() ?
           a.configpath :
           std::string("<zookeeper>")) + ":" +
          pfi::lang::lexical_cast<std::string>(e.lineno()) + ":" +
          pfi::lang::lexical_cast<std::string>(e.pos()) + " " +
          e.msg();

      LOG(ERROR) << msg;
      exit(1);
    }
  }

  std::map<std::string, std::string> get_loads() const {
    std::map<std::string, std::string> result;
    {
      pfi::system::sysstat::sysstat_ret sys;
      get_sysstat(sys);
      result["loadavg"] = pfi::lang::lexical_cast<std::string>(sys.loadavg);
      result["total_memory"] = pfi::lang::lexical_cast<std::string>(
          sys.total_memory);
      result["free_memory"] = pfi::lang::lexical_cast<std::string>(
          sys.free_memory);
    }
    return result;
  }

  std::map<std::string, status_t> get_status() const {
    std::map<std::string, status_t> status;
    const server_argv& a = server_->argv();
    status_t& data = status[get_server_identifier(a)];

    common::util::machine_status_t mt;
    common::util::get_machine_status(mt);
    data["VIRT"] = pfi::lang::lexical_cast<std::string>(mt.vm_size);
    data["RSS"] = pfi::lang::lexical_cast<std::string>(mt.vm_resident);
    data["SHR"] = pfi::lang::lexical_cast<std::string>(mt.vm_share);

    // TBD: running_time, epoch_time
    // TBD: type(server type), name(instance name: when zookeeper enabled), eth
    data["timeout"] = pfi::lang::lexical_cast<std::string>(a.timeout);
    data["threadnum"] = pfi::lang::lexical_cast<std::string>(a.threadnum);
    data["datadir"] = a.datadir;
    data["interval_sec"] = pfi::lang::lexical_cast<std::string>(a.interval_sec);
    data["interval_count"] = pfi::lang::lexical_cast<std::string>(
        a.interval_count);
    data["is_standalone"] = pfi::lang::lexical_cast<std::string>(
        a.is_standalone());
    data["VERSION"] = JUBATUS_VERSION;
    data["PROGNAME"] = a.program_name;

    data["update_count"] = pfi::lang::lexical_cast<std::string>(
        server_->update_count());

    server_->get_status(data);

    server_->get_mixer()->get_status(data);
    data["zk"] = a.z;
    data["use_cht"] = pfi::lang::lexical_cast<std::string>(use_cht_);

    return status;
  }

  int start(common::mprpc::rpc_server& serv) {
    const server_argv& a = server_->argv();

    if (!a.is_standalone()) {
      server_->get_mixer()->start();
    }

    try {
      serv.listen(a.port, a.bind_address);
      LOG(INFO) << "start listening at port " << a.port;
      serv.start(a.threadnum, true);
      // RPC server started, then register group membership
      impl_.prepare_for_run(a, use_cht_);
      LOG(INFO) << common::util::get_program_name() << " RPC server startup";
      serv.join();
      if (!a.is_standalone()) {
        server_->get_mixer()->stop();
      }
      return 0;
    } catch (const mp::system_error& e) {
      if (e.code == EADDRINUSE) {
        LOG(FATAL) << "server failed to start: any process using port "
            << a.port << "?";
      } else {
        LOG(FATAL) << "server failed to start: " << e.what();
      }
    } catch (jubatus::core::common::exception::jubatus_exception&) {
      throw;
    } catch (const std::exception& e) {
      LOG(FATAL) << "server failed to start: " << e.what();
    }
    return -1;
  }

    pfi::lang::shared_ptr<Server> server() const {
    return server_;
  }

  pfi::concurrent::rw_mutex& rw_mutex() {
    return server_->rw_mutex();
  }

 private:
  pfi::lang::shared_ptr<Server> server_;
  server_helper_impl impl_;
  const bool use_cht_;
};

}  // namespace framework
}  // namespace server
}  // namespace jubatus

#define JRLOCK_(p) \
  ::pfi::concurrent::scoped_rlock lk((p)->rw_mutex())

#define JWLOCK_(p) \
  ::pfi::concurrent::scoped_wlock lk((p)->rw_mutex()); \
  (p)->server()->event_model_updated()

#define NOLOCK_(p)

#endif  // JUBATUS_SERVER_FRAMEWORK_SERVER_HELPER_HPP_
<|endoftext|>