<commit_before>/*

Copyright (c) 2007, Arvid Norberg
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 author 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 COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_BROADCAST_SOCKET_HPP_INCLUDED
#define TORRENT_BROADCAST_SOCKET_HPP_INCLUDED

#include "libtorrent/socket.hpp"
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <list>

namespace libtorrent
{

	bool is_local(address const& a);
	bool is_loopback(address const& addr);
	bool is_multicast(address const& addr);
	bool is_any(address const& addr);

	address guess_local_address(asio::io_service&);

	typedef boost::function<void(udp::endpoint const& from
		, char* buffer, int size)> receive_handler_t;

	class broadcast_socket
	{
	public:
		broadcast_socket(asio::io_service& ios, udp::endpoint const& multicast_endpoint
			, receive_handler_t const& handler, bool loopback = true);
		~broadcast_socket() { close(); }

		void send(char const* buffer, int size, asio::error_code& ec);
		void close();

	private:

		struct socket_entry
		{
			socket_entry(boost::shared_ptr<datagram_socket> const& s): socket(s) {}
			boost::shared_ptr<datagram_socket> socket;
			char buffer[1024];
			udp::endpoint remote;
			void close()
			{
				if (!socket) return;
				asio::error_code ec;
				socket->close(ec);
			}
		};

		void on_receive(socket_entry* s, asio::error_code const& ec
			, std::size_t bytes_transferred);
		void open_unicast_socket(io_service& ios, address const& addr);

		// these sockets are used to
		// join the multicast group (on each interface)
		// and receive multicast messages
		std::list<socket_entry> m_sockets;
		// these sockets are not bound to any
		// specific port and are used to
		// send messages to the multicast group
		// and receive unicast responses
		std::list<socket_entry> m_unicast_sockets;
		udp::endpoint m_multicast_endpoint;
		receive_handler_t m_on_receive;

	};
}

#endif

<commit_msg>broadcast socket header file update<commit_after>/*

Copyright (c) 2007, Arvid Norberg
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 author 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 COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_BROADCAST_SOCKET_HPP_INCLUDED
#define TORRENT_BROADCAST_SOCKET_HPP_INCLUDED

#include "libtorrent/socket.hpp"
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <list>

namespace libtorrent
{

	bool is_local(address const& a);
	bool is_loopback(address const& addr);
	bool is_multicast(address const& addr);
	bool is_any(address const& addr);

	address guess_local_address(asio::io_service&);

	typedef boost::function<void(udp::endpoint const& from
		, char* buffer, int size)> receive_handler_t;

	class broadcast_socket
	{
	public:
		broadcast_socket(asio::io_service& ios, udp::endpoint const& multicast_endpoint
			, receive_handler_t const& handler, bool loopback = true);
		~broadcast_socket() { close(); }

		void send(char const* buffer, int size, asio::error_code& ec);
		void close();

	private:

		struct socket_entry
		{
			socket_entry(boost::shared_ptr<datagram_socket> const& s): socket(s) {}
			boost::shared_ptr<datagram_socket> socket;
			char buffer[1024];
			udp::endpoint remote;
			void close()
			{
				if (!socket) return;
				asio::error_code ec;
				socket->close(ec);
			}
		};

		void on_receive(socket_entry* s, asio::error_code const& ec
			, std::size_t bytes_transferred);
		void open_unicast_socket(io_service& ios, address const& addr);
		void open_multicast_socket(io_service& ios, address const& addr
			, bool loopback);

		// these sockets are used to
		// join the multicast group (on each interface)
		// and receive multicast messages
		std::list<socket_entry> m_sockets;
		// these sockets are not bound to any
		// specific port and are used to
		// send messages to the multicast group
		// and receive unicast responses
		std::list<socket_entry> m_unicast_sockets;
		udp::endpoint m_multicast_endpoint;
		receive_handler_t m_on_receive;

	};
}

#endif

<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    VectorIndexSelection.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

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

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

// Software Guide : BeginCodeSnippet
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkVectorIndexSelectionCastImageFilter.h"
#include "itkRGBPixel.h"

// Software Guide : EndCodeSnippet

#include "itkImage.h"

int main( int argc, char ** argv )
{
  // Verify the number of parameters in the command line
  if( argc < 4 )
    {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << " inputImageFile  outputImageFile component" << std::endl;
    return -1;
    }

  // Software Guide : BeginCodeSnippet
  typedef itk::RGBPixel<unsigned char>  InputPixelType;
  typedef unsigned char       OutputPixelType;
  const   unsigned int        Dimension = 2;

  typedef itk::Image< InputPixelType,  Dimension >    InputImageType;
  typedef itk::Image< OutputPixelType, Dimension >    OutputImageType;
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginCodeSnippet
  typedef itk::ImageFileReader< InputImageType  >  ReaderType;
  typedef itk::VectorIndexSelectionCastImageFilter< InputImageType, OutputImageType  >  FilterType;
  typedef itk::ImageFileWriter< OutputImageType >  WriterType;
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginCodeSnippet
  FilterType::Pointer filter = FilterType::New();
  filter->SetIndex(atoi(argv[3]));
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Then, we create the reader and writer and connect the pipeline.
  //
  //  \index{itk::ImageFileReader!New()}
  //  \index{itk::ImageFileWriter!New()}
  //  \index{itk::ImageFileReader!SmartPointer}
  //  \index{itk::ImageFileWriter!SmartPointer}
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();

  filter->SetInput( reader->GetOutput() );
  writer->SetInput( filter->GetOutput() );
  // Software Guide : EndCodeSnippet

  //
  // Here we recover the file names from the command line arguments
  //
  const char * inputFilename  = argv[1];
  const char * outputFilename = argv[2];

  // Software Guide : BeginCodeSnippet
  reader->SetFileName( inputFilename  );
  writer->SetFileName( outputFilename );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Finally we trigger the execution of the pipeline with the Update()
  //  method on the writer. The output image will then be the scaled and cast
  //  version of the input image.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & err )
    {
    std::cout << "ExceptionObject caught !" << std::endl;
    std::cout << err << std::endl;
    return -1;
    }
  // Software Guide : EndCodeSnippet

  return 0;
}

<commit_msg>ERR: wrong signature for main program.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    VectorIndexSelection.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

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

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

// Software Guide : BeginCodeSnippet
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkVectorIndexSelectionCastImageFilter.h"
#include "itkRGBPixel.h"

// Software Guide : EndCodeSnippet

#include "itkImage.h"

int main( int argc, char * argv[] )
{
  // Verify the number of parameters in the command line
  if( argc < 4 )
    {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << " inputImageFile  outputImageFile component" << std::endl;
    return -1;
    }

  // Software Guide : BeginCodeSnippet
  typedef itk::RGBPixel<unsigned char>  InputPixelType;
  typedef unsigned char       OutputPixelType;
  const   unsigned int        Dimension = 2;

  typedef itk::Image< InputPixelType,  Dimension >    InputImageType;
  typedef itk::Image< OutputPixelType, Dimension >    OutputImageType;
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginCodeSnippet
  typedef itk::ImageFileReader< InputImageType  >  ReaderType;
  typedef itk::VectorIndexSelectionCastImageFilter< InputImageType, OutputImageType  >  FilterType;
  typedef itk::ImageFileWriter< OutputImageType >  WriterType;
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginCodeSnippet
  FilterType::Pointer filter = FilterType::New();
  filter->SetIndex(atoi(argv[3]));
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Then, we create the reader and writer and connect the pipeline.
  //
  //  \index{itk::ImageFileReader!New()}
  //  \index{itk::ImageFileWriter!New()}
  //  \index{itk::ImageFileReader!SmartPointer}
  //  \index{itk::ImageFileWriter!SmartPointer}
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();

  filter->SetInput( reader->GetOutput() );
  writer->SetInput( filter->GetOutput() );
  // Software Guide : EndCodeSnippet

  //
  // Here we recover the file names from the command line arguments
  //
  const char * inputFilename  = argv[1];
  const char * outputFilename = argv[2];

  // Software Guide : BeginCodeSnippet
  reader->SetFileName( inputFilename  );
  writer->SetFileName( outputFilename );
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  Finally we trigger the execution of the pipeline with the Update()
  //  method on the writer. The output image will then be the scaled and cast
  //  version of the input image.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & err )
    {
    std::cout << "ExceptionObject caught !" << std::endl;
    std::cout << err << std::endl;
    return -1;
    }
  // Software Guide : EndCodeSnippet

  return 0;
}

<|endoftext|>


<commit_before>// @(#)root/cont:$Id$
// Author: Rene Brun   28/09/2001

/*************************************************************************
 * 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.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//
// TProcessID
//
// A TProcessID identifies a ROOT job in a unique way in time and space.
// The TProcessID title consists of a TUUID object which provides a globally
// unique identifier (for more see TUUID.h).
//
// A TProcessID is automatically created by the TROOT constructor.
// When a TFile contains referenced objects (see TRef), the TProcessID
// object is written to the file.
// If a file has been written in multiple sessions (same machine or not),
// a TProcessID is written for each session.
// These objects are used by the class TRef to uniquely identified
// any TObject pointed by a TRef.
//
// When a referenced object is read from a file (its bit kIsReferenced is set),
// this object is entered into the objects table of the corresponding TProcessID.
// Each TFile has a list of TProcessIDs (see TFile::fProcessIDs) also
// accessible via TProcessID::fgPIDs (for all files).
// When this object is deleted, it is removed from the table via the cleanup
// mechanism invoked by the TObject destructor.
//
// Each TProcessID has a table (TObjArray *fObjects) that keeps track
// of all referenced objects. If a referenced object has a fUniqueID set,
// a pointer to this unique object may be found via fObjects->At(fUniqueID).
// In the same way, when a TRef::GetObject is called, GetObject uses
// its own fUniqueID to find the pointer to the referenced object.
// See TProcessID::GetObjectWithID and PutObjectWithID.
//
// When a referenced object is deleted, its slot in fObjects is set to null.
//
// See also TProcessUUID: a specialized TProcessID to manage the single list
// of TUUIDs.
//
//////////////////////////////////////////////////////////////////////////

#include "TProcessID.h"
#include "TROOT.h"
#include "TObjArray.h"
#include "TExMap.h"
#include "TVirtualMutex.h"
#include "TError.h"

TObjArray  *TProcessID::fgPIDs   = 0; //pointer to the list of TProcessID
TProcessID *TProcessID::fgPID    = 0; //pointer to the TProcessID of the current session
UInt_t      TProcessID::fgNumber = 0; //Current referenced object instance count
TExMap     *TProcessID::fgObjPIDs= 0; //Table (pointer,pids)
ClassImp(TProcessID)

////////////////////////////////////////////////////////////////////////////////
/// Return hash value for this object.

static inline ULong_t Void_Hash(const void *ptr)
{
   return TString::Hash(&ptr, sizeof(void*));
}

////////////////////////////////////////////////////////////////////////////////
/// Default constructor.

TProcessID::TProcessID()
{
   fCount = 0;
   fObjects = 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Destructor.

TProcessID::~TProcessID()
{
   delete fObjects;
   fObjects = 0;
   R__LOCKGUARD2(gROOTMutex);
   fgPIDs->Remove(this);
}

////////////////////////////////////////////////////////////////////////////////
/// Static function to add a new TProcessID to the list of PIDs.

TProcessID *TProcessID::AddProcessID()
{
   R__LOCKGUARD2(gROOTMutex);

   if (fgPIDs && fgPIDs->GetEntriesFast() >= 65534) {
      if (fgPIDs->GetEntriesFast() == 65534) {
         ::Warning("TProcessID::AddProcessID","Maximum number of TProcessID (65535) is almost reached (one left).  TRef will stop being functional when the limit is reached.");
      } else {
         ::Fatal("TProcessID::AddProcessID","Maximum number of TProcessID (65535) has been reached.  TRef are not longer functional.");
      }
   }

   TProcessID *pid = new TProcessID();

   if (!fgPIDs) {
      fgPID  = pid;
      fgPIDs = new TObjArray(10);
      gROOT->GetListOfCleanups()->Add(fgPIDs);
   }
   UShort_t apid = fgPIDs->GetEntriesFast();
   pid->IncrementCount();

   fgPIDs->Add(pid);
   // if (apid == 0) for(int incr=0; incr < 65533; ++incr) fgPIDs->Add(0); // NOTE: DEBUGGING ONLY MUST BE REMOVED!
   char name[20];
   snprintf(name,20,"ProcessID%d",apid);
   pid->SetName(name);
   pid->SetUniqueID((UInt_t)apid);
   TUUID u;
   //apid = fgPIDs->GetEntriesFast();
   pid->SetTitle(u.AsString());
   return pid;
}

////////////////////////////////////////////////////////////////////////////////
/// static function returning the ID assigned to obj
/// If the object is not yet referenced, its kIsReferenced bit is set
/// and its fUniqueID set to the current number of referenced objects so far.

UInt_t TProcessID::AssignID(TObject *obj)
{
   R__LOCKGUARD2(gROOTMutex);

   UInt_t uid = obj->GetUniqueID() & 0xffffff;
   if (obj == fgPID->GetObjectWithID(uid)) return uid;
   if (obj->TestBit(kIsReferenced)) {
      fgPID->PutObjectWithID(obj,uid);
      return uid;
   }
   if (fgNumber >= 16777215) {
      // This process id is 'full', we need to use a new one.
      fgPID = AddProcessID();
      fgNumber = 0;
      for(Int_t i = 0; i < fgPIDs->GetLast()+1; ++i) {
         TProcessID *pid = (TProcessID*)fgPIDs->At(i);
         if (pid && pid->fObjects && pid->fObjects->GetEntries() == 0) {
            pid->Clear();
         }
      }
   }
   fgNumber++;
   obj->SetBit(kIsReferenced);
   uid = fgNumber;
   // if (fgNumber<10) fgNumber = 16777213; // NOTE: DEBUGGING ONLY MUST BE REMOVED!
   if ( fgPID->GetUniqueID() < 255 ) {
      obj->SetUniqueID( (uid & 0xffffff) + (fgPID->GetUniqueID()<<24) );
   } else {
      obj->SetUniqueID( (uid & 0xffffff) + 0xff000000 /* 255 << 24 */ );
   }
   fgPID->PutObjectWithID(obj,uid);
   return uid;
}

