Copernicus: Generating Code from polymorphic components and heterogenous models.


Researchers: Stephen Neuendorffer and Christopher Hylands
Advisor:Edward A. Lee

The high-level of abstraction possible in component-based modeling offers many advantages, such as simulation speed, the strength of formal models of computation, etc. However, the fundamental weakness of high-level modeling is the difficulty of actual implementation. Traditionally the easiest way to get high performance has been to translate the model by hand into a low-level implementation language. Automatic code generation from the model is sometimes possible by assembling the component specifications, but only with serious performance penalties.

These penalties come from several sources:

  1. A component in the modeling environment is inevitably built to be easy to design with. Components can often accept a variety of data types (type-polymorphism), can be used in a variety of control or communication models (domain-polymorphism), can be configured with different parameters (operational-polymorphism), and can be used in any environment (context-polymorphism). This flexibility directly conflicts with the goals of most optimized implementations.
  2. A model consists of components, their ports, and the connections between those ports. The model of computation associated with a model determines how connected components communicate and control their execution. In some cases the boundaries of components correspond to physical boundaries of the implemented system. For example, there might be one component for each physical processor that is connected to a system bus. However, the boundaries of components often have no physical importance in a system. They are specified arbitrarily by the system designer, or because of the social structure of group designing the model, or because of the availability of reusable components. Simple code generation strategies blindly preserve the structure of the model, which can result in unnecessary overhead.
At some level, these problems can be ameliorated using traditional code generation strategies. If a component is too flexible to generate good code, then it can be replaced with a specialized hand-written version. If there is unnecessary structure in the model, then change the model so that the structure is removed. However, these solutions conflict directly with good engineering practice, and greatly complicate the implementation procedure.

We are developing a code generation strategy that attempts to handle these difficulties automatically. The key idea is that we combine code generation from a model with compilation of the code for individual actors. We call this strategy Co-compilation. This strategy directly addresses the difficulties above. We parse the code for an actor and specialize it according to its use in a particular model (the types, the particular domain, the values of parameters and the connections that have been made to it). We can also perform cross-actor optimizations to eliminate or reorganize the structure of a model.

Co-compilation also offers a straightforward path to code generation from heterogenous models that contain different communication and control strategies organized in a hierarchical structure. We anticipate being able to generate code for a model at one level of the hierarchy and then use the generated code as a component at a higher level of the hierarchy. This can result in reduced overhead as well, since a system designer is not limited to a single model of computation.

We have implemented this code-generation strategy as the Copernicus package, which is part of Ptolemy II. Copernicus parses the Java bytecode for actors, optimizes it, combines it with code generation from the model and outputs Java bytecode. The resulting generated code is currently useful for high-speed compiled code simulation. We are currently exploring how to generated code for embedded architectures and for FPGAs.

Last updated 11/18/02