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

/* $Id$ */

//-------------------------------------------------------------------------
//     AOD class for jets
//     Author: Andreas Morsch, CERN
//-------------------------------------------------------------------------

#include <TLorentzVector.h>
#include "AliAODJet.h"

ClassImp(AliAODJet)

//______________________________________________________________________________
AliAODJet::AliAODJet() :
    AliVParticle(),
    fNeutralFraction(0),
    fTrigger(0),
    fMomentum(0),
    fVectorAreaCharged(0),
    fRefTracks(new TRefArray())
{
  // constructor
    fBackgEnergy[0]   = 0.;
    fBackgEnergy[1]   = 0.;
    fEffectiveArea[0] = 0.;
    fEffectiveArea[1] = 0.;
    fEffectiveAreaError[0] = fEffectiveAreaError[1] = 0;
}

AliAODJet::AliAODJet(Double_t px, Double_t py, Double_t pz, Double_t e):
    AliVParticle(),
    fNeutralFraction(0),
    fTrigger(0),
    fMomentum(0),
    fVectorAreaCharged(0),
    fRefTracks(new TRefArray())
{
  // constructor
    fBackgEnergy[0]   = 0.;
    fBackgEnergy[1]   = 0.;
    fEffectiveArea[0] = 0.;
    fEffectiveArea[1] = 0.;
    fEffectiveAreaError[0] = fEffectiveAreaError[1] = 0;
    fMomentum = new TLorentzVector(px, py, pz, e);
}

AliAODJet::AliAODJet(TLorentzVector & p):
    AliVParticle(),
    fNeutralFraction(0),
    fTrigger(0),
    fMomentum(0),
    fVectorAreaCharged(0),
    fRefTracks(new TRefArray())
{
  // constructor
    fBackgEnergy[0]   = 0.;
    fBackgEnergy[1]   = 0.;
    fEffectiveArea[0] = 0.;
    fEffectiveArea[1] = 0.;
    fEffectiveAreaError[0] = fEffectiveAreaError[1] = 0;
    fMomentum = new TLorentzVector(p);
}

//______________________________________________________________________________
AliAODJet::~AliAODJet()
{
  // destructor
    delete fMomentum;
    delete fVectorAreaCharged;
    delete fRefTracks;
}

//______________________________________________________________________________
AliAODJet::AliAODJet(const AliAODJet& jet) :
    AliVParticle(jet),
    fNeutralFraction(jet.fNeutralFraction),
    fTrigger(jet.fTrigger),
    fMomentum(0),
    fVectorAreaCharged(0),
    fRefTracks(0)
{
  // Copy constructor
    fBackgEnergy[0]   = jet.fBackgEnergy[0];
    fBackgEnergy[1]   = jet.fBackgEnergy[1];
    fEffectiveArea[0] = jet.fEffectiveArea[0];
    fEffectiveArea[1] = jet.fEffectiveArea[1];
    fEffectiveAreaError[0] = jet.fEffectiveAreaError[0];
    fEffectiveAreaError[1] = jet.fEffectiveAreaError[1];
    fMomentum  = new TLorentzVector(*jet.fMomentum);
    fVectorAreaCharged = new TLorentzVector(*jet.fVectorAreaCharged);
    fRefTracks = new TRefArray(*jet.fRefTracks);
}

//______________________________________________________________________________
AliAODJet& AliAODJet::operator=(const AliAODJet& jet)
{
  // Assignment operator
  if(this!=&jet) {

    fBackgEnergy[0]   = jet.fBackgEnergy[0];
    fBackgEnergy[1]   = jet.fBackgEnergy[1];
    fEffectiveArea[0] = jet.fEffectiveArea[0];
    fEffectiveArea[1] = jet.fEffectiveArea[1];
    fEffectiveAreaError[0] = jet.fEffectiveAreaError[0];
    fEffectiveAreaError[1] = jet.fEffectiveAreaError[1];
    fNeutralFraction = jet.fNeutralFraction;
    fTrigger = jet.fTrigger;
    *fMomentum  = *jet.fMomentum;
    *fVectorAreaCharged = *jet.fVectorAreaCharged;
    delete fRefTracks;
    fRefTracks = new TRefArray(*jet.fRefTracks);
  }

  return *this;
}

void AliAODJet::Print(Option_t* /*option*/) const
{
  // Print information of all data members
  printf("Jet 4-vector:\n");
  printf("     E  = %13.3f\n", E() );
  printf("     Px = %13.3f\n", Px());
  printf("     Py = %13.3f\n", Py());
  printf("     Pz = %13.3f\n", Pz());
  printf("Background Energy:\n");
  printf("Charged:  %13.3f\n", ChargedBgEnergy());
  printf("Neutral:  %13.3f\n", NeutralBgEnergy());
  printf("Total:    %13.3f\n", TotalBgEnergy());
  printf("Effective Area: \n");
  printf("Charged:  %13.3f\n", EffectiveAreaCharged());
  printf("Neutral:  %13.3f\n", EffectiveAreaNeutral());
}

void  AliAODJet::SetPxPyPzE(Double_t px, Double_t py, Double_t pz, Double_t e){
  //
  // Set the four Momentum from outside
  // MomentumVector()->SetPxPyPzE() cannot be used since pointer can be 0x0
  //

  if(!fMomentum){
    fMomentum = new TLorentzVector(px,py,pz,e);
  }
  else{
    fMomentum->SetPxPyPzE(px,py,pz,e);
  }
}

Double_t AliAODJet::DeltaR(const AliVParticle* part){

  // Helper function to calculate the distance between two jets
  // or a jet and particle

  Double_t dPhi = Phi() - part->Phi();
  if(dPhi>TMath::Pi())dPhi = dPhi - 2.*TMath::Pi();
  if(dPhi<(-1.*TMath::Pi()))dPhi = dPhi + 2.*TMath::Pi();
  Double_t dEta = Eta() - part->Eta();
  Double_t dR = TMath::Sqrt(dPhi*dPhi+dEta*dEta);
  return dR;
}

void  AliAODJet::AddTrack(TObject *tr) {
    // Add a track to the list of referenced tracks
    if (fRefTracks->GetEntries() == 0) {
	new(fRefTracks) TRefArray(TProcessID::GetProcessWithUID(tr));
    }

    fRefTracks->Add(tr);
}

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

/* $Id$ */

//-------------------------------------------------------------------------
//     AOD class for jets
//     Author: Andreas Morsch, CERN
//-------------------------------------------------------------------------

#include <TLorentzVector.h>
#include "AliAODJet.h"

ClassImp(AliAODJet)

//______________________________________________________________________________
AliAODJet::AliAODJet() :
    AliVParticle(),
    fNeutralFraction(0),
    fTrigger(0),
    fMomentum(0),
    fVectorAreaCharged(0),
    fRefTracks(new TRefArray())
{
  // constructor
    fBackgEnergy[0]   = 0.;
    fBackgEnergy[1]   = 0.;
    fEffectiveArea[0] = 0.;
    fEffectiveArea[1] = 0.;
    fEffectiveAreaError[0] = fEffectiveAreaError[1] = 0;
}

AliAODJet::AliAODJet(Double_t px, Double_t py, Double_t pz, Double_t e):
    AliVParticle(),
    fNeutralFraction(0),
    fTrigger(0),
    fMomentum(0),
    fVectorAreaCharged(0),
    fRefTracks(new TRefArray())
{
  // constructor
    fBackgEnergy[0]   = 0.;
    fBackgEnergy[1]   = 0.;
    fEffectiveArea[0] = 0.;
    fEffectiveArea[1] = 0.;
    fEffectiveAreaError[0] = fEffectiveAreaError[1] = 0;
    fMomentum = new TLorentzVector(px, py, pz, e);
}

AliAODJet::AliAODJet(TLorentzVector & p):
    AliVParticle(),
    fNeutralFraction(0),
    fTrigger(0),
    fMomentum(0),
    fVectorAreaCharged(0),
    fRefTracks(new TRefArray())
{
  // constructor
    fBackgEnergy[0]   = 0.;
    fBackgEnergy[1]   = 0.;
    fEffectiveArea[0] = 0.;
    fEffectiveArea[1] = 0.;
    fEffectiveAreaError[0] = fEffectiveAreaError[1] = 0;
    fMomentum = new TLorentzVector(p);
}

//______________________________________________________________________________
AliAODJet::~AliAODJet()
{
  // destructor
    delete fMomentum;
    delete fVectorAreaCharged;
    delete fRefTracks;
}

//______________________________________________________________________________
AliAODJet::AliAODJet(const AliAODJet& jet) :
    AliVParticle(jet),
    fNeutralFraction(jet.fNeutralFraction),
    fTrigger(jet.fTrigger),
    fMomentum(0),
    fVectorAreaCharged(0),
    fRefTracks(0)
{
  // Copy constructor
    fBackgEnergy[0]   = jet.fBackgEnergy[0];
    fBackgEnergy[1]   = jet.fBackgEnergy[1];
    fEffectiveArea[0] = jet.fEffectiveArea[0];
    fEffectiveArea[1] = jet.fEffectiveArea[1];
    fEffectiveAreaError[0] = jet.fEffectiveAreaError[0];
    fEffectiveAreaError[1] = jet.fEffectiveAreaError[1];
    if(jet.fMomentum)fMomentum  = new TLorentzVector(*jet.fMomentum);
    if(jet.fVectorAreaCharged)fVectorAreaCharged = new TLorentzVector(*jet.fVectorAreaCharged);
    fRefTracks = new TRefArray(*jet.fRefTracks);
}

//______________________________________________________________________________
AliAODJet& AliAODJet::operator=(const AliAODJet& jet)
{
  // Assignment operator
  if(this!=&jet) {

    fBackgEnergy[0]   = jet.fBackgEnergy[0];
    fBackgEnergy[1]   = jet.fBackgEnergy[1];
    fEffectiveArea[0] = jet.fEffectiveArea[0];
    fEffectiveArea[1] = jet.fEffectiveArea[1];
    fEffectiveAreaError[0] = jet.fEffectiveAreaError[0];
    fEffectiveAreaError[1] = jet.fEffectiveAreaError[1];
    fNeutralFraction = jet.fNeutralFraction;
    fTrigger = jet.fTrigger;

    if(jet.fMomentum){
      if(fMomentum)*fMomentum  = *jet.fMomentum;
      else fMomentum  = new TLorentzVector(*jet.fMomentum);
    }

    if(jet.fVectorAreaCharged){
	if(fVectorAreaCharged)*fVectorAreaCharged = *jet.fVectorAreaCharged;
	else fVectorAreaCharged = new TLorentzVector(*jet.fVectorAreaCharged);
      }
    delete fRefTracks;
    fRefTracks = new TRefArray(*jet.fRefTracks);
  }

  return *this;
}

