Flavors Technology, Inc. |
Paracell Users' Guide |
|
A variable is a reference to a memory location in the PIM. You can store a numeric value at this memory location, and use the Paracell code to change the value. A variable has the following set of properties.
When you attempt to use a variable without specifying these parts, the Paracell Compiler will try to fill in the missing pieces. When it can not, it will ask you for the missing information. One part the compiler cannot fill in for you is the name. You must assign a name to the variable you are going to use.
In the following sections, the details of .i.type;, .i.scope;, and values you can assign to a variable are explained.
The type of variable determines what kinds of values can be represented by the variable. In Paracell, there are two types of numbers:
Safe Numbers are able to encode values that cannot be represented by a numeric value -- called Exceptional Values. Exceptional Values are needed for representing the results of operations that cannot produce a meaningful result -- for example, on an attempt to divide by zero.
In Safe Numbers, three exceptional values are defined: -RAIL, NAN, and +RAIL. The RAILs represent half-infinite ranges of numbers outside the range of the numeric type, and are produced on numeric overflow. NAN (Not A Number) represents an unknown or otherwise non-representable result. Exceptional values propagate through the flow of computation so that variables which exceed their range do not corrupt other variables without detection.
-RAIL | +RAIL | |||||
<------------| | ------*----*----- | | | ------*----*------ | |------------> | ||
-Infinity | -Y -X | 0 | X Y | +Infinity |
From above, we see that both x and y are less than +RAIL. If however, X + Y = +RAIL, then the following can still be true.
X < +RAIL Y < +RAIL
but, algebraic manipulations are no longer valid. Subtracting X from both sides results in,
NAN = +RAIL - X
and not the expected,
Y = +RAIL - X
Paracell operations maintain as much information as possible using these Exceptional Values in the results of operations. Exceptional Values propagate through operations based on formal algebra. For example, adding a positive number to +RAIL produces +RAIL. The result of the addition is some positive numeric value greater than that can be represented, +RAIL.
The benefit of adding RAILs to the type definitions is that even after overflow has occurred (and perhaps after some additional computation), useful comparisons can still be made. For example, it is true that a value +RAIL is greater than any representable numeric values.
The documentation for each numeric operation in Paracell describes how exceptional numeric values are generated and propagated. For each numeric operation, a table describes the result of the operation given the class of input. This can get quite involved. For example, multiplying +RAIL by a number between zero and one (exclusive) yields NAN.
Two expressions which produce NAN are not necessarily equal. Similarly +RAIL does not equal +RAIL (nor is it unequal, as the relationship is unknown).
Paracell provides mechanisms for checking Exceptional Values, to keep arithmetic operations accurate.
In Paracell, a .i.Machine Integer; represents an integer with a value between -2,147,483,648 and +2,147,483,687, inclusive. A machine integer is stored as a 32-bit signed integer in the PIM.
Below is a sample of how Machine Integers are stored in PIM.
Decimal Representation | Binary Representation |
-2147483648 | 1000 0000 0000 0000 0000 0000 0000 0000 |
-2147483647 | 1000 0000 0000 0000 0000 0000 0000 0001 |
-2147483646 | 1000 0000 0000 0000 0000 0000 0000 0010 |
-2147483645 |
1000 0000 0000 0000 0000 0000 0000 0011 |
-2 | 1111 1111 1111 1111 1111 1111 1111 1110 |
-1 | 1111 1111 1111 1111 1111 1111 1111 1111 |
0 | 0000 0000 0000 0000 0000 0000 0000 0000 |
1 | 0000 0000 0000 0000 0000 0000 0000 0001 |
2 | 0000 0000 0000 0000 0000 0000 0000 0010 |
2147483645 | 0111 1111 1111 1111 1111 1111 1111 1101 |
2147483646 | 0111 1111 1111 1111 1111 1111 1111 1110 |
2147483647 | 0111 1111 1111 1111 1111 1111 1111 1111 |
A Paracell Number represents a signed rational number n/10,000, where n is an integer. The denominator is an implied constant such that Paracell numbers require only 32 bits of storage. A Paracell Number is a number system in which the absolute difference between any two different numbers, is at least epsilon, and the difference between two representable numbers is exactly epsilon.
Epsilon is a unit of guaranteed precision, which for Paracell Number is 0.0001.
The range of Paracell Number values is -214,748.3646 to +214,748.3646.
Some arithmetic operations on Paracell numbers (e.g., +,-) are faster than their corresponding floating point operations. Paracell numbers can be thought of as fixed point numbers.
Paracell Number is a class of .i.Safe Number;. Safe Numbers are able to encode values that cannot be represented by a numeric value -- called Exceptional Values. In Paracell Numbers, there are three exceptional values defined: +RAIL, -RAIL, and NAN. +RAIL represents numbers larger than the largest representable value in Paracell Number. Likewise, -RAIL represents numbers less than the smallest representable value in Paracell Number. NAN (Not A Number) represents an unknown or otherwise non-representable value -- e.g., result of a divide by zero.
Below is a sample of how Paracell Numbers are stored in PIM.
Decimal Representation | Binary Representation |
NAN | 1000 0000 0000 0000 0000 0000 0000 0000 |
-RAIL | 1000 0000 0000 0000 0000 0000 0000 0001 |
-214748.3646 | 1000 0000 0000 0000 0000 0000 0000 0010 |
-214748.3645 | 1000 0000 0000 0000 0000 0000 0000 0011 |
-0.0002 | 1111 1111 1111 1111 1111 1111 1111 1110 |
-0.0001 | 1111 1111 1111 1111 1111 1111 1111 1111 |
0 | 0000 0000 0000 0000 0000 0000 0000 0000 |
0.0001 | 0000 0000 0000 0000 0000 0000 0000 0001 |
0.0002 | 0000 0000 0000 0000 0000 0000 0000 0010 |
214748.3645 | 0111 1111 1111 1111 1111 1111 1111 1101 |
214748.3646 | 0111 1111 1111 1111 1111 1111 1111 1110 |
+RAIL | 0111 1111 1111 1111 1111 1111 1111 1111 |
The scope of a variable determines the memory location referenced by the variable. A variable can either refer to a location in PIM's global memory or PIM's local memory. Therefore, a variable can have one of two the scopes: global or local.
Global variables reference a memory location in PIM's global memory. Since the global memory is shared, a global variable can be "seen" by any of the tiles in the application. To read the value of this global variable, a tile imports the variable. To write a value to the global variable, a tile exports the variable. More than one tile can import a global variable at a given frame. However, only one tile may export a global variable at a time. If there are more than one tile attempting to export a global variable at the same time, a sequence is used to resolve this conflict. A sequence establishes the precedence of the exporting tiles.
Local variables reference a memory location in the PIM User Processor (PUP). The PUP resides on the Multi-Processor (MP) board. The visibility of a local variable is limited to one tile, the tile on which the local variable exists. Only this tile can read and write the values of the local variable. Hence, local variables do not have the problem of export conflict.
Local variables can be accessed at any time, even within a frame. This is a fundamental difference between global and local variables. Consider a tile containing the following two sentences.
x = x + 1.
x = x + 1.
A global variable can be imported or exported once a frame, only. Therefore, if x is a global variable, and initially had a value of 1, the tile will export a value of 2 at the end of the frame. This is because the imported value remains the same within a frame. An equivalent sentence would be,
x = x + 1.
However, with local variables, the values can be changed within a frame. Hence, if x is a local variable, the value of x at the end of the second sentence is 3. An equivalent sentence would be,
x = x + 2.
Since local variables are visible to only one tile, you may have local variables with the same name in many tiles. Although each local variable may have the same name, each refers to a local memory location of different tiles, and are therefore, different. This is in contrast to global variables. Global variables with the same name in different tiles, point to the same global memory location. Hence, you can distinguish global variables by their names, and local variables by their tiles.
Arrays are the most basic collection type in Paracell. An array is a collection of one or more values of a number type. Each member of an array can be referenced by its index in the array. The array variable type provides a way to tie a group of variables together. For example,
Generators is an array[1..10] of Machine Integers.
This is a definition that declares variable, Generator, to be an array of 10 Machine Integers. With this declaration, you have allocated memory locations for 10 Machine Integers. This array has 10 members, each with an index between 1 and 10. To reference the first element, simply place the index number within the brackets.
Generator[1] = 100.
This sentence assigns the value 100 to the element referenced by the index number 1 in the array Generator. You may also use a Local variable of type Machine Integer, as an index.
Generator[current_generator] = 100.
The variable, current_generator, is a variable of type Machine Integer.
The current version of Paracell prohibits changing the value of current_generator before an assignment of value to the array. The variable used in indexing the array can be changed, after the sentence that assigns a value to the array element. Here are some more example of declaring arrays.
Truck is a Machine Integer array[10].
This defines a Machine Integer array with 10 elements, indices from 0 to 9. When you do not specify the range of index numbers, the compiler assumes it to be zero based. Therefore, the first element of the array Truck, is Truck[0].
Paint_Mod is an array[first_mod .. last_mod] of Paracell Numbers.
Here, "first_mod" and "last_mod" are constant numbers.
Generator is an array[10, 5] of Paracell Numbers.
This defines a two-dimensional array of Paracell Numbers. The dimension of an array can be thought of as the number of indices required to reference an element in the array. For example, if you have divided your generators into zones and sectors, you may wish to use a two-dimensional array.
Generator[zone_number,sector_number] = 100.
The indices of a multi-dimensional array are always separated by commas.
In the current implementation of Paracell, each unique reference in a tile to a global array is considered a separate import or export.
Set Generator[10] to 0, set Generator[k] to 1.
In this example, Generator[10] and Generator[k] are 2 distinct exports.
Set X to Generator[k], set Y to Generator[k] + 1.
In this example, the 2 occurrences of Generator[k] require only 1 import.
Next: Operators,
Top: Table of Contents
Flavors Technology, Inc. |
Copyright© 1993-6 by Flavors Technology, Inc. All rights Reserved.