Code Generation

This code generator is patterned after the Ptolemy Classic code generator where actors have template files consisting of code blocks. The code blocks are stitched together to create the resulting file.

Ptolemy II includes two code generators, one in $PTII/ptolemy/codegen that is no longer being developed and $PTII/ptolemy/cg, which is under active development.

Simple Demo

  1. Generate HTML code that describes a model.
    If you are viewing this page from within vergil, open $PTII/ptolemy/cg/adapter/generic/html/demo/HierarchicalModel/HierarchicalModel.xml
    If you are viewing this page from a browser, start vergil with: $PTII/bin/vergil /Users/cxh/ptII/ptolemy/cg/adapter/generic/html/demo/HierarchicalModel/HierarchicalModel.xml
  2. Click on the HTMLCodeGenerator icon.
  3. A dialog box will appear, click on "Generate"
  4. An HTML description of the model will be generated and displayed.

Java Command Line Demo

To generate Java code for a simple model, run:
$PTII/bin/ptcg -language java $PTII/ptolemy/cg/kernel/generic/program/procedural/java/test/auto/Display.xml 
or
java -classpath $PTII ptolemy.cg.kernel.generic.GenericCodeGenerator -language java $PTII/ptolemy/cg/kernel/generic/program/procedural/java/test/auto/Display.xml

Package overview

The cg facility uses an adapter pattern where classes in a regular Ptolemy II model have corresponding classes in the cg facility.

The cg subpackages are structured so that language specific code is separate from generic code.

The main entry point is $PTII/ptolemy/cg/kernel/generic/GenericCodeGenerator.java. This file is invoked by $PTII/bin/ptcg. To get the complete list of options, run $PTII/bin/ptcg -help.

To invoke the cg code generator from the GUI, drag in a code generator attribute from More Libraries -> CodeGenerators ->CGCodegen.

The ptolemy/cg directory has these subdirectories:

ptolemy/cg/adapter
Language specific adapters classes that correspond with regular Ptolemy II classes.
ptolemy/cg/gui
Graphical User Interface (gui) code. If a model has a ptolemy.cg.gui.CodeGeneratorGUIFactory attribute in it, then double clicking on that attribute brings up the code generator gui.
ptolemy/cg/kernel
Non-language specific code generation classes and language-specific type information.
ptolemy/cg/lib
Modular code generation work and syntactic code generation work


FIXME: Not updated below here
FIXME: Not updated below here
FIXME: Not updated below here

Other Codegen Demonstrations

Limitations

This is a highly preliminary code generator facility, with many limitations. It is best viewed as a concept demonstration.

FAQ

Problems Generating Code

Generating code results in IOException: java.io.IOException: CreateProcess: make -f Model.mk error=2
This will happen if make is not in your path. Under Windows, you may need to install Cygwin, see the Ptolemy II Cygwin installer. Under Windows, if Cygwin is installed, then be sure that C:\cygwin\bin is in your Windows path. To edit your path, do Start Menu -> Settings -> Control Panels -> System -> Advanced -> Environment Variables.
Models that use a plotter fail to compile.
Models that use the plotter use the Java Native Interface (JNI) to invoke the plotter from within the C process. This is done so that the plotter is interactive while the model is running as opposed to plotting the data after the model completes. The JNI facility requires that a Java Development Kit (JDK) be installed instead of a Java Runtime Environment (JRE). The Ptolemy II Windows installer includes a JRE which is optionally installed. If the Windows installer is installed with the bundled JRE, then models that use the plotter will probably fail to compile with message like:
make: *** [Ramp] Error 1

Problems Running

Models that use the plotter require setup
To properly run a model that has a plotter, you must have jvm.dll in your path. If you do not, then when you run the executable, it will immediately exit with no message! For example, place
C:\Progra~1\Java\jdk1.5.0_11\jre\bin\client
in your path. If you are running Vergil from the command line as $PTII/bin/ptinvoke, then this has been handled for you. If you are running via Eclipse, then you must update your path by hand.
When in Windows, clicking on a .exe produced by the code generator fails to start up. The message is:
The procedure entry point _impure_ptr could not be located in the dynamic link library cygwin1.dll
The solution is to add C:\cygwin\bin to the Windows path by doing: Start Menu -> Settings -> Control Panels -> System -> Advanced -> Environment Variables and adding C:\cygwin\bin to the path.
To get rid of the console, compile with the exe with -mwindows:
make -f Model.mk CC_FLAGS=-mwindows

Extending the Code Generator

Why are some of my ports being generated as Tokens in the C output?
The simple rule for the the type resolution in codegen is that any resolved Ptolemy types the codegen kernel defines to be non-primitive will be Token type in the generated code. User code (helper classes) is responsible for making the distinction between different data types, which mean the helper code may have different code blocks for handling different resolved type in the generated code. The CodeGeneratorHelper.isPrimitive() method is what is used to determine if a type is primitive. Also, a good example to look at is the codegen/c/actor/lib/ArrayElement helper.
How do I get timing data from the C output?
At the top of the generated C file, insert
#include <sys/time.h>
At the beginning of main() method, insert:
struct timespec start, end;
double dT = 0.0;
clock_gettime(CLOCK_REALTIME, &start);
Toward the end of main() method, insert:
clock_gettime(CLOCK_REALTIME, &end);
dT = end.tv_sec - start.tv_sec + (end.tv_nsec - start.tv_nsec) * 1.0e-9;
printf("execution time: %g seconds\n", dT);
You can also get the time resolution of your system by inserting the following code:
struct timespec res;
clock_getres(CLOCK_REALTIME, &res);
printf(" time resolution: %ld ns\n", res.tv_nsec);
A test is failing, the output code is confusing, what do I do?

Try creating the smallest possible test case and run it using $PTII/bin/ptcg.

Try using the -verbosity 10 command line argument option to $PTII/bin/ptcg. This will cause the comments to include the classname where the comment() method was called.

By hand, modify the output code so that it works and then change the code generator. For example, if the command is $PTII/bin/ptcg -language java Foo.xml, then the file to modify will be ~/cg/Foo.java. To compile the file, run (cd ~/cg; make -f Foo.mk run).

Porting from ptolemy/codegen
When porting code from ptolemy/codegen, the primary issue is finding where to put the classes. Looking at the mapping for c and java files from codegen to cg can be helpful. In general, files that generate language-specific code for actors ends up in ptolemy.cg.adapater. Language-specific type code ends up in ptolemy.cg.kernel.

Compiling Large C Files

make -f ModelName.mk WARNING_CC_FLAGS= USER_CC_FLAGS="-pipe -O0
--verbose -Q"
Each of the options above:
No -Wall
avoid any optimization
-pipe
avoid temporary files
-O0
avoid optimization
--verbose
print out steps
-Q
print out summary information.