void AliAODJet::Print(Option_t* /*option*/) const
{
  // Print information of all data members
  printf("Jet 4-vector:\n");
  printf("     E  = %13.3f\n", E() );
  printf("     Px = %13.3f\n", Px());
  printf("     Py = %13.3f\n", Py());
  printf("     Pz = %13.3f\n", Pz());
  printf("Background Energy:\n");
  printf("Charged:  %13.3f\n", ChargedBgEnergy());
  printf("Neutral:  %13.3f\n", NeutralBgEnergy());
  printf("Total:    %13.3f\n", TotalBgEnergy());
  printf("Effective Area: \n");
  printf("Charged:  %13.3f\n", EffectiveAreaCharged());
  printf("Neutral:  %13.3f\n", EffectiveAreaNeutral());
}

void  AliAODJet::SetPxPyPzE(Double_t px, Double_t py, Double_t pz, Double_t e){
  //
  // Set the four Momentum from outside
  // MomentumVector()->SetPxPyPzE() cannot be used since pointer can be 0x0
  //

  if(!fMomentum){
    fMomentum = new TLorentzVector(px,py,pz,e);
  }
  else{
    fMomentum->SetPxPyPzE(px,py,pz,e);
  }
}

Double_t AliAODJet::DeltaR(const AliVParticle* part){

  // Helper function to calculate the distance between two jets
  // or a jet and particle

  Double_t dPhi = Phi() - part->Phi();
  if(dPhi>TMath::Pi())dPhi = dPhi - 2.*TMath::Pi();
  if(dPhi<(-1.*TMath::Pi()))dPhi = dPhi + 2.*TMath::Pi();
  Double_t dEta = Eta() - part->Eta();
  Double_t dR = TMath::Sqrt(dPhi*dPhi+dEta*dEta);
  return dR;
}

void  AliAODJet::AddTrack(TObject *tr) {
    // Add a track to the list of referenced tracks
    if (fRefTracks->GetEntries() == 0) {
	new(fRefTracks) TRefArray(TProcessID::GetProcessWithUID(tr));
    }

    fRefTracks->Add(tr);
}

<|endoftext|>


<commit_before>#include <MinConsole.hpp>
#include <Windows.h>
#include <mutex>

namespace MinConsole
{
void* GetOutputHandle()
{
	static void* Handle = nullptr;
	std::once_flag HandleCached;
	std::call_once(HandleCached, []()
		{
			Handle = GetStdHandle(STD_OUTPUT_HANDLE);
		});
	return Handle;
}

void SetTextColor(Color NewColor)
{
	SetConsoleTextAttribute(
		GetOutputHandle(),
		static_cast<std::underlying_type_t<MinConsole::Color>>(NewColor)
	);
}

std::size_t GetWidth()
{
	CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
	if( GetConsoleScreenBufferInfo(
		GetOutputHandle(),
		&ConsoleInfo) )
	{
		return static_cast<size_t>(ConsoleInfo.dwSize.X);
	}
	return 0;
}
}
<commit_msg>Add explicit lambda attritubes<commit_after>#include <MinConsole.hpp>
#include <Windows.h>
#include <mutex>

namespace MinConsole
{
void* GetOutputHandle()
{
	static void* Handle = nullptr;
	std::once_flag HandleCached;
	std::call_once(HandleCached, []() noexcept -> void
		{
			Handle = GetStdHandle(STD_OUTPUT_HANDLE);
		});
	return Handle;
}

void SetTextColor(Color NewColor)
{
	SetConsoleTextAttribute(
		GetOutputHandle(),
		static_cast<std::underlying_type_t<MinConsole::Color>>(NewColor)
	);
}

std::size_t GetWidth()
{
	CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
	if( GetConsoleScreenBufferInfo(
		GetOutputHandle(),
		&ConsoleInfo) )
	{
		return static_cast<size_t>(ConsoleInfo.dwSize.X);
	}
	return 0;
}
}
<|endoftext|>


<commit_before>// @(#)root/rint:$Name:  $:$Id: TRint.cxx,v 1.46 2005/06/06 12:47:49 pcanal Exp $
// Author: Rene Brun   17/02/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// Rint                                                                 //
//                                                                      //
// Rint is the ROOT Interactive Interface. It allows interactive access //
// to the ROOT system via the CINT C/C++ interpreter.                   //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TROOT.h"
#include "TClass.h"
#include "TVirtualX.h"
#include "Getline.h"
#include "TStyle.h"
#include "TObjectTable.h"
#include "TClassTable.h"
#include "TStopwatch.h"
#include "TBenchmark.h"
#include "TRint.h"
#include "TSystem.h"
#include "TEnv.h"
#include "TSysEvtHandler.h"
#include "TError.h"
#include "TException.h"
#include "TInterpreter.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TFile.h"
#include "TMapFile.h"
#include "TTabCom.h"
#include "TError.h"

#ifdef R__UNIX
#include <signal.h>

extern "C" {
   extern int G__get_security_error();
   extern int G__genericerror(const char* msg);
}
#endif

static Int_t key_pressed(Int_t key) { gApplication->KeyPressed(key); return 0; }

//----- Interrupt signal handler -----------------------------------------------
//______________________________________________________________________________
class TInterruptHandler : public TSignalHandler {
public:
   TInterruptHandler() : TSignalHandler(kSigInterrupt, kFALSE) { }
   Bool_t  Notify();
};

//______________________________________________________________________________
Bool_t TInterruptHandler::Notify()
{
   // TRint interrupt handler.

   if (fDelay) {
      fDelay++;
      return kTRUE;
   }

   // make sure we use the sbrk heap (in case of mapped files)
   gMmallocDesc = 0;

   if (!G__get_security_error())
      G__genericerror("\n *** Break *** keyboard interrupt");
   else {
      Break("TInterruptHandler::Notify", "keyboard interrupt");
      if (TROOT::Initialized()) {
         Getlinem(kInit, "Root > ");
         gInterpreter->RewindDictionary();
         Throw(GetSignal());
      }
   }
   return kTRUE;
}

//----- Terminal Input file handler --------------------------------------------
//______________________________________________________________________________
class TTermInputHandler : public TFileHandler {
public:
   TTermInputHandler(Int_t fd) : TFileHandler(fd, 1) { }
   Bool_t Notify();
   Bool_t ReadNotify() { return Notify(); }
};

//______________________________________________________________________________
Bool_t TTermInputHandler::Notify()
{
   return gApplication->HandleTermInput();
}

ClassImp(TRint)

//______________________________________________________________________________
TRint::TRint(const char *appClassName, Int_t *argc, char **argv, void *options,
             Int_t numOptions, Bool_t noLogo)
       : TApplication(appClassName, argc, argv, options, numOptions)
{
   // Create an application environment. The TRint environment provides an
   // interface to the WM manager functionality and eventloop via inheritance
   // of TApplication and in addition provides interactive access to
   // the CINT C++ interpreter via the command line.

   fNcmd          = 0;
   fDefaultPrompt = "root [%d] ";
   fInterrupt     = kFALSE;

   gBenchmark = new TBenchmark();

   if (!noLogo && !NoLogoOpt())
      PrintLogo();

   // Everybody expects iostream to be available, so load it...
   ProcessLine("#include <iostream>", kTRUE);
   ProcessLine("#include <_string>", kTRUE); // for std::string iostream.
   ProcessLine("#include <vector>", kTRUE);  // Needed because std::vector and std::pair are
   ProcessLine("#include <pair>", kTRUE);    //   used within the core ROOT dictionaries
                                             //   and CINT will not be able to properly unload these files

   // Allow the usage of ClassDef and ClassImp in interpreted macros
   ProcessLine("#include <RtypesCint.h>", kTRUE);

   // Disallow the interpretation of Rtypes.h, TError.h and TGenericClassInfo.h
   ProcessLine("#define ROOT_Rtypes 0", kTRUE);
   ProcessLine("#define ROOT_TError 0", kTRUE);
   ProcessLine("#define ROOT_TGenericClassInfo 0", kTRUE);

   // The following libs are also useful to have, make sure they are loaded...
   gROOT->LoadClass("TMinuit",     "Minuit");
   gROOT->LoadClass("TPostScript", "Postscript");
   gROOT->LoadClass("THtml",       "Html");

   // Load user functions
   const char *logon;
   logon = gEnv->GetValue("Rint.Load", (char*)0);
   if (logon) {
      char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
      if (mac)
         ProcessLine(Form(".L %s",logon),kTRUE);
      delete [] mac;
   }

   // Execute logon macro
   logon = gEnv->GetValue("Rint.Logon", (char*)0);
   if (logon && !NoLogOpt()) {
      char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
      if (mac)
         ProcessFile(logon);
      delete [] mac;
   }

   // Save current interpreter context
   gInterpreter->SaveContext();
   gInterpreter->SaveGlobalsContext();

   // Install interrupt and terminal input handlers
   TInterruptHandler *ih = new TInterruptHandler();
   ih->Add();
   SetSignalHandler(ih);

   // Handle stdin events
   fInputHandler = new TTermInputHandler(0);
   fInputHandler->Add();

   // Goto into raw terminal input mode
   char defhist[128];
#ifndef R__VMS
   sprintf(defhist, "%s/.root_hist", gSystem->Getenv("HOME"));
#else
   sprintf(defhist, "%s.root_hist", gSystem->Getenv("HOME"));
#endif
   logon = gEnv->GetValue("Rint.History", defhist);
   Gl_histinit((char *)logon);
   Gl_windowchanged();

   // Setup for tab completion
   gTabCom = new TTabCom;
   Gl_in_key = &key_pressed;
}

//______________________________________________________________________________
TRint::~TRint()
{

}

//______________________________________________________________________________
void TRint::Run(Bool_t retrn)
{
   // Main application eventloop. First process files given on the command
   // line and then go into the main application event loop, unless the -q
   // command line option was specfied in which case the program terminates.
   // When retrun is true this method returns even when -q was specified.
   //
   // When QuitOpt is true and retrn is false, terminate the application with
   // an error code equal to either the ProcessLine error (if any) or the
   // return value of the command casted to a long.

   Getlinem(kInit, GetPrompt());

   Long_t retval = 0;
   Int_t  error = 0;

   // Process shell command line input files
   if (InputFiles()) {
      Bool_t needGetlinemInit = kFALSE;
      TIter next(InputFiles());
      RETRY {
         retval = 0; error = 0;
         Int_t nfile = 0;
         TObjString *file;
         while ((file = (TObjString *)next())) {
            char cmd[256];
            if (!fNcmd)
               printf("\n");
            if (file->String().EndsWith(".root")) {
               file->String().ReplaceAll("\\","/");
               const char *rfile = (const char*)file->String();
               Printf("Attaching file %s as _file%d...", rfile, nfile);
               sprintf(cmd, "TFile *_file%d = TFile::Open(\"%s\")", nfile++, rfile);
            } else {
               Printf("Processing %s...", (const char*)file->String());
               sprintf(cmd, ".x %s", (const char*)file->String());
            }
            Getlinem(kCleanUp, 0);
            Gl_histadd(cmd);
            fNcmd++;

            // The ProcessLine might throw an 'exception'.  In this case,
            // GetLinem(kInit,"Root >") is called and we are jump back
            // to RETRY ... and we have to avoid the Getlinem(kInit, GetPrompt());
            needGetlinemInit = kFALSE;
            retval = ProcessLine(cmd, kFALSE, &error);
	    gInterpreter->EndOfLineAction();

            // The ProcessLine has successfully completed and we need
            // to call Getlinem(kInit, GetPrompt());
            needGetlinemInit = kTRUE;

            if (error != 0) break;
         }
      } ENDTRY;

      if (QuitOpt()) {
         if (retrn) return;
         Terminate(error == 0 ? retval : error);
      }

      ClearInputFiles();

      if (needGetlinemInit) Getlinem(kInit, GetPrompt());
   }

   if (QuitOpt()) {
      printf("\n");
      if (retrn) return;
      Terminate(0);
   }

   TApplication::Run(retrn);

   Getlinem(kCleanUp, 0);
}

