Cello Components
The software design of Enzo-E / Cello is based on object-oriented
programming (OOP), a proven software design and implementation
paradigm that helps reduce software complexity and improves code
maintainability.
The Cello framework is functionally decomposed into a collection
of software components. The Enzo-E application is implemented on
top of Cello, which is comprised of the components within the central
boxed region. Cello is in turn implemented using the Charm++
parallel programming system. Components in Cello are organized
into multiple layers, with software dependencies directed primarily
downwards; cross-cutting software concerns are also implemented as
components. Each component is composed of one or more inter-operating
C++ classes.
Enzo-E
Enzo-E is the astrophysics and cosmology application built on top
of the Cello scalable AMR framework. Enzo-E interfaces with
Cello primarily through C++ class inheritance of Cello classes
in the Simulation, Problem, Method, and Mesh
components. Due to the separation of concerns between Enzo-E and
Cello, development of Enzo-E requires no knowledge or awareness of
parallel programming, and development of Cello requires no
knowledge of specific numerical methods. This allows relatively
independent software development of Enzo-E by physical science and
numerical methods experts, and of Cello by computer science and
parallel programming experts.
High-level components
Top level components of Cello include Simulation, Problem,
and Method. A Simulation defines and manages a computational
astrophysics Problem, which defines physics, method, and data
structure Parameters, initial conditions, and boundary conditions.
The Simulation class, which is implemented as a Charm process
group, initializes and begins parallel execution of the simulation.
Method classes are used to implement individual numerical methods
that compute on Field (current) data on a block, as well as
Particle and Ray data (proposed).
Data structure components
Data structure components include the existing Mesh and Field
components, and the proposed Particle and Ray components, for
implementing the distributed computational data containers. The
Mesh component includes classes for representing and operating on
an adaptive mesh hierarchy, implemented as a fully-distributed
array-of-octrees. Octree nodes are associated with Blocks, which are
containers for the Field and other data, and implemented as a
Charm++ chare array.
Middle-level components
Middle-level components include Control, Parameters and Io
Control handles the time stepping of Method s to advance the
problem forward in time, as well as sequencing adaptive mesh
refinement data structure operations, including remeshing, scheduling
dynamic load balancing (which will be delegated to Charm++), and
refreshing ghost zones on Block boundaries. The Parameters
component serves to read, store, and provide access to parameters
defined in an input configuration file. To improve usability over
Enzo, configuration files are more structured, and support
floating-point and logical expressions to greatly simplify
initializing problems with complex initial conditions. The Io
component serves as a layer to coordinate the disk output of data
structure components, such as Simulation Hierarchy and
Field data. It calls the Disk component to handle actual file
operations.
Hardware-interface components
The lower-level hardware-interface components include Disk,
Memory and Parallel. The Disk component implements basic
disk operations, isolating the specific file format from the
higher-level Io component. Disk currently supports HDF5, and
we propose to support the Adaptable IO System (ADIOS) in the future to
enhance transfer of data to and from other HPC software
components. The Memory component controls dynamic memory
allocation and management. Currently Memory handles allocating
and monitoring heap memory usage; proposed functionality includes
allocating, deallocating, and transferring data between main memory,
hardware accelerator (GPU) memory, and many-core coprocessors
(e.g.~the Intel Xeon Phi). As with the Disk component, this
serves to isolate lower-level details from higher-level components.
The Parallel component currently supplies basic access to core
rank and core count, and is being depreciated.
Interface components
Interface components include Monitor (current) and Portal
(proposed). The Monitor component controls the user-readable
summary of progress to stdout, and the proposed Portal component
will control the interaction of Enzo-E with external applications
running concurrently, such as inline analysis or real-time
visualization. One particular such analysis and visualization
application is yt, which we will use to help drive the design and
development of the Portal component.
Cross-cutting components
Some Cello components can in principle be called from any software
layer—these include Performance and Error. The
Performance component dynamically collects performance data for
the running Enzo-E simulation, and provides a holistic summary of
performance data to the user, as well as to software components that
can adapt to optimize desired performance metrics. Current metrics
measured include memory usage (via the Memory component), and
computation amount and memory access amount (via the Performance
Application Programming Interface (PAPI). Future support will include
metrics for monitoring parallel communication, dynamic load balancing,
and disk usage. The Error component will be used to detect,
evaluate, and decide what to do about software errors; higher-level
error detection and recovery will be handled by Charm++, which
supports both simple checkpoint to disk, as well as double in-memory
checkpoint with automatic restart.