<commit_before>/*

TOF DA for online calibration from pulser data

Contact: Chiara.Zampolli@bo.infn.it
Link: www.bo.infn.it/~zampolli
Run Type: NOISE
DA Type: LDC
Number of events needed: 10000
Input Files: TOF<nrun>.raw, where <nrun> is the run number
Output Files: TOFoutPulserLDC_<LDCid>.root, where <LDCid> is the id of the LDC which is read (2 characters field, e.g. TOFoutPulserLDC_03.root),to be exported to the DAQ FXS
Trigger types used: PHYSICS_EVENT (for the time being)

*/

// DATE
#include "event.h"
#include "monitor.h"
#include "daqDA.h"

#include <stdio.h>
#include <stdlib.h>

//AliRoot
#include <AliTOFRawStream.h>
#include <AliRawReaderDate.h>
#include <AliRawReader.h>
#include <AliTOFGeometry.h>
#include <AliDAQ.h>
#include <AliTOFHitData.h>
#include <AliTOFHitDataBuffer.h>
#include <AliTOFDecoder.h>
#include <AliTOFNoiseConfigHandler.h>

//ROOT
#include <TFile.h>
#include <TKey.h>
#include <TH1I.h>
#include <TObject.h>
#include <TMath.h>
#include <TSystem.h>
#include "TROOT.h"
#include "TPluginManager.h"
#include "TSAXParser.h"

/* Main routine
      Arguments: list of DATE raw data files
*/
int main(int argc, char **argv) {

/* magic line from Rene */
  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
                    "*",
                    "TStreamerInfo",
                    "RIO",
                    "TStreamerInfo()");

  AliTOFGeometry * geom = new AliTOFGeometry();

  static const Int_t size = AliTOFGeometry::NPadXSector()*AliTOFGeometry::NSectors();
  TH1F::AddDirectory(0);
  TH1F * htofNoise = new TH1F("hTOFnoise","histo with signals on TOF during noise", size,-0.5,size-0.5);
  for (Int_t ibin =1;ibin<=size;ibin++){
    htofNoise->SetBinContent(ibin,-1);
  }
  UInt_t ldcId=0;

  int status;

  /* log start of process */
  printf("TOF DA started\n");

  /* check that we got some arguments = list of files */
  if (argc<2) {
    printf("Wrong number of arguments\n");
    return -1;
  }

  /* open result file */
  FILE *fp=NULL;
  fp=fopen("./result.txt","a");
  if (fp==NULL) {
    printf("Failed to open file\n");
    return -1;
  }

  /* retrieve config file */
  int getConfigFile = daqDA_DB_getFile("TOFNoiseConfig.xml","TOFNoiseConfig.xml");
  if (getConfigFile != 0){
    printf("Failed to retrieve config file from DB! returning...\n");
    return -1;
  }

  AliTOFNoiseConfigHandler* tofHandler = new AliTOFNoiseConfigHandler();
  TSAXParser *parser = new TSAXParser();
  parser->ConnectToHandler("AliTOFNoiseConfigHandler", tofHandler);
  if (parser->ParseFile("./TOFNoiseConfig.xml") != 0){
	  printf("Failed parsing config file! retunring... \n");
	  return -1;
  }

  Int_t debugFlag = tofHandler->GetDebugFlag();

  printf("the debug flag is %i\n",debugFlag);

  /* init some counters */
  int nevents_physics=0;
  int nevents_total=0;

  /* read the data files */
  int n;
  for (n=1;n<argc;n++) {

    status=monitorSetDataSource( argv[n] );
    if (status!=0) {
      printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
      return -1;
    }

    /* read the file */
    for(;;) {
      struct eventHeaderStruct *event;
      eventTypeType eventT;

      /* get next event */
      status=monitorGetEventDynamic((void **)&event);
      if (status==MON_ERR_EOF) break; /* end of monitoring file has been reached */
      if (status!=0) {
        printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
        return -1;
      }

      /* retry if got no event */
      if (event==NULL) {
        break;
      }

      /* use event - here, just write event id to result file */
      eventT=event->eventType;

      if (eventT==PHYSICS_EVENT) {
	//printf ("event %i \n", nevents_physics);
	Int_t nPDBEntriesToT = 0;
	Int_t nDBEntriesToT = 0;
	AliTOFHitData *HitData;
	Int_t dummy = -1;
	Int_t Volume[5];
	AliRawReader *rawReader = new AliRawReaderDate((void*)event);
	AliTOFRawStream *rawStreamTOF = new AliTOFRawStream(rawReader);
        const AliRawDataHeader *currentCDH;
	AliTOFDecoder * decoderTOF = new AliTOFDecoder();
	AliTOFHitDataBuffer *DataBuffer[72];
	AliTOFHitDataBuffer *PackedDataBuffer[72];
	for (Int_t i=0;i<AliDAQ::NumberOfDdls("TOF");i++){
	  DataBuffer[i]=new AliTOFHitDataBuffer();
	  PackedDataBuffer[i]=new AliTOFHitDataBuffer();
	}
	Int_t currentEquipment;
	Int_t currentDDL;
	UChar_t *data = 0x0;
	while(rawReader->ReadHeader()){
	  //printf ("ldcId = %i \n",ldcId);
	  ldcId = rawReader->GetLDCId();

	  //memory leak prevention (actually data should be always 0x0 here)
	  if (data != 0x0) delete [] data;

	  //get equipment infos
	  currentEquipment = rawReader->GetEquipmentId();
	  currentDDL = rawReader->GetDDLID();
	  currentCDH = rawReader->GetDataHeader();
	  Int_t nchDDL = 0;
	  if (currentDDL%2==0) {
	    nchDDL = 2160;
	  }
	  else {
	    nchDDL = 2208;
	  }
	  Int_t * array = new Int_t[nchDDL];
	  decoderTOF->GetArrayDDL(array, currentDDL);

	  for (Int_t i=0;i<nchDDL;i++){
	    if (htofNoise->GetBinContent(array[i]+1)<0) htofNoise->SetBinContent(array[i]+1,0);
	  }

	  //printf(" Equipment = %i, and DDL = %i \n", currentEquipment,currentDDL);
	  const Int_t kDataSize = rawReader->GetDataSize();
	  const Int_t kDataWords = kDataSize / 4;
	  data = new UChar_t[kDataSize];
	  decoderTOF->SetDataBuffer(DataBuffer[currentDDL]);
	  decoderTOF->SetPackedDataBuffer(PackedDataBuffer[currentDDL]);
	  //start decoding
	  if (!rawReader->ReadNext(data, kDataSize)){
	    rawReader->AddMajorErrorLog(AliTOFRawStream::kDDLdataReading);
	    printf("Error while reading DDL data. Go to next equipment \n");
	    delete [] data;
	    data = 0x0;
	    continue;
	  }
	  if (decoderTOF->Decode((UInt_t *)data, kDataWords, currentCDH) == kTRUE ){
	    rawReader->AddMajorErrorLog(AliTOFRawStream::kDDLDecoder,Form("DDL # = %d",currentDDL));
	    printf("Error while decoding DDL # %d: decoder returned with errors \n", currentDDL);
	  }

	  Int_t nDBEntries = DataBuffer[currentDDL]->GetEntries();
	  Int_t nPDBEntries = PackedDataBuffer[currentDDL]->GetEntries();
	  nPDBEntriesToT+=nPDBEntries;
	  nDBEntriesToT+=nDBEntries;
	  /* reset buffer */
	  DataBuffer[currentDDL]->Reset();

	  /* read data buffer hits */
	  for (Int_t iHit = 0; iHit < nPDBEntries; iHit++){
	    HitData = PackedDataBuffer[currentDDL]->GetHit(iHit);
	    /* add volume information */
	    HitData->SetDDLID(currentDDL);
	    rawStreamTOF->EquipmentId2VolumeId(HitData, Volume);
	    if (Volume[0]==-1 ||
		Volume[1]==-1 ||
		Volume[2]==-1 ||
		Volume[3]==-1 ||
		Volume[4]==-1) continue;
	    else {
	      dummy = Volume[3];
	      Volume[3] = Volume[4];
	      Volume[4] = dummy;
	      Int_t index = geom->GetIndex(Volume);
	      // to check array indexes
	      /*
	      Bool_t found =kFALSE;
	      for (Int_t j=0;j<nchDDL;j++){
		if (index==array[j]) {
		  found = kTRUE;
		  break;
		}
	      }
	      printf ("index = %i, found = %i\n",index, (Int_t)found);
	      */
	      //printf ("index = %i \n",index);
	      htofNoise->Fill(index); //channel index start from 0, bin index from 1
	      //debugging printings
	      if (debugFlag) printf("sector %i, plate %i, strip %i, padz %i, padx %i \n",Volume[0],Volume[1],Volume[2],Volume[3],Volume[4]);
	    }
	  }
	  /* reset buffer */
	  PackedDataBuffer[currentDDL]->Reset();
	  delete [] data;
	  data = 0x0;
	  delete [] array;
	}

	//printf(" Packed Hit Buffer Entries = %i \n",nPDBEntriesToT);
	//printf(" Hit Buffer Entries = %i \n",nDBEntriesToT);

	delete decoderTOF;
	decoderTOF=0x0;

	for (Int_t i=0;i<72;i++){
	  delete DataBuffer[i];
	  delete PackedDataBuffer[i];
	}

	delete rawStreamTOF;
	rawStreamTOF = 0x0;

	delete rawReader;
	rawReader = 0x0;
        nevents_physics++;
      }
      nevents_total++;

      /* free resources */
      free(event);
    }

  }
  delete geom;
  geom = 0x0;

  Int_t noisyChannels = 0;
  Int_t checkedChannels = 0;
  Float_t time = nevents_physics; // acquisition time in number of events
  //printf(" Noise run lasted %f s \n",time);
  for (Int_t ibin =1;ibin<=size;ibin++){
    Float_t cont = htofNoise->GetBinContent(ibin);
    if (cont!=-1) {
      checkedChannels++;
      //printf(" content = %f \n", cont);
      htofNoise->SetBinContent(ibin,cont/time);
      //printf(" scaled content = %f \n", cont/time);
      if (cont != 0){
	noisyChannels++;
      }
    }
  }

  if (debugFlag){
	  printf("Number of checked channels = %i\n",checkedChannels);
	  printf("Number of noisy channels = %i\n",noisyChannels);
  }

  //write the Run level file
  char filename[100];
  sprintf(filename,"TOFoutNoiseLDC_%02i.root",ldcId);
  TFile * fileRun = new TFile (filename,"RECREATE");
  htofNoise->Write();
  fileRun->Close();

  /* write report */
  fprintf(fp,"Run #%s, received %d physics events out of %d\n",getenv("DATE_RUN_NUMBER"),nevents_physics,nevents_total);

  /* close result file */
  fclose(fp);

  status =0;

  /* store the result file on FES */
  status=daqDA_FES_storeFile(filename,"NOISE");
  if (status) {
    status = -2;
  }

  return status;
}
<commit_msg>Improvements in memory handling. Obsolete printings removed.<commit_after>/*

TOF DA for online calibration from pulser data

Contact: Chiara.Zampolli@bo.infn.it
Link: www.bo.infn.it/~zampolli
Run Type: NOISE
DA Type: LDC
Number of events needed: 10000
Input Files: TOF<nrun>.raw, where <nrun> is the run number
Output Files: TOFoutPulserLDC_<LDCid>.root, where <LDCid> is the id of the LDC which is read (2 characters field, e.g. TOFoutPulserLDC_03.root),to be exported to the DAQ FXS
Trigger types used: PHYSICS_EVENT (for the time being)

*/

// DATE
#include "event.h"
#include "monitor.h"
#include "daqDA.h"

#include <stdio.h>
#include <stdlib.h>

//AliRoot
#include <AliTOFRawStream.h>
#include <AliRawReaderDate.h>
#include <AliRawReader.h>
#include <AliTOFGeometry.h>
#include <AliDAQ.h>
#include <AliTOFHitData.h>
#include <AliTOFHitDataBuffer.h>
#include <AliTOFDecoder.h>
#include <AliTOFNoiseConfigHandler.h>

//ROOT
#include <TFile.h>
#include <TKey.h>
#include <TH1I.h>
#include <TObject.h>
#include <TMath.h>
#include <TSystem.h>
#include "TROOT.h"
#include "TPluginManager.h"
#include "TSAXParser.h"

/* Main routine
      Arguments: list of DATE raw data files
*/
int main(int argc, char **argv) {

/* magic line from Rene */
  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
                    "*",
                    "TStreamerInfo",
                    "RIO",
                    "TStreamerInfo()");

  AliTOFGeometry * geom = new AliTOFGeometry();

  static const Int_t size = AliTOFGeometry::NPadXSector()*AliTOFGeometry::NSectors();
  TH1F::AddDirectory(0);
  TH1F * htofNoise = new TH1F("hTOFnoise","histo with signals on TOF during noise", size,-0.5,size-0.5);
  for (Int_t ibin =1;ibin<=size;ibin++){
    htofNoise->SetBinContent(ibin,-1);
  }
  UInt_t ldcId=0;

  int status;

  /* log start of process */
  printf("TOF DA started\n");

  /* check that we got some arguments = list of files */
  if (argc<2) {
    printf("Wrong number of arguments\n");
    return -1;
  }

  /* open result file */
  FILE *fp=NULL;
  fp=fopen("./result.txt","a");
  if (fp==NULL) {
    printf("Failed to open file\n");
    return -1;
  }

  /* retrieve config file */
  int getConfigFile = daqDA_DB_getFile("TOFNoiseConfig.xml","TOFNoiseConfig.xml");
  if (getConfigFile != 0){
    printf("Failed to retrieve config file from DB! returning...\n");
    return -1;
  }

  AliTOFNoiseConfigHandler* tofHandler = new AliTOFNoiseConfigHandler();
  TSAXParser *parser = new TSAXParser();
  parser->ConnectToHandler("AliTOFNoiseConfigHandler", tofHandler);
  if (parser->ParseFile("./TOFNoiseConfig.xml") != 0) {
    printf("Failed parsing config file! retunring... \n");
    return -1;
  }

  Int_t debugFlag = tofHandler->GetDebugFlag();

  printf("the debug flag is %i\n",debugFlag);

  /* init some counters */
  int nevents_physics=0;
  int nevents_total=0;

  Int_t nPDBEntriesToT = 0;
  Int_t nDBEntriesToT = 0;
  AliTOFHitData *HitData;
  Int_t dummy = -1;
  Int_t Volume[5];
  for (Int_t i=0;i<5;i++) Volume[i]=-1;
  AliTOFRawStream *rawStreamTOF = new AliTOFRawStream();
  const AliRawDataHeader *currentCDH;
  AliTOFDecoder * decoderTOF = new AliTOFDecoder();
  AliTOFHitDataBuffer *DataBuffer[AliDAQ::NumberOfDdls("TOF")];
  AliTOFHitDataBuffer *PackedDataBuffer[AliDAQ::NumberOfDdls("TOF")];
  for (Int_t i=0;i<AliDAQ::NumberOfDdls("TOF");i++) {
    DataBuffer[i]=new AliTOFHitDataBuffer();
    PackedDataBuffer[i]=new AliTOFHitDataBuffer();
  }
  Int_t currentEquipment;
  Int_t currentDDL;
  UChar_t *data = 0x0;

  /* read the data files */
  int n;
  for (n=1;n<argc;n++) {

    status=monitorSetDataSource( argv[n] );
    if (status!=0) {
      printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
      return -1;
    }

    /* read the file */
    for(;;) {
      struct eventHeaderStruct *event;
      eventTypeType eventT;

      /* get next event */
      status=monitorGetEventDynamic((void **)&event);
      if (status==MON_ERR_EOF) break; /* end of monitoring file has been reached */
      if (status!=0) {
        printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
        return -1;
      }

      /* retry if got no event */
      if (event==NULL) {
        break;
      }

      /* use event - here, just write event id to result file */
      eventT=event->eventType;

      if (eventT==PHYSICS_EVENT) {
	//printf ("event %i \n", nevents_physics);

	nPDBEntriesToT = 0;
        nDBEntriesToT = 0;
	dummy = -1;
	AliRawReader *rawReader = new AliRawReaderDate((void*)event);
	rawStreamTOF->SetRawReader(rawReader);
	data = 0x0;

	while(rawReader->ReadHeader()){
	  ldcId = rawReader->GetLDCId();
	  //debugging printings
	  //if (debugFlag) printf ("ldcId = %i \n",ldcId);

	  //memory leak prevention (actually data should be always 0x0 here)
	  if (data != 0x0) delete [] data;

	  //get equipment infos
	  currentEquipment = rawReader->GetEquipmentId();
	  currentDDL = rawReader->GetDDLID();
	  currentCDH = rawReader->GetDataHeader();
	  Int_t nchDDL = 0;
	  if (currentDDL%2==0) {
	    nchDDL = 2160;
	  }
	  else {
	    nchDDL = 2208;
	  }

	  Int_t * array = new Int_t[nchDDL];

	  for (Int_t ii=0; ii<nchDDL; ii++) array[ii] = 0;
	  decoderTOF->GetArrayDDL(array, currentDDL);

	  for (Int_t i=0;i<nchDDL;i++) {
	    if (htofNoise->GetBinContent(array[i]+1)<0) htofNoise->SetBinContent(array[i]+1,0);
	  }

	  //debugging printings
	  //	  if (debugFlag) printf(" Equipment = %i, and DDL = %i \n", currentEquipment,currentDDL);
	  const Int_t kDataSize = rawReader->GetDataSize();
	  const Int_t kDataWords = kDataSize / 4;
	  data = new UChar_t[kDataSize];
	  decoderTOF->SetDataBuffer(DataBuffer[currentDDL]);
	  decoderTOF->SetPackedDataBuffer(PackedDataBuffer[currentDDL]);
	  //start decoding
	  if (!rawReader->ReadNext(data, kDataSize)){
	    rawReader->AddMajorErrorLog(AliTOFRawStream::kDDLdataReading);
	    printf("Error while reading DDL data. Go to next equipment \n");
	    delete [] data;
	    data = 0x0;
	    continue;
	  }
	  if (decoderTOF->Decode((UInt_t *)data, kDataWords, currentCDH) == kTRUE ) {
	    rawReader->AddMajorErrorLog(AliTOFRawStream::kDDLDecoder,Form("DDL # = %d",currentDDL));
	    printf("Error while decoding DDL # %d: decoder returned with errors \n", currentDDL);
	  }

	  Int_t nDBEntries = DataBuffer[currentDDL]->GetEntries();
	  Int_t nPDBEntries = PackedDataBuffer[currentDDL]->GetEntries();
	  nPDBEntriesToT+=nPDBEntries;
	  nDBEntriesToT+=nDBEntries;
	  /* reset buffer */
	  DataBuffer[currentDDL]->Reset();

	  /* read data buffer hits */
	  for (Int_t iHit = 0; iHit < nPDBEntries; iHit++){
	    HitData = PackedDataBuffer[currentDDL]->GetHit(iHit);
	    /* add volume information */
	    HitData->SetDDLID(currentDDL);
	    for (Int_t i=0;i<5;i++) Volume[i]=-1;
	    rawStreamTOF->EquipmentId2VolumeId(HitData, Volume);
	    if (Volume[0]==-1 ||
		Volume[1]==-1 ||
		Volume[2]==-1 ||
		Volume[3]==-1 ||
		Volume[4]==-1) continue;
	    else {
	      dummy = Volume[3];
	      Volume[3] = Volume[4];
	      Volume[4] = dummy;
	      Int_t index = geom->GetIndex(Volume);
	      // to check array indexes
	      /*
	      Bool_t found =kFALSE;
	      for (Int_t j=0;j<nchDDL;j++){
		if (index==array[j]) {
		  found = kTRUE;
		  break;
		}
	      }
	      printf ("index = %i, found = %i\n",index, (Int_t)found);
	      */
	      //printf ("index = %i \n",index);
	      htofNoise->Fill(index); //channel index start from 0, bin index from 1
	      //debugging printings
	      // if (debugFlag) printf("sector %i, plate %i, strip %i, padz %i, padx %i \n",Volume[0],Volume[1],Volume[2],Volume[3],Volume[4]); // too verbose
	    }
	  }
	  /* reset buffer */
	  PackedDataBuffer[currentDDL]->Reset();
	  delete [] data;
	  data = 0x0;
	  delete [] array;
	}

	//debugging printings
	//if (debugFlag) {
	//  printf(" Packed Hit Buffer Entries = %i \n",nPDBEntriesToT);
	//  printf(" Hit Buffer Entries = %i \n",nDBEntriesToT);
	//	}

	delete rawReader;
	rawReader = 0x0;
        nevents_physics++;
      }
      nevents_total++;

      /* free resources */
      free(event);
    }

  }

  delete decoderTOF;
  decoderTOF=0x0;

  for (Int_t i=0;i<AliDAQ::NumberOfDdls("TOF");i++){
    delete DataBuffer[i];
    delete PackedDataBuffer[i];
  }

  delete rawStreamTOF;
  rawStreamTOF = 0x0;

  delete geom;
  geom = 0x0;

  Int_t noisyChannels = 0;
  Int_t checkedChannels = 0;
  Float_t time = nevents_physics; // acquisition time in number of events
  //debugging printings
  if (debugFlag) printf(" Noise run lasted %f s \n",time);
  for (Int_t ibin =1;ibin<=size;ibin++){
    Float_t cont = htofNoise->GetBinContent(ibin);
    if (cont!=-1) {
      checkedChannels++;
      //debugging printings
      if (debugFlag) printf(" content = %f \n", cont);
      htofNoise->SetBinContent(ibin,cont/time);
      //debugging printings
      if (debugFlag) printf(" scaled content = %f \n", cont/time);
      if (cont != 0){
	noisyChannels++;
      }
    }
  }

  if (debugFlag) {
    printf("Number of checked channels = %i\n",checkedChannels);
    printf("Number of noisy channels (before applying threshold) = %i\n",noisyChannels);
  }

  //write the Run level file
  char filename[100];
  sprintf(filename,"TOFoutNoiseLDC_%02i.root",ldcId);
  TFile * fileRun = new TFile (filename,"RECREATE");
  htofNoise->Write();
  fileRun->Close();

  /* write report */
  fprintf(fp,"Run #%s, received %d physics events out of %d\n",getenv("DATE_RUN_NUMBER"),nevents_physics,nevents_total);

  /* close result file */
  fclose(fp);

  status =0;

  /* store the result file on FES */
  status=daqDA_FES_storeFile(filename,"NOISE");
  if (status) {
    status = -2;
  }

  return status;
}
<|endoftext|>


<commit_before>/* Copyright (C) 2012, Lukas Orsvrn <lucas.orsv@gmail.com>
   Copyright (C) 2005-2010, Thorvald Natvig <thorvald@natvig.com>

   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   - Redistributions of source code must retain the above copyright notice,
     this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation
     and/or other materials provided with the distribution.
   - Neither the name of the Mumble Developers nor the names of its
     contributors may be used to endorse or promote products derived from this
     software without specific prior written permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#include "../mumble_plugin_win32.h"

static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &context, std::wstring &identity) {
	for (int i=0;i<3;i++)
		avatar_pos[i]=avatar_front[i]=avatar_top[i]=0.0f;

        char state;
	bool ok;
        // Create containers to stuff our raw data into, so we can convert it to Mumble's coordinate system
	float pos_corrector[3];
	float front_corrector[3];
	float top_corrector[3];

	/*
		value is <     >
	*/
	ok = peekProc((BYTE *) 0xB378564, &state, 1); // Magical state value
	if (! ok)
		return false;

	if (state == 1)
             return true; // This results in all vectors beeing zero which tells Mumble to ignore them.

        // Peekproc and assign game addresses to our containers, so we can retrieve positional data
	ok = peekProc((BYTE *) 0x1243BE84, &pos_corrector, 12) &&
	     peekProc((BYTE *) 0x1243BEA8, &front_corrector, 12) &&
	     peekProc((BYTE *) 0x1243BE9C, &top_corrector, 12);

	if (! ok)
		return false;

        // Convert to left-handed coordinate system

	avatar_pos[0] = pos_corrector[0];
	avatar_pos[1] = pos_corrector[1];
	avatar_pos[2] = -pos_corrector[2];

	for (int i=0;i<3;i++)
		avatar_pos[i] / 15; // Scale to meters

	avatar_front[0] = -front_corrector[0];
	avatar_front[1] = -front_corrector[1];
	avatar_front[2] = front_corrector[2];

	avatar_top[0] = top_corrector[0];
	avatar_top[1] = top_corrector[1];
	avatar_top[2] = -top_corrector[2];

	for (int i=0;i<3;i++) {
		camera_pos[i] = avatar_pos[i];
		camera_front[i] = avatar_front[i];
		camera_top[i] = avatar_top[i];
	}

	return true;
}