//______________________________________________________________________________
void TRint::PrintLogo()
{
   // Print the ROOT logo on standard output.

   Int_t iday,imonth,iyear;
   static const char *months[] = {"January","February","March","April","May",
                                  "June","July","August","September","October",
                                  "November","December"};
   const char *root_version = gROOT->GetVersion();
   Int_t idatqq = gROOT->GetVersionDate();
   iday   = idatqq%100;
   imonth = (idatqq/100)%100;
   iyear  = (idatqq/10000);
   char *version_date = Form("%d %s %4d",iday,months[imonth-1],iyear);
   idatqq = gROOT->GetBuiltDate();
   iday   = idatqq%100;
   imonth = (idatqq/100)%100;
   iyear  = (idatqq/10000);
   char *built_date = Form("%d %s %4d",iday,months[imonth-1],iyear);

   Printf("  *******************************************");
   Printf("  *                                         *");
   Printf("  *        W E L C O M E  to  R O O T       *");
   Printf("  *                                         *");
   Printf("  *   Version%10s %17s   *", root_version, version_date);
// Printf("  *            Development version          *");
   Printf("  *                                         *");
   Printf("  *  You are welcome to visit our Web site  *");
   Printf("  *          http://root.cern.ch            *");
   Printf("  *                                         *");
   Printf("  *******************************************");

   if (strstr(gVirtualX->GetName(), "TTF")) {
      Int_t major, minor, patch;
      //TTF::Version(major, minor, patch);
      // avoid dependency on libGraf and hard code, will not change too often
      major = 2; minor = 1; patch = 9;
      Printf("\nFreeType Engine v%d.%d.%d used to render TrueType fonts.",
             major, minor, patch);
   }
#ifdef _REENTRANT
   else
      printf("\n");
   Printf("Compiled on %s for %s with thread support.", built_date,
          gSystem->GetBuildArch());
#else
   else
      printf("\n");
   Printf("Compiled on %s for %s.", built_date, gSystem->GetBuildArch());
#endif

   gInterpreter->PrintIntro();

#ifdef R__UNIX
   // Popdown X logo, only if started with -splash option
   for (int i = 0; i < Argc(); i++)
      if (!strcmp(Argv(i), "-splash"))
         kill(getppid(), SIGUSR1);
#endif
}

//______________________________________________________________________________
char *TRint::GetPrompt()
{
   // Get prompt from interpreter. Either "root [n]" or "end with '}'".

   char *s = gInterpreter->GetPrompt();
   if (s[0])
      strcpy(fPrompt, s);
   else
      sprintf(fPrompt, fDefaultPrompt.Data(), fNcmd);

   return fPrompt;
}

//______________________________________________________________________________
const char *TRint::SetPrompt(const char *newPrompt)
{
   // Set a new default prompt. It returns the previous prompt.
   // The prompt may contain a %d which will be replaced by the commend
   // number. The default prompt is "root [%d] ". The maximum length of
   // the prompt is 55 characters. To set the prompt in an interactive
   // session do:
   // root [0] ((TRint*)gROOT->GetApplication())->SetPrompt("aap> ")
   // aap>

   static TString op = fDefaultPrompt;

   if (newPrompt && strlen(newPrompt) <= 55)
      fDefaultPrompt = newPrompt;
   else
      Error("SetPrompt", "newPrompt too long (> 55 characters)");

   return op.Data();
}

//______________________________________________________________________________
Bool_t TRint::HandleTermInput()
{
   // Handle input coming from terminal.

   static TStopwatch timer;
   char *line;

   if ((line = Getlinem(kOneChar, 0))) {
      if (line[0] == 0 && Gl_eof())
         Terminate(0);

      gVirtualX->SetKeyAutoRepeat(kTRUE);

      Gl_histadd(line);

      TString sline = line;
      line[0] = 0;

      // strip off '\n' and leading and trailing blanks
      sline = sline.Chop();
      sline = sline.Strip(TString::kBoth);
      ReturnPressed((char*)sline.Data());

      fInterrupt = kFALSE;

      if (!gInterpreter->GetMore() && !sline.IsNull()) fNcmd++;

      // prevent recursive calling of this input handler
      fInputHandler->DeActivate();

      if (gROOT->Timer()) timer.Start();

      Bool_t added = kFALSE;
#ifdef R__EH
      try {
#endif
         TRY {
            ProcessLine(sline);
         } CATCH(excode) {
            // enable again input handler
            fInputHandler->Activate();
            added = kTRUE;
            Throw(excode);
         } ENDTRY;
#ifdef R__EH
      }
      // handle every exception
      catch (...) {
         // enable again intput handler
         if (!added) fInputHandler->Activate();
         throw;
      }
#endif

      if (gROOT->Timer()) timer.Print("u");

      // enable again intput handler
      fInputHandler->Activate();

      if (!sline.BeginsWith(".reset"))
         gInterpreter->EndOfLineAction();

      gTabCom->ClearAll();
      Getlinem(kInit, GetPrompt());
   }
   return kTRUE;
}

//______________________________________________________________________________
void TRint::Terminate(Int_t status)
{
   // Terminate the application. Reset the terminal to sane mode and call
   // the logoff macro defined via Rint.Logoff environment variable.

   Getlinem(kCleanUp, 0);

   if (ReturnFromRun()) {
      gSystem->ExitLoop();
   } else {
      //Execute logoff macro
      const char *logoff;
      logoff = gEnv->GetValue("Rint.Logoff", (char*)0);
      if (logoff && !NoLogOpt()) {
         char *mac = gSystem->Which(TROOT::GetMacroPath(), logoff, kReadPermission);
         if (mac)
            ProcessFile(logoff);
         delete [] mac;
      }

      gSystem->Exit(status);
   }
}

//______________________________________________________________________________
void TRint::SetEchoMode(Bool_t mode)
{
   // Set console mode:
   //
   //  mode = kTRUE  - echo input symbols
   //  mode = kFALSE - noecho input symbols

   Gl_config("noecho", mode ? 0 : 1);
}
<commit_msg>From Paul Russo:<commit_after>// @(#)root/rint:$Name:  $:$Id: TRint.cxx,v 1.47 2005/06/06 12:48:37 pcanal Exp $
// Author: Rene Brun   17/02/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// Rint                                                                 //
//                                                                      //
// Rint is the ROOT Interactive Interface. It allows interactive access //
// to the ROOT system via the CINT C/C++ interpreter.                   //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TROOT.h"
#include "TClass.h"
#include "TVirtualX.h"
#include "Getline.h"
#include "TStyle.h"
#include "TObjectTable.h"
#include "TClassTable.h"
#include "TStopwatch.h"
#include "TBenchmark.h"
#include "TRint.h"
#include "TSystem.h"
#include "TEnv.h"
#include "TSysEvtHandler.h"
#include "TError.h"
#include "TException.h"
#include "TInterpreter.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TFile.h"
#include "TMapFile.h"
#include "TTabCom.h"
#include "TError.h"

#ifdef R__UNIX
#include <signal.h>

extern "C" {
   extern int G__get_security_error();
   extern int G__genericerror(const char* msg);
}
#endif

static Int_t key_pressed(Int_t key) { gApplication->KeyPressed(key); return 0; }

//----- Interrupt signal handler -----------------------------------------------
//______________________________________________________________________________
class TInterruptHandler : public TSignalHandler {
public:
   TInterruptHandler() : TSignalHandler(kSigInterrupt, kFALSE) { }
   Bool_t  Notify();
};

//______________________________________________________________________________
Bool_t TInterruptHandler::Notify()
{
   // TRint interrupt handler.

   if (fDelay) {
      fDelay++;
      return kTRUE;
   }

   // make sure we use the sbrk heap (in case of mapped files)
   gMmallocDesc = 0;

   if (!G__get_security_error())
      G__genericerror("\n *** Break *** keyboard interrupt");
   else {
      Break("TInterruptHandler::Notify", "keyboard interrupt");
      if (TROOT::Initialized()) {
         Getlinem(kInit, "Root > ");
         gInterpreter->RewindDictionary();
         Throw(GetSignal());
      }
   }
   return kTRUE;
}

//----- Terminal Input file handler --------------------------------------------
//______________________________________________________________________________
class TTermInputHandler : public TFileHandler {
public:
   TTermInputHandler(Int_t fd) : TFileHandler(fd, 1) { }
   Bool_t Notify();
   Bool_t ReadNotify() { return Notify(); }
};

//______________________________________________________________________________
Bool_t TTermInputHandler::Notify()
{
   return gApplication->HandleTermInput();
}

ClassImp(TRint)

//______________________________________________________________________________
TRint::TRint(const char *appClassName, Int_t *argc, char **argv, void *options,
             Int_t numOptions, Bool_t noLogo)
       : TApplication(appClassName, argc, argv, options, numOptions)
{
   // Create an application environment. The TRint environment provides an
   // interface to the WM manager functionality and eventloop via inheritance
   // of TApplication and in addition provides interactive access to
   // the CINT C++ interpreter via the command line.

   fNcmd          = 0;
   fDefaultPrompt = "root [%d] ";
   fInterrupt     = kFALSE;

   gBenchmark = new TBenchmark();

   if (!noLogo && !NoLogoOpt())
      PrintLogo();

   // Everybody expects iostream to be available, so load it...
   ProcessLine("#include <iostream>", kTRUE);
   ProcessLine("#include <_string>", kTRUE); // for std::string iostream.
   ProcessLine("#include <vector>", kTRUE);  // Needed because std::vector and std::pair are
   ProcessLine("#include <pair>", kTRUE);    //   used within the core ROOT dictionaries
                                             //   and CINT will not be able to properly unload these files

   // Allow the usage of ClassDef and ClassImp in interpreted macros
   ProcessLine("#include <RtypesCint.h>", kTRUE);

   // Disallow the interpretation of Rtypes.h, TError.h and TGenericClassInfo.h
   ProcessLine("#define ROOT_Rtypes 0", kTRUE);
   ProcessLine("#define ROOT_TError 0", kTRUE);
   ProcessLine("#define ROOT_TGenericClassInfo 0", kTRUE);

   // The following libs are also useful to have, make sure they are loaded...
   gROOT->LoadClass("TMinuit",     "Minuit");
   gROOT->LoadClass("TPostScript", "Postscript");
   gROOT->LoadClass("THtml",       "Html");

   // Load user functions
   const char *logon;
   logon = gEnv->GetValue("Rint.Load", (char*)0);
   if (logon) {
      char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
      if (mac)
         ProcessLine(Form(".L %s",logon),kTRUE);
      delete [] mac;
   }

   // Execute logon macro
   logon = gEnv->GetValue("Rint.Logon", (char*)0);
   if (logon && !NoLogOpt()) {
      char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
      if (mac)
         ProcessFile(logon);
      delete [] mac;
   }

   // Save current interpreter context
   gInterpreter->SaveContext();
   gInterpreter->SaveGlobalsContext();

   // Install interrupt and terminal input handlers
   TInterruptHandler *ih = new TInterruptHandler();
   ih->Add();
   SetSignalHandler(ih);

   // Handle stdin events
   fInputHandler = new TTermInputHandler(0);
   fInputHandler->Add();

   // Goto into raw terminal input mode
   char defhist[128];
#ifndef R__VMS
   sprintf(defhist, "%s/.root_hist", gSystem->Getenv("HOME"));
#else
   sprintf(defhist, "%s.root_hist", gSystem->Getenv("HOME"));
#endif
   logon = gEnv->GetValue("Rint.History", defhist);
   Gl_histinit((char *)logon);
   Gl_windowchanged();

   // Setup for tab completion
   gTabCom = new TTabCom;
   Gl_in_key = &key_pressed;
}