////////////////////////////////////////////////////////////////////////////////
/// Initialize fObjects.

void TProcessID::CheckInit()
{
   if (!fObjects) fObjects = new TObjArray(100);
}

////////////////////////////////////////////////////////////////////////////////
/// static function (called by TROOT destructor) to delete all TProcessIDs

void TProcessID::Cleanup()
{
   R__LOCKGUARD2(gROOTMutex);

   fgPIDs->Delete();
   gROOT->GetListOfCleanups()->Remove(fgPIDs);
   delete fgPIDs;
   fgPIDs = 0;
}

////////////////////////////////////////////////////////////////////////////////
/// delete the TObjArray pointing to referenced objects
/// this function is called by TFile::Close("R")

void TProcessID::Clear(Option_t *)
{
   if (GetUniqueID()>254 && fObjects && fgObjPIDs) {
      // We might have many references registered in the map
      for(Int_t i = 0; i < fObjects->GetSize(); ++i) {
         TObject *obj = fObjects->UncheckedAt(i);
         if (obj) {
            ULong64_t hash = Void_Hash(obj);
            fgObjPIDs->Remove(hash,(Long64_t)obj);
            (*fObjects)[i] = 0;
         }
      }
   }
   delete fObjects; fObjects = 0;
}

////////////////////////////////////////////////////////////////////////////////

Int_t TProcessID::DecrementCount()
{
   // the reference fCount is used to delete the TProcessID
   // in the TFile destructor when fCount = 0

   fCount--;
   if (fCount < 0) fCount = 0;
   return fCount;
}

////////////////////////////////////////////////////////////////////////////////
/// static function returning a pointer to TProcessID number pid in fgPIDs

TProcessID *TProcessID::GetProcessID(UShort_t pid)
{
   return (TProcessID*)fgPIDs->At(pid);
}

////////////////////////////////////////////////////////////////////////////////
/// Return the (static) number of process IDs.

UInt_t TProcessID::GetNProcessIDs()
{
   return fgPIDs ? fgPIDs->GetLast()+1 : 0;
}

////////////////////////////////////////////////////////////////////////////////
/// static function returning a pointer to TProcessID with its pid
/// encoded in the highest byte of uid

TProcessID *TProcessID::GetProcessWithUID(UInt_t uid, const void *obj)
{
   R__LOCKGUARD2(gROOTMutex);

   Int_t pid = (uid>>24)&0xff;
   if (pid==0xff) {
      // Look up the pid in the table (pointer,pid)
      if (fgObjPIDs==0) return 0;
      ULong_t hash = Void_Hash(obj);
      pid = fgObjPIDs->GetValue(hash,(Long_t)obj);
   }
   return (TProcessID*)fgPIDs->At(pid);
}

////////////////////////////////////////////////////////////////////////////////
/// static function returning a pointer to TProcessID with its pid
/// encoded in the highest byte of obj->GetUniqueID()

TProcessID *TProcessID::GetProcessWithUID(const TObject *obj)
{
   return GetProcessWithUID(obj->GetUniqueID(),obj);
}

////////////////////////////////////////////////////////////////////////////////
/// static function returning the pointer to the session TProcessID

TProcessID *TProcessID::GetSessionProcessID()
{
   return fgPID;
}

////////////////////////////////////////////////////////////////////////////////
/// Increase the reference count to this object.

Int_t TProcessID::IncrementCount()
{
   if (!fObjects) fObjects = new TObjArray(100);
   fCount++;
   return fCount;
}

////////////////////////////////////////////////////////////////////////////////
/// Return the current referenced object count
/// fgNumber is incremented everytime a new object is referenced

UInt_t TProcessID::GetObjectCount()
{
   return fgNumber;
}

////////////////////////////////////////////////////////////////////////////////
///returns the TObject with unique identifier uid in the table of objects

TObject *TProcessID::GetObjectWithID(UInt_t uidd)
{
   Int_t uid = uidd & 0xffffff;  //take only the 24 lower bits

   if (fObjects==0 || uid >= fObjects->GetSize()) return 0;
   return fObjects->UncheckedAt(uid);
}

////////////////////////////////////////////////////////////////////////////////
///static: returns pointer to current TProcessID

TProcessID *TProcessID::GetPID()
{
   return fgPID;
}

////////////////////////////////////////////////////////////////////////////////
///static: returns array of TProcessIDs

TObjArray *TProcessID::GetPIDs()
{
   return fgPIDs;
}

////////////////////////////////////////////////////////////////////////////////
/// static function. return kTRUE if pid is a valid TProcessID

Bool_t TProcessID::IsValid(TProcessID *pid)
{
   R__LOCKGUARD2(gROOTMutex);

   if (fgPIDs==0) return kFALSE;
   if (fgPIDs->IndexOf(pid) >= 0) return kTRUE;
   if (pid == (TProcessID*)gROOT->GetUUIDs())  return kTRUE;
   return kFALSE;
}

////////////////////////////////////////////////////////////////////////////////
///stores the object at the uid th slot in the table of objects
///The object uniqueid is set as well as its kMustCleanup bit

void TProcessID::PutObjectWithID(TObject *obj, UInt_t uid)
{
   if (uid == 0) uid = obj->GetUniqueID() & 0xffffff;

   if (!fObjects) fObjects = new TObjArray(100);
   fObjects->AddAtAndExpand(obj,uid);

   obj->SetBit(kMustCleanup);
   if ( (obj->GetUniqueID()&0xff000000)==0xff000000 ) {
      // We have more than 255 pids we need to store this
      // pointer in the table(pointer,pid) since there is no
      // more space in fUniqueID
      if (fgObjPIDs==0) fgObjPIDs = new TExMap;
      ULong_t hash = Void_Hash(obj);

      // We use operator() rather than Add() because
      // if the address has already been registered, we want to
      // update it's uniqueID (this can easily happen when the
      // referenced object have been stored in a TClonesArray.
      (*fgObjPIDs)(hash, (Long_t)obj) = GetUniqueID();
   }
}

////////////////////////////////////////////////////////////////////////////////
/// called by the object destructor
/// remove reference to obj from the current table if it is referenced

void TProcessID::RecursiveRemove(TObject *obj)
{
   if (!fObjects) return;
   if (!obj->TestBit(kIsReferenced)) return;
   UInt_t uid = obj->GetUniqueID() & 0xffffff;
   if (obj == GetObjectWithID(uid)) {
      if (fgObjPIDs) {
         ULong64_t hash = Void_Hash(obj);
         fgObjPIDs->Remove(hash,(Long64_t)obj);
      }
      (*fObjects)[uid] = 0; // Avoid recalculation of fLast (compared to ->RemoveAt(uid))
   }
}

////////////////////////////////////////////////////////////////////////////////
/// static function to set the current referenced object count
/// fgNumber is incremented everytime a new object is referenced

void TProcessID::SetObjectCount(UInt_t number)
{
   fgNumber = number;
}
<commit_msg>Doxygen<commit_after>// @(#)root/cont:$Id$
// Author: Rene Brun   28/09/2001

/*************************************************************************
 * 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.             *
 *************************************************************************/

/** \class TProcessID
A TProcessID identifies a ROOT job in a unique way in time and space.
The TProcessID title consists of a TUUID object which provides a globally
unique identifier (for more see TUUID.h).

A TProcessID is automatically created by the TROOT constructor.
When a TFile contains referenced objects (see TRef), the TProcessID
object is written to the file.
If a file has been written in multiple sessions (same machine or not),
a TProcessID is written for each session.
These objects are used by the class TRef to uniquely identified
any TObject pointed by a TRef.

When a referenced object is read from a file (its bit kIsReferenced is set),
this object is entered into the objects table of the corresponding TProcessID.
Each TFile has a list of TProcessIDs (see TFile::fProcessIDs) also
accessible via TProcessID::fgPIDs (for all files).
When this object is deleted, it is removed from the table via the cleanup
mechanism invoked by the TObject destructor.

Each TProcessID has a table (TObjArray *fObjects) that keeps track
of all referenced objects. If a referenced object has a fUniqueID set,
a pointer to this unique object may be found via fObjects->At(fUniqueID).
In the same way, when a TRef::GetObject is called, GetObject uses
its own fUniqueID to find the pointer to the referenced object.
See TProcessID::GetObjectWithID and PutObjectWithID.

When a referenced object is deleted, its slot in fObjects is set to null.
//
See also TProcessUUID: a specialized TProcessID to manage the single list
of TUUIDs.
*/

#include "TProcessID.h"
#include "TROOT.h"
#include "TObjArray.h"
#include "TExMap.h"
#include "TVirtualMutex.h"
#include "TError.h"

TObjArray  *TProcessID::fgPIDs   = 0; //pointer to the list of TProcessID
TProcessID *TProcessID::fgPID    = 0; //pointer to the TProcessID of the current session
UInt_t      TProcessID::fgNumber = 0; //Current referenced object instance count
TExMap     *TProcessID::fgObjPIDs= 0; //Table (pointer,pids)
ClassImp(TProcessID)

////////////////////////////////////////////////////////////////////////////////
/// Return hash value for this object.

static inline ULong_t Void_Hash(const void *ptr)
{
   return TString::Hash(&ptr, sizeof(void*));
}

////////////////////////////////////////////////////////////////////////////////
/// Default constructor.