static int trylock(const std::multimap<std::wstring, unsigned long long int> &pids) {

	if (! initialize(pids, L"subrosa.exe"))
		return false;

	// Check if we can get meaningful data from it
	float apos[3], afront[3], atop[3];
	float cpos[3], cfront[3], ctop[3];
	std::wstring sidentity;
	std::string scontext;

	if (fetch(apos, afront, atop, cpos, cfront, ctop, scontext, sidentity)) {
		return true;
	} else {
		generic_unlock();
		return false;
	}
}

static const std::wstring longdesc() {
	return std::wstring(L"Supports Sub Rosa. No identity or context support yet.");
}

static std::wstring description(L"Sub Rosa v0.07b");
static std::wstring shortname(L"Sub Rosa");

static int trylock1() {
	return trylock(std::multimap<std::wstring, unsigned long long int>());
}

static MumblePlugin subrosaplug = {
	MUMBLE_PLUGIN_MAGIC,
	description,
	shortname,
	NULL,
	NULL,
	trylock1,
	generic_unlock,
	longdesc,
	fetch
};

static MumblePlugin2 subrosaplug2 = {
	MUMBLE_PLUGIN_MAGIC_2,
	MUMBLE_PLUGIN_VERSION,
	trylock
};

extern "C" __declspec(dllexport) MumblePlugin *getMumblePlugin() {
	return &subrosaplug;
}

extern "C" __declspec(dllexport) MumblePlugin2 *getMumblePlugin2() {
	return &subrosaplug2;
}<commit_msg>Fix bug and formating in subrosa PA plugin.<commit_after>/* Copyright (C) 2012, Lukas Orsvrn <lucas.orsv@gmail.com>
   Copyright (C) 2005-2010, Thorvald Natvig <thorvald@natvig.com>

   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   - Redistributions of source code must retain the above copyright notice,
     this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation
     and/or other materials provided with the distribution.
   - Neither the name of the Mumble Developers nor the names of its
     contributors may be used to endorse or promote products derived from this
     software without specific prior written permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#include "../mumble_plugin_win32.h"

static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &/*context*/, std::wstring &/*identity*/) {
	for (int i=0;i<3;i++)
		avatar_pos[i]=avatar_front[i]=avatar_top[i]=0.0f;

	char state;
	bool ok;
	// Create containers to stuff our raw data into, so we can convert it to Mumble's coordinate system
	float pos_corrector[3];
	float front_corrector[3];
	float top_corrector[3];

	/*
		value is <     >
	*/
	ok = peekProc((BYTE *) 0xB378564, &state, 1); // Magical state value
	if (! ok)
		return false;

	if (state == 1)
		return true; // This results in all vectors beeing zero which tells Mumble to ignore them.

	// Peekproc and assign game addresses to our containers, so we can retrieve positional data
	ok = peekProc((BYTE *) 0x1243BE84, &pos_corrector, 12) &&
	        peekProc((BYTE *) 0x1243BEA8, &front_corrector, 12) &&
	        peekProc((BYTE *) 0x1243BE9C, &top_corrector, 12);

	if (! ok)
		return false;

	// Convert to left-handed coordinate system

	avatar_pos[0] = pos_corrector[0];
	avatar_pos[1] = pos_corrector[1];
	avatar_pos[2] = -pos_corrector[2];

	for (int i=0;i<3;i++)
		avatar_pos[i] /= 15; // Scale to meters

	avatar_front[0] = -front_corrector[0];
	avatar_front[1] = -front_corrector[1];
	avatar_front[2] = front_corrector[2];

	avatar_top[0] = top_corrector[0];
	avatar_top[1] = top_corrector[1];
	avatar_top[2] = -top_corrector[2];

	for (int i=0;i<3;i++) {
		camera_pos[i] = avatar_pos[i];
		camera_front[i] = avatar_front[i];
		camera_top[i] = avatar_top[i];
	}

	return true;
}

static int trylock(const std::multimap<std::wstring, unsigned long long int> &pids) {

	if (! initialize(pids, L"subrosa.exe"))
		return false;

	// Check if we can get meaningful data from it
	float apos[3], afront[3], atop[3];
	float cpos[3], cfront[3], ctop[3];
	std::wstring sidentity;
	std::string scontext;

	if (fetch(apos, afront, atop, cpos, cfront, ctop, scontext, sidentity)) {
		return true;
	} else {
		generic_unlock();
		return false;
	}
}

static const std::wstring longdesc() {
	return std::wstring(L"Supports Sub Rosa. No identity or context support yet.");
}

static std::wstring description(L"Sub Rosa v0.07b");
static std::wstring shortname(L"Sub Rosa");

static int trylock1() {
	return trylock(std::multimap<std::wstring, unsigned long long int>());
}

static MumblePlugin subrosaplug = {
	MUMBLE_PLUGIN_MAGIC,
	description,
	shortname,
	NULL,
	NULL,
	trylock1,
	generic_unlock,
	longdesc,
	fetch
};

static MumblePlugin2 subrosaplug2 = {
	MUMBLE_PLUGIN_MAGIC_2,
	MUMBLE_PLUGIN_VERSION,
	trylock
};

extern "C" __declspec(dllexport) MumblePlugin *getMumblePlugin() {
	return &subrosaplug;
}

extern "C" __declspec(dllexport) MumblePlugin2 *getMumblePlugin2() {
	return &subrosaplug2;
}
<|endoftext|>


<commit_before>//
// Created by lz on 1/22/17.
//

#include <c10k/queue.hpp>
#include <catch.hpp>
#include <thread>
#include <vector>
#include <atomic>
#include <cstddef>
#include <chrono>

using namespace std::chrono_literals;

TEST_CASE("Queue in multi producer multi consumer status", "[queue]")
{
    using namespace c10k;
    detail::BoundedBlockingQueue<int> bbq(15);

    std::atomic_int producer_cnt {0}, consumer_cnt {0};
    std::atomic_bool stop_producer {false}, stop_consumer {false};

    constexpr std::size_t PRODUCER_CNT = 10, CONSUMER_CNT = 8;

    std::vector<std::thread> producers, consumers;
    for (int i=0; i<PRODUCER_CNT; ++i) {
        producers.emplace_back([&]() {
            while (!stop_producer.load()) {
                bbq.push(std::rand() % 25);
                producer_cnt.fetch_add(1);
                std::this_thread::sleep_for(std::chrono::microseconds(std::rand() % 10));
            }
        });
        producers.rbegin()->detach();
    }

    for (int i=0; i<CONSUMER_CNT; ++i) {
        consumers.emplace_back([&]() {
            while (!stop_consumer.load()) {
                int result;
                bbq.pop(result);
                consumer_cnt.fetch_add(1);
                std::this_thread::sleep_for(std::chrono::microseconds(std::rand() % 10));
            }
        });
        consumers.rbegin()->detach();
    }

    std::this_thread::sleep_for(200ms);
    stop_producer.store(true);

    std::this_thread::sleep_for(50ms);
    stop_consumer.store(true);

    std::this_thread::sleep_for(50ms);
    REQUIRE(producer_cnt.load() == consumer_cnt.load());
    REQUIRE(bbq.is_empty());

}<commit_msg>test: queue: fix infinite waiting in consumer thread<commit_after>//
// Created by lz on 1/22/17.
//

#include <c10k/queue.hpp>
#include <catch.hpp>
#include <thread>
#include <vector>
#include <atomic>
#include <cstddef>
#include <chrono>

using namespace std::chrono_literals;

TEST_CASE("Queue in multi producer multi consumer status", "[queue]")
{
    using namespace c10k;
    detail::BoundedBlockingQueue<int> bbq(15);

    std::atomic_int producer_cnt {0}, consumer_cnt {0};
    std::atomic_bool stop_producer {false}, stop_consumer {false};

    constexpr std::size_t PRODUCER_CNT = 10, CONSUMER_CNT = 8;

    std::vector<std::thread> producers, consumers;
    for (int i=0; i<PRODUCER_CNT; ++i) {
        producers.emplace_back([&]() {
            while (!stop_producer.load()) {
                bbq.push(std::rand() % 25);
                producer_cnt.fetch_add(1);
                std::this_thread::sleep_for(std::chrono::microseconds(std::rand() % 10));
            }
        });
        producers.rbegin()->detach();
    }

    for (int i=0; i<CONSUMER_CNT; ++i) {
        consumers.emplace_back([&]() {
            while (!stop_consumer.load()) {
                int result;
                if (bbq.try_pop(result))
                    consumer_cnt.fetch_add(1);
                std::this_thread::sleep_for(std::chrono::microseconds(std::rand() % 10));
            }
        });
        consumers.rbegin()->detach();
    }

    std::this_thread::sleep_for(200ms);
    stop_producer.store(true);

    std::this_thread::sleep_for(50ms);
    stop_consumer.store(true);

    std::this_thread::sleep_for(50ms);
    REQUIRE(producer_cnt.load() == consumer_cnt.load());
    REQUIRE(bbq.is_empty());

}<|endoftext|>


<commit_before>/* ---------------------------------------------------------------------
 * Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2013, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero Public License for more details.
 *
 * You should have received a copy of the GNU Affero Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ---------------------------------------------------------------------
 */

/** @file */

//----------------------------------------------------------------------

#ifndef NTA_LOGGING_EXCEPTION_HPP
#define NTA_LOGGING_EXCEPTION_HPP

#include <nupic/types/Exception.hpp>
#include <sstream>
#include <vector>

namespace nupic {
class LoggingException : public Exception {
public:
  LoggingException(const std::string &filename, UInt32 lineno)
      : Exception(filename, lineno, std::string()), ss_(std::string()),
        lmessageValid_(false), alreadyLogged_(false) {}

  virtual ~LoggingException() throw();

  const char *getMessage() const override {
    // Make sure we use a persistent string. Otherwise the pointer may
    // become invalid.
    // If the underlying stringstream object hasn't changed, don't regenerate
    // lmessage_. This is important because if we catch this exception a second
    // call to exception.what() will trash the buffer returned by a first call
    // to exception.what()
    if (!lmessageValid_) {
      lmessage_ = ss_.str();
      lmessageValid_ = true;
    }
    return lmessage_.c_str();
  }

  // for Index.hpp: // because stringstream cant take << vector
  LoggingException &
  operator<<(std::vector<nupic::UInt32, std::allocator<nupic::UInt32> > v) {
    lmessageValid_ = false;
    ss_ << "[";
    for (auto &elem : v)
      ss_ << elem << " ";
    ss_ << "]";
    return *this;
  }

  template <typename T> LoggingException &operator<<(const T &obj) {
    // underlying stringstream changes, so let getMessage() know
    // to regenerate lmessage_
    lmessageValid_ = false;
    ss_ << obj;
    return *this;
  }

  LoggingException(const LoggingException &l)
      : Exception(l), ss_(l.ss_.str()), lmessage_(""), lmessageValid_(false),
        alreadyLogged_(true) // copied exception does not log

  {
    // make sure message string is up to date for debuggers.
    getMessage();
  }

private:
  std::stringstream ss_;
  mutable std::string lmessage_; // mutable because getMesssage() modifies it
  mutable bool lmessageValid_;
  bool alreadyLogged_;
}; // class LoggingException

} // namespace nupic

#endif // NTA_LOGGING_EXCEPTION_HPP
<commit_msg>resolve merge conflict with LoggingException.hpp<commit_after>/* ---------------------------------------------------------------------
 * Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2013, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero Public License for more details.
 *
 * You should have received a copy of the GNU Affero Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ---------------------------------------------------------------------
 */

/** @file */

//----------------------------------------------------------------------

#ifndef NTA_LOGGING_EXCEPTION_HPP
#define NTA_LOGGING_EXCEPTION_HPP

#include <nupic/types/Exception.hpp>
#include <sstream>
#include <vector>

namespace nupic {
class LoggingException : public Exception {
public:
  LoggingException(const std::string &filename, UInt32 lineno)
      : Exception(filename, lineno, std::string()), ss_(std::string()),
        lmessageValid_(false), alreadyLogged_(false) {}

  virtual ~LoggingException() throw();

  const char *getMessage() const override {
    // Make sure we use a persistent string. Otherwise the pointer may
    // become invalid.
    // If the underlying stringstream object hasn't changed, don't regenerate
    // lmessage_. This is important because if we catch this exception a second
    // call to exception.what() will trash the buffer returned by a first call
    // to exception.what()
    if (!lmessageValid_) {
      lmessage_ = ss_.str();
      lmessageValid_ = true;
    }
    return lmessage_.c_str();
  }

  // for Index.hpp: // because stringstream cant take << vector
  LoggingException& operator<<(std::vector<nupic::UInt32, std::allocator<nupic::UInt32> > v) {
    lmessageValid_ = false;
    ss_ << "[";
    for (auto &elem : v)
      ss_ << elem << " ";
    ss_ << "]";
    return *this;
  }

  template <typename T> LoggingException &operator<<(const T &obj) {
    // underlying stringstream changes, so let getMessage() know
    // to regenerate lmessage_
    lmessageValid_ = false;
    ss_ << obj;
    return *this;
  }

  LoggingException(const LoggingException &l)
      : Exception(l), ss_(l.ss_.str()), lmessage_(""), lmessageValid_(false),
        alreadyLogged_(true) // copied exception does not log

  {
    // make sure message string is up to date for debuggers.
    getMessage();
  }

private:
  std::stringstream ss_;
  mutable std::string lmessage_; // mutable because getMesssage() modifies it
  mutable bool lmessageValid_;
  bool alreadyLogged_;
}; // class LoggingException

} // namespace nupic

#endif // NTA_LOGGING_EXCEPTION_HPP
<|endoftext|>


<commit_before>#ifndef LIGHTGBM_OBJECTIVE_XENTROPY_OBJECTIVE_HPP_
#define LIGHTGBM_OBJECTIVE_XENTROPY_OBJECTIVE_HPP_

#include <LightGBM/utils/common.h>

#include <LightGBM/objective_function.h>

#include <cstring>
#include <cmath>

/*
 * Implements gradients and hessians for the following point losses.
 * Target y is anything in interval [0, 1].
 *
 * (1) CrossEntropy; "xentropy";
 *
 * loss(y, p, w) = { -(1-y)*log(1-p)-y*log(p) }*w,
 * with probability p = 1/(1+exp(-f)), where f is being boosted
 *
 * ConvertToOutput: f -> p
 *
 * (2) CrossEntropyLambda; "xentlambda"
 *
 * loss(y, p, w) = -(1-y)*log(1-p)-y*log(p),
 * with p = 1-exp(-lambda*w), lambda = log(1+exp(f)), f being boosted, and w > 0
 *
 * ConvertToOutput: f -> lambda
 *
 * (1) and (2) are the same if w=1; but outputs still differ.
 *
 */

namespace LightGBM {
/*!
* \brief Objective function for cross-entropy (with optional linear weights)
*/
class CrossEntropy: public ObjectiveFunction {
public:
  explicit CrossEntropy(const ObjectiveConfig&) {
  }

  explicit CrossEntropy(const std::vector<std::string>&) {
  }

  ~CrossEntropy() {}

  void Init(const Metadata& metadata, data_size_t num_data) override {
    num_data_ = num_data;
    label_ = metadata.label();
    weights_ = metadata.weights();

    CHECK_NOTNULL(label_);
    Common::check_elements_interval_closed(label_, 0.0f, 1.0f, num_data_, GetName());
    Log::Info("[%s:%s]: (objective) labels passed interval [0, 1] check",  GetName(), __func__);

    if (weights_ != nullptr) {
      float minw;
      double sumw;
      Common::obtain_min_max_sum(weights_, num_data_, &minw, nullptr, &sumw);
      if (minw < 0.0f) {
        Log::Fatal("[%s]: at least one weight is negative.", GetName());
      }
      if (sumw == 0.0f) {
        Log::Fatal("[%s]: sum of weights is zero.", GetName());
      }
    }

  }

  void GetGradients(const double* score, score_t* gradients, score_t* hessians) const override {
    if (weights_ == nullptr) {
      // compute pointwise gradients and hessians with implied unit weights
      #pragma omp parallel for schedule(static)
      for (data_size_t i = 0; i < num_data_; ++i) {
        const double z = 1.0f / (1.0f + std::exp(-score[i]));
        gradients[i] = static_cast<score_t>(z - label_[i]);
        hessians[i] = static_cast<score_t>(z * (1.0f - z));
      }
    } else {
      // compute pointwise gradients and hessians with given weights
      #pragma omp parallel for schedule(static)
      for (data_size_t i = 0; i < num_data_; ++i) {
        const double z = 1.0f / (1.0f + std::exp(-score[i]));
        gradients[i] = static_cast<score_t>((z - label_[i]) * weights_[i]);
        hessians[i] = static_cast<score_t>(z * (1.0f - z) * weights_[i]);
      }
    }
  }

  const char* GetName() const override {
    return "xentropy";
  }

  // convert score to a probability
  void ConvertOutput(const double* input, double* output) const override {
    output[0] = 1.0f / (1.0f + std::exp(-input[0]));
  }

  std::string ToString() const override {
    std::stringstream str_buf;
    str_buf << GetName();
    return str_buf.str();
  }

  // allow boost from average option
  bool BoostFromAverage() const override { return true; }

  // implement custom average to boost from (if enabled among options)
  bool GetCustomAverage(double *initscore) const override {
    if (initscore == nullptr) return false;
    double suml = 0.0f;
    double sumw = 0.0f;
    if (weights_ == nullptr) {
      for (data_size_t i = 0; i < num_data_; ++i) {
        suml += label_[i] * weights_[i];
        sumw += weights_[i];
      }
    } else {
      sumw = static_cast<double>(num_data_);
      for (data_size_t i = 0; i < num_data_; ++i) {
        suml += label_[i];
      }
    }
    double pavg = suml / sumw;
    *initscore = std::log(pavg / (1.0f - pavg));
    Log::Info("[%s:%s]: pavg=%f -> initscore=%f",  GetName(), __func__, pavg, *initscore);
    return true;
  }

private:
  /*! \brief Number of data points */
  data_size_t num_data_;
  /*! \brief Pointer for label */
  const float* label_;
  /*! \brief Weights for data */
  const float* weights_;
};

/*!
* \brief Objective function for alternative parameterization of cross-entropy (see top of file for explanation)
*/
class CrossEntropyLambda: public ObjectiveFunction {
public:
  explicit CrossEntropyLambda(const ObjectiveConfig&) {
    min_weight_ = max_weight_ = 0.0f;
  }

  explicit CrossEntropyLambda(const std::vector<std::string>&) {
  }

  ~CrossEntropyLambda() {}

  void Init(const Metadata& metadata, data_size_t num_data) override {
    num_data_ = num_data;
    label_ = metadata.label();
    weights_ = metadata.weights();

    CHECK_NOTNULL(label_);
    Common::check_elements_interval_closed(label_, 0.0f, 1.0f, num_data_, GetName());
    Log::Info("[%s:%s]: (objective) labels passed interval [0, 1] check",  GetName(), __func__);

    if (weights_ != nullptr) {

      Common::obtain_min_max_sum(weights_, num_data_, &min_weight_, &max_weight_, nullptr);
      if (min_weight_ <= 0.0f) {
        Log::Fatal("[%s]: at least one weight is non-positive.", GetName());
      }

      // Issue an info statement about this ratio
      double weight_ratio = max_weight_ / min_weight_;
      Log::Info("[%s:%s]: min, max weights = %f, %f; ratio = %f",
                GetName(), __func__,
                min_weight_, max_weight_,
                weight_ratio);
    } else {
      // all weights are implied to be unity; no need to do anything
    }
  }

  void GetGradients(const double* score, score_t* gradients, score_t* hessians) const override {
    if (weights_ == nullptr) {
      // compute pointwise gradients and hessians with implied unit weights; exactly equivalent to CrossEntropy with unit weights
      #pragma omp parallel for schedule(static)
      for (data_size_t i = 0; i < num_data_; ++i) {
        const double z = 1.0f / (1.0f + std::exp(-score[i]));
        gradients[i] = static_cast<score_t>(z - label_[i]);
        hessians[i] = static_cast<score_t>(z * (1.0f - z));
      }
    } else {
      // compute pointwise gradients and hessians with given weights
      #pragma omp parallel for schedule(static)
      for (data_size_t i = 0; i < num_data_; ++i) {
        const double w = weights_[i];
        const double y = label_[i];
        const double epf = std::exp(score[i]);
        const double hhat = std::log(1.0f + epf);
        const double z = 1.0f - std::exp(-w*hhat);
        const double enf = 1.0f / epf; // = std::exp(-score[i]);
        gradients[i] = static_cast<score_t>((1.0f - y / z) * w / (1.0f + enf));
        const double c = 1.0f / (1.0f - z);
        double d = 1.0f + epf;
        const double a = w * epf / (d * d);
        d = c - 1.0f;
        const double b = (c / (d * d) ) * (1.0f + w * epf - c);
        hessians[i] = static_cast<score_t>(a * (1.0f + y * b));
      }
    }
  }

  const char* GetName() const override {
    return "xentlambda";
  }

  //
  // ATTENTION: the function output is the "normalized exponential parameter" lambda > 0, not the probability
  //
  // If this code would read: output[0] = 1.0f / (1.0f + std::exp(-input[0]));
  // The output would still not be the probability unless the weights are unity.
  //
  // Let z = 1 / (1 + exp(-f)), then prob(z) = 1-(1-z)^w, where w is the weight for the specific point.
  //

  void ConvertOutput(const double* input, double* output) const override {
    output[0] = std::log(1.0f + std::exp(input[0]));
  }

  std::string ToString() const override {
    std::stringstream str_buf;
    str_buf << GetName();
    return str_buf.str();
  }

  bool BoostFromAverage() const override { return true; }

  bool GetCustomAverage(double *initscore) const override {
    if (initscore == nullptr) return false;
    double sumy = 0.0f;
    for (data_size_t i = 0; i < num_data_; ++i) sumy += label_[i];
    double sumw = 0.0f;
    if (weights_ == nullptr) {
      for (data_size_t i = 0; i < num_data_; ++i) sumw += weights_[i];
    } else {
      sumw = static_cast<double>(num_data_);
    }
    double havg = sumy / sumw;
    *initscore = std::log(std::exp(havg) - 1.0f);
    Log::Info("[%s:%s]: havg=%f -> initscore=%f",  GetName(), __func__, havg, *initscore);
    return true;
  }

private:
  /*! \brief Number of data points */
  data_size_t num_data_;
  /*! \brief Pointer for label */
  const float* label_;
  /*! \brief Weights for data */
  const float* weights_;
  /*! \brief Minimum weight found during init */
  float min_weight_;
  /*! \brief Maximum weight found during init */
  float max_weight_;
};

}  // end namespace LightGBM

