Table of Contents
In this exercise, you will work with pre-built components from the integrator example to compose several CCA-based applications and execute them. The integrator application is a simple example, designed to illustrate the basics of creating, building, and running component-based applications without scientific complexities a more realistic application would also present. The purpose of this application is to numerically integrate a one-dimensional function. Several different integrators and functions are available, in the form of components. A “driver” component orchestrates the calculation, and for the Monte Carlo integrator, a random number generator is also required. The specific components available are:
functions.PiFunction (4/(1+x2), which integrates to π),
functions.CubeFunction* (x3, which integrates to 0.25),
functions.LinearFunction (x, which integrates to 0.5)
randomgens.RandNumGenerator (required by
Components marked with a “*” are ones that you will be
creating in the subsequent exercises (you only need to do one of the
two driver components), but as we have mentioned, the pre-built
tutorial-src tree includes completed examples of
all of the components.
There are three different procedures for this exercise. In Section 2.1, “A CCA Application in Detail”, you interact directly with Ccaffeine
on the command line to do everything. This is the best place to start
to understand how to assemble and run a CCA application. In Section 2.2, “
Running Ccaffeine Using an
”, you will see how the steps you
performed manually in the first procedure can be captured in a script
that Ccaffeine reads. This is the more common scenario because it
gives you an easy way to represent a complete CCA application that is
easy to reproduce, or to adapt to other situations, without having to
re-do everything from scratch every time you want to run it. This is
probably the approach you'll want to use when testing your work in the
subsequent exercises. Finally, in Section 2.3, “Using the GUI Front-End to Ccaffeine”, we use a graphical front-end to
Ccaffeine, which allows you to perform the composition and execution
of the application using a “visual programming” metaphor.
In the interests of time, it is not necessary for you to actually do all three procedures before moving on to the later chapters, but you should certainly read and understand this chapter before moving on. In particular, you will find that Section 2.1, “A CCA Application in Detail” has the most detailed explanations of what is going on, but at the same time, it is the most tedious procedure to actually perform because it involves a lot of typing, and doesn't tolerate typing errors well. However the later sections and subsequent chapters assume that you understand this material.
This exercise uses the
These exercises can involve a fair amount of typing. You may find
it convenient to use the online HTML version of this Guide (at
to cut and paste the necessary inputs. Note, however, that not
everything can be cut-and-based directly. Take particular care with
lines that had to be broken for purposes of documentation, and for
placeholder values such as “
In this section, you will interact directly with the Ccaffeine framework to assemble and run several different numerical integration applications from pre-built components.
We will present the procedure in the form of a dialog between you and
the Ccaffeine framework. Things you are supposed to type are
like this and Ccaffeine's output will
like this. Note that
Ccaffeine's input prompt is “
Particular features of the output will sometimes be marked and
discussed in further detail below the output fragment.
The complete set of Ccaffeine commands for this procedure can be
Start the Ccaffeine framework with the command
is one of several ways to invoke the Ccaffeine framework, and is
used for single-process (i.e. sequential) interactive sessions;
ccafe-batch is designed for use in
non-interactive situations, including parallel jobs; and
ccafe-client is designed to interact with a
front-end GUI rather than with a user at the command line
You should see something like this (note that some of the output
lines have been folded for presentation here, indicated by
(16251) CmdLineClientMain.cxx: MPI_Init not called in \ ccafe-single mode. (16251) CmdLineClientMain.cxx: Try running with ccafe-single \ --ccafe-mpi yes , or (16251) CmdLineClientMain.cxx: try setenv CCAFE_USE_MPI 1 to force MPI_Init. (16251) my rank: -1, my pid: 16251 my rank: -1, my pid: 16251 my rank: -1, my pid: 16251 my rank: -1, my pid: 16251Type: One Processor Interactive CCAFFEINE configured with babel.
cca>CmdContextCCAMPI::initRC: No rc file found. Pallet may be empty.
Lines between these two markers give information about the
status of MPI in the Ccaffeine framework, including the
processes rank if MPI is initialized. As the messages
indicate, ccafe-single is intended for
single-process use and does not normally call
This message confirms that this Ccaffeine executable was configured and built to work with Babel. This is a useful thing to check when you're using an unfamiliar installation of Ccaffeine, or the first time you Ccaffeine after building it yourself.
It is common to use an “
We present Ccaffeine's output with “spew” disabled
(the default). If Ccaffeine is configured and built with the
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). When it starts up, Ccaffeine's path is empty, and it
has no idea where to find components. Next you will set the path
that points to the pre-built components:
pathpathBegin pathEnd! empty path.
path set# There are allegedly 19 classes in the component path
Remember that when you see markup like
Path-related commands in Ccaffeine include:
Adds a directory to the end of the current path.
Sets the path from the value of the
$CCA_COMPONENT_PATH environment variable.
Adds a directory to the beginning of the current path.
Sets the path to the value provided.
Typing help at the Ccaffeine
Ccaffeine also has the concept of a palette of components
from which applications can be assembled, which is based on the
components (specifically, the
.cca files) Ccaffeine finds in
the path you set. The
palette command will show you what is currently
in the palette, and the repository get-global
class_name command is used to
get the component of the specified class name from the repository
(path) and load it into the palette. To begin with, we're
going to load a set of components that will allow us to build just
one specific integration application; later, we'll add other
components and show how you can “plug and play” to
create a variety of distinct integration applications from the
full pallette of available components.
repository get-global drivers.CXXDriverLoaded drivers.CXXDriver NOW GLOBAL .
repository get-global functions.PiFunctionLoaded functions.PiFunction NOW GLOBAL .
repository get-global integrators.MonteCarloLoaded integrators.MonteCarlo NOW GLOBAL .
repository get-global randomgens.RandNumGeneratorLoaded randomgens.RandNumGenerator NOW GLOBAL .
paletteComponents available: drivers.CXXDriver functions.PiFunction integrators.MonteCarlo randomgens.RandNumGenerator
Next, you need to instantiate the components you're going to
use. The instances command will list all the
component instances in Ccaffeine's work area, or
arena. The command instantiate
component_instance_name will create an
instance of the specified class from the palette with the
specified instance name and call the new component instance's
instancesFRAMEWORK of type Ccaffeine-Support
instantiate drivers.CXXDriver driversCXXDriverdriversCXXDriver of type drivers.CXXDriver successfully instantiated
instantiate functions.PiFunction functionsPiFunctionfunctionsPiFunction of type functions.PiFunction successfully instantiated
instantiate integrators.MonteCarlo integratorsMonteCarlointegratorsMonteCarlo of type integrators.MonteCarlo successfully instantiated
instantiate randomgens.RandNumGenerator randomgensRandNumGeneratorrandomgensRandNumGenerator of type randomgens.RandNumGenerator successfully instantiated
instancesFRAMEWORK of type Ccaffeine-Support driversCXXDriver of type drivers.CXXDriver functionsPiFunction of type functions.PiFunction integratorsMonteCarlo of type integrators.MonteCarlo randomgensRandNumGenerator of type randomgens.RandNumGenerator
When you instantiate a component, you can name it whatever you like as long as it is unique with respect to all of the components that you've instantiated in your session with the framework. It is possible to instantiate the a given component class multiple times (with different names, of course).
Once the components you need are instantiated, you need to
connect up their ports appropriately. The display
chain command will list the component instances in
Ccaffeine's arena and any connections among their ports.
To make a connection, you use the command connect
that some of the input lines have been folded with
\” to fit on the page -- you'll
have to rejoin them when you type in the commands because
Ccaffeine doesn't understand continuation lines). In this case,
we need to connect appropriate ports on the driver to the
integrator, and the integrator to the function to be integrated.
Since we're using the Monte Carlo method in this integrator, the
integrator also needs to be connected to a random number
display chainComponent FRAMEWORK of type Ccaffeine-Support Component driversCXXDriver of type drivers.CXXDriver Component functionsPiFunction of type functions.PiFunction Component integratorsMonteCarlo of type integrators.MonteCarlo Component randomgensRandNumGenerator of type randomgens.RandNumGenerator
connect driversCXXDriver IntegratorPort integratorsMonteCarlo \ IntegratorPortdriversCXXDriver))))IntegratorPort---->IntegratorPort((((integratorsMonteCarlo connection made successfully
connect integratorsMonteCarlo FunctionPort functionsPiFunction \ FunctionPortintegratorsMonteCarlo))))FunctionPort---->FunctionPort((((functionsPiFunction connection made successfully
connect integratorsMonteCarlo RandomGeneratorPort \ randomgensRandNumGenerator RandomGeneratorPortintegratorsMonteCarlo))))RandomGeneratorPort---->\ RandomGeneratorPort((((randomgensRandNumGenerator connection made successfully
display chainComponent FRAMEWORK of type Ccaffeine-Support Component driversCXXDriver of type drivers.CXXDriver is using IntegratorPort connected to Port: IntegratorPort provided by \ component integratorsMonteCarlo Component functionsPiFunction of type functions.PiFunction Component integratorsMonteCarlo of type integrators.MonteCarlo is using FunctionPort connected to Port: FunctionPort provided by \ component functionsPiFunction is using RandomGeneratorPort connected to Port: RandomGeneratorPort \ provided by component randomgensRandNumGenerator Component randomgensRandNumGenerator of type randomgens.RandNumGenerator
At this point, there are no connections, so the output of display chain looks very much like that of instances -- just a simple listing of the component instances in the arena.
Characteristic of the output of a connect command is the ASCII “cartoon” illustrating the connection, with the user on the left and the provider on the right.
Now the output of display chain lists the connections associated with each component instance. Note that the connection information is printed with the using component instance only, not the provider.
Port names and port types are defined by the person who implements the component. They have to be unique within the component, but not across an entire application. In order to connect a uses port to a provides port, the types of the port must match, but the names need not match.
In the Ccaffeine framework, you can find out what ports a
particular component uses and provides with the
command display component
At this point, you have a fully-assembled application and are ready to run it!
While most CCA ports are defined by component developers, the
CCA specification includes a special port of type
The purpose of this port is to initiate the
execution of a component. The command go
go_port_name instructs the
framework to invoke the specified go port:
go driversCXXDriver GoPortValue = 3.141768 ##specific go command successful
and you can see a (fairly inaccurate) value for π computed by Monte Carlo integration of the function 4/(1+x2).
The type, or class name of the port must be
At this stage, you have successfully composed and run a CCA application based on existing components. In the remainder of this procedure, we'll see how it is possible to dynamically change the application you've assembled by disconnecting components and connecting others in their place. Or you can jump straight to Step 11 to (gracefully) end this session with Ccaffeine and move on to other procedures in this chapter, or on to other tasks altogether.
At the moment, Ccaffeine's palette contains only the components we needed for the first application. Now, we'll add some more components to the palette and instantiate them in the arena:
repository get-global integrators.MidpointLoaded integrators.Midpoint NOW GLOBAL .
instantiate integrators.Midpoint integratorsMidpointintegratorsMidpoint of type integrators.Midpoint successfully instantiated
repository get-global functions.CubeFunctionLoaded functions.CubeFunction NOW GLOBAL .
instantiate functions.CubeFunction functionsCubeFunctionfunctionsCubeFunction of type functions.CubeFunction successfully instantiated
There is no harm in having components you don't use in the palette, or even having instances of them in the arena.
In order to be able to swap out components for others, we first need to disconnect them. The disconnect command has the same syntax as the connect command, with both the uses and provides end points of the connection being specified.
Let's begin by changing the Monte Carlo integrator for another. The integrator is connected to both the driver and the function. (And also to the random number generator, but since we don't need it for anything else, there is no harm in leaving that connection intact.)
disconnect driversCXXDriver IntegratorPort integratorsMonteCarlo \ IntegratorPortdriversCXXDriver))))IntegratorPort-\ \-IntegratorPort((((integratorsMonteCarlo connection broken successfully
disconnect integratorsMonteCarlo FunctionPort functionsPiFunction \ FunctionPortintegratorsMonteCarlo))))FunctionPort-\ \-FunctionPort((((functionsPiFunction connection broken successfully
The disconnect command prints an ASCII cartoon of a broken connection, similar to that printed by the connect command.
Once we connect up a new integrator (in this case, using the mid-point rule algorithm) to the driver and function, we have a new “application” that's ready to run:
connect driversCXXDriver IntegratorPort integratorsMidpoint \ IntegratorPortdriversCXXDriver))))IntegratorPort---->IntegratorPort((((integratorsMidpoint connection made successfully
connect integratorsMidpoint FunctionPort functionsPiFunction \ FunctionPortintegratorsMidpoint))))FunctionPort---->FunctionPort((((functionsPiFunction connection made successfully
display chainComponent FRAMEWORK of type Ccaffeine-Support Component driversCXXDriver of type drivers.CXXDriver is using IntegratorPort connected to Port: IntegratorPort provided by \ component integratorsMidpoint Component functionsCubeFunction of type functions.CubeFunction Component functionsPiFunction of type functions.PiFunction Component integratorsMidpoint of type integrators.Midpoint is using FunctionPort connected to Port: FunctionPort provided by \ component functionsPiFunction Component integratorsMonteCarlo of type integrators.MonteCarlo is using RandomGeneratorPort connected to Port: RandomGeneratorPort \ provided by component randomgensRandNumGenerator Component randomgensRandNumGenerator of type \ randomgens.RandNumGenerator
go driversCXXDriver GoPortValue = 3.141553 ##specific go command successful
Observe that there are a number of component instances in
the arena that we have either never used
The Monte Carlo algorithm is unique among the integrators we have implemented in requiring a source of random numbers. As a consequence, the mid-point and other integrators do not have a uses port for a random number generator, and it is not necessary, or even possble in the CCA context, to connect a random number generator to any of the integrators besides the Monte Carlo.
Finally, we swap the π function for an x3 function and run a third application built from the same set of components:
disconnect integratorsMidpoint FunctionPort functionsPiFunction \ FunctionPortintegratorsMidpoint))))FunctionPort-\ \-FunctionPort((((functionsPiFunction connection broken successfully
connect integratorsMidpoint FunctionPort functionsCube FunctionPortintegratorsMidpoint))))FunctionPort---->FunctionPort((((functionsCubeFunction connection made successfully
display chainComponent FRAMEWORK of type Ccaffeine-Support Component driversCXXDriver of type drivers.CXXDriver is using IntegratorPort connected to Port: IntegratorPort provided by \ component integratorsMidpoint Component functionsCubeFunction of type functions.CubeFunction Component functionsPiFunction of type functions.PiFunction Component integratorsMidpoint of type integrators.Midpoint is using FunctionPort connected to Port: FunctionPort provided by \ component functionsCubeFunction Component integratorsMonteCarlo of type integrators.MonteCarlo is using RandomGeneratorPort connected to Port: RandomGeneratorPort \ provided by component randomgensRandNumGenerator Component randomgensRandNumGenerator of type randomgens.RandNumGenerator
go driversCXXDriver GoPortValue = 0.250010 ##specific go command successful
To exit Ccaffeine “politely” and allow it to cleanly shutdown and destroy all components, use the quit command: