[Swift-commit] r8393 - in www/Swift-T: . downloads
wozniak at ci.uchicago.edu
wozniak at ci.uchicago.edu
Fri Mar 13 15:03:05 CDT 2015
Author: wozniak
Date: 2015-03-13 15:03:05 -0500 (Fri, 13 Mar 2015)
New Revision: 8393
Modified:
www/Swift-T/downloads/examples.tar.gz
www/Swift-T/guide.html
www/Swift-T/leaf.html
Log:
Fix in leaf examples
Modified: www/Swift-T/downloads/examples.tar.gz
===================================================================
(Binary files differ)
Modified: www/Swift-T/guide.html
===================================================================
--- www/Swift-T/guide.html 2015-03-13 17:55:23 UTC (rev 8392)
+++ www/Swift-T/guide.html 2015-03-13 20:03:05 UTC (rev 8393)
@@ -830,9 +830,15 @@
</li>
<li>
<p>
-Source distributions are available at the <a href="http://www.tcl.tk">Tcl web site</a>
+Source distributions are available at the <a href="http://www.tcl.tk">Tcl web
+site</a>
</p>
</li>
+<li>
+<p>
+Tcl 8.5 is also acceptable.
+</p>
+</li>
</ul></div>
</li>
<li>
@@ -1091,7 +1097,7 @@
</p>
</dd>
<dt class="hdlist1">
-<code>-T</code>
+<code>-f</code>
</dt>
<dd>
<p>
@@ -1099,7 +1105,7 @@
</p>
</dd>
<dt class="hdlist1">
-<code>-t</code>
+<code>-F</code>
</dt>
<dd>
<p>
@@ -1112,30 +1118,29 @@
<div class="sect1">
<h2 id="_program_structure">4. Program structure</h2>
<div class="sectionbody">
-<div class="paragraph"><p>Swift programs are composed of <em>composite</em> functions. These
-share syntax with C-like languages. The program starts in <code>main()</code>.
-The following is a complete Swift program:</p></div>
+<div class="paragraph"><p>Swift is a language with C-like syntax. Hello world is written as:</p></div>
<div class="listingblock">
<div class="content">
-<pre><code>main
-{}</code></pre>
-</div></div>
-<div class="paragraph"><p>STC input is preprocessed by <code>cpp</code>, the C preprocessor.</p></div>
-<div class="paragraph"><p>Hello world is written as:</p></div>
-<div class="listingblock">
-<div class="content">
<pre><code>import io;
-main
-{
- printf("Hello world");
-}</code></pre>
+
+printf("Hello world");</code></pre>
</div></div>
<div class="paragraph"><p>The newline is supplied by <code>printf()</code>.</p></div>
-<div class="paragraph"><p>Swift programs eventually call <em>leaf</em> functions, which are the primary
-way to do work. From the perspective of the Swift script, they are
+<div class="paragraph"><p>Swift programs are composed of
+<em>composite</em> functions containing Swift code, <em>top-level</em> Swift code
+outside of composite functions, and <em>leaf</em> functions that wrap
+non-Swift code, for example native code functions or
+external application programs.</p></div>
+<div class="paragraph"><p>In typical Swift programs, leaf functions do the computational
+heavy-lifting, while Swift code provides the "glue" to compose
+leaf functions into a complete application.
+From the perspective of the Swift programmer, leaf functions
atomic operations that wait for input variables and set output
-variables. They may be implemented as native code functions or
-external application programs.</p></div>
+variables.</p></div>
+<div class="paragraph"><p>The definition of a function can come before or after the usage
+in the Swift source code. E.g. a function defined on line 100
+of a Swift source file can be called at line 10.</p></div>
+<div class="paragraph"><p>STC input is preprocessed by <code>cpp</code>, the C preprocessor.</p></div>
</div>
</div>
<div class="sect1">
@@ -1214,8 +1219,67 @@
</div>
</div>
<div class="sect1">
-<h2 id="_dataflow_evaluation">7. Dataflow evaluation</h2>
+<h2 id="_variable_declarations">7. Variable declarations</h2>
<div class="sectionbody">
+<div class="paragraph"><p>Swift is a statically and strongly typed language. Thus, every variable
+in the program must have a fixed type at compile time and types are,
+with limited exceptions, not automatically converted.</p></div>
+<div class="paragraph"><p>To declare a variable in Swift code, you must declare it with
+one of following variations of the variable declaration syntax:</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code><type> <variable name>;
+<type> <variable name> = <expression>;
+<variable name> = <expression>;</code></pre>
+</div></div>
+<div class="paragraph"><p>For example:</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>int x;
+int x = 1;
+x = 1;</code></pre>
+</div></div>
+<div class="paragraph"><p>In the last two cases, the variable is declared and assigned in the
+same statement.
+In the first two cases, the type of the variable is explicitly specified
+by the programmer. In the last case, where the type of the variable is
+omitted and there was no prior declaration of the variable, then the
+type of the variable is automatically inferred based on the type of the
+expression on the right hand side of the assignment.</p></div>
+<div class="paragraph"><p>The scope of a variable is limited to the code block in which the declaration
+appears. Two variables with the same name cannot be declared in the same
+block. <strong>Shadowing</strong> of variables, where a variable has the same name as
+a variable in an outer scope, is also not allowed in Swift. This language
+design decision is intended to eliminate some common programming errors.</p></div>
+<div class="paragraph"><p>This is shadowing and will result in a compile error:</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>int x;
+{
+ int x;
+}</code></pre>
+</div></div>
+<div class="paragraph"><p>This is not shadowing, because the scopes of the two declarations of x do not
+overlap, and is allowed:</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>{
+ int x;
+}
+{
+ int x;
+}</code></pre>
+</div></div>
+<div class="paragraph"><p>Variables, functions, and types share the same namespace so it is possible
+for a variable’s name to shadow a function’s name. This is allowed in
+the specific case when a local variable has the same name as a global function
+(although it will not be possible to use the function within the scope
+where it has been shadowed).</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_dataflow_evaluation">8. Dataflow evaluation</h2>
+<div class="sectionbody">
<div class="paragraph"><p>Swift expressions are evaluated in <em>dataflow</em> order:</p></div>
<div class="listingblock">
<div class="content">
@@ -1243,11 +1307,10 @@
</div>
</div>
<div class="sect1">
-<h2 id="_composite_functions">8. Composite functions</h2>
+<h2 id="_composite_functions">9. Composite functions</h2>
<div class="sectionbody">
-<div class="paragraph"><p>Swift code is written in composite functions. The composite function
-<code>main</code> is required.</p></div>
-<div class="paragraph"><p>Composite functions have the form:</p></div>
+<div class="paragraph"><p>Composite functions provide a way to organise and reuse Swift code.
+They have the form:</p></div>
<div class="listingblock">
<div class="content">
<pre><code>[(<output list>)] function_name [(<input list>)]
@@ -1266,10 +1329,18 @@
// or equivalently:
(x1, x2) = f(i1, i2);</code></pre>
</div></div>
+<div class="ulist"><ul>
+<li>
+<p>
+<strong>Note:</strong> If a composite function named <code>main</code> is provided, it is
+ automatically run at the start of the program.
+</p>
+</li>
+</ul></div>
</div>
</div>
<div class="sect1">
-<h2 id="_types">9. Types</h2>
+<h2 id="_types">10. Types</h2>
<div class="sectionbody">
<div class="paragraph"><p>Swift provides a similar range of primitive types to many other
programming languages. Files are a primitive type in Swift, unlike
@@ -1277,7 +1348,7 @@
that merit special mention.
Two basic kinds of data structure are provided: arrays and structs.</p></div>
<div class="sect2">
-<h3 id="_primitive_types">9.1. Primitive types</h3>
+<h3 id="_primitive_types">10.1. Primitive types</h3>
<div class="paragraph"><p>Swift has the conventional types:</p></div>
<div class="dlist"><dl>
<dt class="hdlist1">
@@ -1456,7 +1527,7 @@
</ul></div>
</div>
<div class="sect2">
-<h3 id="_files">9.2. Files</h3>
+<h3 id="_files">10.2. Files</h3>
<div class="paragraph"><p>A file is a first-class entity in Swift that in many ways can be treated
as any other variable. The main difference is that a file can be
<strong>mapped</strong> to path in a filesystem. Assigning to a mapped file variable
@@ -1471,12 +1542,9 @@
the following Swift program will copy the file to <code>/home/user/out.txt</code>.</p></div>
<div class="listingblock">
<div class="content">
-<pre><code>main
-{
- file x = input_file("/home/user/in.txt");
- file y <"/home/user/out.txt">; // Declare a mapped file
- y = x; // Do the copy
-}</code></pre>
+<pre><code>file x = input_file("/home/user/in.txt");
+file y <"/home/user/out.txt">; // Declare a mapped file
+y = x; // Do the copy</code></pre>
</div></div>
<div class="paragraph"><p>A range of functions to work with files are provided in the
<code>files</code> library module.</p></div>
@@ -1496,13 +1564,38 @@
// Find the name of a file with filename
trace("Temporary filename is: " + filename(tmp));</code></pre>
</div></div>
-<div class="paragraph"><p>Temporary files are created as necessary if unmapped files are
-written to. For example, the file <code>tmp</code> in the above code snippet.
-This feature is implemented by calling GNU <code>mktemp</code> with suffix
-<code>.turbine</code>; thus, the directory is set with environment variable
-<code>TMPDIR</code> which defaults to <code>/tmp</code>.</p></div>
-<div class="paragraph"><p>Currently Swift/T assumes that the file system is shared among
-all nodes.</p></div>
+<div class="paragraph"><p><a id="unmapped_files"></a>
+Temporary files are created as necessary if unmapped files are
+written to, for example, the file <code>tmp</code> in the code snippet above.
+This file is created in <code>/tmp</code> by default unless
+<a href="#env_swift_tmp">overridden by <code>SWIFT_TMP</code></a>.</p></div>
+<div class="paragraph"><p>The way this feature is implemented depends on the Tcl version:</p></div>
+<div class="dlist"><dl>
+<dt class="hdlist1">
+8.5
+</dt>
+<dd>
+<p>
+Implemented by calling system command <code>mktemp</code>. The directory
+may be set with environment variable <code>TMPDIR</code> which defaults to
+<code>/tmp</code>, or <code>SWIFT_PATH</code>. The filename will contain <code>.turbine</code> in the
+middle or as a suffix, depending on <code>mktemp</code> implementation.
+</p>
+</dd>
+<dt class="hdlist1">
+8.6
+</dt>
+<dd>
+<p>
+Implemented with a Tcl builtin. File always has suffix
+<code>.turbine</code>.
+</p>
+</dd>
+</dl></div>
+<div class="paragraph"><p>Swift/T assumes that the file system is shared among all nodes. Set
+<code>SWIFT_TMP</code> to a shared file system for best results when running
+across nodes. (The directory <code>/tmp</code> is usually a fast local file
+system and cleared on system reboot.)</p></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
@@ -1526,7 +1619,7 @@
</div>
</div>
<div class="sect2">
-<h3 id="_blobs">9.3. Blobs</h3>
+<h3 id="_blobs">10.3. Blobs</h3>
<div class="paragraph"><p>Blobs represent raw byte data. They are primarily used to pass
data to and from native code libraries callable from Swift. They are
like Swift strings but may contain arbitrary data.</p></div>
@@ -1534,7 +1627,7 @@
blobs to and from Swift types, and pass blobs to leaf functions.</p></div>
</div>
<div class="sect2">
-<h3 id="_arrays">9.4. Arrays</h3>
+<h3 id="_arrays">10.4. Arrays</h3>
<div class="paragraph"><p>Arrays can be declared with empty square brackets:</p></div>
<div class="listingblock">
<div class="content">
@@ -1596,7 +1689,7 @@
</div></div>
</div>
<div class="sect2">
-<h3 id="_nested_arrays">9.5. Nested arrays</h3>
+<h3 id="_nested_arrays">10.5. Nested arrays</h3>
<div class="paragraph"><p>Swift allows arrays of arrays: nested arrays. They can be declared and
assigned as follows:</p></div>
<div class="listingblock">
@@ -1613,7 +1706,7 @@
(e.g. <code>A[i][j] = …</code>).</p></div>
</div>
<div class="sect2">
-<h3 id="_structs">9.6. Structs</h3>
+<h3 id="_structs">10.6. Structs</h3>
<div class="paragraph"><p>In Swift, structs are defined with the <code>type</code> keyword. They define
a new type.</p></div>
<div class="listingblock">
@@ -1655,9 +1748,15 @@
<pre><code>people[2].name = "Abe"; // Not supported!
people[2].age = 90; // Not supported!</code></pre>
</div></div>
+<div class="paragraph"><p>It is possible to construct a struct by invoking the type name
+as if it is a function:</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>person p3 = person("Nguyen", 42);</code></pre>
+</div></div>
</div>
<div class="sect2">
-<h3 id="_defining_new_types">9.7. Defining new types</h3>
+<h3 id="_defining_new_types">10.7. Defining new types</h3>
<div class="paragraph"><p>Swift has two ways to define new types based on existing types.</p></div>
<div class="paragraph"><p>The first is <code>typedef</code>, which creates a new name for the type.
The new type and the existing type will be completely interchangeable,
@@ -1667,12 +1766,10 @@
<div class="content">
<pre><code>typedef newint int;
-main {
- // We can freely convert between int and newint
- newint x = 1;
- int y = x;
- newint z = y;
-}</code></pre>
+// We can freely convert between int and newint
+newint x = 1;
+int y = x;
+newint z = y;</code></pre>
</div></div>
<div class="paragraph"><p>The second is with <code>type</code>, which creates a new type that is a
specialization of an existing type. That is, it is a distinct
@@ -1695,52 +1792,54 @@
"/usr/bin/uniq" i @stdout=o
}
-main {
- file unsorted = input_file("input.txt");
- sorted_file sorted <"sorted.txt"> = sort(unsorted);
- file u <"unique.txt"> = unique(sorted);
+file unsorted = input_file("input.txt");
+sorted_file sorted <"sorted.txt"> = sort(unsorted);
+file u <"unique.txt"> = unique(sorted);
- // Can convert from sorted_file to file
- file result2 = sort(unsorted);
+// Can convert from sorted_file to file
+file result2 = sort(unsorted);
- // This would cause a type error
- // sorted_file not_sorted = unsorted;
-}</code></pre>
+// This would cause a type error
+// sorted_file not_sorted = unsorted;</code></pre>
</div></div>
</div>
<div class="sect2">
-<h3 id="_global_constants">9.8. Global Constants</h3>
-<div class="paragraph"><p>Swift supports a basic feature for defining globally visible constants. You
-can use the <code>global const</code> statement at the top level of the program. The
-syntax only supports literals of scalar types: e.g. integer literals, floating
-point literals and string literals.</p></div>
+<h3 id="_global_variables">10.8. Global Variables</h3>
+<div class="paragraph"><p>Variables defined at the top level of a Swift program are in
+global scope and can be used anywhere
+Swift supports a basic feature for defining globally visible constants.</p></div>
+<div class="paragraph"><p>You can use global variables to define program-wide constants: the
+single assignment semantics of Swift mean that they variables cannot
+be reassigned elsewhere in the program.</p></div>
<div class="listingblock">
<div class="content">
-<pre><code>global const string hello = "Hello World";
-global const float pi_approx = 3.142;
-global const int ONE = 1;
+<pre><code>string HELLO = "Hello World";
+float PI_APPROX = 3.142;
+int ONE = 1;
-main () {
- trace(hello, pi_approx, ONE);
-}</code></pre>
+trace(HELLO, PI_APPROX, ONE);</code></pre>
</div></div>
-<div class="paragraph"><p><strong>Note:</strong> global constants provide no performance benefit compared with
-variables initialized to constant values at optimization levels <code>O1</code>
-or greater.</p></div>
-<div class="paragraph"><p><strong>Note:</strong> better support is planned in future for more flexible support for
-global variables and code.</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+<strong>Note:</strong> You can also define global constants with the syntax
+ <code>global const <name> = <value>;</code>, e.g. <code>global const X = 1;</code>.
+ This syntax offers no advantages and is deprecated.
+</p>
+</li>
+</ul></div>
</div>
</div>
</div>
<div class="sect1">
-<h2 id="_control_structures">10. Control structures</h2>
+<h2 id="_control_structures">11. Control structures</h2>
<div class="sectionbody">
<div class="paragraph"><p>Swift provides control structures that may be placed as statements
-inside a composite function.</p></div>
+in Swift code.</p></div>
<div class="sect2">
-<h3 id="_conditionals">10.1. Conditionals</h3>
+<h3 id="_conditionals">11.1. Conditionals</h3>
<div class="sect3">
-<h4 id="_if_statement">10.1.1. If statement</h4>
+<h4 id="_if_statement">11.1.1. If statement</h4>
<div class="paragraph"><p>If statements have the form:</p></div>
<div class="listingblock">
<div class="content">
@@ -1759,7 +1858,7 @@
execute until the value of the condition expression is available.</p></div>
</div>
<div class="sect3">
-<h4 id="_switch_statement">10.1.2. Switch statement</h4>
+<h4 id="_switch_statement">11.1.2. Switch statement</h4>
<div class="listingblock">
<div class="content">
<pre><code>int a = 20;
@@ -1782,10 +1881,10 @@
</div>
</div>
<div class="sect2">
-<h3 id="_iteration">10.2. Iteration</h3>
+<h3 id="_iteration">11.2. Iteration</h3>
<div class="paragraph"><p>Iteration is performed with the <code>foreach</code> and <code>for</code> statements.</p></div>
<div class="sect3">
-<h4 id="_foreach_loop">10.2.1. Foreach loop</h4>
+<h4 id="_foreach_loop">11.2.1. Foreach loop</h4>
<div class="paragraph"><p>The <code>foreach</code> loop allows for parallel iteration over an array:</p></div>
<div class="listingblock">
<div class="content">
@@ -1809,7 +1908,7 @@
</div></div>
</div>
<div class="sect3">
-<h4 id="_for_loop">10.2.2. For loop</h4>
+<h4 id="_for_loop">11.2.2. For loop</h4>
<div class="paragraph"><p>The <code>for</code> loop allows for sequential iteration. This example
implements a counter based on the return values of a function that
accepts integers:</p></div>
@@ -1852,7 +1951,7 @@
</div>
</div>
<div class="sect2">
-<h3 id="_explicit_data_dependent_execution">10.3. Explicit data-dependent execution</h3>
+<h3 id="_explicit_data_dependent_execution">11.3. Explicit data-dependent execution</h3>
<div class="paragraph"><p>In general, execution ordering in Swift/T is implicit and driven by
data dependencies. In some cases it is useful to add explicit data
dependencies, for example if you want to print a message to indicate
@@ -1893,7 +1992,7 @@
in this fashion.</p></div>
</div>
<div class="sect2">
-<h3 id="_scoping_blocks">10.4. Scoping blocks</h3>
+<h3 id="_scoping_blocks">11.4. Scoping blocks</h3>
<div class="paragraph"><p>Arbitrary scoping blocks may be used. In this example, two different
variables, both represented by <code>b</code>, are assigned different values.</p></div>
<div class="listingblock">
@@ -1911,7 +2010,7 @@
</div>
</div>
<div class="sect1">
-<h2 id="_operators">11. Operators</h2>
+<h2 id="_operators">12. Operators</h2>
<div class="sectionbody">
<div class="paragraph"><p>The following binary arithmetic operators on numbers are defined:</p></div>
<div class="paragraph"><p><code>+</code> (plus), <code>-</code> (minus), <code>*</code> (times), <code>/</code> (divide),
@@ -1930,7 +2029,7 @@
</div>
</div>
<div class="sect1">
-<h2 id="_standard_library">12. Standard library</h2>
+<h2 id="_standard_library">13. Standard library</h2>
<div class="sectionbody">
<div class="paragraph"><p>Each category of function is shown with the required import
statement, if necessary.</p></div>
@@ -1941,7 +2040,7 @@
<div class="paragraph"><p>If a function is described below an <strong>Import:</strong> label, be sure to
<code>import</code> that package.</p></div>
<div class="sect2">
-<h3 id="_general">12.1. General</h3>
+<h3 id="_general">13.1. General</h3>
<div class="dlist"><dl>
<dt class="hdlist1">
<code>xor(boolean,boolean) → boolean</code>
@@ -1980,7 +2079,7 @@
</dl></div>
</div>
<div class="sect2">
-<h3 id="_type_conversion">12.2. Type conversion</h3>
+<h3 id="_type_conversion">13.2. Type conversion</h3>
<div class="dlist"><dl>
<dt class="hdlist1">
<code>fromint(int) → string</code>
@@ -2045,7 +2144,7 @@
</dl></div>
</div>
<div class="sect2">
-<h3 id="_output">12.3. Output</h3>
+<h3 id="_output">13.3. Output</h3>
<div class="dlist"><dl>
<dt class="hdlist1">
<code>trace(anything, anything, …)</code>
@@ -2069,7 +2168,7 @@
</dl></div>
</div>
<div class="sect2">
-<h3 id="_string_functions">12.4. String functions</h3>
+<h3 id="_string_functions">13.4. String functions</h3>
<div class="paragraph"><p><code>strcat(string,string)</code>: Concatenation</p></div>
<div class="paragraph"><p><strong>Import:</strong> <code>string</code></p></div>
<div class="dlist"><dl>
@@ -2188,7 +2287,7 @@
</dl></div>
</div>
<div class="sect2">
-<h3 id="_math">12.5. Math</h3>
+<h3 id="_math">13.5. Math</h3>
<div class="dlist"><dl>
<dt class="hdlist1">
<code>max|min_integer(int,int) → int</code>
@@ -2340,7 +2439,7 @@
</dl></div>
</div>
<div class="sect2">
-<h3 id="_system">12.6. System</h3>
+<h3 id="_system">13.6. System</h3>
<div class="paragraph"><p><strong>Import:</strong> <code>sys</code></p></div>
<div class="dlist"><dl>
<dt class="hdlist1">
@@ -2353,7 +2452,7 @@
</dd>
</dl></div>
<div class="sect3">
-<h4 id="argv">12.6.1. Command line</h4>
+<h4 id="argv">13.6.1. Command line</h4>
<div class="paragraph"><p>Consider this command line:</p></div>
<div class="literalblock">
<div class="content">
@@ -2437,7 +2536,7 @@
</dl></div>
</div>
<div class="sect3">
-<h4 id="_debugging">12.6.2. Debugging</h4>
+<h4 id="_debugging">13.6.2. Debugging</h4>
<div class="paragraph"><p><strong>Import:</strong> <code>assert</code></p></div>
<div class="dlist"><dl>
<dt class="hdlist1">
@@ -2451,7 +2550,7 @@
</dl></div>
</div>
<div class="sect3">
-<h4 id="Turbine_information">12.6.3. Turbine information</h4>
+<h4 id="Turbine_information">13.6.3. Turbine information</h4>
<div class="dlist"><dl>
<dt class="hdlist1">
<code>adlb_servers() → int</code>
@@ -2473,7 +2572,7 @@
</div>
</div>
<div class="sect2">
-<h3 id="_files_2">12.7. Files</h3>
+<h3 id="_files_2">13.7. Files</h3>
<div class="dlist"><dl>
<dt class="hdlist1">
<code>filename(file) → string</code>
@@ -2614,7 +2713,7 @@
</dl></div>
</div>
<div class="sect2">
-<h3 id="_blobs_2">12.8. Blobs</h3>
+<h3 id="_blobs_2">13.8. Blobs</h3>
<div class="paragraph"><p><strong>Import:</strong> <code>blob</code></p></div>
<div class="dlist"><dl>
<dt class="hdlist1">
@@ -2693,50 +2792,60 @@
</dl></div>
</div>
<div class="sect2">
-<h3 id="library_location">12.9. Location</h3>
+<h3 id="library_location">13.9. Location</h3>
<div class="paragraph"><p>See the section about <a href="#location">location</a>.</p></div>
<div class="dlist"><dl>
<dt class="hdlist1">
-<code>location_from_rank(int) → location</code>
+<code>locationFromRank(int) → location</code>
</dt>
<dd>
<p>
Convert the rank integer to a
-<code>location</code> variable compatible with <code>@location</code>.
+<code>location</code> variable compatible with <code>@location</code> with <code>HARD</code>, <code>RANK</code>.
</p>
</dd>
<dt class="hdlist1">
-<code>random_worker() → location</code>
+<code>randomWorker() → location</code>
</dt>
<dd>
<p>
-Obtain a worker at random.
+Obtain a worker at random with <code>HARD</code>,
+<code>RANK</code>.
</p>
</dd>
<dt class="hdlist1">
-<code>hostmap_list() → string[]</code>
+<code>randomWorkerRank() → int</code>
</dt>
<dd>
<p>
-Obtain the whole hostmap.
+Obtain a random worker rank.
</p>
</dd>
<dt class="hdlist1">
-<code>hostmap_one(string) → location</code>
+<code>hostmapList() → string[]</code>
</dt>
<dd>
<p>
+Obtain the whole hostmap as an array
+with integer keys and string hostname values.
+</p>
+</dd>
+<dt class="hdlist1">
+<code>hostmapOne(string) → location</code>
+</dt>
+<dd>
+<p>
Lookup the string as a host in the
-hostmap and return one rank running on that host.
+hostmap and return one rank running on that host with <code>HARD</code>, <code>RANK</code>.
</p>
</dd>
<dt class="hdlist1">
-<code>hostmap_one_worker(string) → location</code>
+<code>hostmapOneWorkerRank(string) → int</code>
</dt>
<dd>
<p>
Lookup the string as a host
-in the hostmap and return one worker rank running on that host.
+in the hostmap and return one of the worker ranks running on that host.
</p>
</dd>
</dl></div>
@@ -2744,7 +2853,7 @@
</div>
</div>
<div class="sect1">
-<h2 id="_defining_leaf_functions">13. Defining leaf functions</h2>
+<h2 id="leaf_functions">14. Defining leaf functions</h2>
<div class="sectionbody">
<div class="paragraph"><p>In typical Swift applications, the computationally intensive parts of
the application are not written in the Swift language. Rather, the
@@ -2755,7 +2864,7 @@
functions mentioned above are implemented as extension functions in
Tcl, which may wrap C/C++/Fortran functions.</p></div>
<div class="sect2">
-<h3 id="_swift_extension_functions">13.1. Swift extension functions</h3>
+<h3 id="swift_extension_functions">14.1. Swift extension functions</h3>
<div class="paragraph"><p>Currently we support Tcl extension functions, where a function is
implemented as a Tcl function. Tcl has good support for wrapping
native C/C++ functions, so this provides an indirect way to call
@@ -2781,7 +2890,7 @@
</li>
</ul></div>
<div class="sect3">
-<h4 id="_simple_tcl_fragment_example">13.1.1. Simple Tcl fragment example</h4>
+<h4 id="_simple_tcl_fragment_example">14.1.1. Simple Tcl fragment example</h4>
<div class="paragraph"><p>In this example, the Swift program will simply use Tcl to output a
string:</p></div>
<div class="listingblock">
@@ -2790,9 +2899,7 @@
"puts <<s>>"
];
-main {
- my_output("HELLO");
-}</code></pre>
+my_output("HELLO");</code></pre>
</div></div>
<div class="paragraph"><p><code>puts</code> is the Tcl builtin for screen output, like <code>puts()</code> in C.</p></div>
<div class="paragraph"><p>The above definition has, from left to right, the output arguments
@@ -2804,7 +2911,7 @@
indicating where variables should be substituted.</p></div>
</div>
<div class="sect3">
-<h4 id="_simple_tcl_package_example">13.1.2. Simple Tcl package example</h4>
+<h4 id="_simple_tcl_package_example">14.1.2. Simple Tcl package example</h4>
<div class="paragraph"><p>In this first example we will implement a trivial Tcl extension function
that doubles an integer. Here is the Tcl code that will go in
<code>myextension.tcl</code>:</p></div>
@@ -2825,7 +2932,7 @@
];</code></pre>
</div></div>
<div class="paragraph"><p>We can also tell the Swift compiler a little about the function so
-that it can better optimmize your programs. For example, <code>double</code> has
+that it can better optimize your programs. For example, <code>double</code> has
no side-effects and produces the same result each time for the same
arguments (i.e. is deterministic), so we can annotate it as a <code>@pure</code>
function.</p></div>
@@ -2861,7 +2968,7 @@
</ul></div>
</div>
<div class="sect3">
-<h4 id="_swift_tcl_data_type_mapping">13.1.3. Swift/Tcl data type mapping</h4>
+<h4 id="_swift_tcl_data_type_mapping">14.1.3. Swift/Tcl data type mapping</h4>
<div class="paragraph"><p>If you are defining Tcl functions in the way above with inline
Tcl code, Swift types are mapped to Tcl types in the following way:</p></div>
<div class="ulist"><ul>
@@ -2905,7 +3012,7 @@
</ul></div>
</div>
<div class="sect3">
-<h4 id="_calling_native_libraries_from_swift">13.1.4. Calling native libraries from Swift</h4>
+<h4 id="_calling_native_libraries_from_swift">14.1.4. Calling native libraries from Swift</h4>
<div class="paragraph"><p>The first step is to test that you can successfully call your
C/C++/Fortran function from a test Tcl script. If so, you will then
be able to use the Swift→Tcl techniques to call it from Swift.</p></div>
@@ -2917,7 +3024,7 @@
Tcl bindings.</p></div>
</div>
<div class="sect3">
-<h4 id="_writing_custom_tcl_interfaces">13.1.5. Writing custom Tcl interfaces</h4>
+<h4 id="_writing_custom_tcl_interfaces">14.1.5. Writing custom Tcl interfaces</h4>
<div class="paragraph"><p>It is possible to write a Tcl wrapper function that is
directly passed references to data in Swift’s global data store. In
this case your function must manually retrieve/store data from/to the
@@ -2935,7 +3042,7 @@
</div>
</div>
<div class="sect2">
-<h3 id="_dispatch_and_work_types">13.2. Dispatch and work types</h3>
+<h3 id="_dispatch_and_work_types">14.2. Dispatch and work types</h3>
<div class="paragraph"><p>Each worker in Swift/T is devoted to executing a single type of work.
There is a default work type that encompasses Swift/T script logic and
CPU tasks.</p></div>
@@ -2962,7 +3069,7 @@
for remote command-line and GPU tasks respectively.
It is also possible to define custom types of CPU leaf functions.</p></div>
<div class="sect3">
-<h4 id="_custom_work_types">13.2.1. Custom work types</h4>
+<h4 id="_custom_work_types">14.2.1. Custom work types</h4>
<div class="paragraph"><p>For some applications, it is useful to be able to divide up
CPU workers into multiple categories that execute different
kinds of work. For these scenarios, Swift/T provides the
@@ -2984,13 +3091,11 @@
"puts [ format {Hello %s} <<msg>> ]"
]
-main () {
- // Hello Foo will be printed on a foo_work worker
- hello1("Foo");
+// Hello Foo will be printed on a foo_work worker
+hello1("Foo");
- // Hello Bar will be printed on a regular worker
- hello2("Bar");
-}</code></pre>
+// Hello Bar will be printed on a regular worker
+hello2("Bar");</code></pre>
</div></div>
<div class="paragraph"><p>In order to run the above script, we need to ensure that
a worker is allocated to execute <code>foo_work</code> tasks. This is
@@ -3000,7 +3105,7 @@
</div>
</div>
<div class="sect2">
-<h3 id="app_functions">13.3. App functions</h3>
+<h3 id="app_functions">14.3. App functions</h3>
<div class="paragraph"><p>App functions are functions that are implemented as command-line
programs. These command-line programs can be brought into a Swift
program as functions with typed inputs and outputs.
@@ -3059,9 +3164,7 @@
"/bin/cat" inputs @stdout=out
}
-main {
- file joined <"joined.txt"> = cat(glob("*.txt"));
-}</code></pre>
+file joined <"joined.txt"> = cat(glob("*.txt"));</code></pre>
</div></div>
<div class="paragraph"><p>Here is an example of an app function that sleeps for an arbitrary
amount of time:</p></div>
@@ -3071,19 +3174,17 @@
"/bin/sleep" secs
}
-main {
- foreach time in [1:5] {
- void signal = sleep(time);
- // Wait on output signal so that trace occurs after sleep
- wait(signal) {
- trace("Slept " + fromint(time));
- }
+foreach time in [1:5] {
+ void signal = sleep(time);
+ // Wait on output signal so that trace occurs after sleep
+ wait(signal) {
+ trace("Slept " + fromint(time));
}
}</code></pre>
</div></div>
</div>
<div class="sect2">
-<h3 id="_remote_job_execution_with_coasters">13.4. Remote job execution with Coasters</h3>
+<h3 id="_remote_job_execution_with_coasters">14.4. Remote job execution with Coasters</h3>
<div class="paragraph"><p><strong>Note:</strong> Swift/T and Coasters integration is a work in progress
and is currently best suited for advanced users.
Planned future changes will make it easier to install and use.</p></div>
@@ -3193,9 +3294,9 @@
to the <a href="http://swift-lang.org/docs/">Swift/K documentation</a>.</p></div>
</div>
<div class="sect2">
-<h3 id="_external_scripting_support">13.5. External scripting support</h3>
+<h3 id="_external_scripting_support">14.5. External scripting support</h3>
<div class="sect3">
-<h4 id="_calling_python">13.5.1. Calling Python</h4>
+<h4 id="_calling_python">14.5.1. Calling Python</h4>
<div class="paragraph"><p>You can evaluate arbitrary Python code from within Swift/T. For
example, you can perform processing with a Python library.
Once you have that working, you can use Swift/T to coordinate
@@ -3206,10 +3307,8 @@
<pre><code>import io;
import python;
-main {
- i = python("print(\"python works\")\nrepr(2+2)");
- printf("i: %s", i);
-}</code></pre>
+i = python("print(\"python works\")\nrepr(2+2)");
+printf("i: %s", i);</code></pre>
</div></div>
<div class="paragraph"><p>This simply evaluates the Python code line by line. The last line must
return a Python string to Swift, in this case, the Python string
@@ -3250,13 +3349,10 @@
R = replace_all(t, "\n", "", 0);
}
-main
-{
- matrix A1 = eye(3);
- matrix A2 = eye(3);
- matrix sum = add(A1, A2);
- printf("2*eye(3)=%s", sum);
-}</code></pre>
+matrix A1 = eye(3);
+matrix A2 = eye(3);
+matrix sum = add(A1, A2);
+printf("2*eye(3)=%s", sum);</code></pre>
</div></div>
<div class="paragraph"><p>An Python script template is created that imports Numpy and performs
some simple calculations. This code is represented in a Swift string.
@@ -3286,7 +3382,7 @@
</div>
</div>
<div class="sect3">
-<h4 id="_calling_r">13.5.2. Calling R</h4>
+<h4 id="_calling_r">14.5.2. Calling R</h4>
<div class="paragraph"><p>Consider the following Swift script:</p></div>
<div class="listingblock">
<div class="content">
@@ -3302,12 +3398,9 @@
a
""";
-main
-{
- code = sprintf(template, 4);
- s = R(code);
- printf("the answer was: %i", s);
-}</code></pre>
+code = sprintf(template, 4);
+s = R(code);
+printf("the answer was: %i", s);</code></pre>
</div></div>
<div class="paragraph"><p>An <a href="http://www.r-project.org">R language</a> script template is placed in a
Swift string. The template is filled in with the value 4 by the Swift
@@ -3338,7 +3431,7 @@
</div>
</div>
<div class="sect3">
-<h4 id="_calling_julia">13.5.3. Calling Julia</h4>
+<h4 id="_calling_julia">14.5.3. Calling Julia</h4>
<div class="paragraph"><p>Consider the following Swift script:</p></div>
<div class="listingblock">
<div class="content">
@@ -3347,9 +3440,8 @@
import string;
import sys;
-main {
- start = clock();
- f =
+start = clock();
+f =
"""
begin
f(x) = begin
@@ -3359,13 +3451,12 @@
f(%s)
end
""";
- s1 = julia(sprintf(f, 1));
- s2 = julia(sprintf(f, 2));
- s3 = julia(sprintf(f, 3));
- printf("julia results: %s %s %s", s1, s2, s3);
- wait (s1, s2, s3) {
- printf("duration: %0.2f", clock()-start);
- }
+s1 = julia(sprintf(f, 1));
+s2 = julia(sprintf(f, 2));
+s3 = julia(sprintf(f, 3));
+printf("julia results: %s %s %s", s1, s2, s3);
+wait (s1, s2, s3) {
+ printf("duration: %0.2f", clock()-start);
}</code></pre>
</div></div>
<div class="paragraph"><p>In this example, a <a href="http://julialang.org">Julia</a> script is placed in
@@ -3390,12 +3481,16 @@
</div>
</div>
<div class="sect1">
-<h2 id="annotations">14. Function call annotations</h2>
+<h2 id="_more_about_functions">15. More about functions</h2>
<div class="sectionbody">
+<div class="paragraph"><p>In this section we discuss more advanced features for defining and
+calling functions.</p></div>
+<div class="sect2">
+<h3 id="annotations">15.1. Function call annotations</h3>
<div class="paragraph"><p>Swift/T supports many annotations to influence the behavior of function
calls.</p></div>
-<div class="sect2">
-<h3 id="_priority">14.1. Priority</h3>
+<div class="sect3">
+<h4 id="_priority">15.1.1. Priority</h4>
<div class="paragraph"><p>Leaf tasks resulting from Swift dataflow may be prioritized by using
the <code>@prio</code> annotation:</p></div>
<div class="listingblock">
@@ -3410,21 +3505,60 @@
of <code>i</code> may be any Swift integer.</p></div>
<div class="paragraph"><p>This annotation is applied to the leaf task call.</p></div>
</div>
-<div class="sect2">
-<h3 id="location">14.2. Location</h3>
+<div class="sect3">
+<h4 id="location">15.1.2. Location</h4>
<div class="paragraph"><p>Leaf tasks resulting from Swift dataflow may be assigned to a given
-processor by using the <code>@location</code> annotation:</p></div>
+processing location by using the <code>@location</code> annotation:</p></div>
<div class="listingblock">
<div class="content">
<pre><code>foreach i in [0:n-1] {
- location L = location_from_rank(i);
+ location L = locationFromRank(i);
@location=L f(i);
}</code></pre>
</div></div>
-<div class="paragraph"><p>In this case, each <code>f(i)</code> will execute on a different worker.</p></div>
-<div class="paragraph"><p>This annotation is applied to the leaf task call.</p></div>
-<div class="sect3">
-<h4 id="_hostmap">14.2.1. Hostmap</h4>
+<div class="paragraph"><p>In this case, each <code>f(i)</code> will execute on a different worker.
+This annotation is applied to the leaf task call.</p></div>
+<div class="paragraph"><p>The <code>location</code> type may constructed by the <code>location()</code> builtin, which
+has the signature:</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>location L = location(rank, HARD|SOFT, RANK|NODE);</code></pre>
+</div></div>
+<div class="ulist"><ul>
+<li>
+<p>
+<code>rank</code> is the MPI rank.
+</p>
+</li>
+<li>
+<p>
+<code>HARD</code> indicates that the location specification must be met strictly.
+</p>
+</li>
+<li>
+<p>
+<code>SOFT</code> indicates that the location specification may be ignored if
+ there is otherwise no work available for a worker. This is
+ noticeable during startup and shutdown, when there is typically
+ limited available work for workers.
+</p>
+</li>
+<li>
+<p>
+<code>RANK</code> indicates that the task must be run on the given <code>rank</code>.
+</p>
+</li>
+<li>
+<p>
+<code>NODE</code> indicates that the task may be run on any rank running on the
+ same node as the given <code>rank</code>.
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>See the <a href="#library_location">Location library</a> for usage for helper
+functions to work with locations.</p></div>
+<div class="sect4">
+<h5 id="_hostmap">Hostmap</h5>
<div class="paragraph"><p>At startup, by default, Turbine obtains all hostnames used in the run
and builds up a data structure called the hostmap to map hostnames to
ranks. You may combine the location features with the hostmap
@@ -3434,9 +3568,113 @@
</div>
</div>
</div>
+<div class="sect2">
+<h3 id="_advanced_function_topics">15.2. Advanced function topics</h3>
+<div class="paragraph"><p>Swift/T provides various facilities to define functions with flexible
+input and output types that can enable writing cleaner and more
+generic code.</p></div>
+<div class="sect3">
+<h4 id="_optional_and_keyword_arguments_to_functions">15.2.1. Optional and keyword arguments to functions</h4>
+<div class="paragraph"><p>Swift/T functions can have optional arguments to functions, where a
+default value is used if the caller does not provide that function argument.
+The default values are specified in the function definition and must be
+literal constant expressions. For example, the following function has two
+optional arguments:</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>(string o) msg(string a, int b=0, float c=0.0) {
+ o = "%s %i %f" % (a, b, c);
+}</code></pre>
+</div></div>
+<div class="paragraph"><p>Optional arguments can be provided as <strong>positional arguments</strong> in the same way
+as non-optional arguments, e.g.:</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>trace(msg("test"));
+trace(msg("test", 1));
+trace(msg("test", 1, 2.0));</code></pre>
+</div></div>
+<div class="paragraph"><p>Optional arguments, unlike non-optional arguments, can also be provided
+as <strong>keyword arguments</strong>. For example:</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>trace(msg("test", y=2.0));</code></pre>
+</div></div>
</div>
+<div class="sect3">
+<h4 id="_variable_length_argument_lists">15.2.2. Variable-length argument lists</h4>
+<div class="paragraph"><p><a href="#swift_extension_functions">Swift extension functions</a> support variable
+length argument lists, where the final argument can be repeated 0 or
+more times. The full list of arguments is passed into the extension
+function definition. For example, it is possible to define a function
+that takes any number of integers as arguments and returns the sum. Let us
+assume that a Tcl function <code>my_sum</code> is defined that computes the sum of
+its inputs. Then the following Tcl extension function definition is possible:</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>(int o) my_sum(int... vals) "my_pkg" "1.0" [
+ "set <<o>> [ my_pkg::my_sum <<vals>> ]"
+];</code></pre>
+</div></div>
+</div>
+<div class="sect3">
+<h4 id="_function_overloading">15.2.3. Function overloading</h4>
+<div class="paragraph"><p>Swift/T supports <em>overloading</em> of functions, where multiple function
+definitions with the same name coexist in the program. If a function
+name is overloaded, Swift/T will decide which definition to use
+based on the argument types. In order to overload a function, the
+input types of the two definitions must be different enough to
+allow Swift/T to reliably determine which definition is meant. This
+means that you can only overload functions if:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+All input arguments have a single concrete type, e.g. <code>file</code> or <code>int[][]</code>.
+ Union argument types and type variables are not supported in overloaded
+ functions.
+</p>
+</li>
+<li>
+<p>
+No optional arguments are used (variable-length argument lists are supported)
+</p>
+</li>
+<li>
+<p>
+No list of input types could match multiple possible definitions, for example
+ <code>f(1)</code> could match both <code>f(int x)</code> and <code>f(int x, float y…)</code>.
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>Swift/T will exit with a compile error if you break one of these rules.</p></div>
+<div class="paragraph"><p>For example, the following program will print <code>int: 1</code> and <code>float: 3.14</code>.</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>import io;
+
+() print_num(int x) {
+ printf("int: %i", x);
+}
+
+() print_num(float x) {
+ printf("float: %0.2f", x);
+}
+
+print_num(1);
+print_num(3.14);</code></pre>
+</div></div>
+</div>
+<div class="sect3">
+<h4 id="_union_argument_types_and_type_variables">15.2.4. Union argument types and type variables</h4>
+<div class="paragraph"><p><a href="#swift_extension_functions">Swift extension functions</a> support
+additional argument types that can match multiple possible input types.</p></div>
+<div class="paragraph"><p>TODO</p></div>
+</div>
+</div>
+</div>
+</div>
<div class="sect1">
-<h2 id="Optimizations">15. Optimizations</h2>
+<h2 id="Optimizations">16. Optimizations</h2>
<div class="sectionbody">
<div class="paragraph"><p>STC performs a range of compiler optimizations that can significantly
speed up most Swift programs. The optimization level can be controlled
@@ -3460,8 +3698,8 @@
# All optimizations (also recommended)
stc -O3 example.swift example.tcl</code></pre>
</div></div>
-<div class="paragraph"><p>Individual optimizations can be toggled on using <code>-T <opt name></code>
-or off with <code>-t <opt name></code>, but this typically is only useful for
+<div class="paragraph"><p>Individual optimizations can be toggled on using <code>-f <opt name></code>
+or off with <code>-F <opt name></code>, but this typically is only useful for
debugging. You can find an up-to-date list of optimizations in
the stc command-line help:</p></div>
<div class="listingblock">
@@ -3471,11 +3709,11 @@
</div>
</div>
<div class="sect1">
-<h2 id="Turbine">16. Running in Turbine</h2>
+<h2 id="Turbine">17. Running in Turbine</h2>
<div class="sectionbody">
<div class="paragraph"><p>The following describes how to run Turbine programs.</p></div>
<div class="sect2">
-<h3 id="_architecture">16.1. Architecture</h3>
+<h3 id="_architecture">17.1. Architecture</h3>
<div class="paragraph"><p>Turbine runs as an MPI program consisting of many processes. Turbine
programs are ADLB programs. Thus, they produce and execute discrete
tasks that are distributed and load balanced at run time.</p></div>
@@ -3505,7 +3743,7 @@
also store Swift data (integers, strings, etc.).</p></div>
</div>
<div class="sect2">
-<h3 id="_concurrency">16.2. Concurrency</h3>
+<h3 id="_concurrency">17.2. Concurrency</h3>
<div class="paragraph"><p>The available concurrency and efficiency in your Swift script is
limited by the following factors:</p></div>
<div class="ulist"><ul>
@@ -3532,7 +3770,7 @@
</ul></div>
</div>
<div class="sect2">
-<h3 id="_invocation">16.3. Invocation</h3>
+<h3 id="_invocation">17.3. Invocation</h3>
<div class="paragraph"><p>The form of a Turbine invocation for STC-generated
<code>program.tcl</code> is:</p></div>
<div class="listingblock">
@@ -3676,7 +3914,33 @@
Either variable name may be used.
</p>
</dd>
+</dl></div>
+<div class="paragraph"><p><a id="env_swift_tmp"></a></p></div>
+<div class="dlist"><dl>
<dt class="hdlist1">
+<code>SWIFT_TMP</code>
+</dt>
+<dt class="hdlist1">
+<code>TMP</code>
+</dt>
+<dd>
+<p>
+Directory location for <a href="#unmapped_files">unmapped files</a>.
+<code>SWIFT_PATH</code> overrides <code>TMP</code>. The default is <code>/tmp</code>.
+</p>
+</dd>
+<dt class="hdlist1">
+<code>SWIFT_TMP_AUTODELETE=0</code>
+</dt>
+<dd>
+<p>
+By default, Swift/T deletes
+<a href="#unmapped_files">unmapped files</a> when they are no longer used.
+Setting this to 0 logs these temporary files when created and prevents
+Swift/T from automatically deleting them.
+</p>
+</dd>
+<dt class="hdlist1">
<code>TURBINE_USER_LIB</code>
</dt>
<dd>
@@ -3698,7 +3962,7 @@
</dt>
<dd>
<p>
-Using <code>turbine -l</code> or equivalent prepend the
+Using <code>turbine -l</code> or equivalent prepends the
MPI rank number to each output line. This works with typical MPICH or
OpenMPI systems, however, this is not available on some systems, so
set this to emulate the rank output on such systems.
@@ -3835,11 +4099,11 @@
</dl></div>
</div>
<div class="sect2">
-<h3 id="Build_configuration">16.4. Build configuration</h3>
+<h3 id="Build_configuration">17.4. Build configuration</h3>
<div class="paragraph"><p>The following describes how to run Swift/T programs in Turbine
on more complex systems.</p></div>
<div class="sect3">
-<h4 id="_build_troubleshooting">16.4.1. Build troubleshooting</h4>
+<h4 id="_build_troubleshooting">17.4.1. Build troubleshooting</h4>
<div class="paragraph"><p>If <code>exm-setup.zsh</code> does not succeed, you may need to change how it
tries to configure and compile Swift/T.</p></div>
<div class="paragraph"><p>Troubleshooting a build problem can require a few steps. The first
@@ -3872,7 +4136,7 @@
</ol></div>
</div>
<div class="sect3">
-<h4 id="Manual_build_configuration">16.4.2. Manual configuration</h4>
+<h4 id="Manual_build_configuration">17.4.2. Manual configuration</h4>
<div class="paragraph"><p><code>exm-setup.zsh</code> and <code>exm-settings.sh</code> provide a convenient way to install
Swift/T. However, this method does not allow full control over
the configuration. Swift/T is built with standard Ant (Java) and
@@ -3908,7 +4172,7 @@
</ul></div>
</div>
<div class="sect3">
-<h4 id="_non_standard_mpi_locations">16.4.3. Non-standard MPI locations</h4>
+<h4 id="_non_standard_mpi_locations">17.4.3. Non-standard MPI locations</h4>
<div class="paragraph"><p>Sometimes simply specifying the MPI directory is not enough to
configure Swift/T.</p></div>
<div class="paragraph"><p>You can modify these settings in <code>exm-settings.sh</code> to more precisely
@@ -3930,7 +4194,7 @@
</div>
</div>
<div class="sect2">
-<h3 id="_performance_enhancements">16.5. Performance enhancements</h3>
+<h3 id="_performance_enhancements">17.5. Performance enhancements</h3>
<div class="olist arabic"><ol class="arabic">
<li>
<p>
@@ -3989,7 +4253,7 @@
</ol></div>
</div>
<div class="sect2">
-<h3 id="mkstatic">16.6. Building standalone executables with mkstatic.tcl</h3>
+<h3 id="mkstatic">17.6. Building standalone executables with mkstatic.tcl</h3>
<div class="paragraph"><p>It is possible to build a fully self-contained executable, including
all Tcl scripts and compiled code, provided that all dependencies support
static linking. If not, it is also possible to build an executable with
@@ -4023,7 +4287,7 @@
<div class="content">
<pre><code>stc my.swift</code></pre>
</div></div>
-<div class="paragraph"><p>producing the Turbine Tcl script <code>my.tcl</code>.</p></div>
+<div class="paragraph"><p>producing the Turbine Tcl script <code>my.tic</code>.</p></div>
</li>
<li>
<p>
@@ -4039,7 +4303,7 @@
replacement for <code>tclsh</code> with required Turbine libraries statically
linked in.
For a simple Swift program with no user Tcl libraries,
-you only need to set <code>main_script = my.tcl</code>.</p></div>
+you only need to set <code>main_script = my.tic</code>.</p></div>
</li>
<li>
<p>
@@ -4102,6 +4366,8 @@
If building a fully static executable, you can
provide the <code>-static</code> flag, plus all object files, plus <code>-L</code>
and <code>-l</code> flags for all required library directories and libraries.
+ This requires that all libraries have static archives (<code>*.a</code>),
+ including Tcl (simply build Tcl with <code>--disable-shared</code>).
</p>
<div class="listingblock">
<div class="content">
@@ -4172,7 +4438,7 @@
</dl></div>
</div>
<div class="sect2">
-<h3 id="debugging">16.7. Debugging Swift/T runs</h3>
+<h3 id="debugging">17.7. Debugging Swift/T runs</h3>
<div class="paragraph"><p>Applying the debugger allows you to debug native code linked to Swift/T
from a normal debugger. This will allow you to step through your code
(and the Swift/T run time libraries).</p></div>
@@ -4192,7 +4458,7 @@
</li>
</ul></div>
<div class="sect3">
-<h4 id="valgrind">16.7.1. Valgrind</h4>
+<h4 id="valgrind">17.7.1. Valgrind</h4>
<div class="paragraph"><p>The Swift/T launcher scripts support <a href="http://valgrind.org">valgrind</a>.
Simply set the environment variable <code>VALGRIND</code> to the valgrind command
you wish to use. A suppressions file is distributed with Turbine to
@@ -4205,7 +4471,7 @@
</div></div>
</div>
<div class="sect3">
-<h4 id="gdb">16.7.2. GDB</h4>
+<h4 id="gdb">17.7.2. GDB</h4>
<div class="paragraph"><p>The Turbine library provides a convenient attachment mechanism
compatible with debuggers like GDB, Eclipse, etc. You attach to a
Turbine execution by using the <code>GDB_RANK</code> variable:</p></div>
@@ -4227,7 +4493,7 @@
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
-Last updated 2014-12-17 11:09:58 CST
+Last updated 2015-03-05 12:25:57 CST
</div>
</div>
</body>
Modified: www/Swift-T/leaf.html
===================================================================
--- www/Swift-T/leaf.html 2015-03-13 17:55:23 UTC (rev 8392)
+++ www/Swift-T/leaf.html 2015-03-13 20:03:05 UTC (rev 8393)
@@ -535,6 +535,16 @@
}
+
+/* SWIFT/T GUIDE CUSTOMIZATIONS */
+
+a:visited {
+ color: gray;
+}
+h5 {
+ font-size: 0.8em;
+}
+
</style>
<script type="text/javascript">
/*<![CDATA[*/
@@ -731,7 +741,7 @@
/*]]>*/
</script>
</head>
-<body class="article">
+<body class="article" style="max-width:750px">
<div id="header">
<h1>Swift/T Leaf Function Guide</h1>
<div id="toc">
@@ -811,12 +821,16 @@
</p>
</li>
</ul></div>
+<div class="paragraph"><p>When you unpack this file, you will have a directory <code>examples/</code>.
+Change to this directory and <code>source setup.sh</code> to obtain build
+settings.</p></div>
+<div class="paragraph"><p>You can use the <code>clean.sh</code> scripts to clean up.</p></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Note</div>
</td>
-<td class="content">In many scripts, we use shell options <code>set -ex</code>.</td>
+<td class="content">We often use shell options <code>set -eux</code>.</td>
</tr></table>
</div>
<div class="admonitionblock">
@@ -918,9 +932,19 @@
<td class="icon">
<div class="title">Note</div>
</td>
-<td class="content"><code>TCLLIBPATH</code> is space-separated (which makes for easier Tcl processing).</td>
+<td class="content"><code>TCLLIBPATH</code> is space-separated (which makes for easier Tcl
+processing).</td>
</tr></table>
</div>
+<div class="admonitionblock">
+<table><tr>
+<td class="icon">
+<div class="title">Note</div>
+</td>
+<td class="content"><code>TCLLIBPATH</code> is modified by Turbine. To expose a Tcl package to
+Swift/T, set <code>SWIFT_PATH</code>.</td>
+</tr></table>
+</div>
<div class="paragraph"><p>We create <code>pkgIndex.tcl</code> from the shell:</p></div>
<div class="listingblock">
<div class="content">
@@ -954,13 +978,11 @@
<div class="content">
<pre><code>import io;
import f;
-main
-{
- int x = 2;
- int y = 3;
- int z = f(x,y);
- printf("sum: %i", z);
-}</code></pre>
+
+int x = 2;
+int y = 3;
+int z = f(x,y);
+printf("sum: %i", z);</code></pre>
</div></div>
<div class="paragraph"><p>Now, make the package available to Turbine and run it:</p></div>
<div class="listingblock">
@@ -986,6 +1008,7 @@
<div class="listingblock">
<div class="content">
<pre><code>#include <stdio.h>
+#include <unistd.h>
#include "g.h"
@@ -995,6 +1018,7 @@
printf("g: %i+%i=%i\n", i1, i2, sum);
printf("sleeping for %i seconds...\n", sum);
sleep(sum);
+ return sum;
}</code></pre>
</div></div>
<div class="paragraph"><p>This function is normally called as (<code>test-g.c</code>):</p></div>
@@ -1010,11 +1034,11 @@
<div class="paragraph"><p>It may be compiled and run with (<code>test-g.sh</code>):</p></div>
<div class="listingblock">
<div class="content">
-<pre><code>#!/bin/sh
+<pre><code>#!/bin/sh -ex
-gcc -c g.c || exit 1
-gcc -c test-g.c || exit 1
-gcc -o g.x test-g.o g.o || exit 1
+gcc -c g.c
+gcc -c test-g.c
+gcc -o g.x test-g.o g.o
./g.x</code></pre>
</div></div>
@@ -1039,10 +1063,12 @@
(<code>test-swig-g.sh</code>):</p></div>
<div class="listingblock">
<div class="content">
-<pre><code>rm *.o
-gcc -c -fPIC g.c &&
-gcc -c -fPIC -I /usr/include/tcl8.5 g_wrap.c &&
-gcc -shared -o libg.so g_wrap.o g.o &&
+<pre><code>#!/bin/sh
+rm -fv *.o
+set -ex
+gcc -c -fPIC -Wall g.c
+gcc -c -fPIC -I/home/wozniak/sfw/tcl-8.6.0/include g_wrap.c
+gcc -shared -o libg.so g_wrap.o g.o
tclsh make-package.tcl > pkgIndex.tcl</code></pre>
</div></div>
<div class="paragraph"><p>This produces <code>libg.so</code> and the Tcl package file <code>pkgIndex.tcl</code>.
@@ -1058,7 +1084,9 @@
<pre><code>> export TCLLIBPATH=$PWD
> tclsh test-g.tcl
g: 2+3=5
-sleeping for 5 seconds...</code></pre>
+sleeping for 5 seconds...
+
+te</code></pre>
</div></div>
</div>
<div class="sect3">
@@ -1066,13 +1094,14 @@
<div class="paragraph"><p>Then, we bring the Tcl package into Swift (<code>test-g-1.swift</code>):</p></div>
<div class="listingblock">
<div class="content">
-<pre><code>@dispatch=WORKER
+<pre><code>import io;
+
+ at dispatch=WORKER
(int sum) g(int i1, int i2) "g" "0.0"
[ "set <<sum>> [ g <<i1>> <<i2>> ]" ];
-main {
- int sum = g(2, 3);
-}</code></pre>
+int sum = g(2, 3);
+printf("Swift: sum: %i", sum);</code></pre>
</div></div>
<div class="paragraph"><p>Compile and run (<code>test-g-1.sh</code>):</p></div>
<div class="listingblock">
@@ -1093,15 +1122,21 @@
<div class="paragraph"><p>Write a foreach loop around the call to <code>g</code> (<code>test-g-n.swift</code>):</p></div>
<div class="listingblock">
<div class="content">
-<pre><code>@dispatch=WORKER
+<pre><code>import io;
+import stats;
+
+
+ at dispatch=WORKER
(int sum) g(int i1, int i2) "g" "0.0"
-[ "set <<sum>> [ g <<i1>> <<i2>> ]" ];
+ [ "set <<sum>> [ g <<i1>> <<i2>> ]" ];
-main {
- foreach i in [0:5] {
- int sum = g(i, 5-i);
- }
-}</code></pre>
+int d[];
+foreach i in [0:5] {
+ d[i] = g(i, 5-i);
+}
+
+y = sum_integer(d);
+printf("y: %i", y);</code></pre>
</div></div>
<div class="paragraph"><p>Compile and run (<code>test-g-n.swift</code>):</p></div>
<div class="listingblock">
@@ -1168,14 +1203,12 @@
<pre><code>import blob;
import io;
-main {
- file data = input_file("input.data");
- blob b = blob_read(data);
- float v[] = floats_from_blob(b);
- printf("size(v) = %i", size(v));
- printf("v[0]=%0.2f", v[0]);
- printf("v[last]=%0.2f", v[size(v)-1]);
-}</code></pre>
+file data = input_file("input.data");
+blob b = blob_read(data);
+float v[] = floats_from_blob(b);
+printf("size(v) = %i", size(v));
+printf("v[0]=%0.2f", v[0]);
+printf("v[last]=%0.2f", v[size(v)-1]);</code></pre>
</div></div>
<div class="paragraph"><p><code>test-b-simple.sh</code>:</p></div>
<div class="listingblock">
@@ -1239,9 +1272,9 @@
<div class="listingblock">
<div class="content">
<pre><code>rm *.o
-swig -module b b.h
+swig -module b b.i
gcc -c -fPIC b.c
-gcc -c -fPIC -I /usr/include/tcl8.5 b_wrap.c
+gcc -c -fPIC $TCL_INCLUDE_SPEC b_wrap.c
gcc -shared -o libb.so b_wrap.o b.o
tclsh make-package.tcl > pkgIndex.tcl</code></pre>
</div></div>
@@ -1293,13 +1326,11 @@
(blob sum) b(blob v) "b" "0.0"
[ "set <<sum>> [ b::b_tcl <<v>> ]" ];
-main {
- file data = input_file("input.data");
- blob v = blob_read(data);
- blob s = b(v);
- float sum[] = floats_from_blob(s);
- printf("sum (swift): %f", sum[0]);
-}</code></pre>
+file data = input_file("input.data");
+blob v = blob_read(data);
+blob s = b(v);
+float sum[] = floats_from_blob(s);
+printf("sum (swift): %f", sum[0]);</code></pre>
</div></div>
<div class="paragraph"><p><code>test-b-swift.sh</code>:</p></div>
<div class="listingblock">
@@ -1321,6 +1352,8 @@
<div class="paragraph"><p>This example will demonstrate multiplying <code>y=A*x</code> using Swift to call
a user Fortran library, which in turn calls the BLAS function
<code>dgemv</code>. This demonstrates the generality of our model.</p></div>
+<div class="paragraph"><p>In these scripts, you must have the BLAS archive. Change the
+appropriate shell variable to point to this file.</p></div>
<div class="imageblock latex">
<div class="content">
<img src="leaf__1.png" alt="leaf__1.png" />
@@ -1383,18 +1416,17 @@
<div class="paragraph"><p>It is built and run with (<code>test-mvm.sh</code>):</p></div>
<div class="listingblock">
<div class="content">
-<pre><code>#!/bin/bash
+<pre><code>#!/bin/bash -eu
# Note Fortran memory layout:
turbine-write-doubles A.data 1 3 2 4
turbine-write-doubles x.data 5 6
-BLAS="$HOME/Downloads/BLAS/blas_LINUX.a"
-gfortran -c MVM.f &&
-gfortran -c test-MVM.f &&
-gfortran -o test-MVM.x test-MVM.o MVM.o $BLAS || exit 1
+gfortran -c mvm.f
+gfortran -c test-mvm.f
+gfortran -o test-mvm.x test-mvm.o mvm.o ${BLAS}
-./test-MVM.x</code></pre>
+./test-mvm.x</code></pre>
</div></div>
<div class="paragraph"><p>FortWrap will scan <code>mvm.f</code> and produce the C++ files <code>FortFuncs.h</code> and
<code>FortFuncs.cpp</code>, which we wrap with SWIG to produce a Tcl function
@@ -1413,15 +1445,13 @@
(blob y) mvm_blob(blob A, blob x, int n) "mvm" "0.0"
[ "set <<y>> [ mvm::mvm <<A>> <<x>> <<n>> ]" ];
-main {
- int n = 2;
- blob A_blob = blob_read(input_file("A.data"));
- blob x_blob = blob_read(input_file("x.data"));
- blob y_blob = mvm_blob(A_blob, x_blob, n);
- float y[] = floats_from_blob(y_blob);
- foreach v, i in y {
- printf("y[%i]=%f", i, v);
- }
+int n = 2;
+blob A_blob = blob_read(input_file("A.data"));
+blob x_blob = blob_read(input_file("x.data"));
+blob y_blob = mvm_blob(A_blob, x_blob, n);
+float y[] = floats_from_blob(y_blob);
+foreach v, i in y {
+ printf("y[%i]=%f", i, v);
}</code></pre>
</div></div>
<div class="paragraph"><p>Our Tcl wrapper converts the Tcl call to <code>mvm</code> on blob arguments
@@ -1433,17 +1463,12 @@
<div class="paragraph"><p>Now, we build everything (<code>build.sh</code>):</p></div>
<div class="listingblock">
<div class="content">
-<pre><code>#!/bin/bash -e
+<pre><code>#!/bin/bash -eu
TURBINE=$( which turbine )
TURBINE_HOME=$( dirname $( dirname ${TURBINE} ) )
source ${TURBINE_HOME}/scripts/turbine-config.sh
-set -x
-
-BLAS="$HOME/Downloads/BLAS/blas_LINUX.a"
-TCL_INCLUDE=${TCL}/include
-
# Wrap the Fortran in C++
fortwrap.py --array-as-ptr --no-vector --no-fmat mvm.f
# Wrap the C++ in Tcl
@@ -1453,7 +1478,7 @@
# Compile everything
g++ -c -fPIC -I . FortFuncs.cpp
-g++ -c -fPIC -I ${TCL_INCLUDE} FortFuncs_wrap.cxx
+g++ -c -fPIC ${TCL_INCLUDE_SPEC} FortFuncs_wrap.cxx
gfortran -c -fPIC mvm.f
# Build the shared object
@@ -1465,12 +1490,9 @@
<div class="paragraph"><p>We run it in Swift with (<code>test-mvm-swift.sh</code>):</p></div>
<div class="listingblock">
<div class="content">
-<pre><code>#!/bin/bash
+<pre><code>#!/bin/sh
-stc test-mvm.swift test-mvm.tcl
-
-export TURBINE_USER_LIB=$PWD
-turbine test-mvm.tcl</code></pre>
+swift-t -r $PWD test-mvm.swift</code></pre>
</div></div>
<div class="paragraph"><p>This produces:</p></div>
<div class="listingblock">
@@ -1487,52 +1509,61 @@
case that the Swift program will construct an array of strings to pass
to the C code. The C program is minimally modified by
renaming its <code>main()</code> function and calling that from Swift/T.</p></div>
-<div class="paragraph"><p>Consider the user code (<code>swift-main.c</code>):</p></div>
+<div class="paragraph"><p>Consider the user code (<code>main.c</code>):</p></div>
<div class="listingblock">
<div class="content">
<pre><code>#include <stdio.h>
-#include "swift-main.h"
-int swift_main(int argc, char* argv[]) {
+#include "main.h"
+int main(int argc, char* argv[]) {
for (int i = 0; i < argc; i++)
printf("arg[%i]: %s\n", i, argv[i]);
return 0;
}</code></pre>
</div></div>
-<div class="paragraph"><p>This is essentially a simple C program except that its <code>main()</code> function
-has been renamed to <code>swift_main()</code>. Also, the header <code>swift-main.h</code>
-has been created to allow the Swift/T framework to call this code.
-The function essentially acts like <code>/bin/echo</code>, reporting its
+<div class="paragraph"><p>The function essentially acts like <code>/bin/echo</code>, reporting its
arguments.</p></div>
-<div class="paragraph"><p>An example C wrapper to call this function is as follows (<code>prog-c.c</code>):</p></div>
+<div class="paragraph"><p>Consider the user code (<code>main_leaf.c</code>):</p></div>
<div class="listingblock">
<div class="content">
-<pre><code>#include "swift-main.h"
-int main(int argc, char* argv[]) {
- swift_main(argc, argv);
+<pre><code>#include <stdio.h>
+#include "main.h"
+int main_leaf(int argc, char** argv) {
+ for (int i = 0; i < argc; i++)
+ printf("arg[%i]: %s\n", i, argv[i]);
return 0;
}</code></pre>
</div></div>
-<div class="paragraph"><p>The equivalent Swift code is as follows (<code>prog-swift.swift</code>):</p></div>
+<div class="paragraph"><p>This is essentially the same program except that its <code>main()</code> function
+has been renamed to <code>swift_main()</code>. Also, the header <code>swift-main.h</code>
+has been created to allow the Swift/T framework to call this code.</p></div>
+<div class="paragraph"><p>The Swift/T distribution comes with functionality to make this easy to
+call. The key program is <code>genleaf</code>.</p></div>
+<div class="paragraph"><p>The equivalent Swift code is as follows (<code>test-main.swift</code>):</p></div>
<div class="listingblock">
<div class="content">
<pre><code>import io;
-(int v) swift_main(string A[]) "swift_main" "0.0" "swift_main_wrap";
-main {
- string A[] = [ "arg1", "arg2", "arg3" ];
- rc = swift_main(A);
- printf("exit code: %i", rc);
-}</code></pre>
+
+mainapp;
+
+printf("Swift...");
+string A[] = [ "arg1", "arg2", "arg3" ];
+rc = main_leaf(A);
+printf("exit code: %i", rc);</code></pre>
</div></div>
<div class="paragraph"><p>The Swift version defines the extension function symbol <code>swift_main</code>,
then calls it with the given array of strings. The "exit code"
(actually just a return value) is available to Swift.</p></div>
<div class="paragraph"><p>This example may be compiled and run (from C, Tcl, and Swift) by using
the provided Makefile.</p></div>
-<div class="paragraph"><p>The above process is semi-automated by the <code>genleaf</code> script. The script takes a C program and a header file as input and produces the required Tcl-C extension and Tcl leaf function. It also produces a simple source Swift and stc-compiled Tcl code ready to be run via <code>turbine</code>. Invoke <code>genleaf</code> as follows:</p></div>
+<div class="paragraph"><p>The above process is semi-automated by the <code>genleaf</code> script. The
+script takes a C program and a header file as input and produces the
+required Tcl-C extension and Tcl leaf function. It also produces a
+simple source Swift and stc-compiled Tcl code ready to be run via
+<code>turbine</code>. Invoke <code>genleaf</code> as follows (<code>test-main.sh</code>):</p></div>
<div class="listingblock">
<div class="content">
-<pre><code>./genleaf ex2.c ex2.h
-turbine user-code.tcl</code></pre>
+<pre><code>genleaf -vv main.c main.h test-main.swift
+swift-t -r $PWD user-code.swift</code></pre>
</div></div>
</div>
<div class="sect2">
@@ -1614,8 +1645,8 @@
</p>
<div class="listingblock">
<div class="content">
-<pre><code>export TURBINE_USER_LIB=$PWD
-turbine prog-swift.tcl</code></pre>
+<pre><code>make
+swift-t -r $PWD prog-swift.swift</code></pre>
</div></div>
</li>
</ol></div>
@@ -1691,12 +1722,10 @@
(int o) f(int i1, int i2) "my_pkg" "0.0" "f";
-main {
- int x = 2;
- int y = 3;
- int z = f(x,y);
- printf("sum: %i", z);
-}</code></pre>
+int x = 2;
+int y = 3;
+int z = f(x,y);
+printf("sum: %i", z);</code></pre>
</div></div>
<div class="paragraph"><p>For more information about the APIs used to store/retrieve Swift/T
data and issue rules, see <a href="turbine-internals.html">Turbine
@@ -1721,9 +1750,11 @@
<pre><code>double
f(MPI_Comm comm, int k)
{
+ printf("f()\n");
int task_rank, task_size;
MPI_Comm_rank(comm, &task_rank);
MPI_Comm_size(comm, &task_size);
+ printf("In f(): rank: %i/%i\n", task_rank, task_size);
MPI_Barrier(comm);
sleep(task_rank);
MPI_Barrier(comm);
@@ -1749,11 +1780,8 @@
@par @dispatch=WORKER (float z) f(int k) "f" "0.0" "f_tcl";
-main
-{
- float z = @par=2 f(3);
- printf("z: %0.3f", z);
-}</code></pre>
+float z = @par=2 f(3);
+printf("z: %0.3f", z);</code></pre>
</div></div>
<div class="paragraph"><p>In the declaration, <code>@par</code> allows us to call the function as a
parallel function. At call time, we use <code>@par=2</code>.</p></div>
@@ -1773,7 +1801,7 @@
set k_value [ retrieve_integer $k ]
# Look up MPI information
set comm [ turbine::c::task_comm ]
- set rank [ turbine::c::task_rank ]
+ set rank [ adlb::rank $comm ]
# Run the user code
set z_value [ f $comm $k_value ]
# Store result
@@ -1833,13 +1861,10 @@
import io;
import sys;
-main
-{
- printf("args: %s", args());
- string s = "MY_OUTPUT";
- blob b = blob_from_string(s);
- turbine_run_output_blob(b);
-}</code></pre>
+printf("args: %s", args());
+string s = "MY_OUTPUT";
+blob b = blob_from_string(s);
+turbine_run_output_blob(b);</code></pre>
</div></div>
<div class="paragraph"><p>The controller MPI program is run as: (<code>run.sh</code>):</p></div>
<div class="listingblock">
@@ -1866,7 +1891,7 @@
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
-Last updated 2014-07-18 16:07:23 CDT
+Last updated 2015-03-13 14:59:30 CDT
</div>
</div>
</body>
More information about the Swift-commit
mailing list