#endif   // end #ifndef LIGHTGBM_OBJECTIVE_XENTROPY_OBJECTIVE_HPP_
<commit_msg>Fix a3c63ff ( @strint ) (#737)<commit_after>#ifndef LIGHTGBM_OBJECTIVE_XENTROPY_OBJECTIVE_HPP_
#define LIGHTGBM_OBJECTIVE_XENTROPY_OBJECTIVE_HPP_

#include <LightGBM/utils/common.h>

#include <LightGBM/objective_function.h>

#include <cstring>
#include <cmath>

/*
 * Implements gradients and hessians for the following point losses.
 * Target y is anything in interval [0, 1].
 *
 * (1) CrossEntropy; "xentropy";
 *
 * loss(y, p, w) = { -(1-y)*log(1-p)-y*log(p) }*w,
 * with probability p = 1/(1+exp(-f)), where f is being boosted
 *
 * ConvertToOutput: f -> p
 *
 * (2) CrossEntropyLambda; "xentlambda"
 *
 * loss(y, p, w) = -(1-y)*log(1-p)-y*log(p),
 * with p = 1-exp(-lambda*w), lambda = log(1+exp(f)), f being boosted, and w > 0
 *
 * ConvertToOutput: f -> lambda
 *
 * (1) and (2) are the same if w=1; but outputs still differ.
 *
 */

namespace LightGBM {
/*!
* \brief Objective function for cross-entropy (with optional linear weights)
*/
class CrossEntropy: public ObjectiveFunction {
public:
  explicit CrossEntropy(const ObjectiveConfig&) {
  }

  explicit CrossEntropy(const std::vector<std::string>&) {
  }

  ~CrossEntropy() {}

  void Init(const Metadata& metadata, data_size_t num_data) override {
    num_data_ = num_data;
    label_ = metadata.label();
    weights_ = metadata.weights();

    CHECK_NOTNULL(label_);
    Common::check_elements_interval_closed(label_, 0.0f, 1.0f, num_data_, GetName());
    Log::Info("[%s:%s]: (objective) labels passed interval [0, 1] check",  GetName(), __func__);

    if (weights_ != nullptr) {
      float minw;
      double sumw;
      Common::obtain_min_max_sum(weights_, num_data_, &minw, nullptr, &sumw);
      if (minw < 0.0f) {
        Log::Fatal("[%s]: at least one weight is negative.", GetName());
      }
      if (sumw == 0.0f) {
        Log::Fatal("[%s]: sum of weights is zero.", GetName());
      }
    }

  }

  void GetGradients(const double* score, score_t* gradients, score_t* hessians) const override {
    if (weights_ == nullptr) {
      // compute pointwise gradients and hessians with implied unit weights
      #pragma omp parallel for schedule(static)
      for (data_size_t i = 0; i < num_data_; ++i) {
        const double z = 1.0f / (1.0f + std::exp(-score[i]));
        gradients[i] = static_cast<score_t>(z - label_[i]);
        hessians[i] = static_cast<score_t>(z * (1.0f - z));
      }
    } else {
      // compute pointwise gradients and hessians with given weights
      #pragma omp parallel for schedule(static)
      for (data_size_t i = 0; i < num_data_; ++i) {
        const double z = 1.0f / (1.0f + std::exp(-score[i]));
        gradients[i] = static_cast<score_t>((z - label_[i]) * weights_[i]);
        hessians[i] = static_cast<score_t>(z * (1.0f - z) * weights_[i]);
      }
    }
  }

  const char* GetName() const override {
    return "xentropy";
  }

  // convert score to a probability
  void ConvertOutput(const double* input, double* output) const override {
    output[0] = 1.0f / (1.0f + std::exp(-input[0]));
  }

  std::string ToString() const override {
    std::stringstream str_buf;
    str_buf << GetName();
    return str_buf.str();
  }

  // allow boost from average option
  bool BoostFromAverage() const override { return true; }

  // implement custom average to boost from (if enabled among options)
  bool GetCustomAverage(double *initscore) const override {
    if (initscore == nullptr) return false;
    double suml = 0.0f;
    double sumw = 0.0f;
    if (weights_ == nullptr) {
      for (data_size_t i = 0; i < num_data_; ++i) {
        suml += label_[i] * weights_[i];
        sumw += weights_[i];
      }
    } else {
      sumw = static_cast<double>(num_data_);
      for (data_size_t i = 0; i < num_data_; ++i) {
        suml += label_[i];
      }
    }
    double pavg = suml / sumw;
    *initscore = std::log(pavg / (1.0f - pavg));
    Log::Info("[%s:%s]: pavg=%f -> initscore=%f",  GetName(), __func__, pavg, *initscore);
    return true;
  }

private:
  /*! \brief Number of data points */
  data_size_t num_data_;
  /*! \brief Pointer for label */
  const float* label_;
  /*! \brief Weights for data */
  const float* weights_;
};

/*!
* \brief Objective function for alternative parameterization of cross-entropy (see top of file for explanation)
*/
class CrossEntropyLambda: public ObjectiveFunction {
public:
  explicit CrossEntropyLambda(const ObjectiveConfig&) {
    min_weight_ = max_weight_ = 0.0f;
  }

  explicit CrossEntropyLambda(const std::vector<std::string>&) {
  }

  ~CrossEntropyLambda() {}

  void Init(const Metadata& metadata, data_size_t num_data) override {
    num_data_ = num_data;
    label_ = metadata.label();
    weights_ = metadata.weights();

    CHECK_NOTNULL(label_);
    Common::check_elements_interval_closed(label_, 0.0f, 1.0f, num_data_, GetName());
    Log::Info("[%s:%s]: (objective) labels passed interval [0, 1] check",  GetName(), __func__);

    if (weights_ != nullptr) {

      Common::obtain_min_max_sum(weights_, num_data_, &min_weight_, &max_weight_, nullptr);
      if (min_weight_ <= 0.0f) {
        Log::Fatal("[%s]: at least one weight is non-positive.", GetName());
      }

      // Issue an info statement about this ratio
      double weight_ratio = max_weight_ / min_weight_;
      Log::Info("[%s:%s]: min, max weights = %f, %f; ratio = %f",
                GetName(), __func__,
                min_weight_, max_weight_,
                weight_ratio);
    } else {
      // all weights are implied to be unity; no need to do anything
    }
  }

  void GetGradients(const double* score, score_t* gradients, score_t* hessians) const override {
    if (weights_ == nullptr) {
      // compute pointwise gradients and hessians with implied unit weights; exactly equivalent to CrossEntropy with unit weights
      #pragma omp parallel for schedule(static)
      for (data_size_t i = 0; i < num_data_; ++i) {
        const double z = 1.0f / (1.0f + std::exp(-score[i]));
        gradients[i] = static_cast<score_t>(z - label_[i]);
        hessians[i] = static_cast<score_t>(z * (1.0f - z));
      }
    } else {
      // compute pointwise gradients and hessians with given weights
      #pragma omp parallel for schedule(static)
      for (data_size_t i = 0; i < num_data_; ++i) {
        const double w = weights_[i];
        const double y = label_[i];
        const double epf = std::exp(score[i]);
        const double hhat = std::log(1.0f + epf);
        const double z = 1.0f - std::exp(-w*hhat);
        const double enf = 1.0f / epf; // = std::exp(-score[i]);
        gradients[i] = static_cast<score_t>((1.0f - y / z) * w / (1.0f + enf));
        const double c = 1.0f / (1.0f - z);
        double d = 1.0f + epf;
        const double a = w * epf / (d * d);
        d = c - 1.0f;
        const double b = (c / (d * d) ) * (1.0f + w * epf - c);
        hessians[i] = static_cast<score_t>(a * (1.0f + y * b));
      }
    }
  }

  const char* GetName() const override {
    return "xentlambda";
  }

  //
  // ATTENTION: the function output is the "normalized exponential parameter" lambda > 0, not the probability
  //
  // If this code would read: output[0] = 1.0f / (1.0f + std::exp(-input[0]));
  // The output would still not be the probability unless the weights are unity.
  //
  // Let z = 1 / (1 + exp(-f)), then prob(z) = 1-(1-z)^w, where w is the weight for the specific point.
  //

  void ConvertOutput(const double* input, double* output) const override {
    output[0] = std::log(1.0f + std::exp(input[0]));
  }

  std::string ToString() const override {
    std::stringstream str_buf;
    str_buf << GetName();
    return str_buf.str();
  }

  bool BoostFromAverage() const override { return true; }

  bool GetCustomAverage(double *initscore) const override {
    if (initscore == nullptr) return false;
    double sumy = 0.0f;
    for (data_size_t i = 0; i < num_data_; ++i) sumy += label_[i];
    double sumw = 0.0f;
    if (weights_ != nullptr) {
      for (data_size_t i = 0; i < num_data_; ++i) sumw += weights_[i];
    } else {
      sumw = static_cast<double>(num_data_);
    }
    double havg = sumy / sumw;
    *initscore = std::log(std::exp(havg) - 1.0f);
    Log::Info("[%s:%s]: havg=%f -> initscore=%f",  GetName(), __func__, havg, *initscore);
    return true;
  }

private:
  /*! \brief Number of data points */
  data_size_t num_data_;
  /*! \brief Pointer for label */
  const float* label_;
  /*! \brief Weights for data */
  const float* weights_;
  /*! \brief Minimum weight found during init */
  float min_weight_;
  /*! \brief Maximum weight found during init */
  float max_weight_;
};

}  // end namespace LightGBM

#endif   // end #ifndef LIGHTGBM_OBJECTIVE_XENTROPY_OBJECTIVE_HPP_
<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file AutoComplete.cxx
 ** Defines the auto completion list box.
 **/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "Platform.h"

#include "PropSet.h"
#include "AutoComplete.h"

AutoComplete::AutoComplete() :
	active(false),
	separator(' '),
	ignoreCase(false),
	chooseSingle(false),
	posStart(0),
	startLen(0),
	cancelAtStartPos(true),
	autoHide(true),
	dropRestOfWord(false)	{
	stopChars[0] = '\0';
	fillUpChars[0] = '\0';
}

AutoComplete::~AutoComplete() {
	lb.Destroy();
}

bool AutoComplete::Active() {
	return active;
}

void AutoComplete::Start(Window &parent, int ctrlID, int position, int startLen_) {
	if (!lb.Created()) {
		lb.Create(parent, ctrlID);
	}
	lb.Clear();
	active = true;
	startLen = startLen_;
	posStart = position;
}

void AutoComplete::SetStopChars(const char *stopChars_) {
	strncpy(stopChars, stopChars_, sizeof(stopChars));
	stopChars[sizeof(stopChars) - 1] = '\0';
}

bool AutoComplete::IsStopChar(char ch) {
	return ch && strchr(stopChars, ch);
}

void AutoComplete::SetFillUpChars(const char *fillUpChars_) {
	strncpy(fillUpChars, fillUpChars_, sizeof(fillUpChars));
	fillUpChars[sizeof(fillUpChars) - 1] = '\0';
}

bool AutoComplete::IsFillUpChar(char ch) {
	return ch && strchr(fillUpChars, ch);
}

void AutoComplete::SetSeparator(char separator_) {
	separator = separator_;
}

char AutoComplete::GetSeparator() {
	return separator;
}

void AutoComplete::SetList(const char *list) {
	lb.Clear();
	char *words = new char[strlen(list) + 1];
	if (words) {
		strcpy(words, list);
		char *startword = words;
		int i = 0;
		for (; words && words[i]; i++) {
			if (words[i] == separator) {
				words[i] = '\0';
				lb.Append(startword);
				startword = words + i + 1;
			}
		}
		if (startword) {
			lb.Append(startword);
		}
		delete []words;
	}
}

void AutoComplete::Show() {
	lb.Show();
	lb.Select(0);
}

void AutoComplete::Cancel() {
	if (lb.Created()) {
		lb.Destroy();
		active = false;
	}
}

void AutoComplete::Move(int delta) {
	int count = lb.Length();
	int current = lb.GetSelection();
	current += delta;
	if (current >= count)
		current = count - 1;
	if (current < 0)
		current = 0;
	lb.Select(current);
}

void AutoComplete::Select(const char *word) {
	size_t lenWord = strlen(word);
	int location = -1;
	const int maxItemLen=1000;
	char item[maxItemLen];
	int start = 0; // lower bound of the api array block to search
	int end = lb.Length() - 1; // upper bound of the api array block to search
	while ((start <= end) && (location == -1)) { // Binary searching loop
		int pivot = (start + end) / 2;
		lb.GetValue(pivot, item, maxItemLen);
		int cond;
		if (ignoreCase)
			cond = CompareNCaseInsensitive(word, item, lenWord);
		else
			cond = strncmp(word, item, lenWord);
		if (!cond) {
			// Find first match
			while (pivot > start) {
				lb.GetValue(pivot-1, item, maxItemLen);
				if (ignoreCase)
					cond = CompareNCaseInsensitive(word, item, lenWord);
				else
					cond = strncmp(word, item, lenWord);
				if (0 != cond)
					break;
				--pivot;
			}
			location = pivot;
		} else if (cond < 0) {
			end = pivot - 1;
		} else if (cond > 0) {
			start = pivot + 1;
		}
	}
	if (location == -1 && autoHide)
		Cancel();
	else
		lb.Select(location);
}

<commit_msg>More of the icons in autocompletion patch.<commit_after>// Scintilla source code edit control
/** @file AutoComplete.cxx
 ** Defines the auto completion list box.
 **/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "Platform.h"

#include "PropSet.h"
#include "AutoComplete.h"

AutoComplete::AutoComplete() :
	active(false),
	separator(' '),
	typesep('?'),
	ignoreCase(false),
	chooseSingle(false),
	posStart(0),
	startLen(0),
	cancelAtStartPos(true),
	autoHide(true),
	dropRestOfWord(false)	{
	stopChars[0] = '\0';
	fillUpChars[0] = '\0';
}

AutoComplete::~AutoComplete() {
	lb.Destroy();
}

bool AutoComplete::Active() {
	return active;
}

void AutoComplete::Start(Window &parent, int ctrlID, int position, int startLen_) {
	if (!lb.Created()) {
		lb.Create(parent, ctrlID);
	}
	lb.Clear();
	active = true;
	startLen = startLen_;
	posStart = position;
}

void AutoComplete::SetStopChars(const char *stopChars_) {
	strncpy(stopChars, stopChars_, sizeof(stopChars));
	stopChars[sizeof(stopChars) - 1] = '\0';
}

bool AutoComplete::IsStopChar(char ch) {
	return ch && strchr(stopChars, ch);
}

void AutoComplete::SetFillUpChars(const char *fillUpChars_) {
	strncpy(fillUpChars, fillUpChars_, sizeof(fillUpChars));
	fillUpChars[sizeof(fillUpChars) - 1] = '\0';
}

bool AutoComplete::IsFillUpChar(char ch) {
	return ch && strchr(fillUpChars, ch);
}

void AutoComplete::SetSeparator(char separator_) {
	separator = separator_;
}

char AutoComplete::GetSeparator() {
	return separator;
}

void AutoComplete::SetTypesep(char separator_) {
	typesep = separator_;
}

char AutoComplete::GetTypesep() {
	return typesep;
}

void AutoComplete::SetList(const char *list) {
	lb.Clear();
	char *words = new char[strlen(list) + 1];
	if (words) {
		strcpy(words, list);
		char *startword = words;
		char *numword = NULL;
		int i = 0;
		for (; words && words[i]; i++) {
			if (words[i] == separator) {
				words[i] = '\0';
				if (numword)
					*numword = '\0';
				lb.Append(startword, numword?atoi(numword + 1):0);
				startword = words + i + 1;
				numword = NULL;
			} else if (words[i] == typesep) {
				numword = words + i;
			}
		}
		if (startword) {
			if (numword)
				*numword = '\0';
			lb.Append(startword, numword?atoi(numword + 1):0);
		}
		delete []words;
	}
}

void AutoComplete::Show() {
	lb.Show();
	lb.Select(0);
}

void AutoComplete::Cancel() {
	if (lb.Created()) {
		lb.Destroy();
		active = false;
	}
}

void AutoComplete::Move(int delta) {
	int count = lb.Length();
	int current = lb.GetSelection();
	current += delta;
	if (current >= count)
		current = count - 1;
	if (current < 0)
		current = 0;
	lb.Select(current);
}

void AutoComplete::Select(const char *word) {
	size_t lenWord = strlen(word);
	int location = -1;
	const int maxItemLen=1000;
	char item[maxItemLen];
	int start = 0; // lower bound of the api array block to search
	int end = lb.Length() - 1; // upper bound of the api array block to search
	while ((start <= end) && (location == -1)) { // Binary searching loop
		int pivot = (start + end) / 2;
		lb.GetValue(pivot, item, maxItemLen);
		int cond;
		if (ignoreCase)
			cond = CompareNCaseInsensitive(word, item, lenWord);
		else
			cond = strncmp(word, item, lenWord);
		if (!cond) {
			// Find first match
			while (pivot > start) {
				lb.GetValue(pivot-1, item, maxItemLen);
				if (ignoreCase)
					cond = CompareNCaseInsensitive(word, item, lenWord);
				else
					cond = strncmp(word, item, lenWord);
				if (0 != cond)
					break;
				--pivot;
			}
			location = pivot;
		} else if (cond < 0) {
			end = pivot - 1;
		} else if (cond > 0) {
			start = pivot + 1;
		}
	}
	if (location == -1 && autoHide)
		Cancel();
	else
		lb.Select(location);
}

<|endoftext|>


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

#include "builder.h"
#include "code_generator.h"
#include "common_compiler_test.h"
#include "dex_file.h"
#include "dex_instruction.h"
#include "instruction_set.h"
#include "nodes.h"
#include "optimizing_unit_test.h"

#include "gtest/gtest.h"

namespace art {

class ExecutableMemoryAllocator : public CodeAllocator {
 public:
  ExecutableMemoryAllocator() { }

  virtual uint8_t* Allocate(size_t size) {
    memory_.reset(new uint8_t[size]);
    CommonCompilerTest::MakeExecutable(memory_.get(), size);
    return memory_.get();
  }

  uint8_t* memory() const { return memory_.get(); }

 private:
  UniquePtr<uint8_t[]> memory_;

  DISALLOW_COPY_AND_ASSIGN(ExecutableMemoryAllocator);
};

static void TestCode(const uint16_t* data, bool has_result = false, int32_t expected = 0) {
  ArenaPool pool;
  ArenaAllocator arena(&pool);
  HGraphBuilder builder(&arena);
  const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
  HGraph* graph = builder.BuildGraph(*item);
  ASSERT_NE(graph, nullptr);
  ExecutableMemoryAllocator allocator;
  CHECK(CodeGenerator::CompileGraph(graph, kX86, &allocator));
  typedef int32_t (*fptr)();
#if defined(__i386__)
  int32_t result = reinterpret_cast<fptr>(allocator.memory())();
#endif
  CHECK(CodeGenerator::CompileGraph(graph, kArm, &allocator));
#if defined(__arm__)
  int32_t result = reinterpret_cast<fptr>(allocator.memory())();
#endif
  if (has_result) {
    CHECK_EQ(result, expected);
  }
}

TEST(CodegenTest, ReturnVoid) {
  const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(Instruction::RETURN_VOID);
  TestCode(data);
}

TEST(CodegenTest, CFG1) {
  const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::GOTO | 0x100,
    Instruction::RETURN_VOID);

  TestCode(data);
}

TEST(CodegenTest, CFG2) {
  const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::GOTO | 0x100,
    Instruction::GOTO | 0x100,
    Instruction::RETURN_VOID);

  TestCode(data);
}

