33
Framework What has been happening? Jim Kowalkowski

Framework What has been happening?

  • Upload
    gafna

  • View
    32

  • Download
    0

Embed Size (px)

DESCRIPTION

Framework What has been happening?. Jim Kowalkowski. Framework Quick Update. Still inherit from Package , implement one or more interface(s) Executables still currently built using libraries and standalone object files. Flow and Interface parameters have sensible defaults - PowerPoint PPT Presentation

Citation preview

Page 1: Framework What has been happening?

FrameworkWhat has been happening?

Jim Kowalkowski

Page 2: Framework What has been happening?

Framework Quick Update

• Still inherit from Package, implement one or more interface(s)

• Executables still currently built using libraries and standalone object files.

• Flow and Interface parameters have sensible defaults

• Interfaces (Hooks) are automatically made available

• Dataflow dispatching available• Release version string available

Page 3: Framework What has been happening?

Parts Needed

• Main program object– framework.o

• Framework related libraries– libframework.a– libio_packages.a– libevpack.a– libd0om.a– ... Analyze package has

a full list (it might have more than required)

• Package libraries– libemreco.a– libcpsreco.a– one required for each

package you use

• Package registration objects– RegEMReco.o– RegCPSReco.o– one required for each

package you use

Page 4: Framework What has been happening?

Contents of Framework RCP

PackageName = “Controller” // optional but useful

string Packages = “read_event prereq conejet_5 conejet_7”

// Define what these package instances meanRCP read_event = <example ReadEvent>RCP prereq = <example SomeCalorimeterStuff>RCP conejet_5 = <example ConeJet5>RCP conejet_7 = <example Conejet7>

(That is all!)

Page 5: Framework What has been happening?

Complex Framework RCP

If you must change ordering or limit available interfaces

bool OverrideInterfaces = truebool OverrideFlow = truestring Interfaces = "decide process finish"string Flow = "decide process"

string Packages = “read_event prereq conejet_5 conejet_7” RCP read_event = <example ReadEvent>RCP prereq = <example SomeCalorimeterStuff>RCP conejet_5 = <example ConeJet5>RCP conejet_7 = <example Conejet7>

Page 6: Framework What has been happening?

Interfaces (Hooks)

• Default order of execution is defined in– framework/interfaces/Order.hpp

• A child controller has different ordering than the parent framework controller

• Flow interfaces defined in– framework/interfaces/Flow.hpp

• Standalone interfaces defined in– framework/interfaces/StandAlone.hpp

Page 7: Framework What has been happening?

The Flow Interfaces (Default Order)

• Generate - events are read in here (io_packages)• Decide - things like runInit discovered and handled here• Builder - mess with the event, like dropping chunks• Merge - combine some events (io_packages)• Filter - stop further processing of event if need be• Process - do reconstruction• Analyze - produce ntuples entries and fill histograms• Tag - mark individual chunks and the event for output• Finish - fill ntuple (flush)• Dump - debugging output for the event• Output - write the event

Page 8: Framework What has been happening?

Child Flow (Default Order)

• Filter• Process• Analyze• Tag• Dump

Page 9: Framework What has been happening?

The Standalone Interfaces

• fileOpen - file name that’s been opened• fileClose - file name that’s been closed• runInit - a run is starting• runEnd - a run is ending• luminBegin - a luminosity section start• luminEnd - a luminosity section end• jobSummary - end of the job processing

Page 10: Framework What has been happening?

Simple Package Example

.hpp:Class Processor : public fwk::Package, fwk::Process {public:

Processor(fwk::Context* cxt):Package(cxt),Process(cxt) { … }~Processor();fwk::Result processEvent(edm::Event& e);// should write statusReport, reinitialize, and flush here too

};

.cc:FWK_REGISTRY_IMPL(Processor,"$Name: $")Reg.cc:FWK_REGISTRY_DECL(Processor)

This is all that is required!!!

Page 11: Framework What has been happening?

Package Initialization

• Do not use the Context* passed into the constructor, treat it as a void* and pass it to the base classes

• Get at parameters via method Package::packageRCP( )

• Get access to the framework RCP file using method Package::frameworkRCP(). Useful if you want globally available flags or other things.

Page 12: Framework What has been happening?

Using the Framework

• Implement the processEvent() interface for reconstruction purposes

• From Package, implement– statusReport( )

• Report summary of state (statistics) to cout

– reinitialize(RCP r)• this should call setParameters(r), probably should

clear histograms, etc.

– flush( )• Flush any buffers your package contains

