The standalone compiler: ohuac¶
The ohuac executable is a standalone program which can compile a source file
written in one of the ohua Frontends for ohua algorithms and generate code for various platforms.
Getting it¶
Prebuilt binaries are available for 64bit Linux and OSX. Provided for each release by Travis CI.
Simply download the appropriate executable for you platform (ohuac-linux or
ohuac-osx) from the releases page.
Building from source / Getting the source code¶
The source code for the compiler can be found on GitHub. However major parts of the compiler are separate libraries. For more information on the repository structure see the project organisation page.
ohuac is written in Haskell and uses the stack tool for building and dependency management.
If you have stack installed already you can simply download the source from the
releases page and run stack install.
This downloads and builds all dependencies, as well as the Haskell compiler
ghc, should it not be present already. It should not interfere with any
system-level libraries, Haskell ecosystems etc.
It builds the executable ohuac and copies it to ~/.local/bin. If you do
not wish this use stack build instead and find the path of the finished
binary using stack exec -- which ohuac afterwards. After building the binary
can be freely moved to any location on the system.
Usage¶
The capabilities and options for the compiler can be interactively explored by
calling ohuac --help or ohuac COMMAND --help to get help for a specific
COMMAND.
The build command¶
The most common command is build.
The build command transitively builds your ohua modules. This means it not only compiles the one module you directly specify but also all modules it may depend on.
Currently the search path for modules cannot be influenced. Therefore they must
be in a specific location, which is module/submodule.ohuac. The type of file
(.ohuac or .ohuas) does not matter in this case. In fact they can also be
mixed. A ohuas file can import a module that is defined as a ohuac file.
As an example we may have a module A.ohuac, which depends on foo.bar.B
and foo.C.
A
|-- foo.bar.B
'-- foo.C
During compilation the compiler will look for these dependencies
at foo/bar/B.ohuac or foo/bar/B.ohuas and foo/C.ohuac or
foo/C.ohuas. All paths being relative to the current working directory.
So if the compiler was called with ohuac build A.ohuac, the working
directory is expected to look something like this
WORKING_DIR/
|-- A.ohuac
'-- foo/
|--bar/
| '-- B.ohuac
'-- C.ohuas
If both an .ohuac and .ohuas file is found for a particular dependency
the compiler will exit with an error.
Universal options¶
The options listed in ohuac --help apply to all subcommands. They are
generally prepended to the options passed to the subcommand.
Supported targets for code generation¶
The standalone compiler currently supports two compilation targets. One is a universal format, which simply encodes the dataflow graph directly in JSON and a second which creates a java class.
JSON Graph repesentation¶
The JSON output from ohua is selected with the -g json-graph option.
The default file extension is .ohuao.
This representation only encodes the dataflow graph and the stateful functions
used. It is intended to be a universal, easily to use intermediate for backeds
which have no direct support in ohuac yet. Such a backend only has to define
the runtime for the dataflow execution and the loading and linking of stateful
functions, ohuac will take care of parsing, interpreting and optimising the
algorithms.
A simple runnable java class¶
The -g simple-java-class code gen option is a very lightweight code
generation for the java platform.
It generates a class where the module path is its package and the algorithm name
is the name of the class. E.g. namespace foo.bar.baz with the main
algorithm selected generates a class foo.bar.baz.Main.
For an algorithm main with arguments A, B, C and return type of D,
the class has the following structure
class Main {
public static C invoke(A argument0, B argument1, C argument2);
public static Configured configure(RuntimeProcessConfiguration configuration);
public static class Configured {
public Prepared prepare(A argument0, B argument1, C argument2);
}
public static class Prepared {
public static D invoke();
}
}
The argument and return types default to Object.
The structure of the class follows a simple schema. Each algorithm class has two
static methods invoke and configure. invoke simply executes the
algorithm with the default runtime parameters. configure allows
customization of runtime parameters.
Furthermore there are always two inner classes, Configured and Prepared.
The two inner classes represent stages of algorithm configuration.
Configured is a graph with an associated runtime configuration and can be
turned into a Prepared by calling prepare with the arguments specified
in the algorithm description.