2.2. Running Ccaffeine Using an rc File

In practice, most people don't use the GUI all the time. And even die-hard GUI users will sometimes need to modify the rc file that does the initialization. Ccaffeine will also accept commands interactively or in the form of a script (the rc file). This capability is very useful when you simply want to run CCA-based applications that you already know how to assemble. In this section, we will examine in detail an rc file that does everything you did in the GUI in the previous section.

When we're not using the GUI, the Ccaffeine invocation is much simpler, and there is no need for the helper scripts we used before (utils/bocca-gui-backend.sh or gui-backend.sh). For direct use, Ccaffeine can be invoked as ccafe-single or ccafe-batch, depending on whether you're using it in a single-process (i.e. sequential) interactive situation, or in non-interactive situations, including parallel jobs.

  1. Change directories to your WORKDIR or another place write in, so that we can capture the output of running the $TUTORIAL_SRC/components/tests/task0.rc rc file.

    Execute the command

    
    ccafe-single --ccafe-rc $TUTORIAL_SRC/components/tests/task0.rc \
    	     >& task0.out
    

    (assuming you're using the csh or tcsh shells; if you're using the sh or bash shells, replace the output redirection “>& task0.out” with “> task0.out 2>&1”).

    The rc file is a simple script interpreted by the Ccaffeine framework. It allows components to be instantiated and destroyed, and for ports to be connected and disconnected. The utils/bocca-run-guibackend.sh (or utils/run-gui.sh) script you used in the previous procedure to launch the framework automatically included a simpler rc file ($TUTORIAL_SRC/components/tests/guitest.gen.rc) that merely sets the component search path and makes the project's components available on the the palette, leaving you to actually instantiate and connect up components in the GUI.

    View the task0.out file satisfy yourself that the script ran. (Of course you can also view the script itself if you want.) Below we'll work our way through each section of the script and the corresponding output, but it may help you to see the input and output in their entirety. The step numbers should correspond to the steps in the preceeding GUI procedure.

  2. The beginning of the task0.rc script looks like this:

    #!ccaffeine bootstrap file. 
    # ------- don't change anything ABOVE this line.-------------
    
    # Step 2
    
    path
    path set /home/csm/bernhold/proj/cca/tutorial/tutorial/src-acts07/components/lib
    path
    
    palette
    repository get-global drivers.CXXDriver
    repository get-global drivers.F90Driver
    repository get-global functions.CubeFunction
    repository get-global functions.LinearFunction
    repository get-global functions.QuinticFunction
    repository get-global functions.SquareFunction
    repository get-global integrators.MonteCarlo
    repository get-global integrators.Simpson
    repository get-global integrators.Trapezoid
    repository get-global randomgens.RandNumGenerator
    palette
    
    

    The rc file begins with a “magic” line (a structured comment) indicating that the script is meant to be processed by Ccaffeine. Ccaffeine expect to find such a line at the beginning of all rc files.

    Ccaffeine uses a “path” to determine where it should look for CCA components (specifically the .cca files, which internally point to the actual libraries that comprise the component). The rc file prints the path before and after setting the path for pedagogical reasons. In “real” scripts, you might want to print the path out for debugging or documentation purposes.

    Path-related commands in Ccaffeine include:

    path

    Prints the current path.

    path append

    Adds a directory to the end of the current path.

    path init

    Sets the path from the value of the $CCA_COMPONENT_PATH environment variable.

    path prepend

    Adds a directory to the beginning of the current path.

    path set

    Sets the path to the value provided.

    Ccaffeine also has the concept of a palette of components from which applications can be assembled. Unlike a typical unix shell, where putting an executable into your path means you can use it directly, Ccaffeine has a two step process. Components in the path can be added to the palette using the command repository get-global class_name, where class_name is the component's class name. This two step approach gives you a little more control when there are large numbers of components in your path. However in this case, we've simply loaded all of the components in the tutorial-src tree.

    The palette commands before and after the block of repository commands is simply meant to illustrate that the framework's palette starts empty, and ends up with the components you requested. They aren't needed in a “real” script.

    The output from these commands should look something like this:

    CCAFFEINE configured with spec (0.8.2) and babel (1.0.4).
    
    CCAFFEINE configured with classic (0.5.7).
    
    CCAFFEINE configured without neo and neo components.
    my rank: -1, my pid: 27566
    Type: One Processor Interactive
    
    
    CmdContextCCA::initRC: Found task0_rc.
    
    
    
    
    pathBegin
    pathEnd! empty path.
    
    # There are allegedly 11 classes in the component path
    
    pathBegin
    pathElement /home/csm/bernhold/proj/cca/tutorial/tutorial/src-acts07/components/lib
    pathEnd
    
    Components available:
    
    Loaded drivers.CXXDriver NOW  GLOBAL .
    
    Loaded drivers.F90Driver NOW  GLOBAL .
    
    Loaded functions.CubeFunction NOW  GLOBAL .
    
    Loaded functions.LinearFunction NOW  GLOBAL .
    
    Loaded functions.QuinticFunction NOW  GLOBAL .
    
    Loaded functions.SquareFunction NOW  GLOBAL .
    
    Loaded integrators.MonteCarlo NOW  GLOBAL .
    
    Loaded integrators.Simpson NOW  GLOBAL .
    
    Loaded integrators.Trapezoid NOW  GLOBAL .
    
    Loaded randomgens.RandNumGenerator NOW  GLOBAL .
    
    Components available:
    drivers.CXXDriver
    drivers.F90Driver
    functions.CubeFunction
    functions.LinearFunction
    functions.QuinticFunction
    functions.SquareFunction
    integrators.MonteCarlo
    integrators.Simpson
    integrators.Trapezoid
    randomgens.RandNumGenerator
    
    

    [Note] Note

    rc files used to initialize the GUI should contain only the magic line, path and repository get-global commands. You can view $TUTORIAL_SRC/components/tests/gui-setup.rc as an example.

  3. Next we instantiate the components we're going to use to assemble our first application, to place them in the arena:

    # Steps 3-4
    
    instances
    instantiate drivers.CXXDriver CXXDriver0
    instantiate functions.PiFunction PiFunction0
    instantiate integrators.MonteCarlo MonteCarlo0
    instantiate randomgens.RandNumGenerator RandNumGenerator0
    instances
    
    

    The command syntax is instantiate class_name instance_name. (The plain instantiate commands before and after are, once again, for pedagogical purposes, to list the contents of the arena.) The component's class_name is set in the SIDL file where it is defined, and is also used in the repository get-global command. The instance_name is chosen by the user, and must simply be unique within the arena. You may remember that the GUI suggests a default instance_name when prompting you for it, but that's a feature of the GUI, not the framework. Here you have to enter it yourself. It happens that we've used the same thing that the GUI would suggest.

    The output from these commands should look something like this:

    FRAMEWORK of type Ccaffeine-Support
    
    CXXDriver0 of type drivers.CXXDriver 
    successfully instantiated
    
    PiFunction0 of type functions.PiFunction 
    successfully instantiated
    
    MonteCarlo0 of type integrators.MonteCarlo 
    successfully instantiated
    
    RandNumGenerator0 of type randomgens.RandNumGenerator 
    successfully instantiated
    
    CXXDriver0 of type drivers.CXXDriver
    FRAMEWORK of type Ccaffeine-Support
    MonteCarlo0 of type integrators.MonteCarlo
    PiFunction0 of type functions.PiFunction
    RandNumGenerator0 of type randomgens.RandNumGenerator
    
    

  4. Now we need to connect up the ports on the components we've instantiated in order to assemble the application:

    # Steps 5-6
    
    display chain
    display component MonteCarlo0
    connect CXXDriver0 integrate MonteCarlo0 integrate
    connect MonteCarlo0 function PiFunction0 function
    connect MonteCarlo0 RandomGeneratorPort RandNumGenerator0 RandomGeneratorPort
    display chain
    
    

    The command syntax is connect user_component user_port provider_component provider_port.

    The display command provides various kinds of information about the arena and components therein. display chain details the connections between components. display component component_instance lists the uses and provides ports the component has registered.

    The output from these commands should look something like this:

    Component CXXDriver0 of type drivers.CXXDriver
    Component FRAMEWORK of type Ccaffeine-Support
    Component MonteCarlo0 of type integrators.MonteCarlo
    Component PiFunction0 of type functions.PiFunction
    Component RandNumGenerator0 of type randomgens.RandNumGenerator
    
    ------------------------------------
    Instance name: MonteCarlo0
    Class name: integrators.MonteCarlo
    ------------------------------------
    UsesPorts registered for MonteCarlo0
    
    0. Instance Name: function Class Name: function.FunctionPort
    1. Instance Name: RandomGeneratorPort Class Name: randomgen.RandomGeneratorPort
    ------------------------------------
    ProvidesPorts registered for MonteCarlo0
    
    Instance Name: integrate Class Name: integrator.IntegratorPort
    ------------------------------------
    
    CXXDriver0))))integrate---->integrate((((MonteCarlo0
    connection made successfully
    
    MonteCarlo0))))function---->function((((PiFunction0
    connection made successfully
    
    MonteCarlo0))))RandomGeneratorPort---->RandomGeneratorPort((((RandNumGenerator0
    connection made successfully
    
    Component CXXDriver0 of type drivers.CXXDriver
     is using integrate connected to Port: integrate provided by component MonteCarlo0
    Component FRAMEWORK of type Ccaffeine-Support
    Component MonteCarlo0 of type integrators.MonteCarlo
     is using function connected to Port: function provided by component PiFunction0
     is using RandomGeneratorPort connected to Port: RandomGeneratorPort provided by component RandNumGenerator0
    Component PiFunction0 of type functions.PiFunction
    Component RandNumGenerator0 of type randomgens.RandNumGenerator
    
    

  5. Now that we have a complete application, we can start it by invoking the driver's go:

    # Step 7
    
    go CXXDriver0 go
    
    

    The command syntax is go component_instance port_name.

    The output from these commands should look something like this:

    Value = 3.140205
    ##specific go command successful
    
    

  6. Now we use commands we already know to complete the rest of the operations that we previously performed using the GUI:

    # Step 8
    
    instantiate integrators.Simpson Simpson0
    instantiate functions.CubeFunction CubeFunction0
    
    # Step 9
    
    disconnect CXXDriver0 integrate MonteCarlo0 integrate
    disconnect MonteCarlo0 function PiFunction0 function
    
    # Step 10
    
    connect CXXDriver0 integrate Simpson0 integrate
    connect Simpson0 function PiFunction0 function
    display chain
    go CXXDriver0 go
    
    # Step 11
    
    disconnect Simpson0 function PiFunction0 function
    connect Simpson0 function CubeFunction0 function
    display chain
    go CXXDriver0 go
    
    

    The output from these commands should look something like this:

    Simpson0 of type integrators.Simpson 
    successfully instantiated
    
    CubeFunction0 of type functions.CubeFunction 
    successfully instantiated
    
    
    
    
    CXXDriver0))))integrate-\ \-integrate((((MonteCarlo0
    connection broken successfully
    
    MonteCarlo0))))function-\ \-function((((PiFunction0
    connection broken successfully
    
    
    
    
    CXXDriver0))))integrate---->integrate((((Simpson0
    connection made successfully
    
    Simpson0))))function---->function((((PiFunction0
    connection made successfully
    
    Component CXXDriver0 of type drivers.CXXDriver
     is using integrate connected to Port: integrate provided by component Simpson0
    Component CubeFunction0 of type functions.CubeFunction
    Component FRAMEWORK of type Ccaffeine-Support
    Component MonteCarlo0 of type integrators.MonteCarlo
     is using RandomGeneratorPort connected to Port: RandomGeneratorPort provided by component RandNumGenerator0
    Component PiFunction0 of type functions.PiFunction
    Component RandNumGenerator0 of type randomgens.RandNumGenerator
    Component Simpson0 of type integrators.Simpson
     is using function connected to Port: function provided by component PiFunction0
    
    Value = 3.141593
    ##specific go command successful
    
    
    
    
    Simpson0))))function-\ \-function((((PiFunction0
    connection broken successfully
    
    Simpson0))))function---->function((((CubeFunction0
    connection made successfully
    
    Component CXXDriver0 of type drivers.CXXDriver
     is using integrate connected to Port: integrate provided by component Simpson0
    Component CubeFunction0 of type functions.CubeFunction
    Component FRAMEWORK of type Ccaffeine-Support
    Component MonteCarlo0 of type integrators.MonteCarlo
     is using RandomGeneratorPort connected to Port: RandomGeneratorPort provided by component RandNumGenerator0
    Component PiFunction0 of type functions.PiFunction
    Component RandNumGenerator0 of type randomgens.RandNumGenerator
    Component Simpson0 of type integrators.Simpson
     is using function connected to Port: function provided by component CubeFunction0
    
    Value = 0.250000
    ##specific go command successful
    
    

  7. At the end of the rc files, it is important to remember to terminate the framework.

    # Step 13
    
    quit
    
    

    The output from these commands should look something like this:

    bye!
    exit
    
    

    [Warning] Warning

    If your rc file ends without a quit command, Ccaffeine will leave you in interactive mode rather than terminating and returning you to the shell prompt. If you make this mistake a Control-c will interrupt Ccaffeine and return you to the shell prompt.

Feel free to copy $TUTORIAL_SRC/components/tests/task0.rc to your workspace, modify it, and run it yourself.