TEST(CodegenTest, CFG3) {
  const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::GOTO | 0x200,
    Instruction::RETURN_VOID,
    Instruction::GOTO | 0xFF00);

  TestCode(data1);

  const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::GOTO_16, 3,
    Instruction::RETURN_VOID,
    Instruction::GOTO_16, 0xFFFF);

  TestCode(data2);

  const uint16_t data3[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::GOTO_32, 4, 0,
    Instruction::RETURN_VOID,
    Instruction::GOTO_32, 0xFFFF, 0xFFFF);

  TestCode(data3);
}

TEST(CodegenTest, CFG4) {
  const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::RETURN_VOID,
    Instruction::GOTO | 0x100,
    Instruction::GOTO | 0xFE00);

  TestCode(data);
}

TEST(CodegenTest, CFG5) {
  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::IF_EQ, 3,
    Instruction::GOTO | 0x100,
    Instruction::RETURN_VOID);

  TestCode(data);
}

TEST(CodegenTest, IntConstant) {
  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::RETURN_VOID);

  TestCode(data);
}

TEST(CodegenTest, Return1) {
  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::RETURN | 0);

  TestCode(data, true, 0);
}

TEST(CodegenTest, Return2) {
  const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::CONST_4 | 0 | 1 << 8,
    Instruction::RETURN | 1 << 8);

  TestCode(data, true, 0);
}

TEST(CodegenTest, Return3) {
  const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::CONST_4 | 1 << 8 | 1 << 12,
    Instruction::RETURN | 1 << 8);

  TestCode(data, true, 1);
}

TEST(CodegenTest, ReturnIf1) {
  const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::CONST_4 | 1 << 8 | 1 << 12,
    Instruction::IF_EQ, 3,
    Instruction::RETURN | 0 << 8,
    Instruction::RETURN | 1 << 8);

  TestCode(data, true, 1);
}

TEST(CodegenTest, ReturnIf2) {
  const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::CONST_4 | 1 << 8 | 1 << 12,
    Instruction::IF_EQ | 0 << 4 | 1 << 8, 3,
    Instruction::RETURN | 0 << 8,
    Instruction::RETURN | 1 << 8);

  TestCode(data, true, 0);
}

}  // namespace art
<commit_msg>am c1db36ce: Merge "Fix non-{arm, x86} builds."<commit_after>/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "builder.h"
#include "code_generator.h"
#include "common_compiler_test.h"
#include "dex_file.h"
#include "dex_instruction.h"
#include "instruction_set.h"
#include "nodes.h"
#include "optimizing_unit_test.h"

#include "gtest/gtest.h"

namespace art {

class ExecutableMemoryAllocator : public CodeAllocator {
 public:
  ExecutableMemoryAllocator() { }

  virtual uint8_t* Allocate(size_t size) {
    memory_.reset(new uint8_t[size]);
    CommonCompilerTest::MakeExecutable(memory_.get(), size);
    return memory_.get();
  }

  uint8_t* memory() const { return memory_.get(); }

 private:
  UniquePtr<uint8_t[]> memory_;

  DISALLOW_COPY_AND_ASSIGN(ExecutableMemoryAllocator);
};

static void TestCode(const uint16_t* data, bool has_result = false, int32_t expected = 0) {
  ArenaPool pool;
  ArenaAllocator arena(&pool);
  HGraphBuilder builder(&arena);
  const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
  HGraph* graph = builder.BuildGraph(*item);
  ASSERT_NE(graph, nullptr);
  ExecutableMemoryAllocator allocator;
  CHECK(CodeGenerator::CompileGraph(graph, kX86, &allocator));
  typedef int32_t (*fptr)();
#if defined(__i386__)
  int32_t result = reinterpret_cast<fptr>(allocator.memory())();
  if (has_result) {
    CHECK_EQ(result, expected);
  }
#endif
  CHECK(CodeGenerator::CompileGraph(graph, kArm, &allocator));
#if defined(__arm__)
  int32_t result = reinterpret_cast<fptr>(allocator.memory())();
  if (has_result) {
    CHECK_EQ(result, expected);
  }
#endif
}

TEST(CodegenTest, ReturnVoid) {
  const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(Instruction::RETURN_VOID);
  TestCode(data);
}

TEST(CodegenTest, CFG1) {
  const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::GOTO | 0x100,
    Instruction::RETURN_VOID);

  TestCode(data);
}

TEST(CodegenTest, CFG2) {
  const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::GOTO | 0x100,
    Instruction::GOTO | 0x100,
    Instruction::RETURN_VOID);

  TestCode(data);
}

TEST(CodegenTest, CFG3) {
  const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::GOTO | 0x200,
    Instruction::RETURN_VOID,
    Instruction::GOTO | 0xFF00);

  TestCode(data1);

  const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::GOTO_16, 3,
    Instruction::RETURN_VOID,
    Instruction::GOTO_16, 0xFFFF);

  TestCode(data2);

  const uint16_t data3[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::GOTO_32, 4, 0,
    Instruction::RETURN_VOID,
    Instruction::GOTO_32, 0xFFFF, 0xFFFF);

  TestCode(data3);
}

TEST(CodegenTest, CFG4) {
  const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
    Instruction::RETURN_VOID,
    Instruction::GOTO | 0x100,
    Instruction::GOTO | 0xFE00);

  TestCode(data);
}

TEST(CodegenTest, CFG5) {
  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::IF_EQ, 3,
    Instruction::GOTO | 0x100,
    Instruction::RETURN_VOID);

  TestCode(data);
}

TEST(CodegenTest, IntConstant) {
  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::RETURN_VOID);

  TestCode(data);
}

TEST(CodegenTest, Return1) {
  const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::RETURN | 0);

  TestCode(data, true, 0);
}

TEST(CodegenTest, Return2) {
  const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::CONST_4 | 0 | 1 << 8,
    Instruction::RETURN | 1 << 8);

  TestCode(data, true, 0);
}

TEST(CodegenTest, Return3) {
  const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::CONST_4 | 1 << 8 | 1 << 12,
    Instruction::RETURN | 1 << 8);

  TestCode(data, true, 1);
}

TEST(CodegenTest, ReturnIf1) {
  const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::CONST_4 | 1 << 8 | 1 << 12,
    Instruction::IF_EQ, 3,
    Instruction::RETURN | 0 << 8,
    Instruction::RETURN | 1 << 8);

  TestCode(data, true, 1);
}

TEST(CodegenTest, ReturnIf2) {
  const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
    Instruction::CONST_4 | 0 | 0,
    Instruction::CONST_4 | 1 << 8 | 1 << 12,
    Instruction::IF_EQ | 0 << 4 | 1 << 8, 3,
    Instruction::RETURN | 0 << 8,
    Instruction::RETURN | 1 << 8);

  TestCode(data, true, 0);
}

}  // namespace art
<|endoftext|>


<commit_before>/* RTcmix  - Copyright (C) 2000  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
#define MAIN
#include <pthread.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream.h>
#include <signal.h>
#ifdef LINUX
   #include <sys/soundcard.h>
#endif
#ifdef SGI
   #include <dmedia/audio.h>
#endif
#include <globals.h>
#include <prototypes.h>
#include <ugens.h>
#include <version.h>
#include "../rtstuff/rt.h"
#include "sockdefs.h"
#include "defs.h"
#include "notetags.h"           // contains defs for note-tagging
#include "../H/dbug.h"

extern "C" {
   int ug_intro();
   void *yyparse();
   int profile();
   void rtprofile();
#ifdef SGI
   void flush_all_underflows_to_zero();
#endif
#ifdef LINUX
   void flush_fpe(int sig);
#endif
}

rt_item *rt_list;     /* can't put this in globals.h because of rt.h trouble */

int interactive;     /* used in y.tab.c - don't remove this! */
Tree program;

#define CMAX 16    /* allow up to 16 command line args to be passed to subs */
char *aargv[CMAX];
char name[NAMESIZE];
int aargc;

/* <yyin> is yacc's input file. If we leave it alone, stdin will be used. */
extern FILE *yyin;

