The concepts used in mapping a Sequoia program to different target machines are independent of any specific mapping syntax. The Sequoia compiler currently supports an XML mapping file interface, although other interfaces are being actively developed, as the XML syntax is extremely verbose and inconvenient to use. The mapping information provided via the XML syntax is the same as is described in the Generic Mapping Concepts section.
XML Mapping File Template
The following is a template for an XML mapping file which includes all of the currently supported mapping directives. As shown in the example programs, an application need only adapt this template to its specific needs, picking and choosing which XML entries to use. Further, the Sequoia compiler is capable of producing an XML template which has been tailored to a Sequoia program, with the programmer then only having to "fill in the blanks".
<?xml version="1.0"?>
<mapping>
<!-- The machine description file to use. -->
<machine filename="cell.xml"/>
<!-- Do codegen for this top-level instance; this is the task instance -->
<!-- which may be called from external code. -->
<entrypoints> task_inst_name </entrypoints>
<!-- Each "base" task has a <taskmapping> entry. -->
<taskmapping name="task_name">
<!-- Each task instance has an <instance> entry. -->
<!-- There may be multiple instances defined of a single task. -->
<instance name="task_inst_name">
<!-- The task variant that this instance is instantiating. -->
<variant> variant_name </variant>
<!-- For external tasks only: -->
<!-- The name of the file containing the external implementation. -->
<filename> ext_file_name </filename>
<!-- For leaf tasks only, when the target is Cell: -->
<!-- On Cell, program code must be put into overlays. This flag, if present, -->
<!-- will force the object code for this leaf task to be in an overlay -->
<!-- by itself; without this flag, the compiler may try to pack some other -->
<!-- code into the overlay with the leaf object code. -->
<!-- Use this to reduce the size of an overlay. -->
<cellforceuniqueoverlay />
<!-- An integer constant assigned to a tunable parameter. -->
<tunable name="tunable_name" lexnum="0"> 64 </tunable>
<!-- Specifies a default memory level for all ctrl and data. -->
<!-- This will be overrided by "nested" <level> entries. -->
<level> 2 </level>
<!-- A <data> block specifies mapping details for program arrays. -->
<data>
<!-- Specifies a default memory level for all data objects. -->
<!-- This overrides an instance-wide <level> specification, -->
<!-- and is itself overrided by any per-array <level> entries. -->
<level> 2 </level>
<!-- Applies to leaf tasks only: -->
<!-- Specify that multiple arrays in the same instance will be -->
<!-- physically packed at the same memory address; this is in general -->
<!-- not "safe". An example of when it is safe is if an input and an -->
<!-- output array are traversed together sequentially, with an input -->
<!-- array element only being read before the corresponding output -->
<!-- array element is written. -->
<spaceshare> array1, array2, array3 </spaceshare>
<!-- An <array> block specifies mapping details for a single array. -->
<array name="array_name" lexnum="2">
<!-- Specifies the memory level of this array, overriding -->
<!-- any <level> entries "above" this. -->
<level> 2 </level>
<!-- An array precondition is used to assert that the -->
<!-- arguments are a certain size; before a task is called, -->
<!-- the precondition will be checked, and if false, the program -->
<!-- will raise an error. -->
<!-- There are two types of array preconditions: "numelmt", -->
<!-- and "pitch"; these correspond to the fields of the -->
<!-- same names in the sqArray_t structure in the Sequoia API. -->
<!-- It is not used to decide which task to call -->
<!-- Types are "boundabove", "exact", and "boundbelow". -->
<arraynumelmtprecond type="boundabove"> 1024,128 </arraynumelmtprecond>
<arraypitchprecond type="boundabove"> 1024,128 </arraypitchprecond>
</array>
</data>
<!-- A ctrl block specifies mapping details for program loops and callsites. -->
<ctrl>
<!-- Specifies a default memory level for all loops. -->
<!-- This overrides an instance-wide <level> specification, -->
<!-- and is itself overrided by any per-loop <level> entries. -->
<level> 0 </level>
<!-- A <loop> block specifies mapping details for a single -->
<!-- Sequoia loop: mappar, mapseq, or mapreduce.-->
<loop name="j" lexnum="0">
<!-- Specifies the memory level of this loop, overriding -->
<!-- any <level> entries "above" this. -->
<level> 0 </level>
<!-- Software-pipeline (SWP) this loop. The number specified -->
<!-- is the max number of stages; the compiler may use less -->
<!-- stages than this. -->
<!-- "1" would be the same as not software-pipelining at all. -->
<!-- Only mappar and mapreduce loops may be SW-pipelined. -->
<swp> 2 </swp>
<!-- Unroll this loop. The number specified is the unroll -->
<! count; 1 = not unrolled, 3 = three versions of loop, etc. -->
<unroll> 3 </unroll>
<!-- Flatten this loop. This means completely unrolling it, -->
<!-- so it's a loop of 1 iteration, and then actually removing -->
<!-- the loop and inlining its contained ops. -->
<!-- Only loops with constant iteration bounds can be flattened. -->
<flatten />
<!-- Spatially parallelize this loop, in a SPMD manner. -->
<!-- If the loop is mapped to memory level M and level M has -->
<!-- parallel control units or PEs, then the loop can be -->
<!-- SPMD-ized over them; this will distribute the iteration -->
<!-- space of the loop, with each parallel processor getting -->
<!-- an equal share the iterations. -->
<spmd>
<!-- The first time this is "seen" it sets the full SPMD width -->
<!-- within a memory level, and it is subsequently ignored. -->
<!-- This directive is necessary if N-way SPMD-ness will be -->
<!-- "built up" over multiple loops; for example, loop "i" -->
<!-- could be 2-way, and nested loop j could be 4-way, resulting -->
<!-- an 8-way parallelization. The outer loop in the nest (i) -->
<!-- would specify the <fullrange> of the SPMD-ization. -->
<fullrange> 0,8 </fullrange>
<!-- Number of ways to parallelize this loop, up to the full -->
<!-- SPMD width. -->
<ways> 4 </ways>
<!-- Number of ways can also be "auto", and will be filled in to -->
<!-- bring the SPMD-ness up to the fill SPMD width. -->
<!-- (Either specify an integer, or "auto", for <ways>, not both.) -->
<ways> auto </ways>
<!-- The loop iterations are divided over the parallel PEs -->
<!-- in chunks of "iterblk" iterations; it's a block-cyclic -->
<!-- distribution. -->
<iterblk> 16 </iterblk>
</spmd>
</loop>
<!-- A <callsite> block specifies mapping details for a -->
<!-- task callsite in the Sequoia code. Multiple candidate instances -->
<!-- can be specified, with calling conditions selecting which to call. -->
<callsite name="callee_task_name" lexnum="2">
<!-- A candidate task instance to call at this callsite. -->
<!-- If there are multiple candidates, then the conditions -->
<!-- of each are tried, in the order they are listed here, -->
<!-- until one of the candidate's conditions evaluate to true, -->
<!-- and that is the instance which will be called. -->
<target name="task_inst_name">
<!-- Conditions; call this target if they are ALL true. --%gt;
<!-- That is, it's an "AND". -->
<!-- Only call this instance if the specified array in the -->
<!-- Sequoia task has a certain size. -->
<!-- Note that the array referred to is an array in the calling -->
<!-- task, not the callee task. -->
<!-- Arraysizecond types are "boundabove", "exact", "boundbelow" -->
<arraysizecond name="array_name1" type="boundabove"> 16,32 </arraysizecond>
<!-- A condition on number of times this instance has been "called", -->
<!-- in top-down, runtime program order. -->
<!-- Note that by "called", it means that this instance was -->
<!-- selected to be called at a callsite, and in the case of -->
<!-- a callsite in a loop, the selection only happens once, with -->
<!-- every iteration calling the same instance. -->
<!-- Types are "lt", "leq", "eq", "geq", "gt" -->
<numinstcond type="leq"> 3 </numinstcond>
<!-- Override to specify to always call the task dynamically. -->
<!-- Never statically expand the call graph in the compiler -->
<!-- through this callsite. -->
<forcedynamiccall />
<!-- Override to specify that the CBVR copy of this argument -->
<!-- mustn't be eliminated by the compiler. -->
<forcecopy name="array_name1" />
</target>
</callsite>
</ctrl>
</instance>
</taskmapping>
</mapping>
|
Below is the same template, without all the comments.
<?xml version="1.0"?>
<mapping>
<machine filename="cell.xml"/>
<entrypoints> task_inst_name </entrypoints>
<taskmapping name="task_name">
<instance name="task_inst_name">
<variant> variant_name </variant>
<filename> ext_file_name </filename>
<cellforceuniqueoverlay />
<tunable name="tunable_name" lexnum="0"> 64 </tunable>
<level> 2 </level>
<data>
<level> 2 </level>
<spaceshare> array1, array2, array3 </spaceshare>
<array name="array_name" lexnum="2">
<level> 2 </level>
<arraynumelmtprecond type="boundabove"> 1024,128 </arraynumelmtprecond>
<arraypitchprecond type="boundabove"> 1024,128 </arraypitchprecond>
</array>
</data>
<ctrl>
<level> 0 </level>
<loop name="j" lexnum="0">
<level> 0 </level>
<swp> 2 </swp>
<unroll> 3 </unroll>
<flatten />
<spmd>
<fullrange> 0,8 </fullrange>
<ways> 4 </ways>
<ways> auto </ways>
<iterblk> 16 </iterblk>
</spmd>
</loop>
<callsite name="callee_task_name" lexnum="2">
<target name="task_inst_name">
<arraysizecond name="array_name1" type="boundabove"> 16,32 </arraysizecond>
<numinstcond type="leq"> 3 </numinstcond>
<forcedynamiccall />
<forcecopy name="array_name1" />
</target>
</callsite>
</ctrl>
</instance>
</taskmapping>
</mapping>
|
Naming Program Objects
The mapping file needs to be able to name objects in the Sequoia source code, such as loop variables, arrays, callsites, and tunable parameters. In the case that these names are unique within a Sequoia task variant, the symbolic name itself can be used to identify the program object that is being mapped. For example, if the array A was being mapped, then the following would be the XML code to refer to this array:
<array name="A">
...
</array>
|
If there are multiple objects in a task with the same name, then the lexnum field can be used to identify which one is being referred to, where lexnum="X" would refer to the (X+1)th version of the symbol, in the program's lexical order (starting counting from 0). For example, the following would be a mapping entry for the third array B defined in a task:
<array name="B" lexnum="2">
...
</array>
|