CorePy Synthetic Component Frameworks

From CorePy

Jump to: navigation, search

On PowerPC-based platforms (PPC32, PPC64, Cell SPU), CorePy provides a collection of synthetic components for common tasks. These include:

  • Variables that abstract basic register management and constant formation tasks.
  • Expressions use Python objects and operator overloading to generate instruction sequences using a more natural expression syntax.
  • Iterators use Python iterators to generate instructions for managing loops. The iterator classes support many different iteration semantics and allow for user defined loop semantics (e.g., auto-simdization)

[edit] Variables and Expressions

Easy access to low-level machine instructions is a double-edged sword. On one side, you have direct access to the full power of the processor. But, expressing common things can be tedious and make one long for high-level languages. CorePy's variable and expression libraries add support for building stronger type checking and building expressions for common operations.

Machine instructions, while technically only operating on the Register and Immediate types, imply a number of semantic types. For instance, add instructions may perform signed or unsigned addition. Selecting the wrong instruction can lead to obscure bugs. Of course, this is one of the value propositions for typed languages. Variables provide a solution to this for common types. Variables encapsulate a register and a collection of type-specific operations via overloaded operators. Typed variables can only be used with compatible variables. The type semantics are still evolving in CorePy, but they are similar to those found in C.

Types are found in arch/[ppc,vmx,spu,cal]/types/[ppc,vmx,spu,cal]_types.py. Each file has series of test cases demonstrating the available operators. (note: missing operators will be added over time, contributions are welcome!). For example, the SPU Bits type supports common logical operations and is the base type for the Halfword and Word types:

  ... setup active code ...
  import corepy.arch.spu.types.spu_types as var
 
  x = var.Bits(0)
  y = var.Bits(0)
  z = var.Bits(0)
 
  z.v = (x | y) & (x ^ y)
 
  proc.execute(code)

The example generates the instruction sequence suggested by the expression. Note the .v when the expression is assigned to z. Python's = operator cannot be overloaded directly and instead the special .v property triggers evaluation of the expression.

[edit] Iterators

One of the most common tasks in implementing high-performance kernels is writing loops. Managing loops at the instruction level is a tedious and error prone process and one of the best reasons to use compiled languages for high-performance code generation. CorePy Iterators are powerful Python iterators allow you to use Python loop syntax to generate high-performance loops. For example, a nested sum can be implemented using a CorePy Iterator:

  ... set active code ...
  import arch.ppc.lib.iterators as iter
  import arch.ppc.types.ppc_types as var
 
  a = var.UnsignedWord(0)
 
  for i in iter.syn_iter(code, 5):
    for j in iter.syn_iter(code, 5):
      for k in iter.syn_iter(code, 5):
        a.v = a + i + j + k
      
  util.return_var(a)
  a.release_register()
 
  proc = synppc.Processor()
  r = proc.execute(code)
  # r == 750

This example creates three nested loops. The induction variables on the loops are returned as CorePy variables and can be used in expressions.

The iterator library can be found in arch/[ppc,spu,etc.]/lib/iterators.py. PowerPC and SPU iterator types include iterators for scalar arrays, vector arrays (e.g., simple auto-simdization), Pythonic iteration (zip/range), thread/processor-parallel block decomposition (auto-natural parallelism), and stream buffer management for moving data to and from SPU local stores. x86, x86_64, and CAL support a subset of these. Explore the iterator files for examples.