/* --------------------------------------------------------- init_globals --- */
static void
init_globals()
{
   RTBUFSAMPS = 8192;           /* default, modifyable with rtsetparams */
   NCHANS = 2;
   audioNCHANS = 0;

#ifdef LINUX
   for (int i = 0; i < MAXBUS; i++)
      in_port[i] = out_port[i] = 0;
#endif /* LINUX */
#ifdef SGI
   in_port = 0;
   out_port = 0;
#endif /* SGI */

   interactive = 1;
   rtInteractive = 0;
   noParse = 0;
   socknew = 0;
   rtsetparams_called = 0;

   audio_on = 0;
   audio_config = 1;
   play_audio = 1;              /* modified with set_option */
   full_duplex = 0;
   check_peaks = 1;
   report_clipping = 1;

   output_data_format = -1;
   output_header_type = -1;
   normalize_output_floats = 0;
   is_float_format = 0;
   rtoutsfname = NULL;

   tags_on = 0;

   rtfileit = 0;                /* signal writing to soundfile */
   rtoutfile = 0;

   print_is_on = 1;

   Bus_Configed = NO;

   for (int i = 0; i < MAX_INPUT_FDS; i++)
      inputFileTable[i].fd = NO_FD;

   init_buf_ptrs();
}

/* ------------------------------------------------------- signal_handler --- */
static void
signal_handler(int signo)
{
#ifdef DBUG
   printf("Signal handler called (signo %d)\n", signo);
#endif

   if (rtsetparams_called) {
      close_audio_ports();
      rtreportstats();
      rtcloseout();
   }
   else
      closesf();

   exit(1);
}

/* ----------------------------------------------------------------- main --- */
int
main(int argc, char *argv[])
{
   int         i, j;
   int         retcode;                 /* for mutexes */
   char        *cp, *infile;
   pthread_t   sockitThread, inTraverseThread;

   init_globals();

#ifdef LINUX
   signal(SIGFPE, flush_fpe);          /* Install signal handler */
#endif
#ifdef SGI
   flush_all_underflows_to_zero();
#endif

   /* Call signal_handler on cntl-C. */
   if (signal(SIGINT, signal_handler) == SIG_ERR) {
      fprintf(stderr, "Error installing signal handler.\n");
      exit(1);
   }

   /* Copy command-line args, if any.
      Now, command-line args will be available to any subroutine
      in aargc; and char *aargv[], (both declared extern in ugens.h)
      parsing is exactly the same then as standard C routine.
      Maximum of CMAX arguments allowed.
   */
   for (j = 1; j < argc; j++)
      aargv[j - 1] = argv[j];
   aargc = argc;

   /* Banner */
   printf("--------> %s %s (%s) <--------\n",
                                      RTCMIX_NAME, RTCMIX_VERSION, argv[0]);

   /* Process command line. */
   if (argc >= 2) {
      while ((*++argv)[0] == '-') {
         argc -= 1;             /* Take away two args */
         for (cp = argv[0] + 1; *cp; cp++) {
            switch (*cp) {      /* Grap options */
               case 'i':               /* for separate parseit thread */
                  rtInteractive = 1;
                  audio_config = 0;
                  break;
               case 'n':               /* for separate parseit thread */
                  noParse = 1;
                  break;
               case 's':               /* set up a socket offset */
                  socknew = atoi(*++argv);
                  fprintf(stderr, "listening on socket: %d\n",
                                                         MYPORT + socknew);
                  argc -= 1;
                  break;
               case 'c':     /* set up for continuous control (note tags on) */
                  tags_on = 1;
                  printf("rtupdates enabled\n");
                  curtag = 1;          /* "0" is reserved for all notes */
                  for (i = 0; i < MAXPUPS; i++)     /* initialize element 0 */
                     pupdatevals[0][i] = NOPUPDATE;
                  break;
               case 'f':     /* use file name arg instead of stdin as score */
                  infile = *++argv;
                  yyin = fopen(infile, "r+");
                  if (yyin == NULL) {
                     printf("Can't open %s\n", infile);
                     exit(1);
                  }
                  fprintf(stderr, "Using file %s\n", infile);
                  argc -= 1;
                  break;
               default:
                  printf("Don't know about option '%c'\n", *cp);
            }
         }
         if (argc == 1)
            break;
      }
   }

   ug_intro();                  /* introduce standard routines */
   profile();                   /* introduce user-written routines etc. */
   rtprofile();                 /* introduce real-time user-written routines */

   setbuf(stdout, NULL);        /*  Want to see stdout errors */

   /* In rtInteractive mode, we set up RTcmix to listen for score data
      over a socket, and then parse this, schedule instruments, and play
      them concurrently. The socket listening and parsing go in one
      thread, and the scheduler and instrument code go in another.

      When not in rtInteractive mode, RTcmix parses the score, schedules
      all instruments, and then plays them -- in that order. No threads.
   */
   if (rtInteractive) {

      fprintf(stdout, "rtInteractive mode set\n");

      /* Read an initialization score. */
      if (!noParse) {
         cout << "Parsing once ...\n";
         yyparse();
      }

      /* Create parsing thread. */
#ifdef DBUG
      fprintf(stdout, "creating sockit() thread\n");
#endif
      retcode = pthread_create(&sockitThread, NULL, sockit, "");
      if (retcode != 0) {
         fprintf(stderr, "sockit() thread create failed\n");
      }

      /* Create scheduling thread. */
#ifdef DBUG
      fprintf(stdout, "creating inTraverse() thread\n");
#endif
      retcode = pthread_create(&inTraverseThread, NULL, inTraverse, "");
      if (retcode != 0) {
         fprintf(stderr, "inTraverse() thread create failed\n");
      }

      /* Join scheduling thread. */
#ifdef DBUG
      fprintf(stdout, "joining inTraverse() thread\n");
#endif
      retcode = pthread_join(inTraverseThread, NULL);
      if (retcode != 0) {
         fprintf(stderr, "inTraverse() thread join failed\n");
      }

      /* Join parsing thread. */
#ifdef DBUG
      fprintf(stdout, "joining sockit() thread\n");
#endif
      retcode = pthread_join(sockitThread, NULL);
      if (retcode != 0) {
         fprintf(stderr, "sockit() thread join failed\n");
      }

   }
   else {
      yyparse();
      inTraverse(NULL);
   }

   closesf();

   return 0;
}

<commit_msg>Add cast to last arg of pthread_create calls. Needed for Irix and other Linuces.<commit_after>/* RTcmix  - Copyright (C) 2000  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
#define MAIN
#include <pthread.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream.h>
#include <signal.h>
#ifdef LINUX
   #include <sys/soundcard.h>
#endif
#ifdef SGI
   #include <dmedia/audio.h>
#endif
#include <globals.h>
#include <prototypes.h>
#include <ugens.h>
#include <version.h>
#include "../rtstuff/rt.h"
#include "sockdefs.h"
#include "defs.h"
#include "notetags.h"           // contains defs for note-tagging
#include "../H/dbug.h"

extern "C" {
   int ug_intro();
   void *yyparse();
   int profile();
   void rtprofile();
#ifdef SGI
   void flush_all_underflows_to_zero();
#endif
#ifdef LINUX
   void flush_fpe(int sig);
#endif
}

rt_item *rt_list;     /* can't put this in globals.h because of rt.h trouble */

int interactive;     /* used in y.tab.c - don't remove this! */
Tree program;

#define CMAX 16    /* allow up to 16 command line args to be passed to subs */
char *aargv[CMAX];
char name[NAMESIZE];
int aargc;

/* <yyin> is yacc's input file. If we leave it alone, stdin will be used. */
extern FILE *yyin;

/* --------------------------------------------------------- init_globals --- */
static void
init_globals()
{
   RTBUFSAMPS = 8192;           /* default, modifyable with rtsetparams */
   NCHANS = 2;
   audioNCHANS = 0;

#ifdef LINUX
   for (int i = 0; i < MAXBUS; i++)
      in_port[i] = out_port[i] = 0;
#endif /* LINUX */
#ifdef SGI
   in_port = 0;
   out_port = 0;
#endif /* SGI */

   interactive = 1;
   rtInteractive = 0;
   noParse = 0;
   socknew = 0;
   rtsetparams_called = 0;

   audio_on = 0;
   audio_config = 1;
   play_audio = 1;              /* modified with set_option */
   full_duplex = 0;
   check_peaks = 1;
   report_clipping = 1;

   output_data_format = -1;
   output_header_type = -1;
   normalize_output_floats = 0;
   is_float_format = 0;
   rtoutsfname = NULL;

   tags_on = 0;

   rtfileit = 0;                /* signal writing to soundfile */
   rtoutfile = 0;

   print_is_on = 1;

   Bus_Configed = NO;

   for (int i = 0; i < MAX_INPUT_FDS; i++)
      inputFileTable[i].fd = NO_FD;

   init_buf_ptrs();
}

/* ------------------------------------------------------- signal_handler --- */
static void
signal_handler(int signo)
{
#ifdef DBUG
   printf("Signal handler called (signo %d)\n", signo);
#endif

   if (rtsetparams_called) {
      close_audio_ports();
      rtreportstats();
      rtcloseout();
   }
   else
      closesf();

   exit(1);
}

/* ----------------------------------------------------------------- main --- */
int
main(int argc, char *argv[])
{
   int         i, j;
   int         retcode;                 /* for mutexes */
   char        *cp, *infile;
   pthread_t   sockitThread, inTraverseThread;

   init_globals();

#ifdef LINUX
   signal(SIGFPE, flush_fpe);          /* Install signal handler */
#endif
#ifdef SGI
   flush_all_underflows_to_zero();
#endif

   /* Call signal_handler on cntl-C. */
   if (signal(SIGINT, signal_handler) == SIG_ERR) {
      fprintf(stderr, "Error installing signal handler.\n");
      exit(1);
   }

   /* Copy command-line args, if any.
      Now, command-line args will be available to any subroutine
      in aargc; and char *aargv[], (both declared extern in ugens.h)
      parsing is exactly the same then as standard C routine.
      Maximum of CMAX arguments allowed.
   */
   for (j = 1; j < argc; j++)
      aargv[j - 1] = argv[j];
   aargc = argc;

   /* Banner */
   printf("--------> %s %s (%s) <--------\n",
                                      RTCMIX_NAME, RTCMIX_VERSION, argv[0]);

   /* Process command line. */
   if (argc >= 2) {
      while ((*++argv)[0] == '-') {
         argc -= 1;             /* Take away two args */
         for (cp = argv[0] + 1; *cp; cp++) {
            switch (*cp) {      /* Grap options */
               case 'i':               /* for separate parseit thread */
                  rtInteractive = 1;
                  audio_config = 0;
                  break;
               case 'n':               /* for separate parseit thread */
                  noParse = 1;
                  break;
               case 's':               /* set up a socket offset */
                  socknew = atoi(*++argv);
                  fprintf(stderr, "listening on socket: %d\n",
                                                         MYPORT + socknew);
                  argc -= 1;
                  break;
               case 'c':     /* set up for continuous control (note tags on) */
                  tags_on = 1;
                  printf("rtupdates enabled\n");
                  curtag = 1;          /* "0" is reserved for all notes */
                  for (i = 0; i < MAXPUPS; i++)     /* initialize element 0 */
                     pupdatevals[0][i] = NOPUPDATE;
                  break;
               case 'f':     /* use file name arg instead of stdin as score */
                  infile = *++argv;
                  yyin = fopen(infile, "r+");
                  if (yyin == NULL) {
                     printf("Can't open %s\n", infile);
                     exit(1);
                  }
                  fprintf(stderr, "Using file %s\n", infile);
                  argc -= 1;
                  break;
               default:
                  printf("Don't know about option '%c'\n", *cp);
            }
         }
         if (argc == 1)
            break;
      }
   }

   ug_intro();                  /* introduce standard routines */
   profile();                   /* introduce user-written routines etc. */
   rtprofile();                 /* introduce real-time user-written routines */

   setbuf(stdout, NULL);        /*  Want to see stdout errors */

   /* In rtInteractive mode, we set up RTcmix to listen for score data
      over a socket, and then parse this, schedule instruments, and play
      them concurrently. The socket listening and parsing go in one
      thread, and the scheduler and instrument code go in another.

      When not in rtInteractive mode, RTcmix parses the score, schedules
      all instruments, and then plays them -- in that order. No threads.
   */
   if (rtInteractive) {

      fprintf(stdout, "rtInteractive mode set\n");

      /* Read an initialization score. */
      if (!noParse) {
         cout << "Parsing once ...\n";
         yyparse();
      }

      /* Create parsing thread. */
#ifdef DBUG
      fprintf(stdout, "creating sockit() thread\n");
#endif
      retcode = pthread_create(&sockitThread, NULL, sockit, (void *) "");
      if (retcode != 0) {
         fprintf(stderr, "sockit() thread create failed\n");
      }

      /* Create scheduling thread. */
#ifdef DBUG
      fprintf(stdout, "creating inTraverse() thread\n");
#endif
      retcode = pthread_create(&inTraverseThread, NULL, inTraverse,
                                                             (void *) "");
      if (retcode != 0) {
         fprintf(stderr, "inTraverse() thread create failed\n");
      }

      /* Join scheduling thread. */
#ifdef DBUG
      fprintf(stdout, "joining inTraverse() thread\n");
#endif
      retcode = pthread_join(inTraverseThread, NULL);
      if (retcode != 0) {
         fprintf(stderr, "inTraverse() thread join failed\n");
      }

      /* Join parsing thread. */
#ifdef DBUG
      fprintf(stdout, "joining sockit() thread\n");
#endif
      retcode = pthread_join(sockitThread, NULL);
      if (retcode != 0) {
         fprintf(stderr, "sockit() thread join failed\n");
      }

   }
   else {
      yyparse();
      inTraverse(NULL);
   }

   closesf();

   return 0;
}