//______________________________________________________________________________
TRint::~TRint()
{

}

//______________________________________________________________________________
void TRint::Run(Bool_t retrn)
{
   // Main application eventloop. First process files given on the command
   // line and then go into the main application event loop, unless the -q
   // command line option was specfied in which case the program terminates.
   // When retrun is true this method returns even when -q was specified.
   //
   // When QuitOpt is true and retrn is false, terminate the application with
   // an error code equal to either the ProcessLine error (if any) or the
   // return value of the command casted to a long.

   Getlinem(kInit, GetPrompt());

   Long_t retval = 0;
   Int_t  error = 0;

   // Process shell command line input files
   if (InputFiles()) {
      // Make sure that calls into the event loop
      // ignore end-of-file on the terminal.
      fInputHandler->DeActivate();
      Bool_t needGetlinemInit = kFALSE;
      TIter next(InputFiles());
      RETRY {
         retval = 0; error = 0;
         Int_t nfile = 0;
         TObjString *file;
         while ((file = (TObjString *)next())) {
            char cmd[256];
            if (!fNcmd)
               printf("\n");
            if (file->String().EndsWith(".root")) {
               file->String().ReplaceAll("\\","/");
               const char *rfile = (const char*)file->String();
               Printf("Attaching file %s as _file%d...", rfile, nfile);
               sprintf(cmd, "TFile *_file%d = TFile::Open(\"%s\")", nfile++, rfile);
            } else {
               Printf("Processing %s...", (const char*)file->String());
               sprintf(cmd, ".x %s", (const char*)file->String());
            }
            Getlinem(kCleanUp, 0);
            Gl_histadd(cmd);
            fNcmd++;

            // The ProcessLine might throw an 'exception'.  In this case,
            // GetLinem(kInit,"Root >") is called and we are jump back
            // to RETRY ... and we have to avoid the Getlinem(kInit, GetPrompt());
            needGetlinemInit = kFALSE;
            retval = ProcessLine(cmd, kFALSE, &error);
	    gInterpreter->EndOfLineAction();

            // The ProcessLine has successfully completed and we need
            // to call Getlinem(kInit, GetPrompt());
            needGetlinemInit = kTRUE;

            if (error != 0) break;
         }
      } ENDTRY;

      // Allow end-of-file on the terminal to be noticed
      // after we finish processing the command line input files.
      fInputHandler->Activate();

      if (QuitOpt()) {
         if (retrn) return;
         Terminate(error == 0 ? retval : error);
      }

      ClearInputFiles();

      if (needGetlinemInit) Getlinem(kInit, GetPrompt());
   }

   if (QuitOpt()) {
      printf("\n");
      if (retrn) return;
      Terminate(0);
   }

   TApplication::Run(retrn);

   Getlinem(kCleanUp, 0);
}

//______________________________________________________________________________
void TRint::PrintLogo()
{
   // Print the ROOT logo on standard output.

   Int_t iday,imonth,iyear;
   static const char *months[] = {"January","February","March","April","May",
                                  "June","July","August","September","October",
                                  "November","December"};
   const char *root_version = gROOT->GetVersion();
   Int_t idatqq = gROOT->GetVersionDate();
   iday   = idatqq%100;
   imonth = (idatqq/100)%100;
   iyear  = (idatqq/10000);
   char *version_date = Form("%d %s %4d",iday,months[imonth-1],iyear);
   idatqq = gROOT->GetBuiltDate();
   iday   = idatqq%100;
   imonth = (idatqq/100)%100;
   iyear  = (idatqq/10000);
   char *built_date = Form("%d %s %4d",iday,months[imonth-1],iyear);

   Printf("  *******************************************");
   Printf("  *                                         *");
   Printf("  *        W E L C O M E  to  R O O T       *");
   Printf("  *                                         *");
   Printf("  *   Version%10s %17s   *", root_version, version_date);
// Printf("  *            Development version          *");
   Printf("  *                                         *");
   Printf("  *  You are welcome to visit our Web site  *");
   Printf("  *          http://root.cern.ch            *");
   Printf("  *                                         *");
   Printf("  *******************************************");

   if (strstr(gVirtualX->GetName(), "TTF")) {
      Int_t major, minor, patch;
      //TTF::Version(major, minor, patch);
      // avoid dependency on libGraf and hard code, will not change too often
      major = 2; minor = 1; patch = 9;
      Printf("\nFreeType Engine v%d.%d.%d used to render TrueType fonts.",
             major, minor, patch);
   }
#ifdef _REENTRANT
   else
      printf("\n");
   Printf("Compiled on %s for %s with thread support.", built_date,
          gSystem->GetBuildArch());
#else
   else
      printf("\n");
   Printf("Compiled on %s for %s.", built_date, gSystem->GetBuildArch());
#endif

   gInterpreter->PrintIntro();

#ifdef R__UNIX
   // Popdown X logo, only if started with -splash option
   for (int i = 0; i < Argc(); i++)
      if (!strcmp(Argv(i), "-splash"))
         kill(getppid(), SIGUSR1);
#endif
}

//______________________________________________________________________________
char *TRint::GetPrompt()
{
   // Get prompt from interpreter. Either "root [n]" or "end with '}'".

   char *s = gInterpreter->GetPrompt();
   if (s[0])
      strcpy(fPrompt, s);
   else
      sprintf(fPrompt, fDefaultPrompt.Data(), fNcmd);

   return fPrompt;
}

//______________________________________________________________________________
const char *TRint::SetPrompt(const char *newPrompt)
{
   // Set a new default prompt. It returns the previous prompt.
   // The prompt may contain a %d which will be replaced by the commend
   // number. The default prompt is "root [%d] ". The maximum length of
   // the prompt is 55 characters. To set the prompt in an interactive
   // session do:
   // root [0] ((TRint*)gROOT->GetApplication())->SetPrompt("aap> ")
   // aap>

   static TString op = fDefaultPrompt;

   if (newPrompt && strlen(newPrompt) <= 55)
      fDefaultPrompt = newPrompt;
   else
      Error("SetPrompt", "newPrompt too long (> 55 characters)");

   return op.Data();
}

//______________________________________________________________________________
Bool_t TRint::HandleTermInput()
{
   // Handle input coming from terminal.

   static TStopwatch timer;
   char *line;

   if ((line = Getlinem(kOneChar, 0))) {
      if (line[0] == 0 && Gl_eof())
         Terminate(0);

      gVirtualX->SetKeyAutoRepeat(kTRUE);

      Gl_histadd(line);

      TString sline = line;
      line[0] = 0;

      // strip off '\n' and leading and trailing blanks
      sline = sline.Chop();
      sline = sline.Strip(TString::kBoth);
      ReturnPressed((char*)sline.Data());

      fInterrupt = kFALSE;

      if (!gInterpreter->GetMore() && !sline.IsNull()) fNcmd++;

      // prevent recursive calling of this input handler
      fInputHandler->DeActivate();

      if (gROOT->Timer()) timer.Start();

      Bool_t added = kFALSE;
#ifdef R__EH
      try {
#endif
         TRY {
            ProcessLine(sline);
         } CATCH(excode) {
            // enable again input handler
            fInputHandler->Activate();
            added = kTRUE;
            Throw(excode);
         } ENDTRY;
#ifdef R__EH
      }
      // handle every exception
      catch (...) {
         // enable again intput handler
         if (!added) fInputHandler->Activate();
         throw;
      }
#endif

      if (gROOT->Timer()) timer.Print("u");

      // enable again intput handler
      fInputHandler->Activate();

      if (!sline.BeginsWith(".reset"))
         gInterpreter->EndOfLineAction();

      gTabCom->ClearAll();
      Getlinem(kInit, GetPrompt());
   }
   return kTRUE;
}

//______________________________________________________________________________
void TRint::Terminate(Int_t status)
{
   // Terminate the application. Reset the terminal to sane mode and call
   // the logoff macro defined via Rint.Logoff environment variable.

   Getlinem(kCleanUp, 0);

   if (ReturnFromRun()) {
      gSystem->ExitLoop();
   } else {
      //Execute logoff macro
      const char *logoff;
      logoff = gEnv->GetValue("Rint.Logoff", (char*)0);
      if (logoff && !NoLogOpt()) {
         char *mac = gSystem->Which(TROOT::GetMacroPath(), logoff, kReadPermission);
         if (mac)
            ProcessFile(logoff);
         delete [] mac;
      }

      gSystem->Exit(status);
   }
}

//______________________________________________________________________________
void TRint::SetEchoMode(Bool_t mode)
{
   // Set console mode:
   //
   //  mode = kTRUE  - echo input symbols
   //  mode = kFALSE - noecho input symbols

   Gl_config("noecho", mode ? 0 : 1);
}
<|endoftext|>


<commit_before>#include "workerCL.hpp"

#define __CL_DEFINE_EXCEPTIONS
#include <CL/cl.hpp>

#include <vector>
#include <string>
#include <iostream>

#include "log.hpp"
#include "reads.hpp"

using namespace std;

WorkerCL::WorkerCL(size_t platform_id, size_t device_id){
	/* GPU environment preparation */

	//Get platforms (drivers) list and keep the one to be use
	vector<cl::Platform> all_platforms;
	cl::Platform::get(&all_platforms);
	if(!all_platforms.size()){
		//No platform ? Send error
		string error = "OPENCL: no platforms found.";
		throw(error);
	}
	m_platform = all_platforms[platform_id];

	//Get devices list and keep the one to use
	vector<cl::Device> devices;
	m_platform.getDevices(CL_DEVICE_TYPE_ALL, &devices);
	if(device_id >= devices.size()){
		string error = "OPENCL: no device of id "+to_string(device_id)+
			" on platform "+to_string(platform_id)+" ("+to_string(devices.size())+" devices)";
		throw(error);
	}
	m_device = devices[device_id];

	//Create context
	m_context = cl::Context({m_device});

	//initialize commands queue
	m_commandqueue = cl::CommandQueue(m_context, m_device);

	//Build kernel sources
	m_program = cl::Program(m_context, kernel_cmp_2_contigs);
	if(m_program.build({m_device}) != CL_SUCCESS){
		string error = "Error building: ";
		error += m_program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(m_device);
		throw(error);
	}

	//Make the kernel
	m_kernel = cl::Kernel(m_program, "cmp_2_contigs");

}

