From 099bc582abe3bfe5f1f62b67e596b16a3f44cae0 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Wed, 7 May 2014 22:26:17 +0200 Subject: [PATCH 01/34] adding the first version of a wrapper for ALICE HLT analysis components --- devices/aliceHLTwrapper/AliHLTDataTypes.h | 1536 +++++++++++++++++++ devices/aliceHLTwrapper/CMakeLists.txt | 56 + devices/aliceHLTwrapper/SystemInterface.cxx | 212 +++ devices/aliceHLTwrapper/SystemInterface.h | 117 ++ devices/aliceHLTwrapper/aliceHLTWrapper.cxx | 25 + 5 files changed, 1946 insertions(+) create mode 100644 devices/aliceHLTwrapper/AliHLTDataTypes.h create mode 100644 devices/aliceHLTwrapper/CMakeLists.txt create mode 100644 devices/aliceHLTwrapper/SystemInterface.cxx create mode 100644 devices/aliceHLTwrapper/SystemInterface.h create mode 100644 devices/aliceHLTwrapper/aliceHLTWrapper.cxx diff --git a/devices/aliceHLTwrapper/AliHLTDataTypes.h b/devices/aliceHLTwrapper/AliHLTDataTypes.h new file mode 100644 index 0000000000000..91cad257621dd --- /dev/null +++ b/devices/aliceHLTwrapper/AliHLTDataTypes.h @@ -0,0 +1,1536 @@ +// @(#) $Id$ + +#ifndef ALIHLTDATATYPES_H +#define ALIHLTDATATYPES_H +/* This file is property of and copyright by the ALICE HLT Project * + * ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/** @file AliHLTDataTypes.h + @author Matthias Richter, Timm Steinbeck, Jochen Thaeder + @date + @brief Data type declaration for the HLT module. +*/ + +////////////////////////////////////////////////////////////////////////// +// +// version no of HLT data types +// +////////////////////////////////////////////////////////////////////////// + +/* Version Description + * 1 first version until June 07; implicite, not tagged + * 2 introduced June 07, enhanced/cleaned/arranged structure + * 3 2007-11-15 RAW DDL data type added; some inconsistencies fixed + * ('void' and 'any' origins); added signed HLT basic data types + * 2007-11-23 origin defines have become variables in conjunction + * to be used with the operator| (AliHLTComponentDataType) + * 2007-11-24 added trigger structs and ESD tree data type + * 4 Component configuration and DCS update events added + * gkAliHLTDDLListSize set from 29 to 30 according to new PubSub + * specs + * 5 Data types for Run and Event summary, and for monitoring added + * 6 Common data types for TreeD and TreeR defined + * kAliHLTAllDataTypes and kAliHLTDataOriginSample added + * kAliHLTDataOriginEMCAL added + * kAliHLTDataTypeRunType added + * 7 kAliHLTDataTypeComponentStatistics, kAliHLTDataTypeComponentTable, + * and AliHLTComponentStatistics have been added for optional + * component block statistics + * 8 new wrapper interface has been introduced, old wrapper interface + * deprecated but kept for backward compatibility, the PubSub + * interface is going to be compiled independently of AliHLT, new + * interface provided by the libHLTinterface.so + * AliHLTComponentEnvironment -> AliHLTAnalysisEnvironment + * 9 added data types for arrays of AliHLTExternalTrackParam sets and + * TClonesArrays of AliExternalTrackParam objects. + * 10 Changes for information objects neededfor running with offline + * chains and analysis tasks. + * kAliHLTMCObjectDataType added + * kAliHLTDataOriginOffline added + * kAliHLTDataOriginHLT added + * 11 extended AliHLTComponentStatistics: one more member to store the + * cycle time between events per component. + * 12 added common data type id 'CLUSTERS' + * added data type 'ECSPARAM' for the full ECS parameter string to + * be sebt during SOR + * added kAliHLTDataTypeTrackMC (TRACK_MC) data type + * added data types (note: interface version stays the same + * kAliHLTDataTypeDAQRDOUT (DAQRDOUT) + * kAliHLTDataTypeTriggerDecision (TRIG_DEC) + * kAliHLTDataTypeGlobalTrigger (GLOBTRIG) + * kAliHLTDataTypeStreamerInfo (ROOTSTRI) + * 13 Changed AliHLTEventDDL to now contain 31 words. The extra word is + * for the EMCAL detector, which needs 46 DDLs after DCAL was added. + * 14 Adding new data block type for HLT global trigger counters. + * Adding data block type for ESD content + * Adding data block type for forwarded component table blocks + * Adding new event type for software triggers. + * 15 Modifying data block types for trigger counter blocks. + * 16 Adding data type for the meta data block to be forwarded by the + * TCPDumpSubscriber for the Common Data Header (CDH) and readout + * list information. + */ +#define ALIHLT_DATA_TYPES_VERSION 16 + +////////////////////////////////////////////////////////////////////////// +// +// HLT data origin variables. +// +// By converting from defines to variables, the origins can be used with +// the operator| +// +// AliHLTComponentDataType dt; +// dt = kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC; +// +////////////////////////////////////////////////////////////////////////// + +/** field size of datat type origin + * @ingroup alihlt_component_datatypes + */ +const int kAliHLTComponentDataTypefOriginSize=4; + + +/** invalid data origin + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTDataOriginVoid "\0\0\0" +/** old invalid data origin, kept for backward compatibility */ +# define kAliHLTVoidDataOrigin "\0\0\0" + +/** wildcard data type origin + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTDataOriginAny "***" +/** old wildcard data type origin, kept for backward compatibility */ +# define kAliHLTAnyDataOrigin "***" + +/** Data origin HLT out + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginOut[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin HLT, used for HLT specifc data + * in offline chains. This not a bug! + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginHLT[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin Offline + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginOffline[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin HLT/PubSub private internal + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginPrivate[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin TPC + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginTPC[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin PHOS + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginPHOS[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin FMD + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginFMD[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin MUON + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginMUON[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin TRD + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginTRD[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin ITS + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginITS[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin ITSOut + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginITSOut[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin ITS SPD + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginITSSPD[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin ITS SDD + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginITSSDD[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin ITS SSD + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginITSSSD[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin for examples + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginSample[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin EMCAL + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginEMCAL[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin TOF + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginTOF[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin HMPID + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginHMPID[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin CPV + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginCPV[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin PMD + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginPMD[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin T0 + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginT0[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin VZERO + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginVZERO[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin ZDC + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginZDC[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin ACORDE + * @ingroup alihlt_component_datatypes + */ + +extern const char kAliHLTDataOriginACORDE[kAliHLTComponentDataTypefOriginSize]; + +/** Data origin TRG + * @ingroup alihlt_component_datatypes + */ +extern const char kAliHLTDataOriginTRG[kAliHLTComponentDataTypefOriginSize]; + +////////////////////////////////////////////////////////////////////////// +// +// HLT common data type defines +// +////////////////////////////////////////////////////////////////////////// + +/** field size of data type id + * @ingroup alihlt_component_datatypes + */ +const int kAliHLTComponentDataTypefIDsize=8; + + +/** invalid data type id + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTVoidDataTypeID "\0\0\0\0\0\0\0" + +/** special id for all data types: any + void + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTAllDataTypesID "ALLDATA" + +/** special id for any valid data type id + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTAnyDataTypeID "*******" + +/** DDL RAW data + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTDDLRawDataTypeID {'D','D','L','_','R','A','W',' '} + +/** CLUSTERS data + * Common data type for the output of cluster finders, the exact + * format depends on the origin (detector) + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTClustersDataTypeID {'C','L','U','S','T','E','R','S'} + +/** calibration data for file exchange subscriber + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTFXSCalibDataTypeID {'F','X','S','_','C','A','L',' '} + +/** start of run (SOR) event + * @ref AliHLTRunDesc + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTSORDataTypeID {'S','T','A','R','T','O','F','R'} + +/** end of run (EOR) event + * @ref AliHLTRunDesc + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTEORDataTypeID {'E','N','D','O','F','R','U','N'} + +/** run type data block + * string with run type as payload + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTRunTypeDataTypeID {'R','U','N','T','Y','P','E',' '} + +/** DDL list event + * @ref AliHLTEventDDL + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTDDLDataTypeID {'D','D','L','L','I','S','T',' '} + +/** DAQ readout list + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTDAQRDOUTDataTypeID "DAQRDOUT" + +/** HLT readout list. + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTReadoutListDataTypeID {'H','L','T','R','D','L','S','T'} + +/** EventType event + * - empty payload, specification gives eventType + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTEventDataTypeID {'E','V','E','N','T','T','Y','P'} + +/** ECS parameter event + * - sent during the SOR event by the framework + * - contains the full ECS parameter string + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTECSParamDataTypeID {'E','C','S','P','A','R','A','M'} + +/** ComponentConfiguration event + * - payload contains the CDB path as string + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTComConfDataTypeID {'C','O','M','_','C','O','N','F'} + +/** DCS value update event + * - payload contains string of relevant detectors + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTUpdtDCSDataTypeID {'U','P','D','T','_','D','C','S'} + +/** MC data block + * an AliMCEvent object of varying origin + * The 'V0' at the end allows a versioning + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTMCObjectDataTypeID {'A','L','I','M','C','_','V','0'} + +/** ESDVertex data block + * an AliESDVertex object of varying origin + * The 'V0' at the end allows a versioning + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTESDVertexDataTypeID {'E','S','D','V','T','X','V','0'} + +/** KFVertex data block + * an AliKFVertex object of varying origin + * The 'V0' at the end allows a versioning + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTKFVertexDataTypeID {'A','L','I','K','F','V','V','0'} + + +/** output of the GlobalVertexer data block + * The 'V0' at the end allows a versioning + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTDataTypeGlobalVertexerID {'G','L','B','V','T','X','V','0'} + +/** output of the PrimaryFinder data block + * The 'V0' at the end allows a versioning + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTDataTypePrimaryFinderID {'P','R','I','V','T','X','V','0'} + +/** output of the V0Finder data block + * The 'V0' at the end allows a versioning + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTDataTypeV0FinderID {'V','0','S','V','T','X','V','0'} + +/** ESD data block + * an AliESD object of varying origin + * The 'V0' at the end allows a versioning + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTESDObjectDataTypeID {'A','L','I','E','S','D','V','0'} + +/** ESD + * data blocks designated for the ESD + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTESDContentDataTypeID {'E','S','D','_','C','O','N','T'} + +/** ESD tree data block + * TTree with an AliESD object of varying origin + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTESDTreeDataTypeID {'E','S','D','_','T','R','E','E'} + +/** AliRoot TreeD + * - the digits tree of an AliRoot module + * @ingroup alihlt_component_datatypes + */ +#define kAliHLTTreeDDataTypeID {'A','L','I','T','R','E','E','D'} + +/** AliRoot TreeR + * - the rec points tree of an AliRoot module + * @ingroup alihlt_component_datatypes + */ +#define kAliHLTTreeRDataTypeID {'A','L','I','T','R','E','E','R'} + +/** HW Address selection data block + * - a selection list for 16 bit HW addresses + * - varying origin + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTHwAddr16DataTypeID {'H','W','A','D','D','R','1','6'} + +/** Event Statistics + * - event statistics for given detectors + * - varying origin + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTEventStatisticsDataTypeID {'E','V','_','S','T','A','T','I'} + +/** Event Summary + * - event summary + * - origin : kAliHLTDataOriginOut ( HLT ) + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTEventSummaryDataTypeID {'E','V','_','S','U','M','M','A'} + +/** Run Statistics + * - run statistics for given detectors + * - varying origin + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTRunStatisticsDataTypeID {'R','U','N','S','T','A','T','I'} + +/** Run Summary + * - run summary + * - origin : kAliHLTDataOriginOut ( HLT ) + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTRunSummaryDataTypeID {'R','U','N','S','U','M','M','A'} + +/** Trigger decision + * - origin : kAliHLTDataOriginOut ( HLT ) + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTTriggerDecisionDataTypeID {'T','R','I','G','_','D','E','C'} + +/** Global trigger decision + * - origin : kAliHLTDataOriginOut ( HLT ) + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTGlobalTriggerDataTypeID {'G','L','O','B','T','R','I','G'} + +/** Block Statistics + * - small block statistics info added to the data stream by + * the component base class + * - origin kAliHLTDataOriginPrivate + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTComponentStatisticsDataTypeID {'C','O','M','P','S','T','A','T'} + +/** Component table + * - list of components in the chain to be percolated through the chain + * - each component adds it's chain id string and a generated 32bit id + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTComponentTableDataTypeID {'C','O','M','P','T','A','B','L'} + +/** Forwarded component table + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTComponentFwdTableDataTypeID {'C','O','M','P','T','A','B','F'} + +/** general ROOT TObject + * - a general TObject exported from the HLT analysis + * - varying origin + * @ingroup alihlt_component_datatypes + */ +#define kAliHLTTObjectDataTypeID {'R','O','O','T','T','O','B','J'} + +/** ROOT streamer info + * - used for the transmission of streamer info for objects in the HLTOUT + * - origin kAliHLTDataOriginOut ( HLT ) + * @ingroup alihlt_component_datatypes + */ +#define kAliHLTStreamerInfoDataTypeID {'R','O','O','T','S','T','R','I'} + +/** ROOT TObjArray + * - a TObjArray exported from the HLT analysis + * - varying origin + * @ingroup alihlt_component_datatypes + */ +#define kAliHLTTObjArrayDataTypeID {'R','O','O','T','O','B','A','R'} + +/** ROOT TTree + * - a TTree object exported from the HLT analysis + * - varying origin + * @ingroup alihlt_component_datatypes + */ +#define kAliHLTTTreeDataTypeID {'R','O','O','T','T','R','E','E'} + +/** ROOT histogram + * - a histogram object exported from the HLT analysis + * - class derives from TH1 (directly or indirectly) and inherits all common functionality + * - varying origin + * @ingroup alihlt_component_datatypes + */ +#define kAliHLTHistogramDataTypeID {'R','O','O','T','H','I','S','T'} + +/** ROOT TNtuple + * - a TNtupl object exported from the HLT analysis + * - varying origin + * @ingroup alihlt_component_datatypes + */ +#define kAliHLTTNtupleDataTypeID {'R','O','O','T','T','U','P','L'} + +/** HLT Track + * - Struct for Tracks based on AliExternalTrackParam + * - varying origin + * @ingroup alihlt_component_datatypes + */ +#define kAliHLTTrackDataTypeID {'H','L','T','T','R','A','C','K'} + +/** Track Monte Carlo information + * @ingroup alihlt_component_datatypes + */ +#define kAliHLTTrackMCDataTypeID {'T','R','A','C','K','_','M','C'} + +/** TClonesArray of AliExternalTrackParam + * @ingroup alihlt_component_datatypes + */ +#define kAliHLTExternalTrackParamDataTypeID {'T','C','A','E','X','T','T','R'} + +/** HLT Jet + * - Struct for jets based on AliHLTJETJets + * - varying origin + * @ingroup alihlt_component_datatypes + */ +#define kAliHLTJetDataTypeID {'H','L','T','J','E','T','V','0'} + +/** dEdx data + * Common data type for the dEdx + * format depends on the origin (detector) + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTdEdxDataTypeID {'D','E','D','X',' ',' ',' ',' '} + +/** dNdPt data + * Common data type for the dNdPt output object + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTdNdPtDataTypeID {'D','N','D','P','T',' ',' ',' '} + +/** Global input trigger counters data block type. + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTInputTriggerCountersDataTypeID {'I','N','T','R','G','C','N','T'} + +/** Global output trigger counters data block type. + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTOutputTriggerCountersDataTypeID {'O','T','T','R','G','C','N','T'} + +/** Generic meta data block type ID. + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTMetaDataTypeID {'M','E','T','A','D','A','T','A'} + +extern "C" { + ////////////////////////////////////////////////////////////////////////// + // + // Basic HLT data types + // + ////////////////////////////////////////////////////////////////////////// + + typedef unsigned char AliHLTUInt8_t; + + typedef signed char AliHLTInt8_t; + + typedef unsigned short AliHLTUInt16_t; + + typedef signed short AliHLTInt16_t; + + typedef unsigned int AliHLTUInt32_t; + + typedef signed int AliHLTInt32_t; + + typedef unsigned long long AliHLTUInt64_t; + + typedef signed long long AliHLTInt64_t; + + typedef float AliHLTFloat32_t; + + typedef double AliHLTFloat64_t; + + typedef AliHLTUInt64_t AliHLTEventID_t; + + ////////////////////////////////////////////////////////////////////////// + // + // HLT logging levels + // + ////////////////////////////////////////////////////////////////////////// + + /** + * Logging severities of the HLT + */ + enum AliHLTComponentLogSeverity { + /** no logging */ + kHLTLogNone = 0, + /** benchmark messages */ + kHLTLogBenchmark = 0x1, + /** debug messages */ + kHLTLogDebug = 0x2, + /** info messages */ + kHLTLogInfo = 0x4, + /** warning messages */ + kHLTLogWarning = 0x8, + /** error messages */ + kHLTLogError = 0x10, + /** fatal error messages */ + kHLTLogFatal = 0x20, + /** few important messages not to be filtered out. + * redirected to kHLTLogInfo in AliRoot + */ + kHLTLogImportant = 0x40, + /** special value to enable all messages */ + kHLTLogAll = 0x7f, + /** the default logging filter */ + kHLTLogDefault = 0x79 + }; + + ////////////////////////////////////////////////////////////////////////// + // + // HLT data structures for data exchange and external interface + // + ////////////////////////////////////////////////////////////////////////// + + /** + * @struct AliHLTComponentEventData + * Event descriptor + */ + struct AliHLTComponentEventData + { + AliHLTUInt32_t fStructSize; /// Size of this structure in bytes. + AliHLTEventID_t fEventID; /// 64 bit event ID number. + AliHLTUInt32_t fEventCreation_s; /// Event creation time in seconds (Should be added to fEventCreation_us*1e6). + AliHLTUInt32_t fEventCreation_us; /// Fractional event creation time in micro seconds. + AliHLTUInt32_t fBlockCnt; /// The number of raw data blocks received by the component. + }; + + /** + * @struct AliHLTComponentShmData + * Shared memory descriptor. + * Irrelevant for analysis components. + */ + struct AliHLTComponentShmData + { + AliHLTUInt32_t fStructSize; /// Size of this structure in bytes. + AliHLTUInt32_t fShmType; /// The type code of the shared memory. + AliHLTUInt64_t fShmID; /// The shared memory identifier. + }; + + /** + * @defgroup alihlt_component_datatypes Common Component Data Types + * The analysis framework defines a number of common data types for + * usage in the detector modules, like e.g. ::kAliHLTAnyDataType + * and ::kAliHLTDataTypeDDLRaw. Those data types always have + * origin ::kAliHLTDataOriginAny. The correct detector origin can be + * set by using operator '|' + *
+   * AliHLTComponentDataType dt=kAliHLTDDLRawDataTypeID|kAliHLTDataOriginTPC
+   * 
+ * @ingroup alihlt_component + */ + + /** + * @struct AliHLTComponentDataType + * Data type descriptor for data blocks transferred through the processing + * chain. + * @ingroup alihlt_component_datatypes + */ + struct AliHLTComponentDataType + { + AliHLTUInt32_t fStructSize; /// Size of this structure in bytes. + char fID[kAliHLTComponentDataTypefIDsize]; /// Data type identifier. + char fOrigin[kAliHLTComponentDataTypefOriginSize]; /// Subsystem or detector origin of the data. + }; + + /** + * @struct AliHLTComponentBlockData + * This is the decription of data blocks exchanged between components. + * \b IMPORTANT: The validity of fPtr and fOffset is different for input and + * output blocks: + * - input blocks: The \em fPtr member always points to the beginning of the data + * of size \em fSize. fOffset is ignored and should be in most + * case 0. + * - output blocks: The \em fPtr member is ignored by the framework. \em fOffset + * must specify the start of the data relative to the output + * buffer. The data block has size \em fSize. + */ + struct AliHLTComponentBlockData + { + /** size and version of the struct */ + AliHLTUInt32_t fStructSize; + /** shared memory key, ignored by processing components */ + AliHLTComponentShmData fShmKey; + /** offset of output data relative to the output buffer */ + AliHLTUInt32_t fOffset; + /** start of the data for input data blocks, fOffset to be ignored*/ + void* fPtr; + /** size of the data block */ + AliHLTUInt32_t fSize; + /** data type of the data block */ + AliHLTComponentDataType fDataType; + /** data specification of the data block */ + AliHLTUInt32_t fSpecification; + + AliHLTComponentDataType GetDataType() const {return fDataType;} + AliHLTUInt32_t GetSpecification() const {return fSpecification;} + }; + + /** + * @struct AliHLTComponentEventDoneData + * + */ + struct AliHLTComponentEventDoneData + { + AliHLTUInt32_t fStructSize; /// Size of this structure in bytes. + AliHLTUInt32_t fDataSize; /// Size of the data section (following this data member) in bytes. + void* fData; /// Start of the data section. + }; + + /** + * @struct AliHLTRunDesc + * Event descriptor. + * The struct is sent with the SOR and EOR events. + * + * @note + * The name of the member fRunType is a bit misleading. This is not + * the ALICE Run Type given by the ECS to the sub-system. The member + * is an internal HLT run type and a combination of the HLT running + * mode and the beam type. + *
+   * Bit 0-2:   beam type identifier
+   * Bit 3-31:  HLT mode
+   * 
+ */ + struct AliHLTRunDesc + { + AliHLTUInt32_t fStructSize; /// Size of this structure in bytes. + AliHLTUInt32_t fRunNo; /// The run number for the current active run. + AliHLTUInt32_t fRunType; /// The HLT run type. + }; + + /** + * @struct AliHLTComponentStatistics + * Small block size summary added by the AliHLTComponent base class + * if component statistics are enabled (--enable-compstat). + * + * fLevel is retrieved from incoming block statistics and incremented. + * Incoming block statistics are appended to the newly added one if + * --enable-compstat=full has been chosen. + * + * ChangeLog: + * 2009-01-14 fComponentCycleTime added + */ + struct AliHLTComponentStatistics + { + AliHLTUInt32_t fStructSize; /// Size of this structure in bytes. + AliHLTUInt32_t fLevel; /// Indicates from which processing stage this information is from. + AliHLTUInt32_t fId; /// Unique identifier for the chain based on CRC code. + AliHLTUInt32_t fTime; /// Real wall time used to process the data (micro seconds). + AliHLTUInt32_t fCTime; /// CPU time used to process the data (micro seconds). + AliHLTUInt32_t fInputBlockCount; /// Number of input data blocks. + AliHLTUInt32_t fTotalInputSize; /// Total size in bytes of input data. + AliHLTUInt32_t fOutputBlockCount; /// Number of output data blocks. + AliHLTUInt32_t fTotalOutputSize; /// Total size in bytes of output data. + AliHLTUInt32_t fComponentCycleTime; /// Real wall time indicating the start of the data processing (micro seconds). + }; + + /** + * @struct AliHLTComponentTableEntry + * Structure to be send on SOR event through the chain. + * The 'length' of the structure is variable and depends on the length + * of the buffer at the end. + * + * ComponentTableEntries are sent with data type @ref kAliHLTDataTypeComponentTable + * and are identified by a 32bit Id specification generated by a CRC + * algorithm from the chain Id of the component. This is not a 100% unique + * id but with a high probability. This approach accounts for the fact + * that all components are separated processes. + * + * The buffer consists of an array of 32bit Ids containing the Ids of + * all direct parents taken from the specification of the data blocks. + * The number of parents is stored in fNofParents. Each component forwards the + * incoming component table entries with data type @ref kAliHLTDataTypeComponentFwdTable + * by that the direct parents can be identified. + * + * Following this array a description string contains the chain id, component args, and + * maybe more properties in the future. The current format is + * 'chain_id{component_id:component args}' e.g. TPC-CF_00_0{TPCClusterFinder32Bit:-deconvolute-time} + */ + struct AliHLTComponentTableEntry + { + AliHLTUInt32_t fStructSize; /// Size of this structure in bytes. + AliHLTUInt32_t fLevel; /// Indicates from which processing stage this information is from. + AliHLTUInt16_t fNofParents; /// size of the array of parent ids + AliHLTUInt8_t fSizeDescription; /// size of the description string in the appended buffer + AliHLTUInt8_t fBuffer[1]; /// the strings: chain id, component args, reserved + }; + + ////////////////////////////////////////////////////////////////////////// + // + // Trigger meta information + // + ////////////////////////////////////////////////////////////////////////// + + /** field size of fAttribute */ + const int gkAliHLTBlockDAttributeCount = 8; + + /** field size of fCommonHeader */ + const int gkAliHLTCommonHeaderCount = 8; + + /** size of the DDL list first version */ + const int gkAliHLTDDLListSizeV0 = 30; + + /** size of the DDL list after DCAL added to EMCAL */ + const int gkAliHLTDDLListSizeV1 = 31; + + /** size of the DDL list */ + const int gkAliHLTDDLListSize = gkAliHLTDDLListSizeV1; + + /** Number of Trigger Classes of CTP in CDH */ + const int gkNCTPTriggerClasses = 50; + + /** + * @struct AliHLTEventDDLV0 + * First version of the DDL list event. + * The struct is send with the DDLLIST event. + * Used in the trigger structure for internal apperance of + * the DLLs as well as for the HLT readout list send to DAQ + * ( as DataType : kAliHLTDataTypeDDL ) + */ + struct AliHLTEventDDLV0 + { + AliHLTUInt32_t fCount; /// Indicates the number of words in fList. + AliHLTUInt32_t fList[gkAliHLTDDLListSizeV0]; /// The list of DDL enable/disable bits. + }; + + /** + * @struct AliHLTEventDDLV1 + * DDL list event structure with extra word for DCAL bits. + */ + struct AliHLTEventDDLV1 + { + AliHLTUInt32_t fCount; /// Indicates the number of words in fList. + AliHLTUInt32_t fList[gkAliHLTDDLListSizeV1]; /// The list of DDL enable/disable bits. + }; + + /** + * @typedef AliHLTEventDDL + * Current used default version of the AliHLTEventDDL structure. + */ + typedef AliHLTEventDDLV1 AliHLTEventDDL; + + /** + * @struct AliHLTEventTriggerData + */ + struct AliHLTEventTriggerData + { + AliHLTUInt8_t fAttributes[gkAliHLTBlockDAttributeCount]; /// List of data block attibutes. + AliHLTUInt64_t fHLTStatus; /// Bit field + AliHLTUInt32_t fCommonHeaderWordCnt; /// Number of words in fCommonHeader. + AliHLTUInt32_t fCommonHeader[gkAliHLTCommonHeaderCount]; /// The common header words. + union + { + AliHLTEventDDL fReadoutList; /// The default readout list structure. + AliHLTEventDDLV0 fReadoutListV0; /// Access to the old version of the readout list structure. + AliHLTEventDDLV1 fReadoutListV1; /// Access to the readout list structure with DCAL included. + }; + }; + + /** + * @struct AliHLTComponentTriggerData + * Trigger data + */ + struct AliHLTComponentTriggerData + { + AliHLTUInt32_t fStructSize; /// Size of this structure in bytes. + AliHLTUInt32_t fDataSize; /// Size of the data section (following this data member) in bytes. + void* fData; /// Start of the data section. + }; + + ////////////////////////////////////////////////////////////////////////// + // + // HLT Event Type Specification + // + ////////////////////////////////////////////////////////////////////////// + + /** Unknown eventType specification */ + const AliHLTUInt32_t gkAliEventTypeUnknown = ~(AliHLTUInt32_t)0; + /** SOR eventType specification */ + const AliHLTUInt32_t gkAliEventTypeStartOfRun=1; + /** Data eventType specification */ + const AliHLTUInt32_t gkAliEventTypeData=2; + /** EOR eventType specification */ + const AliHLTUInt32_t gkAliEventTypeEndOfRun=4; + /** Corrupt eventType specification */ + const AliHLTUInt32_t gkAliEventTypeCorruptID=8; + /** Calibration eventType specification */ + const AliHLTUInt32_t gkAliEventTypeCalibration=16; + /** Software eventType specification */ + const AliHLTUInt32_t gkAliEventTypeSoftware=24; + /** DataReplay eventType specification */ + const AliHLTUInt32_t gkAliEventTypeDataReplay=32; + /** Configuration eventType specification */ + const AliHLTUInt32_t gkAliEventTypeConfiguration=34; + /** Update DCS eventType specification */ + const AliHLTUInt32_t gkAliEventTypeReadPreprocessor=35; + /** Tick eventType specification */ + const AliHLTUInt32_t gkAliEventTypeTick=64; + /** Max eventType specification */ + const AliHLTUInt32_t gkAliEventTypeMax=64; + + ////////////////////////////////////////////////////////////////////////// + // + // HLT defines and defaults + // + ////////////////////////////////////////////////////////////////////////// + + /** invalid event id + * @ingroup alihlt_component_datatypes + */ + const AliHLTEventID_t kAliHLTVoidEventID=~(AliHLTEventID_t)0; + + /** invalid data specification + * @ingroup alihlt_component_datatypes + */ + const AliHLTUInt32_t kAliHLTVoidDataSpec = ~(AliHLTUInt32_t)0; + + /** invalid run no + * @ingroup alihlt_component_datatypes + */ + const AliHLTUInt32_t kAliHLTVoidRunNo = ~(AliHLTUInt32_t)0; + + /** invalid run type + * @ingroup alihlt_component_datatypes + */ + const AliHLTUInt32_t kAliHLTVoidRunType = ~(AliHLTUInt32_t)0; + + /** invalid run descriptor + * @ingroup alihlt_component_datatypes + */ + const AliHLTRunDesc kAliHLTVoidRunDesc={sizeof(AliHLTRunDesc), kAliHLTVoidRunNo, kAliHLTVoidRunType}; + + /** invalid shared memory type */ + const AliHLTUInt32_t gkAliHLTComponentInvalidShmType = 0; + + /** invalid shared memory id */ + const AliHLTUInt64_t gkAliHLTComponentInvalidShmID = ~(AliHLTUInt64_t)0; + + /** invalid data type + * @ingroup alihlt_component_datatypes + */ + const AliHLTComponentDataType kAliHLTVoidDataType = { + sizeof(AliHLTComponentDataType), + kAliHLTVoidDataTypeID, + kAliHLTDataOriginVoid + }; + + /** all data types, means any + void data type + * @ingroup alihlt_component_datatypes + */ + const AliHLTComponentDataType kAliHLTAllDataTypes = { + sizeof(AliHLTComponentDataType), + kAliHLTAllDataTypesID, + kAliHLTDataOriginAny + }; + + // there is currently a problem with rootcint if the predefined ids + // (commented below) are used. rootcint does not find the id if they + // are char arrays defined with {} and individual chars. If strings + // are used it works fine + /** any data type + * @ingroup alihlt_component_datatypes + */ + const AliHLTComponentDataType kAliHLTAnyDataType = { + sizeof(AliHLTComponentDataType), + kAliHLTAnyDataTypeID, + kAliHLTDataOriginAny + }; + + /** multiple output data types + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTMultipleDataType; + + /** data to file exchange subscriber + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeFXSCalib; + + /** DDL list data type + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeDDL; + + /** DAQ readout list + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeDAQRDOUT; + + /** CLUSTERS data + * Common data type for the output of cluster finders, the exact + * format depends on the origin (detector) + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeClusters; + + /** SOR data type + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeSOR; + + /** EOR data type + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeEOR; + + /** Run type data block + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeRunType; + + /** Event type specification + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeEvent; + + /** ECS parameter event + * - sent during the SOR event by the framework + * - contains the full ECS parameter string + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeECSParam; // {ECSPARAM:PRIV} + + /** Configuration event data type + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeComConf; + + /** DCS value update event + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeUpdtDCS; + + /** RAW DDL data specification, origin is 'any', data publisher origin correctly + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeDDLRaw; + + /** AliMCEvent object data specification, origin is 'OFFL' + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeMCObject; + + /** ESD vertex object data specification, origin is 'any' + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeESDVertex; + + /** KF vertex object data specification, origin is 'any' + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeKFVertex; + + /** global vertexer data specification, origin is 'any' + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeGlobalVertexer; + + /** primary finder data specification, origin is 'any' + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypePrimaryFinder; + + /** primary finder data specification, origin is 'any' + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeV0Finder; + + /** ESD object data specification, origin is 'any' + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeESDObject; + + /** ESD content data specification, origin is 'any' + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeESDContent; + + /** ESD Tree data specification, origin is 'any' + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeESDTree; + + /** AliRoot TreeD data specification, origin is 'any' + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeAliTreeD; + + /** AliRoot TreeR data specification, origin is 'any' + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeAliTreeR; + + /** 16 bit Hardware address selection data specification, origin is 'any' + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeHwAddr16; + + /** Event statistics + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeEventStatistics; + + /** Event summary + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeEventSummary; + + /** Event statistics + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeRunStatistics; + + /** Run summary + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeRunSummary; + + /** Trigger decision + * - origin : kAliHLTDataOriginOut ( HLT ) + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeTriggerDecision; // {TRIG_DEC:HLT } + + /** Trigger decision + * - origin : kAliHLTDataOriginOut ( HLT ) + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeReadoutList; // {HLTRDLST:HLT } + + /** Global trigger decision + * - origin : kAliHLTDataOriginOut ( HLT ) + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeGlobalTrigger; // {GLOBTRIG:HLT } + + /** Component block statistics + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeComponentStatistics; + + /** Component table + * To be sent on SOR event, each component adds it's chain id string + * and a generated 32bit identifier to the table + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeComponentTable; + + /** Forwarded component table + * To be sent on SOR event, each component forwards blocks of type + * @ref kAliHLTDataTypeComponentTable was kAliHLTDataTypeComponentFwdTable + * after adding the parent ids to its own table struct. + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeComponentFwdTable; + + /** + * Data type for the Common Data Header and readout list information sent by TCPDumpSubscriber. + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeTriggerMetaBlock; // {METADATA:PRIV} + + ////////////////////////////////////////////////////////////////////////// + // + // Data Types for Monitoring objects + // + ////////////////////////////////////////////////////////////////////////// + + /** general ROOT TObject + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeTObject; // {ROOTTOBJ,"***"} + + /** ROOT streamer info + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeStreamerInfo; // {ROOTSTRI,HLT } + + /** ROOT TObjArray + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeTObjArray; // {ROOTOBAR,"***"} + + /** ROOT TTree + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeTTree; // {ROOTTREE,"***"} + + /** ROOT TH1 (can be used for all histograms, they derive from TH1) + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeHistogram; // {ROOTHIST,"***"} + + /** ROOT TNtuple + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeTNtuple; // {ROOTTUPL,"***"} + + /** Global input trigger counters. + * - origin : kAliHLTDataOriginOut ( HLT ) + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeInputTriggerCounters; // {INTRGCNT:HLT } + + /** Global output trigger counters. + * - origin : kAliHLTDataOriginOut ( HLT ) + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeOutputTriggerCounters; // {OTTRGCNT:HLT } + + /** General track array for the barrel tracks based on AliExternalTrackParam + * Data format defined by AliHLTTracksData + * + * We follow the naming scheme of AliESDEvent where 'Tracks' denote the + * barrel tracks and detector tracks get names 'DETTracks' + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeTrack; // {HLTTRACK,"***"} + + /** Track Monte Carlo information + */ + extern const AliHLTComponentDataType kAliHLTDataTypeTrackMC; // {TRACK_MC,"***"} + + /** TClonesArray of AliExternalTrackParam + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeExternalTrackParam; // {TCAEXTTR,"***"} + + /** Container containing jets (AliHLTJETJets) + * Containing TClonesArray of AliAODJets + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeJet; // {HLTJETV0,"***"} + + /** Container of ITS tracks + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType fgkITSTracksDataType; + + /** Container of calorimeter clusters + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeCaloCluster; + + /** Container of dEdx + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypedEdx; + + /** Container of dNdPt + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypedNdPt; + + ////////////////////////////////////////////////////////////////////////// + // + // FXS subscriber meta information + // + ////////////////////////////////////////////////////////////////////////// + + const int gkAliHLTFXSHeaderfOriginSize = 4; + const int gkAliHLTFXSHeaderfFileIDSize = 128; + const int gkAliHLTFXSHeaderfDDLNumberSize = 64; + + /** Header in front of the data payload, in order to sent data to the FXS. */ + struct AliHLTFXSHeader + { + AliHLTUInt32_t fHeaderVersion; /// HLT software version number. + AliHLTUInt32_t fRunNumber; /// The current run number. + char fOrigin[gkAliHLTFXSHeaderfOriginSize]; /// The detector from which the FXS data is received. + char fFileID[gkAliHLTFXSHeaderfFileIDSize]; /// File identifier for the stored data. + char fDDLNumber[gkAliHLTFXSHeaderfDDLNumberSize]; /// The DDL bits. + }; + + ////////////////////////////////////////////////////////////////////////// + // + // Component running environment + // + ////////////////////////////////////////////////////////////////////////// + + /** definition of a void fct pointer */ + typedef void (*AliHLTfctVoid)(); + + /** logging function */ + typedef int (*AliHLTfctLogging)( void* param, + AliHLTComponentLogSeverity severity, + const char* origin, + const char* keyword, + const char* message); + + /** + * @struct AliHLTAnalysisEnvironment + * Running environment for analysis components. + * The struct describes function callbacks for actions to be + * carried out by the calling framework, like memory allocation, + * property callbecks, logging, etc. + * + * @ingroup alihlt_wrapper_interface + */ + struct AliHLTAnalysisEnvironment + { + /** size of the structure */ + AliHLTUInt32_t fStructSize; + + /** the component parameter given by the framework on creation */ + void* fParam; + + /** allocated memory */ + void* (*fAllocMemoryFunc)( void* param, unsigned long size ); + + /** allocate an EventDoneData structure. */ + int (*fGetEventDoneDataFunc)( void* param, AliHLTEventID_t eventID, unsigned long size, AliHLTComponentEventDoneData** edd ); + + /** logging callback */ + AliHLTfctLogging fLoggingFunc; + }; +#if 0 + // I just keep this as a note pad. Has to be added to the end of the structure + // future addition already foreseen/envisioned + // IMPORTANT: don not just remove the defines as this breaks the binary + // compatibility + int (*fAllocShmMemoryFunc)( void* param, unsigned long size, AliHLTComponentBlockData* blockLocation ); +#endif + + /** + * @struct AliHLTComponentEnvironment + * This was the original definition of the running environment. + * Due to a bug in the AliRootWrapperSubscriber/SimpleComponentWrapper, + * this structure can not be used any longer but is kept for backward + * compatibility. + * @note The external interface provided by the libHLTbase is now kept + * frozen but should not be used any more. Use the interface provided + * by the libHLTinterface library. + * + * @ingroup alihlt_wrapper_interface_deprecated + */ + struct AliHLTComponentEnvironment + { + AliHLTUInt32_t fStructSize; + void* fParam; + void* (*fAllocMemoryFunc)( void* param, unsigned long size ); + int (*fGetEventDoneDataFunc)( void* param, AliHLTEventID_t eventID, unsigned long size, AliHLTComponentEventDoneData** edd ); + AliHLTfctLogging fLoggingFunc; + }; + + ////////////////////////////////////////////////////////////////////////// + // + // The external interface definition + // + ////////////////////////////////////////////////////////////////////////// + + /** + * The component handle. + * Used as indification in the outside world. + * @ingroup alihlt_wrapper_interface + */ + typedef void* AliHLTComponentHandle; + + /** @ingroup alihlt_wrapper_interface */ + const AliHLTComponentHandle kEmptyHLTComponentHandle = 0; + + /** + * Get a system call of the interface. + * @param function signature + * @return pointer to system call + * @ingroup alihlt_wrapper_interface + */ + typedef void* (*AliHLTAnalysisFctGetInterfaceCall)(const char*); + +# define ALIHLTANALYSIS_INTERFACE_LIBRARY "libHLTinterface.so" +# define ALIHLTANALYSIS_FCT_GETINTERFACECALL "AliHLTAnalysisGetInterfaceCall" + + /** @ingroup alihlt_wrapper_interface */ + typedef int (*AliHLTExtFctInitSystem)( unsigned long version, AliHLTAnalysisEnvironment* externalEnv, unsigned long runNo, const char* runType ); + + /** @ingroup alihlt_wrapper_interface */ + typedef int (*AliHLTExtFctDeinitSystem)(); + + /** @ingroup alihlt_wrapper_interface */ + typedef int (*AliHLTExtFctLoadLibrary)( const char* ); + + /** @ingroup alihlt_wrapper_interface */ + typedef int (*AliHLTExtFctUnloadLibrary)( const char* ); + + /** @ingroup alihlt_wrapper_interface */ + typedef int (*AliHLTExtFctCreateComponent)( const char*, void*, int, const char**, AliHLTComponentHandle*, const char* description ); + + /** @ingroup alihlt_wrapper_interface */ + typedef int (*AliHLTExtFctDestroyComponent)( AliHLTComponentHandle ); + + /** @ingroup alihlt_wrapper_interface */ + typedef int (*AliHLTExtFctProcessEvent)( AliHLTComponentHandle, const AliHLTComponentEventData*, const AliHLTComponentBlockData*, + AliHLTComponentTriggerData*, AliHLTUInt8_t*, + AliHLTUInt32_t*, AliHLTUInt32_t*, + AliHLTComponentBlockData**, + AliHLTComponentEventDoneData** ); + + /** @ingroup alihlt_wrapper_interface */ + typedef int (*AliHLTExtFctGetOutputDataType)( AliHLTComponentHandle, AliHLTComponentDataType* ); + + /** @ingroup alihlt_wrapper_interface */ + typedef int (*AliHLTExtFctGetOutputSize)( AliHLTComponentHandle, unsigned long*, double* ); + +} + +using namespace std; + +////////////////////////////////////////////////////////////////////////// +// +// Data type helper functions +// +////////////////////////////////////////////////////////////////////////// + +/** exact comparison of HLT component data types + * @ingroup alihlt_component_datatypes + */ +inline bool MatchExactly( const AliHLTComponentDataType& dt1, const AliHLTComponentDataType& dt2 ) +{ + for ( int i = 0; i < kAliHLTComponentDataTypefIDsize; i++ ) + if ( dt1.fID[i] != dt2.fID[i] ) + return false; + for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) + if ( dt1.fOrigin[i] != dt2.fOrigin[i] ) + return false; + return true; +} + +/** Comparison operator for HLT component data types. + * The operator takes wildcards into account, i.e. the ::kAliHLTAnyDataType, + * ::kAliHLTAnyDataTypeID and ::kAliHLTDataOriginAny definitions. + * @ingroup alihlt_component_datatypes + */ +inline bool operator==( const AliHLTComponentDataType& dt1, const AliHLTComponentDataType& dt2 ) +{ + if (MatchExactly(dt1, kAliHLTAllDataTypes)) return true; + if (MatchExactly(dt2, kAliHLTAllDataTypes)) return true; + + bool any1=true, any2=true, void1=true, void2=true, match=true; + for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) { + any1&=(dt1.fOrigin[i]==kAliHLTDataOriginAny[i]); + any2&=(dt2.fOrigin[i]==kAliHLTDataOriginAny[i]); + void1&=(dt1.fOrigin[i]==kAliHLTDataOriginVoid[i]); + void2&=(dt2.fOrigin[i]==kAliHLTDataOriginVoid[i]); + match&=dt1.fOrigin[i]==dt2.fOrigin[i]; + if (!(match || (any2 && !void1) || (any1 && !void2))) + return false; + } + + any1=true, any2=true, match=true; + for ( int i = 0; i < kAliHLTComponentDataTypefIDsize; i++ ) { + any1&=(dt1.fID[i]==kAliHLTAnyDataTypeID[i]); + any2&=(dt2.fID[i]==kAliHLTAnyDataTypeID[i]); + void1&=(dt1.fID[i]==kAliHLTVoidDataTypeID[i]); + void2&=(dt2.fID[i]==kAliHLTVoidDataTypeID[i]); + match&=dt1.fID[i]==dt2.fID[i]; + if (!(match || (any2 && !void1) || (any1 && !void2))) + return false; + } + return true; +} + +/** Comparison operator for HLT component data types + * Invers of operator== + * @ingroup alihlt_component_datatypes + */ +inline bool operator!=( const AliHLTComponentDataType& dt1, const AliHLTComponentDataType& dt2 ) +{ + return !(dt1==dt2); +} + +/** merge operator for HLT component data types and origins + * @ingroup alihlt_component_datatypes + */ +inline AliHLTComponentDataType operator|(const AliHLTComponentDataType srcdt, const char origin[kAliHLTComponentDataTypefOriginSize]) +{ + AliHLTComponentDataType dt=srcdt; + for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) + dt.fOrigin[i]=origin[i]; + return dt; +} + +/** + * Helper function to initialize a data type from an id char array and origin string. + * @return data type structure initialized with the specified id and origin + * @ingroup alihlt_component_datatypes + */ +inline AliHLTComponentDataType AliHLTComponentDataTypeInitializer(const char id[kAliHLTComponentDataTypefIDsize], const char* origin) +{ + AliHLTComponentDataType dt=kAliHLTVoidDataType; + int i=0; + for (i = 0; i < kAliHLTComponentDataTypefIDsize && id[i]!=0; i++) + dt.fID[i]=id[i]; + for (i = 0; i < kAliHLTComponentDataTypefOriginSize && origin[i]!=0; i++ ) + dt.fOrigin[i]=origin[i]; + return dt; +} + +/** + * Helper function to initialize a data type from a default data type and + * an origin string. Basically it merges the specified origin into the data + * type. + * @return data type structure initialized with the id from specified data type + * and origin + * @ingroup alihlt_component_datatypes + */ +inline AliHLTComponentDataType AliHLTComponentDataTypeInitializer(const AliHLTComponentDataType src, const char* origin) +{ + return AliHLTComponentDataTypeInitializer(src.fID, origin); +} + +#endif diff --git a/devices/aliceHLTwrapper/CMakeLists.txt b/devices/aliceHLTwrapper/CMakeLists.txt new file mode 100644 index 0000000000000..ed7fda44384a0 --- /dev/null +++ b/devices/aliceHLTwrapper/CMakeLists.txt @@ -0,0 +1,56 @@ +set(INCLUDE_DIRECTORIES + # ${CMAKE_SOURCE_DIR}/fairmq + # ${CMAKE_SOURCE_DIR}/fairmq/zeromq + # ${Boost_INCLUDE_DIR} + ${CMAKE_SOURCE_DIR}/devices/aliceHLTwrapper +) + +include_directories(${INCLUDE_DIRECTORIES}) + +#configure_file( ${CMAKE_SOURCE_DIR}/example/flp2epn/run/startSomething.sh.in ${CMAKE_BINARY_DIR}/bin/startSomething.sh ) + +set(LINK_DIRECTORIES + # ${Boost_LIBRARY_DIRS} +) + +link_directories(${LINK_DIRECTORIES}) + +set(SRCS + SystemInterface.cxx +) + +set(DEPENDENCIES + ${DEPENDENCIES} + # ${ZMQ_LIBRARY_SHARED} + ) + +set(DEPENDENCIES + ${DEPENDENCIES} +# ${CMAKE_THREAD_LIBS_INIT} + # FairMQ +) + +set(LIBRARY_NAME ALICEHLT) + +GENERATE_LIBRARY() + +Set(Exe_Names +# ${Exe_Names} + aliceHLTWrapper +) + +set(Exe_Source + aliceHLTWrapper.cxx +) + +list(LENGTH Exe_Names _length) +math(EXPR _length ${_length}-1) + +ForEach(_file RANGE 0 ${_length}) + list(GET Exe_Names ${_file} _name) + list(GET Exe_Source ${_file} _src) + set(EXE_NAME ${_name}) + set(SRCS ${_src}) + set(DEPENDENCIES ALICEHLT dl) + GENERATE_EXECUTABLE() +EndForEach(_file RANGE 0 ${_length}) diff --git a/devices/aliceHLTwrapper/SystemInterface.cxx b/devices/aliceHLTwrapper/SystemInterface.cxx new file mode 100644 index 0000000000000..63684552e3a57 --- /dev/null +++ b/devices/aliceHLTwrapper/SystemInterface.cxx @@ -0,0 +1,212 @@ +//**************************************************************************** +//* This file 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 3 of the License, or * +//* (at your option) any later version. * +//* * +//* Primary Authors: Matthias Richter * +//* * +//* The authors make no claims about the suitability of this software for * +//* any purpose. It is provided "as is" without express or implied warranty. * +//**************************************************************************** + +// @file SystemInterface.cxx +// @author Matthias Richter +// @since 2014-05-07 +// @brief FairRoot/ALFA interface to ALICE HLT code + +#include "SystemInterface.h" +#include "AliHLTDataTypes.h" +#include +#include +#include +#include +#include +using namespace ALICE::HLT; + +SystemInterface::SystemInterface() : + mpAliHLTExtFctInitSystem(NULL), + mpAliHLTExtFctDeinitSystem(NULL), + mpAliHLTExtFctLoadLibrary(NULL), + mpAliHLTExtFctUnloadLibrary(NULL), + mpAliHLTExtFctCreateComponent(NULL), + mpAliHLTExtFctDestroyComponent(NULL), + mpAliHLTExtFctProcessEvent(NULL), + mpAliHLTExtFctGetOutputDataType(NULL), + mpAliHLTExtFctGetOutputSize(NULL) +{ +} + +SystemInterface::~SystemInterface() +{ + /* THINK ABOUT + make SystemInterface a singleton and release the interface here if still + active + */ +} + +const char* gInterfaceCallSignatures[]={ + //int AliHLTAnalysisInitSystem( unsigned long version, AliHLTAnalysisEnvironment* externalEnv, unsigned long runNo, const char* runType ) + "int AliHLTAnalysisInitSystem(unsigned long,AliHLTAnalysisEnvironment*,unsigned long,const char*)", + + //int AliHLTAnalysisDeinitSystem() + "int AliHLTAnalysisDeinitSystem()", + + //int AliHLTAnalysisLoadLibrary( const char* libraryPath ) + "int AliHLTAnalysisLoadLibrary(const char*)", + + //int AliHLTAnalysisUnloadLibrary( const char* /*libraryPath*/ ) + "int AliHLTAnalysisUnloadLibrary(const char*)", + + //int AliHLTAnalysisCreateComponent( const char* componentType, void* environParam, int argc, const char** argv, AliHLTComponentHandle* handle, const char* description ) + "int AliHLTAnalysisCreateComponent(const char*,void*,int,const char**,AliHLTComponentHandle*,const char*)", + + //int AliHLTAnalysisDestroyComponent( AliHLTComponentHandle handle ) + "int AliHLTAnalysisDestroyComponent(AliHLTComponentHandle)", + + //int AliHLTAnalysisProcessEvent( AliHLTComponentHandle handle, const AliHLTComponentEventData* evtData, const AliHLTComponentBlockData* blocks, AliHLTComponentTriggerData* trigData, AliHLTUInt8_t* outputPtr, AliHLTUInt32_t* size, AliHLTUInt32_t* outputBlockCnt, AliHLTComponentBlockData** outputBlocks, AliHLTComponentEventDoneData** edd ) + "int AliHLTAnalysisProcessEvent(AliHLTComponentHandle,const AliHLTComponentEventData*,const AliHLTComponentBlockData*,AliHLTComponentTriggerData*,AliHLTUInt8_t*,AliHLTUInt32_t*,AliHLTUInt32_t*,AliHLTComponentBlockData**,AliHLTComponentEventDoneData**)", + + //int AliHLTAnalysisGetOutputDataType( AliHLTComponentHandle handle, AliHLTComponentDataType* dataType ) + "int AliHLTAnalysisGetOutputDataType(AliHLTComponentHandle,AliHLTComponentDataType*)", + + //int AliHLTAnalysisGetOutputSize( AliHLTComponentHandle handle, unsigned long* constEventBase, unsigned long* constBlockBase, double* inputBlockMultiplier ) + "int AliHLTAnalysisGetOutputSize(AliHLTComponentHandle,unsigned long*,unsigned long*,double*)", + + NULL +}; + +int SystemInterface::InitSystem() +{ + /// init the system: load interface libraries and read function pointers + string libraryPath=ALIHLTANALYSIS_INTERFACE_LIBRARY; + + void* libHandle=dlopen(libraryPath.c_str(), RTLD_NOW); + if (!libHandle) { + cerr << "error: can not load library " << libraryPath.c_str() << endl; + return -ELIBACC; + } + + AliHLTAnalysisFctGetInterfaceCall fctGetSystemCall=(AliHLTAnalysisFctGetInterfaceCall)dlsym(libHandle, ALIHLTANALYSIS_FCT_GETINTERFACECALL); + if (!fctGetSystemCall) { + cerr << "error: can not find function '" << ALIHLTANALYSIS_FCT_GETINTERFACECALL << "' in " << libraryPath.c_str() << endl; + return -ENOSYS; + } + + const char** arrayCalls=gInterfaceCallSignatures; + for (int i=0; arrayCalls[i]!=NULL; i++) { + AliHLTExtFctInitSystem call=(AliHLTExtFctInitSystem)(*fctGetSystemCall)(arrayCalls[i]); + if (call==NULL) { + cerr << "error: can not find function signature '" << arrayCalls[i] << "' in " << libraryPath.c_str() << endl; + } else { + cout << "function '" << arrayCalls[i] << "' loaded from " << libraryPath.c_str() << endl; + switch (i) { + case 0: mpAliHLTExtFctInitSystem=(AliHLTExtFctInitSystem)call; break; + case 1: mpAliHLTExtFctDeinitSystem=(AliHLTExtFctDeinitSystem)call; break; + case 2: mpAliHLTExtFctLoadLibrary=(AliHLTExtFctLoadLibrary)call; break; + case 3: mpAliHLTExtFctUnloadLibrary=(AliHLTExtFctUnloadLibrary)call; break; + case 4: mpAliHLTExtFctCreateComponent=(AliHLTExtFctCreateComponent)call; break; + case 5: mpAliHLTExtFctDestroyComponent=(AliHLTExtFctDestroyComponent)call; break; + case 6: mpAliHLTExtFctProcessEvent=(AliHLTExtFctProcessEvent)call; break; + case 7: mpAliHLTExtFctGetOutputDataType=(AliHLTExtFctGetOutputDataType)call; break; + case 8: mpAliHLTExtFctGetOutputSize=(AliHLTExtFctGetOutputSize)call; break; + default: + cerr << "error: number of function signatures does not match expected number of functions" << endl; + } + } + } + + return 0; +} + +int SystemInterface::ReleaseSystem() +{ + /// release the system interface, clean all internal structures + + /* THINK ABOUT + bookkeeping of loaded libraries and unloading them before releasing the system? + */ + int iResult=0; + if (mpAliHLTExtFctDeinitSystem) + iResult=(*mpAliHLTExtFctDeinitSystem)(); + Clear(); + return iResult; +} + +int SystemInterface::LoadLibrary(const char* libname) +{ + if (!mpAliHLTExtFctLoadLibrary) return -ENOSYS; + return (*mpAliHLTExtFctLoadLibrary)(libname); +} + +int SystemInterface::UnloadLibrary(const char* libname) +{ + if (!mpAliHLTExtFctUnloadLibrary) return -ENOSYS; + return (*mpAliHLTExtFctUnloadLibrary)(libname); +} + +int SystemInterface::CreateComponent(const char* componentType, + void* environParam, + int argc, + const char** argv, + AliHLTComponentHandle* handle, + const char* description + ) +{ + if (!mpAliHLTExtFctCreateComponent) return -ENOSYS; + return (*mpAliHLTExtFctCreateComponent)(componentType, + environParam, + argc, argv, + handle, + description); +} + +int SystemInterface::DestroyComponent(AliHLTComponentHandle handle) +{ + if (!mpAliHLTExtFctDestroyComponent) return -ENOSYS; + return (*mpAliHLTExtFctDestroyComponent)(handle); +} + +int SystemInterface::ProcessEvent( AliHLTComponentHandle handle, + const AliHLTComponentEventData* evtData, const AliHLTComponentBlockData* blocks, + AliHLTComponentTriggerData* trigData, + AliHLTUInt8_t* outputPtr, AliHLTUInt32_t* size, + AliHLTUInt32_t* outputBlockCnt, AliHLTComponentBlockData** outputBlocks, + AliHLTComponentEventDoneData** edd ) +{ + if (!mpAliHLTExtFctProcessEvent) return -ENOSYS; + return (*mpAliHLTExtFctProcessEvent)(handle, evtData, blocks, trigData, + outputPtr, size, outputBlockCnt, outputBlocks, edd); +} + +int SystemInterface::GetOutputDataType(AliHLTComponentHandle handle, AliHLTComponentDataType* dataType) +{ + if (!mpAliHLTExtFctGetOutputDataType) return -ENOSYS; + return (*mpAliHLTExtFctGetOutputDataType)(handle, dataType); +} + +int SystemInterface::GetOutputSize(AliHLTComponentHandle handle, unsigned long* constEventBase, + unsigned long* /*constBlockBase*/, double* inputBlockMultiplier) +{ + if (!mpAliHLTExtFctGetOutputSize) return -ENOSYS; + return (*mpAliHLTExtFctGetOutputSize)(handle, constEventBase, inputBlockMultiplier); +} + +void SystemInterface::Clear(const char* /*option*/) +{ + /// clear the object and reset pointer references + mpAliHLTExtFctInitSystem = NULL; + mpAliHLTExtFctDeinitSystem = NULL; + mpAliHLTExtFctLoadLibrary = NULL; + mpAliHLTExtFctUnloadLibrary = NULL; + mpAliHLTExtFctCreateComponent = NULL; + mpAliHLTExtFctDestroyComponent = NULL; + mpAliHLTExtFctProcessEvent = NULL; + mpAliHLTExtFctGetOutputDataType = NULL; + mpAliHLTExtFctGetOutputSize = NULL; +} + +void SystemInterface::Print(const char* /*option*/) const +{ + /// print info +} diff --git a/devices/aliceHLTwrapper/SystemInterface.h b/devices/aliceHLTwrapper/SystemInterface.h new file mode 100644 index 0000000000000..8ca3f51bfd87b --- /dev/null +++ b/devices/aliceHLTwrapper/SystemInterface.h @@ -0,0 +1,117 @@ +//-*- Mode: C++ -*- + +#ifndef SYSTEMINTERFACE_H +#define SYSTEMINTERFACE_H +//**************************************************************************** +//* This file 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 3 of the License, or * +//* (at your option) any later version. * +//* * +//* Primary Authors: Matthias Richter * +//* * +//* The authors make no claims about the suitability of this software for * +//* any purpose. It is provided "as is" without express or implied warranty. * +//**************************************************************************** + +// @file SystemInterface.h +// @author Matthias Richter +// @since 2014-05-07 +// @brief FairRoot/ALFA interface to ALICE HLT code + +#include "AliHLTDataTypes.h" +namespace ALICE +{ + namespace HLT + { + + class SystemInterface { + public: + /// default constructor + SystemInterface(); + /// destructor + ~SystemInterface(); + + /** initilize the system + * load external library and set up the HLT system + */ + int InitSystem(); + + /** cleanup and release system + */ + int ReleaseSystem(); + + /** load HLT plugin library + */ + int LoadLibrary(const char* libname); + + /** unload HLT plugin library + */ + int UnloadLibrary(const char* libname); + + /** create/factorize component + * @param componentType + * @param environParam + * @param argc + * @param argv + * @param handle + * @param description + * @return 0 on success and valid handle + */ + int CreateComponent(const char* componentType, + void* environParam, + int argc, + const char** argv, + AliHLTComponentHandle* handle, + const char* description + ); + + /** create/factorize component + * @param handle + * @return 0 on success + */ + int DestroyComponent(AliHLTComponentHandle handle); + + /** process event + */ + int ProcessEvent( AliHLTComponentHandle handle, + const AliHLTComponentEventData* evtData, const AliHLTComponentBlockData* blocks, + AliHLTComponentTriggerData* trigData, + AliHLTUInt8_t* outputPtr, AliHLTUInt32_t* size, + AliHLTUInt32_t* outputBlockCnt, AliHLTComponentBlockData** outputBlocks, + AliHLTComponentEventDoneData** edd ); + + /** get the output data type + */ + int GetOutputDataType(AliHLTComponentHandle handle, AliHLTComponentDataType* dataType); + + /** get output data size + * return an estimation of the size of the produced data relative to the number of + * input blocks and input size + */ + int GetOutputSize(AliHLTComponentHandle handle, unsigned long* constEventBase, + unsigned long* constBlockBase, double* inputBlockMultiplier); + + /// clear the object and reset pointer references + virtual void Clear(const char* /*option*/ =""); + + /// print info + virtual void Print(const char* option="") const; + + protected: + + private: + AliHLTExtFctInitSystem mpAliHLTExtFctInitSystem; + AliHLTExtFctDeinitSystem mpAliHLTExtFctDeinitSystem; + AliHLTExtFctLoadLibrary mpAliHLTExtFctLoadLibrary; + AliHLTExtFctUnloadLibrary mpAliHLTExtFctUnloadLibrary; + AliHLTExtFctCreateComponent mpAliHLTExtFctCreateComponent; + AliHLTExtFctDestroyComponent mpAliHLTExtFctDestroyComponent; + AliHLTExtFctProcessEvent mpAliHLTExtFctProcessEvent; + AliHLTExtFctGetOutputDataType mpAliHLTExtFctGetOutputDataType; + AliHLTExtFctGetOutputSize mpAliHLTExtFctGetOutputSize; + }; + + } // namespace hlt +} // namespace alice +#endif // SYSTEMINTERFACE_H diff --git a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx new file mode 100644 index 0000000000000..e206022157173 --- /dev/null +++ b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx @@ -0,0 +1,25 @@ +//**************************************************************************** +//* This file 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 3 of the License, or * +//* (at your option) any later version. * +//* * +//* Primary Authors: Matthias Richter * +//* * +//* The authors make no claims about the suitability of this software for * +//* any purpose. It is provided "as is" without express or implied warranty. * +//**************************************************************************** + +// @file aliHLTWrapper.cxx +// @author Matthias Richter +// @since 2014-05-07 +// @brief FairRoot/ALFA device running ALICE HLT code + +#include "SystemInterface.h" + +int main(int argc, char** argv) +{ + ALICE::HLT::SystemInterface iface; + iface.InitSystem(); + return 0; +} From 9400e82ba6a4a3315ca1221d7df29d6b30dd7a08 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Thu, 8 May 2014 01:13:40 +0200 Subject: [PATCH 02/34] adding command line parsing and workflow up to the creation of the component --- devices/aliceHLTwrapper/SystemInterface.cxx | 20 ++++-- devices/aliceHLTwrapper/SystemInterface.h | 6 +- devices/aliceHLTwrapper/aliceHLTWrapper.cxx | 74 ++++++++++++++++++++- 3 files changed, 93 insertions(+), 7 deletions(-) diff --git a/devices/aliceHLTwrapper/SystemInterface.cxx b/devices/aliceHLTwrapper/SystemInterface.cxx index 63684552e3a57..2619d9bdb147d 100644 --- a/devices/aliceHLTwrapper/SystemInterface.cxx +++ b/devices/aliceHLTwrapper/SystemInterface.cxx @@ -33,8 +33,11 @@ SystemInterface::SystemInterface() : mpAliHLTExtFctDestroyComponent(NULL), mpAliHLTExtFctProcessEvent(NULL), mpAliHLTExtFctGetOutputDataType(NULL), - mpAliHLTExtFctGetOutputSize(NULL) + mpAliHLTExtFctGetOutputSize(NULL), + mEnvironment() { + memset(&mEnvironment, 0, sizeof(mEnvironment)); + mEnvironment.fStructSize=sizeof(mEnvironment); } SystemInterface::~SystemInterface() @@ -76,9 +79,11 @@ const char* gInterfaceCallSignatures[]={ NULL }; -int SystemInterface::InitSystem() +int SystemInterface::InitSystem(unsigned long runNo) { /// init the system: load interface libraries and read function pointers + int iResult=0; + string libraryPath=ALIHLTANALYSIS_INTERFACE_LIBRARY; void* libHandle=dlopen(libraryPath.c_str(), RTLD_NOW); @@ -115,6 +120,13 @@ int SystemInterface::InitSystem() } } } + + if (mpAliHLTExtFctInitSystem) { + if ((iResult=(*mpAliHLTExtFctInitSystem)(ALIHLT_DATA_TYPES_VERSION, &mEnvironment, runNo, NULL))!=0) { + cerr << "error: AliHLTAnalysisInitSystem failed with error " << iResult << endl; + return -ENOSYS; + } + } return 0; } @@ -145,7 +157,7 @@ int SystemInterface::UnloadLibrary(const char* libname) return (*mpAliHLTExtFctUnloadLibrary)(libname); } -int SystemInterface::CreateComponent(const char* componentType, +int SystemInterface::CreateComponent(const char* componentId, void* environParam, int argc, const char** argv, @@ -154,7 +166,7 @@ int SystemInterface::CreateComponent(const char* componentType, ) { if (!mpAliHLTExtFctCreateComponent) return -ENOSYS; - return (*mpAliHLTExtFctCreateComponent)(componentType, + return (*mpAliHLTExtFctCreateComponent)(componentId, environParam, argc, argv, handle, diff --git a/devices/aliceHLTwrapper/SystemInterface.h b/devices/aliceHLTwrapper/SystemInterface.h index 8ca3f51bfd87b..d5e07b22b5cbf 100644 --- a/devices/aliceHLTwrapper/SystemInterface.h +++ b/devices/aliceHLTwrapper/SystemInterface.h @@ -35,7 +35,7 @@ namespace ALICE /** initilize the system * load external library and set up the HLT system */ - int InitSystem(); + int InitSystem(unsigned long runNo); /** cleanup and release system */ @@ -58,7 +58,7 @@ namespace ALICE * @param description * @return 0 on success and valid handle */ - int CreateComponent(const char* componentType, + int CreateComponent(const char* componentId, void* environParam, int argc, const char** argv, @@ -110,6 +110,8 @@ namespace ALICE AliHLTExtFctProcessEvent mpAliHLTExtFctProcessEvent; AliHLTExtFctGetOutputDataType mpAliHLTExtFctGetOutputDataType; AliHLTExtFctGetOutputSize mpAliHLTExtFctGetOutputSize; + + AliHLTAnalysisEnvironment mEnvironment; }; } // namespace hlt diff --git a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx index e206022157173..a92a4c1a93533 100644 --- a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx +++ b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx @@ -16,10 +16,82 @@ // @brief FairRoot/ALFA device running ALICE HLT code #include "SystemInterface.h" +#include +#include +#include +#include +#include + +using std::cout; +using std::cerr; int main(int argc, char** argv) { + int iResult=0; + // parse options + static struct option programOptions[] = { + {"library", required_argument, 0, 'l'}, + {"component", required_argument, 0, 'c'}, + {"parameter", required_argument, 0, 'p'}, + {"run", required_argument, 0, 'r'}, + {0, 0, 0, 0} + }; + + /* getopt_long stores the option index here. */ + char c=0; + int iOption = 0; + const char* componentLibrary=""; + const char* componentId=""; + const char* componentParameter=""; + int runNumber=0; + + while ((c=getopt_long(argc, argv, "l:c:p:", programOptions, &iOption)) != -1) { + switch (c) { + case 'l': + componentLibrary=optarg; + break; + case 'c': + componentId=optarg; + break; + case 'p': + componentParameter=optarg; + break; + case '?': + // TODO: more error handling + break; + default: + cerr << "unknown option: '"<< c << "'" << endl; + } + } + + cout << "Library: " << componentLibrary << " - " << componentId << " (" << componentParameter << ")" << endl; + + AliHLTComponentHandle componentHandle=kEmptyHLTComponentHandle; + + // chop the parameter string in order to provide parameters in the argc/argv format + vector parameters; + auto_ptr parameterBuffer(new char[strlen(componentParameter)+1]); + if (strlen(componentParameter)>0 && parameterBuffer.get()!=NULL) { + strcpy(parameterBuffer.get(), componentParameter); + char* iterator=parameterBuffer.get(); + parameters.push_back(iterator); + for (; *iterator!=0; iterator++) { + if (*iterator!=' ') continue; + *iterator=0; // separate strings + if (*(iterator+1)!=' ' && *(iterator+1)!=0) + parameters.push_back(iterator+1); + } + } + ALICE::HLT::SystemInterface iface; - iface.InitSystem(); + if ((iResult=iface.InitSystem(runNumber))<0) + return iResult; + + if ((iResult=iface.LoadLibrary(componentLibrary))<0) + return iResult; + + if ((iResult=iface.CreateComponent(componentId, NULL, parameters.size(), ¶meters[0], &componentHandle, ""))<0) + return iResult; + return 0; } From ca199e2b7917c74696c246095c9f951c2e03d263 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Thu, 8 May 2014 09:52:08 +0200 Subject: [PATCH 03/34] adding support of HOMER library from the ALICE HLT project (HLT Online Monitoring Environment including ROOT) --- devices/aliceHLTwrapper/AliHLTHOMERData.h | 391 +++++++++++++++++++ devices/aliceHLTwrapper/AliHLTHOMERReader.h | 395 ++++++++++++++++++++ devices/aliceHLTwrapper/AliHLTHOMERWriter.h | 282 ++++++++++++++ devices/aliceHLTwrapper/CMakeLists.txt | 1 + devices/aliceHLTwrapper/HOMERFactory.cxx | 317 ++++++++++++++++ devices/aliceHLTwrapper/HOMERFactory.h | 182 +++++++++ 6 files changed, 1568 insertions(+) create mode 100644 devices/aliceHLTwrapper/AliHLTHOMERData.h create mode 100644 devices/aliceHLTwrapper/AliHLTHOMERReader.h create mode 100644 devices/aliceHLTwrapper/AliHLTHOMERWriter.h create mode 100644 devices/aliceHLTwrapper/HOMERFactory.cxx create mode 100644 devices/aliceHLTwrapper/HOMERFactory.h diff --git a/devices/aliceHLTwrapper/AliHLTHOMERData.h b/devices/aliceHLTwrapper/AliHLTHOMERData.h new file mode 100644 index 0000000000000..3d5a997b9e306 --- /dev/null +++ b/devices/aliceHLTwrapper/AliHLTHOMERData.h @@ -0,0 +1,391 @@ +// XEMacs -*-C++-*- +#ifndef ALIHLTHOMERDATA_H +#define ALIHLTHOMERDATA_H + +// @file AliHLTHOMERData.h +// @author Matthias Richter +// @since 2014-05-07 +// @brief Original AliHLTHOMERData.h of AliRoot included for HOMER +// support in the ALFA project + + +//************************************************************************ +//* +//* +//* This file is property of and copyright by the Technical Computer +//* Science Group, Kirchhoff Institute for Physics, Ruprecht-Karls- +//* University, Heidelberg, Germany, 2001 +//* This file has been written by Timm Morten Steinbeck, +//* timm@kip.uni-heidelberg.de +//* +//* +//* See the file license.txt for details regarding usage, modification, +//* distribution and warranty. +//* Important: This file is provided without any warranty, including +//* fitness for any particular purpose. +//* +//* +//* Newer versions of this file's package will be made available from +//* http://web.kip.uni-heidelberg.de/Hardwinf/L3/ +//* or the corresponding page of the Heidelberg Alice Level 3 group. +//* +//************************************************************************/ + +/* +*************************************************************************** +** +** $Author$ - Initial Version by Timm Morten Steinbeck +** +** $Id$ +** +*************************************************************************** +*/ + +#ifdef USE_ROOT +#include "Rtypes.h" +#endif +#include + + +// Determine the sizes of the different integer type +// homer_uint32, homer_uint64 +#if !defined(USE_ROOT) && !defined(__CINT__) +// First homer_uint32 +#if USHRT_MAX==4294967295 +typedef unsigned short homer_uint32; +#else // USHRT_MAX==4294967295 + +#if UINT_MAX==4294967295 +typedef unsigned int homer_uint32; +#else // UINT_MAX==4294967295 + +#if ULONG_MAX==4294967295l +typedef unsigned long homer_uint32; +#else // ULONG_MAX==4294967295l + +#error Could not typedef homer_uint32 + +#endif // ULONG_MAX==4294967295l + +#endif // UINT_MAX==4294967295 + +#endif // USHRT_MAX==4294967295 + +// Then homer_uint16 +#if USHRT_MAX==65535 +typedef unsigned short homer_uint16; +#else // USHRT_MAX==65535 + +#if UINT_MAX==65535 +typedef unsigned int homer_uint16; +#else // UINT_MAX==65535 + +#if ULONG_MAX==65535 +typedef unsigned long homer_uint16; +#else // ULONG_MAX==65535 + +#error Could not typedef homer_uint16 + +#endif // ULONG_MAX==65535 + +#endif // UINT_MAX==65535 + +#endif // USHRT_MAX==65535 + +// Then homer_uint64 +#if ULONG_MAX==18446744073709551615UL +typedef unsigned long homer_uint64; +#else // ULONG_MAX==18446744073709551615UL + +#if defined __GNUC__ +typedef unsigned long long homer_uint64; +#else // defined __GNUC__ + +#if defined __SUNPRO_CC +typedef unsigned long long homer_uint64; +#else // defined __SUNPRO_CC + +#error Could not typedef homer_uint64 + +#endif // defined __SUNPRO_CC +#endif // defined __GNUC__ + +#endif // ULONG_MAX==18446744073709551615UL + +typedef unsigned char homer_uint8; + +#else // !USE_ROOT && !CINT + + +typedef UShort_t homer_uint16; +typedef UInt_t homer_uint32; +typedef ULong64_t homer_uint64; +typedef Byte_t homer_uint8; + +#ifdef __CINT__ +typedef int key_t; +#endif + +#endif // USE_ROOT + +//typedef homer_uint64 AliEventID_t; + + +#define kAttribute_8b_StartOffset 0 +#define kByteOrderAttribute_8b_Offset kAttribute_8b_StartOffset+0 +#define kVersionAttribute_8b_Offset kAttribute_8b_StartOffset+1 +#define kAlignment_8b_StartOffset 24 +#define kUInt64Alignment_8b_Offset kAlignment_8b_StartOffset+0 +#define kUInt32Alignment_8b_Offset kAlignment_8b_StartOffset+1 +#define kUInt16Alignment_8b_Offset kAlignment_8b_StartOffset+2 +#define kUInt8Alignment_8b_Offset kAlignment_8b_StartOffset+3 +#define kDoubleAlignment_8b_Offset kAlignment_8b_StartOffset+4 +#define kFloatAlignment_8b_Offset kAlignment_8b_StartOffset+5 + + +#define kID_64b_Offset 1 +#define kLength_64b_Offset 2 +#define kType_64b_Offset 4 +#define kSubType1_64b_Offset 5 +#define kSubType2_64b_Offset 6 +#define kBirth_s_64b_Offset 7 +#define kBirth_us_64b_Offset 8 +#define kProducerNode_64b_Offset 9 +#define kOffset_64b_Offset 10 +#define kSize_64b_Offset 11 +#define kStatusFlags_64b_Offset 12 +#define kEnd_64b_Offset 13 +#define kCount_64b_Words kEnd_64b_Offset + +// Possible values for fAttributes[kByteOrderAttribute] +/* Keep this consistent with BCLNetworkData.hpp kLittleEndian/kBigEndian and AliHLTSubEventDataDescriptor.hpp */ +const homer_uint8 kHOMERUnknownByteOrder = 0; +const homer_uint8 kHOMERLittleEndianByteOrder = 1; +const homer_uint8 kHOMERBigEndianByteOrder = 2; +#ifdef __i386__ + const homer_uint8 kHOMERNativeByteOrder = kHOMERLittleEndianByteOrder; +#else +#ifdef __arm__ + const homer_uint8 kHOMERNativeByteOrder = kHOMERLittleEndianByteOrder; +#else +#ifdef __x86_64__ + const homer_uint8 kHOMERNativeByteOrder = kHOMERLittleEndianByteOrder; +#else +#ifdef __ia64__ + const homer_uint8 kHOMERNativeByteOrder = kHOMERLittleEndianByteOrder; +#else +#if defined(__powerpc__) + const homer_uint8 kHOMERNativeByteOrder = kHOMERBigEndianByteOrder; +#else +#ifdef __CINT__ + const homer_uint8 kHOMERNativeByteOrder = kHOMERLittleEndianByteOrder; +#warning Assuming little endian format for __CINT__ +#else + const homer_uint8 kHOMERNativeByteOrder = kHOMERLittleEndianByteOrder; +#warning Assuming little endian format for unknown architecture +//#error Byte format (little/big endian) currently not defined for platforms other than intel i386 compatible, x86-64 (AMD64) and arm... +#endif +#endif +#endif +#endif +#endif +#endif + + +//#define HOMER_BLOCK_DESCRIPTOR_TYPEID (((homer_uint64)'HOBL')<<32 | 'KDES') +#define HOMER_BLOCK_DESCRIPTOR_TYPEID ( (((homer_uint64)'H')<<56)|(((homer_uint64)'O')<<48)|(((homer_uint64)'B')<<40)|(((homer_uint64)'L')<<32)|(((homer_uint64)'K')<<24)|(((homer_uint64)'D')<<16)|(((homer_uint64)'E')<<8)|(((homer_uint64)'S')<<0) ) +//#define HOMER_BLOCK_DESCRIPTOR_TYPEID ( (((homer_uint64)'H')<<56)|(((homer_uint64)'O')<<48) ) +#define HOMER_HEADER_CURRENT_VERSION 2 + + +class AliHLTHOMERBlockDescriptor + { + public: + + static unsigned GetHOMERBlockDescriptorSize() + { + return sizeof(homer_uint64)*kCount_64b_Words; + } + + AliHLTHOMERBlockDescriptor( void* header = 0 ) + : fHeader(header) + { + } + void UseHeader( void* header ) + { + fHeader = header; + } + void Initialize() + { + if ( fHeader ) + { + for ( unsigned ii=0; ii +#include +#include +#include "AliHLTHOMERData.h" + + + +/** + * @class AliHLTMonitoringReader + * The class provides a virtual interface for the HOMER reader. + * Used for dynamic generation of HOMER readers and dynamic loading of + * the libAliHLTHOMER library. + * @see AliHLTHOMERLibManager + * + * @ingroup alihlt_homer + */ +class AliHLTMonitoringReader + { + public: + + AliHLTMonitoringReader() {}; + virtual ~AliHLTMonitoringReader() {}; + + /* Return the status of the connection as established by one of the constructors. + 0 means connection is ok, non-zero specifies the type of error that occured. */ + virtual int GetConnectionStatus() const = 0; + + /* Return the index of the connection for which an error given by the above + function occured. */ + virtual unsigned int GetErrorConnectionNdx() const = 0; + + /* Read in the next available event */ + virtual int ReadNextEvent() = 0; + /* Read in the next available event, wait max. timeout microsecs. */ + virtual int ReadNextEvent( unsigned long timeout ) = 0; + + /* Return the type of the current event */ + virtual homer_uint64 GetEventType() const = 0; + + /* Return the ID of the current event */ + virtual homer_uint64 GetEventID() const = 0; + + /* Return the number of data blocks in the current event */ + virtual unsigned long GetBlockCnt() const = 0; + + /* Return the size (in bytes) of the current event's data + block with the given block index (starting at 0). */ + virtual unsigned long GetBlockDataLength( unsigned long ndx ) const = 0; + /* Return a pointer to the start of the current event's data + block with the given block index (starting at 0). */ + virtual const void* GetBlockData( unsigned long ndx ) const = 0; + /* Return IP address or hostname of node which sent the + current event's data block with the given block index + (starting at 0). */ + virtual const char* GetBlockSendNodeID( unsigned long ndx ) const = 0; + /* Return byte order of the data stored in the + current event's data block with the given block + index (starting at 0). + 0 is unknown alignment, + 1 ist little endian, + 2 is big endian. */ + virtual homer_uint8 GetBlockByteOrder( unsigned long ndx ) const = 0; + /* Return the alignment (in bytes) of the given datatype + in the data stored in the current event's data block + with the given block index (starting at 0). + Possible values for the data type are + 0: homer_uint64 + 1: homer_uint32 + 2: uin16 + 3: homer_uint8 + 4: double + 5: float + */ + virtual homer_uint8 GetBlockTypeAlignment( unsigned long ndx, homer_uint8 dataType ) const = 0; + + virtual homer_uint64 GetBlockStatusFlags( unsigned long ndx ) const = 0; + + /* Return the type of the data in the current event's data + block with the given block index (starting at 0). */ + virtual homer_uint64 GetBlockDataType( unsigned long ndx ) const = 0; + /* Return the origin of the data in the current event's data + block with the given block index (starting at 0). */ + virtual homer_uint32 GetBlockDataOrigin( unsigned long ndx ) const = 0; + /* Return a specification of the data in the current event's data + block with the given block index (starting at 0). */ + virtual homer_uint32 GetBlockDataSpec( unsigned long ndx ) const = 0; + + /* Find the next data block in the current event with the given + data type, origin, and specification. Returns the block's + index. */ + virtual unsigned long FindBlockNdx( homer_uint64 type, homer_uint32 origin, + homer_uint32 spec, unsigned long startNdx=0 ) const = 0; + + /* Find the next data block in the current event with the given + data type, origin, and specification. Returns the block's + index. */ + virtual unsigned long FindBlockNdx( char type[8], char origin[4], + homer_uint32 spec, unsigned long startNdx=0 ) const = 0; +#ifdef USE_ROOT + ClassDef(AliHLTMonitoringReader,1); +#endif + }; + + + +class AliHLTHOMERReader: public AliHLTMonitoringReader + { + public: +#ifdef USE_ROOT + AliHLTHOMERReader(); +#endif + + /* Constructors & destructors, HOMER specific */ + /* For reading from a TCP port */ + AliHLTHOMERReader( const char* hostname, unsigned short port ); + /* For reading from multiple TCP ports */ + AliHLTHOMERReader( unsigned int tcpCnt, const char** hostnames, const unsigned short* ports ); + /* For reading from a System V shared memory segment */ + AliHLTHOMERReader( key_t shmKey, int shmSize ); + /* For reading from multiple System V shared memory segments */ + AliHLTHOMERReader( unsigned int shmCnt, const key_t* shmKey, const int* shmSize ); + /* For reading from multiple TCP ports and multiple System V shared memory segments */ + AliHLTHOMERReader( unsigned int tcpCnt, const char** hostnames, const unsigned short* ports, + unsigned int shmCnt, const key_t* shmKey, const int* shmSize ); + /* For reading from a buffer */ + AliHLTHOMERReader( const void* pBuffer, int size ); + virtual ~AliHLTHOMERReader(); + + /* Return the status of the connection as established by one of the constructors. + 0 means connection is ok, non-zero specifies the type of error that occured. */ + int GetConnectionStatus() const + { + return fConnectionStatus; + } + + /* Return the index of the connection for which an error given by the above + function occured. */ + unsigned int GetErrorConnectionNdx() const + { + return fErrorConnection; + } + + void SetEventRequestAdvanceTime( unsigned long time ) + { + // advance time in us + fEventRequestAdvanceTime = time; + } + + /* Defined in AliHLTMonitoringReader */ + /** Read in the next available event */ + virtual int ReadNextEvent(); + /** Read in the next available event */ + virtual int ReadNextEvent( unsigned long timeout ); + + /** Return the type of the current event */ + virtual homer_uint64 GetEventType() const + { + return fCurrentEventType; + } + + /** Return the ID of the current event */ + virtual homer_uint64 GetEventID() const + { + return fCurrentEventID; + } + + /** Return the number of data blocks in the current event */ + virtual unsigned long GetBlockCnt() const + { + return fBlockCnt; + } + + /** Return a pointer to the start of the current event's data + block with the given block index (starting at 0). */ + virtual const void* GetBlockData( unsigned long ndx ) const; + /** Return the size (in bytes) of the current event's data + block with the given block index (starting at 0). */ + virtual unsigned long GetBlockDataLength( unsigned long ndx ) const; + /** Return IP address or hostname of node which sent the + current event's data block with the given block index + (starting at 0). + For HOMER this is the ID of the node on which the subscriber + that provided this data runs/ran. */ + virtual const char* GetBlockSendNodeID( unsigned long ndx ) const; + /** Return byte order of the data stored in the + current event's data block with the given block + index (starting at 0). + 0 is unknown alignment, + 1 ist little endian, + 2 is big endian. */ + virtual homer_uint8 GetBlockByteOrder( unsigned long ndx ) const; + /** Return the alignment (in bytes) of the given datatype + in the data stored in the current event's data block + with the given block index (starting at 0). + Possible values for the data type are + 0: homer_uint64 + 1: homer_uint32 + 2: uin16 + 3: homer_uint8 + 4: double + 5: float + */ + virtual homer_uint8 GetBlockTypeAlignment( unsigned long ndx, homer_uint8 dataType ) const; + + virtual homer_uint64 GetBlockStatusFlags( unsigned long ndx ) const; + + /* HOMER specific */ + /** Return the type of the data in the current event's data + block with the given block index (starting at 0). */ + homer_uint64 GetBlockDataType( unsigned long ndx ) const; + /** Return the origin of the data in the current event's data + block with the given block index (starting at 0). */ + homer_uint32 GetBlockDataOrigin( unsigned long ndx ) const; + /** Return a specification of the data in the current event's data + block with the given block index (starting at 0). */ + homer_uint32 GetBlockDataSpec( unsigned long ndx ) const; + + /** Return the time stamp of when the data block was created. + This is a UNIX time stamp in seconds. + \param ndx The index of the block (starting at 0). */ + homer_uint64 GetBlockBirthSeconds( unsigned long ndx ) const; + + /** Return the micro seconds part of the time stamp of when the data + block was created. + \param ndx The index of the block (starting at 0). */ + homer_uint64 GetBlockBirthMicroSeconds( unsigned long ndx ) const; + + /** Find the next data block in the current event with the given + data type, origin, and specification. Returns the block's + index. */ + unsigned long FindBlockNdx( homer_uint64 type, homer_uint32 origin, + homer_uint32 spec, unsigned long startNdx=0 ) const; + + /** Find the next data block in the current event with the given + data type, origin, and specification. Returns the block's + index. */ + unsigned long FindBlockNdx( char type[8], char origin[4], + homer_uint32 spec, unsigned long startNdx=0 ) const; + + /** Return the ID of the node that actually produced this data block. + This may be different from the node which sent the data to this + monitoring object as returned by GetBlockSendNodeID. */ + const char* GetBlockCreateNodeID( unsigned long ndx ) const; + + protected: + + enum DataSourceType { kUndef=0, kTCP, kShm, kBuf}; + struct DataSource + { + DataSourceType fType; // source type (TCP or Shm) + unsigned fNdx; // This source's index + const char* fHostname; // Filled for both Shm and TCP + unsigned short fTCPPort; // port if type TCP + key_t fShmKey; // shm key if type Shm + int fShmSize; // shm size if type Shm + int fTCPConnection; // File descriptor for the TCP connection + int fShmID; // ID of the shared memory area + void* fShmPtr; // Pointer to shared memory area + void* fData; // Pointer to data read in for current event from this source + unsigned long fDataSize; // Size of data (to be) read in for current event from this source + unsigned long fDataRead; // Data actually read for current event + }; + + void Init(); + + bool AllocDataSources( unsigned int sourceCnt ); + int AddDataSource( const char* hostname, unsigned short port, DataSource& source ); + int AddDataSource( key_t shmKey, int shmSize, DataSource& source ); + int AddDataSource( void* pBuffer, int size, DataSource& source ); + void FreeDataSources(); + int FreeShmDataSource( DataSource& source ); + int FreeTCPDataSource( DataSource& source ); + int ReadNextEvent( bool useTimeout, unsigned long timeout ); + void ReleaseCurrentEvent(); + int TriggerTCPSource( DataSource& source, bool useTimeout, unsigned long timeout ); + int TriggerShmSource( DataSource& source, bool useTimeout, unsigned long timeout ) const; + int ReadDataFromTCPSources( unsigned sourceCnt, DataSource* sources, bool useTimeout, unsigned long timeout ); + int ReadDataFromShmSources( unsigned sourceCnt, DataSource* sources, bool useTimeout, unsigned long timeout ); + int ParseSourceData( const DataSource& source ); + int ReAllocBlocks( unsigned long newCnt ); + homer_uint64 GetSourceEventID( const DataSource& source ); + homer_uint64 GetSourceEventType( const DataSource& source ); + homer_uint64 Swap( homer_uint8 destFormat, homer_uint8 sourceFormat, homer_uint64 source ) const; + + homer_uint32 Swap( homer_uint8 destFormat, homer_uint8 sourceFormat, homer_uint32 source ) const; + + + struct DataBlock + { + unsigned int fSource; // Index of originating data source + void* fData; // pointer to data + unsigned long fLength; // buffer length + homer_uint64* fMetaData; // Pointer to meta data describing data itself. + const char* fOriginatingNodeID; // node id from which the data originates + }; + + /** type of the current event */ + homer_uint64 fCurrentEventType; //!transient + /** ID of the current event */ + homer_uint64 fCurrentEventID; //!transient + /** no of blocks currently used */ + unsigned long fBlockCnt; //!transient + /** available space in the block array */ + unsigned long fMaxBlockCnt; //!transient + /** block array */ + DataBlock* fBlocks; //!transient + + /** total no of data sources */ + unsigned int fDataSourceCnt; //!transient + /** no of TCP data sources */ + unsigned int fTCPDataSourceCnt; //!transient + /** no of Shm data sources */ + unsigned int fShmDataSourceCnt; //!transient + /** available space in the sources array */ + unsigned int fDataSourceMaxCnt; //!transient + /** array of data source descriptions */ + DataSource* fDataSources; //!transient + + /** status of the connection */ + int fConnectionStatus; //!transient + /** flag an error for */ + unsigned fErrorConnection; //!transient + + /** */ + unsigned long fEventRequestAdvanceTime; //!transient + private: + /** copy constructor prohibited */ + AliHLTHOMERReader(const AliHLTHOMERReader&); + /** assignment operator prohibited */ + AliHLTHOMERReader& operator=(const AliHLTHOMERReader&); + +#ifdef USE_ROOT + ClassDef(AliHLTHOMERReader,2); +#endif + }; + +/** defined for backward compatibility */ +typedef AliHLTMonitoringReader MonitoringReader; +/** defined for backward compatibility */ +typedef AliHLTHOMERReader HOMERReader; + +// external interface of the HOMER reader +#define ALIHLTHOMERREADER_CREATE_FROM_TCPPORT "AliHLTHOMERReaderCreateFromTCPPort" +#define ALIHLTHOMERREADER_CREATE_FROM_TCPPORTS "AliHLTHOMERReaderCreateFromTCPPorts" +#define ALIHLTHOMERREADER_CREATE_FROM_BUFFER "AliHLTHOMERReaderCreateFromBuffer" +#define ALIHLTHOMERREADER_DELETE "AliHLTHOMERReaderDelete" + +#ifdef __cplusplus +extern "C" { +#endif + + typedef AliHLTHOMERReader* (*AliHLTHOMERReaderCreateFromTCPPort_t)(const char* hostname, unsigned short port ); + typedef AliHLTHOMERReader* (*AliHLTHOMERReaderCreateFromTCPPorts_t)(unsigned int tcpCnt, const char** hostnames, unsigned short* ports); + typedef AliHLTHOMERReader* (*AliHLTHOMERReaderCreateFromBuffer_t)(const void* pBuffer, int size); + typedef void (*AliHLTHOMERReaderDelete_t)(AliHLTHOMERReader* pInstance); + + /** + * Create instance of HOMER reader working on a TCP port. + */ + AliHLTHOMERReader* AliHLTHOMERReaderCreateFromTCPPort(const char* hostname, unsigned short port ); + + /** + * Create instance of HOMER reader working on multiple TCP ports. + */ + AliHLTHOMERReader* AliHLTHOMERReaderCreateFromTCPPorts(unsigned int tcpCnt, const char** hostnames, unsigned short* ports); + + /** + * Create instance of HOMER reader working on buffer. + */ + AliHLTHOMERReader* AliHLTHOMERReaderCreateFromBuffer(const void* pBuffer, int size); + + /** + * Delete instance of HOMER reader. + */ + void AliHLTHOMERReaderDelete(AliHLTHOMERReader* pInstance); +#ifdef __cplusplus +} +#endif + +#endif /* AliHLTHOMERREADER_H */ diff --git a/devices/aliceHLTwrapper/AliHLTHOMERWriter.h b/devices/aliceHLTwrapper/AliHLTHOMERWriter.h new file mode 100644 index 0000000000000..ce5129ddcc149 --- /dev/null +++ b/devices/aliceHLTwrapper/AliHLTHOMERWriter.h @@ -0,0 +1,282 @@ +// XEMacs -*-C++-*- +#ifndef ALIHLTHOMERWRITER_H +#define ALIHLTHOMERWRITER_H +/************************************************************************ +** +** +** This file is property of and copyright by the Technical Computer +** Science Group, Kirchhoff Institute for Physics, Ruprecht-Karls- +** University, Heidelberg, Germany, 2001 +** This file has been written by Timm Morten Steinbeck, +** timm@kip.uni-heidelberg.de +** +** +** See the file license.txt for details regarding usage, modification, +** distribution and warranty. +** Important: This file is provided without any warranty, including +** fitness for any particular purpose. +** +** +** Newer versions of this file's package will be made available from +** http://web.kip.uni-heidelberg.de/Hardwinf/L3/ +** or the corresponding page of the Heidelberg Alice Level 3 group. +** +*************************************************************************/ + +/* +*************************************************************************** +** +** $Author$ - Initial Version by Timm Morten Steinbeck +** +** $Id$ +** +*************************************************************************** +*/ + +/** @file AliHLTHOMERWriter.h + @author Timm Steinbeck + @date Sep 14 2007 + @brief HLT Online Monitoring Environment including ROOT - Writer + @note migrated from PubSub HLT-stable-20070905.141318 (rev 2375) + 2014-05-08 included to ALFA for HOMER support +*/ + +// see below for class documentation +// or +// refer to README to build package +// or +// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt + + +#include "AliHLTHOMERData.h" +#include + +/** + * @class AliHLTMonitoringWriter + * A pure virtual interface definition for HLT monitoring writers. + * + * @ingroup alihlt_homer + */ +class AliHLTMonitoringWriter + { + public: + AliHLTMonitoringWriter() {} + virtual ~AliHLTMonitoringWriter() {} + + virtual void Clear() = 0; + + virtual void AddBlock( const void* descriptor, const void* data ) = 0; + + virtual homer_uint32 GetTotalMemorySize( bool includeData = true ) = 0; + virtual void Copy( void* destination, homer_uint64 eventType, homer_uint64 eventNr, homer_uint64 statusFlags, homer_uint64 nodeID, bool includeData = true ) = 0; + }; + +/** + * @class AliHLTHOMERWriter + * The HOMER writer assembles several data blocks of different properties + * into one big buffer and adds meta information to describe the data's + * alignment and byte order. + */ +class AliHLTHOMERWriter : public AliHLTMonitoringWriter + { + public: + + AliHLTHOMERWriter(); + virtual ~AliHLTHOMERWriter(); + + /** + * Resets the writer and clears the block list. + */ + void Clear(); + + /** + * Add a data block to the writer. + * The HOMER header must contain all meta information including the + * size of the data. + * @param homerHeader pointer to the header describing the block + * @param data pointer to data + */ + void AddBlock( const void* homerHeader, const void* data ); + + /** + * Add a data block to the writer. + * The function has certainly been introduced to make type + * conversion easier. In fact it makes it worse. The presence of the + * function with void* argument leads to a wrong interpretation when + * passing a non const pointer to HOMERBlockDescriptor. Then the + * other function is called directly, leading to pointer mess up. + */ + void AddBlock( const HOMERBlockDescriptor* descriptor, const void* data ) + { + AddBlock( descriptor->GetHeader(), data ); + } + + /** + * Add a data block to the writer. + * Function added to avoid potential pointer mismatches + */ + void AddBlock( HOMERBlockDescriptor* descriptor, const void* data ) + { + AddBlock( descriptor->GetHeader(), data ); + } + + /** + * Get the total buffer size required to write all data into one buffer + */ + homer_uint32 GetTotalMemorySize( bool includeData = true ); + + /** + * Copy the data into a buffer. + * The buffer is supposed to be big enough, the capacity should be queried + * by calling @ref GetTotalMemorySize. + */ + void Copy( void* destination, homer_uint64 eventType, homer_uint64 eventNr, homer_uint64 statusFlags, homer_uint64 nodeID, bool includeData = true ); + + /** determine alignment of 64 bit variables */ + static homer_uint8 DetermineUInt64Alignment(); + /** determine alignment of 32 bit variables */ + static homer_uint8 DetermineUInt32Alignment(); + /** determine alignment of 16 bit variables */ + static homer_uint8 DetermineUInt16Alignment(); + /** determine alignment of 8 bit variables */ + static homer_uint8 DetermineUInt8Alignment(); + /** determine alignment of double type variables */ + static homer_uint8 DetermineDoubleAlignment(); + /** determine alignment of float type bit variables */ + static homer_uint8 DetermineFloatAlignment(); + + + /** test structure for the alignment determination of 64 bit variables */ + struct AliHLTHOMERWriterAlignment64TestStructure + { + homer_uint64 f64Fill; // ! + homer_uint64 f64Test64; // ! + homer_uint32 f32Fill; // ! + homer_uint64 f64Test32; // ! + homer_uint16 f16Fill; // ! + homer_uint64 f64Test16; // ! + homer_uint8 f8Fill; // ! + homer_uint64 f64Test8; // ! + }; + /** test structure for the alignment determination of 32 bit variables */ + struct AliHLTHOMERWriterAlignment32TestStructure + { + homer_uint64 f64Fill; // ! + homer_uint32 f32Test64; // ! + homer_uint32 f32Fill; // ! + homer_uint32 f32Test32; // ! + homer_uint16 f16Fill; // ! + homer_uint32 f32Test16; // ! + homer_uint8 f8Fill; // ! + homer_uint32 f32Test8; // ! + }; + /** test structure for the alignment determination of 16 bit variables */ + struct AliHLTHOMERWriterAlignment16TestStructure + { + homer_uint64 f64Fill; // ! + homer_uint16 f16Test64; // ! + homer_uint32 f32Fill; // ! + homer_uint16 f16Test32; // ! + homer_uint16 f16Fill; // ! + homer_uint16 f16Test16; // ! + homer_uint8 f8Fill; // ! + homer_uint16 f16Test8; // ! + }; + /** test structure for the alignment determination of 8 bit variables */ + struct AliHLTHOMERWriterAlignment8TestStructure + { + homer_uint64 f64Fill; // ! + homer_uint8 f8Test64; // ! + homer_uint32 f32Fill; // ! + homer_uint8 f8Test32; // ! + homer_uint16 f16Fill; // ! + homer_uint8 f8Test16; // ! + homer_uint8 f8Fill; // ! + homer_uint8 f8Test8; // ! + }; + /** test structure for the alignment determination of double type variables */ + struct AliHLTHOMERWriterAlignmentDoubleTestStructure + { + homer_uint64 f64Fill; // ! + double fDoubleTest64; // ! + homer_uint32 f32Fill; // ! + double fDoubleTest32; // ! + homer_uint16 f16Fill; // ! + double fDoubleTest16; // ! + homer_uint8 f8Fill; // ! + double fDoubleTest8; // ! + }; + /** test structure for the alignment determination of float type variables */ + struct AliHLTHOMERWriterAlignmentFloatTestStructure + { + homer_uint64 f64Fill; // ! + float fFloatTest64; // ! + homer_uint32 f32Fill; // ! + float fFloatTest32; // ! + homer_uint16 f16Fill; // ! + float fFloatTest16; // ! + homer_uint8 f8Fill; // ! + float fFloatTest8; // ! + }; + protected: + + /** + * Block descriptor structure. + * The descriptor contains a header for meta information and position + * and a pointer to the data. + */ + struct TBlockData + { + homer_uint64 fDescriptor[kCount_64b_Words]; //!transient + const void* fData; //!transient + }; + + unsigned long fDataOffset; //!transient + + /** list of data blocks */ + std::vector fBlocks; //!transient +#ifdef USE_ROOT + ClassDef(AliHLTHOMERWriter,0); +#endif + }; + + +/** defined for backward compatibility */ +typedef AliHLTHOMERWriter HOMERWriter; + +// external interface of the HOMER writer +#define ALIHLTHOMERWRITER_CREATE "AliHLTHOMERWriterCreate" +#define ALIHLTHOMERWRITER_DELETE "AliHLTHOMERWriterDelete" + +#ifdef __cplusplus +extern "C" { +#endif + + typedef AliHLTHOMERWriter* (*AliHLTHOMERWriterCreate_t)(); + typedef void (*AliHLTHOMERWriterDelete_t)(AliHLTHOMERWriter* pInstance); + /** + * Create instance of HOMER writer. + */ + AliHLTHOMERWriter* AliHLTHOMERWriterCreate(); + + /** + * Delete instance of HOMER writer. + */ + void AliHLTHOMERWriterDelete(AliHLTHOMERWriter* pInstance); +#ifdef __cplusplus +} +#endif + + + +/* +*************************************************************************** +** +** $Author$ - Initial Version by Timm Morten Steinbeck +** +** $Id$ +** +*************************************************************************** +*/ + +#endif // ALIHLTHOMERWRITER_H diff --git a/devices/aliceHLTwrapper/CMakeLists.txt b/devices/aliceHLTwrapper/CMakeLists.txt index ed7fda44384a0..7fde0fef22e9f 100644 --- a/devices/aliceHLTwrapper/CMakeLists.txt +++ b/devices/aliceHLTwrapper/CMakeLists.txt @@ -17,6 +17,7 @@ link_directories(${LINK_DIRECTORIES}) set(SRCS SystemInterface.cxx + HOMERFactory.cxx ) set(DEPENDENCIES diff --git a/devices/aliceHLTwrapper/HOMERFactory.cxx b/devices/aliceHLTwrapper/HOMERFactory.cxx new file mode 100644 index 0000000000000..90194721d6887 --- /dev/null +++ b/devices/aliceHLTwrapper/HOMERFactory.cxx @@ -0,0 +1,317 @@ +//**************************************************************************** +//* This file 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 3 of the License, or * +//* (at your option) any later version. * +//* * +//* Primary Authors: Matthias Richter * +//* * +//* The authors make no claims about the suitability of this software for * +//* any purpose. It is provided "as is" without express or implied warranty. * +//* * +//* See original copyright notice below * +//**************************************************************************** + +// @file HOMERFactory.cxx +// @author Matthias Richter +// @since 2014-05-07 +// @brief Original AliHLTHOMERLibManager.h of AliRoot adapted to the +// ALFA project + +/************************************************************************** + * This file is property of and copyright by the ALICE HLT Project * + * ALICE Experiment at CERN, All rights reserved. * + * * + * Primary Authors: Matthias Richter * + * 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 +#include +#include +#include +#include +#include +#include "HOMERFactory.h" +#include "AliHLTHOMERReader.h" +#include "AliHLTHOMERWriter.h" + +using namespace ALICE::HLT; + +// global flag of the library status +int HOMERFactory::fgLibraryStatus=0; +// This list must be NULL terminated, since we use it as a marker to identify +// the end of the list. +const char* HOMERFactory::fgkLibraries[] = {"libAliHLTHOMER.so", "libHOMER.so", NULL}; +// The size of the list of reference counts must be one less than fgkLibraries. +int HOMERFactory::fgkLibRefCount[] = {0, 0}; + +HOMERFactory::HOMERFactory() + : + fFctCreateReaderFromTCPPort(NULL), + fFctCreateReaderFromTCPPorts(NULL), + fFctCreateReaderFromBuffer(NULL), + fFctDeleteReader(NULL), + fFctCreateWriter(NULL), + fFctDeleteWriter(NULL), + fLoadedLib(NULL) +{ + // constructor + // + // Interface to the HLT Online Monitoring Including Root (HOMER) library. + // It allows to decouple the HLT base library from this additional library + // while providing the basic functionality to the component libraries +} + +HOMERFactory::~HOMERFactory() +{ + // destructor + // + // the library load strategy has been changed in March 2013 in order to + // stabilize the runtime memory layout of AliRoot in an attemp to get control + // over memory corruptions + // UnloadHOMERLibrary(); +} + +AliHLTHOMERReader* HOMERFactory::OpenReader(const char* hostname, unsigned short port ) +{ + // Open Reader instance for host + if (fgLibraryStatus<0) return NULL; + + fgLibraryStatus=LoadHOMERLibrary(); + if (fgLibraryStatus <= 0) { + return NULL; + } + + AliHLTHOMERReader* pReader=NULL; + if (fFctCreateReaderFromTCPPort!=NULL && (pReader=(((AliHLTHOMERReaderCreateFromTCPPort_t)fFctCreateReaderFromTCPPort)(hostname, port)))==NULL) { + cout <<"can not create instance of HOMER reader from ports" << endl; + } + + return pReader; +} + +AliHLTHOMERReader* HOMERFactory::OpenReader(unsigned int tcpCnt, const char** hostnames, unsigned short* ports) +{ + // Open Reader instance for a list of hosts + if (fgLibraryStatus<0) return NULL; + + fgLibraryStatus=LoadHOMERLibrary(); + if (fgLibraryStatus <= 0) { + return NULL; + } + + AliHLTHOMERReader* pReader=NULL; + if (fFctCreateReaderFromTCPPorts!=NULL && (pReader=(((AliHLTHOMERReaderCreateFromTCPPorts_t)fFctCreateReaderFromTCPPorts)(tcpCnt, hostnames, ports)))==NULL) { + //HLTError("can not create instance of HOMER reader (function %p)", fFctCreateReaderFromTCPPorts); + cout << "can not create instance of HOMER reader from port"<0 && *library!=NULL) { + // print compile info + typedef void (*CompileInfo)( char*& date, char*& time); + + fFctCreateReaderFromTCPPort=(void (*)())dlsym(fHandle, ALIHLTHOMERREADER_CREATE_FROM_TCPPORT); + fFctCreateReaderFromTCPPorts=(void (*)())dlsym(fHandle, ALIHLTHOMERREADER_CREATE_FROM_TCPPORTS); + fFctCreateReaderFromBuffer=(void (*)())dlsym(fHandle, ALIHLTHOMERREADER_CREATE_FROM_BUFFER); + fFctDeleteReader=(void (*)())dlsym(fHandle, ALIHLTHOMERREADER_DELETE); + fFctCreateWriter=(void (*)())dlsym(fHandle, ALIHLTHOMERWRITER_CREATE); + fFctDeleteWriter=(void (*)())dlsym(fHandle, ALIHLTHOMERWRITER_DELETE); + if (fFctCreateReaderFromTCPPort==NULL || + fFctCreateReaderFromTCPPorts==NULL || + fFctCreateReaderFromBuffer==NULL || + fFctDeleteReader==NULL || + fFctCreateWriter==NULL || + fFctDeleteWriter==NULL) { + iResult=-ENOSYS; + } else { + } + } + if (iResult<0 || *library==NULL) { + fFctCreateReaderFromTCPPort=NULL; + fFctCreateReaderFromTCPPorts=NULL; + fFctCreateReaderFromBuffer=NULL; + fFctDeleteReader=NULL; + fFctCreateWriter=NULL; + fFctDeleteWriter=NULL; + } + + return iResult; +} + +int HOMERFactory::UnloadHOMERLibrary() +{ + // unload HOMER library + int iResult=0; + + if (fLoadedLib != NULL) + { + // Find the corresponding reference count. + const char** library=&fgkLibraries[0]; + int* refcount = &fgkLibRefCount[0]; + while (*library != NULL) + { + if (strcmp(*library, fLoadedLib) == 0) break; + ++library; + ++refcount; + } + + // Decrease the reference count and remove the library if it is zero. + if (*refcount >= 0) --(*refcount); + if (*refcount == 0) + { /* Matthias 2014-05-08 that part of the code has been disabled for the ROOT-independent + version. + TODO: dlopen is maintaining an internal reference count, which also makes the + counters here obsolete + + // Check that the library we are trying to unload is actually the last library + // in the gSystem->GetLibraries() list. If not then we must abort the removal. + // This is because of a ROOT bug/feature/limitation. If we try unload the library + // then ROOT will also wipe all libraries in the gSystem->GetLibraries() list + // following the library we want to unload. + TString libstring = gSystem->GetLibraries(); + TString token, lastlib; + Ssiz_t from = 0; + Int_t numOfLibs = 0, posOfLib = -1; + while (libstring.Tokenize(token, from, " ")) + { + ++numOfLibs; + lastlib = token; + if (token.Contains(fLoadedLib)) posOfLib = numOfLibs; + } + if (numOfLibs == posOfLib) + { + gSystem->Unload(fLoadedLib); + + // Check that the library is gone, since Unload() does not return a status code. + libstring = gSystem->GetLibraries(); + if (libstring.Contains(fLoadedLib)) iResult = -EBADF; + } + else + { + AliHLTLogging log; + log.LoggingVarargs(kHLTLogWarning, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__, + Form("ROOT limitation! Cannot properly cleanup and unload the shared" + " library '%s' since another library '%s' was loaded afterwards. Trying to" + " unload this library will remove the others and lead to serious memory faults.", + fLoadedLib, lastlib.Data() + )); + } + */ + dlclose(fHandle); + } + } + + // Clear the function pointers. + fFctCreateReaderFromTCPPort = NULL; + fFctCreateReaderFromTCPPorts = NULL; + fFctCreateReaderFromBuffer = NULL; + fFctDeleteReader = NULL; + fFctCreateWriter = NULL; + fFctDeleteWriter = NULL; + + return iResult; +} diff --git a/devices/aliceHLTwrapper/HOMERFactory.h b/devices/aliceHLTwrapper/HOMERFactory.h new file mode 100644 index 0000000000000..8ae391c07320f --- /dev/null +++ b/devices/aliceHLTwrapper/HOMERFactory.h @@ -0,0 +1,182 @@ +//-*- Mode: C++ -*- + +#ifndef HOMERFACTORY_H +#define HOMERFACTORY_H +//**************************************************************************** +//* This file 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 3 of the License, or * +//* (at your option) any later version. * +//* * +//* Primary Authors: Matthias Richter * +//* * +//* The authors make no claims about the suitability of this software for * +//* any purpose. It is provided "as is" without express or implied warranty. * +//* * +//* See original copyright notice below * +//**************************************************************************** + +// @file HOMERFactory.h +// @author Matthias Richter +// @since 2014-05-07 +// @brief Original AliHLTHOMERLibManager.h of AliRoot adapted to the +// ALFA project + +/* This file is property of and copyright by the ALICE HLT Project * + * ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +#include "AliHLTDataTypes.h" +class AliHLTHOMERReader; +class AliHLTHOMERWriter; + +namespace ALICE { + namespace HLT { + +/** + * @class HOMERFactory + * Dynamic manager of HOMER library. + * The class allows to generate objects of HOMER readers and writers + * dynamically and loads also the HOMER lib. In order to write HOMER library + * independent code it is important to use the AliHLTMonitoringWriter/ + * AliHLTMonitoringReader classes when ever class methods are used. Those + * classes just define a virtual interface.
+ * + * Instead of creating a reader or writer by \em new and deleting it with + * \em delete, one has to use the Open and Delete methods of this class. + * + *
+ * HOMERFactory manager;
+ *
+ * // open a HOMER reader listening at port 23000 of the localhost
+ * AliHLTMonitoringReader* pReader=manager.OpenReader(localhost, 23000);
+ *
+ * // read next event, timeout 5s
+ * while (pReader && pReader->ReadNextEvent(5000000)==0) {
+ *   unsigned long count=pReader->GetBlockCnt();
+ *   gSystem->Sleep(5);
+ *   ...
+ * }
+ *
+ * // delete reader
+ * manager.DeleteReader(pReader);
+ * 
+ * + * The manager does not provide methods to create a HOMER reader on + * basis of shared memory. This is most likely a depricated functionality, + * although kept for the sake of completeness. However, at some point it + * might become useful. Please notify the developers if you need that + * functionality. + * + * @ingroup alihlt_homer + */ +class HOMERFactory { + public: + /** standard constructor */ + HOMERFactory(); + /** destructor */ + virtual ~HOMERFactory(); + + /** + * Open a homer reader working on a TCP port. + */ + AliHLTHOMERReader* OpenReader(const char* hostname, unsigned short port ); + + /** + * Open a homer reader working on multiple TCP ports. + */ + AliHLTHOMERReader* OpenReader(unsigned int tcpCnt, const char** hostnames, unsigned short* ports); + + /** + * Open a HOMER reader for reading from a System V shared memory segment. + AliHLTHOMERReader* OpenReader(key_t shmKey, int shmSize ); + */ + + /** + * Open a HOMER reader for reading from multiple System V shared memory segments + AliHLTHOMERReader* OpenReader(unsigned int shmCnt, key_t* shmKey, int* shmSize ); + */ + + /** + * Open a HOMER reader for reading from multiple TCP ports and multiple System V shared memory segments + AliHLTHOMERReader* OpenReader(unsigned int tcpCnt, const char** hostnames, unsigned short* ports, + unsigned int shmCnt, key_t* shmKey, int* shmSize ); + */ + + /** + * Open a HOMER reader. + * Load HOMER library dynamically and create object working on the provided + * buffer. + */ + AliHLTHOMERReader* OpenReaderBuffer(const AliHLTUInt8_t* pBuffer, int size); + + /** + * Delete a HOMER reader. + * Clean-up of the object is done inside the HOMER library. + */ + int DeleteReader(AliHLTHOMERReader* pReader); + + /** + * Open a HOMER writer. + * Load HOMER library dynamically and create object working on the provided + * buffer. + */ + AliHLTHOMERWriter* OpenWriter(); + + /** + * Delete a HOMER writer. + * Clean-up of the object is done inside the HOMER library. + */ + int DeleteWriter(AliHLTHOMERWriter* pWriter); + + protected: + + private: + /** copy constructor prohibited */ + HOMERFactory(const HOMERFactory&); + /** assignment operator prohibited */ + HOMERFactory& operator=(const HOMERFactory&); + + /** + * Load the HOMER library. + */ + int LoadHOMERLibrary(); + + /** + * Unloads the HOMER library. + */ + int UnloadHOMERLibrary(); + + /** status of the loading of the HOMER library */ +static int fgLibraryStatus; //!transient + + /** entry in the HOMER library */ + void (*fFctCreateReaderFromTCPPort)(); //!transient + + /** entry in the HOMER library */ + void (*fFctCreateReaderFromTCPPorts)(); //!transient + + /** entry in the HOMER library */ + void (*fFctCreateReaderFromBuffer)(); //!transient + + /** entry in the HOMER library */ + void (*fFctDeleteReader)(); //!transient + + /** entry in the HOMER library */ + void (*fFctCreateWriter)(); //!transient + + /** entry in the HOMER library */ + void (*fFctDeleteWriter)(); //!transient + + /** Indicates the library that was actually (and if) loaded in LoadHOMERLibrary(). */ + const char* fLoadedLib; //!transient + + /** library handle returned by dlopen */ + void* fHandle; + + static const char* fgkLibraries[]; /// List of libraries to try and load. + static int fgkLibRefCount[]; /// The library reference count to control when to unload the library. +}; +} // namespace hlt +} // namespace alice +#endif From d4515668cdf065f84a765887b7f0820a82c43135 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Thu, 8 May 2014 18:29:00 +0200 Subject: [PATCH 04/34] added first implementation of the WrapperDevice --- devices/aliceHLTwrapper/CMakeLists.txt | 7 +- devices/aliceHLTwrapper/WrapperDevice.cxx | 259 ++++++++++++++++++++++ devices/aliceHLTwrapper/WrapperDevice.h | 82 +++++++ 3 files changed, 345 insertions(+), 3 deletions(-) create mode 100644 devices/aliceHLTwrapper/WrapperDevice.cxx create mode 100644 devices/aliceHLTwrapper/WrapperDevice.h diff --git a/devices/aliceHLTwrapper/CMakeLists.txt b/devices/aliceHLTwrapper/CMakeLists.txt index 7fde0fef22e9f..59e94331d30e3 100644 --- a/devices/aliceHLTwrapper/CMakeLists.txt +++ b/devices/aliceHLTwrapper/CMakeLists.txt @@ -1,6 +1,6 @@ set(INCLUDE_DIRECTORIES - # ${CMAKE_SOURCE_DIR}/fairmq - # ${CMAKE_SOURCE_DIR}/fairmq/zeromq + ${CMAKE_SOURCE_DIR}/fairmq + ${CMAKE_SOURCE_DIR}/fairmq/zeromq # ${Boost_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/devices/aliceHLTwrapper ) @@ -18,6 +18,7 @@ link_directories(${LINK_DIRECTORIES}) set(SRCS SystemInterface.cxx HOMERFactory.cxx + WrapperDevice.cxx ) set(DEPENDENCIES @@ -28,7 +29,7 @@ set(DEPENDENCIES set(DEPENDENCIES ${DEPENDENCIES} # ${CMAKE_THREAD_LIBS_INIT} - # FairMQ + FairMQ ) set(LIBRARY_NAME ALICEHLT) diff --git a/devices/aliceHLTwrapper/WrapperDevice.cxx b/devices/aliceHLTwrapper/WrapperDevice.cxx new file mode 100644 index 0000000000000..4fedb3208a005 --- /dev/null +++ b/devices/aliceHLTwrapper/WrapperDevice.cxx @@ -0,0 +1,259 @@ +//**************************************************************************** +//* This file 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 3 of the License, or * +//* (at your option) any later version. * +//* * +//* Primary Authors: Matthias Richter * +//* * +//* The authors make no claims about the suitability of this software for * +//* any purpose. It is provided "as is" without express or implied warranty. * +//**************************************************************************** + +// @file WrapperDevice.cxx +// @author Matthias Richter +// @since 2014-05-07 +// @brief FairRoot/ALFA device running ALICE HLT code + +#include "WrapperDevice.h" +#include "AliHLTDataTypes.h" +#include "SystemInterface.h" +#include "HOMERFactory.h" +#include "FairMQLogger.h" +#include "FairMQPoller.h" + +#include +#include +#include +#include +#include +#include +#include +using namespace ALICE::HLT; + +WrapperDevice::WrapperDevice(const char* library, const char* id, const char* parameter, unsigned runNumber) + : mComponentLibrary(library) + , mComponentId(id) + , mComponentParameter(parameter) + , mRunNumber(runNumber) + , mOutputBuffer() + , mOutputBlocks() + , mpSystem(NULL) + , mpFactory(NULL) + , mpReader(NULL) + , mpWriter(NULL) + , mProcessor(kEmptyHLTComponentHandle) +{ +} + +WrapperDevice::~WrapperDevice() +{ +} + +void WrapperDevice::Init() +{ + /// inherited from FairMQDevice + + int iResult=0; + // TODO: make the SystemInterface a singleton + auto_ptr iface(new SystemInterface); + if (iface.get()==NULL || ((iResult=iface->InitSystem(mRunNumber)))<0) { + LOG(ERROR) << "failed to set up SystemInterface " << iface.get() << " (" << iResult << ")"; + return; + } + auto_ptr homerfact(new HOMERFactory); + if (!homerfact.get()) { + LOG(ERROR) << "failed to set up HOMERFactory " << homerfact.get(); + return; + } + + // basic initialization succeeded, make the instances persistent + mpSystem=iface.release(); + mpFactory=homerfact.release(); + + // load the component library + if ((iResult=mpSystem->LoadLibrary(mComponentLibrary.c_str()))<0) + return; + + // chop the parameter string in order to provide parameters in the argc/argv format + vector parameters; + auto_ptr parameterBuffer(new char[mComponentParameter.length()+1]); + if (mComponentParameter.length()>0 && parameterBuffer.get()!=NULL) { + strcpy(parameterBuffer.get(), mComponentParameter.c_str()); + char* iterator=parameterBuffer.get(); + parameters.push_back(iterator); + for (; *iterator!=0; iterator++) { + if (*iterator!=' ') continue; + *iterator=0; // separate strings + if (*(iterator+1)!=' ' && *(iterator+1)!=0) + parameters.push_back(iterator+1); + } + } + + // create component + if ((iResult=mpSystem->CreateComponent(mComponentId.c_str(), NULL, parameters.size(), ¶meters[0], &mProcessor, ""))<0) + return; + +} + +void WrapperDevice::Run() +{ + /// inherited from FairMQDevice + if (!mpSystem) return; + int iResult=0; + + // TODO: make the initial size configurable + unsigned outputBufferSize=10000; + mOutputBuffer.reserve(outputBufferSize); + + AliHLTComponentEventData evtData; + memset(&evtData, 0, sizeof(evtData)); + evtData.fStructSize=sizeof(evtData); + + AliHLTComponentTriggerData trigData; + memset(&trigData, 0, sizeof(trigData)); + trigData.fStructSize=sizeof(trigData); + + AliHLTUInt32_t outputBlockCnt=0; + AliHLTComponentBlockData* pOutputBlocks=NULL; + AliHLTComponentEventDoneData* pEventDoneData=NULL; + + boost::thread rateLogger(boost::bind(&FairMQDevice::LogSocketRates, this)); + + FairMQPoller* poller = fTransportFactory->CreatePoller(*fPayloadInputs); + + bool received = false; + + // inherited variables of FairMQDevice: + // fNumInputs + // fTransportFactory + // fPayloadInputs + // fPayloadOutputs + int NoOfMsgParts=fNumInputs-1; + + vector inputMessages(fNumInputs); + while ( fState == RUNNING ) { + + // read input messages + poller->Poll(100); + for(int i = 0; i < fNumInputs; i++) { + received = false; + if (poller->CheckInput(i)){ + auto_ptr msg(fTransportFactory->CreateMessage()); + received = fPayloadInputs->at(i)->Receive(msg.get()); + if (received) { + inputMessages.push_back(msg.release()); + LOG(INFO) << "------ recieve Msg from " << i ; + } + } + } + + // call HLT component + + // prepare input from messages + vector inputBlocks; + + // process + evtData.fBlockCnt=inputBlocks.size(); + int nofTrials=2; + do { + outputBufferSize=mOutputBuffer.capacity(); + outputBlockCnt=0; + // TODO: check if that is working with the corresponding allocation method of the + // component environment + if (pOutputBlocks) delete [] pOutputBlocks; + pOutputBlocks=NULL; + if (pEventDoneData) delete pEventDoneData; + pEventDoneData=NULL; + + iResult=mpSystem->ProcessEvent(mProcessor, &evtData, &inputBlocks[0], &trigData, + &mOutputBuffer[0], &outputBufferSize, + &outputBlockCnt, &pOutputBlocks, + &pEventDoneData); + + if (iResult==-ENOSPC) { + if (mOutputBuffer.capacity()0); + + // build the message from the output block + auto_ptr msg(fTransportFactory->CreateMessage()); + if (msg.get()) { + AliHLTComponentBlockData* pOutputBlock=pOutputBlocks; + for (unsigned blockIndex=0; blockIndexfSize; + msg->Rebuild(msgSize); + if (msg->GetSize()(msg->GetData()); + memcpy(pTarget, pOutputBlock, sizeof(AliHLTComponentBlockData)); + pTarget+=sizeof(AliHLTComponentBlockData); + memcpy(pTarget, &mOutputBuffer[pOutputBlock->fOffset], pOutputBlock->fSize); + if (blockIndex+1at(0)->Send(msg.get()/*, ZMQ_SNDMORE*/); + } else { + fPayloadOutputs->at(0)->Send(msg.get()); + } + } + } + + // cleanup + inputBlocks.clear(); + for (vector::iterator mit=inputMessages.begin(); + mit!=inputMessages.end(); mit++) + delete *mit; + inputMessages.clear(); + mOutputBuffer.clear(); + outputBlockCnt=0; + if (pOutputBlocks) delete [] pOutputBlocks; + pOutputBlocks=NULL; + if (pEventDoneData) delete pEventDoneData; + pEventDoneData=NULL; + } + + delete poller; + + rateLogger.interrupt(); + rateLogger.join(); +} + +void WrapperDevice::Pause() +{ + /// inherited from FairMQDevice + + // nothing to do +} + +void WrapperDevice::Shutdown() +{ + /// inherited from FairMQDevice + + int iResult=0; + if (!mpSystem) return; + + iResult=mpSystem->DestroyComponent(mProcessor); + iResult=mpSystem->ReleaseSystem(); + +} + +void WrapperDevice::InitOutput() +{ + /// inherited from FairMQDevice + +} + +void WrapperDevice::InitInput() +{ + /// inherited from FairMQDevice + +} + diff --git a/devices/aliceHLTwrapper/WrapperDevice.h b/devices/aliceHLTwrapper/WrapperDevice.h new file mode 100644 index 0000000000000..5abb52d9494ab --- /dev/null +++ b/devices/aliceHLTwrapper/WrapperDevice.h @@ -0,0 +1,82 @@ +//-*- Mode: C++ -*- + +#ifndef WRAPPERDEVICE_H +#define WRAPPERDEVICE_H +//**************************************************************************** +//* This file 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 3 of the License, or * +//* (at your option) any later version. * +//* * +//* Primary Authors: Matthias Richter * +//* * +//* The authors make no claims about the suitability of this software for * +//* any purpose. It is provided "as is" without express or implied warranty. * +//**************************************************************************** + +// @file WrapperDevice.h +// @author Matthias Richter +// @since 2014-05-08 +// @brief FairRoot/ALFA device running ALICE HLT code + +#include "AliHLTDataTypes.h" +#include "FairMQDevice.h" +#include + +class AliHLTHOMERReader; +class AliHLTHOMERWriter; + +namespace ALICE +{ + namespace HLT + { + class HOMERFactory; + class SystemInterface; + + class WrapperDevice : public FairMQDevice { + public: + /// default constructor + WrapperDevice(const char* library="", const char* id="", const char* parameter="", unsigned runNumber=0); + /// destructor + ~WrapperDevice(); + + ///////////////////////////////////////////////////////////////// + // the FairMQDevice interface + + /// inherited from FairMQDevice + virtual void Init(); + /// inherited from FairMQDevice + virtual void Run(); + /// inherited from FairMQDevice + virtual void Pause(); + /// inherited from FairMQDevice + virtual void Shutdown(); + /// inherited from FairMQDevice + virtual void InitOutput(); + /// inherited from FairMQDevice + virtual void InitInput(); + protected: + + private: + // copy constructor prohibited + WrapperDevice(const WrapperDevice&); + // assignment operator prohibited + WrapperDevice& operator=(const WrapperDevice&); + + string mComponentLibrary; + string mComponentId; + string mComponentParameter; + unsigned mRunNumber; + vector mOutputBuffer; + vector mOutputBlocks; + + SystemInterface* mpSystem; + HOMERFactory* mpFactory; + AliHLTHOMERReader* mpReader; + AliHLTHOMERWriter* mpWriter; + AliHLTComponentHandle mProcessor; + }; + + } // namespace hlt +} // namespace alice +#endif // WRAPPERDEVICE_H From d3cd7dab1caa001ffa6e45867772a53e9238228f Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Fri, 9 May 2014 19:45:15 +0200 Subject: [PATCH 05/34] added the event type data block to the component input, implemented two output message modes: multi-part and single message in HOMER format --- devices/aliceHLTwrapper/WrapperDevice.cxx | 146 +++++++++++++++++----- devices/aliceHLTwrapper/WrapperDevice.h | 13 ++ 2 files changed, 127 insertions(+), 32 deletions(-) diff --git a/devices/aliceHLTwrapper/WrapperDevice.cxx b/devices/aliceHLTwrapper/WrapperDevice.cxx index 4fedb3208a005..efd194152a08d 100644 --- a/devices/aliceHLTwrapper/WrapperDevice.cxx +++ b/devices/aliceHLTwrapper/WrapperDevice.cxx @@ -19,6 +19,9 @@ #include "AliHLTDataTypes.h" #include "SystemInterface.h" #include "HOMERFactory.h" +#include "AliHLTHOMERData.h" +#include "AliHLTHOMERWriter.h" +#include "AliHLTHOMERReader.h" #include "FairMQLogger.h" #include "FairMQPoller.h" @@ -93,6 +96,8 @@ void WrapperDevice::Init() // create component if ((iResult=mpSystem->CreateComponent(mComponentId.c_str(), NULL, parameters.size(), ¶meters[0], &mProcessor, ""))<0) return; + + FairMQDevice::Init(); } @@ -152,11 +157,35 @@ void WrapperDevice::Run() // prepare input from messages vector inputBlocks; + // ... + // create blocks from messages + // ... + unsigned nofInputBlocks=inputBlocks.size(); + + // add event type data block + AliHLTComponentBlockData eventTypeBlock; + memset(&eventTypeBlock, 0, sizeof(eventTypeBlock)); + eventTypeBlock.fStructSize=sizeof(eventTypeBlock); + // Note: no payload! + eventTypeBlock.fDataType=AliHLTComponentDataTypeInitializer("EVENTTYP", "PRIV"); + eventTypeBlock.fSpecification=gkAliEventTypeData; + inputBlocks.push_back(eventTypeBlock); // process evtData.fBlockCnt=inputBlocks.size(); int nofTrials=2; do { + unsigned long constEventBase=0; + unsigned long constBlockBase=0; + double inputBlockMultiplier=0.; + mpSystem->GetOutputSize(mProcessor, &constEventBase, &constBlockBase, &inputBlockMultiplier); + outputBufferSize=constEventBase+nofInputBlocks*constBlockBase; + if (mOutputBuffer.capacity()0); + } while (iResult==ENOSPC && --nofTrials>0); // build the message from the output block - auto_ptr msg(fTransportFactory->CreateMessage()); - if (msg.get()) { - AliHLTComponentBlockData* pOutputBlock=pOutputBlocks; - for (unsigned blockIndex=0; blockIndexfSize; - msg->Rebuild(msgSize); - if (msg->GetSize()(msg->GetData()); - memcpy(pTarget, pOutputBlock, sizeof(AliHLTComponentBlockData)); - pTarget+=sizeof(AliHLTComponentBlockData); - memcpy(pTarget, &mOutputBuffer[pOutputBlock->fOffset], pOutputBlock->fSize); - if (blockIndex+1at(0)->Send(msg.get()/*, ZMQ_SNDMORE*/); - } else { - fPayloadOutputs->at(0)->Send(msg.get()); - } - } - } + SendMultiMessages(pOutputBlocks, outputBlockCnt); // cleanup inputBlocks.clear(); @@ -226,6 +225,89 @@ void WrapperDevice::Run() rateLogger.join(); } +int WrapperDevice::SendMultiMessages(AliHLTComponentBlockData* pOutputBlocks, AliHLTUInt32_t outputBlockCnt) +{ + // send data blocks in a group of messages + int iResult=0; + auto_ptr msg(fTransportFactory->CreateMessage()); + if (msg.get()) { + AliHLTComponentBlockData* pOutputBlock=pOutputBlocks; + for (unsigned blockIndex=0; blockIndexfSize; + msg->Rebuild(msgSize); + if (msg->GetSize()(msg->GetData()); + memcpy(pTarget, pOutputBlock, sizeof(AliHLTComponentBlockData)); + pTarget+=sizeof(AliHLTComponentBlockData); + memcpy(pTarget, &mOutputBuffer[pOutputBlock->fOffset], pOutputBlock->fSize); + if (blockIndex+1at(0)->Send(msg.get()/*, ZMQ_SNDMORE*/); + } else { + fPayloadOutputs->at(0)->Send(msg.get()); + } + } + } + return iResult; +} + +int WrapperDevice::SendHOMERMessage(AliHLTComponentBlockData* pOutputBlocks, AliHLTUInt32_t outputBlockCnt) +{ + // send data blocks in HOMER format in one message + int iResult=0; + if (!mpFactory) return -ENODEV; + auto_ptr writer(mpFactory->OpenWriter()); + if (writer.get()==NULL) return -ENOSYS; + + homer_uint64 homerHeader[kCount_64b_Words]; + HOMERBlockDescriptor homerDescriptor(homerHeader); + + AliHLTComponentBlockData* pOutputBlock=pOutputBlocks; + for (unsigned blockIndex=0; blockIndexfDataType.fID, sizeof(homer_uint64)); + memcpy(((AliHLTUInt8_t*)&origin)+sizeof(homer_uint32), pOutputBlock->fDataType.fOrigin, sizeof(homer_uint32)); + homerDescriptor.SetType((id)); + homerDescriptor.SetSubType1((origin)); + homerDescriptor.SetSubType2(pOutputBlock->fSpecification); + homerDescriptor.SetBlockSize(pOutputBlock->fSize); + writer->AddBlock(homerHeader, &mOutputBuffer[pOutputBlock->fOffset]); + } + + auto_ptr msg(fTransportFactory->CreateMessage()); + if (msg.get()) { + int msgSize=writer->GetTotalMemorySize(); + msg->Rebuild(msgSize); + if (msg->GetSize()(msg->GetData()); + writer->Copy(pTarget, 0, 0, 0, 0); + fPayloadOutputs->at(0)->Send(msg.get()); + } + } + return iResult; +} + +int WrapperDevice::ReadSingleBlock(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks) +{ + // read a single block from message payload consisting of AliHLTComponentBlockData followed by + // the block data + return 0; +} + +int WrapperDevice::ReadHOMERMessage(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks) +{ + // read message payload in HOMER format + return 0; +} + void WrapperDevice::Pause() { /// inherited from FairMQDevice diff --git a/devices/aliceHLTwrapper/WrapperDevice.h b/devices/aliceHLTwrapper/WrapperDevice.h index 5abb52d9494ab..68bd3a4ee1dee 100644 --- a/devices/aliceHLTwrapper/WrapperDevice.h +++ b/devices/aliceHLTwrapper/WrapperDevice.h @@ -63,6 +63,19 @@ namespace ALICE // assignment operator prohibited WrapperDevice& operator=(const WrapperDevice&); + // send data blocks in a group of messages + int SendMultiMessages(AliHLTComponentBlockData* pOutputBlocks, AliHLTUInt32_t outputBlockCnt); + + // send data blocks in HOMER format in one message + int SendHOMERMessage(AliHLTComponentBlockData* pOutputBlocks, AliHLTUInt32_t outputBlockCnt); + + // read a single block from message payload consisting of AliHLTComponentBlockData followed by + // the block data + int ReadSingleBlock(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks); + + // read message payload in HOMER format + int ReadHOMERMessage(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks); + string mComponentLibrary; string mComponentId; string mComponentParameter; From 487bd1f6a5c14bb5d039bc48094cca2cfa2ea57e Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Fri, 9 May 2014 19:46:39 +0200 Subject: [PATCH 06/34] adding mockup for using the FairMQDevice state machine --- devices/aliceHLTwrapper/aliceHLTWrapper.cxx | 54 ++++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx index a92a4c1a93533..be537126dd7ab 100644 --- a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx +++ b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx @@ -16,14 +16,21 @@ // @brief FairRoot/ALFA device running ALICE HLT code #include "SystemInterface.h" +#include "WrapperDevice.h" #include #include #include #include #include +#ifdef NANOMSG + #include "FairMQTransportFactoryNN.h" +#else + #include "FairMQTransportFactoryZMQ.h" +#endif using std::cout; using std::cerr; +using std::stringstream; int main(int argc, char** argv) { @@ -40,12 +47,21 @@ int main(int argc, char** argv) /* getopt_long stores the option index here. */ char c=0; int iOption = 0; + + // HLT components are implemented in shared libraries, the library name + // and component id are used to factorize a component + // optionally, a list of configuration parameters can be specified as + // one single string which is translated in an array of string in the + // argc/argv format const char* componentLibrary=""; const char* componentId=""; - const char* componentParameter=""; + const char* componentParameter=""; + + // the configuration and calibration is fixed for every run and identified + // by the run no int runNumber=0; - while ((c=getopt_long(argc, argv, "l:c:p:", programOptions, &iOption)) != -1) { + while ((c=getopt_long(argc, argv, "l:c:p:r:", programOptions, &iOption)) != -1) { switch (c) { case 'l': componentLibrary=optarg; @@ -56,6 +72,8 @@ int main(int argc, char** argv) case 'p': componentParameter=optarg; break; + case 'r': + stringstream(optarg) >> runNumber; case '?': // TODO: more error handling break; @@ -66,6 +84,38 @@ int main(int argc, char** argv) cout << "Library: " << componentLibrary << " - " << componentId << " (" << componentParameter << ")" << endl; + ALICE::HLT::WrapperDevice device(componentLibrary, componentId, componentParameter, runNumber); + +#ifdef NANOMSG + FairMQTransportFactory* transportFactory = new FairMQTransportFactoryNN(); +#else + FairMQTransportFactory* transportFactory = new FairMQTransportFactoryZMQ(); +#endif + + device.SetTransport(transportFactory); + device.SetProperty(FairMQDevice::Id, "ID"); + device.SetProperty(FairMQDevice::NumIoThreads, 1); + device.SetProperty(FairMQDevice::NumInputs, 0); + device.SetProperty(FairMQDevice::NumOutputs, 1); + device.ChangeState(FairMQDevice::INIT); + device.SetProperty(FairMQDevice::OutputSocketType, "push"); + device.SetProperty(FairMQDevice::OutputSndBufSize, 10000, 0); + device.SetProperty(FairMQDevice::OutputMethod, "connect", 0); + device.SetProperty(FairMQDevice::OutputAddress, "tcp://localhost:5565", 0); + + device.ChangeState(FairMQDevice::SETOUTPUT); + device.ChangeState(FairMQDevice::SETINPUT); + device.ChangeState(FairMQDevice::RUN); + + char ch; + cin.get(ch); + + device.ChangeState(FairMQDevice::STOP); + device.ChangeState(FairMQDevice::END); + + return iResult; + + /* !!!! preliminary code below is disabled !!!*/ AliHLTComponentHandle componentHandle=kEmptyHLTComponentHandle; // chop the parameter string in order to provide parameters in the argc/argv format From f66650665a9b29112cfe3d8a90df9e5d46478af5 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Fri, 9 May 2014 23:15:42 +0200 Subject: [PATCH 07/34] bugfix: one function definition and actual implementation of the ALICE HLT external interface has been inconsistent over the years, needs to be propagated back to AliRoot --- devices/aliceHLTwrapper/AliHLTDataTypes.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/devices/aliceHLTwrapper/AliHLTDataTypes.h b/devices/aliceHLTwrapper/AliHLTDataTypes.h index 91cad257621dd..d36e3cae6a41b 100644 --- a/devices/aliceHLTwrapper/AliHLTDataTypes.h +++ b/devices/aliceHLTwrapper/AliHLTDataTypes.h @@ -70,8 +70,13 @@ * 16 Adding data type for the meta data block to be forwarded by the * TCPDumpSubscriber for the Common Data Header (CDH) and readout * list information. + * 17 bugfix: definition of function AliHLTExtFctGetOutputSize did not + * match the implementation in AliHLTExternalInterface; the bug was + * introduced when extending the function call by one parameter and + * has never been observed in the ALICE HLT because the PubSub + * framework uses its own definition of function types */ -#define ALIHLT_DATA_TYPES_VERSION 16 +#define ALIHLT_DATA_TYPES_VERSION 17 ////////////////////////////////////////////////////////////////////////// // @@ -1424,7 +1429,7 @@ extern "C" { typedef int (*AliHLTExtFctGetOutputDataType)( AliHLTComponentHandle, AliHLTComponentDataType* ); /** @ingroup alihlt_wrapper_interface */ - typedef int (*AliHLTExtFctGetOutputSize)( AliHLTComponentHandle, unsigned long*, double* ); + typedef int (*AliHLTExtFctGetOutputSize)( AliHLTComponentHandle, unsigned long*, unsigned long*, double* ); } From 463d86aaffd59c349be8e116ffb5d9acc285d509 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Fri, 9 May 2014 23:17:23 +0200 Subject: [PATCH 08/34] applying the bugfix in AliHLTDataTypes.h to the system interface --- devices/aliceHLTwrapper/SystemInterface.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/devices/aliceHLTwrapper/SystemInterface.cxx b/devices/aliceHLTwrapper/SystemInterface.cxx index 2619d9bdb147d..8ac8c1a37fa8a 100644 --- a/devices/aliceHLTwrapper/SystemInterface.cxx +++ b/devices/aliceHLTwrapper/SystemInterface.cxx @@ -198,10 +198,10 @@ int SystemInterface::GetOutputDataType(AliHLTComponentHandle handle, AliHLTCompo } int SystemInterface::GetOutputSize(AliHLTComponentHandle handle, unsigned long* constEventBase, - unsigned long* /*constBlockBase*/, double* inputBlockMultiplier) + unsigned long* constBlockBase, double* inputBlockMultiplier) { if (!mpAliHLTExtFctGetOutputSize) return -ENOSYS; - return (*mpAliHLTExtFctGetOutputSize)(handle, constEventBase, inputBlockMultiplier); + return (*mpAliHLTExtFctGetOutputSize)(handle, constEventBase, constEventBase, inputBlockMultiplier); } void SystemInterface::Clear(const char* /*option*/) From da474d285756f8f713e6b3e29976c6e92aa48563 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Fri, 9 May 2014 23:44:28 +0200 Subject: [PATCH 09/34] moving all HLT component related code to a dedicated class in order to separate FairMQ and ALICE HLT functionality; adding standalone test program intended to evolve into unit test --- devices/aliceHLTwrapper/Component.cxx | 290 +++++++++++++++++++++++ devices/aliceHLTwrapper/Component.h | 79 ++++++ devices/aliceHLTwrapper/runComponent.cxx | 50 ++++ 3 files changed, 419 insertions(+) create mode 100644 devices/aliceHLTwrapper/Component.cxx create mode 100644 devices/aliceHLTwrapper/Component.h create mode 100644 devices/aliceHLTwrapper/runComponent.cxx diff --git a/devices/aliceHLTwrapper/Component.cxx b/devices/aliceHLTwrapper/Component.cxx new file mode 100644 index 0000000000000..201f5379808bc --- /dev/null +++ b/devices/aliceHLTwrapper/Component.cxx @@ -0,0 +1,290 @@ +//**************************************************************************** +//* This file 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 3 of the License, or * +//* (at your option) any later version. * +//* * +//* Primary Authors: Matthias Richter * +//* * +//* The authors make no claims about the suitability of this software for * +//* any purpose. It is provided "as is" without express or implied warranty. * +//**************************************************************************** + +// @file Component.cxx +// @author Matthias Richter +// @since 2014-05-07 +// @brief A component running ALICE HLT code + +#include "Component.h" +#include "AliHLTDataTypes.h" +#include "SystemInterface.h" +#include "HOMERFactory.h" +#include "AliHLTHOMERData.h" +#include "AliHLTHOMERWriter.h" +#include "AliHLTHOMERReader.h" + +#include +#include +#include +#include +#include +#include +#include +using namespace ALICE::HLT; + +Component::Component() + : mOutputBuffer() + , mpSystem(NULL) + , mpFactory(NULL) + , mpWriter(NULL) + , mProcessor(kEmptyHLTComponentHandle) +{ +} + +Component::~Component() +{ +} + +int Component::Init(int argc, char** argv) +{ + /// initialize: scan arguments, setup system interface and create component + + // parse options + static struct option programOptions[] = { + {"library", required_argument, 0, 'l'}, + {"component", required_argument, 0, 'c'}, + {"parameter", optional_argument, 0, 'p'}, + {"run", required_argument, 0, 'r'}, + {"msgsize", optional_argument, 0, 's'}, + {0, 0, 0, 0} + }; + + /* getopt_long stores the option index here. */ + char c=0; + int iOption = 0; + + // HLT components are implemented in shared libraries, the library name + // and component id are used to factorize a component + // optionally, a list of configuration parameters can be specified as + // one single string which is translated in an array of string in the + // argc/argv format + const char* componentLibrary=""; + const char* componentId=""; + const char* componentParameter=""; + + // the configuration and calibration is fixed for every run and identified + // by the run no + int runNumber=0; + + while ((c=getopt_long(argc, argv, "l:c:p:r:s:", programOptions, &iOption)) != -1) { + switch (c) { + case 'l': + componentLibrary=optarg; + break; + case 'c': + componentId=optarg; + break; + case 'p': + componentParameter=optarg; + break; + case 'r': + std::stringstream(optarg) >> runNumber; + break; + case 's': + { + unsigned size=0; + std::stringstream(optarg) >> size; + if (mOutputBuffer.capacity() iface(new SystemInterface); + if (iface.get()==NULL || ((iResult=iface->InitSystem(runNumber)))<0) { + //LOG(ERROR) << "failed to set up SystemInterface " << iface.get() << " (" << iResult << ")"; + return -ENOSYS; + } + auto_ptr homerfact(new HOMERFactory); + if (!homerfact.get()) { + //LOG(ERROR) << "failed to set up HOMERFactory " << homerfact.get(); + return -ENOSYS; + } + + // basic initialization succeeded, make the instances persistent + mpSystem=iface.release(); + mpFactory=homerfact.release(); + + // load the component library + if ((iResult=mpSystem->LoadLibrary(componentLibrary))!=0) + return iResult>0?-iResult:iResult; + + // chop the parameter string in order to provide parameters in the argc/argv format + vector parameters; + unsigned parameterLength=strlen(componentParameter); + auto_ptr parameterBuffer(new char[parameterLength+1]); + if (parameterLength>0 && parameterBuffer.get()!=NULL) { + strcpy(parameterBuffer.get(), componentParameter); + char* iterator=parameterBuffer.get(); + parameters.push_back(iterator); + for (; *iterator!=0; iterator++) { + if (*iterator!=' ') continue; + *iterator=0; // separate strings + if (*(iterator+1)!=' ' && *(iterator+1)!=0) + parameters.push_back(iterator+1); + } + } + + // create component + if ((iResult=mpSystem->CreateComponent(componentId, NULL, parameters.size(), ¶meters[0], &mProcessor, ""))<0) + return iResult>0?-iResult:iResult; + + return iResult; +} + +int Component::Process(vector& dataArray) +{ + if (!mpSystem) return -ENOSYS; + int iResult=0; + + // TODO: make the initial size configurable + unsigned outputBufferSize=10000; + mOutputBuffer.reserve(outputBufferSize); + + AliHLTComponentEventData evtData; + memset(&evtData, 0, sizeof(evtData)); + evtData.fStructSize=sizeof(evtData); + + AliHLTComponentTriggerData trigData; + memset(&trigData, 0, sizeof(trigData)); + trigData.fStructSize=sizeof(trigData); + + AliHLTUInt32_t outputBlockCnt=0; + AliHLTComponentBlockData* pOutputBlocks=NULL; + AliHLTComponentEventDoneData* pEventDoneData=NULL; + + + // prepare input structure for the ALICE HLT component + vector inputBlocks; + for (vector::iterator data=dataArray.begin(); + data!=dataArray.end(); data++) { + if (ReadSingleBlock(data->p, data->size, inputBlocks)<0) { + // not in the format of a single block, check if its a HOMER block + if (ReadHOMERFormat(data->p, data->size, inputBlocks)<0) { + // not in HOMER format either, ignore the input + // TODO: decide if that should be an error + } + } + } + unsigned nofInputBlocks=inputBlocks.size(); + + // add event type data block + AliHLTComponentBlockData eventTypeBlock; + memset(&eventTypeBlock, 0, sizeof(eventTypeBlock)); + eventTypeBlock.fStructSize=sizeof(eventTypeBlock); + // Note: no payload! + eventTypeBlock.fDataType=AliHLTComponentDataTypeInitializer("EVENTTYP", "PRIV"); + eventTypeBlock.fSpecification=gkAliEventTypeData; + inputBlocks.push_back(eventTypeBlock); + + // process + evtData.fBlockCnt=inputBlocks.size(); + int nofTrials=2; + do { + unsigned long constEventBase=0; + unsigned long constBlockBase=0; + double inputBlockMultiplier=0.; + mpSystem->GetOutputSize(mProcessor, &constEventBase, &constBlockBase, &inputBlockMultiplier); + outputBufferSize=constEventBase+nofInputBlocks*constBlockBase; + if (mOutputBuffer.capacity()ProcessEvent(mProcessor, &evtData, &inputBlocks[0], &trigData, + &mOutputBuffer[0], &outputBufferSize, + &outputBlockCnt, &pOutputBlocks, + &pEventDoneData); + + } while (iResult==ENOSPC && --nofTrials>0); + + // build the message from the output block + + // cleanup + // NOTE: don't cleanup mOutputBuffer as the data is going to be used outside the class + // until released. + inputBlocks.clear(); + outputBlockCnt=0; + if (pOutputBlocks) delete [] pOutputBlocks; + pOutputBlocks=NULL; + if (pEventDoneData) delete pEventDoneData; + pEventDoneData=NULL; + + return -iResult; +} + +AliHLTHOMERWriter* Component::CreateHOMERFormat(AliHLTComponentBlockData* pOutputBlocks, AliHLTUInt32_t outputBlockCnt) +{ + // send data blocks in HOMER format in one message + int iResult=0; + if (!mpFactory) return NULL; + auto_ptr writer(mpFactory->OpenWriter()); + if (writer.get()==NULL) return NULL; + + homer_uint64 homerHeader[kCount_64b_Words]; + HOMERBlockDescriptor homerDescriptor(homerHeader); + + AliHLTComponentBlockData* pOutputBlock=pOutputBlocks; + for (unsigned blockIndex=0; blockIndexfDataType.fID, sizeof(homer_uint64)); + memcpy(((AliHLTUInt8_t*)&origin)+sizeof(homer_uint32), pOutputBlock->fDataType.fOrigin, sizeof(homer_uint32)); + homerDescriptor.SetType((id)); + homerDescriptor.SetSubType1((origin)); + homerDescriptor.SetSubType2(pOutputBlock->fSpecification); + homerDescriptor.SetBlockSize(pOutputBlock->fSize); + writer->AddBlock(homerHeader, &mOutputBuffer[pOutputBlock->fOffset]); + } + return writer.release(); +} + +int Component::ReadSingleBlock(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks) +{ + // read a single block from message payload consisting of AliHLTComponentBlockData followed by + // the block data + return 0; +} + +int Component::ReadHOMERFormat(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks) +{ + // read message payload in HOMER format + return 0; +} diff --git a/devices/aliceHLTwrapper/Component.h b/devices/aliceHLTwrapper/Component.h new file mode 100644 index 0000000000000..6278a74778ac7 --- /dev/null +++ b/devices/aliceHLTwrapper/Component.h @@ -0,0 +1,79 @@ +//-*- Mode: C++ -*- + +#ifndef COMPONENT_H +#define COMPONENT_H +//**************************************************************************** +//* This file 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 3 of the License, or * +//* (at your option) any later version. * +//* * +//* Primary Authors: Matthias Richter * +//* * +//* The authors make no claims about the suitability of this software for * +//* any purpose. It is provided "as is" without express or implied warranty. * +//**************************************************************************** + +// @file Component.h +// @author Matthias Richter +// @since 2014-05-08 +// @brief A component running ALICE HLT code + +#include "AliHLTDataTypes.h" +#include + +class AliHLTHOMERReader; +class AliHLTHOMERWriter; + +namespace ALICE +{ + namespace HLT + { + class HOMERFactory; + class SystemInterface; + + class Component { + public: + /// default constructor + Component(); + /// destructor + ~Component(); + + int Init(int argc, char** argv); + + struct BufferDesc_t { + unsigned char* p; + unsigned size; + }; + + int Process(vector& dataArray); + + protected: + + private: + // copy constructor prohibited + Component(const Component&); + // assignment operator prohibited + Component& operator=(const Component&); + + // read a single block from message payload consisting of AliHLTComponentBlockData followed by + // the block data + int ReadSingleBlock(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks); + + // read message payload in HOMER format + int ReadHOMERFormat(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks); + + // create HOMER format from the output blocks + AliHLTHOMERWriter* CreateHOMERFormat(AliHLTComponentBlockData* pOutputBlocks, AliHLTUInt32_t outputBlockCnt); + + vector mOutputBuffer; + + SystemInterface* mpSystem; + HOMERFactory* mpFactory; + AliHLTHOMERWriter* mpWriter; + AliHLTComponentHandle mProcessor; + }; + + } // namespace hlt +} // namespace alice +#endif // COMPONENT_H diff --git a/devices/aliceHLTwrapper/runComponent.cxx b/devices/aliceHLTwrapper/runComponent.cxx new file mode 100644 index 0000000000000..220d91e812a27 --- /dev/null +++ b/devices/aliceHLTwrapper/runComponent.cxx @@ -0,0 +1,50 @@ +//**************************************************************************** +//* This file 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 3 of the License, or * +//* (at your option) any later version. * +//* * +//* Primary Authors: Matthias Richter * +//* * +//* The authors make no claims about the suitability of this software for * +//* any purpose. It is provided "as is" without express or implied warranty. * +//**************************************************************************** + +// @file runComponent.cxx +// @author Matthias Richter +// @since 2014-05-07 +// @brief run a component encapsulating ALICE HLT code + +// TODO: this file is intended to evolve into a unit test + +#include "SystemInterface.h" +#include "Component.h" +#include +#include +#include +#include +#include + +using std::cout; +using std::cerr; +using std::stringstream; + +int main(int argc, char** argv) +{ + int iResult=0; + + ALICE::HLT::Component c; + if ((iResult=c.Init(argc, argv))<0) { + cerr << "error: init failed with " << iResult << endl; + // the ALICE HLT external interface uses the following error definition + // 0 success + // >0 error number + return -iResult; + } + + vector blockData; + if ((iResult=c.Process(blockData))<0) { + cerr << "error: init failed with " << iResult << endl; + return -iResult; + } +} From 4d56e680bf2ab0c0d6f1cfa2a7cafbec95534bcb Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Sat, 10 May 2014 16:17:39 +0200 Subject: [PATCH 10/34] adding the memory allocation functionality (forgotten to commit so far) --- devices/aliceHLTwrapper/SystemInterface.cxx | 14 ++++++++++++++ devices/aliceHLTwrapper/SystemInterface.h | 6 ++++++ 2 files changed, 20 insertions(+) diff --git a/devices/aliceHLTwrapper/SystemInterface.cxx b/devices/aliceHLTwrapper/SystemInterface.cxx index 8ac8c1a37fa8a..89bb914d64ea6 100644 --- a/devices/aliceHLTwrapper/SystemInterface.cxx +++ b/devices/aliceHLTwrapper/SystemInterface.cxx @@ -38,6 +38,7 @@ SystemInterface::SystemInterface() : { memset(&mEnvironment, 0, sizeof(mEnvironment)); mEnvironment.fStructSize=sizeof(mEnvironment); + mEnvironment.fAllocMemoryFunc=SystemInterface::Alloc; } SystemInterface::~SystemInterface() @@ -222,3 +223,16 @@ void SystemInterface::Print(const char* /*option*/) const { /// print info } + +void* SystemInterface::Alloc( void* /*param*/, unsigned long size ) +{ + // allocate memory + return malloc(size); +} + +void SystemInterface::Dealloc( void* buffer, unsigned long /*size*/ ) +{ + // deallocate memory + if (buffer==NULL) return; + free(buffer); +} diff --git a/devices/aliceHLTwrapper/SystemInterface.h b/devices/aliceHLTwrapper/SystemInterface.h index d5e07b22b5cbf..b2cc233df468d 100644 --- a/devices/aliceHLTwrapper/SystemInterface.h +++ b/devices/aliceHLTwrapper/SystemInterface.h @@ -98,6 +98,12 @@ namespace ALICE /// print info virtual void Print(const char* option="") const; + /// allocate memory + static void* Alloc( void* param, unsigned long size ); + + /// deallocate memory + static void Dealloc( void* buffer, unsigned long size ); + protected: private: From 5e651c9079499850125f46202acbf537215121e7 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Sat, 10 May 2014 16:18:57 +0200 Subject: [PATCH 11/34] adding Component class and test program to build; adding the correct path to find the zmq.h header file --- devices/aliceHLTwrapper/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/devices/aliceHLTwrapper/CMakeLists.txt b/devices/aliceHLTwrapper/CMakeLists.txt index 59e94331d30e3..ff31d416bea07 100644 --- a/devices/aliceHLTwrapper/CMakeLists.txt +++ b/devices/aliceHLTwrapper/CMakeLists.txt @@ -1,11 +1,14 @@ set(INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/fairmq ${CMAKE_SOURCE_DIR}/fairmq/zeromq + ${SIMPATH}/include # ${Boost_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/devices/aliceHLTwrapper ) include_directories(${INCLUDE_DIRECTORIES}) +# set(CXXOPT "-O0 -g -ggdb") +# set(CXXFLAGS "-O0 -g -ggdb") #configure_file( ${CMAKE_SOURCE_DIR}/example/flp2epn/run/startSomething.sh.in ${CMAKE_BINARY_DIR}/bin/startSomething.sh ) @@ -19,6 +22,7 @@ set(SRCS SystemInterface.cxx HOMERFactory.cxx WrapperDevice.cxx + Component.cxx ) set(DEPENDENCIES @@ -39,10 +43,12 @@ GENERATE_LIBRARY() Set(Exe_Names # ${Exe_Names} aliceHLTWrapper + runComponent ) set(Exe_Source aliceHLTWrapper.cxx + runComponent.cxx ) list(LENGTH Exe_Names _length) From 9cd6142cc9f74918e00e6faa5e25896eaef6ffde Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Sat, 10 May 2014 16:21:05 +0200 Subject: [PATCH 12/34] adding gitignore for the devices/aliceHLTwrapper folder --- devices/aliceHLTwrapper/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 devices/aliceHLTwrapper/.gitignore diff --git a/devices/aliceHLTwrapper/.gitignore b/devices/aliceHLTwrapper/.gitignore new file mode 100644 index 0000000000000..b25c15b81fae0 --- /dev/null +++ b/devices/aliceHLTwrapper/.gitignore @@ -0,0 +1 @@ +*~ From d317d2b9c87e0d1929c90c3fedd57dbd5e803d09 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Tue, 13 May 2014 09:11:26 +0200 Subject: [PATCH 13/34] using the ZMQ_INCLUDE_DIR for includes of zmq.h --- devices/aliceHLTwrapper/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devices/aliceHLTwrapper/CMakeLists.txt b/devices/aliceHLTwrapper/CMakeLists.txt index ff31d416bea07..7157445c06751 100644 --- a/devices/aliceHLTwrapper/CMakeLists.txt +++ b/devices/aliceHLTwrapper/CMakeLists.txt @@ -1,7 +1,7 @@ set(INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/fairmq ${CMAKE_SOURCE_DIR}/fairmq/zeromq - ${SIMPATH}/include + ${ZMQ_INCLUDE_DIR} # ${Boost_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/devices/aliceHLTwrapper ) From 7f24c4c866ee43b45d1e0531f642e6c84974fd99 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Tue, 13 May 2014 16:35:57 +0200 Subject: [PATCH 14/34] implementing file input and output in the standalone test component; support for 3 output modes: HOMER, multi-part, sequence added, corresponding input handling added --- devices/aliceHLTwrapper/Component.cxx | 136 ++++++++++++++++++++--- devices/aliceHLTwrapper/Component.h | 25 ++++- devices/aliceHLTwrapper/runComponent.cxx | 59 +++++++++- 3 files changed, 195 insertions(+), 25 deletions(-) diff --git a/devices/aliceHLTwrapper/Component.cxx b/devices/aliceHLTwrapper/Component.cxx index 201f5379808bc..9bd049908ea55 100644 --- a/devices/aliceHLTwrapper/Component.cxx +++ b/devices/aliceHLTwrapper/Component.cxx @@ -38,6 +38,7 @@ Component::Component() , mpFactory(NULL) , mpWriter(NULL) , mProcessor(kEmptyHLTComponentHandle) + , mOutputMode(kOutputModeSequence) { } @@ -56,6 +57,7 @@ int Component::Init(int argc, char** argv) {"parameter", optional_argument, 0, 'p'}, {"run", required_argument, 0, 'r'}, {"msgsize", optional_argument, 0, 's'}, + {"output-mode", optional_argument, 0, 'm'}, {0, 0, 0, 0} }; @@ -76,7 +78,7 @@ int Component::Init(int argc, char** argv) // by the run no int runNumber=0; - while ((c=getopt_long(argc, argv, "l:c:p:r:s:", programOptions, &iOption)) != -1) { + while ((c=getopt_long(argc, argv, "l:c:p:r:s:m:", programOptions, &iOption)) != -1) { switch (c) { case 'l': componentLibrary=optarg; @@ -94,10 +96,12 @@ int Component::Init(int argc, char** argv) { unsigned size=0; std::stringstream(optarg) >> size; - if (mOutputBuffer.capacity()> mOutputMode; + break; case '?': // TODO: more error handling break; @@ -162,9 +166,7 @@ int Component::Process(vector& dataArray) if (!mpSystem) return -ENOSYS; int iResult=0; - // TODO: make the initial size configurable - unsigned outputBufferSize=10000; - mOutputBuffer.reserve(outputBufferSize); + unsigned outputBufferSize=0; AliHLTComponentEventData evtData; memset(&evtData, 0, sizeof(evtData)); @@ -183,9 +185,9 @@ int Component::Process(vector& dataArray) vector inputBlocks; for (vector::iterator data=dataArray.begin(); data!=dataArray.end(); data++) { - if (ReadSingleBlock(data->p, data->size, inputBlocks)<0) { + if (ReadBlockSequence(data->mP, data->mSize, inputBlocks)<0) { // not in the format of a single block, check if its a HOMER block - if (ReadHOMERFormat(data->p, data->size, inputBlocks)<0) { + if (ReadHOMERFormat(data->mP, data->mSize, inputBlocks)<0) { // not in HOMER format either, ignore the input // TODO: decide if that should be an error } @@ -211,13 +213,13 @@ int Component::Process(vector& dataArray) double inputBlockMultiplier=0.; mpSystem->GetOutputSize(mProcessor, &constEventBase, &constBlockBase, &inputBlockMultiplier); outputBufferSize=constEventBase+nofInputBlocks*constBlockBase; - if (mOutputBuffer.capacity()& dataArray) &mOutputBuffer[0], &outputBufferSize, &outputBlockCnt, &pOutputBlocks, &pEventDoneData); + if (outputBufferSize>0) { + if (outputBufferSize>mOutputBuffer.size()) { + cerr << "fatal error: component writing beyond buffer capacity" << endl; + return -EFAULT; + } else if (outputBufferSize0); - // build the message from the output block + // prepare output + dataArray.clear(); + if (mOutputMode==kOutputModeHOMER) { + AliHLTHOMERWriter* pWriter=CreateHOMERFormat(pOutputBlocks, outputBlockCnt); + if (pWriter) { + AliHLTUInt32_t position=mOutputBuffer.size(); + AliHLTUInt32_t payloadSize=pWriter->GetTotalMemorySize(); + if (mOutputBuffer.capacity()Copy(&mOutputBuffer[position], 0, 0, 0, 0); + mpFactory->DeleteWriter(pWriter); + dataArray.push_back(BufferDesc_t(&mOutputBuffer[position], payloadSize)); + } + } else if (mOutputMode==kOutputModeMultiPart) { + AliHLTUInt32_t position=mOutputBuffer.size(); + AliHLTComponentBlockData* pOutputBlock=pOutputBlocks; + for (unsigned blockIndex=0; blockIndexfSize) + mOutputBuffer.reserve(position+sizeof(AliHLTComponentBlockData)+pOutputBlock->fSize); + dataArray.push_back(BufferDesc_t(&mOutputBuffer[position], sizeof(AliHLTComponentBlockData)+pOutputBlock->fSize)); + AliHLTUInt32_t sourcePosition=pOutputBlock->fOffset; + pOutputBlock->fOffset=0; + pOutputBlock->fPtr=NULL; + memcpy(&mOutputBuffer[position], pOutputBlock, sizeof(AliHLTComponentBlockData)); + position+=sizeof(AliHLTComponentBlockData); + memcpy(&mOutputBuffer[position], &mOutputBuffer[sourcePosition], pOutputBlock->fSize); + position+=pOutputBlock->fSize; + } + } else if (mOutputMode==kOutputModeSequence) { + AliHLTUInt32_t position=mOutputBuffer.size(); + AliHLTUInt32_t startPosition=position; + AliHLTComponentBlockData* pOutputBlock=pOutputBlocks; + for (unsigned blockIndex=0; blockIndexfSize) + mOutputBuffer.reserve(position+sizeof(AliHLTComponentBlockData)+pOutputBlock->fSize); + AliHLTUInt32_t sourcePosition=pOutputBlock->fOffset; + pOutputBlock->fOffset=0; + pOutputBlock->fPtr=NULL; + memcpy(&mOutputBuffer[position], pOutputBlock, sizeof(AliHLTComponentBlockData)); + position+=sizeof(AliHLTComponentBlockData); + memcpy(&mOutputBuffer[position], &mOutputBuffer[sourcePosition], pOutputBlock->fSize); + position+=pOutputBlock->fSize; + } + dataArray.push_back(BufferDesc_t(&mOutputBuffer[startPosition], position-startPosition)); + } else { + // invalid output mode + cerr << "error ALICE::HLT::Component: invalid output mode " << mOutputMode << endl; + } // cleanup // NOTE: don't cleanup mOutputBuffer as the data is going to be used outside the class @@ -260,7 +320,7 @@ AliHLTHOMERWriter* Component::CreateHOMERFormat(AliHLTComponentBlockData* pOutpu HOMERBlockDescriptor homerDescriptor(homerHeader); AliHLTComponentBlockData* pOutputBlock=pOutputBlocks; - for (unsigned blockIndex=0; blockIndex& inputBlocks) +int Component::ReadBlockSequence(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks) { - // read a single block from message payload consisting of AliHLTComponentBlockData followed by - // the block data - return 0; + // read a sequence of blocks consisting of AliHLTComponentBlockData followed by payload + // from a buffer + if (buffer==NULL) return 0; + unsigned position=0; + vector input; + while (position+sizeof(AliHLTComponentBlockData)(buffer+position); + if (p->fStructSize+position>size || // no space for the header + p->fStructSize+p->fSize+position>size) { // no space for the payload + // the buffer is only a valid sequence of data blocks if payload + // of the last block exacly matches the buffer boundary + // otherwize all blocks added until now are ignored + return 0; + } + // insert a new block + input.push_back(*p); + position+=p->fStructSize; + input.back().fPtr=buffer+position; + position+=p->fSize; + } + + inputBlocks.insert(inputBlocks.end(), input.begin(), input.end()); + return input.size(); } int Component::ReadHOMERFormat(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks) { // read message payload in HOMER format + if (buffer==NULL || mpFactory==NULL) return 0; + auto_ptr reader(mpFactory->OpenReaderBuffer(buffer, size)); + if (reader.get()==NULL) return 0; + + if (reader->ReadNextEvent()==0) { + unsigned nofBlocks=reader->GetBlockCnt(); + for (unsigned i=0; iGetBlockDataType( i ); + homer_uint32 origin=reader->GetBlockDataOrigin( i ); + memcpy(&block.fDataType.fID, &id, sizeof(id)>kAliHLTComponentDataTypefIDsize?kAliHLTComponentDataTypefIDsize:sizeof(id)); + memcpy(&block.fDataType.fOrigin, &origin, sizeof(origin)>kAliHLTComponentDataTypefOriginSize?kAliHLTComponentDataTypefOriginSize:sizeof(origin)); + block.fSpecification=reader->GetBlockDataSpec( i ); + block.fPtr=const_cast(reader->GetBlockData( i )); + block.fSize=reader->GetBlockDataLength( i ); + inputBlocks.push_back(block); + } + } + return 0; } diff --git a/devices/aliceHLTwrapper/Component.h b/devices/aliceHLTwrapper/Component.h index 6278a74778ac7..9cb392f3a2677 100644 --- a/devices/aliceHLTwrapper/Component.h +++ b/devices/aliceHLTwrapper/Component.h @@ -42,8 +42,22 @@ namespace ALICE int Init(int argc, char** argv); struct BufferDesc_t { - unsigned char* p; - unsigned size; + unsigned char* mP; + unsigned mSize; + + BufferDesc_t(unsigned char* p, unsigned size) { + mP=p; mSize=size; + } + }; + + enum { + // all blocks in HOMER format + kOutputModeHOMER=0, + // each block individually as part of a multi-part output + kOutputModeMultiPart, + // all blocks as sequence of header and payload + kOutputModeSequence, + kOutputModeLast }; int Process(vector& dataArray); @@ -56,9 +70,9 @@ namespace ALICE // assignment operator prohibited Component& operator=(const Component&); - // read a single block from message payload consisting of AliHLTComponentBlockData followed by - // the block data - int ReadSingleBlock(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks); + // read a sequence of blocks consisting of AliHLTComponentBlockData followed by payload + // from a buffer + int ReadBlockSequence(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks); // read message payload in HOMER format int ReadHOMERFormat(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks); @@ -72,6 +86,7 @@ namespace ALICE HOMERFactory* mpFactory; AliHLTHOMERWriter* mpWriter; AliHLTComponentHandle mProcessor; + int mOutputMode; }; } // namespace hlt diff --git a/devices/aliceHLTwrapper/runComponent.cxx b/devices/aliceHLTwrapper/runComponent.cxx index 220d91e812a27..9a1a12a0b393b 100644 --- a/devices/aliceHLTwrapper/runComponent.cxx +++ b/devices/aliceHLTwrapper/runComponent.cxx @@ -20,6 +20,7 @@ #include "SystemInterface.h" #include "Component.h" #include +#include #include #include #include @@ -32,9 +33,33 @@ using std::stringstream; int main(int argc, char** argv) { int iResult=0; + // parse options + const char* inputFileName=NULL; + const char* outputFileName=NULL; - ALICE::HLT::Component c; - if ((iResult=c.Init(argc, argv))<0) { + vector componentOptions; + for (int i=0; i=argc) { + cerr << "missing file name for option " << arg << endl; + } + else if (arg[1]=='i') inputFileName=argv[i+1]; + else outputFileName=argv[i+1]; + break; + } + } + // intended fall-through + default: + componentOptions.push_back(arg); + } + } + + ALICE::HLT::Component component; + if ((iResult=component.Init(componentOptions.size(), &componentOptions[0]))<0) { cerr << "error: init failed with " << iResult << endl; // the ALICE HLT external interface uses the following error definition // 0 success @@ -43,8 +68,36 @@ int main(int argc, char** argv) } vector blockData; - if ((iResult=c.Process(blockData))<0) { + char* inputBuffer=NULL; + if (inputFileName) { + std::ifstream input(inputFileName, std::ifstream::binary); + if (input) { + // get length of file: + input.seekg (0, input.end); + int length = input.tellg(); + input.seekg (0, input.beg); + + // allocate memory: + inputBuffer=new char [length]; + input.read (inputBuffer,length); + input.close(); + blockData.push_back(ALICE::HLT::Component::BufferDesc_t(reinterpret_cast(inputBuffer), length)); + } + } + if ((iResult=component.Process(blockData))<0) { cerr << "error: init failed with " << iResult << endl; + } + if (inputBuffer) delete [] inputBuffer; + inputBuffer=NULL; + if (iResult<0) return -iResult; + + // for now, only the first buffer is written + if (blockData.size()>0 && outputFileName!=NULL) { + ofstream outputFile(outputFileName); + if (outputFile.good()) { + outputFile.write(reinterpret_cast(blockData[0].mP), blockData[0].mSize); + outputFile.close(); + } } } From 47cc1832318b4c3def78c080e9e00cdea60edf31 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Wed, 14 May 2014 08:56:34 +0200 Subject: [PATCH 15/34] some bugfixes concerning reading of blocks in HOMER format; using consistent error codes; added a warning if none of the input blocks is recognized as valid input --- devices/aliceHLTwrapper/Component.cxx | 58 +++++++++++++++++++++------ devices/aliceHLTwrapper/Component.h | 3 ++ 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/devices/aliceHLTwrapper/Component.cxx b/devices/aliceHLTwrapper/Component.cxx index 9bd049908ea55..7fe1b943276d0 100644 --- a/devices/aliceHLTwrapper/Component.cxx +++ b/devices/aliceHLTwrapper/Component.cxx @@ -194,6 +194,9 @@ int Component::Process(vector& dataArray) } } unsigned nofInputBlocks=inputBlocks.size(); + if (dataArray.size()>0 && nofInputBlocks==0) { + cerr << "warning: none of " << dataArray.size() << " input buffers recognized as valid input" << endl; + } // add event type data block AliHLTComponentBlockData eventTypeBlock; @@ -327,8 +330,8 @@ AliHLTHOMERWriter* Component::CreateHOMERFormat(AliHLTComponentBlockData* pOutpu homer_uint64 origin=0; memcpy(&id, pOutputBlock->fDataType.fID, sizeof(homer_uint64)); memcpy(((AliHLTUInt8_t*)&origin)+sizeof(homer_uint32), pOutputBlock->fDataType.fOrigin, sizeof(homer_uint32)); - homerDescriptor.SetType((id)); - homerDescriptor.SetSubType1((origin)); + homerDescriptor.SetType(ByteSwap64(id)); + homerDescriptor.SetSubType1(ByteSwap64(origin)); homerDescriptor.SetSubType2(pOutputBlock->fSpecification); homerDescriptor.SetBlockSize(pOutputBlock->fSize); writer->AddBlock(homerHeader, &mOutputBuffer[pOutputBlock->fOffset]); @@ -345,18 +348,26 @@ int Component::ReadBlockSequence(AliHLTUInt8_t* buffer, unsigned size, vector input; while (position+sizeof(AliHLTComponentBlockData)(buffer+position); - if (p->fStructSize+position>size || // no space for the header + if (p->fStructSize==0 || // no valid header + p->fStructSize+position>size || // no space for the header p->fStructSize+p->fSize+position>size) { // no space for the payload // the buffer is only a valid sequence of data blocks if payload // of the last block exacly matches the buffer boundary // otherwize all blocks added until now are ignored - return 0; + return -ENODATA; } // insert a new block input.push_back(*p); position+=p->fStructSize; - input.back().fPtr=buffer+position; - position+=p->fSize; + if (p->fSize>0) { + input.back().fPtr=buffer+position; + position+=p->fSize; + } else { + // Note: also a valid block, payload is optional + input.back().fPtr=NULL; + } + // offset always 0 for iput blocks + input.back().fOffset=0; } inputBlocks.insert(inputBlocks.end(), input.begin(), input.end()); @@ -366,19 +377,20 @@ int Component::ReadBlockSequence(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks) { // read message payload in HOMER format - if (buffer==NULL || mpFactory==NULL) return 0; + if (buffer==NULL || mpFactory==NULL) return -EINVAL; auto_ptr reader(mpFactory->OpenReaderBuffer(buffer, size)); - if (reader.get()==NULL) return 0; + if (reader.get()==NULL) return -ENOMEM; + unsigned nofBlocks=0; if (reader->ReadNextEvent()==0) { - unsigned nofBlocks=reader->GetBlockCnt(); + nofBlocks=reader->GetBlockCnt(); for (unsigned i=0; iGetBlockDataType( i ); - homer_uint32 origin=reader->GetBlockDataOrigin( i ); + homer_uint64 id=ByteSwap64(reader->GetBlockDataType( i )); + homer_uint32 origin=ByteSwap32(reader->GetBlockDataOrigin( i )); memcpy(&block.fDataType.fID, &id, sizeof(id)>kAliHLTComponentDataTypefIDsize?kAliHLTComponentDataTypefIDsize:sizeof(id)); memcpy(&block.fDataType.fOrigin, &origin, sizeof(origin)>kAliHLTComponentDataTypefOriginSize?kAliHLTComponentDataTypefOriginSize:sizeof(origin)); block.fSpecification=reader->GetBlockDataSpec( i ); @@ -388,5 +400,27 @@ int Component::ReadHOMERFormat(AliHLTUInt8_t* buffer, unsigned size, vector> 8) | + ((src & 0xFF0000000000ULL) >> 24) | + ((src & 0xFF000000000000ULL) >> 40) | + ((src & 0xFF00000000000000ULL) >> 56); +} + +AliHLTUInt32_t Component::ByteSwap32(AliHLTUInt32_t src) +{ + // swap a 32 bit number + return ((src & 0xFFULL) << 24) | + ((src & 0xFF00ULL) << 8) | + ((src & 0xFF0000ULL) >> 8) | + ((src & 0xFF000000ULL) >> 24); } diff --git a/devices/aliceHLTwrapper/Component.h b/devices/aliceHLTwrapper/Component.h index 9cb392f3a2677..af93931508c69 100644 --- a/devices/aliceHLTwrapper/Component.h +++ b/devices/aliceHLTwrapper/Component.h @@ -62,6 +62,9 @@ namespace ALICE int Process(vector& dataArray); + AliHLTUInt64_t ByteSwap64(AliHLTUInt64_t src); + AliHLTUInt32_t ByteSwap32(AliHLTUInt32_t src); + protected: private: From c7e01dfa6a8e52f4ffa7342939700e733a76321b Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Wed, 14 May 2014 09:42:33 +0200 Subject: [PATCH 16/34] added warning for dropped output blocks --- devices/aliceHLTwrapper/runComponent.cxx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/devices/aliceHLTwrapper/runComponent.cxx b/devices/aliceHLTwrapper/runComponent.cxx index 9a1a12a0b393b..a7ffd0181f83d 100644 --- a/devices/aliceHLTwrapper/runComponent.cxx +++ b/devices/aliceHLTwrapper/runComponent.cxx @@ -93,11 +93,15 @@ int main(int argc, char** argv) return -iResult; // for now, only the first buffer is written - if (blockData.size()>0 && outputFileName!=NULL) { + if (blockData.size()>0) { + if (outputFileName!=NULL) { ofstream outputFile(outputFileName); if (outputFile.good()) { outputFile.write(reinterpret_cast(blockData[0].mP), blockData[0].mSize); outputFile.close(); } + } else { + cerr << "WARNING: dropping " << blockData.size() << " data block(s) produced by component, use option '-o' to specify output file" << endl; + } } } From 91b8f4e2234347ffe23222afb22f223cb56c4578 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Wed, 14 May 2014 11:58:21 +0200 Subject: [PATCH 17/34] WrapperDevice finished, now based on the ALICE::HLT::Component class; finished argument scan and executable --- devices/aliceHLTwrapper/WrapperDevice.cxx | 279 +++++--------------- devices/aliceHLTwrapper/WrapperDevice.h | 36 +-- devices/aliceHLTwrapper/aliceHLTWrapper.cxx | 127 +++------ 3 files changed, 110 insertions(+), 332 deletions(-) diff --git a/devices/aliceHLTwrapper/WrapperDevice.cxx b/devices/aliceHLTwrapper/WrapperDevice.cxx index efd194152a08d..0ab05cd1f580a 100644 --- a/devices/aliceHLTwrapper/WrapperDevice.cxx +++ b/devices/aliceHLTwrapper/WrapperDevice.cxx @@ -16,12 +16,7 @@ // @brief FairRoot/ALFA device running ALICE HLT code #include "WrapperDevice.h" -#include "AliHLTDataTypes.h" -#include "SystemInterface.h" -#include "HOMERFactory.h" -#include "AliHLTHOMERData.h" -#include "AliHLTHOMERWriter.h" -#include "AliHLTHOMERReader.h" +#include "Component.h" #include "FairMQLogger.h" #include "FairMQPoller.h" @@ -34,19 +29,11 @@ #include using namespace ALICE::HLT; -WrapperDevice::WrapperDevice(const char* library, const char* id, const char* parameter, unsigned runNumber) - : mComponentLibrary(library) - , mComponentId(id) - , mComponentParameter(parameter) - , mRunNumber(runNumber) - , mOutputBuffer() - , mOutputBlocks() - , mpSystem(NULL) - , mpFactory(NULL) - , mpReader(NULL) - , mpWriter(NULL) - , mProcessor(kEmptyHLTComponentHandle) +WrapperDevice::WrapperDevice(int argc, char** argv) + : mComponent(NULL) + , mArgv() { + mArgv.insert(mArgv.end(), argv, argv+argc); } WrapperDevice::~WrapperDevice() @@ -58,71 +45,26 @@ void WrapperDevice::Init() /// inherited from FairMQDevice int iResult=0; - // TODO: make the SystemInterface a singleton - auto_ptr iface(new SystemInterface); - if (iface.get()==NULL || ((iResult=iface->InitSystem(mRunNumber)))<0) { - LOG(ERROR) << "failed to set up SystemInterface " << iface.get() << " (" << iResult << ")"; - return; - } - auto_ptr homerfact(new HOMERFactory); - if (!homerfact.get()) { - LOG(ERROR) << "failed to set up HOMERFactory " << homerfact.get(); - return; - } - - // basic initialization succeeded, make the instances persistent - mpSystem=iface.release(); - mpFactory=homerfact.release(); - - // load the component library - if ((iResult=mpSystem->LoadLibrary(mComponentLibrary.c_str()))<0) - return; - - // chop the parameter string in order to provide parameters in the argc/argv format - vector parameters; - auto_ptr parameterBuffer(new char[mComponentParameter.length()+1]); - if (mComponentParameter.length()>0 && parameterBuffer.get()!=NULL) { - strcpy(parameterBuffer.get(), mComponentParameter.c_str()); - char* iterator=parameterBuffer.get(); - parameters.push_back(iterator); - for (; *iterator!=0; iterator++) { - if (*iterator!=' ') continue; - *iterator=0; // separate strings - if (*(iterator+1)!=' ' && *(iterator+1)!=0) - parameters.push_back(iterator+1); - } + std::auto_ptr component(new ALICE::HLT::Component); + if (!component.get()) return /*-ENOMEM*/; + + if ((iResult=component->Init(mArgv.size(), &mArgv[0]))<0) { + LOG(ERROR) << "component init failed with error code" << iResult; + // the ALICE HLT external interface uses the following error definition + // 0 success + // >0 error number + return /*-iResult*/; } - // create component - if ((iResult=mpSystem->CreateComponent(mComponentId.c_str(), NULL, parameters.size(), ¶meters[0], &mProcessor, ""))<0) - return; - + mComponent=component.release(); FairMQDevice::Init(); - } void WrapperDevice::Run() { /// inherited from FairMQDevice - if (!mpSystem) return; int iResult=0; - // TODO: make the initial size configurable - unsigned outputBufferSize=10000; - mOutputBuffer.reserve(outputBufferSize); - - AliHLTComponentEventData evtData; - memset(&evtData, 0, sizeof(evtData)); - evtData.fStructSize=sizeof(evtData); - - AliHLTComponentTriggerData trigData; - memset(&trigData, 0, sizeof(trigData)); - trigData.fStructSize=sizeof(trigData); - - AliHLTUInt32_t outputBlockCnt=0; - AliHLTComponentBlockData* pOutputBlocks=NULL; - AliHLTComponentEventDoneData* pEventDoneData=NULL; - boost::thread rateLogger(boost::bind(&FairMQDevice::LogSocketRates, this)); FairMQPoller* poller = fTransportFactory->CreatePoller(*fPayloadInputs); @@ -135,8 +77,10 @@ void WrapperDevice::Run() // fPayloadInputs // fPayloadOutputs int NoOfMsgParts=fNumInputs-1; + int errorCount=0; + const int maxError=10; - vector inputMessages(fNumInputs); + vector inputMessages(fNumInputs); while ( fState == RUNNING ) { // read input messages @@ -153,70 +97,59 @@ void WrapperDevice::Run() } } - // call HLT component - // prepare input from messages - vector inputBlocks; - // ... - // create blocks from messages - // ... - unsigned nofInputBlocks=inputBlocks.size(); + vector dataArray; + for (vector::iterator msg=inputMessages.begin(); + msg!=inputMessages.end(); msg++) { + void* buffer=(*msg)->GetData(); + dataArray.push_back(ALICE::HLT::Component::BufferDesc_t(reinterpret_cast(buffer), (*msg)->GetSize())); + } - // add event type data block - AliHLTComponentBlockData eventTypeBlock; - memset(&eventTypeBlock, 0, sizeof(eventTypeBlock)); - eventTypeBlock.fStructSize=sizeof(eventTypeBlock); - // Note: no payload! - eventTypeBlock.fDataType=AliHLTComponentDataTypeInitializer("EVENTTYP", "PRIV"); - eventTypeBlock.fSpecification=gkAliEventTypeData; - inputBlocks.push_back(eventTypeBlock); + // call the component + if ((iResult=mComponent->Process(dataArray))<0) { + LOG(ERROR) << "component processing failed with error code" << iResult; + } - // process - evtData.fBlockCnt=inputBlocks.size(); - int nofTrials=2; - do { - unsigned long constEventBase=0; - unsigned long constBlockBase=0; - double inputBlockMultiplier=0.; - mpSystem->GetOutputSize(mProcessor, &constEventBase, &constBlockBase, &inputBlockMultiplier); - outputBufferSize=constEventBase+nofInputBlocks*constBlockBase; - if (mOutputBuffer.capacity() msg(fTransportFactory->CreateMessage()); + if (msg.get() && fPayloadOutputs!=NULL && fPayloadOutputs->size()>0) { + vector::iterator data=dataArray.begin(); + while (data!=dataArray.end()) { + msg->Rebuild(data->mSize); + if (msg->GetSize()mSize) { + iResult=-ENOSPC; + break; + } + AliHLTUInt8_t* pTarget=reinterpret_cast(msg->GetData()); + memcpy(pTarget, data->mP, data->mSize); + if (data+1==dataArray.end()) { + // that is the last data block + // TODO: replace this with the corresponding FairMQ flag if that becomes available + fPayloadOutputs->at(0)->Send(msg.get()/*, ZMQ_SNDMORE*/); + } else { + fPayloadOutputs->at(0)->Send(msg.get()); + } + + data=dataArray.erase(data); } - outputBufferSize=mOutputBuffer.capacity(); - outputBlockCnt=0; - // TODO: check if that is working with the corresponding allocation method of the - // component environment - if (pOutputBlocks) delete [] pOutputBlocks; - pOutputBlocks=NULL; - if (pEventDoneData) delete pEventDoneData; - pEventDoneData=NULL; - - iResult=mpSystem->ProcessEvent(mProcessor, &evtData, &inputBlocks[0], &trigData, - &mOutputBuffer[0], &outputBufferSize, - &outputBlockCnt, &pOutputBlocks, - &pEventDoneData); - - } while (iResult==ENOSPC && --nofTrials>0); - - // build the message from the output block - SendMultiMessages(pOutputBlocks, outputBlockCnt); + } else if (fPayloadOutputs==NULL || fPayloadOutputs->size()==0) { + if (errorCount==maxError && errorCount++>0) + LOG(ERROR) << "persistent error, suppressing further output"; + else if (errorCount++0) + LOG(ERROR) << "persistent error, suppressing further output"; + else if (errorCount++::iterator mit=inputMessages.begin(); mit!=inputMessages.end(); mit++) delete *mit; inputMessages.clear(); - mOutputBuffer.clear(); - outputBlockCnt=0; - if (pOutputBlocks) delete [] pOutputBlocks; - pOutputBlocks=NULL; - if (pEventDoneData) delete pEventDoneData; - pEventDoneData=NULL; } delete poller; @@ -225,89 +158,6 @@ void WrapperDevice::Run() rateLogger.join(); } -int WrapperDevice::SendMultiMessages(AliHLTComponentBlockData* pOutputBlocks, AliHLTUInt32_t outputBlockCnt) -{ - // send data blocks in a group of messages - int iResult=0; - auto_ptr msg(fTransportFactory->CreateMessage()); - if (msg.get()) { - AliHLTComponentBlockData* pOutputBlock=pOutputBlocks; - for (unsigned blockIndex=0; blockIndexfSize; - msg->Rebuild(msgSize); - if (msg->GetSize()(msg->GetData()); - memcpy(pTarget, pOutputBlock, sizeof(AliHLTComponentBlockData)); - pTarget+=sizeof(AliHLTComponentBlockData); - memcpy(pTarget, &mOutputBuffer[pOutputBlock->fOffset], pOutputBlock->fSize); - if (blockIndex+1at(0)->Send(msg.get()/*, ZMQ_SNDMORE*/); - } else { - fPayloadOutputs->at(0)->Send(msg.get()); - } - } - } - return iResult; -} - -int WrapperDevice::SendHOMERMessage(AliHLTComponentBlockData* pOutputBlocks, AliHLTUInt32_t outputBlockCnt) -{ - // send data blocks in HOMER format in one message - int iResult=0; - if (!mpFactory) return -ENODEV; - auto_ptr writer(mpFactory->OpenWriter()); - if (writer.get()==NULL) return -ENOSYS; - - homer_uint64 homerHeader[kCount_64b_Words]; - HOMERBlockDescriptor homerDescriptor(homerHeader); - - AliHLTComponentBlockData* pOutputBlock=pOutputBlocks; - for (unsigned blockIndex=0; blockIndexfDataType.fID, sizeof(homer_uint64)); - memcpy(((AliHLTUInt8_t*)&origin)+sizeof(homer_uint32), pOutputBlock->fDataType.fOrigin, sizeof(homer_uint32)); - homerDescriptor.SetType((id)); - homerDescriptor.SetSubType1((origin)); - homerDescriptor.SetSubType2(pOutputBlock->fSpecification); - homerDescriptor.SetBlockSize(pOutputBlock->fSize); - writer->AddBlock(homerHeader, &mOutputBuffer[pOutputBlock->fOffset]); - } - - auto_ptr msg(fTransportFactory->CreateMessage()); - if (msg.get()) { - int msgSize=writer->GetTotalMemorySize(); - msg->Rebuild(msgSize); - if (msg->GetSize()(msg->GetData()); - writer->Copy(pTarget, 0, 0, 0, 0); - fPayloadOutputs->at(0)->Send(msg.get()); - } - } - return iResult; -} - -int WrapperDevice::ReadSingleBlock(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks) -{ - // read a single block from message payload consisting of AliHLTComponentBlockData followed by - // the block data - return 0; -} - -int WrapperDevice::ReadHOMERMessage(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks) -{ - // read message payload in HOMER format - return 0; -} - void WrapperDevice::Pause() { /// inherited from FairMQDevice @@ -320,11 +170,7 @@ void WrapperDevice::Shutdown() /// inherited from FairMQDevice int iResult=0; - if (!mpSystem) return; - - iResult=mpSystem->DestroyComponent(mProcessor); - iResult=mpSystem->ReleaseSystem(); - + // TODO: shutdown component and delte instance } void WrapperDevice::InitOutput() @@ -338,4 +184,3 @@ void WrapperDevice::InitInput() /// inherited from FairMQDevice } - diff --git a/devices/aliceHLTwrapper/WrapperDevice.h b/devices/aliceHLTwrapper/WrapperDevice.h index 68bd3a4ee1dee..c03314bb036c0 100644 --- a/devices/aliceHLTwrapper/WrapperDevice.h +++ b/devices/aliceHLTwrapper/WrapperDevice.h @@ -19,24 +19,19 @@ // @since 2014-05-08 // @brief FairRoot/ALFA device running ALICE HLT code -#include "AliHLTDataTypes.h" #include "FairMQDevice.h" #include -class AliHLTHOMERReader; -class AliHLTHOMERWriter; - namespace ALICE { namespace HLT { - class HOMERFactory; - class SystemInterface; + class Component; class WrapperDevice : public FairMQDevice { public: /// default constructor - WrapperDevice(const char* library="", const char* id="", const char* parameter="", unsigned runNumber=0); + WrapperDevice(int argc, char** argv); /// destructor ~WrapperDevice(); @@ -63,31 +58,8 @@ namespace ALICE // assignment operator prohibited WrapperDevice& operator=(const WrapperDevice&); - // send data blocks in a group of messages - int SendMultiMessages(AliHLTComponentBlockData* pOutputBlocks, AliHLTUInt32_t outputBlockCnt); - - // send data blocks in HOMER format in one message - int SendHOMERMessage(AliHLTComponentBlockData* pOutputBlocks, AliHLTUInt32_t outputBlockCnt); - - // read a single block from message payload consisting of AliHLTComponentBlockData followed by - // the block data - int ReadSingleBlock(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks); - - // read message payload in HOMER format - int ReadHOMERMessage(AliHLTUInt8_t* buffer, unsigned size, vector& inputBlocks); - - string mComponentLibrary; - string mComponentId; - string mComponentParameter; - unsigned mRunNumber; - vector mOutputBuffer; - vector mOutputBlocks; - - SystemInterface* mpSystem; - HOMERFactory* mpFactory; - AliHLTHOMERReader* mpReader; - AliHLTHOMERWriter* mpWriter; - AliHLTComponentHandle mProcessor; + Component* mComponent; + vector mArgv; }; } // namespace hlt diff --git a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx index be537126dd7ab..ad5bc6580a2ca 100644 --- a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx +++ b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx @@ -15,11 +15,9 @@ // @since 2014-05-07 // @brief FairRoot/ALFA device running ALICE HLT code -#include "SystemInterface.h" #include "WrapperDevice.h" #include #include -#include #include #include #ifdef NANOMSG @@ -35,56 +33,49 @@ using std::stringstream; int main(int argc, char** argv) { int iResult=0; - // parse options - static struct option programOptions[] = { - {"library", required_argument, 0, 'l'}, - {"component", required_argument, 0, 'c'}, - {"parameter", required_argument, 0, 'p'}, - {"run", required_argument, 0, 'r'}, - {0, 0, 0, 0} - }; - - /* getopt_long stores the option index here. */ - char c=0; - int iOption = 0; - - // HLT components are implemented in shared libraries, the library name - // and component id are used to factorize a component - // optionally, a list of configuration parameters can be specified as - // one single string which is translated in an array of string in the - // argc/argv format - const char* componentLibrary=""; - const char* componentId=""; - const char* componentParameter=""; - // the configuration and calibration is fixed for every run and identified - // by the run no - int runNumber=0; - - while ((c=getopt_long(argc, argv, "l:c:p:r:", programOptions, &iOption)) != -1) { - switch (c) { - case 'l': - componentLibrary=optarg; - break; - case 'c': - componentId=optarg; - break; - case 'p': - componentParameter=optarg; + // parse options + int iArg=1; + bool bPrintUsage=true; + std::string id; + int numIoThreads=0; + int numInputs=0; + int numOutputs=0; + std::string socketType; + int outputBufferSize=0; + std::string connectMethod; + std::string address; + for (; iArg> numIoThreads; break; + case 3: std::stringstream(arg) >> numInputs; break; + case 4: std::stringstream(arg) >> numOutputs; break; + case 5: socketType=arg; break; + case 6: std::stringstream(arg) >> outputBufferSize; break; + case 7: connectMethod=arg; break; + case 8: address=arg; break; + default: + bPrintUsage=false; break; - case 'r': - stringstream(optarg) >> runNumber; - case '?': - // TODO: more error handling + } + if (arg[0]=='-') { + // all options after the first one starting with '-' are propagated + // to the HLT component break; - default: - cerr << "unknown option: '"<< c << "'" << endl; } } - cout << "Library: " << componentLibrary << " - " << componentId << " (" << componentParameter << ")" << endl; + if (bPrintUsage) { + cout << "Usage : " << argv[0] << " ID numIoThreads numInputs numOutputs socketType bufferSize connectMethod address componentArguments" << endl; + return 0; + } - ALICE::HLT::WrapperDevice device(componentLibrary, componentId, componentParameter, runNumber); + vector deviceArgs; + deviceArgs.push_back(argv[0]); + deviceArgs.insert(deviceArgs.end(), argv+iArg, argv+argc); + ALICE::HLT::WrapperDevice device(deviceArgs.size(), &deviceArgs[0]); #ifdef NANOMSG FairMQTransportFactory* transportFactory = new FairMQTransportFactoryNN(); @@ -93,15 +84,15 @@ int main(int argc, char** argv) #endif device.SetTransport(transportFactory); - device.SetProperty(FairMQDevice::Id, "ID"); - device.SetProperty(FairMQDevice::NumIoThreads, 1); - device.SetProperty(FairMQDevice::NumInputs, 0); - device.SetProperty(FairMQDevice::NumOutputs, 1); + device.SetProperty(FairMQDevice::Id, id.c_str()); + device.SetProperty(FairMQDevice::NumIoThreads, numIoThreads); + device.SetProperty(FairMQDevice::NumInputs, numInputs); + device.SetProperty(FairMQDevice::NumOutputs, numOutputs); device.ChangeState(FairMQDevice::INIT); - device.SetProperty(FairMQDevice::OutputSocketType, "push"); - device.SetProperty(FairMQDevice::OutputSndBufSize, 10000, 0); - device.SetProperty(FairMQDevice::OutputMethod, "connect", 0); - device.SetProperty(FairMQDevice::OutputAddress, "tcp://localhost:5565", 0); + device.SetProperty(FairMQDevice::OutputSocketType, socketType.c_str()); + device.SetProperty(FairMQDevice::OutputSndBufSize, outputBufferSize, 0); + device.SetProperty(FairMQDevice::OutputMethod, connectMethod.c_str(), 0); + device.SetProperty(FairMQDevice::OutputAddress, address.c_str(), 0); device.ChangeState(FairMQDevice::SETOUTPUT); device.ChangeState(FairMQDevice::SETINPUT); @@ -114,34 +105,4 @@ int main(int argc, char** argv) device.ChangeState(FairMQDevice::END); return iResult; - - /* !!!! preliminary code below is disabled !!!*/ - AliHLTComponentHandle componentHandle=kEmptyHLTComponentHandle; - - // chop the parameter string in order to provide parameters in the argc/argv format - vector parameters; - auto_ptr parameterBuffer(new char[strlen(componentParameter)+1]); - if (strlen(componentParameter)>0 && parameterBuffer.get()!=NULL) { - strcpy(parameterBuffer.get(), componentParameter); - char* iterator=parameterBuffer.get(); - parameters.push_back(iterator); - for (; *iterator!=0; iterator++) { - if (*iterator!=' ') continue; - *iterator=0; // separate strings - if (*(iterator+1)!=' ' && *(iterator+1)!=0) - parameters.push_back(iterator+1); - } - } - - ALICE::HLT::SystemInterface iface; - if ((iResult=iface.InitSystem(runNumber))<0) - return iResult; - - if ((iResult=iface.LoadLibrary(componentLibrary))<0) - return iResult; - - if ((iResult=iface.CreateComponent(componentId, NULL, parameters.size(), ¶meters[0], &componentHandle, ""))<0) - return iResult; - - return 0; } From 63d2f58cce7ca052337d39a68eb7330d3546b235 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Wed, 14 May 2014 16:37:49 +0200 Subject: [PATCH 18/34] bugfix for handling input messages: initial size of array caused invalid pointers; error messages for missing output slot only if device does not produce data; simple treatment of either one input or output slot per device - better configuration options to come --- devices/aliceHLTwrapper/Component.cxx | 4 +++- devices/aliceHLTwrapper/WrapperDevice.cxx | 11 +++++++++-- devices/aliceHLTwrapper/aliceHLTWrapper.cxx | 21 +++++++++++++++------ 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/devices/aliceHLTwrapper/Component.cxx b/devices/aliceHLTwrapper/Component.cxx index 7fe1b943276d0..38cde98ec3a79 100644 --- a/devices/aliceHLTwrapper/Component.cxx +++ b/devices/aliceHLTwrapper/Component.cxx @@ -197,6 +197,7 @@ int Component::Process(vector& dataArray) if (dataArray.size()>0 && nofInputBlocks==0) { cerr << "warning: none of " << dataArray.size() << " input buffers recognized as valid input" << endl; } + dataArray.clear(); // add event type data block AliHLTComponentBlockData eventTypeBlock; @@ -249,7 +250,7 @@ int Component::Process(vector& dataArray) } while (iResult==ENOSPC && --nofTrials>0); // prepare output - dataArray.clear(); + if (outputBlockCnt>0) { if (mOutputMode==kOutputModeHOMER) { AliHLTHOMERWriter* pWriter=CreateHOMERFormat(pOutputBlocks, outputBlockCnt); if (pWriter) { @@ -297,6 +298,7 @@ int Component::Process(vector& dataArray) // invalid output mode cerr << "error ALICE::HLT::Component: invalid output mode " << mOutputMode << endl; } + } // cleanup // NOTE: don't cleanup mOutputBuffer as the data is going to be used outside the class diff --git a/devices/aliceHLTwrapper/WrapperDevice.cxx b/devices/aliceHLTwrapper/WrapperDevice.cxx index 0ab05cd1f580a..675480fc325fa 100644 --- a/devices/aliceHLTwrapper/WrapperDevice.cxx +++ b/devices/aliceHLTwrapper/WrapperDevice.cxx @@ -80,7 +80,7 @@ void WrapperDevice::Run() int errorCount=0; const int maxError=10; - vector inputMessages(fNumInputs); + vector inputMessages; while ( fState == RUNNING ) { // read input messages @@ -92,7 +92,7 @@ void WrapperDevice::Run() received = fPayloadInputs->at(i)->Receive(msg.get()); if (received) { inputMessages.push_back(msg.release()); - LOG(INFO) << "------ recieve Msg from " << i ; + //LOG(INFO) << "------ recieve Msg from " << i ; } } } @@ -111,6 +111,7 @@ void WrapperDevice::Run() } // build messages from output data + if (dataArray.size()>0) { auto_ptr msg(fTransportFactory->CreateMessage()); if (msg.get() && fPayloadOutputs!=NULL && fPayloadOutputs->size()>0) { vector::iterator data=dataArray.begin(); @@ -144,6 +145,7 @@ void WrapperDevice::Run() LOG(ERROR) << "can not get output message from framework"; iResult=-ENOMSG; } + } // cleanup for (vector::iterator mit=inputMessages.begin(); @@ -163,6 +165,7 @@ void WrapperDevice::Pause() /// inherited from FairMQDevice // nothing to do + FairMQDevice::Pause(); } void WrapperDevice::Shutdown() @@ -171,16 +174,20 @@ void WrapperDevice::Shutdown() int iResult=0; // TODO: shutdown component and delte instance + + FairMQDevice::Shutdown(); } void WrapperDevice::InitOutput() { /// inherited from FairMQDevice + FairMQDevice::InitOutput(); } void WrapperDevice::InitInput() { /// inherited from FairMQDevice + FairMQDevice::InitInput(); } diff --git a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx index ad5bc6580a2ca..16bed70292e0c 100644 --- a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx +++ b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx @@ -42,7 +42,7 @@ int main(int argc, char** argv) int numInputs=0; int numOutputs=0; std::string socketType; - int outputBufferSize=0; + int bufferSize=0; std::string connectMethod; std::string address; for (; iArg> numInputs; break; case 4: std::stringstream(arg) >> numOutputs; break; case 5: socketType=arg; break; - case 6: std::stringstream(arg) >> outputBufferSize; break; + case 6: std::stringstream(arg) >> bufferSize; break; case 7: connectMethod=arg; break; case 8: address=arg; break; default: @@ -89,10 +89,19 @@ int main(int argc, char** argv) device.SetProperty(FairMQDevice::NumInputs, numInputs); device.SetProperty(FairMQDevice::NumOutputs, numOutputs); device.ChangeState(FairMQDevice::INIT); - device.SetProperty(FairMQDevice::OutputSocketType, socketType.c_str()); - device.SetProperty(FairMQDevice::OutputSndBufSize, outputBufferSize, 0); - device.SetProperty(FairMQDevice::OutputMethod, connectMethod.c_str(), 0); - device.SetProperty(FairMQDevice::OutputAddress, address.c_str(), 0); + // TODO: this is for a quick test, extended configuration options + // necessary + if (numInputs>0) { + device.SetProperty(FairMQDevice::InputSocketType, socketType.c_str()); + device.SetProperty(FairMQDevice::InputSndBufSize, bufferSize, 0); + device.SetProperty(FairMQDevice::InputMethod, connectMethod.c_str(), 0); + device.SetProperty(FairMQDevice::InputAddress, address.c_str(), 0); + } else if (numOutputs>0) { + device.SetProperty(FairMQDevice::OutputSocketType, socketType.c_str()); + device.SetProperty(FairMQDevice::OutputSndBufSize, bufferSize, 0); + device.SetProperty(FairMQDevice::OutputMethod, connectMethod.c_str(), 0); + device.SetProperty(FairMQDevice::OutputAddress, address.c_str(), 0); + } device.ChangeState(FairMQDevice::SETOUTPUT); device.ChangeState(FairMQDevice::SETINPUT); From fb45ad7a17b94cbd0cf05255ac76a856eefd53e1 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Thu, 15 May 2014 21:58:44 +0200 Subject: [PATCH 19/34] more flexible argument scan, configurable number of both input and output sockets --- devices/aliceHLTwrapper/Component.cxx | 7 +- devices/aliceHLTwrapper/aliceHLTWrapper.cxx | 134 ++++++++++++++------ 2 files changed, 101 insertions(+), 40 deletions(-) diff --git a/devices/aliceHLTwrapper/Component.cxx b/devices/aliceHLTwrapper/Component.cxx index 38cde98ec3a79..dd83d4a9193a9 100644 --- a/devices/aliceHLTwrapper/Component.cxx +++ b/devices/aliceHLTwrapper/Component.cxx @@ -54,10 +54,10 @@ int Component::Init(int argc, char** argv) static struct option programOptions[] = { {"library", required_argument, 0, 'l'}, {"component", required_argument, 0, 'c'}, - {"parameter", optional_argument, 0, 'p'}, + {"parameter", required_argument, 0, 'p'}, {"run", required_argument, 0, 'r'}, - {"msgsize", optional_argument, 0, 's'}, - {"output-mode", optional_argument, 0, 'm'}, + {"msgsize", required_argument, 0, 's'}, + {"output-mode", required_argument, 0, 'm'}, {0, 0, 0, 0} }; @@ -78,6 +78,7 @@ int Component::Init(int argc, char** argv) // by the run no int runNumber=0; + optind=1; // indicate new start of scanning, especially when getop has been used in a higher layer already while ((c=getopt_long(argc, argv, "l:c:p:r:s:m:", programOptions, &iOption)) != -1) { switch (c) { case 'l': diff --git a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx index 16bed70292e0c..f410c14834850 100644 --- a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx +++ b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx @@ -30,51 +30,110 @@ using std::cout; using std::cerr; using std::stringstream; + struct SocketProperties_t { + std::string type; + int size; + std::string method; + std::string address; + }; + int main(int argc, char** argv) { int iResult=0; // parse options - int iArg=1; - bool bPrintUsage=true; + int iArg=0; + int iDeviceArg=-1; + bool bPrintUsage=false; std::string id; int numIoThreads=0; int numInputs=0; int numOutputs=0; - std::string socketType; - int bufferSize=0; - std::string connectMethod; - std::string address; - for (; iArg> numIoThreads; break; - case 3: std::stringstream(arg) >> numInputs; break; - case 4: std::stringstream(arg) >> numOutputs; break; - case 5: socketType=arg; break; - case 6: std::stringstream(arg) >> bufferSize; break; - case 7: connectMethod=arg; break; - case 8: address=arg; break; - default: - bPrintUsage=false; + + vector inputSockets; + vector outputSockets; + + static struct option programOptions[] = { + {"input", required_argument, 0, 'i'}, + {"output", required_argument, 0, 'o'}, + {0, 0, 0, 0} + }; + + enum socketkeyids{ + TYPE = 0, + SIZE, + METHOD, + ADDRESS, + lastsocketkey + }; + + const char *socketkeys[] = { + [TYPE] = "type", + [SIZE] = "size", + [METHOD] = "method", + [ADDRESS] = "address", + NULL + }; + + char c=0; + int iOption = 0; + opterr=false; + optind=1; // indicate new start of scanning + while ((c=getopt_long(argc, argv, "-i:o:", programOptions, &iOption)) != -1 + && bPrintUsage==false + && iDeviceArg<0) { + switch (c) { + case 'i': + case 'o': + { + char* subopts = optarg; + char* value=NULL; + int keynum=0; + SocketProperties_t prop; + while (subopts && *subopts!=0 && *subopts != ' ') { + char *saved = subopts; + switch(getsubopt(&subopts, (char **)socketkeys, &value)) { + case TYPE: keynum++; prop.type=value; break; + case SIZE: keynum++; std::stringstream(value) >> prop.size; break; + case METHOD: keynum++; prop.method=value; break; + case ADDRESS: keynum++; prop.address=value; break; + default: + keynum=0; + break; + } + } + if (bPrintUsage=(keynum> numIoThreads; break; + default: + bPrintUsage=true; + } break; + default: + cerr << "unknown option: '"<< c << "'" << endl; } } if (bPrintUsage) { - cout << "Usage : " << argv[0] << " ID numIoThreads numInputs numOutputs socketType bufferSize connectMethod address componentArguments" << endl; + cout << "Usage : " << argv[0] << " ID numIoThreads [--input|--output type=value,size=value,method=value,address=value] componentArguments" << endl; return 0; } vector deviceArgs; deviceArgs.push_back(argv[0]); - deviceArgs.insert(deviceArgs.end(), argv+iArg, argv+argc); + deviceArgs.insert(deviceArgs.end(), argv+iDeviceArg, argv+argc); ALICE::HLT::WrapperDevice device(deviceArgs.size(), &deviceArgs[0]); #ifdef NANOMSG @@ -83,24 +142,25 @@ int main(int argc, char** argv) FairMQTransportFactory* transportFactory = new FairMQTransportFactoryZMQ(); #endif + numInputs=inputSockets.size(); + numOutputs=outputSockets.size(); device.SetTransport(transportFactory); device.SetProperty(FairMQDevice::Id, id.c_str()); device.SetProperty(FairMQDevice::NumIoThreads, numIoThreads); device.SetProperty(FairMQDevice::NumInputs, numInputs); device.SetProperty(FairMQDevice::NumOutputs, numOutputs); device.ChangeState(FairMQDevice::INIT); - // TODO: this is for a quick test, extended configuration options - // necessary - if (numInputs>0) { - device.SetProperty(FairMQDevice::InputSocketType, socketType.c_str()); - device.SetProperty(FairMQDevice::InputSndBufSize, bufferSize, 0); - device.SetProperty(FairMQDevice::InputMethod, connectMethod.c_str(), 0); - device.SetProperty(FairMQDevice::InputAddress, address.c_str(), 0); - } else if (numOutputs>0) { - device.SetProperty(FairMQDevice::OutputSocketType, socketType.c_str()); - device.SetProperty(FairMQDevice::OutputSndBufSize, bufferSize, 0); - device.SetProperty(FairMQDevice::OutputMethod, connectMethod.c_str(), 0); - device.SetProperty(FairMQDevice::OutputAddress, address.c_str(), 0); + for (unsigned iInput=0; iInput Date: Tue, 20 May 2014 15:21:18 +0200 Subject: [PATCH 20/34] bugfix: missing input/output parameters handled and usage printout extended --- devices/aliceHLTwrapper/aliceHLTWrapper.cxx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx index f410c14834850..6e9ea476e9764 100644 --- a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx +++ b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx @@ -126,14 +126,21 @@ int main(int argc, char** argv) } } - if (bPrintUsage) { + numInputs=inputSockets.size(); + numOutputs=outputSockets.size(); + if (bPrintUsage || iDeviceArg<0 || + (numInputs==0 && numOutputs==0)) { + cout << endl << argv[0] << ":" << endl; + cout << " wrapper to run an ALICE HLT component in a FairRoot/ALFA device" << endl; cout << "Usage : " << argv[0] << " ID numIoThreads [--input|--output type=value,size=value,method=value,address=value] componentArguments" << endl; + cout << " Multiple slots can be defined by --input/--output options" << endl; return 0; } vector deviceArgs; deviceArgs.push_back(argv[0]); - deviceArgs.insert(deviceArgs.end(), argv+iDeviceArg, argv+argc); + if (iDeviceArg>0) + deviceArgs.insert(deviceArgs.end(), argv+iDeviceArg, argv+argc); ALICE::HLT::WrapperDevice device(deviceArgs.size(), &deviceArgs[0]); #ifdef NANOMSG @@ -142,8 +149,6 @@ int main(int argc, char** argv) FairMQTransportFactory* transportFactory = new FairMQTransportFactoryZMQ(); #endif - numInputs=inputSockets.size(); - numOutputs=outputSockets.size(); device.SetTransport(transportFactory); device.SetProperty(FairMQDevice::Id, id.c_str()); device.SetProperty(FairMQDevice::NumIoThreads, numIoThreads); From fe54e8cd9c11ddd0cec1c26dce75f45165f51815 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Thu, 22 May 2014 07:49:30 +0200 Subject: [PATCH 21/34] correcting compilation error on some compilers; throwing runtime_error exeption if component init failed in order to terminate in a controlled way, the program goes on otherwise and there is a crash downstream because FairMQDevice::Init was not called --- devices/aliceHLTwrapper/Component.cxx | 6 +++++- devices/aliceHLTwrapper/WrapperDevice.cxx | 8 +++----- devices/aliceHLTwrapper/aliceHLTWrapper.cxx | 8 ++++---- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/devices/aliceHLTwrapper/Component.cxx b/devices/aliceHLTwrapper/Component.cxx index dd83d4a9193a9..9c5a81bf640db 100644 --- a/devices/aliceHLTwrapper/Component.cxx +++ b/devices/aliceHLTwrapper/Component.cxx @@ -156,8 +156,12 @@ int Component::Init(int argc, char** argv) } // create component - if ((iResult=mpSystem->CreateComponent(componentId, NULL, parameters.size(), ¶meters[0], &mProcessor, ""))<0) + if ((iResult=mpSystem->CreateComponent(componentId, NULL, parameters.size(), ¶meters[0], &mProcessor, ""))<0) { + // the ALICE HLT external interface uses the following error definition + // 0 success + // >0 error number return iResult>0?-iResult:iResult; + } return iResult; } diff --git a/devices/aliceHLTwrapper/WrapperDevice.cxx b/devices/aliceHLTwrapper/WrapperDevice.cxx index 675480fc325fa..d33558189a8ab 100644 --- a/devices/aliceHLTwrapper/WrapperDevice.cxx +++ b/devices/aliceHLTwrapper/WrapperDevice.cxx @@ -49,11 +49,9 @@ void WrapperDevice::Init() if (!component.get()) return /*-ENOMEM*/; if ((iResult=component->Init(mArgv.size(), &mArgv[0]))<0) { - LOG(ERROR) << "component init failed with error code" << iResult; - // the ALICE HLT external interface uses the following error definition - // 0 success - // >0 error number - return /*-iResult*/; + LOG(ERROR) << "component init failed with error code " << iResult; + throw std::runtime_error("component init failed"); + return /*iResult*/; } mComponent=component.release(); diff --git a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx index 6e9ea476e9764..b28949f2cd7f1 100644 --- a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx +++ b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx @@ -68,10 +68,10 @@ int main(int argc, char** argv) }; const char *socketkeys[] = { - [TYPE] = "type", - [SIZE] = "size", - [METHOD] = "method", - [ADDRESS] = "address", + /*[TYPE] = */ "type", + /*[SIZE] = */ "size", + /*[METHOD] = */ "method", + /*[ADDRESS] = */ "address", NULL }; From a29cf67d48a1433184610e9f3d985c7d2c8c200f Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Thu, 22 May 2014 12:04:59 +0200 Subject: [PATCH 22/34] inluding the boost include and library directory; not yet clear why this is needed in the build of some systems, to be checked --- devices/aliceHLTwrapper/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/devices/aliceHLTwrapper/CMakeLists.txt b/devices/aliceHLTwrapper/CMakeLists.txt index 7157445c06751..4b11661236cb8 100644 --- a/devices/aliceHLTwrapper/CMakeLists.txt +++ b/devices/aliceHLTwrapper/CMakeLists.txt @@ -2,7 +2,7 @@ set(INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/fairmq ${CMAKE_SOURCE_DIR}/fairmq/zeromq ${ZMQ_INCLUDE_DIR} - # ${Boost_INCLUDE_DIR} + ${Boost_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/devices/aliceHLTwrapper ) @@ -13,7 +13,7 @@ include_directories(${INCLUDE_DIRECTORIES}) #configure_file( ${CMAKE_SOURCE_DIR}/example/flp2epn/run/startSomething.sh.in ${CMAKE_BINARY_DIR}/bin/startSomething.sh ) set(LINK_DIRECTORIES - # ${Boost_LIBRARY_DIRS} + ${Boost_LIBRARY_DIRS} ) link_directories(${LINK_DIRECTORIES}) From 05ceed70610fc493cb1d1e506bde28605cca4eaf Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Fri, 23 May 2014 15:31:03 +0200 Subject: [PATCH 23/34] adding tool macros/scripts --- .../aliceHLTwrapper/createLaunchCommands.sh | 31 ++++++++++ .../macros/hltConfigurations.C | 61 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 devices/aliceHLTwrapper/createLaunchCommands.sh create mode 100644 devices/aliceHLTwrapper/macros/hltConfigurations.C diff --git a/devices/aliceHLTwrapper/createLaunchCommands.sh b/devices/aliceHLTwrapper/createLaunchCommands.sh new file mode 100644 index 0000000000000..84b843a72f82d --- /dev/null +++ b/devices/aliceHLTwrapper/createLaunchCommands.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# very simple helper script to create the commands for starting several processes + +minSlice=0 +maxSlice=0 +minPart=0 +maxPart=5 +runNo=167808 +msgSize=1000 + +firstSocketNo=45000 +let socketNo=firstSocketNo +trackerInputSockets= + +for ((slice=minSlice; slice<=maxSlice; slice++)); do + for ((part=minPart; part<=maxPart; part++)); do + spec=`printf 0x%02x%02x%02x%02x $slice $slice $part $part` + command="aliceHLTWrapper ClusterPublisher_$spec 1 --output type=push,size=$msgSize,method=connect,address=tcp://localhost:$socketNo --library libAliHLTUtil.so --component FilePublisher --run 167808 --parameter '-datafilelist emulated-tpc-clusters_$spec.txt'" + echo "xterm -e $command &" + trackerInputSockets=`echo "$trackerInputSockets $socketNo"` + let socketNo++ + done +done + +command="aliceHLTWrapper Tracker 1 " +for socket in $trackerInputSockets; do + command=`echo "$command --input type=pull,size=$msgSize,method=bind,address=tcp://*:$socket"` +done +command=`echo "$command --library libAliHLTTPC.so --component TPCCATracker --run $runNo --parameter '-GlobalTracking'"` +echo "xterm -e $command &" diff --git a/devices/aliceHLTwrapper/macros/hltConfigurations.C b/devices/aliceHLTwrapper/macros/hltConfigurations.C new file mode 100644 index 0000000000000..715890366fe59 --- /dev/null +++ b/devices/aliceHLTwrapper/macros/hltConfigurations.C @@ -0,0 +1,61 @@ +//**************************************************************************** +//* This file 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 3 of the License, or * +//* (at your option) any later version. * +//* * +//* Primary Authors: Matthias Richter * +//* * +//* The authors make no claims about the suitability of this software for * +//* any purpose. It is provided "as is" without express or implied warranty. * +//**************************************************************************** + +// @file hltConfigurations.C +// @author Matthias Richter +// @since 2014-05-20 +// @brief Various helper configurations for the ALICE HLT + +/** + * Usage: aliroot -b -q -l \ + * hltConfigurations.C \ + * recraw-local.C'("file", "cdb", minEvent, maxEvent, modules)' + * + * Macro defines the following configurations: + * - cluster-collection: emulation of TPC HLT clusters from TPC raw data + */ +void hltConfigurations() +{ + // init the HLT system + AliHLTSystem* pHLT=AliHLTPluginBase::GetInstance(); + + /////////////////////////////////////////////////////////////////////////////////////////// + // + // list of configurations + // + /////////////////////////////////////////////////////////////////////////////////////////// + int iMinSlice=0; + int iMaxSlice=35; + int iMinPart=0; + int iMaxPart=5; + + TString collectionInput; + for (int slice=iMinSlice; slice<=iMaxSlice; slice++) { + for (int part=iMinPart; part<=iMaxPart; part++) { + TString arg; + TString filterid; + filterid.Form("TPC-CLFilter_%02d_%d", slice, part); + arg.Form("-dataspec 0x%02x%02x%02x%02x", slice, slice, part, part); + AliHLTConfiguration clusterfilter(filterid.Data(), "BlockFilter","TPC-ClusterTransformation", arg.Data()); + + TString cid; + cid.Form("TPC-CLWriter_%02d_%d", slice, part); + arg=("-directory emulated-tpc-clusters -subdir -specfmt=_0x%08x -blocknofmt="); + arg+=Form(" -publisher-conf emulated-tpc-clusters_0x%02x%02x%02x%02x.txt", slice, slice, part, part); + AliHLTConfiguration clusterwriter(cid.Data(), "FileWriter", filterid.Data(), arg.Data()); + + if (collectionInput.Length()>0) collectionInput+=" "; + collectionInput+=cid; + } + } + liHLTConfiguration clustercollection("cluster-collection", "BlockFilter", collectionInput.Data(), ""); +} From 8642b26678d492e5ba161048c4289f61169f9d97 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Fri, 23 May 2014 17:28:27 +0200 Subject: [PATCH 24/34] adding README; changing file attributes of createLaunchCommands.sh --- devices/aliceHLTwrapper/README | 92 +++++++++++++++++++ .../aliceHLTwrapper/createLaunchCommands.sh | 0 2 files changed, 92 insertions(+) create mode 100644 devices/aliceHLTwrapper/README mode change 100644 => 100755 devices/aliceHLTwrapper/createLaunchCommands.sh diff --git a/devices/aliceHLTwrapper/README b/devices/aliceHLTwrapper/README new file mode 100644 index 0000000000000..8d1460d61fd3a --- /dev/null +++ b/devices/aliceHLTwrapper/README @@ -0,0 +1,92 @@ + +1) Software packages +==================== +a) install all external packages needed for FairRoot +---------------------------------------------------- +installation script + git clone https://github.com/FairRootGroup/FairSoft + +b) FairRoot +----------- + export ALFA_INSTALL_DIR= + git clone https://github.com/FairRootGroup/FairRoot + cd FairRoot + mkdir build + cd build + cmake -D$ALFA_INSTALL_DIR -DCMAKE_BUILD_TYPE=Debug .. + make install + +c) install AliRoot +------------------ +add library directory to LD_LIBRARY_PATH + +d) set up development clone +--------------------------- + git remote add --no-tags matthias gitolite@git.uio.no:u/mrichter/FairRoot + git remote update matthias + git branch --track alicehlt remotes/matthias/alicehlt + git checkout alicehlt # code can be found in devices/aliceHLTwrapper + make install # in the build directory + + +2) Environment +============== +AliRoot, FairRoot and external packages need to be set up, in particular +library directories need to be added to LD LIBRARY PATH, bin folder to +PATH, e.g. + + export SIMPATH= + export ALFA_INSTALL_DIR= + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$SIMPATH/lib + export PATH=$PATH:$SIMPATH/bin + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ALFA_INSTALL_DIR/lib + export PATH=$PATH:$ALFA_INSTALL_DIR/bin + +Path to the OCDB copy used for running the HLT components + + export ALIHLT_HCDBDIR=local://./OCDB + +3) Test Data +============ +Generate binary files of HLT TPC clusters to be used by FilePublishers of a simple processing topology, +e.g. 6 publishers (one full slice/sector of the TPC) to one tracker instance +Using: +macro example/alice/hlt/macros/hltConfigurations.C to define a custom chain +macro $ALICE_ROOT/HLT/exa/recraw-local.C to run the HLT chain embedded to AliRoot reconstruction + + ln -s $ALICE_ROOT/HLT/exa/recraw-local.C + ln -s $ALICE_ROOT/HLT/exa/EnableHLTInGRP.C + aliroot -b -q -l hltConfigurations.C recraw-local.C’("raw.root", "raw://", 0, 0, "HLT TPC", "loglevel=0x79 chains=cluster-collection", "local://./OCDB")’ + aliroot -b -q -l EnableHLTInGRP.C’(167808, "local://./OCDB", "local://./OCDB")’ + rm galice.root QA.root + aliroot -b -q -l hltConfigurations.C recraw-local.C’("raw.root", "local://OCDB", -1, -1, "HLT", "loglevel=0x79 chains=cluster-collection")’ 2>&1 | tee cluster-collection.log + +Runs HLT TPC cluster emulation, binary files stored in emulated-tpc-clusters +configuration files emulated-tpc-clusters *.txt for FilePublisher components + +Be aware that there might be crashes of the AliRoot framework after the last event has been +processed. That does not effect the generation of the test data. + +4) Running the Wrapper +====================== +Three groups of parameters: +a) device specific arguments: id and number of i/o threads + +b) flexible input and output slot configuration, multiple arguments possible + --output|--input type=,size=,method=,address= + +c) HLT component arguments: library, component id, parameters, run number + --library --component --run + +NOTE: have to be in that fixed sequence!!! + +Example: + aliceHLTWrapper ClusterPublisher_0x00000000 1 \ + --input type=pull,size=1000,method=bind,address=tcp://*:45000 \ + --output type=push,size=1000,method=connect,address=tcp://localhost:45001 \ + --library libAliHLTUtil.so --component FilePublisher --run 167808 \ + --parameter ’-datafilelist emulated-tpc-clusters_0x00000000.txt’ + +Complex topology: +Helper script to create the commands to launch multiple processes + createLaunchCommands.sh diff --git a/devices/aliceHLTwrapper/createLaunchCommands.sh b/devices/aliceHLTwrapper/createLaunchCommands.sh old mode 100644 new mode 100755 From 04dedc388bc42bf53499458f0efddf7f6f716367 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Tue, 22 Jul 2014 20:55:35 +0200 Subject: [PATCH 25/34] typo corrected, first capital letter of a class declaration was missing --- devices/aliceHLTwrapper/macros/hltConfigurations.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devices/aliceHLTwrapper/macros/hltConfigurations.C b/devices/aliceHLTwrapper/macros/hltConfigurations.C index 715890366fe59..440947c279d72 100644 --- a/devices/aliceHLTwrapper/macros/hltConfigurations.C +++ b/devices/aliceHLTwrapper/macros/hltConfigurations.C @@ -57,5 +57,5 @@ void hltConfigurations() collectionInput+=cid; } } - liHLTConfiguration clustercollection("cluster-collection", "BlockFilter", collectionInput.Data(), ""); + AliHLTConfiguration clustercollection("cluster-collection", "BlockFilter", collectionInput.Data(), ""); } From 2cde4630dae5e6d20276801fc957547221a37315 Mon Sep 17 00:00:00 2001 From: Mohammad Al-Turany Date: Thu, 14 Aug 2014 12:57:25 +0200 Subject: [PATCH 26/34] chenges needed to run on MAC OS --- devices/aliceHLTwrapper/SystemInterface.cxx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/devices/aliceHLTwrapper/SystemInterface.cxx b/devices/aliceHLTwrapper/SystemInterface.cxx index 89bb914d64ea6..e9e8ab0c0df21 100644 --- a/devices/aliceHLTwrapper/SystemInterface.cxx +++ b/devices/aliceHLTwrapper/SystemInterface.cxx @@ -85,12 +85,19 @@ int SystemInterface::InitSystem(unsigned long runNo) /// init the system: load interface libraries and read function pointers int iResult=0; + string libraryPath=ALIHLTANALYSIS_INTERFACE_LIBRARY; void* libHandle=dlopen(libraryPath.c_str(), RTLD_NOW); if (!libHandle) { cerr << "error: can not load library " << libraryPath.c_str() << endl; - return -ELIBACC; +#ifdef __APPLE__ + int returnvalue =-EFTYPE; +#else + int returnvalue =-ELIBACC; +#endif + + return returnvalue; } AliHLTAnalysisFctGetInterfaceCall fctGetSystemCall=(AliHLTAnalysisFctGetInterfaceCall)dlsym(libHandle, ALIHLTANALYSIS_FCT_GETINTERFACECALL); From 991add180c00e75b85a8453044a9238c9f0637ed Mon Sep 17 00:00:00 2001 From: Alexey Rybalchenko Date: Tue, 26 Aug 2014 23:15:17 +0200 Subject: [PATCH 27/34] blind attempt to fix false termination issue --- devices/aliceHLTwrapper/WrapperDevice.cxx | 6 ++++++ devices/aliceHLTwrapper/aliceHLTWrapper.cxx | 7 +++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/devices/aliceHLTwrapper/WrapperDevice.cxx b/devices/aliceHLTwrapper/WrapperDevice.cxx index d33558189a8ab..47d0757751b63 100644 --- a/devices/aliceHLTwrapper/WrapperDevice.cxx +++ b/devices/aliceHLTwrapper/WrapperDevice.cxx @@ -156,6 +156,12 @@ void WrapperDevice::Run() rateLogger.interrupt(); rateLogger.join(); + + Shutdown(); + + boost::lock_guard lock(fRunningMutex); + fRunningFinished = true; + fRunningCondition.notify_one(); } void WrapperDevice::Pause() diff --git a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx index b28949f2cd7f1..6310ab032e0d5 100644 --- a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx +++ b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx @@ -172,8 +172,11 @@ int main(int argc, char** argv) device.ChangeState(FairMQDevice::SETINPUT); device.ChangeState(FairMQDevice::RUN); - char ch; - cin.get(ch); + boost::unique_lock lock(device.fRunningMutex); + while (!device.fRunningFinished) + { + device.fRunningCondition.wait(lock); + } device.ChangeState(FairMQDevice::STOP); device.ChangeState(FairMQDevice::END); From 6239c30ee9f1c7c3b00c06b8782dc1a355b3cff8 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Mon, 22 Sep 2014 07:48:31 +0200 Subject: [PATCH 28/34] bugfix: providing an event ID to the component, simple counter at the moment, to be adjusted to the appropriate format if available --- devices/aliceHLTwrapper/Component.cxx | 8 ++++++++ devices/aliceHLTwrapper/Component.h | 1 + 2 files changed, 9 insertions(+) diff --git a/devices/aliceHLTwrapper/Component.cxx b/devices/aliceHLTwrapper/Component.cxx index 9c5a81bf640db..77da45d4cddac 100644 --- a/devices/aliceHLTwrapper/Component.cxx +++ b/devices/aliceHLTwrapper/Component.cxx @@ -39,6 +39,7 @@ Component::Component() , mpWriter(NULL) , mProcessor(kEmptyHLTComponentHandle) , mOutputMode(kOutputModeSequence) + , mEventCount(-1) { } @@ -163,6 +164,8 @@ int Component::Init(int argc, char** argv) return iResult>0?-iResult:iResult; } + mEventCount=0; + return iResult; } @@ -176,6 +179,11 @@ int Component::Process(vector& dataArray) AliHLTComponentEventData evtData; memset(&evtData, 0, sizeof(evtData)); evtData.fStructSize=sizeof(evtData); + if (mEventCount>=0) { + // very simple approach to provide an event ID + // TODO: adjust to the relevant format if available + evtData.fEventID=mEventCount++; + } AliHLTComponentTriggerData trigData; memset(&trigData, 0, sizeof(trigData)); diff --git a/devices/aliceHLTwrapper/Component.h b/devices/aliceHLTwrapper/Component.h index af93931508c69..37c08f88fc59b 100644 --- a/devices/aliceHLTwrapper/Component.h +++ b/devices/aliceHLTwrapper/Component.h @@ -90,6 +90,7 @@ namespace ALICE AliHLTHOMERWriter* mpWriter; AliHLTComponentHandle mProcessor; int mOutputMode; + int mEventCount; }; } // namespace hlt From bb4f9773276def7b508dec75a8a9c7bf2dcafac3 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Tue, 23 Sep 2014 11:02:21 +0200 Subject: [PATCH 29/34] implemented synchronized input, statistics and options for polling and logging period --- devices/aliceHLTwrapper/WrapperDevice.cxx | 133 +++++++++++++++++++++- devices/aliceHLTwrapper/WrapperDevice.h | 37 +++++- 2 files changed, 163 insertions(+), 7 deletions(-) diff --git a/devices/aliceHLTwrapper/WrapperDevice.cxx b/devices/aliceHLTwrapper/WrapperDevice.cxx index 47d0757751b63..ec893b74c810f 100644 --- a/devices/aliceHLTwrapper/WrapperDevice.cxx +++ b/devices/aliceHLTwrapper/WrapperDevice.cxx @@ -29,9 +29,30 @@ #include using namespace ALICE::HLT; +// the chrono lib needs C++11 +#if __cplusplus < 201103L +# warning statistics measurement for WrapperDevice disabled: need C++11 standard +#else +# define USE_CHRONO +#endif +#ifdef USE_CHRONO +#include +using std::chrono::system_clock; +typedef std::chrono::milliseconds TimeScale; +#endif //USE_CHRONO + WrapperDevice::WrapperDevice(int argc, char** argv) : mComponent(NULL) , mArgv() + , mPollingPeriod(10) + , mSkipProcessing(0) + , mLastCalcTime(-1) + , mLastSampleTime(-1) + , mMinTimeBetweenSample(-1) + , mMaxTimeBetweenSample(-1) + , mTotalReadCycles(-1) + , mMaxReadCycles(-1) + , mNSamples(-1) { mArgv.insert(mArgv.end(), argv, argv+argc); } @@ -55,6 +76,14 @@ void WrapperDevice::Init() } mComponent=component.release(); + mLastCalcTime=-1; + mLastSampleTime=-1; + mMinTimeBetweenSample=-1; + mMaxTimeBetweenSample=-1; + mTotalReadCycles=0; + mMaxReadCycles=-1; + mNSamples=0; + FairMQDevice::Init(); } @@ -63,6 +92,9 @@ void WrapperDevice::Run() /// inherited from FairMQDevice int iResult=0; +#ifdef USE_CHRONO + static system_clock::time_point refTime = system_clock::now(); +#endif //USE_CHRONO boost::thread rateLogger(boost::bind(&FairMQDevice::LogSocketRates, this)); FairMQPoller* poller = fTransportFactory->CreatePoller(*fPayloadInputs); @@ -78,23 +110,70 @@ void WrapperDevice::Run() int errorCount=0; const int maxError=10; - vector inputMessages; + vector inputMessages(fNumInputs, NULL); + int nReadCycles=0; while ( fState == RUNNING ) { // read input messages - poller->Poll(100); + poller->Poll(mPollingPeriod); + int inputsReceived=0; + bool receivedAtLeastOneMessage=false; for(int i = 0; i < fNumInputs; i++) { + if (inputMessages[i]!=NULL) { + inputsReceived++; + continue; + } received = false; if (poller->CheckInput(i)){ auto_ptr msg(fTransportFactory->CreateMessage()); received = fPayloadInputs->at(i)->Receive(msg.get()); if (received) { - inputMessages.push_back(msg.release()); + receivedAtLeastOneMessage=true; + inputMessages[i]=msg.release(); + inputsReceived++; //LOG(INFO) << "------ recieve Msg from " << i ; } } } + if (receivedAtLeastOneMessage) nReadCycles++; + if (inputsReceived1) { + // LOG(INFO) << "------ recieved complete Msg from " << fNumInputs << " input(s) after " << nReadCycles << " read cycles" ; + // } + nReadCycles=0; +#ifdef USE_CHRONO + auto duration = std::chrono::duration_cast< TimeScale>(std::chrono::system_clock::now() - refTime); + + if (mLastSampleTime>=0) { + int sampleTimeDiff=duration.count()-mLastSampleTime; + if (mMinTimeBetweenSample < 0 || sampleTimeDiffmMaxTimeBetweenSample) + mMaxTimeBetweenSample=sampleTimeDiff; + } + mLastSampleTime=duration.count(); + if (duration.count()-mLastCalcTime>fLogIntervalInMs) { + LOG(INFO) << "------ processed " << mNSamples << " sample(s) "; + if (mNSamples>0) { + LOG(INFO) << "------ min " << mMinTimeBetweenSample << "ms, max " << mMaxTimeBetweenSample << "ms avrg " << (duration.count()-mLastCalcTime)/mNSamples << "ms "; + LOG(INFO) << "------ avrg number of read cycles " << mTotalReadCycles/mNSamples << " max number of read cycles " << mMaxReadCycles; + } + mNSamples=0; + mTotalReadCycles=0; + mMinTimeBetweenSample=-1; + mMaxTimeBetweenSample=-1; + mMaxReadCycles=-1; + mLastCalcTime=duration.count(); + } +#endif //USE_CHRONO + if (!mSkipProcessing) { // prepare input from messages vector dataArray; for (vector::iterator msg=inputMessages.begin(); @@ -144,12 +223,14 @@ void WrapperDevice::Run() iResult=-ENOMSG; } } + } // cleanup for (vector::iterator mit=inputMessages.begin(); - mit!=inputMessages.end(); mit++) + mit!=inputMessages.end(); mit++) { delete *mit; - inputMessages.clear(); + *mit=NULL; + } } delete poller; @@ -195,3 +276,45 @@ void WrapperDevice::InitInput() FairMQDevice::InitInput(); } + +void WrapperDevice::SetProperty(const int key, const string& value, const int slot) +{ + /// inherited from FairMQDevice + /// handle device specific properties and forward to FairMQDevice::SetProperty + return FairMQDevice::SetProperty(key, value, slot); +} + +string WrapperDevice::GetProperty(const int key, const string& default_, const int slot) +{ + /// inherited from FairMQDevice + /// handle device specific properties and forward to FairMQDevice::GetProperty + return FairMQDevice::GetProperty(key, default_, slot); +} + +void WrapperDevice::SetProperty(const int key, const int value, const int slot) +{ + /// inherited from FairMQDevice + /// handle device specific properties and forward to FairMQDevice::SetProperty + switch (key) { + case PollingPeriod: + mPollingPeriod=value; + return; + case SkipProcessing: + mSkipProcessing=value; + return; + } + return FairMQDevice::SetProperty(key, value, slot); +} + +int WrapperDevice::GetProperty(const int key, const int default_, const int slot) +{ + /// inherited from FairMQDevice + /// handle device specific properties and forward to FairMQDevice::GetProperty + switch (key) { + case PollingPeriod: + return mPollingPeriod; + case SkipProcessing: + return mSkipProcessing; + } + return FairMQDevice::GetProperty(key, default_, slot); +} diff --git a/devices/aliceHLTwrapper/WrapperDevice.h b/devices/aliceHLTwrapper/WrapperDevice.h index c03314bb036c0..ddca059357f34 100644 --- a/devices/aliceHLTwrapper/WrapperDevice.h +++ b/devices/aliceHLTwrapper/WrapperDevice.h @@ -50,6 +50,29 @@ namespace ALICE virtual void InitOutput(); /// inherited from FairMQDevice virtual void InitInput(); + /// inherited from FairMQDevice + /// handle device specific properties and forward to FairMQDevice::SetProperty + virtual void SetProperty(const int key, const string& value, const int slot = 0); + /// inherited from FairMQDevice + /// handle device specific properties and forward to FairMQDevice::GetProperty + virtual string GetProperty(const int key, const string& default_ = "", const int slot = 0); + /// inherited from FairMQDevice + /// handle device specific properties and forward to FairMQDevice::SetProperty + virtual void SetProperty(const int key, const int value, const int slot = 0); + /// inherited from FairMQDevice + /// handle device specific properties and forward to FairMQDevice::GetProperty + virtual int GetProperty(const int key, const int default_ = 0, const int slot = 0); + + ///////////////////////////////////////////////////////////////// + // device property identifier + enum + { + Id = FairMQDevice::Last, + PollingPeriod, + SkipProcessing, + Last + }; + protected: private: @@ -58,8 +81,18 @@ namespace ALICE // assignment operator prohibited WrapperDevice& operator=(const WrapperDevice&); - Component* mComponent; - vector mArgv; + Component* mComponent; // component instance + vector mArgv; // array of arguments for the component + + int mPollingPeriod; // period of polling on input sockets in ms + int mSkipProcessing; // skip component processing + int mLastCalcTime; // start time of current statistic period + int mLastSampleTime; // time of last data sample + int mMinTimeBetweenSample; // min time between data samples in statistic period + int mMaxTimeBetweenSample; // max time between data samples in statistic period + int mTotalReadCycles; // tot number of read cycles in statistic period + int mMaxReadCycles; // max number of read cycles in statistic period + int mNSamples; // number of samples in statistic period }; } // namespace hlt From 85945db66752b6e6b806258ba55d931dd09c5b2b Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Tue, 23 Sep 2014 11:35:50 +0200 Subject: [PATCH 30/34] adding options factory-type, verbosity, loginterval, poll-period, n --- devices/aliceHLTwrapper/aliceHLTWrapper.cxx | 83 ++++++++++++++++++--- 1 file changed, 71 insertions(+), 12 deletions(-) diff --git a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx index 6310ab032e0d5..0245843a6b7e3 100644 --- a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx +++ b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx @@ -22,9 +22,8 @@ #include #ifdef NANOMSG #include "FairMQTransportFactoryNN.h" -#else - #include "FairMQTransportFactoryZMQ.h" #endif +#include "FairMQTransportFactoryZMQ.h" using std::cout; using std::cerr; @@ -52,10 +51,20 @@ int main(int argc, char** argv) vector inputSockets; vector outputSockets; + const char* factoryType="zmq"; + int verbosity=-1; + int deviceLogInterval=10000; + int pollingPeriod=-1; + int skipProcessing=0; static struct option programOptions[] = { - {"input", required_argument, 0, 'i'}, - {"output", required_argument, 0, 'o'}, + {"input", required_argument, 0, 'i'}, // input socket + {"output", required_argument, 0, 'o'}, // output socket + {"factory-type",required_argument, 0, 't'}, // type of the factory "zmq", "nanomsg" + {"verbosity", required_argument, 0, 'v'}, // verbosity + {"loginterval", required_argument, 0, 'l'}, // logging interval + {"poll-period", required_argument, 0, 'p'}, // polling period of the device in ms + {"dry-run", required_argument, 0, 'n'}, // skip the component processing {0, 0, 0, 0} }; @@ -79,7 +88,7 @@ int main(int argc, char** argv) int iOption = 0; opterr=false; optind=1; // indicate new start of scanning - while ((c=getopt_long(argc, argv, "-i:o:", programOptions, &iOption)) != -1 + while ((c=getopt_long(argc, argv, "-i:o:t:v:l:p:q:", programOptions, &iOption)) != -1 && bPrintUsage==false && iDeviceArg<0) { switch (c) { @@ -110,10 +119,29 @@ int main(int argc, char** argv) } } break; + case 't': + factoryType=optarg; + break; + case 'v': + std::stringstream(optarg) >> std::hex >> verbosity; + break; + case 'l': + std::stringstream(optarg) >> deviceLogInterval; + break; + case 'p': + std::stringstream(optarg) >> pollingPeriod; + break; + case 'n': + std::stringstream(optarg) >> skipProcessing; + break; case '?': // all remaining arguments passed to the device instance iDeviceArg=optind-1; break; case '\1': // the first required arguments are without hyphens and in fixed order + // special treatment of elements not defined in the option string is + // indicated by the leading hyphen in the option string, that makes + // getopt to return value '1' for any of those elements allowing + // for a custom handling, matches only elemments not starting with a hyphen switch (++iArg) { case 1: id=optarg; break; case 2: std::stringstream(optarg) >> numIoThreads; break; @@ -132,28 +160,59 @@ int main(int argc, char** argv) (numInputs==0 && numOutputs==0)) { cout << endl << argv[0] << ":" << endl; cout << " wrapper to run an ALICE HLT component in a FairRoot/ALFA device" << endl; - cout << "Usage : " << argv[0] << " ID numIoThreads [--input|--output type=value,size=value,method=value,address=value] componentArguments" << endl; + cout << "Usage : " << argv[0] << " ID numIoThreads [--factory type] [--input|--output type=value,size=value,method=value,address=value] componentArguments" << endl; + cout << " The first two arguments are in fixed order, followed by optional arguments: " << endl; + cout << " --factory-type,-t nanomsg|zmq" << endl; + cout << " --poll-period,-p period_in_ms" << endl; + cout << " --loginterval,-l period_in_ms" << endl; + cout << " --verbosity,-v 0xhexval verbosity level" << endl; + cout << " --dry-run,-n skip the component processing" << endl; cout << " Multiple slots can be defined by --input/--output options" << endl; + cout << " HLT component arguments at the end of the list" << endl; + cout << " --library,-l componentLibrary" << endl; + cout << " --component,-c componentId" << endl; + cout << " --parameter,-p parameter" << endl; + cout << " --run,-r runNo" << endl; + return 0; } + FairMQTransportFactory* transportFactory=NULL; + if (strcmp(factoryType, "nanomsg")==0) { +#ifdef NANOMSG + transportFactory = new FairMQTransportFactoryNN(); +#else + cerr << "can not create factory for NANOMSG: not enabled in build" << endl; + return -ENODEV; +#endif + } else if (strcmp(factoryType, "zmq")==0) { + transportFactory = new FairMQTransportFactoryZMQ(); + } else { + cerr << "invalid factory type: " << factoryType << endl; + return -ENODEV; + } + + if (verbosity>=0) { + std::ios::fmtflags oldflags = std::cout.flags(); + std::cout << "Verbosity: 0x" << std::setfill('0') << std::setw(2) << std::hex << verbosity << std::endl; + std::cout.flags(oldflags); + // TODO: verbosity options to be propagated to device and component + } + vector deviceArgs; deviceArgs.push_back(argv[0]); if (iDeviceArg>0) deviceArgs.insert(deviceArgs.end(), argv+iDeviceArg, argv+argc); ALICE::HLT::WrapperDevice device(deviceArgs.size(), &deviceArgs[0]); -#ifdef NANOMSG - FairMQTransportFactory* transportFactory = new FairMQTransportFactoryNN(); -#else - FairMQTransportFactory* transportFactory = new FairMQTransportFactoryZMQ(); -#endif - device.SetTransport(transportFactory); device.SetProperty(FairMQDevice::Id, id.c_str()); device.SetProperty(FairMQDevice::NumIoThreads, numIoThreads); device.SetProperty(FairMQDevice::NumInputs, numInputs); device.SetProperty(FairMQDevice::NumOutputs, numOutputs); + device.SetProperty(FairMQDevice::LogIntervalInMs, deviceLogInterval); + if (pollingPeriod>0) device.SetProperty(ALICE::HLT::WrapperDevice::PollingPeriod, pollingPeriod); + if (skipProcessing) device.SetProperty(ALICE::HLT::WrapperDevice::SkipProcessing, skipProcessing); device.ChangeState(FairMQDevice::INIT); for (unsigned iInput=0; iInput Date: Tue, 23 Sep 2014 13:37:50 +0200 Subject: [PATCH 31/34] correctly implemented the --dry-run option with no argument; building getopt optionstring directly from the definitions of options --- devices/aliceHLTwrapper/aliceHLTWrapper.cxx | 26 ++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx index 0245843a6b7e3..661d86f44ab9e 100644 --- a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx +++ b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx @@ -64,7 +64,7 @@ int main(int argc, char** argv) {"verbosity", required_argument, 0, 'v'}, // verbosity {"loginterval", required_argument, 0, 'l'}, // logging interval {"poll-period", required_argument, 0, 'p'}, // polling period of the device in ms - {"dry-run", required_argument, 0, 'n'}, // skip the component processing + {"dry-run", no_argument , 0, 'n'}, // skip the component processing {0, 0, 0, 0} }; @@ -88,7 +88,27 @@ int main(int argc, char** argv) int iOption = 0; opterr=false; optind=1; // indicate new start of scanning - while ((c=getopt_long(argc, argv, "-i:o:t:v:l:p:q:", programOptions, &iOption)) != -1 + + // build the string from the option definition + // hyphen in the beginning indicates custom handling for non-option elements + // a colon after the option indicates a required argument to that option + // two colons after the option indicate an optional argument + std::string optstring="-"; + for (struct option* programOption=programOptions; + programOption!=NULL && programOption->name!=NULL; + programOption++) { + if (programOption->flag==NULL) { + // programOption->val uniquely identifies particular long option + optstring+=((char)programOption->val); + if (programOption->has_arg==required_argument) + optstring+=":"; // one colon to indicate required argument + if (programOption->has_arg==optional_argument) + optstring+="::"; // two colons to indicate optional argument + } else { + throw std::runtime_error("handling of program option flag is not yet implemented, please check option definitions"); + } + } + while ((c=getopt_long(argc, argv, optstring.c_str(), programOptions, &iOption)) != -1 && bPrintUsage==false && iDeviceArg<0) { switch (c) { @@ -132,7 +152,7 @@ int main(int argc, char** argv) std::stringstream(optarg) >> pollingPeriod; break; case 'n': - std::stringstream(optarg) >> skipProcessing; + skipProcessing=1; break; case '?': // all remaining arguments passed to the device instance iDeviceArg=optind-1; From 322ef430d57b86e007faa9721a25f3ac9c3fdfcf Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Thu, 25 Sep 2014 07:24:59 +0200 Subject: [PATCH 32/34] added signal handling for proper termination --- devices/aliceHLTwrapper/aliceHLTWrapper.cxx | 45 +++++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx index 661d86f44ab9e..41744c05a7957 100644 --- a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx +++ b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx @@ -17,6 +17,7 @@ #include "WrapperDevice.h" #include +#include #include #include #include @@ -36,6 +37,33 @@ using std::stringstream; std::string address; }; +FairMQDevice* gDevice=NULL; +static void s_signal_handler (int signal) +{ + cout << endl << "Caught signal " << signal << endl; + + if (gDevice) { + gDevice->ChangeState(FairMQDevice::STOP); + gDevice->ChangeState(FairMQDevice::END); + cout << "Shutdown complete. Bye!" << endl; + } else { + cerr << "No device to shut down, ignoring signal ..." << endl; + } + + exit(1); +} + +static void s_catch_signals (void) +{ + struct sigaction action; + action.sa_handler = s_signal_handler; + action.sa_flags = 0; + sigemptyset(&action.sa_mask); + sigaction(SIGINT, &action, NULL); + sigaction(SIGQUIT, &action, NULL); + sigaction(SIGTERM, &action, NULL); +} + int main(int argc, char** argv) { int iResult=0; @@ -223,7 +251,16 @@ int main(int argc, char** argv) deviceArgs.push_back(argv[0]); if (iDeviceArg>0) deviceArgs.insert(deviceArgs.end(), argv+iDeviceArg, argv+argc); - ALICE::HLT::WrapperDevice device(deviceArgs.size(), &deviceArgs[0]); + + gDevice=new ALICE::HLT::WrapperDevice(deviceArgs.size(), &deviceArgs[0]); + if (!gDevice) { + cerr << "failed to create device" << endl; + return -ENODEV; + } + s_catch_signals(); + + { // scope for the device reference variable + FairMQDevice& device=*gDevice; device.SetTransport(transportFactory); device.SetProperty(FairMQDevice::Id, id.c_str()); @@ -256,9 +293,11 @@ int main(int argc, char** argv) { device.fRunningCondition.wait(lock); } + } // scope for the device reference variable - device.ChangeState(FairMQDevice::STOP); - device.ChangeState(FairMQDevice::END); + FairMQDevice* almostdead=gDevice; + gDevice=NULL; + delete almostdead; return iResult; } From 66f8d1555ce7e0a29604123bf9752217df46ba3c Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Wed, 1 Oct 2014 08:28:02 +0200 Subject: [PATCH 33/34] setting high-water-mark for send and receive buffers of the socket to the same value from the command line argument --- devices/aliceHLTwrapper/aliceHLTWrapper.cxx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx index 41744c05a7957..888479d7ee663 100644 --- a/devices/aliceHLTwrapper/aliceHLTWrapper.cxx +++ b/devices/aliceHLTwrapper/aliceHLTWrapper.cxx @@ -273,13 +273,20 @@ int main(int argc, char** argv) device.ChangeState(FairMQDevice::INIT); for (unsigned iInput=0; iInput Date: Tue, 7 Oct 2014 17:32:33 +0200 Subject: [PATCH 34/34] correctly handling the output buffer estimator of the HLT component to determine the size of the output buffer; fixing the --msgsize option which allows to specify a fixed buffer; minor formatting of error an message --- devices/aliceHLTwrapper/Component.cxx | 14 ++++++++++++-- devices/aliceHLTwrapper/WrapperDevice.cxx | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/devices/aliceHLTwrapper/Component.cxx b/devices/aliceHLTwrapper/Component.cxx index 77da45d4cddac..aaf6331863b76 100644 --- a/devices/aliceHLTwrapper/Component.cxx +++ b/devices/aliceHLTwrapper/Component.cxx @@ -212,6 +212,13 @@ int Component::Process(vector& dataArray) } dataArray.clear(); + // determine the total input size, needed later on for the calculation of the output buffer size + int totalInputSize=0; + for (vector::const_iterator ci=inputBlocks.begin(); + ci!=inputBlocks.end(); ci++) { + totalInputSize+=ci->fSize; + } + // add event type data block AliHLTComponentBlockData eventTypeBlock; memset(&eventTypeBlock, 0, sizeof(eventTypeBlock)); @@ -229,7 +236,10 @@ int Component::Process(vector& dataArray) unsigned long constBlockBase=0; double inputBlockMultiplier=0.; mpSystem->GetOutputSize(mProcessor, &constEventBase, &constBlockBase, &inputBlockMultiplier); - outputBufferSize=constEventBase+nofInputBlocks*constBlockBase; + outputBufferSize=constEventBase+nofInputBlocks*constBlockBase+totalInputSize*inputBlockMultiplier; + // take the full available buffer and increase if that + // is too little + mOutputBuffer.resize(mOutputBuffer.capacity()); if (mOutputBuffer.size()& dataArray) } } while (iResult==ENOSPC && --nofTrials>0); - + // prepare output if (outputBlockCnt>0) { if (mOutputMode==kOutputModeHOMER) { diff --git a/devices/aliceHLTwrapper/WrapperDevice.cxx b/devices/aliceHLTwrapper/WrapperDevice.cxx index ec893b74c810f..b0ed9593f14cd 100644 --- a/devices/aliceHLTwrapper/WrapperDevice.cxx +++ b/devices/aliceHLTwrapper/WrapperDevice.cxx @@ -184,7 +184,7 @@ void WrapperDevice::Run() // call the component if ((iResult=mComponent->Process(dataArray))<0) { - LOG(ERROR) << "component processing failed with error code" << iResult; + LOG(ERROR) << "component processing failed with error code " << iResult; } // build messages from output data