<|endoftext|>


<commit_before>#include <sirius.h>

using namespace sirius;

void test_wf_ortho(std::vector<int> mpi_grid_dims__,
                   double cutoff__,
                   int num_bands__,
                   int use_gpu__,
                   int bs__)
{
    device_t pu = static_cast<device_t>(use_gpu__);

    BLACS_grid blacs_grid(mpi_comm_world(), mpi_grid_dims__[0], mpi_grid_dims__[1]);

    matrix3d<double> M = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};

    /* create FFT box */
    FFT3D_grid fft_box(Utils::find_translations(2.01 * cutoff__, M));
    /* create G-vectors */
    Gvec gvec(vector3d<double>(0, 0, 0), M, cutoff__, fft_box, mpi_comm_world().size(), mpi_comm_world(), false);

    if (mpi_comm_world().rank() == 0) {
        printf("total number of G-vectors: %i\n", gvec.num_gvec());
        printf("local number of G-vectors: %i\n", gvec.gvec_count(0));
        printf("FFT grid size: %i %i %i\n", fft_box.size(0), fft_box.size(1), fft_box.size(2));
    }

    wave_functions phi(pu, mpi_comm_world(), gvec, 2 * num_bands__);
    wave_functions hphi(pu, mpi_comm_world(), gvec, 2 * num_bands__);
    wave_functions ophi(pu, mpi_comm_world(), gvec, 2 * num_bands__);
    wave_functions tmp(pu, mpi_comm_world(), gvec, 2 * num_bands__);
    tmp.pw_coeffs().prime().zero();

    for (int i = 0; i < 2 * num_bands__; i++) {
        for (int j = 0; j < phi.pw_coeffs().num_rows_loc(); j++) {
            phi.pw_coeffs().prime(j, i) = type_wrapper<double_complex>::random();
            hphi.pw_coeffs().prime(j, i) = phi.pw_coeffs().prime(j, i) * double(i + 1);
            ophi.pw_coeffs().prime(j, i) = phi.pw_coeffs().prime(j, i);
        }
    }
    dmatrix<double_complex> ovlp(2 * num_bands__, 2 * num_bands__, blacs_grid, bs__, bs__);

    #ifdef __GPU
    if (pu == GPU) {
        phi.allocate_on_device();
        phi.copy_to_device(0, 2 * num_bands__);

        hphi.allocate_on_device();
        hphi.copy_to_device(0, 2 * num_bands__);

        ophi.allocate_on_device();
        ophi.copy_to_device(0, 2 * num_bands__);

        tmp.allocate_on_device();

        if (mpi_comm_world().size() == 1) {
            ovlp.allocate(memory_t::device);
        }
    }
    #endif

    mpi_comm_world().barrier();
    sddk::timer t1("ortho");
    orthogonalize<double_complex>(0, num_bands__, phi, hphi, ophi, ovlp, tmp);
    orthogonalize<double_complex>(num_bands__, num_bands__, phi, hphi, ophi, ovlp, tmp);
    mpi_comm_world().barrier();
    double tval = t1.stop();

    int k = gvec.num_gvec();

    // one inner product
    long double flop1 = 8.0 * num_bands__ * num_bands__ * k;
    // one Cholesky + one inversion, inversion cost is half-Cholesky
    long double flop2 = 1.5 * (8.0 / 3) * num_bands__ * num_bands__ * num_bands__;
    // three transformations
    long double flop3 = 3.0 * 8.0 * num_bands__ * k * num_bands__;

    long double num_gflop = 1e-9 * (flop1 + flop3 + 2.0 * (flop1 + flop2 + flop3));

    if (mpi_comm_world().rank() == 0) {
        printf("total performance            : %18.6Lf GFlop/s\n", num_gflop / tval);
        printf("average MPI rank performance : %18.6Lf GFlop/s\n", num_gflop / tval / mpi_comm_world().size());
    }

    inner(phi, 0, 2 * num_bands__, ophi, 0, 2 * num_bands__, ovlp, 0, 0);

    for (int j = 0; j < ovlp.num_cols_local(); j++) {
        for (int i = 0; i < ovlp.num_rows_local(); i++) {
            double_complex z = (ovlp.irow(i) == ovlp.icol(j)) ? ovlp(i, j) - 1.0 : ovlp(i, j);
            if (std::abs(z) > 1e-12) {
                TERMINATE("wrong overlap");
            }
        }
    }
}

int main(int argn, char** argv)
{
    cmd_args args;
    args.register_key("--mpi_grid_dims=", "{int int} dimensions of MPI grid");
    args.register_key("--cutoff=", "{double} wave-functions cutoff");
    args.register_key("--num_bands=", "{int} number of bands");
    args.register_key("--bs=", "{int} block size");
    args.register_key("--use_gpu=", "{int} 0: CPU only, 1: hybrid CPU+GPU");
    args.register_key("--repeat=", "{int} number of repeats");

    args.parse_args(argn, argv);
    if (args.exist("help")) {
        printf("Usage: %s [options]\n", argv[0]);
        args.print_help();
        return 0;
    }
    auto mpi_grid_dims = args.value< std::vector<int> >("mpi_grid_dims", {1, 1});
    auto cutoff = args.value<double>("cutoff", 2.0);
    auto num_bands = args.value<int>("num_bands", 10);
    auto use_gpu = args.value<int>("use_gpu", 0);
    auto repeat = args.value<int>("repeat", 1);
    auto bs = args.value<int>("bs", 16);

    sirius::initialize(1);
    for (int i = 0; i < repeat; i++) {
        test_wf_ortho(mpi_grid_dims, cutoff, num_bands, use_gpu, bs);
    }
    mpi_comm_world().barrier();
    sddk::timer::print();
    //sddk::timer::print_all();
    sirius::finalize();
}
<commit_msg>write mpi grid info<commit_after>#include <sirius.h>

using namespace sirius;

void test_wf_ortho(std::vector<int> mpi_grid_dims__,
                   double cutoff__,
                   int num_bands__,
                   int use_gpu__,
                   int bs__)
{
    device_t pu = static_cast<device_t>(use_gpu__);

    BLACS_grid blacs_grid(mpi_comm_world(), mpi_grid_dims__[0], mpi_grid_dims__[1]);

    matrix3d<double> M = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};

    /* create FFT box */
    FFT3D_grid fft_box(Utils::find_translations(2.01 * cutoff__, M));
    /* create G-vectors */
    Gvec gvec(vector3d<double>(0, 0, 0), M, cutoff__, fft_box, mpi_comm_world().size(), mpi_comm_world(), false);

    if (mpi_comm_world().rank() == 0) {
        printf("total number of G-vectors: %i\n", gvec.num_gvec());
        printf("local number of G-vectors: %i\n", gvec.gvec_count(0));
        printf("FFT grid size: %i %i %i\n", fft_box.size(0), fft_box.size(1), fft_box.size(2));
    }

    wave_functions phi(pu, mpi_comm_world(), gvec, 2 * num_bands__);
    wave_functions hphi(pu, mpi_comm_world(), gvec, 2 * num_bands__);
    wave_functions ophi(pu, mpi_comm_world(), gvec, 2 * num_bands__);
    wave_functions tmp(pu, mpi_comm_world(), gvec, 2 * num_bands__);
    tmp.pw_coeffs().prime().zero();

    for (int i = 0; i < 2 * num_bands__; i++) {
        for (int j = 0; j < phi.pw_coeffs().num_rows_loc(); j++) {
            phi.pw_coeffs().prime(j, i) = type_wrapper<double_complex>::random();
            hphi.pw_coeffs().prime(j, i) = phi.pw_coeffs().prime(j, i) * double(i + 1);
            ophi.pw_coeffs().prime(j, i) = phi.pw_coeffs().prime(j, i);
        }
    }
    dmatrix<double_complex> ovlp(2 * num_bands__, 2 * num_bands__, blacs_grid, bs__, bs__);

    #ifdef __GPU
    if (pu == GPU) {
        phi.allocate_on_device();
        phi.copy_to_device(0, 2 * num_bands__);

        hphi.allocate_on_device();
        hphi.copy_to_device(0, 2 * num_bands__);

        ophi.allocate_on_device();
        ophi.copy_to_device(0, 2 * num_bands__);

        tmp.allocate_on_device();

        if (mpi_comm_world().size() == 1) {
            ovlp.allocate(memory_t::device);
        }
    }
    #endif

    mpi_comm_world().barrier();
    sddk::timer t1("ortho");
    orthogonalize<double_complex>(0, num_bands__, phi, hphi, ophi, ovlp, tmp);
    orthogonalize<double_complex>(num_bands__, num_bands__, phi, hphi, ophi, ovlp, tmp);
    mpi_comm_world().barrier();
    double tval = t1.stop();

    int k = gvec.num_gvec();

    // one inner product
    long double flop1 = 8.0 * num_bands__ * num_bands__ * k;
    // one Cholesky + one inversion, inversion cost is half-Cholesky
    long double flop2 = 1.5 * (8.0 / 3) * num_bands__ * num_bands__ * num_bands__;
    // three transformations
    long double flop3 = 3.0 * 8.0 * num_bands__ * k * num_bands__;

    long double num_gflop = 1e-9 * (flop1 + flop3 + 2.0 * (flop1 + flop2 + flop3));

    if (mpi_comm_world().rank() == 0) {
        printf("total performance            : %18.6Lf GFlop/s\n", num_gflop / tval);
        printf("average MPI rank performance : %18.6Lf GFlop/s\n", num_gflop / tval / mpi_comm_world().size());
    }

    inner(phi, 0, 2 * num_bands__, ophi, 0, 2 * num_bands__, ovlp, 0, 0);

    for (int j = 0; j < ovlp.num_cols_local(); j++) {
        for (int i = 0; i < ovlp.num_rows_local(); i++) {
            double_complex z = (ovlp.irow(i) == ovlp.icol(j)) ? ovlp(i, j) - 1.0 : ovlp(i, j);
            if (std::abs(z) > 1e-12) {
                TERMINATE("wrong overlap");
            }
        }
    }
}

int main(int argn, char** argv)
{
    cmd_args args;
    args.register_key("--mpi_grid_dims=", "{int int} dimensions of MPI grid");
    args.register_key("--cutoff=", "{double} wave-functions cutoff");
    args.register_key("--num_bands=", "{int} number of bands");
    args.register_key("--bs=", "{int} block size");
    args.register_key("--use_gpu=", "{int} 0: CPU only, 1: hybrid CPU+GPU");
    args.register_key("--repeat=", "{int} number of repeats");

    args.parse_args(argn, argv);
    if (args.exist("help")) {
        printf("Usage: %s [options]\n", argv[0]);
        args.print_help();
        return 0;
    }
    auto mpi_grid_dims = args.value< std::vector<int> >("mpi_grid_dims", {1, 1});
    auto cutoff = args.value<double>("cutoff", 2.0);
    auto num_bands = args.value<int>("num_bands", 10);
    auto use_gpu = args.value<int>("use_gpu", 0);
    auto repeat = args.value<int>("repeat", 1);
    auto bs = args.value<int>("bs", 16);

    sirius::initialize(1);
    if (mpi_comm_world().rank() == 0) {
        printf("Running on %i x %i MPI grid\n", mpi_grid_dims[0], mpi_grid_dims[1]);
    }
    for (int i = 0; i < repeat; i++) {
        test_wf_ortho(mpi_grid_dims, cutoff, num_bands, use_gpu, bs);
    }
    mpi_comm_world().barrier();
    sddk::timer::print();
    //sddk::timer::print_all();
    sirius::finalize();
}
<|endoftext|>