(histograms, log streams, etc.)

Page 13: Framework What has been happening?

Please…

• Stop putting Flow/Interfaces parameters into your framework RCP files unless you are really using them. They are not used.

• Stop creating packages with unnecessary framework methods that have been obsolete for years.

• Put good version strings into the registry macros (most everyone does this).

Page 14: Framework What has been happening?

Version Information

• From package code:– include framework/utilities/Functions.hpp– call getProductionVersion(), it returns an

std::string

• From command line:– my.exe -version– my.exe -show

• Try “-mem” option, it will report, between package, each time memory usage increases.

Page 15: Framework What has been happening?

Using Framework Groups

• Assume the following packages exist:– Single lepton cut package (emuCut)– Tau reconstruction package (tauReco)– Tri-Lepton cut package (multiLeptonCut)– SUSY analysis package (susyAnalysis)

• Assume the packages use the proper hooks• We do not want to make any code changes• Want to tune Tau reco parameters• We want to run the following sequence:

ReadEvent emuCut tauReco multiLeptonCut susyAnalysis

Page 16: Framework What has been happening?

Using Groups

Standard Flow not good enough, we would need:

Generate -> Filter -> Process -> Filter -> Analyze

Could use framework group instead, revisedsequence would be:

Main: ReadEvent -> emuCut -> tauReco -> Controller2 Controller2: multiLeptonCut -> susyAnalysis

Now default Flow ok and everything works just fine.

Page 17: Framework What has been happening?

Group RCP Example

Main.rcp: string PackageName = “Controller” string Packages = “reader emu_cut tau_reco susy” RCP reader = < example doread > RCP emu_cut = < example emu_cut > RCP tau_reco = < example tau_reco > RCP susy = < example dosusy >

doread.rcp: string PackageName = “ReadEvent”emu_cut.rcp: string PackageName = “emuCut”tau_reco.rcp: string PackageName = “tauReco”multi_cut.rcp: string PackageName = “multiLeptonCutsusy.rcp: string PackageName = “susyAnalysis”

dosusy.rcp: string PackageName = “Controller” string Packages = “multi_cut susy” RCP multi_cut = < example multi_cut > RCP susy = < example susy >

Page 18: Framework What has been happening?

Creating a “Hook”

// File: MyHooks.hpp

// helper macros with example use#include “framework/interfaces/Maker.hpp

// hook with no arguments, named “myhook”, class MyHook, method dumbHookFWKI_NOARG(”myhook",MyHook,dumbHook)

// hook with one arg, named “muochunk”, class MuoStuff, method muoChunk,// object type MuoHitChunk, managed by framework smart pointerFWKI_ARG(”muochunk",MuoStuff,muoChunk,MuoHitChunk,fwk::Ref<MuoHitChunk>)

// hook with one const argument and access to the framework work queueFWKI_CONSTARG_WQ(”find",Find,findObj,edm::Event,d0_Ref<edm::Event>)

Page 19: Framework What has been happening?

Using the New Hooks

#include “MyHooks.hpp”class MyPkg : public MyHook, public MuoStuff, public Find {public:

fwk::Result dumbHook();fwk::Result muoChunk(MuoHitChunk& e);// can add objects to the framework work queue with findObjfwk::Result findObj(const edm::Event& e, fwk::WorkQueue& q);fwk::Result findObj(fwk::WorkQueue& q);...

};

fwk::Result MyPkg::findObj(const Event& e, fwk::WorkQueue& q) {Thandle<MuoRawData> raw = e.find_me_this_thing;fwk::Ref<MuoHitChunk> m = createChunk(raw);fwk::pushQueueBack(q, muo_msg_id, m);return Result::success;

}

Page 20: Framework What has been happening?

New Hook Notes

• It is not difficult to create new hooks• The documentation is poor• There are plenty of examples in the

framework package• Come see me if you are interested

Page 21: Framework What has been happening?

Use of ErrorLog at D0

// using the protected member of the Package class…fwk::Result MyPkg::processEvent(edm::Event& e) { … if(error occurred) error_log(ELwarning,”FWK") << “help me” << '\n' << endmsg;

// anywhere in your code…void func(edm::Event& e) { ErrorLog elog(“MyFuncPackage”); ... if(error occurred) elog(ELwarning,”DEATH”) << “help me” << ‘\n’ << endmsg;}

Page 22: Framework What has been happening?

ErrorLog Usage

• Both will produce the same framework context information– run/event numbers– currently executing package instance/method

• The package name will be the name assigned in the RCP file for the first one