TProcessID::TProcessID()
{
   fCount = 0;
   fObjects = 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Destructor.

TProcessID::~TProcessID()
{
   delete fObjects;
   fObjects = 0;
   R__LOCKGUARD2(gROOTMutex);
   fgPIDs->Remove(this);
}

////////////////////////////////////////////////////////////////////////////////
/// Static function to add a new TProcessID to the list of PIDs.

TProcessID *TProcessID::AddProcessID()
{
   R__LOCKGUARD2(gROOTMutex);

   if (fgPIDs && fgPIDs->GetEntriesFast() >= 65534) {
      if (fgPIDs->GetEntriesFast() == 65534) {
         ::Warning("TProcessID::AddProcessID","Maximum number of TProcessID (65535) is almost reached (one left).  TRef will stop being functional when the limit is reached.");
      } else {
         ::Fatal("TProcessID::AddProcessID","Maximum number of TProcessID (65535) has been reached.  TRef are not longer functional.");
      }
   }

   TProcessID *pid = new TProcessID();

   if (!fgPIDs) {
      fgPID  = pid;
      fgPIDs = new TObjArray(10);
      gROOT->GetListOfCleanups()->Add(fgPIDs);
   }
   UShort_t apid = fgPIDs->GetEntriesFast();
   pid->IncrementCount();

   fgPIDs->Add(pid);
   // if (apid == 0) for(int incr=0; incr < 65533; ++incr) fgPIDs->Add(0); // NOTE: DEBUGGING ONLY MUST BE REMOVED!
   char name[20];
   snprintf(name,20,"ProcessID%d",apid);
   pid->SetName(name);
   pid->SetUniqueID((UInt_t)apid);
   TUUID u;
   //apid = fgPIDs->GetEntriesFast();
   pid->SetTitle(u.AsString());
   return pid;
}

////////////////////////////////////////////////////////////////////////////////
/// static function returning the ID assigned to obj
/// If the object is not yet referenced, its kIsReferenced bit is set
/// and its fUniqueID set to the current number of referenced objects so far.

UInt_t TProcessID::AssignID(TObject *obj)
{
   R__LOCKGUARD2(gROOTMutex);

   UInt_t uid = obj->GetUniqueID() & 0xffffff;
   if (obj == fgPID->GetObjectWithID(uid)) return uid;
   if (obj->TestBit(kIsReferenced)) {
      fgPID->PutObjectWithID(obj,uid);
      return uid;
   }
   if (fgNumber >= 16777215) {
      // This process id is 'full', we need to use a new one.
      fgPID = AddProcessID();
      fgNumber = 0;
      for(Int_t i = 0; i < fgPIDs->GetLast()+1; ++i) {
         TProcessID *pid = (TProcessID*)fgPIDs->At(i);
         if (pid && pid->fObjects && pid->fObjects->GetEntries() == 0) {
            pid->Clear();
         }
      }
   }
   fgNumber++;
   obj->SetBit(kIsReferenced);
   uid = fgNumber;
   // if (fgNumber<10) fgNumber = 16777213; // NOTE: DEBUGGING ONLY MUST BE REMOVED!
   if ( fgPID->GetUniqueID() < 255 ) {
      obj->SetUniqueID( (uid & 0xffffff) + (fgPID->GetUniqueID()<<24) );
   } else {
      obj->SetUniqueID( (uid & 0xffffff) + 0xff000000 /* 255 << 24 */ );
   }
   fgPID->PutObjectWithID(obj,uid);
   return uid;
}

////////////////////////////////////////////////////////////////////////////////
/// Initialize fObjects.

void TProcessID::CheckInit()
{
   if (!fObjects) fObjects = new TObjArray(100);
}

////////////////////////////////////////////////////////////////////////////////
/// static function (called by TROOT destructor) to delete all TProcessIDs

void TProcessID::Cleanup()
{
   R__LOCKGUARD2(gROOTMutex);

   fgPIDs->Delete();
   gROOT->GetListOfCleanups()->Remove(fgPIDs);
   delete fgPIDs;
   fgPIDs = 0;
}

////////////////////////////////////////////////////////////////////////////////
/// delete the TObjArray pointing to referenced objects
/// this function is called by TFile::Close("R")

void TProcessID::Clear(Option_t *)
{
   if (GetUniqueID()>254 && fObjects && fgObjPIDs) {
      // We might have many references registered in the map
      for(Int_t i = 0; i < fObjects->GetSize(); ++i) {
         TObject *obj = fObjects->UncheckedAt(i);
         if (obj) {
            ULong64_t hash = Void_Hash(obj);
            fgObjPIDs->Remove(hash,(Long64_t)obj);
            (*fObjects)[i] = 0;
         }
      }
   }
   delete fObjects; fObjects = 0;
}

////////////////////////////////////////////////////////////////////////////////
/// The reference fCount is used to delete the TProcessID
/// in the TFile destructor when fCount = 0

Int_t TProcessID::DecrementCount()
{
   fCount--;
   if (fCount < 0) fCount = 0;
   return fCount;
}

////////////////////////////////////////////////////////////////////////////////
/// static function returning a pointer to TProcessID number pid in fgPIDs

TProcessID *TProcessID::GetProcessID(UShort_t pid)
{
   return (TProcessID*)fgPIDs->At(pid);
}

////////////////////////////////////////////////////////////////////////////////
/// Return the (static) number of process IDs.

UInt_t TProcessID::GetNProcessIDs()
{
   return fgPIDs ? fgPIDs->GetLast()+1 : 0;
}

////////////////////////////////////////////////////////////////////////////////
/// static function returning a pointer to TProcessID with its pid
/// encoded in the highest byte of uid

TProcessID *TProcessID::GetProcessWithUID(UInt_t uid, const void *obj)
{
   R__LOCKGUARD2(gROOTMutex);

   Int_t pid = (uid>>24)&0xff;
   if (pid==0xff) {
      // Look up the pid in the table (pointer,pid)
      if (fgObjPIDs==0) return 0;
      ULong_t hash = Void_Hash(obj);
      pid = fgObjPIDs->GetValue(hash,(Long_t)obj);
   }
   return (TProcessID*)fgPIDs->At(pid);
}

////////////////////////////////////////////////////////////////////////////////
/// static function returning a pointer to TProcessID with its pid
/// encoded in the highest byte of obj->GetUniqueID()

TProcessID *TProcessID::GetProcessWithUID(const TObject *obj)
{
   return GetProcessWithUID(obj->GetUniqueID(),obj);
}

////////////////////////////////////////////////////////////////////////////////
/// static function returning the pointer to the session TProcessID

TProcessID *TProcessID::GetSessionProcessID()
{
   return fgPID;
}

////////////////////////////////////////////////////////////////////////////////
/// Increase the reference count to this object.

Int_t TProcessID::IncrementCount()
{
   if (!fObjects) fObjects = new TObjArray(100);
   fCount++;
   return fCount;
}

////////////////////////////////////////////////////////////////////////////////
/// Return the current referenced object count
/// fgNumber is incremented every time a new object is referenced

UInt_t TProcessID::GetObjectCount()
{
   return fgNumber;
}

////////////////////////////////////////////////////////////////////////////////
/// returns the TObject with unique identifier uid in the table of objects

TObject *TProcessID::GetObjectWithID(UInt_t uidd)
{
   Int_t uid = uidd & 0xffffff;  //take only the 24 lower bits

   if (fObjects==0 || uid >= fObjects->GetSize()) return 0;
   return fObjects->UncheckedAt(uid);
}

////////////////////////////////////////////////////////////////////////////////
/// static: returns pointer to current TProcessID

TProcessID *TProcessID::GetPID()
{
   return fgPID;
}

////////////////////////////////////////////////////////////////////////////////
/// static: returns array of TProcessIDs

TObjArray *TProcessID::GetPIDs()
{
   return fgPIDs;
}

////////////////////////////////////////////////////////////////////////////////
/// static function. return kTRUE if pid is a valid TProcessID

Bool_t TProcessID::IsValid(TProcessID *pid)
{
   R__LOCKGUARD2(gROOTMutex);

   if (fgPIDs==0) return kFALSE;
   if (fgPIDs->IndexOf(pid) >= 0) return kTRUE;
   if (pid == (TProcessID*)gROOT->GetUUIDs())  return kTRUE;
   return kFALSE;
}

////////////////////////////////////////////////////////////////////////////////
/// stores the object at the uid th slot in the table of objects
/// The object uniqued is set as well as its kMustCleanup bit

void TProcessID::PutObjectWithID(TObject *obj, UInt_t uid)
{
   if (uid == 0) uid = obj->GetUniqueID() & 0xffffff;

   if (!fObjects) fObjects = new TObjArray(100);
   fObjects->AddAtAndExpand(obj,uid);

   obj->SetBit(kMustCleanup);
   if ( (obj->GetUniqueID()&0xff000000)==0xff000000 ) {
      // We have more than 255 pids we need to store this
      // pointer in the table(pointer,pid) since there is no
      // more space in fUniqueID
      if (fgObjPIDs==0) fgObjPIDs = new TExMap;
      ULong_t hash = Void_Hash(obj);

      // We use operator() rather than Add() because
      // if the address has already been registered, we want to
      // update it's uniqueID (this can easily happen when the
      // referenced object have been stored in a TClonesArray.
      (*fgObjPIDs)(hash, (Long_t)obj) = GetUniqueID();
   }
}

////////////////////////////////////////////////////////////////////////////////
/// called by the object destructor
/// remove reference to obj from the current table if it is referenced

void TProcessID::RecursiveRemove(TObject *obj)
{
   if (!fObjects) return;
   if (!obj->TestBit(kIsReferenced)) return;
   UInt_t uid = obj->GetUniqueID() & 0xffffff;
   if (obj == GetObjectWithID(uid)) {
      if (fgObjPIDs) {
         ULong64_t hash = Void_Hash(obj);
         fgObjPIDs->Remove(hash,(Long64_t)obj);
      }
      (*fObjects)[uid] = 0; // Avoid recalculation of fLast (compared to ->RemoveAt(uid))
   }
}

////////////////////////////////////////////////////////////////////////////////
/// static function to set the current referenced object count
/// fgNumber is incremented every time a new object is referenced

void TProcessID::SetObjectCount(UInt_t number)
{
   fgNumber = number;
}
<|endoftext|>


<commit_before>// @(#) $Id$
// **************************************************************************
// This file is property of and copyright by the ALICE HLT Project          *
// ALICE Experiment at CERN, All rights reserved.                           *
//                                                                          *
// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
//                  for The ALICE HLT Project.                              *
//                                                                          *
// 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.                    *
//                                                                          *
//***************************************************************************

#include "AliHLTTPCCAParam.h"
#include "AliHLTTPCCAMath.h"

#if !defined(HLTCA_GPUCODE)

GPUdi() AliHLTTPCCAParam::AliHLTTPCCAParam()
    : fISlice( 0 ), fNRows( 63 ), fAlpha( 0.174533 ), fDAlpha( 0.349066 ),
    fCosAlpha( 0 ), fSinAlpha( 0 ), fAngleMin( 0 ), fAngleMax( 0 ), fRMin( 83.65 ), fRMax( 133.3 ),
    fZMin( 0.0529937 ), fZMax( 249.778 ), fErrX( 0 ), fErrY( 0 ), fErrZ( 0.228808 ), fPadPitch( 0.4 ), fBzkG( -5.00668 ),
    fConstBz( -5.00668*0.000299792458 ), fHitPickUpFactor( 1. ),
      fMaxTrackMatchDRow( 4 ), fNeighboursSearchArea(3.), fTrackConnectionFactor( 3.5 ), fTrackChiCut( 3.5 ), fTrackChi2Cut( 10 ), fClusterError2CorrectionY(1.), fClusterError2CorrectionZ(1.),
      fMinNTrackClusters( -1 ), fMaxTrackQPt(1./0.015), fHighQPtForward(1.e10), fNWays(1), fSearchWindowDZDR(0.), fContinuousTracking(false)
{
  // constructor
  fParamS0Par[0][0][0] = 0.00047013;
  fParamS0Par[0][0][1] = 2.00135e-05;
  fParamS0Par[0][0][2] = 0.0106533;
  fParamS0Par[0][0][3] = 5.27104e-08;
  fParamS0Par[0][0][4] = 0.012829;
  fParamS0Par[0][0][5] = 0.000147125;
  fParamS0Par[0][0][6] = 4.99432;
  fParamS0Par[0][1][0] = 0.000883342;
  fParamS0Par[0][1][1] = 1.07011e-05;
  fParamS0Par[0][1][2] = 0.0103187;
  fParamS0Par[0][1][3] = 4.25141e-08;
  fParamS0Par[0][1][4] = 0.0224292;
  fParamS0Par[0][1][5] = 8.27274e-05;
  fParamS0Par[0][1][6] = 4.17233;
  fParamS0Par[0][2][0] = 0.000745399;
  fParamS0Par[0][2][1] = 5.62408e-06;
  fParamS0Par[0][2][2] = 0.0151562;
  fParamS0Par[0][2][3] = 5.08757e-08;
  fParamS0Par[0][2][4] = 0.0601004;
  fParamS0Par[0][2][5] = 7.97129e-05;
  fParamS0Par[0][2][6] = 4.84913;
  fParamS0Par[1][0][0] = 0.00215126;
  fParamS0Par[1][0][1] = 6.82233e-05;
  fParamS0Par[1][0][2] = 0.0221867;
  fParamS0Par[1][0][3] = -6.27825e-09;
  fParamS0Par[1][0][4] = -0.00745378;
  fParamS0Par[1][0][5] = 0.000172629;
  fParamS0Par[1][0][6] = 6.24987;
  fParamS0Par[1][1][0] = 0.00181667;
  fParamS0Par[1][1][1] = -4.17772e-06;
  fParamS0Par[1][1][2] = 0.0253429;
  fParamS0Par[1][1][3] = 1.3011e-07;
  fParamS0Par[1][1][4] = -0.00362827;
  fParamS0Par[1][1][5] = 0.00030406;
  fParamS0Par[1][1][6] = 17.7775;
  fParamS0Par[1][2][0] = 0.00158251;
  fParamS0Par[1][2][1] = -3.55911e-06;
  fParamS0Par[1][2][2] = 0.0247899;
  fParamS0Par[1][2][3] = 7.20604e-08;
  fParamS0Par[1][2][4] = 0.0179946;
  fParamS0Par[1][2][5] = 0.000425504;
  fParamS0Par[1][2][6] = 20.9294;

  for( int i=0; i<200; i++ ) fRowX[i] = 0;

  Update();
}

void AliHLTTPCCAParam::Initialize( int iSlice,
    int nRows, float rowX[],
    float alpha, float dAlpha,
    float rMin, float rMax,
    float zMin, float zMax,
    float padPitch, float zSigma,
    float bz
                                        )
{
  // initialization
  fISlice = iSlice;
  fAlpha = alpha;
  fDAlpha = dAlpha;
  fRMin = rMin;
  fRMax = rMax;
  fZMin = zMin;
  fZMax = zMax;
  fPadPitch = padPitch;
  fErrY = 1.; // not in use
  fErrZ = zSigma;
  fBzkG = bz;
  fNRows = nRows;
  for ( int irow = 0; irow < nRows; irow++ ) {
    fRowX[irow] = rowX[irow];
    //std::cout << " row " << irow << " x= " << rowX[irow] << std::endl;
  }

  Update();
}

void AliHLTTPCCAParam::Update()
{
  // update of calculated values

  const double kCLight = 0.000299792458;
  fConstBz = fBzkG * kCLight;

  fPolinomialFieldBz[0] = fConstBz * (  0.999286   );
  fPolinomialFieldBz[1] = fConstBz * ( -4.54386e-7 );
  fPolinomialFieldBz[2] = fConstBz * (  2.32950e-5 );
  fPolinomialFieldBz[3] = fConstBz * ( -2.99912e-7 );
  fPolinomialFieldBz[4] = fConstBz * ( -2.03442e-8 );
  fPolinomialFieldBz[5] = fConstBz * (  9.71402e-8 );

  fCosAlpha = CAMath::Cos( fAlpha );
  fSinAlpha = CAMath::Sin( fAlpha );
  fAngleMin = fAlpha - fDAlpha / 2.f;
  fAngleMax = fAlpha + fDAlpha / 2.f;
  fErrX = fPadPitch / CAMath::Sqrt( 12. );
  fTrackChi2Cut = fTrackChiCut * fTrackChiCut;
}

#endif

MEM_CLASS_PRE() GPUdi() void MEM_LG(AliHLTTPCCAParam)::Slice2Global( float x, float y,  float z,
    float *X, float *Y,  float *Z ) const
{
  // conversion of coorinates sector->global
  *X = x * fCosAlpha - y * fSinAlpha;
  *Y = y * fCosAlpha + x * fSinAlpha;
  *Z = z;
}

MEM_CLASS_PRE() GPUdi() void MEM_LG(AliHLTTPCCAParam)::Global2Slice( float X, float Y,  float Z,
    float *x, float *y,  float *z ) const
{
  // conversion of coorinates global->sector
  *x = X * fCosAlpha + Y * fSinAlpha;
  *y = Y * fCosAlpha - X * fSinAlpha;
  *z = Z;
}

MEM_CLASS_PRE() GPUdi() float MEM_LG(AliHLTTPCCAParam)::GetClusterError2( int yz, int type, float z, float angle ) const
{
  //* recalculate the cluster error wih respect to the track slope

  float angle2 = angle * angle;
  MakeType(const float*) c = fParamS0Par[yz][type];
  float v = c[0] + z * ( c[1] + c[3] * z ) + angle2 * ( c[2] + angle2 * c[4] + c[5] * z );
  return CAMath::Abs( v );
}

MEM_CLASS_PRE() GPUdi() void MEM_LG(AliHLTTPCCAParam)::GetClusterErrors2( int iRow, float z, float sinPhi, float cosPhi, float DzDs, float &Err2Y, float &Err2Z ) const
{
  //
  // Use calibrated cluster error from OCDB
  //

  z = CAMath::Abs( ( 250. - 0.275 ) - CAMath::Abs( z ) );
  int    type = ( iRow < 63 ) ? 0 : ( ( iRow > 126 ) ? 1 : 2 );
  float cosPhiInv = CAMath::Abs( cosPhi ) > 1.e-2 ? 1. / cosPhi : 0;
  float angleY = sinPhi * cosPhiInv ; // dy/dx
  float angleZ = DzDs * cosPhiInv ; // dz/dx

  Err2Y = GetClusterError2( 0, type, z, angleY );
  Err2Z = GetClusterError2( 1, type, z, angleZ );
}

MEM_CLASS_PRE() GPUdi() void MEM_LG(AliHLTTPCCAParam)::GetClusterErrors2v1( int rowType, float z, float sinPhi, float cosPhi, float DzDs, float &Err2Y, float &Err2Z ) const
{
  //
  // Use calibrated cluster error from OCDB
  //

  z = CAMath::Abs( ( 250. - 0.275 ) - CAMath::Abs( z ) );
  float cosPhiInv = CAMath::Abs( cosPhi ) > 1.e-2 ? 1. / cosPhi : 0;
  float angleY = sinPhi * cosPhiInv ; // dy/dx
  float angleZ = DzDs * cosPhiInv ; // dz/dx

  Err2Y = GetClusterError2( 0, rowType, z, angleY );
  Err2Z = GetClusterError2( 1, rowType, z, angleZ );
}

#ifndef HLTCA_GPUCODE
GPUh() void AliHLTTPCCAParam::WriteSettings( std::ostream &out ) const
{
  // write settings to the file
  out << fISlice << std::endl;
  out << fNRows << std::endl;
  out << fAlpha << std::endl;
  out << fDAlpha << std::endl;
  out << fCosAlpha << std::endl;
  out << fSinAlpha << std::endl;
  out << fAngleMin << std::endl;
  out << fAngleMax << std::endl;
  out << fRMin << std::endl;
  out << fRMax << std::endl;
  out << fZMin << std::endl;
  out << fZMax << std::endl;
  out << fErrX << std::endl;
  out << fErrY << std::endl;
  out << fErrZ << std::endl;
  out << fPadPitch << std::endl;
  out << fBzkG << std::endl;
  out << fHitPickUpFactor << std::endl;
  out << fMaxTrackMatchDRow << std::endl;
  out << fTrackConnectionFactor << std::endl;
  out << fTrackChiCut << std::endl;
  out << fTrackChi2Cut << std::endl;
  for ( int iRow = 0; iRow < fNRows; iRow++ ) {
    out << fRowX[iRow] << std::endl;
  }
  out << std::endl;
  for ( int i = 0; i < 2; i++ )
    for ( int j = 0; j < 3; j++ )
      for ( int k = 0; k < 7; k++ )
        out << fParamS0Par[i][j][k] << std::endl;
  out << std::endl;
}

GPUh() void AliHLTTPCCAParam::ReadSettings( std::istream &in )
{
  // Read settings from the file

  in >> fISlice;
  in >> fNRows;
  in >> fAlpha;
  in >> fDAlpha;
  in >> fCosAlpha;
  in >> fSinAlpha;
  in >> fAngleMin;
  in >> fAngleMax;
  in >> fRMin;
  in >> fRMax;
  in >> fZMin;
  in >> fZMax;
  in >> fErrX;
  in >> fErrY;
  in >> fErrZ;
  in >> fPadPitch;
  in >> fBzkG;
  in >> fHitPickUpFactor;
  in >> fMaxTrackMatchDRow;
  in >> fTrackConnectionFactor;
  in >> fTrackChiCut;
  in >> fTrackChi2Cut;

  if( fNRows<0 || fNRows > 200 ) fNRows = 0;

  for ( int iRow = 0; iRow < fNRows; iRow++ ) {
    in >> fRowX[iRow];
  }
  for ( int i = 0; i < 2; i++ )
    for ( int j = 0; j < 3; j++ )
      for ( int k = 0; k < 7; k++ )
        in >> fParamS0Par[i][j][k];
}
#endif
<commit_msg>unify computation of cluster errors depending on row number or row type<commit_after>// @(#) $Id$
// **************************************************************************
// This file is property of and copyright by the ALICE HLT Project          *
// ALICE Experiment at CERN, All rights reserved.                           *
//                                                                          *
// Primary Authors: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
//                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
//                  for The ALICE HLT Project.                              *
//                                                                          *
// 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.                    *
//                                                                          *
//***************************************************************************

#include "AliHLTTPCCAParam.h"
#include "AliHLTTPCCAMath.h"

#if !defined(HLTCA_GPUCODE)

GPUdi() AliHLTTPCCAParam::AliHLTTPCCAParam()
    : fISlice( 0 ), fNRows( 63 ), fAlpha( 0.174533 ), fDAlpha( 0.349066 ),
    fCosAlpha( 0 ), fSinAlpha( 0 ), fAngleMin( 0 ), fAngleMax( 0 ), fRMin( 83.65 ), fRMax( 133.3 ),
    fZMin( 0.0529937 ), fZMax( 249.778 ), fErrX( 0 ), fErrY( 0 ), fErrZ( 0.228808 ), fPadPitch( 0.4 ), fBzkG( -5.00668 ),
    fConstBz( -5.00668*0.000299792458 ), fHitPickUpFactor( 1. ),
      fMaxTrackMatchDRow( 4 ), fNeighboursSearchArea(3.), fTrackConnectionFactor( 3.5 ), fTrackChiCut( 3.5 ), fTrackChi2Cut( 10 ), fClusterError2CorrectionY(1.), fClusterError2CorrectionZ(1.),
      fMinNTrackClusters( -1 ), fMaxTrackQPt(1./0.015), fHighQPtForward(1.e10), fNWays(1), fSearchWindowDZDR(0.), fContinuousTracking(false)
{
  // constructor
  fParamS0Par[0][0][0] = 0.00047013;
  fParamS0Par[0][0][1] = 2.00135e-05;
  fParamS0Par[0][0][2] = 0.0106533;
  fParamS0Par[0][0][3] = 5.27104e-08;
  fParamS0Par[0][0][4] = 0.012829;
  fParamS0Par[0][0][5] = 0.000147125;
  fParamS0Par[0][0][6] = 4.99432;
  fParamS0Par[0][1][0] = 0.000883342;
  fParamS0Par[0][1][1] = 1.07011e-05;
  fParamS0Par[0][1][2] = 0.0103187;
  fParamS0Par[0][1][3] = 4.25141e-08;
  fParamS0Par[0][1][4] = 0.0224292;
  fParamS0Par[0][1][5] = 8.27274e-05;
  fParamS0Par[0][1][6] = 4.17233;
  fParamS0Par[0][2][0] = 0.000745399;
  fParamS0Par[0][2][1] = 5.62408e-06;
  fParamS0Par[0][2][2] = 0.0151562;
  fParamS0Par[0][2][3] = 5.08757e-08;
  fParamS0Par[0][2][4] = 0.0601004;
  fParamS0Par[0][2][5] = 7.97129e-05;
  fParamS0Par[0][2][6] = 4.84913;
  fParamS0Par[1][0][0] = 0.00215126;
  fParamS0Par[1][0][1] = 6.82233e-05;
  fParamS0Par[1][0][2] = 0.0221867;
  fParamS0Par[1][0][3] = -6.27825e-09;
  fParamS0Par[1][0][4] = -0.00745378;
  fParamS0Par[1][0][5] = 0.000172629;
  fParamS0Par[1][0][6] = 6.24987;
  fParamS0Par[1][1][0] = 0.00181667;
  fParamS0Par[1][1][1] = -4.17772e-06;
  fParamS0Par[1][1][2] = 0.0253429;
  fParamS0Par[1][1][3] = 1.3011e-07;
  fParamS0Par[1][1][4] = -0.00362827;
  fParamS0Par[1][1][5] = 0.00030406;
  fParamS0Par[1][1][6] = 17.7775;
  fParamS0Par[1][2][0] = 0.00158251;
  fParamS0Par[1][2][1] = -3.55911e-06;
  fParamS0Par[1][2][2] = 0.0247899;
  fParamS0Par[1][2][3] = 7.20604e-08;
  fParamS0Par[1][2][4] = 0.0179946;
  fParamS0Par[1][2][5] = 0.000425504;
  fParamS0Par[1][2][6] = 20.9294;

  for( int i=0; i<200; i++ ) fRowX[i] = 0;

  Update();
}

void AliHLTTPCCAParam::Initialize( int iSlice,
    int nRows, float rowX[],
    float alpha, float dAlpha,
    float rMin, float rMax,
    float zMin, float zMax,
    float padPitch, float zSigma,
    float bz
                                        )
{
  // initialization
  fISlice = iSlice;
  fAlpha = alpha;
  fDAlpha = dAlpha;
  fRMin = rMin;
  fRMax = rMax;
  fZMin = zMin;
  fZMax = zMax;
  fPadPitch = padPitch;
  fErrY = 1.; // not in use
  fErrZ = zSigma;
  fBzkG = bz;
  fNRows = nRows;
  for ( int irow = 0; irow < nRows; irow++ ) {
    fRowX[irow] = rowX[irow];
    //std::cout << " row " << irow << " x= " << rowX[irow] << std::endl;
  }

  Update();
}

void AliHLTTPCCAParam::Update()
{
  // update of calculated values

  const double kCLight = 0.000299792458;
  fConstBz = fBzkG * kCLight;

  fPolinomialFieldBz[0] = fConstBz * (  0.999286   );
  fPolinomialFieldBz[1] = fConstBz * ( -4.54386e-7 );
  fPolinomialFieldBz[2] = fConstBz * (  2.32950e-5 );
  fPolinomialFieldBz[3] = fConstBz * ( -2.99912e-7 );
  fPolinomialFieldBz[4] = fConstBz * ( -2.03442e-8 );
  fPolinomialFieldBz[5] = fConstBz * (  9.71402e-8 );

  fCosAlpha = CAMath::Cos( fAlpha );
  fSinAlpha = CAMath::Sin( fAlpha );
  fAngleMin = fAlpha - fDAlpha / 2.f;
  fAngleMax = fAlpha + fDAlpha / 2.f;
  fErrX = fPadPitch / CAMath::Sqrt( 12. );
  fTrackChi2Cut = fTrackChiCut * fTrackChiCut;
}

#endif

MEM_CLASS_PRE() GPUdi() void MEM_LG(AliHLTTPCCAParam)::Slice2Global( float x, float y,  float z,
    float *X, float *Y,  float *Z ) const
{
  // conversion of coorinates sector->global
  *X = x * fCosAlpha - y * fSinAlpha;
  *Y = y * fCosAlpha + x * fSinAlpha;
  *Z = z;
}

MEM_CLASS_PRE() GPUdi() void MEM_LG(AliHLTTPCCAParam)::Global2Slice( float X, float Y,  float Z,
    float *x, float *y,  float *z ) const
{
  // conversion of coorinates global->sector
  *x = X * fCosAlpha + Y * fSinAlpha;
  *y = Y * fCosAlpha - X * fSinAlpha;
  *z = Z;
}

MEM_CLASS_PRE() GPUdi() float MEM_LG(AliHLTTPCCAParam)::GetClusterError2( int yz, int type, float z, float angle ) const
{
  //* recalculate the cluster error wih respect to the track slope
  float angle2 = angle * angle;
  MakeType(const float*) c = fParamS0Par[yz][type];
  float v = c[0] + z * ( c[1] + c[3] * z ) + angle2 * ( c[2] + angle2 * c[4] + c[5] * z );
  return CAMath::Abs( v );
}

MEM_CLASS_PRE() GPUdi() void MEM_LG(AliHLTTPCCAParam)::GetClusterErrors2( int iRow, float z, float sinPhi, float cosPhi, float DzDs, float &Err2Y, float &Err2Z ) const
{
  // Use calibrated cluster error from OCDB
  int    type = ( iRow < 63 ) ? 0 : ( ( iRow > 126 ) ? 1 : 2 );
  GetClusterErrors2v1(type, z, sinPhi, cosPhi, DzDs, Err2Y, Err2Z);
}

MEM_CLASS_PRE() GPUdi() void MEM_LG(AliHLTTPCCAParam)::GetClusterErrors2v1( int rowType, float z, float sinPhi, float cosPhi, float DzDs, float &Err2Y, float &Err2Z ) const
{
  //
  // Use calibrated cluster error from OCDB
  //

  z = CAMath::Abs( ( 250. - 0.275 ) - CAMath::Abs( z ) );
  float cosPhiInv = CAMath::Abs( cosPhi ) > 1.e-2 ? 1. / cosPhi : 0;
  float angleY = sinPhi * cosPhiInv ; // dy/dx
  float angleZ = DzDs * cosPhiInv ; // dz/dx

  Err2Y = GetClusterError2( 0, rowType, z, angleY );
  Err2Z = GetClusterError2( 1, rowType, z, angleZ );
}

#ifndef HLTCA_GPUCODE
GPUh() void AliHLTTPCCAParam::WriteSettings( std::ostream &out ) const
{
  // write settings to the file
  out << fISlice << std::endl;
  out << fNRows << std::endl;
  out << fAlpha << std::endl;
  out << fDAlpha << std::endl;
  out << fCosAlpha << std::endl;
  out << fSinAlpha << std::endl;
  out << fAngleMin << std::endl;
  out << fAngleMax << std::endl;
  out << fRMin << std::endl;
  out << fRMax << std::endl;
  out << fZMin << std::endl;
  out << fZMax << std::endl;
  out << fErrX << std::endl;
  out << fErrY << std::endl;
  out << fErrZ << std::endl;
  out << fPadPitch << std::endl;
  out << fBzkG << std::endl;
  out << fHitPickUpFactor << std::endl;
  out << fMaxTrackMatchDRow << std::endl;
  out << fTrackConnectionFactor << std::endl;
  out << fTrackChiCut << std::endl;
  out << fTrackChi2Cut << std::endl;
  for ( int iRow = 0; iRow < fNRows; iRow++ ) {
    out << fRowX[iRow] << std::endl;
  }
  out << std::endl;
  for ( int i = 0; i < 2; i++ )
    for ( int j = 0; j < 3; j++ )
      for ( int k = 0; k < 7; k++ )
        out << fParamS0Par[i][j][k] << std::endl;
  out << std::endl;
}

GPUh() void AliHLTTPCCAParam::ReadSettings( std::istream &in )
{
  // Read settings from the file

  in >> fISlice;
  in >> fNRows;
  in >> fAlpha;
  in >> fDAlpha;
  in >> fCosAlpha;
  in >> fSinAlpha;
  in >> fAngleMin;
  in >> fAngleMax;
  in >> fRMin;
  in >> fRMax;
  in >> fZMin;
  in >> fZMax;
  in >> fErrX;
  in >> fErrY;
  in >> fErrZ;
  in >> fPadPitch;
  in >> fBzkG;
  in >> fHitPickUpFactor;
  in >> fMaxTrackMatchDRow;
  in >> fTrackConnectionFactor;
  in >> fTrackChiCut;
  in >> fTrackChi2Cut;

  if( fNRows<0 || fNRows > 200 ) fNRows = 0;

  for ( int iRow = 0; iRow < fNRows; iRow++ ) {
    in >> fRowX[iRow];
  }
  for ( int i = 0; i < 2; i++ )
    for ( int j = 0; j < 3; j++ )
      for ( int k = 0; k < 7; k++ )
        in >> fParamS0Par[i][j][k];
}
#endif
<|endoftext|>


<commit_before>#ifndef VIENNAGRID_META_UTILS_HPP
#define VIENNAGRID_META_UTILS_HPP

/* =======================================================================
   Copyright (c) 2011-2014, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include <iterator>

/** @file viennagrid/meta/utils.hpp
    @brief A collection of tools for meta programming
*/

namespace viennagrid
{

  /** @brief An empty type, used within typelists and typemaps */
  class null_type {};

  // some special types
  /** @brief Empty type used to indicate that an element in a typelist/typemap is out of range */
  class out_of_range {};
  /** @brief Empty type indicating that an element in a typelist/typemap wasn't found */
  class not_found {};

  // a static type pair
  /** @brief A static pair time. To be seen as the equivalent of std::pair<>, but for metaprogramming. */
  template<typename FirstT, typename SecondT>
  struct static_pair
  {
    typedef FirstT   first;
    typedef SecondT  second;
  };

  namespace detail
  {
    // basic operations
    template<typename type1, typename type2>
    struct EQUAL
    {
      static const bool value = false;
    };

    template<typename type>
    struct EQUAL<type,type>
    {
      static const bool value = true;
    };

    template<typename type1, typename type2>
    struct NOT_EQUAL
    {
      static const bool value = !EQUAL<type1, type2>::value;
    };

    template<bool condition, typename type1, typename type2>
    struct IF
    {
      typedef type1 type;
    };

    template<typename type1, typename type2>
    struct IF<false, type1, type2>
    {
      typedef type2 type;
    };

    template<typename T>
    struct IDENTITY
    {
      typedef T type;
    };

    // error generator
    template<bool ErrorT>
    struct STATIC_ASSERT
    {
      typedef void type;
    };

    template<>
    struct STATIC_ASSERT<false>
    {};

    namespace result_of
    {
      template<typename pair>
      struct first
      {
          typedef not_found type;
      };

      template<typename first_, typename second_>
      struct first< static_pair<first_, second_> >
      {
          typedef first_ type;
      };

      template<typename pair>
      struct second
      {
          typedef not_found type;
      };

      template<typename first_, typename second_>
      struct second< static_pair<first_, second_> >
      {
          typedef second_ type;
      };
    }

    // a tag wrapper
    template<typename foo>
    class tag {};

    // a true functor
    struct true_predicate
    {
      template<typename type>
      bool operator()(const type &)
      {
          return true;
      }
    };

    template<typename some_type>
    struct remove_const
    {
      typedef some_type type;
    };

    template<typename some_type>
    struct remove_const<const some_type>
    {
      typedef some_type type;
    };

    // http://stackoverflow.com/questions/5423246/how-to-detect-if-a-type-is-an-iterator-or-const-iterator
    template<typename T>
    struct is_const_pointer { static const bool value = false; };

    template<typename T>
    struct is_const_pointer<const T*> { static const bool value = true; };

    template <typename TIterator>
    struct is_const_iterator
    {
      typedef typename std::iterator_traits<TIterator>::pointer pointer;
      static const bool value = is_const_pointer<pointer>::value;
    };

  } // namespace detail
} // namespace viennagrid

#endif
<commit_msg>Delete utils.hpp<commit_after><|endoftext|>


<commit_before>#include "stdafx.h"
#include "AdvCalc.h"
#include <intrin.h>

AdvCalc::AdvCalc()
{
	// ڴ
	m_pV = (float*)_aligned_malloc(sizeof(float) * c_len, 64);
	//
	for (int i = 0;i < c_len;i++) {
		m_pV[i] = 1.0f * rand() / RAND_MAX;
	}
}

AdvCalc::~AdvCalc()
{
	_aligned_free(m_pV);
	m_pV = NULL;
}

// SIMD֧
BOOL AdvCalc::IsSupport(SIMD level)
{
	// https://en.wikipedia.org/wiki/CPUID

	int cpuinfo[4], cpuinfo7[4];
	__cpuid(cpuinfo, 0x01);
	__cpuid(cpuinfo7, 0x07);
	int ebx = cpuinfo7[1];
	int ecx = cpuinfo[2];
	int edx = cpuinfo[3];

	BOOL bSupport = FALSE;
	switch (level)
	{
	case NA:
		bSupport = TRUE;
		break;
	case MMX:
		bSupport = edx & 0x00800000;
		break;
	case SSE:
		bSupport = edx & 0x02000000;
		break;
	case AVX:
		bSupport = ecx & 0x10000000;
		break;
	case FMA:
		bSupport = ecx & 0x00001000;
		break;
	case AVX512:
		bSupport = ebx & 0x04000000;
		break;
	default:
		break;
	}

	return bSupport;
}

//
float AdvCalc::calcBasic()
{
	float fSum;
	for (int j = 0;j < c_loop;j++) {
		fSum = 0.0f;
		for (int i = 0;i < c_len;i++) {
			float fX = m_fA * m_pV[i] + m_fB;
			fSum += fX;
		}
	}
	return fSum;
}

// SSE
float AdvCalc::calcSSE()
{
	float fSum;
	for (int j = 0;j < c_loop;j++) {
		__m128 a = _mm_set_ps1(m_fA);
		__m128 b = _mm_set_ps1(m_fB);
		__m128* pV = (__m128*)m_pV;
		__m128 sum = _mm_set_ps1(0.0f);

		for (int i = 0;i < c_len / 4;i++) {
			__m128 x = _mm_mul_ps(a, pV[i]);
			x = _mm_add_ps(x, b);
			sum = _mm_add_ps(sum, x);
		}

		float* pSum = (float*)_aligned_malloc(sizeof(float) * 4, 64);
		_mm_store_ps(pSum, sum);

		fSum = 0.0f;
		for (int i = 0;i < 4;i++) {
			fSum += pSum[i];
		}
		_aligned_free(pSum);
	}

	return fSum;
}

// AVX
float AdvCalc::calcAVX()
{
	float fSum;
	for (int j = 0;j < c_loop;j++) {
		__m256 a = _mm256_set1_ps(m_fA);
		__m256 b = _mm256_set1_ps(m_fB);
		__m256* pV = (__m256*)m_pV;
		__m256 sum = _mm256_set1_ps(0.0f);

		for (int i = 0;i < c_len / 8;i++) {
			__m256 x = _mm256_mul_ps(a, pV[i]);
			x = _mm256_add_ps(x, b);
			sum = _mm256_add_ps(sum, x);
		}

		sum = _mm256_hadd_ps(sum, sum);
		sum = _mm256_hadd_ps(sum, sum);
		sum = _mm256_hadd_ps(sum, sum);

		float* pSum = (float*)_aligned_malloc(sizeof(float) * 8, 64);
		_mm256_store_ps(pSum, sum);
		fSum = *pSum;
		_aligned_free(pSum);
	}
	return fSum;
}

// FMA
float AdvCalc::calcFMA()
{
	float fSum;
	for (int j = 0;j < c_loop;j++) {
		__m256 a = _mm256_set1_ps(m_fA);
		__m256 b = _mm256_set1_ps(m_fB);
		__m256* pV = (__m256*)m_pV;
		__m256 sum = _mm256_set1_ps(0.0f);

		for (int i = 0;i < c_len / 8;i++) {
			__m256 x = _mm256_fmadd_ps(pV[i], a, b);
			sum = _mm256_add_ps(sum, x);
		}

		sum = _mm256_hadd_ps(sum, sum);
		sum = _mm256_hadd_ps(sum, sum);
		sum = _mm256_hadd_ps(sum, sum);

		float* pSum = (float*)_aligned_malloc(sizeof(float) * 8, 64);
		_mm256_store_ps(pSum, sum);
		fSum = *pSum;
		_aligned_free(pSum);
	}
	return fSum;
}

// AVX512
float AdvCalc::calcAVX512()
{
	float fSum;
	for (int j = 0;j < c_loop;j++) {
		__m512 a = _mm512_set1_ps(m_fA);
		__m512 b = _mm512_set1_ps(m_fB);
		__m512* pV = (__m512*)m_pV;
		__m512 sum = _mm512_set1_ps(0.0f);

		for (int i = 0;i < c_len / 16;i++) {
			__m512 x = _mm512_mul_ps(a, pV[i]);
			x = _mm512_add_ps(x, b);
			sum = _mm512_add_ps(sum, x);
		}

		float* pSum = (float*)_aligned_malloc(sizeof(float) * 16, 64);
		_mm512_store_ps(pSum, sum);

		fSum = 0.0f;
		for (int i = 0;i < 16;i++) {
			fSum += pSum[i];
		}
		_aligned_free(pSum);
	}
	return fSum;
}<commit_msg>AVX512<commit_after>#include "stdafx.h"
#include "AdvCalc.h"
#include <intrin.h>

AdvCalc::AdvCalc()
{
	// ڴ
	m_pV = (float*)_aligned_malloc(sizeof(float) * c_len, 64);
	//
	for (int i = 0;i < c_len;i++) {
		m_pV[i] = 1.0f * rand() / RAND_MAX;
	}
}

AdvCalc::~AdvCalc()
{
	_aligned_free(m_pV);
	m_pV = NULL;
}

// SIMD֧
BOOL AdvCalc::IsSupport(SIMD level)
{
	// https://en.wikipedia.org/wiki/CPUID

	int cpuinfo[4], cpuinfo7[4];
	__cpuid(cpuinfo, 0x01);
	__cpuid(cpuinfo7, 0x07);
	int ebx = cpuinfo7[1];
	int ecx = cpuinfo[2];
	int edx = cpuinfo[3];

	BOOL bSupport = FALSE;
	switch (level)
	{
	case NA:
		bSupport = TRUE;
		break;
	case MMX:
		bSupport = edx & 0x00800000;
		break;
	case SSE:
		bSupport = edx & 0x02000000;
		break;
	case AVX:
		bSupport = ecx & 0x10000000;
		break;
	case FMA:
		bSupport = ecx & 0x00001000;
		break;
	case AVX512:
		bSupport = ebx & 0x04000000;
		break;
	default:
		break;
	}

	return bSupport;
}

//
float AdvCalc::calcBasic()
{
	float fSum;
	for (int j = 0;j < c_loop;j++) {
		fSum = 0.0f;
		for (int i = 0;i < c_len;i++) {
			float fX = m_fA * m_pV[i] + m_fB;
			fSum += fX;
		}
	}
	return fSum;
}

// SSE
float AdvCalc::calcSSE()
{
	float fSum;
	for (int j = 0;j < c_loop;j++) {
		__m128 a = _mm_set_ps1(m_fA);
		__m128 b = _mm_set_ps1(m_fB);
		__m128* pV = (__m128*)m_pV;
		__m128 sum = _mm_set_ps1(0.0f);

		for (int i = 0;i < c_len / 4;i++) {
			__m128 x = _mm_mul_ps(a, pV[i]);
			x = _mm_add_ps(x, b);
			sum = _mm_add_ps(sum, x);
		}

		float* pSum = (float*)_aligned_malloc(sizeof(float) * 4, 64);
		_mm_store_ps(pSum, sum);

		fSum = 0.0f;
		for (int i = 0;i < 4;i++) {
			fSum += pSum[i];
		}
		_aligned_free(pSum);
	}

	return fSum;
}

// AVX
float AdvCalc::calcAVX()
{
	float fSum;
	for (int j = 0;j < c_loop;j++) {
		__m256 a = _mm256_set1_ps(m_fA);
		__m256 b = _mm256_set1_ps(m_fB);
		__m256* pV = (__m256*)m_pV;
		__m256 sum = _mm256_set1_ps(0.0f);

		for (int i = 0;i < c_len / 8;i++) {
			__m256 x = _mm256_mul_ps(a, pV[i]);
			x = _mm256_add_ps(x, b);
			sum = _mm256_add_ps(sum, x);
		}

		sum = _mm256_hadd_ps(sum, sum);
		sum = _mm256_hadd_ps(sum, sum);
		sum = _mm256_hadd_ps(sum, sum);

		float* pSum = (float*)_aligned_malloc(sizeof(float) * 8, 64);
		_mm256_store_ps(pSum, sum);
		fSum = *pSum;
		_aligned_free(pSum);
	}
	return fSum;
}

// FMA
float AdvCalc::calcFMA()
{
	float fSum;
	for (int j = 0;j < c_loop;j++) {
		__m256 a = _mm256_set1_ps(m_fA);
		__m256 b = _mm256_set1_ps(m_fB);
		__m256* pV = (__m256*)m_pV;
		__m256 sum = _mm256_set1_ps(0.0f);

		for (int i = 0;i < c_len / 8;i++) {
			__m256 x = _mm256_fmadd_ps(pV[i], a, b);
			sum = _mm256_add_ps(sum, x);
		}

		sum = _mm256_hadd_ps(sum, sum);
		sum = _mm256_hadd_ps(sum, sum);
		sum = _mm256_hadd_ps(sum, sum);

		float* pSum = (float*)_aligned_malloc(sizeof(float) * 8, 64);
		_mm256_store_ps(pSum, sum);
		fSum = *pSum;
		_aligned_free(pSum);
	}
	return fSum;
}

// AVX512
float AdvCalc::calcAVX512()
{
	float fSum;
	for (int j = 0;j < c_loop;j++) {
		__m512 a = _mm512_set1_ps(m_fA);
		__m512 b = _mm512_set1_ps(m_fB);
		__m512* pV = (__m512*)m_pV;
		__m512 sum = _mm512_set1_ps(0.0f);

		for (int i = 0;i < c_len / 16;i++) {
			__m512 x = _mm512_fmadd_ps(pV[i], a, b);
			sum = _mm512_add_ps(sum, x);
		}

		float* pSum = (float*)_aligned_malloc(sizeof(float) * 16, 64);
		_mm512_store_ps(pSum, sum);

		fSum = 0.0f;
		for (int i = 0;i < 16;i++) {
			fSum += pSum[i];
		}
		_aligned_free(pSum);
	}
	return fSum;
}<|endoftext|>


<commit_before>/*
 *  Support functions for VHDL output.
 *
 *  Copyright (C) 2008  Nick Gasson (nick@nickg.me.uk)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "vhdl_target.h"
#include "support.hh"

#include <cassert>
#include <iostream>

void require_support_function(support_function_t f)
{
   vhdl_scope *scope = get_active_entity()->get_arch()->get_scope();
   if (!scope->have_declared(support_function::function_name(f)))
      scope->add_decl(new support_function(f));
}

const char *support_function::function_name(support_function_t type)
{
   switch (type) {
   case SF_UNSIGNED_TO_BOOLEAN: return "Unsigned_To_Boolean";
   case SF_SIGNED_TO_BOOLEAN:   return "Signed_To_Boolean";
   case SF_BOOLEAN_TO_LOGIC:    return "Boolean_To_Logic";
   case SF_REDUCE_OR:           return "Reduce_OR";
   case SF_REDUCE_AND:          return "Reduce_AND";
   case SF_REDUCE_XOR:          return "Reduce_XOR";
   case SF_TERNARY_LOGIC:       return "Ternary_Logic";
   case SF_TERNARY_UNSIGNED:    return "Ternary_Unsigned";
   case SF_TERNARY_SIGNED:      return "Ternary_Signed";
   case SF_LOGIC_TO_INTEGER:    return "Logic_To_Integer";
   default:
      assert(false);
   }
}

vhdl_type *support_function::function_type(support_function_t type)
{
   switch (type) {
   case SF_UNSIGNED_TO_BOOLEAN:
   case SF_SIGNED_TO_BOOLEAN:
      return vhdl_type::boolean();
   case SF_BOOLEAN_TO_LOGIC:
   case SF_REDUCE_OR:
   case SF_REDUCE_AND:
   case SF_REDUCE_XOR:
   case SF_TERNARY_LOGIC:
      return vhdl_type::std_logic();
   case SF_LOGIC_TO_INTEGER:
      return vhdl_type::integer();
   default:
      assert(false);
   }
}

void support_function::emit_ternary(std::ostream &of, int level) const
{
   of << "begin" << nl_string(indent(level))
      << "if T then return X; else return Y; end if;"
      << nl_string(level);
}

void support_function::emit(std::ostream &of, int level) const
{
   of << "function " << function_name(type_);

   switch (type_) {
   case SF_UNSIGNED_TO_BOOLEAN:
      of << "(X : unsigned) return Boolean is" << nl_string(level)
         << "begin" << nl_string(indent(level))
         << "return X /= To_Unsigned(0, X'Length);" << nl_string(level);
      break;
   case SF_SIGNED_TO_BOOLEAN:
      of << "(X : signed) return Boolean is" << nl_string(level)
         << "begin" << nl_string(indent(level))
         << "return X /= To_Signed(0, X'Length);" << nl_string(level);
      break;
   case SF_BOOLEAN_TO_LOGIC:
      of << "(B : Boolean) return std_logic is" << nl_string(level)
         << "begin" << nl_string(indent(level))
         << "if B then" << nl_string(indent(indent(level)))
         << "return '1';" << nl_string(indent(level))
         << "else" << nl_string(indent(indent(level)))
         << "return '0';" << nl_string(indent(level))
         << "end if;" << nl_string(level);
      break;
   case SF_REDUCE_OR:
      of << "(X : std_logic_vector) return std_logic is" << nl_string(level)
         << "begin" << nl_string(indent(level))
         << "for I in X'Range loop" << nl_string(indent(indent(level)))
         << "if X(I) = '1' then" << nl_string(indent(indent(indent(level))))
         << "return '1';" << nl_string(indent(indent(level)))
         << "end if;" << nl_string(indent(level))
         << "end loop;" << nl_string(indent(level))
         << "return '0';" << nl_string(level);
      break;
   case SF_REDUCE_AND:
      of << "(X : std_logic_vector) return std_logic is" << nl_string(level)
         << "begin" << nl_string(indent(level))
         << "for I in X'Range loop" << nl_string(indent(indent(level)))
         << "if X(I) = '0' then" << nl_string(indent(indent(indent(level))))
         << "return '0';" << nl_string(indent(indent(level)))
         << "end if;" << nl_string(indent(level))
         << "end loop;" << nl_string(indent(level))
         << "return '1';" << nl_string(level);
      break;
   case SF_REDUCE_XOR:
      of << "(X : std_logic_vector) return std_logic is"
         << nl_string(indent(level))
         << "variable R : std_logic := '0';" << nl_string(level)
         << "begin" << nl_string(indent(level))
         << "for I in X'Range loop" << nl_string(indent(indent(level)))
         << "R := X(I) xor R;" << nl_string(indent(level))
         << "end loop;" << nl_string(indent(level))
         << "return R;" << nl_string(level);
      break;
   case SF_TERNARY_LOGIC:
      of << "(T : Boolean; X, Y : std_logic) return std_logic is"
         << nl_string(level);
      emit_ternary(of, level);
      break;
   case SF_TERNARY_SIGNED:
      of << "(T : Boolean; X, Y : signed) return signed is"
         << nl_string(level);
      emit_ternary(of, level);
      break;
   case SF_TERNARY_UNSIGNED:
      of << "(T : Boolean; X, Y : signed) return unsigned is"
         << nl_string(level);
      emit_ternary(of, level);
      break;
   case SF_LOGIC_TO_INTEGER:
      of << "(X : std_logic) return integer is" << nl_string(level)
         << "begin" << nl_string(indent(level))
         << "if X = '1' then return 1; else return 0; end if;"
         << nl_string(level);
      break;
   default:
      assert(false);
   }

   of << "end function;" << nl_string(level);
}
<commit_msg>Simplify support function emitting code<commit_after>/*
 *  Support functions for VHDL output.
 *
 *  Copyright (C) 2008  Nick Gasson (nick@nickg.me.uk)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "vhdl_target.h"
#include "support.hh"

#include <cassert>
#include <iostream>

void require_support_function(support_function_t f)
{
   vhdl_scope *scope = get_active_entity()->get_arch()->get_scope();
   if (!scope->have_declared(support_function::function_name(f)))
      scope->add_decl(new support_function(f));
}

const char *support_function::function_name(support_function_t type)
{
   switch (type) {
   case SF_UNSIGNED_TO_BOOLEAN: return "Unsigned_To_Boolean";
   case SF_SIGNED_TO_BOOLEAN:   return "Signed_To_Boolean";
   case SF_BOOLEAN_TO_LOGIC:    return "Boolean_To_Logic";
   case SF_REDUCE_OR:           return "Reduce_OR";
   case SF_REDUCE_AND:          return "Reduce_AND";
   case SF_REDUCE_XOR:          return "Reduce_XOR";
   case SF_TERNARY_LOGIC:       return "Ternary_Logic";
   case SF_TERNARY_UNSIGNED:    return "Ternary_Unsigned";
   case SF_TERNARY_SIGNED:      return "Ternary_Signed";
   case SF_LOGIC_TO_INTEGER:    return "Logic_To_Integer";
   default:
      assert(false);
   }
}

vhdl_type *support_function::function_type(support_function_t type)
{
   switch (type) {
   case SF_UNSIGNED_TO_BOOLEAN:
   case SF_SIGNED_TO_BOOLEAN:
      return vhdl_type::boolean();
   case SF_BOOLEAN_TO_LOGIC:
   case SF_REDUCE_OR:
   case SF_REDUCE_AND:
   case SF_REDUCE_XOR:
   case SF_TERNARY_LOGIC:
      return vhdl_type::std_logic();
   case SF_LOGIC_TO_INTEGER:
      return vhdl_type::integer();
   default:
      assert(false);
   }
}

void support_function::emit_ternary(std::ostream &of, int level) const
{
   of << nl_string(level) << "begin" << nl_string(indent(level))
      << "if T then return X; else return Y; end if;";
}

void support_function::emit(std::ostream &of, int level) const
{
   of << "function " << function_name(type_);

   switch (type_) {
   case SF_UNSIGNED_TO_BOOLEAN:
      of << "(X : unsigned) return Boolean is" << nl_string(level)
         << "begin" << nl_string(indent(level))
         << "return X /= To_Unsigned(0, X'Length);";
      break;
   case SF_SIGNED_TO_BOOLEAN:
      of << "(X : signed) return Boolean is" << nl_string(level)
         << "begin" << nl_string(indent(level))
         << "return X /= To_Signed(0, X'Length);";
      break;
   case SF_BOOLEAN_TO_LOGIC:
      of << "(B : Boolean) return std_logic is" << nl_string(level)
         << "begin" << nl_string(indent(level))
         << "if B then" << nl_string(indent(indent(level)))
         << "return '1';" << nl_string(indent(level))
         << "else" << nl_string(indent(indent(level)))
         << "return '0';" << nl_string(indent(level))
         << "end if;";
      break;
   case SF_REDUCE_OR:
      of << "(X : std_logic_vector) return std_logic is" << nl_string(level)
         << "begin" << nl_string(indent(level))
         << "for I in X'Range loop" << nl_string(indent(indent(level)))
         << "if X(I) = '1' then" << nl_string(indent(indent(indent(level))))
         << "return '1';" << nl_string(indent(indent(level)))
         << "end if;" << nl_string(indent(level))
         << "end loop;" << nl_string(indent(level))
         << "return '0';";
      break;
   case SF_REDUCE_AND:
      of << "(X : std_logic_vector) return std_logic is" << nl_string(level)
         << "begin" << nl_string(indent(level))
         << "for I in X'Range loop" << nl_string(indent(indent(level)))
         << "if X(I) = '0' then" << nl_string(indent(indent(indent(level))))
         << "return '0';" << nl_string(indent(indent(level)))
         << "end if;" << nl_string(indent(level))
         << "end loop;" << nl_string(indent(level))
         << "return '1';";
      break;
   case SF_REDUCE_XOR:
      of << "(X : std_logic_vector) return std_logic is"
         << nl_string(indent(level))
         << "variable R : std_logic := '0';" << nl_string(level)
         << "begin" << nl_string(indent(level))
         << "for I in X'Range loop" << nl_string(indent(indent(level)))
         << "R := X(I) xor R;" << nl_string(indent(level))
         << "end loop;" << nl_string(indent(level))
         << "return R;";
      break;
   case SF_TERNARY_LOGIC:
      of << "(T : Boolean; X, Y : std_logic) return std_logic is";
      emit_ternary(of, level);
      break;
   case SF_TERNARY_SIGNED:
      of << "(T : Boolean; X, Y : signed) return signed is";
      emit_ternary(of, level);
      break;
   case SF_TERNARY_UNSIGNED:
      of << "(T : Boolean; X, Y : signed) return unsigned is";
      emit_ternary(of, level);
      break;
   case SF_LOGIC_TO_INTEGER:
      of << "(X : std_logic) return integer is" << nl_string(level)
         << "begin" << nl_string(indent(level))
         << "if X = '1' then return 1; else return 0; end if;";
      break;
   default:
      assert(false);
   }

   of << nl_string(level) << "end function;" << nl_string(level);
}
<|endoftext|>


<commit_before>// binary search for the depletion voltage of a point contact detector
using namespace GeFiCa;
void search4Vd()
{
   PointContactDZ *vi; // potential (v) due to impurity (i) alone
   PointContactDZ *vu; // potential (v) due to unit (u) bias alone
   PointContactDZ *vt; // totoal (t) potential (v) = vu * bias + vi
   TFile *fi; // ROOT file used to save vi
   TFile *fu; // ROOT file used to save vu

   cout<<"\ncalculate or load potential due to space charge alone:"<<endl;
   if (FILE *input = fopen("impurity.root","r")) { // load from fi
      fclose(input);
      fi = new TFile("impurity.root"); // read only
      vi = (PointContactDZ*) fi->Get("vi");
   } else { // a fresh calculation
      fi = new TFile("impurity.root", "recreate");

      vi = new PointContactDZ(690,505); vi->SetName("vi");
      vi->V0=0; vi->V1=0; // no bias
      vi->Z=5.05*cm; vi->Radius=3.45*cm;
      vi->PointContactZ=0.21*cm; vi->PointContactR=0.14*cm;

      // x in TF3 -> r in PointContactDZ, y in TF3 -> z in PointContactDZ
      TF3 *impurityDistribution = new TF3("fi","-0.318e10+0.025e10*y");
      vi->SetImpurity(impurityDistribution);

      vi->Csor=1.994; // speed up SOR
      vi->CalculatePotential(kSOR2);

      vi->Write(); // save itself to fi
   }
   vi->Dump(); // print configurations

   cout<<"\ncalculate or load potential due to unit bias:"<<endl;
   if (FILE *input = fopen("oneVolt.root","r")) { // load from fu
      fclose(input);
      fu = new TFile("oneVolt.root"); // read only
      vu = (PointContactDZ*) fu->Get("vu");
   } else { // a fresh calculation
      fu = new TFile("oneVolt.root", "recreate");

      vu = new PointContactDZ(690,505); vu->SetName("vu");
      vu->V0=1*volt; vu->V1=0*volt;
      vu->Z=5.05*cm; vu->Radius=3.45*cm;
      vu->PointContactZ=0.21*cm; vu->PointContactR=0.14*cm;
      vu->SetImpurity(new TF3("wpi","0")); // no impurity

      vu->Csor=1.994;
      vu->CalculatePotential(kSOR2);

      vu->Write(); // save itself to fu
   }
   vu->Dump(); // print configurations

   double bias, vLower=0*volt, vUpper=2e4*volt; // range of search
   cout<<"\nStart binary search in ["<<vLower<<", "<<vUpper<<"] V"<<endl;
   while (vUpper-vLower>0.1*volt) { // binary search
      bias=(vUpper+vLower)/2; // a new guess
      // vt = vu*bias + vi
      vt = (PointContactDZ*) vu->Clone("vt");
      (*vt)*=bias; (*vt)+=vi;
      // updating range
      if (vt->IsDepleted()) vUpper=bias;
      else vLower=bias;

      delete vt;
      cout<<"Current guess: "<<bias<<" V, ";
      cout<<"new search range: ["<<vLower<<", "<<vUpper<<"]"<<endl;
   }
   cout<<"The depletion voltage is found to be: "<<bias<<" V"<<endl;

   fu->Close();
   fi->Close();
   delete fi;
   delete fu;
}
<commit_msg>updated<commit_after>// binary search for the depletion voltage of a point contact detector
using namespace GeFiCa;
void search4Vd()
{
   PointContactDZ *vi; // potential (v) due to impurity (i) alone
   PointContactDZ *vu; // potential (v) due to unit (u) bias alone
   PointContactDZ *vt; // totoal (t) potential (v) = vu * bias + vi
   TFile *fi; // ROOT file used to save vi
   TFile *fu; // ROOT file used to save vu

   cout<<"\ncalculate or load potential due to space charge alone:"<<endl;
   if (FILE *input = fopen("impurity.root","r")) { // load from fi
      fclose(input);
      fi = new TFile("impurity.root"); // read only
      vi = (PointContactDZ*) fi->Get("vi");
   } else { // a fresh calculation
      fi = new TFile("impurity.root", "recreate");

      vi = new PointContactDZ(690,505); vi->SetName("vi");
      vi->V0=0; vi->V1=0; // no bias
      vi->Height=5.05*cm; vi->Radius=3.45*cm;
      vi->PointContactH=0.21*cm; vi->PointContactR=0.14*cm;

      // x in TF3 -> r in PointContactDZ, y in TF3 -> z in PointContactDZ
      TF3 *fid = new TF3("fImpDistr","-0.318e10+0.025e10*y");
      vi->SetImpurity(fid);

      vi->Csor=1.994; // speed up SOR
      vi->CalculatePotential(kSOR2);

      vi->Write(); // save itself to fi
   }
   vi->Dump(); // print configurations

   cout<<"\ncalculate or load potential due to unit bias:"<<endl;
   if (FILE *input = fopen("oneVolt.root","r")) { // load from fu
      fclose(input);
      fu = new TFile("oneVolt.root"); // read only
      vu = (PointContactDZ*) fu->Get("vu");
   } else { // a fresh calculation
      fu = new TFile("oneVolt.root", "recreate");

      vu = new PointContactDZ(690,505); vu->SetName("vu");
      vu->V0=1*volt; vu->V1=0*volt;
      vu->Height=5.05*cm; vu->Radius=3.45*cm;
      vu->PointContactH=0.21*cm; vu->PointContactR=0.14*cm;
      vu->SetAverageImpurity(0); // no impurity

      vu->Csor=1.994;
      vu->CalculatePotential(kSOR2);

      vu->Write(); // save itself to fu
   }
   vu->Dump(); // print configurations

   double bias, vLower=0*volt, vUpper=2e4*volt; // range of search
   cout<<"\nStart binary search in ["<<vLower<<", "<<vUpper<<"] V"<<endl;
   while (vUpper-vLower>0.1*volt) { // binary search
      bias=(vUpper+vLower)/2; // a new guess
      // vt = vu*bias + vi
      vt = (PointContactDZ*) vu->Clone("vt");
      (*vt)*=bias; (*vt)+=vi;
      // updating range
      if (vt->IsDepleted()) vUpper=bias;
      else vLower=bias;

      delete vt;
      cout<<"Current guess: "<<bias<<" V, ";
      cout<<"new search range: ["<<vLower<<", "<<vUpper<<"]"<<endl;
   }
   cout<<"The depletion voltage is found to be: "<<bias<<" V"<<endl;

   fu->Close();
   fi->Close();
   delete fi;
   delete fu;
}
<|endoftext|>


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

 The MIT License (MIT)

 Copyright (c) 2015 Dmitry Sovetov

 https://github.com/dmsovetov

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:
 The above copyright notice and this permission notice shall be included in all
 copies or substantial portions of the Software.
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.

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

// Include the engine header file.
#include <Dreemchest.h>

#define LOCAL_MODE	(1)

// Open a root engine namespace
DC_USE_DREEMCHEST

// Open a platform namespace.
using namespace Platform;

// Open a net namespace.
using namespace net;

thread::Thread* serverThread = NULL;

// Application delegate is used to handle an events raised by application instance.
class NetworkHandlers : public ApplicationDelegate {

	struct LolEvent : public io::Serializable {
		ClassEnableTypeId( LolEvent )
		ClassEnableCloning( LolEvent )

		int x;
		std::string bar;

		IoBeginSerializer
			IoField( x )
			IoField( bar )
		IoEndSerializer

		LolEvent( int x = 0, std::string bar = "" ) : x( x ), bar( bar ) {}
	};

	struct ExtraEvent : public io::Serializable {
		ClassEnableTypeId( ExtraEvent )
		ClassEnableCloning( ExtraEvent )
	};

    // This method will be called once an application is launched.
    virtual void handleLaunched( Application* application )
	{
        // Setup default loggers
        Platform::log::setStandardHandler();
        net::log::setStandardHandler();

		//! Create a network interface
		Network network;

	#if LOCAL_MODE
		ServerHandlerPtr server = startServer( application, 20000 );
		serverThread = thread::Thread::create();
		serverThread->start( dcThisMethod( NetworkHandlers::updateServer ), server.get() );

		ClientHandlerPtr client = connectToServer( application, 20000 );
		client->registerEvent<LolEvent>();
		client->registerEvent<ExtraEvent>();
		client->subscribe<LolEvent>( dcThisMethod( NetworkHandlers::handleLolEvent ) );
		client->subscribe<ExtraEvent>( dcThisMethod( NetworkHandlers::handleExtraEvent ) );

		while( true ) {
			client->update();
		}
	#else
		ClientHandlerPtr client = connectToServer( application, 20000 );
		if( client != NULL ) {
			while( true ) {
				client->update();
			}
		}

		ServerHandlerPtr server = startServer( application, 20000 );

		updateServer( server.get() );
	#endif

		// Now quit
		application->quit();
    }

	void handleLolEvent( const LolEvent& e )
	{
		net::log::verbose( "handleLolEvent : x=%d, bar=%s\n", e.x, e.bar.c_str() );
	}

	void handleExtraEvent( const ExtraEvent& e )
	{
		net::log::verbose( "handleExtraEvent\n" );
	}

	void updateServer( void* userData )
	{
		ServerHandler* server = reinterpret_cast<ServerHandler*>( userData );

		int counter = 1;

		while( true ) {
			server->update();
			thread::Thread::sleep( 1 );

			if( (++counter % 500) == 0 ) {
				printf( "emit : %d\n", counter );
				server->emit<LolEvent>( counter, "counter!" );
				server->emit<ExtraEvent>();
			}
		}
	}

	// This method connects to a remote socket.
	ClientHandlerPtr connectToServer( Application* application, u16 port )
	{
		// Connect to remote server
		ClientHandlerPtr client = ClientHandler::create( NetworkAddress::Localhost, port );

		if( client == NULL ) {
			return ClientHandlerPtr();
		}

		return client;
	}

	// This method starts a TCP server
	ServerHandlerPtr startServer( Application* application, u16 port )
	{
		// Create a server-side network handler
		ServerHandlerPtr server = ServerHandler::create( port );

		if( server == NULL ) {
			return ServerHandlerPtr();
		}

		// Check for incomming data.
		net::log::msg( "Waiting for connections...\n" );

		return server;
	}
};

// Now declare an application entry point with NetworkHandlers application delegate.
dcDeclareApplication( new NetworkHandlers )<commit_msg>Fixed examples compilation error<commit_after>/**************************************************************************

 The MIT License (MIT)

 Copyright (c) 2015 Dmitry Sovetov

 https://github.com/dmsovetov

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:
 The above copyright notice and this permission notice shall be included in all
 copies or substantial portions of the Software.
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.

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

// Include the engine header file.
#include <Dreemchest.h>

#define LOCAL_MODE	(1)

// Open a root engine namespace
DC_USE_DREEMCHEST

// Open a platform namespace.
using namespace Platform;

// Open a net namespace.
using namespace net;

thread::Thread* serverThread = NULL;

// Application delegate is used to handle an events raised by application instance.
class NetworkHandlers : public ApplicationDelegate {

	struct LolEvent : public io::Serializable {
		ClassEnableTypeId( LolEvent )
		ClassEnableCloning( LolEvent )

		int x;
		std::string bar;

		IoBeginSerializer
			IoField( x )
			IoField( bar )
		IoEndSerializer

		LolEvent( int x = 0, std::string bar = "" ) : x( x ), bar( bar ) {}
	};

	struct ExtraEvent : public io::Serializable {
		ClassEnableTypeId( ExtraEvent )
		ClassEnableCloning( ExtraEvent )
	};

    // This method will be called once an application is launched.
    virtual void handleLaunched( Application* application )
	{
        // Setup default loggers
        Platform::log::setStandardHandler();
        net::log::setStandardHandler();

		//! Create a network interface
		Network network;

	#if LOCAL_MODE
		ServerHandlerPtr server = startServer( application, 20000 );
		serverThread = thread::Thread::create();
		serverThread->start( dcThisMethod( NetworkHandlers::updateServer ), server.get() );

		ClientHandlerPtr client = connectToServer( application, 20000 );
		client->registerEvent<LolEvent>();
		client->registerEvent<ExtraEvent>();
		client->subscribe<LolEvent>( dcThisMethod( NetworkHandlers::handleLolEvent ) );
		client->subscribe<ExtraEvent>( dcThisMethod( NetworkHandlers::handleExtraEvent ) );

		while( true ) {
			client->update( 16 );
		}
	#else
		ClientHandlerPtr client = connectToServer( application, 20000 );
		if( client != NULL ) {
			while( true ) {
				client->update();
			}
		}

		ServerHandlerPtr server = startServer( application, 20000 );

		updateServer( server.get() );
	#endif

		// Now quit
		application->quit();
    }

	void handleLolEvent( const LolEvent& e )
	{
		net::log::verbose( "handleLolEvent : x=%d, bar=%s\n", e.x, e.bar.c_str() );
	}

	void handleExtraEvent( const ExtraEvent& e )
	{
		net::log::verbose( "handleExtraEvent\n" );
	}

	void updateServer( void* userData )
	{
		ServerHandler* server = reinterpret_cast<ServerHandler*>( userData );

		int counter = 1;

		while( true ) {
			server->update( 16 );
			thread::Thread::sleep( 1 );

			if( (++counter % 500) == 0 ) {
				printf( "emit : %d\n", counter );
				server->emit<LolEvent>( counter, "counter!" );
				server->emit<ExtraEvent>();
			}
		}
	}

	// This method connects to a remote socket.
	ClientHandlerPtr connectToServer( Application* application, u16 port )
	{
		// Connect to remote server
		ClientHandlerPtr client = ClientHandler::create( NetworkAddress::Localhost, port );

		if( client == NULL ) {
			return ClientHandlerPtr();
		}

		return client;
	}

	// This method starts a TCP server
	ServerHandlerPtr startServer( Application* application, u16 port )
	{
		// Create a server-side network handler
		ServerHandlerPtr server = ServerHandler::create( port );

		if( server == NULL ) {
			return ServerHandlerPtr();
		}

		// Check for incomming data.
		net::log::msg( "Waiting for connections...\n" );

		return server;
	}
};

// Now declare an application entry point with NetworkHandlers application delegate.
dcDeclareApplication( new NetworkHandlers )<|endoftext|>