Skip to content

Module Conversion Steps

Dan White edited this page Sep 25, 2013 · 28 revisions

This step-by-step guide walks you through conversion of a module from SCIRun 4 to SCIRun 5. At this time, it only covers modules without a UI screen. Before you begin, make sure you are on your own git branch and NOT on master; master commits are for project admins only.

Phase A: Physical file preparation

  1. Copy the module's C++ source file into the correct path. Look under src/Modules/Legacy to see if it is already there.
  • Example: src/Modules/Legacy/Fields/AlignMeshBoundingBoxes.cc is already checked in, so nothing to do.
  1. Make a copy of the file SCIRunGUIPrototype/src/Modules/Legacy/Fields/CalculateGradients.h (TODO: general header template) and rename it using the same name as the module. It will act as a template for the newly-required module header file.
  • Example: Copied CalculateGradients.h to AlignMeshBoundingBoxes.h.
  1. Edit the corresponding CMakeLists.txt file to both (a) enable/add the module .cc file, and (b) add the newly-created module header file.
  • Example: src/Modules/Legacy/Fields/CMakeLists.txt was edited to add AlignMeshBoundingBoxes.h to the Dataflow_Modules_Legacy_Fields_HEADERS list; and, the line containing AlignMeshBoundingBoxes.cc was uncommented to add both files to the project.
  1. Under src/Modules/X/Tests, where X is the general category of your module, add a unit test source file both to the filesystem and to the corresponding CMakeLists.txt file.
  • Example: Unit tests for the Legacy modules are separated from the Legacy directories to aid file diffing. Thus, a file AlignMeshBoundingBoxesTests.cc was added to src/Modules/Fields/Tests, and then added to the project using CMake. GetFieldBoundaryTests.cc was copied to create the new file; it will be edited in a later step.
  1. At this point, the CMake project structure should be valid (although the projects won't build), and your git changeset should look like this: Step 5
  2. CHECKPOINT: If there is no corresponding Algorithm class for your module, there is a limit on the size of its execute() method of 5 lines. Otherwise, a separate Algorithm class is required to be extracted from the Module's implementation.
  3. With the Algorithm implementation separate, proceed to the Algorithm class's directory.
  • Example: AlignMeshBoundingBoxes uses AlignMeshBoundingBoxes.h/.cc under src/Core/Algorithms/Legacy/Fields/TransformMesh, the files are already there.
  1. Enable/add the algorithm source files to the correct CMake project.
  • Example: src/Core/Algorithms/Legacy/Fields/CMakeLists.txt is edited to enable TransformMesh/AlignMeshBoundingBoxes.cc and add TransformMesh/AlignMeshBoundingBoxes.h (Most algorithm header files are not part of the CMakeLists file already and need to be added).
  1. Repeat step 4 for the Algorithm code. Everything needs test code.
  • Example: The new algorithm tests will go under src/Core/Algorithms/Field/Tests. An existing test file is copied into the new file AlignMeshBoundingBoxesAlgoTests.cc, and it is added to the CMake file.
  1. Your CMake config should be valid, and it is time to make a commit. It's good to separate the file additions and CMake changes from actual code changes in the history.
  • Example: Step10

Phase B: Algorithm compilation

  1. Regenerate your project files and start a build. Most likely the algorithm class will fail to compile. The steps to get it compiling generally break down like this:
  2. Fix/delete unneeded include paths.
  • Example:
  1. Update namespaces.
  • Example:
  1. Update the base class for the Algorithm type.
  • Example:
  1. Move all implementation to the .cc file.
  • Example:
  1. The Algorithm parameter interfaces are centralized under one set of methods, addParameter/get/set. They don't take raw strings anymore, but need an object defined as a key for each parameter. Use a static member variable for each parameter name.
  • Examples:
  1. The algo_start/end interface is removed, instead use ScopedAlgorithmStatusReporter.
  • Example:
  1. Interface changes due switch from LockingHandle to boost::shared_ptr
  • Example:
  1. Certain functions are not available yet, for now macro out their calls (TODO: this step needs to go away soon).
  • Example:
  1. asVector() calls need to be removed.
  • Example:
  1. The interface for deep-copying a field/mesh has changed.
  • Example:
  1. There is a chance that you encounter a compiler error related to another interface change or utility library code that is not enabled yet. In this case, contact @dcwhite and he will work with you on your branch to enable the code you need.

Phase C: Algorithm upgrading and testing

  1. Open the algorithm unit test source file created in step A-9. Create a dummy test similar to the following example:
  • Example:
  1. Make sure proper includes are made. It should fail to compile, with error "cannot instantiate abstract class". This is due to the new generic algorithm interface created to simplify module testing. Writing this new method is straightforward, and may even be automated in the future.
  2. First, declare the generic algorithm method in the header file.
  • Example.
  1. Next, create the shell of the implementation in the source file.
  • Example:
  1. Decide what you want to name the input/output values of the algorithm. They will need Name objects to enable provenance.
  • Example:
  1. Define the name objects, using the same string as the identifier. Don't just use "Input" and "Output", this is a chance to self-document your algorithm.
  • Example:
  1. Fix const-correctness of the run() method, and include AlgorithmPreconditions.h.
  • Example:
  1. The algorithm test should compile now. Here is where you can test your algorithm code without having to instantiate a network, module, the UI, or anything else. If you have some easy base cases to test, or want to bring in some (small) data files to test with, the unit testing framework can handle all of that easily. We simply won't accept untested code into SCIRun 5, so the extra effort here is necessary. Talk to the dev team for assistance.

Phase D: Module conversion

  1. The module header file is a new concept. SCIRun 4's modules are not "includable" since the class declarations are in the source file lumped in with the implementation. The new version is taking advantage of some declarative techniques to do away with the module XML port definition file and keep port names synchronized. Thus there is a standard template for module headers:

    class SCISHARE ModuleClassName : public Dataflow::Networks::Module,
    public InputPortSpec,
    public OutputPortSpec
    {
    public:
    ModuleClassName();
    virtual void execute();
    INPUT_PORT_DESCs
    OUTPUT_PORT_DESCs
    };

Phase E: Factory hook-up

  1. There should exist a basic module instantiation unit test that is failing at this point. Now we can properly hook up module creation in the factory. Open src/Modules/Factory/HardCodedModuleFactory.cc.
  2. Add the module include path.
  • Example:
  1. Add one line of code to register your module. (TODO: this step will be simplified further soon)
  • Example:

Phase F: Module Testing

Phase G: Sanity check