• The package name will be “MyFuncPackage” for the second, each time it is used

Page 23: Framework What has been happening?

Package Coding Rules

• No caching event data between events• No global variables• No removing pointer from handle

– use the handle as a pointer

• Do not include headers from another package’s private directory

• Do reconstruction in the processEvent( ) interface

• Do not cast away const-ness

Page 24: Framework What has been happening?

Error Handling

• Catch exceptions thrown by your own algorithms– Framework catches all exceptions that exit your

package; logs the message and program dies

• Using return codes– Currently any package returning failure aborts

further processing of that event (from that group)

• Proposal for changes given at earlier talk

Page 25: Framework What has been happening?

Best Practice

• Do not put using namespace in any header• Use forward declarations wherever possible• Prefer ++it to it++• Do not expose details unnecessarily

– e.g.: Do hide bit encodings from users• Use meaningful member names, rather than slot numbers

in an array• Watch out for return by value, could be performance killer.• Use “fillme” method.

Page 26: Framework What has been happening?

“fillme” Method

Not very good:

std::vector<int> X::getValues() {std::vector<int> ret;… ret.push_back(x); ...return ret;

}

Better:size_t X::getValues( std::vector<int>& fillme ) {

… fillme.push_back(x); …return num_of_things_in_fillme;

}

Page 27: Framework What has been happening?

Discussion Item

Does anything need to be done about control of the ErrorLogger?

• Framework package to configure it?• Produce statistics?• Separate messages into different files?• Destination that sends email?

Page 28: Framework What has been happening?

Dataflow Dispatcher

• Processing based on input objects becoming available• DFPackages are Packages that can declare input/output

object names• Get invoked with a collection of all the inputs they are

waiting for.• Dispatcher creates network of packages based on inputs

and outputs• Dispatcher verifies that packages will get input objects• Supports nesting of DFPackages• Can pass arbitrary objects to DFPackages, not just Events

Page 29: Framework What has been happening?

More About Dataflow

• Trigger simulator is using it• Can do many, many things that need to be

documented• Standard hooks work (runInit/etc.)• Works with standard Packages (io_packages)• See me if you are interested

Page 30: Framework What has been happening?

Trivial Dataflow Example

Class L2Worker: public fwk::DFPackage {void L2Worker::inputs(list<string>& ilist) {

ilist.push_back(“event”);ilist.push_back(“l2inp”);

}void L2Worker::outputs(list<string>& olist) { olist.push_back(“l2global”);

olist.push_back(“l2out”);}fwk::Result DFProc::ready(DataStore& dstore) {

…vector<L2Inp*> inps;edm::Event* e = getEvent(dstore);queryPointers(dstore,inps,”l2inp”);produceItem(dstore,new L2Global,”l2global”);produceItem(dstore,new L2out,”l2out”);

}};

Page 31: Framework What has been happening?

Dataflow Configuration Example

ReadEvent

L2Source

event

l1muo

L2CalTT

l2caltt l2l3caltt

L2EM

l2em l2l3em

L2Muo

l2muo l2l3muo

L2Collator

*

*

L2Global

L2Presenter

l1eml1caltt

l1calttl1muo

l1em

l2l3data l2l3data

l2l3data

l2l3globall2l3data

l2global l2globall2global

Page 32: Framework What has been happening?

Dataflow DataStore

queryPointers(DataStore& d,vector<X>& out, Action::Id id=0)queryAliases(DataStore& d,vector<X>& out, Action::Id id=0)query(DataStore& d,vector<X>& out, Action::Id id=0)produceSignal(DataStore& d, Action::Id)produceManaged(DataStore& d, ITEM managed_obj, Action::Id id,

Action::Id alias=0)produceManaged(DataStore& d, ITEM managed_obj, Action::Id id, ITER first_alias, ITER last_alias)produceItem(DataStore& d, ITEM* obj, Action::Id id,

Action::Id alias=0)produceItem(DataStore& d, ITEM* obj, Action::Id id, ITER first_alias, ITER last_alias)produceRaw(DataStore& d, ITEM* obj, Action::Id id,

Action::Id alias=0)produceRaw(DataStore& d, ITEM* obj, Action::Id id, ITER first_alias, ITER last_alias)

Page 33: Framework What has been happening?

DataStore Filling

• produceRaw– Takes a pointer to any object. No memory

management. Object ownership is not passed to framework

• produceItem– Takes a pointer to any object. Ownership is

passed to framework (and lifetime control)

• produceManaged– Takes a smart pointer to any object. Ownership

is through users smart pointer