WorkerCL::~WorkerCL(){
}

void WorkerCL::run(const Contigs& contigs){
	/*
	Create the string containing all contigs sequences
	and store the list of contigs size (in same orders)
	to be able to retrieve contigs. Size is store in
	an uint64_t (ulong) to be sure it is 64bits as cl_ulong
	*/

	//Get list of contigs size and the total length of the
	//contigs concatenation
	uint64_t nbContigs = contigs.get_nbContigs();
	uint64_t ultraSequenceSize = 0;
	vector<uint64_t> contigs_size (nbContigs, 0);
	for(uint64_t i=0; i < nbContigs; i++){
		contigs_size[i] = contigs.get_sizeContig(i);
		ultraSequenceSize += contigs_size[i];
	}

	//Create the ultraSequence
	char* ultraSequence = new char[ultraSequenceSize];
	uint64_t i = 0;
		//Get each contigs sequence and add it in ultraSequence
	for(uint64_t c=0; c < nbContigs; c++){
		string seq = contigs.get_seqContig(c);
		for(size_t j=0; j < seq.size();j++){
			ultraSequence[i] = seq[j];
			i++;
		}
	}
	cout << "UltraSequence:" << endl;
	cout << ultraSequence << endl;

	//Prepare GPU for the run
	cl::Event ev;
		//infos buffer (64bits): number of contigs, size of the ultrasequence
		//buffer only accepts non-dynamics arrays (even of size 1)
	uint64_t infos[2] = {nbContigs, ultraSequenceSize};
	cl::Buffer buf_infos (m_context, CL_MEM_READ_ONLY, sizeof(uint64_t));
	m_commandqueue.enqueueWriteBuffer(buf_infos, CL_TRUE, 0, sizeof(uint64_t), &infos);
		//Prepare the buffer for the results matrix (it will be 1D so an id of {x,y} is id=x+y*x_size)
		//The size of the buffer = char * x_size * y_size. Note: x_size == y_size == nb_contigs
	unsigned int scores_size = sizeof(char)*nbContigs*nbContigs;
	cl::Buffer buf_scores (m_context, CL_MEM_WRITE_ONLY, scores_size);
		//sequences sizes (array of 64bits) buffer
	cl::Buffer buf_sizes (m_context, CL_MEM_READ_ONLY, sizeof(uint64_t)*nbContigs);
	m_commandqueue.enqueueWriteBuffer(buf_sizes, CL_TRUE, 0, sizeof(uint64_t)*nbContigs, &contigs_size[0]);

	//Update the kernel (gpu function)
	m_kernel.setArg(0, buf_infos);
	m_kernel.setArg(1, buf_scores);
	m_kernel.setArg(2, buf_sizes);

	//Run the kernel and wait the end
	m_commandqueue.enqueueNDRangeKernel(m_kernel,cl::NullRange, cl::NDRange(nbContigs, nbContigs), cl::NullRange, NULL, &ev);
	ev.wait();

	//Get the score matrix: get the buffer into a 1D array then convert de 2D vectors array
	char* scores_1D = new char[nbContigs*nbContigs];
	m_commandqueue.enqueueReadBuffer(buf_scores, CL_TRUE, 0, scores_size, scores_1D);
	vector< vector<char> > scores = vector< vector<char> >(nbContigs, vector<char>(nbContigs, 0));
	for(size_t j=0; j<nbContigs; j++){
		for(size_t i=0; i<nbContigs; i++){
			scores[i][j] = scores_1D[i+nbContigs*j];
		}
	}

	//TEST: display scores
	cerr << "Seqs" << flush;
	for(size_t i=0; i < nbContigs; i++){cerr << "\t" << i << flush;}
	cerr << endl;
	for(size_t j=0; j < nbContigs; j++){
		string t = to_string(j);
		for(size_t i=0; i < nbContigs; i++){
			t += "\t"+to_string(scores[i][j]);
		}
		cerr << t << endl;
	}

	//Clean the memory
	delete ultraSequence;
	delete scores_1D;
	ultraSequence = nullptr;
	scores_1D = nullptr;
}

void WorkerCL::list_infos(Log& output){
	string txt;

	//Get platforms
	txt = "\n\t[Platforms list]";
	output.write(txt);
	vector<cl::Platform> platforms;
	cl::Platform::get(&platforms);
	if(!platforms.size()){
		txt = "No platform detected";
		output.write(txt);
		return;
	}
	txt = "platform_id\tplatform_name\tplatform_profile\tplatform_vendor\tplatform_version";
	output.write(txt);
	for(size_t i=0; i < platforms.size(); i++){
		cl::Platform& p = platforms[i];

		txt += "\t" + p.getInfo<CL_PLATFORM_NAME>();
		txt += "\t" + p.getInfo<CL_PLATFORM_PROFILE>();
		txt += "\t" + p.getInfo<CL_PLATFORM_VENDOR>();
		txt += "\t" + p.getInfo<CL_PLATFORM_VERSION>();
		//txt += "\t" + p.getInfo<CL_PLATFORM_EXTENSIONS>();
		output.write(txt);
	}

	//Get devices
	txt = "\n\t[Devices list]";
	output.write(txt);
	txt = "platform_id\tdevice_id\tdevice_name\tdevice_vendor\tdevice_profile\tdevice_version\tdriver_version\topencl_c_version";
	output.write(txt);
	for(size_t p = 0; p < platforms.size(); p++){
		vector<cl::Device> devices;
		platforms[p].getDevices(CL_DEVICE_TYPE_ALL, &devices);
		for(size_t d = 0; d < devices.size(); d++){
			cl::Device& device = devices[d];
			txt = to_string(p)+"\t"+to_string(d);
			txt += "\t" + device.getInfo<CL_DEVICE_NAME>();
			txt += "\t" + device.getInfo<CL_DEVICE_VENDOR>();
			txt += "\t" + device.getInfo<CL_DEVICE_PROFILE>();
			txt += "\t" + device.getInfo<CL_DEVICE_VERSION>();
			txt += "\t" + device.getInfo<CL_DRIVER_VERSION>();
			txt += "\t" + device.getInfo<CL_DEVICE_OPENCL_C_VERSION>();
			output.write(txt);
		}
	}
}

/*
Les balises 'R"CLCODE(' et ')CLCODE'   (du type R"NAME( ... )NAME") servent à définir un
string litéral brut. C'est utile pour avoir un string sur plusieurs ligne, comme un code,
et cela évite d'avoir à ouvrir puis fermer les guillemets à chaque ligne.
*/

string WorkerCL::kernel_cmp_2_contigs = R"CLCODE(
	kernel void cmp_2_contigs(global unsigned long *infos, global char *scores, global unsigned long *seqs_sizes){
		int seq1_id = get_global_id(0);
		int seq2_id = get_global_id(1);

		//Get the position of the seqs in the ultraseq
		unsigned long seq1_begin = 0;
		unsigned long seq2_begin = 0;
		unsigned long i=0;
		while(i < seq1_id || i < seq2_id){
			if(i < seq1_id){seq1_begin += seqs_sizes[i];}
			if(i < seq2_id){seq2_begin += seqs_sizes[i];}
			i++;
		}
		//Get the sizes and the end pos of the seqs
		unsigned long seq1_size = seqs_sizes[seq1_id];
		unsigned long seq2_size = seqs_sizes[seq2_id];
		unsigned long seq1_end= seq1_begin + seq1_size - 1;
		unsigned long seq2_end= seq2_begin + seq1_size - 1;

		//Put result on scores buffer
		scores[seq1_id + infos[0]*seq2_id] = seqs_sizes[seq1_id] + seqs_sizes[seq2_id];
	}
)CLCODE";
<commit_msg>Prepare about need2a<commit_after>#include "workerCL.hpp"

#define __CL_DEFINE_EXCEPTIONS
#include <CL/cl.hpp>

#include <vector>
#include <string>
#include <iostream>

#include "log.hpp"
#include "reads.hpp"

using namespace std;

WorkerCL::WorkerCL(size_t platform_id, size_t device_id){
	/* GPU environment preparation */

	//Get platforms (drivers) list and keep the one to be use
	vector<cl::Platform> all_platforms;
	cl::Platform::get(&all_platforms);
	if(!all_platforms.size()){
		//No platform ? Send error
		string error = "OPENCL: no platforms found.";
		throw(error);
	}
	m_platform = all_platforms[platform_id];

	//Get devices list and keep the one to use
	vector<cl::Device> devices;
	m_platform.getDevices(CL_DEVICE_TYPE_ALL, &devices);
	if(device_id >= devices.size()){
		string error = "OPENCL: no device of id "+to_string(device_id)+
			" on platform "+to_string(platform_id)+" ("+to_string(devices.size())+" devices)";
		throw(error);
	}
	m_device = devices[device_id];

	//Create context
	m_context = cl::Context({m_device});

	//initialize commands queue
	m_commandqueue = cl::CommandQueue(m_context, m_device);

	//Build kernel sources
	m_program = cl::Program(m_context, kernel_cmp_2_contigs);
	if(m_program.build({m_device}) != CL_SUCCESS){
		string error = "Error building: ";
		error += m_program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(m_device);
		throw(error);
	}

	//Make the kernel
	m_kernel = cl::Kernel(m_program, "cmp_2_contigs");

}

WorkerCL::~WorkerCL(){
}

void WorkerCL::run(const Contigs& contigs){
	/*
	Create the string containing all contigs sequences
	and store the list of contigs size (in same orders)
	to be able to retrieve contigs. Size is store in
	an uint64_t (ulong) to be sure it is 64bits as cl_ulong
	*/

	//Get list of contigs size, the total length of the
	//contigs concatenation and the longuest contig size
	uint64_t nbContigs = contigs.get_nbContigs();
	uint64_t ultraSequenceSize = 0;
	uint64_t longuest_contig_size = 0;
	vector<uint64_t> contigs_size (nbContigs, 0);
	for(uint64_t i=0; i < nbContigs; i++){
		contigs_size[i] = contigs.get_sizeContig(i);
		ultraSequenceSize += contigs_size[i];
		if(contigs_size[i] > longuest_contig_size){longuest_contig_size = contigs_size[i];}
	}

	//Create the ultraSequence
	char* ultraSequence = new char[ultraSequenceSize];
	uint64_t i = 0;
		//Get each contigs sequence and add it in ultraSequence
	for(uint64_t c=0; c < nbContigs; c++){
		string seq = contigs.get_seqContig(c);
		for(size_t j=0; j < seq.size();j++){
			ultraSequence[i] = seq[j];
			i++;
		}
	}
	cout << "UltraSequence:" << endl;
	cout << ultraSequence << endl;

	//Prepare GPU for the run
	cl::Event ev;
		//infos buffer (64bits): number of contigs, size of the ultrasequence
		//buffer only accepts non-dynamics arrays (even of size 1)
	uint64_t infos[2] = {nbContigs, ultraSequenceSize};
	cl::Buffer buf_infos (m_context, CL_MEM_READ_ONLY, sizeof(uint64_t));
	m_commandqueue.enqueueWriteBuffer(buf_infos, CL_TRUE, 0, sizeof(uint64_t), &infos);
		//Prepare the buffer for the results matrix (it will be 1D so an id of {x,y} is id=x+y*x_size)
		//The size of the buffer = char * x_size * y_size. Note: x_size == y_size == nb_contigs
	unsigned int scores_size = sizeof(char)*nbContigs*nbContigs;
	cl::Buffer buf_scores (m_context, CL_MEM_WRITE_ONLY, scores_size);
		//sequences sizes (array of 64bits) buffer
	cl::Buffer buf_sizes (m_context, CL_MEM_READ_ONLY, sizeof(uint64_t)*nbContigs);
	m_commandqueue.enqueueWriteBuffer(buf_sizes, CL_TRUE, 0, sizeof(uint64_t)*nbContigs, &contigs_size[0]);
		//ultrasequence
	cl::Buffer buf_ultraseq (m_context, CL_MEM_READ_ONLY, sizeof(char)*ultraSequenceSize);
	m_commandqueue.enqueueWriteBuffer(buf_ultraseq, CL_TRUE, 0, sizeof(char)*ultraSequenceSize, ultraSequence);
		//buffer for work items : they need 2 arrays for need2a and 2 array for each sequences. These arrays are of size of longuest contig.

	//Update the kernel (gpu function)
	m_kernel.setArg(0, buf_infos);
	m_kernel.setArg(1, buf_scores);
	m_kernel.setArg(2, buf_sizes);
	m_kernel.setArg(3, buf_ultraseq);

	//Run the kernel and wait the end
	m_commandqueue.enqueueNDRangeKernel(m_kernel,cl::NullRange, cl::NDRange(nbContigs, nbContigs), cl::NullRange, NULL, &ev);
	ev.wait();

	//Get the score matrix: get the buffer into a 1D array then convert de 2D vectors array
	char* scores_1D = new char[nbContigs*nbContigs];
	m_commandqueue.enqueueReadBuffer(buf_scores, CL_TRUE, 0, scores_size, scores_1D);
	vector< vector<char> > scores = vector< vector<char> >(nbContigs, vector<char>(nbContigs, 0));
	for(size_t j=0; j<nbContigs; j++){
		for(size_t i=0; i<nbContigs; i++){
			scores[i][j] = scores_1D[i+nbContigs*j];
		}
	}

	//TEST: display scores
	cerr << "Seqs" << flush;
	for(size_t i=0; i < nbContigs; i++){cerr << "\t" << i << flush;}
	cerr << endl;
	for(size_t j=0; j < nbContigs; j++){
		string t = to_string(j);
		for(size_t i=0; i < nbContigs; i++){
			t += "\t"+to_string(scores[i][j]);
		}
		cerr << t << endl;
	}

	//Clean the memory
	delete ultraSequence;
	delete scores_1D;
	ultraSequence = nullptr;
	scores_1D = nullptr;
}

void WorkerCL::list_infos(Log& output){
	string txt;

	//Get platforms
	txt = "\n\t[Platforms list]";
	output.write(txt);
	vector<cl::Platform> platforms;
	cl::Platform::get(&platforms);
	if(!platforms.size()){
		txt = "No platform detected";
		output.write(txt);
		return;
	}
	txt = "platform_id\tplatform_name\tplatform_profile\tplatform_vendor\tplatform_version";
	output.write(txt);
	for(size_t i=0; i < platforms.size(); i++){
		cl::Platform& p = platforms[i];

		txt += "\t" + p.getInfo<CL_PLATFORM_NAME>();
		txt += "\t" + p.getInfo<CL_PLATFORM_PROFILE>();
		txt += "\t" + p.getInfo<CL_PLATFORM_VENDOR>();
		txt += "\t" + p.getInfo<CL_PLATFORM_VERSION>();
		//txt += "\t" + p.getInfo<CL_PLATFORM_EXTENSIONS>();
		output.write(txt);
	}

	//Get devices
	txt = "\n\t[Devices list]";
	output.write(txt);
	txt = "platform_id\tdevice_id\tdevice_name\tdevice_vendor\tdevice_profile\tdevice_version\tdriver_version\topencl_c_version";
	output.write(txt);
	for(size_t p = 0; p < platforms.size(); p++){
		vector<cl::Device> devices;
		platforms[p].getDevices(CL_DEVICE_TYPE_ALL, &devices);
		for(size_t d = 0; d < devices.size(); d++){
			cl::Device& device = devices[d];
			txt = to_string(p)+"\t"+to_string(d);
			txt += "\t" + device.getInfo<CL_DEVICE_NAME>();
			txt += "\t" + device.getInfo<CL_DEVICE_VENDOR>();
			txt += "\t" + device.getInfo<CL_DEVICE_PROFILE>();
			txt += "\t" + device.getInfo<CL_DEVICE_VERSION>();
			txt += "\t" + device.getInfo<CL_DRIVER_VERSION>();
			txt += "\t" + device.getInfo<CL_DEVICE_OPENCL_C_VERSION>();
			output.write(txt);
		}
	}
}

/*
Les balises 'R"CLCODE(' et ')CLCODE'   (du type R"NAME( ... )NAME") servent à définir un
string litéral brut. C'est utile pour avoir un string sur plusieurs ligne, comme un code,
et cela évite d'avoir à ouvrir puis fermer les guillemets à chaque ligne.
*/

string WorkerCL::kernel_cmp_2_contigs = R"CLCODE(
	kernel void cmp_2_contigs(global unsigned long *infos, global char *scores, global unsigned long *seqs_sizes, global char *ultraseq){
		int seq1_id = get_global_id(0);
		int seq2_id = get_global_id(1);

		//Get the position of the seqs in the ultraseq
		unsigned long seq1_begin = 0;
		unsigned long seq2_begin = 0;
		unsigned long i=0;
		while(i < seq1_id || i < seq2_id){
			if(i < seq1_id){seq1_begin += seqs_sizes[i];}
			if(i < seq2_id){seq2_begin += seqs_sizes[i];}
			i++;
		}
		//Get the sizes and the end pos of the seqs
		unsigned long seq1_size = seqs_sizes[seq1_id];
		unsigned long seq2_size = seqs_sizes[seq2_id];
		unsigned long seq1_end= seq1_begin + seq1_size - 1;
		unsigned long seq2_end= seq2_begin + seq1_size - 1;

		//Get the sequences
		char seq1[10];

		//Put result on scores buffer
		scores[seq1_id + infos[0]*seq2_id] = seqs_sizes[seq1_id] + seqs_sizes[seq2_id];
	}
)CLCODE";
<|endoftext|>


<commit_before>#include "workerCL.hpp"

#define __CL_DEFINE_EXCEPTIONS
#include <CL/cl.hpp>

#include <vector>
#include <string>
#include <iostream>

#include "log.hpp"
#include "reads.hpp"

using namespace std;

WorkerCL::WorkerCL(size_t platform_id, size_t device_id){
	/* GPU environment preparation */

	//Get platforms (drivers) list and keep the one to be use
	vector<cl::Platform> all_platforms;
	cl::Platform::get(&all_platforms);
	if(!all_platforms.size()){
		//No platform ? Send error
		string error = "OPENCL: no platforms found.";
		throw(error);
	}
	m_platform = all_platforms[platform_id];

	//Get devices list and keep the one to use
	vector<cl::Device> devices;
	m_platform.getDevices(CL_DEVICE_TYPE_ALL, &devices);
	if(device_id >= devices.size()){
		string error = "OPENCL: no device of id "+to_string(device_id)+
			" on platform "+to_string(platform_id)+" ("+to_string(devices.size())+" devices)";
		throw(error);
	}
	m_device = devices[device_id];

	//Create context
	m_context = cl::Context({m_device});

	//initialize commands queue
	m_commandqueue = cl::CommandQueue(m_context, m_device);

	//Build kernel sources
	m_program = cl::Program(m_context, kernel_cmp_2_contigs);
	if(m_program.build({m_device}) != CL_SUCCESS){
		string error = "Error building: ";
		error += m_program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(m_device);
		throw(error);
	}

	//Make the kernel
	m_kernel = cl::Kernel(m_program, "cmp_2_contigs");

}

WorkerCL::~WorkerCL(){
}

void WorkerCL::run(const Contigs& contigs, size_t work_group_size){
	/*
	Create the string containing all contigs sequences
	and store the list of contigs size (in same orders)
	to be able to retrieve contigs. Size is store in
	an uint64_t (ulong) to be sure it is 64bits as cl_ulong
	*/

	//Get list of contigs size, the total length of the
	//contigs concatenation and the longuest contig size
	uint64_t nbContigs = contigs.get_nbContigs();
	uint64_t ultraSequenceSize = 0;
	uint64_t longuest_contig_size = 0;
	vector<uint64_t> contigs_size (nbContigs, 0);
	for(uint64_t i=0; i < nbContigs; i++){
		contigs_size[i] = contigs.get_sizeContig(i);
		ultraSequenceSize += contigs_size[i];
		if(contigs_size[i] > longuest_contig_size){longuest_contig_size = contigs_size[i];}
	}

	//Prepare GPU for the run
	cl::Event ev;
		//infos buffer (64bits): number of contigs, size of the ultrasequence, size of longuest contig
		//buffer only accepts non-dynamics arrays (even of size 1)
	uint64_t infos[3] = {nbContigs, ultraSequenceSize, longuest_contig_size};
	cl::Buffer buf_infos (m_context, CL_MEM_READ_ONLY, sizeof(uint64_t));
	m_commandqueue.enqueueWriteBuffer(buf_infos, CL_TRUE, 0, sizeof(uint64_t), &infos);
	m_kernel.setArg(0, buf_infos); //update kernel

		//Prepare the buffer for the results matrix (it will be 1D so an id of {x,y} is id=x+y*x_size)
		//The size of the buffer = char * x_size * y_size. Note: x_size == y_size == nb_contigs
	unsigned int scores_size = sizeof(char)*nbContigs*nbContigs;
	cl::Buffer buf_scores (m_context, CL_MEM_WRITE_ONLY, scores_size);
	m_kernel.setArg(1, buf_scores);

		//sequences sizes (array of 64bits) buffer
	cl::Buffer buf_sizes (m_context, CL_MEM_READ_ONLY, sizeof(uint64_t)*nbContigs);
	m_commandqueue.enqueueWriteBuffer(buf_sizes, CL_TRUE, 0, sizeof(uint64_t)*nbContigs, &contigs_size[0]);
	m_kernel.setArg(2, buf_sizes);

		//ultrasequence, get each contigs sequence and add it in ultrasequence
	char* ultraSequence = new char[ultraSequenceSize];
	uint64_t i = 0;
	for(uint64_t c=0; c < nbContigs; c++){
		string seq = contigs.get_seqContig(c);
		for(size_t j=0; j < seq.size(); j++){
				ultraSequence[i] = seq[j];
				i++;
		}
	}
	cout << "UltraSequence:" << endl;
	cout << ultraSequence << endl;

	cl::Buffer buf_ultraseq (m_context, CL_MEM_READ_ONLY, sizeof(char)*ultraSequenceSize);
	m_commandqueue.enqueueWriteBuffer(buf_ultraseq, CL_TRUE, 0, sizeof(char)*ultraSequenceSize, ultraSequence);
	m_kernel.setArg(3, buf_ultraseq);

	delete ultraSequence; //Clean  the memory
	ultraSequence = nullptr;

		//buffer for work items : they need 2 arrays for need2a and 2 array for each sequences. These arrays are of size of longuest contig.
		/*
			Each work item need its own array (for each arrays) allocated on local.
			So a local array (of a work group) contains all concatenated array of the work items of the same group.
			This local array have a size of longuest_contig_size*work_group_size number of elements.
		*/

	//Run the kernel and wait the end
	m_commandqueue.enqueueNDRangeKernel(m_kernel,cl::NullRange, cl::NDRange(nbContigs, nbContigs), cl::NullRange, NULL, &ev);
	ev.wait();

	//Get the score matrix: get the buffer into a 1D array then convert de 2D vectors array
	char* scores_1D = new char[nbContigs*nbContigs];
	m_commandqueue.enqueueReadBuffer(buf_scores, CL_TRUE, 0, scores_size, scores_1D);
	vector< vector<char> > scores = vector< vector<char> >(nbContigs, vector<char>(nbContigs, 0));
	for(size_t j=0; j<nbContigs; j++){
		for(size_t i=0; i<nbContigs; i++){
			scores[i][j] = scores_1D[i+nbContigs*j];
		}
	}

	//TEST: display scores
	cerr << "Seqs" << flush;
	for(size_t i=0; i < nbContigs; i++){cerr << "\t" << i << flush;}
	cerr << endl;
	for(size_t j=0; j < nbContigs; j++){
		string t = to_string(j);
		for(size_t i=0; i < nbContigs; i++){
			t += "\t"+to_string(scores[i][j]);
		}
		cerr << t << endl;
	}

	//Clean the memory
	delete scores_1D;
	scores_1D = nullptr;
}

void WorkerCL::list_infos(Log& output){
	string txt;

	//Get platforms
	txt = "\n\t[Platforms list]";
	output.write(txt);
	vector<cl::Platform> platforms;
	cl::Platform::get(&platforms);
	if(!platforms.size()){
		txt = "No platform detected";
		output.write(txt);
		return;
	}
	txt = "platform_id\tplatform_name\tplatform_profile\tplatform_vendor\tplatform_version";
	output.write(txt);
	for(size_t i=0; i < platforms.size(); i++){
		cl::Platform& p = platforms[i];
		txt = to_string(i);
		txt += "\t" + p.getInfo<CL_PLATFORM_NAME>();
		txt += "\t" + p.getInfo<CL_PLATFORM_PROFILE>();
		txt += "\t" + p.getInfo<CL_PLATFORM_VENDOR>();
		txt += "\t" + p.getInfo<CL_PLATFORM_VERSION>();
		//txt += "\t" + p.getInfo<CL_PLATFORM_EXTENSIONS>();
		output.write(txt);
	}

	//Get devices
	txt = "\n\t[Devices list]";
	output.write(txt);
	txt = "platform_id\tdevice_id\tdevice_name\tdevice_vendor\tdevice_profile\tdevice_version\tdevice_globalmem\tdevice_localmem\tdevice_maxgroupsize\tdriver_version\topencl_c_version";
	output.write(txt);
	for(size_t p = 0; p < platforms.size(); p++){
		vector<cl::Device> devices;
		platforms[p].getDevices(CL_DEVICE_TYPE_ALL, &devices);
		for(size_t d = 0; d < devices.size(); d++){
			cl::Device& device = devices[d];
			txt = to_string(p)+"\t"+to_string(d);
			txt += "\t" + device.getInfo<CL_DEVICE_NAME>();
			txt += "\t" + device.getInfo<CL_DEVICE_VENDOR>();
			txt += "\t" + device.getInfo<CL_DEVICE_PROFILE>();
			txt += "\t" + device.getInfo<CL_DEVICE_VERSION>();
			txt += "\t" + to_string(device.getInfo<CL_DEVICE_GLOBAL_MEM_SIZE>())+"B";
			txt += "\t" + to_string(device.getInfo<CL_DEVICE_LOCAL_MEM_SIZE>())+"B";
			txt += "\t" + to_string(device.getInfo<CL_DEVICE_MAX_WORK_GROUP_SIZE>());
			txt += "\t" + device.getInfo<CL_DRIVER_VERSION>();
			txt += "\t" + device.getInfo<CL_DEVICE_OPENCL_C_VERSION>();
			output.write(txt);
		}
	}
}

/*
Les balises 'R"CLCODE(' et ')CLCODE'   (du type R"NAME( ... )NAME") servent à définir un
string litéral brut. C'est utile pour avoir un string sur plusieurs ligne, comme un code,
et cela évite d'avoir à ouvrir puis fermer les guillemets à chaque ligne.
*/

string WorkerCL::kernel_cmp_2_contigs = R"CLCODE(
	kernel void cmp_2_contigs(global unsigned long *infos, global char *scores, global unsigned long *seqs_sizes, global char *ultraseq){
		int seq1_id = get_global_id(0);
		int seq2_id = get_global_id(1);

		/* Old way: basic memory. Work
		//Get the position of the seqs in the ultraseq
		unsigned long seq1_begin = 0;
		unsigned long seq2_begin = 0;
		unsigned long i=0;
		while(i < seq1_id || i < seq2_id){
			if(i < seq1_id){seq1_begin += seqs_sizes[i];}
			if(i < seq2_id){seq2_begin += seqs_sizes[i];}
			i++;
		}

		//Get the sizes and the end pos of the seqs
		unsigned long seq1_size = seqs_sizes[seq1_id];
		unsigned long seq2_size = seqs_sizes[seq2_id];
		unsigned long seq1_end= seq1_begin + seq1_size - 1;
		unsigned long seq2_end= seq2_begin + seq1_size - 1;

		//Test if same seq : =1 else =0
		scores[seq1_id + infos[0]*seq2_id] = 0;
		if(seq1_size == seq2_size){
			bool same = true;
			for(unsigned int i=0; i < seq1_size; i++){
				if(ultraseq[seq1_begin+i] != ultraseq[seq2_begin+i]){
					same = false;
					i = seq1_size;
				}
			}
			if(same){scores[seq1_id+infos[0]*seq2_id]=1;}
		}
		*/

		//Get the position of seqs and sizes
		global char* seq1_ptr = NULL;
		global char* seq2_ptr = NULL;
			//Calculate the begin for each item (the for boucle is on all contigs (infos[0]) but it's stop before)
		unsigned long start = 0;
		for(unsigned long i = 0; i < seq1_id; i++){start += seqs_sizes[i];}
		seq1_ptr = &ultraseq[start];
		start = 0;
		for(unsigned long i = 0; i < seq2_id; i++){start += seqs_sizes[i];}
		seq2_ptr = &ultraseq[start];
			//get sizes
		unsigned long seq1_size = seqs_sizes[seq1_id];
		unsigned long seq2_size = seqs_sizes[seq2_id];

		//Test: if same seq then =1 else =0
		scores[seq1_id + infos[0]*seq2_id] = 0;
		if(seq1_size == seq2_size){
			bool same=true;
			for(unsigned int i=0; i < seq1_size; i++){
				if(seq1_ptr[i] != seq2_ptr[i]){
					same = false;
					i = seq1_size;
				}
			}
			if(same){scores[seq1_id+infos[0]*seq2_id]=1;}
		}

	}
)CLCODE";
<commit_msg>Add ultraSeq bytes size information output<commit_after>#include "workerCL.hpp"

#define __CL_DEFINE_EXCEPTIONS
#include <CL/cl.hpp>

#include <vector>
#include <string>
#include <iostream>

#include "log.hpp"
#include "reads.hpp"

using namespace std;

WorkerCL::WorkerCL(size_t platform_id, size_t device_id){
	/* GPU environment preparation */

	//Get platforms (drivers) list and keep the one to be use
	vector<cl::Platform> all_platforms;
	cl::Platform::get(&all_platforms);
	if(!all_platforms.size()){
		//No platform ? Send error
		string error = "OPENCL: no platforms found.";
		throw(error);
	}
	m_platform = all_platforms[platform_id];

	//Get devices list and keep the one to use
	vector<cl::Device> devices;
	m_platform.getDevices(CL_DEVICE_TYPE_ALL, &devices);
	if(device_id >= devices.size()){
		string error = "OPENCL: no device of id "+to_string(device_id)+
			" on platform "+to_string(platform_id)+" ("+to_string(devices.size())+" devices)";
		throw(error);
	}
	m_device = devices[device_id];

	//Create context
	m_context = cl::Context({m_device});

	//initialize commands queue
	m_commandqueue = cl::CommandQueue(m_context, m_device);

	//Build kernel sources
	m_program = cl::Program(m_context, kernel_cmp_2_contigs);
	if(m_program.build({m_device}) != CL_SUCCESS){
		string error = "Error building: ";
		error += m_program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(m_device);
		throw(error);
	}

	//Make the kernel
	m_kernel = cl::Kernel(m_program, "cmp_2_contigs");

}

WorkerCL::~WorkerCL(){
}

