Developing Modules for Efficient Data Handling in SCIRun
250 likes | 266 Vues
Learn the structure, coding standards, and GUI creation for modules in SCIRun. Explore dataflow, ports, and datatypes. Optimize memory management and dynamic compilation for efficient algorithm implementation.
Developing Modules for Efficient Data Handling in SCIRun
E N D
Presentation Transcript
Overview • Before You Start • Structure of a Module • Ports and Datatypes • Component Wizard • GUI’s • Dynamic Compilation
Before You Start • Design Your Function • A Module is a Function • Inputs and Outputs • User Input (GUI Variables) • Dataflow • Coding Standard • Standards • Advice • SCIRun/doc/Developer/Guide/coding_standard.html
Module Structure • Support Files • .cc file • sub.mk • .xml file • .tcl file • sub.mk • .h file (optional)
Ports and Datatypes • Ports • LockingHandles • Generation number • Memory Management • Sending Data • Cache Results • Datatypes • Fields, Matrix, SceneGraph • Detach (Dataflow) • Properties
Component Wizard • Adding a Module
Component Wizard • Edit a Port • Name • Namespace
Component Wizard • Package • Category • Path
Component Wizard • New Package? • New Category? • Reconfiguring.
Component Wizard • After Compiling
Component Wizard • Your Skeleton GUI
GUI’s • TCL • itcl • blt • Use Simple GUI as a Pattern • GuiVars
GUI’s • itcl_class SCIRun_Fields_SelectField { inherit Module constructor {config} { set name SelectField global $this-stampvalue global $this-runmode set_defaults } method set_defaults {} { set $this-stampvalue 100 set $this-runmode 0 # 0 nothing 1 accumulate 2 replace } method replace {} { set $this-runmode 2 $this-c needexecute } method accumulate {} { set $this-runmode 1 $this-c needexecute }
GUI’s • method ui {} { set w .ui[modname] if {[winfo exists $w]} { raise $w return } toplevel $w frame $w.row1 frame $w.row3 frame $w.row4 pack $w.row1 $w.row3 $w.row4 -side top -e y -f both -padx 5 -pady 5 label $w.row1.value_label -text "Selection Value" entry $w.row1.value -textvariable $this-stampvalue pack $w.row1.value_label $w.row1.value -side left button $w.row3.execute -text "Replace" -command "$this replace" pack $w.row3.execute -side top -e n -f both button $w.row4.execute -text "Accumulate" -command "$this accumulate" pack $w.row4.execute -side top -e n -f both }
GUI’s • GuiVars • Values to from C side • Initialize • C++ side constructor synchs with tcl name • tcl side sets the initial value • my_var.reset() • my_var.get() • tcl_command(...) • $this-c “needexecute”
Dynamic Compilation • Motivation • SCIRun::Field • Code Explosion • Extensibility • Maintenance
Dynamic Compilation • Field Types (4) TetVol, LatticeVol, ContourField, TriSurf • Supported Data Types (9) double, int, char, unsigned char, short, unsigned short, bool, Vector, and Tensor • An Algorithm Parameterized on One Field Type • Requires 36 Field instantiations • And 36 Algorithm Instantiations • Parameterized On Two Fields • 362 =1296 Versions of the Algorithm • Parameterized On Three Fields • 363 =46656 Versions of the Algorithm • Actual implementation supports more Field and Data types • Very few of these combinations are needed by any one person or application
Algorithm Structure • Algorithm Base Class • Inherits from common base class • Defines the pure virtual interface needed by a module • Provides a static CompileInfo • Templated Algorithm • Implements the pure virtual interface in the base class • Potentially specialized for specific field type template<class Field> RenderField : public RenderFieldBase virtual void render(FieldBase&)=0;
TypeDescription • TypeDescription object augments RTTI • Holds: • Strings that describe object’s exact type • Namespace string • Path to the .h file that declares the object • Has a recursive structure • Example: foo<bar, foobar<int> >;
CompileInfo • Similar info as a TypeDescription • Algorithm is not instantiated, so cannot yet be queried • Start with a CompileInfo from Algorithm base class • Augmented with information from all pertinent TypeDescription objects for the specific types involved • Passed to DynamicLoader, which creates the proper type
DynamicLoader • Returns Requested Algorithm • Writes C++ instantiation code • Compile shared library, using SCIRun makefiles • Load shared library (dlopen) • Return Instance of Algorithm (Cached for next use) • Synchronization code such that • Only 1 thread can compile at a time per algorithm • Multiple algorithms can compile and load at the same time
Calling Module • void ShowField::execute(){// Get a Field from input field port. field = (FieldIPort *)get_iport("Field"); field->get(field_handle);// Get the input field's type info. const TypeDescription *td = field_handle->get_type_description();// Get the Algorithm. CompileInfo *ci = RenderFieldBase::get_compile_info(td); if (! DynamicLoader::scirun_loader().get(*ci, rend_algo)) { error("Could not compile algorithm for ShowField -"); • return; } RenderFieldBase *rf = dynamic_cast<RenderFieldBase*>(rend_algo);// Let the templated algorithm render this field. rf->render(field_handle, /* any other parameters from gui */);// Send results downstream...} No template instantiations for the exact algorithm type
Example • //! ConvertTetBase supports the dynamically loadable algorithm concept.//! when dynamically loaded the user will dynamically cast to a //! ConvertTetBase from the DynamicAlgoBase they will have a pointer to.class ConvertTetBase : public DynamicAlgoBase{public: virtual FieldHandle convert_quadratic(FieldHandle in) = 0; virtual ~ConvertTetBase(); static const string& get_h_file_path(); static string dyn_file_name(const TypeDescription *td) {// add no extension. return template_class_name() + "." + td->get_filename() + "."; } static const string base_class_name() { static string name("ConvertTetBase"); return name; } static const string template_class_name() { static string name("ConvertTet"); return name; }//! support the dynamically compiled algorithm concept static CompileInfo *get_compile_info(const TypeDescription *td);};
Example • template <class Fld>class ConvertTet : public ConvertTetBase{public://! virtual interface. virtual FieldHandle convert_quadratic(FieldHandle in);};template <class Fld>FieldHandleConvertTet<Fld>::convert_quadratic(FieldHandle ifh){Fld *fld = dynamic_cast<Fld*>(ifh.get_rep()); ASSERT(fld != 0); typedef typename Fld::value_type val_t; FieldHandle fh(QuadraticTetVolField<val_t>::create_from(*fld)); return fh;}
Summary • Concepts • Ports and Datatypes • Modules (Component Wizard) • Templated Algorithms • Dynamic Loading