void WorkerCL::run(const Contigs& contigs, size_t work_group_size){
	/*
	Create the string containing all contigs sequences
	and store the list of contigs size (in same orders)
	to be able to retrieve contigs. Size is store in
	an uint64_t (ulong) to be sure it is 64bits as cl_ulong
	*/

	//Get list of contigs size, the total length of the
	//contigs concatenation and the longuest contig size
	uint64_t nbContigs = contigs.get_nbContigs();
	uint64_t ultraSequenceSize = 0;
	uint64_t longuest_contig_size = 0;
	vector<uint64_t> contigs_size (nbContigs, 0);
	for(uint64_t i=0; i < nbContigs; i++){
		contigs_size[i] = contigs.get_sizeContig(i);
		ultraSequenceSize += contigs_size[i];
		if(contigs_size[i] > longuest_contig_size){longuest_contig_size = contigs_size[i];}
	}

	cout << "ultraSeqSize =  " << to_string(ultraSequenceSize*sizeof(char)) << "B" << endl;

	//Prepare GPU for the run
	cl::Event ev;
		//infos buffer (64bits): number of contigs, size of the ultrasequence, size of longuest contig
		//buffer only accepts non-dynamics arrays (even of size 1)
	uint64_t infos[3] = {nbContigs, ultraSequenceSize, longuest_contig_size};
	cl::Buffer buf_infos (m_context, CL_MEM_READ_ONLY, sizeof(uint64_t));
	m_commandqueue.enqueueWriteBuffer(buf_infos, CL_TRUE, 0, sizeof(uint64_t), &infos);
	m_kernel.setArg(0, buf_infos); //update kernel

		//Prepare the buffer for the results matrix (it will be 1D so an id of {x,y} is id=x+y*x_size)
		//The size of the buffer = char * x_size * y_size. Note: x_size == y_size == nb_contigs
	unsigned int scores_size = sizeof(char)*nbContigs*nbContigs;
	cl::Buffer buf_scores (m_context, CL_MEM_WRITE_ONLY, scores_size);
	m_kernel.setArg(1, buf_scores);

		//sequences sizes (array of 64bits) buffer
	cl::Buffer buf_sizes (m_context, CL_MEM_READ_ONLY, sizeof(uint64_t)*nbContigs);
	m_commandqueue.enqueueWriteBuffer(buf_sizes, CL_TRUE, 0, sizeof(uint64_t)*nbContigs, &contigs_size[0]);
	m_kernel.setArg(2, buf_sizes);

		//ultrasequence, get each contigs sequence and add it in ultrasequence
	char* ultraSequence = new char[ultraSequenceSize];
	uint64_t i = 0;
	for(uint64_t c=0; c < nbContigs; c++){
		string seq = contigs.get_seqContig(c);
		for(size_t j=0; j < seq.size(); j++){
				ultraSequence[i] = seq[j];
				i++;
		}
	}
	cl::Buffer buf_ultraseq (m_context, CL_MEM_READ_ONLY, sizeof(char)*ultraSequenceSize);
	m_commandqueue.enqueueWriteBuffer(buf_ultraseq, CL_TRUE, 0, sizeof(char)*ultraSequenceSize, ultraSequence);
	m_kernel.setArg(3, buf_ultraseq);

	delete ultraSequence; //Clean  the memory
	ultraSequence = nullptr;

		//buffer for work items : they need 2 arrays for need2a and 2 array for each sequences. These arrays are of size of longuest contig.
		/*
			Each work item need its own array (for each arrays) allocated on local.
			So a local array (of a work group) contains all concatenated array of the work items of the same group.
			This local array have a size of longuest_contig_size*work_group_size number of elements.
		*/

	//Run the kernel and wait the end
	m_commandqueue.enqueueNDRangeKernel(m_kernel,cl::NullRange, cl::NDRange(nbContigs, nbContigs), cl::NullRange, NULL, &ev);
	ev.wait();

	//Get the score matrix: get the buffer into a 1D array then convert de 2D vectors array
	char* scores_1D = new char[nbContigs*nbContigs];
	m_commandqueue.enqueueReadBuffer(buf_scores, CL_TRUE, 0, scores_size, scores_1D);
	vector< vector<char> > scores = vector< vector<char> >(nbContigs, vector<char>(nbContigs, 0));
	for(size_t j=0; j<nbContigs; j++){
		for(size_t i=0; i<nbContigs; i++){
			scores[i][j] = scores_1D[i+nbContigs*j];
		}
	}

	//TEST: display scores
	cerr << "Seqs" << flush;
	for(size_t i=0; i < nbContigs; i++){cerr << "\t" << i << flush;}
	cerr << endl;
	for(size_t j=0; j < nbContigs; j++){
		string t = to_string(j);
		for(size_t i=0; i < nbContigs; i++){
			t += "\t"+to_string(scores[i][j]);
		}
		cerr << t << endl;
	}

	//Clean the memory
	delete scores_1D;
	scores_1D = nullptr;
}

void WorkerCL::list_infos(Log& output){
	string txt;

	//Get platforms
	txt = "\n\t[Platforms list]";
	output.write(txt);
	vector<cl::Platform> platforms;
	cl::Platform::get(&platforms);
	if(!platforms.size()){
		txt = "No platform detected";
		output.write(txt);
		return;
	}
	txt = "platform_id\tplatform_name\tplatform_profile\tplatform_vendor\tplatform_version";
	output.write(txt);
	for(size_t i=0; i < platforms.size(); i++){
		cl::Platform& p = platforms[i];
		txt = to_string(i);
		txt += "\t" + p.getInfo<CL_PLATFORM_NAME>();
		txt += "\t" + p.getInfo<CL_PLATFORM_PROFILE>();
		txt += "\t" + p.getInfo<CL_PLATFORM_VENDOR>();
		txt += "\t" + p.getInfo<CL_PLATFORM_VERSION>();
		//txt += "\t" + p.getInfo<CL_PLATFORM_EXTENSIONS>();
		output.write(txt);
	}

	//Get devices
	txt = "\n\t[Devices list]";
	output.write(txt);
	txt = "platform_id\tdevice_id\tdevice_name\tdevice_vendor\tdevice_profile\tdevice_version\tdevice_globalmem\tdevice_localmem\tdevice_maxgroupsize\tdriver_version\topencl_c_version";
	output.write(txt);
	for(size_t p = 0; p < platforms.size(); p++){
		vector<cl::Device> devices;
		platforms[p].getDevices(CL_DEVICE_TYPE_ALL, &devices);
		for(size_t d = 0; d < devices.size(); d++){
			cl::Device& device = devices[d];
			txt = to_string(p)+"\t"+to_string(d);
			txt += "\t" + device.getInfo<CL_DEVICE_NAME>();
			txt += "\t" + device.getInfo<CL_DEVICE_VENDOR>();
			txt += "\t" + device.getInfo<CL_DEVICE_PROFILE>();
			txt += "\t" + device.getInfo<CL_DEVICE_VERSION>();
			txt += "\t" + to_string(device.getInfo<CL_DEVICE_GLOBAL_MEM_SIZE>())+"B";
			txt += "\t" + to_string(device.getInfo<CL_DEVICE_LOCAL_MEM_SIZE>())+"B";
			txt += "\t" + to_string(device.getInfo<CL_DEVICE_MAX_WORK_GROUP_SIZE>());
			txt += "\t" + device.getInfo<CL_DRIVER_VERSION>();
			txt += "\t" + device.getInfo<CL_DEVICE_OPENCL_C_VERSION>();
			output.write(txt);
		}
	}
}

/*
Les balises 'R"CLCODE(' et ')CLCODE'   (du type R"NAME( ... )NAME") servent à définir un
string litéral brut. C'est utile pour avoir un string sur plusieurs ligne, comme un code,
et cela évite d'avoir à ouvrir puis fermer les guillemets à chaque ligne.
*/

string WorkerCL::kernel_cmp_2_contigs = R"CLCODE(
	kernel void cmp_2_contigs(global unsigned long *infos, global char *scores, global unsigned long *seqs_sizes, global char *ultraseq){
		int seq1_id = get_global_id(0);
		int seq2_id = get_global_id(1);

		/* Old way: basic memory. Work
		//Get the position of the seqs in the ultraseq
		unsigned long seq1_begin = 0;
		unsigned long seq2_begin = 0;
		unsigned long i=0;
		while(i < seq1_id || i < seq2_id){
			if(i < seq1_id){seq1_begin += seqs_sizes[i];}
			if(i < seq2_id){seq2_begin += seqs_sizes[i];}
			i++;
		}

		//Get the sizes and the end pos of the seqs
		unsigned long seq1_size = seqs_sizes[seq1_id];
		unsigned long seq2_size = seqs_sizes[seq2_id];
		unsigned long seq1_end= seq1_begin + seq1_size - 1;
		unsigned long seq2_end= seq2_begin + seq1_size - 1;

		//Test if same seq : =1 else =0
		scores[seq1_id + infos[0]*seq2_id] = 0;
		if(seq1_size == seq2_size){
			bool same = true;
			for(unsigned int i=0; i < seq1_size; i++){
				if(ultraseq[seq1_begin+i] != ultraseq[seq2_begin+i]){
					same = false;
					i = seq1_size;
				}
			}
			if(same){scores[seq1_id+infos[0]*seq2_id]=1;}
		}
		*/

		//Get the position of seqs and sizes
		global char* seq1_ptr = NULL;
		global char* seq2_ptr = NULL;
			//Calculate the begin for each item (the for boucle is on all contigs (infos[0]) but it's stop before)
		unsigned long start = 0;
		for(unsigned long i = 0; i < seq1_id; i++){start += seqs_sizes[i];}
		seq1_ptr = &ultraseq[start];
		start = 0;
		for(unsigned long i = 0; i < seq2_id; i++){start += seqs_sizes[i];}
		seq2_ptr = &ultraseq[start];
			//get sizes
		unsigned long seq1_size = seqs_sizes[seq1_id];
		unsigned long seq2_size = seqs_sizes[seq2_id];

		//Test: if same seq then =1 else =0
		scores[seq1_id + infos[0]*seq2_id] = 0;
		if(seq1_size == seq2_size){
			bool same=true;
			for(unsigned int i=0; i < seq1_size; i++){
				if(seq1_ptr[i] != seq2_ptr[i]){
					same = false;
					i = seq1_size;
				}
			}
			if(same){scores[seq1_id+infos[0]*seq2_id]=1;}
		}

	}
)CLCODE";
<|endoftext|>


<commit_before># include <Siv3D.hpp>

void Main()
{
	// 空のテクスチャ
	Texture texture;

	Graphics::SetBackground(Palette::White);

	double t = 0.0;

	while (System::Update())
	{
		Window::SetTitle(Window::GetState().windowSize, Window::Size());

		if (KeyW.down())
		{
			Graphics::SetFullScreen(false, Size(1280, 720));
		}

		if (KeyR.down())
		{
			Window::Resize(Size(1280, 720));
		}

		// 何かがドロップされた
		if (DragDrop::HasNewFilePaths())
		{
			const auto items = DragDrop::GetDroppedFilePaths();

			// テクスチャとしてロードに成功したら
			if (const Texture tmp{ items[0].path })
			{
				// テクスチャを置き換える
				texture = tmp;

				// ウィンドウをテクスチャと同じサイズにする
				Window::Resize(texture.size());
			}
		}

		if (texture)
		{
			texture.draw();
		}

		t += System::DeltaTime();

		for (int32 i = 0; i < 36; ++i)
		{
			const double angle = i * 10_deg + t * 30_deg;

			const Vec2 pos = Circular(200, angle) + Window::Center();

			RectF(25).setCenter(pos).rotated(angle).draw(HSV(i * 10));
		}

		Circle(Cursor::Pos(), 80).draw(ColorF(1,0,0,0.5));
	}
}
<commit_msg>update<commit_after># include <Siv3D.hpp>

void Main()
{
	// create a new empty texture
	Texture texture;

	while (System::Update())
	{
		// if some files have dropped
		if (DragDrop::HasNewFilePaths())
		{
			// retrieve file paths
			const auto items = DragDrop::GetDroppedFilePaths();

			// load the first file as a Texture
			const Texture tmp(items[0].path);

			// if succeeded
			if (tmp)
			{
				// set the new texture
				texture = tmp;

				// resize the window to be the same size as the texture
				Window::Resize(texture.size());
			}
		}

		// if the texture has content
		if (texture)
		{
			// draw
			texture.draw();
		}
	}
}
<|endoftext|>