LIBRARY OF THE UNIVERSITY OF ILLINOIS AT URBANA-CHAMPAICN top- Z Digitized by the Internet Archive in 2013 http://archive.org/details/dynamicpartition421adam /jc V£/ Report No. U21 Op A 3 DYNAMIC PARTITIONING IN THE ARRAY LANGUAGE OL/2 by Harold Corwin Adams II January 1971 THE LIBRARY OF. J NOV 9 1972 UNIVERSITY OF ILLINOIS AT .URBA&IA-CHAMeAIGM DEPARTMENT OF COMPUTER SCIENCE UNIVERSITY OF ILLINOIS AT URBANA-CHAMPAIGN URBANA, ILLINOIS Report No. lj-21 DYNAMIC PARTITIONING IN THE ARRAY LANGUAGE OL/2 by Harold Corwin Adams II January 1971 Department of Computer Science University of Illinois at Urbana- Champaign Urbana, Illinois 6l801 * This work was supported in part by the National Science Foundation under Grant No. US NSF-GJ-328 and was submitted in partial fulfillment for the degree of Master of Science in Computer Science, January 1971- ACKNOWLEDGEMENT I wish to sincerely thank the originator of OL/2, Professor J. R. Phillips, for his suggestion of this thesis topic and his subsequent guidance and suggestions throughout the development and implementation of this part of the lan- guage. I would also like to thank the other members of the OL/2 implementation group, J. L. Latch, D. Jurich, B. Bloemer, and B. Finkel for their suggestions and contributions to the effort. Finally, I would like to express my deep appreciation for the patience of my wife, Boyana , who despite my many long absences, still managed to be encouraging. IV TABLE OF CONTENTS Page 1. INTRODUCTION 1 1.1 Definitions 1 1 . 2 Summary of Results 2 1.3 Earlier Work 4 2. OL/2 PARTITIONING 6 2.1 Partitioning Examples 6 2.2 Array Data Types and Organization 9 2.3 Array Control Blocks 11 3. THE PARTITIONING DATA STRUCTURE 13 3.1 Data Structure Overview 13 3.2 Partition Control Block Design Criteria ... 13 3.3 Partition Control Blocks 15 3 . 4 Partitioning Data Structure Example 18 4. THE SYNTAX, SEMANTICS, AND PROCEDURES 27 4.1 TACOS 27 4.2 Compilation of the PARTITION Statement . ... 28 4.3 Compilation of the SET Statement 34 5. DISCUSSION 38 LIST OF REFERENCES 41 APPENDIX A. OL/2 SOURCE LANGUAGE CHARACTER SETS 42 B. OL/2 LANGUAGE IMPLEMENTATION CONVENTIONS. . . 43 C. OL/2 SYNTAX FOR PARTITION AND SET STATEMENTS. 46 D. OL/2 SEMANTIC ACTION ROUTINES FOR THE SYNTAX OF APPENDIX C 47 E. OL/2 EXECUTION-TIME PROCEDURES 71 F. OL/2 EXAMPLES 85 V LIST OF TABLES Table Page 1. Basic Data Types for Square 2-dimensional Arrays 10 2. IBNF Repetition Symbols 27 3. @OL2 SORT PARTITION VARIABLES Parameter 30 VI LIST OF FIGURES Figure Page 1. Partitioning Examples 3 2. Crout Algorithm Example 7 3. Cholesky Decomposition Example 8 4. Array Control Block (ACB) 12 5. Partition Control Block (PCB) 16 6. Simplified Array Control Block 18 7. Intermediate Steps of Data Structure Example. . . 20 8. Original Array of Example with Partitioning Lines 21 9. Final Array Partitioning Structure of Example . . 22 1. INTRODUCTION 1 . 1 Definitions The OL/2 language has been designed as a programming language for those users who desire to solve their problems of linear algebra painlessly. The language is an extension to the PL/1 language which allows a significant number of ar- ray operations to free the user from the details of element- wise operations. One of the most natural and potentially useful capabilities that should be included in any language operating on arrays as a whole is the concept of partitioning Partitioning is a common operation of matrix algebra in which a given array is divided into smaller matrices or submatrices by horizontal and vertical lines drawn between the rows and columns of the matrix. This operation is generally used to make the computations associated with arrays more convenient. The operation of partitioning, as implemented in OL/2, can easily be used in this relatively static manner. However, the more important and interesting application is the dynamic use of partitioning to indirectly allow references to the rows, columns, and elements of the arrays. As will be seen in Section 2, "dynamic partitioning" allows one to write many of the algorithms of linear algebra in a natural way. In the implementation of partitioning, an extension to the conven- tional definition has also been permitted. This feature al- lows the programmer to specify certain geometric portions of the array. For example, he is allowed to specify for use the lower triangular part of a square matrix. This "diagonal partitioning" capability has also been used to advantage in certain algorithms. Another extension to the concept of par- titioning is the capability of partitioning non-rectangular arrays. The non-rectangular types of arrays, as described in Section 2.2, can only be partitioned after rows or after columns, but not both. This restriction is made to permit the definition of a row partition of a non-rectangular array as a line drawn between two rows, reflecting off of the diagonal, and then drawn between the corresponding columns. The column partition is defined analogously. Examples of the three types of partitioning defined here are given in Figure 1. 1 . 2 Summary of Results The implementation of dynamic partitioning in the language necessarily results in constraints on the strategy of array representation in the language. As in most high- level languages, each OL/2 array has associated with it a block of control information called the Array Control Block (ACB). In order to represent partitioning dynamically in the language, a structure is built at execution-time containing the ACB of the basic array and ACB's that have been estab- lished for those distinct subarrays of the partitioned array that are in use at any one time. This structure is dynamic in the sense that, except for the ACB of the basic array, the structure is continually changing during execution, depending X X X X X X \ X X X X X X X X X X s \ X X X X X X X 1 x X X X s s X X X X X X X X X X X s vX X X X X 1 x X X X X X ^ s* (a) Normal Partitioning of a (b) Diagonal Partitioning of a Rectangular Matrix After Rectangular Matrix into Row 2 and Column 3. Upper Triangular and Strictly Lower Triangular Parts. X X X X X X X X X X X X X X X X I X I X X I — f"x X (c) Non-rectangular Partition- (d ) Non-rectangular Partitioning ing of a Lower Triangular of a Diagonal Matrix After Matrix After Row 4 or Row 3 or After Column 3. After Column 4. Figure 1. Partitioning Examples 4 on the specific partitioning requirements of the user. The structure developed here is extremely versatile since the subarrays which have an ACB may also be partitioned. This, in effect, allows multi-level partitioning or "partitioning of partitioning." The structure can also contain substructures which represent the "diagonal partitioning" referred to in the previous section. Finally, the implementation allows the ef- fective overlay of multiple sets of partitions by allowing several ACB's to refer to the same basic physical array, each ACB having a distinct partitioning structure attached to it. 1 . 3 Earlier Work Very little work has been done in the past in the area of partitioning in array languages. Iverson ' s A Programming Language (APL) /3__/ uses a partitioning operation on matrices in the language, but the operator can only be applied to the linear physical vector in which the matrix is stored. Thus, capability exists only for a crude form of partitioning be- tween rows of the matrix. The SPEAKEASY language developed at Argonne Laboratory /_!_/ is an interpretive array language which contains a very general form of partitioning, in which the programmer can specifically choose the rows and columns of any subarray of interest. It has the distinct disadvantage of requiring the programmer to maintain the structure and the partitioning variables himself. A third language, OSCAR, developed at Oregon State University, permits a type of parti- tioning more like that presented in this paper /6_/. However, OSCAR, as well as the other two languages, is concerned only with the partitioning of rectangular arrays. In OL/2, we have proceeded somewhat farther, allowing the partitioning of triangular and diagonal arrays, and allow- ing what we have defined in the previous sections as diagonal partitioning. 2. OL/2 PARTITIONING 2.1 Partitioning Examples The syntax of partitioning in OL/2 can be illustrated by recalling several well known algorithms from linear algebra, The first example (Figure 2) is the algorithm for LU decomposition using the Crout method. This algorithm decom- poses a square matrix into lower triangular and upper triangu- lar matrices, the product of which is the original matrix. The matrix A is replaced by the lower triangular matrix L and the strictly upper triangular matrix U. The diagonal elements of U are theoretically equal to one and are therefore not stored. The example illustrates the partitioning of a rec- tangular matrix followed by the partitioning of a subarray which we have referred to earlier as multilevel partitioning. At the conclusion of the algorithm, the new matrix A is divided into its distinct triangular matrices L and U, il- lustrating diagonal partitioning. The second example (Figure 3) is the Cholesky decom- position algorithm which illustrates the partitioning of a lower triangular array. In this example the original matrix L is assumed to be symmetric and positive definite and, there- fore, can be stored as a lower triangular matrix. This re- duces the physical storage by approximately one-half. The algorithm then replaces L by a lower triangular matrix in the usual way. The number of operations and the amount of storage L. -I. Xi B y; m CROUT ALGORITHM T" \ \ L \ \ LUJECOMPOSITION: LET A BE A MATRIX OF ORDER ill), L THE LOWER TRIANGULAR PART OF A, AND U THE STRICTLY UPPER TRIANGULAR PART OF A; FOR K = 1, 2 N; PARTITION A AFTER ROW K AND AFTER COLUMNS K-l AND K; SET C = A<2,1>, X = A<1,2>, Y = A<2,2> AND B = A<1,3>; PARTITION C, Y, M AFTER ROW 1; SET R = C<1>, D = Yd), AND Z = n; Y = Y - C*X; Z = ( Z - R*B )/D; END LUJECOMPOSITION; »*»**»*»#»****#»♦»»♦»»*»#»■»»*»##*♦»»#*»»»•»*###♦##*##*#»♦»»♦»♦»*#»#*#*#*#*♦»**» FIGURE 2. CROUT METHOD ••*«•*••*******»»*•»*••*****•*•*»*******»•****•******•*••*••»••»«**•*•«**«*•*•* CHOLESKY ALGORITHM w T Y T ju" L' CHOLESKY JJECOMPOS ITION: FO RWARD.REDUCT ION: LET L BE A LOWER TRIANGULAR MATRIX OF ORDER (N) : LET X, Y, AND Z BE VECTORS OF ORDER (N); FOR K=l, 2 N; PARTITION L, Y, AND Z AFTER ROWS K-l AND K; SET R=L<2,1> ROW VECTOR, D=L<2,2> SCALAR, M=L<3,1>, C=L<3,2> COLUMN VECTOR, U=Y<2>, V=Z<2>, AND W=Y<1>; D = SQRT( D - (R',R') ); C = ( C - M*R' )/D; U = ( V - R*W )/D; END CHOLESKYJDECOMPOS ITION; BACK.SUBSTITUTION: FOR K=N, N-l 1; PARTITION L, X, AND Y AFTER ROWS K-l AND K; SETC=L<3,2>, D=L<2,2> SCALAR, S=X<2>, U=Y<2>, AND T=X<3>; S = ( U - C'*T )/D; END BACK SUBSTITUTION; ####»##*#*#***###*#*♦*»#•##»*#*#»##***##*#»»#»**♦**#*#♦»#♦**#*#*#**#»#*##»###*# FIGURE 3, CHOLESKY METHOD required is thus minimized. This algorithm also illustrates two other constructs: the inner-product (X,Y) of vectors X and Y, and the transpose R' of a row vector R. In these two examples we see how partitioning can be used to simplify the writing of matrix algorithms. However, the perceptive reader will notice that initial and final steps of the algorithms were not discussed. It suffices to say here that the algorithms are correct as they are written, without any special consideration of the initial and final steps. A more complete discussion of these points can be found in /5_/« Also, a complete description of the OL/2 partitioning constructs can be found in Appendix C and /5_/. 2. 2 Array Data Types and Organization The OL/2 language specifications currently provide for the declaration of OL/2 variables as single data elements (scalars) or as arrays with a maximum of eight dimensions. Also allowed, but not discussed in this paper, are the de- clarations for vector spaces and sequences of arrays. For these constructs and their uses we refer to /5_/- In the case of two-dimensional arrays, there are a number of specific data types which reflect the geometric shape of typical arrays. Assume that A is a matrix of order n with elements a. where i,j = 1,... ,n. Then A may be de- clared to be any of the types listed in Table 1. If a geo- metric shape is not specified then the compiler assumes the default configuration which is rectangular or square depending on the specific declaration. 1,0 Table 1. — Basic Data Types for Square 2-dimensional Arrays Geometric shape of A Abbr Code Stored elements of A Strictly Lower Triangular SLT 3 1 < j < i < n Lower Triangular LT 1 1 < j < i < n Diagonal D 6 1 < i = j < n Strictly Upper Triangular SUT 4 1 < i < j < n Upper Triangular UT 2 1 < i < j < n Tridiagonal TD 5 | i- j | < l,l ROW VECTOR, C = A <2,2> SCALAR, AND D = A <3,2> COLUMN VECTOR J PARTITION A <3,1> AFTER ROW 2 AND COLUMN 2; SET E TO THE DIAGONAL PART OF A <3.1> <2.2> 19 PARTITION E AFTER ROW 3; SET F TO E <1,1> ; The first statement, LET A BE A (15 BY 15) LOWER TRIANGULAR ARRAY; is an OL/2 declaration of a lower triangular array of order 15 with a total of 120 elements stored linearly as shown in Figure 8. It causes the generation of the ACB which repre- sents the simple array shown in Figure 7(a). The ACB appears as the root of the structure in Figure 9. The simple PARTITION statement, PARTITION A AFTER ROWS 7,8; defines a non-rectangular partitioning of the array, A. It causes the generation of the PCB appearing at level 1A of the structure in Figure 9. At this point, all pointers in the PCB have been set to the null value, since the subarrays have not been specified explicitly. The row partitioning variables have been set and copied into the column partitioning variable array because of the reflection property of non-rectangular partitioning. The array now exists logically as shown in Figure 7(b). The compound SET statement , SET B = A <2,1> ROW VECTOR, C = A <2,2> SCALAR, AND D = A <3,2> COLUMN VECTOR; explicitly declares the subarrays of interest to the program- mer. Implicit SET declarations are also possible and are men- tioned in Section 4.3. The SET statement causes an ACB to be 20 (a) Array A (b) Partitioned Array A (c) Partitioned Array A (d) Partitioned Subarray A<3 , 1> \ \ \ v \ \ \ \ \ E s \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (e) Partitioned Subarray A<3. 1X2.2> (f) Partitioned Subarray E Figure 7. Intermediate Steps of Data Structure Example 21 o CM LT> CM O CM ^D CTi 00 CO m CM LD CO CM r- H >£> LD oo r- t co I m CM CO CM CM in CM CM OO CM CM CM 00 m m CM oo en O m CTi CM in in in in CO m CO in w i rd 03 C •H tn •H •h O CO H tn •H &4 ACB Level 1 — NAME = 'A' | SiIAPE=LT 22 RELATIVE ORIGIN ■ 1 RLB = 1 KUB = 15 i CLB = 1 CUB = 15 n KB Level 1A — NO SECTIONS SIZE = 3 SIZE = 3 7 8 15 7 8 15 m. > a ' i 1 If ii ACB MAME = '3' SHAPE = PECT ACB NAME »'C'| SHAPE=LT ACB NO NAME SHAPE=K£CT ACB NAME = 'D' SHAFE=nECT RELATIVE PJGIN = 29 RELATIVE ORIGIN = 3d RELATIVE ORIGIN = 37 RELATIVE ORIGIN ■ kh RLB = 1 RUB = 1 RLE = 1 RUB = 1 RLB = 1 RUB = 7 RLB = 1 RUB =■- 7 CLB = 1 CUB • 7 CLB = 1 CUB = 1 CLB = 1 CUB = 7 CLB = 1 CUB = 1 " PCB Level 2A — NO SECTIONS SIZE = 2 SIZE -- 2 2 7 7 2 7 7 • 1 i 1 ACB Level 3 — NO NAME 1 SHAPE =RECT RELATIVE ORIGIN = 58 RLB = 1 RUB = 5 CLB = 1 CUB = 5 ' 1 PCB Level 3A --- LT PART UT PART SLT PART SUT PART TD PART D PART NO PARTITIONS i ACB Level k NAME = 'E' CHAPE=DIAG RELATIVE ORIGIN ■ 58 RLB • 1 RUB = 5 CLB = 1 CUB = 5 1 PCB Level UA — NO SECTIONS SIZE = 2 SIZE = 2 3 5 5 3 5 5 m ' ' ACB Level 5 — KAKB » T' | SHAPE-DIAG RELATira ORIGIN = 53 RLB = 1 HUB = 3 C LB = 1 CUB = 3 Figure Final Array Partitioning Structure of Example 23 allocated for each subarray specified. The row partitioning variable and column partitioning variable for each subarray are used to calculate the linear index for the pointer array and then the link is inserted. The new ACB's are then ini- tialized using data from the next higher-level ACB and its PCB, The results of these operations appear as level 2 in Figure 9, and the logical structure is shown in Figure 7(c). When partitioning is done on a two-dimensional array, it is possible that various subarrays degenerate from matrices to vectors or scalars. If the compiler is aware of these de- generacies, the expression evaluation routines are able to take advantage of the resulting simplifications into the generation of code. Unfortunately, with dynamic partitioning, the degeneracy cannot always be determined. Therefore, the user is allowed to specify any degeneracy that he knows will occur in the SET statement through the use of the three de- clarations given in the example. Our next partitioning operation, PARTITION A <3,1> AFTER ROW 2 AND COLUMN 2; operates on the subarray in the lower left corner of A. The rectangular partitioning here causes the generation of the PCB at level 2A in Figure 9. Here the row and column varia- bles are distinct (although equal in this example) and the PCB is smaller due to the fact that only four subarrays are pos- sible versus the possibility of nine in the original array. The status of subarray A <3,1 > is illustrated in Figure 7(d). 24 Our next simple SET statement, SET E TO THE DIAGONAL PART OF A <3,1><2,2>; effectively includes a diagonal partitioning operation. The statement first causes an ACB to allocate for the lower right section of the subarray A <3,1> so that it can be parti- tioned. The PCB is then allocated and initialized. To ef- fect the diagonal partitioning, another ACB is allocated for the new section and linked to the PCB through the appropriate pointer. The two ACB's and the PCB generated by this state- ment appear in the structure of Figure 9 at levels 3, 3A, and 4. The logical appearance of the subarray and its diagonal part are then shown in Figure 7(e). The non-rectangular PARTITION statement, PARTITION E AFTER ROW 3; defines the reflective-type partitioning of a diagonal array with results similar to those of the first statement in this example with the exception that only those subarrays on the diagonal are defined. Thus, reference to E <1,2> or E <2,1 > is meaningless and not permitted. The diagonal ar- ray now appears as in Figure 7(f) and the PCB for E has been added to the structure of Figure 9 at level 4A. The final statement in the example, SET F TO E < 1,1 > ; is similar to that of our first one, naming a diagonal sub- array of the diagonal array E and causing an ACB to be al- located and initialized, appearing at level 5 in Figure 9. The data structure of the array A, incorporating all ' 25 partitioning, is now complete and appears as diagrammed in Figure 9, and the original array with partition lines drawn in is illustrated in Figure 8. It is important to note that the example just pre- sented is not dynamic, but static, partitioning since the partition lines were specified explicitly with integers. In this case, the entire structure could have been constructed at compile time, provided that no other partitioning of A was attempted. However, to introduce variable bounds and parti- tion lines into the example would have complicated the pre- sentation without introducing anything new. The dynamic form of partitioning is accomplished by using variables instead of integers as partitioning variables and placing partition statements inside controlled loops. This has the effect of moving the partition lines each time through the loop. Examples of this use of dynamic partition- ing appear in Section 2. The structure resulting from using dynamic partitioning in our last example is identical to that of Figure 9 except that the partitioning variables are the current values of the variables specified in the PARTITION statement. In the event some of the values of these variables are identical, implying coincident partitioning lines, or fall outside the bounds of the array, the subarrays theoretically appearing between these lines are still well-defined and be- come null arrays when referenced. / 5/ 26 A second interpretation or result of the dynamic partitioning strategy involves the static placement of parti- tioning lines and the dynamic assignment of a name to the various subarrays. To illustrate, we use the static parti- tioning described in the last example. Assume that the same operations are performed on A <1,1 > and A < 3,3 > of the original array (see Figure 7(b)). This can be accomplished by the following OL/2 statements: FOR 1=1,3; SET G = A < I.I > • END; Or, equivalent ly, but not preferably, we can delete the SET statement above and replace all occurrences of the variable G with the A construct. If used frequently, this al- ternative could result in a degradation of the execution time due to the searching of the partitioning structure at each occurence. In this section we tried to illustrate the essential concepts necessary for understanding the partitioning data structure, and at the same time we have tried to illustrate some of the powerful features which result from a partitioning structure in an array language. In the next section we turn to some of the details which include the implementation of the syntax and semantics of the PARTITION and SET statements. 27 4. THE SYNTAX, SEMANTICS, AND PROCEDURES 4.1 TACOS The compiler for OL/2 is generated by a general translator writing system called TACOS / 2_~ • TACOS is capable of taking as input the syntax of a language and the associated semantics and producing a table completely specifying them. The compiler is then made complete with a fixed interpretive parser which performs a top-down parse according to the con- tents of the table. The specification of the syntax is in IBNF, a form similar to BNF. However, there are several ex- tensions which simplify the specification. First, parentheti- cal expressions are permitted in IBNF in order to reduce the number of phrase classes. Second, three different repetition characters are also defined in order to allow the phrase class interpretations given in Table 2. Table 2. — IBNF Repetition Symbols Repetition Number of IBNF BNF Character Occurrences Example Interpretation + >1 ::=+ : :=| * >0 ::=* : :=| ? or 1 ::=? : :=| The third extension to BNF is the specification of identifiers as intrinsic terminal symbols to the compiler. 26 Thus, instead of parsing letter by letter, the terminal phrase class <*I> causes a routine to be invoked which attempts recognition of a valid identifier. Other terminal symbols, such as delimiters and keywords, are enclosed in quotes or periods. The final departure from standard BNF is the set of terminal phrase classes that cause the compiler to generate calls to semantic action routines written in PL/1 at appro- priate times during the parsing. For example, to generate a call to semantic routine 5, the IBNF syntax would contain the phrase class, <#5>. With this introduction, one may interpret the IBNF syntax of the PARTITION and SET statements in Appendix C. Additional details of TACOS may be obtained from the original document by Gaffney / 2_/. 4.2 Compilation of the PARTITION Statement In this section and the following, the reader may wish to periodically reference the syntax, the semantic routines, the execution-time procedures, and the sample programs in Ap- pendices C through F, respectively. In particular, since the semantic routines will be discussed in general terms, it is helpful and sometimes necessary to refer to the actual rou- tines which are documented with comments in the appendices. First, we should investigate the implementation of a simple, one variable, rectangular PARTITION statement. PARTITION A AFTER ROWS I,J AND AFTER COLUMNS K,L; After the recognition of the keyword PARTITION, semantic , 29 routine 110 initializes the partition module, resets some flags, and initializes the variable stack index (STK-PTR). After this the parser continues scanning, looking for identi- fiers separated by commas, AND's, or both. As each identifier is found, its definition is checked in 111 and the name of its ACB pointer is put into the variable stack ( SUBTREE-PTR) in 114. Also put into this stack is the name of the simple variable's associated maximum partition size indicator which applies to all partitions of this variable. Thus, by observing the conventions in Appendix B, the names ' $1A1' and »#$1A1' are put into the stack. Since A is the only identifier listed, semantic routine 115 determines that the partitioning code can be simplified so that it does not have to use a stack and loop for the partitioning. Thus, the following code is generated: $PART_NODE_PTR = $1A1 ; $PCB_PTR = @OL2_INITIALIZE_PCB ( $PART_NODE_PTR , #$1A1); The function, @OL2_INITIALIZE_PCB, is a procedure that allo- cates the PCB, if necessary and initializes the structure. This procedure and other execution-time procedures are described in more detail in Appendix E. The parser now attempts to recognize either of the sets of keywords referring to rows or columns. Having found the word, ROWS, routine 118 extracts the expressions, I and J, and then produces the code which defines the partitioning in the PCB. 30 #ROW_PARTITION.#VARIABLE (2) = I; #ROW_PARTITION.#VARIABLE (3) = J; #ROW_PARTITION.#SIZE = 3; Now having recognized the keyword, COLUMNS, routine 118, since this is the second time through, produces the fol- lowing code: IF $PART_NODE_PTR -> #TYPE -, = THEN CALL @OL2_DIAGNOSTICS ( 1 ) ; Then, continuing, it generates corresponding statements for the column partitioning: #COL_PARTITION.#VARIABLE(2) = K; #COL_PARTITION . #VARIABLE ( 3 ) = L ; #COL_PARTITION.#SIZE = 3; Finally, semantic routine 119 generates: CALL @OL2_SORT_PARTITION_VARIABLES ($ PCB_PTR , 3 ) ; This procedure orders the partitioning variables in the PCB. For example, at execution-time, if K becomes greater than L, then the positions of K and L in the PCB would be inter- changed, preserving the ascending order of the variables. The second parameter of the routine is an integer indicating which set of variables to sort (see Table 3). Table 3. — @OL2_SORT_PARTITION_VARIABLES Parameter Parameter Action 1 Sort ROW Partitioning Variables only 2 Sort COLUMN Partitioning Variables only 3 Sort Both Sets of Variables , 31 We now consider a similar partitioning statement which contains qualified variables. PARTITION B<3,lx2,2> AFTER ROWS I, J AND AFTER COLUMNS K,L; Since the array to be partitioned here is actually a subarray that has resulted from previous partitioning, neither a name for its ACB pointer nor, in general, a maximum partition size indicator is available to the compiler. Thus, a variable is created to serve as the maximum partition size indicator for this PARTITION statement only, and the ACB pointer must be de- termined at execution time. These requirements are imple- mented by placing the function reference, @0L2_L0CATE_SUBARRAY ( @0L2_L0CATE_SUBARRAY ( $ 1B1 , 3 , 1 ) , 2 , 2 ) , and #PARTMAX1 in the stack and generating the following code: $PART_NODE_PTR = @0L2_L0CATE_SUBARRAY ( (a)OL2_LOCATE_SUBARRAY ($1B1,3 ; 1),2,2); $PCB_PTR = (D0L2_INITIALIZE_PCB( $PART_NODE_PTR , #PARTMAX1 ) ; The function, @OL2_LOCATE_SUBARRAY , is a procedure that, given the ACB pointer of an array and the subarray indices, returns the ACB pointer of the subarray, allocating and initializing the subarray ACB if necessary. The remainder of the code generated is identical to that of the previous example with the exception that the fol- lowing additional statement is generated by action routine 119 to define the maximum partition size variable created earlier and initialize it to the required value: DECLARE #PARTMAX1 FIXED BINARY (15.0) INITIAL (9): 3'2 As mentioned earlier, it is possible to partition several arrays identically with one PARTITION statement, and the arrays are not required to have the same dimensions or bounds. For example, consider the following combination of the previous PARTITION statement: PARTITION A AND B<3 , IX 2 , 2 > AFTER ROWS I, J AND AFTER COLUMNS K,L; In this case we are required to perform the previous series of operations once for both array A and the specified subarray of B. To accomplish this the partitioning is done within a loop. The only two dependent variables necessary for operations with- in the loop are the ACB pointer and corresponding maximum partition size indicator for each array. The control of the loop is maintained by passing these variables in a stack, the loop being executed until the stack is exhausted. Therefore, action routine 115 must first generate code to initially fill the stack. The "stack," as implemented, is a PL/1 controlled structure variable named #PARTITION_STACK with the second level of the structure being the pointer variable $ ROOT_NODE_PTR and the half word integer variable #PART_SIZE_MAX. ALLOCATE #PARTITION_STACK; $ROOT_NODE_PTR = $1A1 ; #PART_SIZE_MAX = #$1A1 ; ALLOCATE #PARTITION_STACK ; $ROOT_NODE_PTR = (§>0L2_L0CATE_SUBARRAY ( @OL2_LOCATE_SUBARRAY ( $1B1 , 3 , 1 ) , 2 , 2 ) ; #PART_SIZE_MAX = #PARTMAX1 ; • 33 Then the DO statement defining the loop and the initializa- tion call are generated: DO WHILE (ALLOCATION ( #PARTITION_STACK ) ) ; $PCB_PTR = @OL2_INITIALIZE_PCB ( $ROOT_NODE_PTR , #PART_S I ZE_MAX ) ; The next eight statements within the loop are identi- cal to those of the previous examples with the exception that $ROOT_NODE_PTR replaces $PART_NODE_PTR . Then, to pop up the stack, close the loop, and provide for the definition of the temporary variables, the following statements are generated: FREE #PARTITION_STACK; END; DECLARE #PARTMAX1 FIXED BINARY (15,0) INITIAL (9); Our final variation of the statement provides for the non-rectangular type of partitioning and for rectangular partitioning of only one dimension. For discussion we can combine the two cases into one PARTITION statement, assuming A is a non-rectangular array (e.g., lower triangular or diagonal) and the subarray B<3,lx2,2> is a rectangular array to be partitioned only between rows. PARTITION A AND B<3 , 1 X2 , 2 > AFTER ROWS I, J; The code generated through the initialization call within the DO group is identical to the last example. Then, action routines 118 and 119 generate the following similar code: 34 #R0W_PARTITI0N.#VARIABLE(2) = I; #ROW_PARTITION . #VARIABLE ( 3 ) = J ; #ROW_PARTITION.#SIZE = 3; CALL @0L2_S0RT_PARTITI0N_VARIABLES ($ PCB_PTR / 1 ) ; At this point in execution time, the program must determine which of the above two cases apply. If this is a rectangular partitioning of only one dimension, then nothing more has to be done. However, if this is the non-rectangular case, the column partitioning parameters must be made identical to the row partitioning variables to preserve the reflection property of this type of partitioning. Therefore, the following state- ment is generated: IF $ROOT_NODE_PTR — > #TYPE -i = THEN CALL @0L2_N0NRECT_PARTITI0N_BY_R0WS ( $ PCB_PTR ) ; The procedure, @0L2_N0NRECT_PARTITI0N_BY_R0WS , implements the reflection property for non-rectangular row partitioning, and @0L2_N0NRECT_PARTITI0N_BY_C0LS is the corresponding procedure for column partitioning. After this test, the loop is closed as in the previous example. 4. 3 Compilation of the SET Statement There are basically two types of SET statements, the overlay SET and the defining SET statements. The overlay type is the simpler of the two and will be discussed first. Assume that A is any OL/2 array that has been defined in a LET statement or a previous SET statement and let us consider the , 35 implementation of the following overlay SET statement: SET C = A; This capability has been implemented to allow an array to have several ACB's and thus allow an arbitrary number of mutually exclusive partitions, each partitioning structure having one of the ACB's as a root. After the recognition of the keyword SET, semantic routine 120 provides the initialization of the set module. Then finding the identifier, C, action routines 62 and 61 check the compiler's identifier table for previous definition. If an entry is found, a multiple definition error is flagged. Otherwise the identifier is added to the table. After recognizing the equals sign, the parser continues scanning, looking for an identifier that should be, in this case, defined. As each identifier is found, its definition is checked in semantic routine 111 and pertinent information is extracted from the identifier table in routine 126. Finally, semantic routine 121 builds the compile time node that is as- sociated with each OL/2 array variable /4_/ and generates the following code: CALL (§)OL2_ACB_DU PLICATE ( $1C1 , • C • , $1A1 ) ; The procedure, @OL2_ACB_DUPLICATE , builds another ACB which fully describes the array A and has the effect of naming it ' C. The defining SET statement names a partitioned subarray or geometrical section at some lower level in the structure. In its basic form, the statement is written as follows: SET D = A; 36 The semantic action routines called upon in this case per- form tasks similar to those in the previous example. However, routine 113 is used to process the partition indices and re- turn the string, @0L2_L0CATE_SUBARRAY ($1A1,N,M), in place of the simple variable. Semantic routine 121 then generates: $1D1 = (§>OL2_LOCATE_SUBARRAY ($1A1,N,M); $1D1 — > #NAME = «D» ; Diagonal partitioning, as described earlier, is im- plemented in the alternate form of the defining SET state- ment. Since this type of partitioning is simple in terms of the changes to the PCB and since a SET statement is always required for the result, the partition and set implementa- tions are combined. The SET is required here because con- structs of the form, A LOWER TRIANGULAR, are not allowed elsewhere in the language, whereas those constructs of the form A<1 , 2>are allowed in other places, such as in expres- sions. An example of diagonal partitioning, then, is the fol- lowing statement : SET E = A<3,4> LOWER TRIANGULAR; or SET E TO THE LOWER TRIANGULAR PART OF A<3,4>; The compiler action on these statements is essentially the same as in the previous example except that routine 8 2 extracts the geometry from the statement and sets the geo- metric type code to 1. Semantic routine 121 then generates the following code: 37 $1E1 = @0L2_L0CATE_PART_0F ( @0L2_L0CATE_SUBARRAY ($1A1,3,4) ,1) ; $1E1 — > #NAME = 'E' ; The function (§>OL2_LOCATE_PART_OF is a procedure which establishes the diagonal partitioning, allocating a PCB if necessary and then allocating an ACB for the geometric section Finally, the capability is present to specify the de- generacy of a subarray of a partitioned array in the SET statement for that subarray. Depending on the partitioning variables, the segments of a partitioned matrix may degenerate into column vectors, row vectors, scalars, or even null operands. If the programmer is aware when the program is written that certain subarrays always will be degenerate, then the degree of degeneracy can be specified in the SET statement for that subarray. This specification does not result in any change in the code generated for the SET statement, but is used subsequently by the compiler. This information is placed into the compile time nodes for these subarrays and, when the subarray appears in an array expression, it is assumed to be of the lower dimension. This results in more efficient code being generated for the expression /4_/. It must be noted, however, that code generated by the Version I compiler will be incorrect if the programmer has specified a degeneracy where actually none exists. 38 5. DISCUSSION We have illustrated, in previous sections, the imple- mentation of array partitioning in its static and dynamic forms. In order to satisfy the design objectives of the OL/2 language it was necessary to create a general tree structure with the root of the tree being the Array Control Block (ACB) of the original array and lower level nodes being the ACB's of the subarrays. Furthermore, it was necessary to allow the tree structure to be dynamic at execution time. The structure is linked together through the Partition Control Block (PCB), containing all of the dynamic information on the current par- tition, and is open-ended, permitting theoretically unbounded multi-level partitioning. The structure also lends itself well to what we have defined as "diagonal partitioning," or the extraction of specific geometric sections of the arrays. Finally, the very useful definition of the reflective parti- tioning of non-rectangular arrays was developed and imple- mented in the language. Some of the more significant problems encountered and for which the solutions have been presented here are: a) efficient design of the structure including the ACB and in particular the PCB. b) efficient design of the generated PL/1 code and execution time-routines. 39 c) implementation of a strategy powerful enough to allow completely "dynamic" partitioning of one- and two- dimensional arrays, i.e., the capability of accepting general scalar expressions in partitioning variables and indices. However, the present implementation has caused the imposition of two restrictions, the removal of which could be the basis for continued research. The first restriction is that the implementation requires the variables in a multiple PARTITION statement to be independent. For example, the statement , PARTITION A, A<1,2> AFTER ROW I AND COLUMN J; will produce unwanted results. This does not work because the list is actually processed in reverse order, that is, A<1,2> is partitioned first. The second restriction is that very large arrays of order 200 or larger are not kept by the compiler in core storage. In general, the size of these ar- rays will require their being kept in auxiliary storage until they are explicitly required. The current partitioning im- plementation does not support these large arrays because of the method of addressing subarrays in the structure. Another goal of further research could be the formula- tion of a definition of partitioning of arrays of dimension three or more. Several important questions must be answered. Is partitioning meaningful for arrays of more than two dimen- sions? Can applications be found for higher-level partitioning? 40 Regardless of the feasibility of further extensions to the concept, we have shown that two-dimensional dynamic partitioning is indeed useful and can be implemented effi- ciently for a high-level array language such as OL/2. kl LIST OF REFERENCES [1] S. Cohen and C. M. Vincent, An Introduction to SPEAKEASY , Argonne Physics Division, Argonne National Laboratory, Argonne, Illinois, Informal Report PHY-I968E (December 1968) . [2] J. L. Gaffney, Jr., TACOS : A Table Driven Compiler - Compiler System , Department of Computer Science, University of Illinois at Urbana- Champaign, Urbana, Illinois, Report No. 325 (June 1969) • [3] K. E. Iverson, A Programming Language , John Wiley and Sons, New York, (19627: [k] J. L. Latch, An Algorithm for Evaluating Array Expressions in OL/2 , Department of Computer Science, University of Illinois at Urbana-Champaign, Urbana, Illinois, Report No. ^22 (December 1970) . [5] J. R. Phillips, The Structure and Design Philosophy of OL/2 - An Array Language , Department of Computer Science, University of Illinois at Urbana-Champaign, Urbana, Illinois, Report No. 420 [6] The OSCAR Language, Informal report, Computer Center, Oregon State University, Corvallis, Oregon (to be published) . 42 APPENDIX A QL/2 SOURCE LANGUAGE CHARACTER SETS 1 1 » • 1 ( ) [ { ] } < > A, -B, ,c, • • A, .B, ,c, • • o, -1, r • • .9 OL/2 OL/2 IMPLEMENTATION CLASSIFICATION 88 CHARACTER SET 60 CHARACTER SET U. C. LETTERS A,B,C L. C. LETTERS a,b,c DIGITS 0,1,. BLANK UNDERSCORE SEPARATORS PARENTHESES BRACKETS BRACES PARTITION BRACKETS ADDITIVE OPERATORS +, - MULTIPLICATIVE OPERATORS X, / / 1 1 1 • 1 • ( 1 ) 1 1 _ <_ __l _> < > + , - * 1 / ** EXPONENTIATION t ** INVERSE -1 ** (-1) TRANSPOSE i ' SIMPLE RELATIONAL = , > , < = ,> , < COMPOUND RELATIONAL 4=, > , < -, = ,-!< , 1> NOT OPERATOR -^ —1 REFERENCE — > — > (not available) $, #, @, ?, %,&, 43 APPENDIX B OL/2 LANGUAGE IMPLEMENTATION CONVENTIONS 1. OL/2 Identifiers An OL/2 Identifier is a possibly empty string of alphameric and break characters preceded by a letter. The implementation restrictions are as follows: The length cannot exceed 24 characters. No special characters or blanks are allowed. The characters @, #, and $ are not allowed because they are re- served as prefixes in the implementation of OL/2. 2. OL/2 Partitioning Structure Nodes The partitioning structure nodes are defined in the implementation by the use of PL/1 based storage. The follow- ing two declarations define these nodes, illustrating the exact substructure of the ACB and PCB: DECLARE 1 #ARRAY_CONTROL_BLOCK BASED ($ROOT_PTR) ALIGNED, 2 #NAME CHAR ( 24) , 2 #ATTRIBUTES , (3 #DEFINED, 3 #STORAGE, 3 #TEMP_VARIABLE , 3 #BASE, 3 #SCALE, 3 #MODE ) BIT ( 1 ) , 3 #PRECISION FIXED BINARY (15,0), 2 #LENGTH FIXED BINARY (31,0), ( 2 #DIMENSIONALITY . 44 2 #MODULUS, 2 #TYPE, 2 #ROW_INCR, 2 #DIAG_INCR) FIXED BINARY (15,0), (2 $ ORIGIN ,2 $PARTITION_PTR) POINTER, 2 #BOUND_PAIR ( #DIM REFER ( #DIMENSIONALITY ) ), (3 #EXTENT, 3 #LOWER, 3 #UPPER ) FIXED BINARY (15,0); DECLARE 1 #PARTITION_CONTROL_BLOCK BASED ( $ PCB_PTR ), 2 #PCB_SIZE FIXED BINARY (15,0), 2 ^SECTION (6) POINTER, 2 #ROW_PARTITION, 3 #SIZE FIXED BINARY (15,0), 3 #VARIABLE (10) FIXED BINARY (15,0), 2 #COL_PARTITION LIKE #ROW__PARTITION , 2 $SUBARRAYS ( #SETMAX REFER ( #PCB_SIZE) ) POINTER; 3. Prefixes for Compiler Generated Variables @ - Built-in function and procedure entry names not avail- able to the OL/2 programmer. # - Compiler-generated arithmetic variable names. $ - Compiler-generated pointer variable names. 4. Structure of Generated Variable Names $XYZ A declared ACB pointer variable, such as $XYZ, is the ACB pointer for the OL/2 array identifier Y declared by the programmer in block number Z and block level X. $TEMPXY A temporary ACB pointer variable, such as $TEMPXY, is the ACB pointer for the Yth temporary variable whose array dimension is X. , 45 #$XYZ A temporary partitioning variable, such as #$XYZ, is the global maximum partition size indicator for the array Y where $XYZ is the ACB pointer constructed as above. #PARTMAXY A temporary partitioning variable, such as #PARTMAXY , is the local maximum partition size indicator for any array qualified by partition- ing indices appearing in a specific PARTITION statement where Y is the number of the statement #TEMPOY A temporary scalar variable, such as #TEMPOY , is the Yth temporary scalar required by the program. 46 APPENDIX C OL/2 SYNTAX FOR PARTITION AND SET STATEMENTS ( FOR THE COMPLETE SYNTAX OF OL/2 SEE REFERENCE 5 ) ::= ( | <#5> ( | <#107> ) )* ; :: = •%' <#140>; ::= ? <#9> ( I I ) ; ::= <#56> ( <*I> •:• <#57> )* <#55> ; :: = .PARTITION. <#110> <#115> •AFTER. <#118> T .AND, (.AFTER.)? <#118> )? ';• <#119> ; ::= (( .ROWS. I .ROW. ) <#116> | ( .COLUMNS. I .COLUMN. | .COLS. I .COL. ) <#117> ) ; ::= <#114> (( »,* ( .AND. )? I .AND. ) <#114> )* ; ::= .SET. <#120> ( ( ',' ( .AND. )? I .AND. ) ( .SET. )? <#120> )* •;• ; ::= <#62> ((.TO. .THE.
<#125> •PART. .OF. <#126> ) | ( ( • = • I .TO. ) ) ) <#121> ; ::= <#126> (
<#125> )? ( .SCALAR. <#122> I ( .ROW. <#123> I ( .COLUMN. I .COL. ) <#124> ) ( .VECTOR. | .VEC. )? )? ?
::= ( .BLOCK. <#77> )? (( .DIAGONAL. I .DIAG. ) <#78> I ( .TRIDIAGONAL. I .TRIDIAG. ) <#79> ) I ( ( ( .STRICTLY. | 'S.' I 'S' ) <#80> )? ( ( ( 'UPPER' <#81> | 'LOWER' <#82> ) ( 'TRIANGULAR' I 'TRIANG' )) I ( 'U.T.' I 'UT' ) <#81> I ( 'L.T.' | 'LT' ) <#82> ) I ( .SYMMETRIC. I .SYM. ) <#83> I 'SELF' ( 'ADJOINT' I •ADJ' ) <#84> I ( .REC. I .RECTANGULAR. I .SQUARE. ) <#85> ) ; ::= <*I> <#111> ( ' I' <#112> '|' <#138> )? ( •<• <#113> •>' )* ; :: = <*I> <#61> ('I' <#63> 'I' )? ; 47 APPENOIX OL/2 SEMANTIC ACTION ROUTINES FOR THE SYNTAX OF APPENDIX C ( FOR THE COMPLETE SEMANTICS OF OL/2 SEE REFERENCE 5 ) ACT: PROCEDURE(WHICH_ACTION_NUM) RECURSIVE; DCL WHICH_ACTION_NUM FIXED BIN (31,0) , /**************#**********************#********#****##****##***#*****/ /* */ /* COMMON STORAGE REGION FOR TRANSMISSION OF INFORMATION */ /* BETWEEN THE PARSER-SCANNER AND THE SEMANTIC ROUTINES */ /* */ 1 BRIDGE EXTERNAL* 2 GOCONDITION FIXED BIN (31,0) , 2 TEMPCONST VARYING CHAR ACTER ( 15 ) , 2 TEMPIDENT VARYING CHARACTER ( 32 ) t 2 TEMPSTRING VARYING CHAR ACTER ( 100 ) , CHAR(32767) CHAR(l) EXTERNAL CONTROLLED, (OK , INP) FIXED BINARY (31,0) EXTERNAL , ACTION (0:200) LABEL ; /***###**#***♦*##*#*****#**#♦#*******##********♦*********#********#**/ /* */ /* THE FOLLOWING ON AREA ROUTINE PROVIDES FOR ADDITIONAL */ /* STORAGE FOR THE COMPILE TIME STRUCTURES IF NECESSARY . */ /* NO AREA MANAGEMENT IS PROVIDED FOR THE EXPRESSION TREE */ /* BUILDING ROUTINES (#<50) BECAUSE OF THEIR LIMITED USE. */ /* */ IF WHICH_ACTION_NUM < 50 THEN ON AREA BEGIN ; CALL #ERR0R(103) ; END ; ELSE ON AREA BEGIN ; ALLOCATE VAR I ABL E_ARE A ; ALLOCATE AREA_STACK ; A_PTR = AREA_PTR ; A_LEVEL = CURRENT_PROGRAM_LEVEL ; END ; 48 /* */ /* PROCEED TO EXECUTE THE DESIRED SEMANTIC ACTION ROUTINE */ /* */ GO TO ACTION(WHICH_ACTION_NUM) ; /#»*********#***#*#*********«*******************#***#**********»*****/ /* */ /*. ENTRY DECLARATIONS */ /* */ DCL ACT ENTRY (FIXED BINARY (31,0)) ; DCL MOVCHAR ENTRY ( , FIXED BINARY (31,0) , FIXED BINARY (31,0) ) , POINTER_TO_STRING ENTRY ( CHAR ( 200 ) VAR Y ING , ARE A ( * ) ) RETURNS (POINTER); DCL #ERROR ENTRY ( FIXED BINARY (15tO) ) ; DCL SEARCH ENTRY ( CHAR(32) VARYING , FIXED BIN (31tO) ) RETURNS ( POINTER ) /* */ /* STATIC INTEGER DECLARATIONS */ /* */ DECLARE ( CURRENT_PROGRAM_LEVEL INITIAL (0) t BLOCK_LABEL_LEVEL (25) , BLOCK_LABEL_POINTER INITIAL (1) t BLOCK_# (20) INITIAL ((20)(0>) , CURRENT_in INITIAL (1) , I DENT I F I ER_LEVEL (200) ♦ IDENTIFIER_TYPECDDE (200) , UNDEFINED INITIAL (-1) ♦ IDENTIFIER_DIMENSION (200) t MAX_#_DI MENS I ONS INITIAL (8) ♦ RECTANGULAR INITIAL (0) , LOWER_TR I ANGULAR INITIAL (1) t UPPER_TRIANGULAR INITIAL (2) , STR I CTLY_LOWER INITIAL (3) , STRICTLYJJPPER INITIAL (4) t TRIDIAGONAL INITIAL (5) , DIAGONAL INITIAL (6) , SYMMETRIC INITIAL (7) , SELF_ADJOINT INITIAL (8) ♦ VECTOR_SPACE INITIAL (9) , BLOCK_ARRAY INITIAL (10) , STRING_LENGTH , TEMP_TYPECODE , MAX_STACK INITIAL (50) t MAX_ID_TA8LE INITIAL (200) , MAX_LABEL_TABLE INITIAL (25) , PARTITION_NUMBER INITIAL (0) * ROW_COL_SWl TCH t COMMA_COUNT , SIZE_PART(2) , TEMP_PARTSIZE , OVERRIDE INITIAL (4) , PARENT_DIMENSIONS , LAST_ENTRY_NOT_PROCESSED, #_OF_DI MENS I ONS , TEMP_POINTER ♦ SCALAR INITIAL (0) t FUNCTION INITIAL (1) »COL_VEC INITIAL (2) , ROW_VEC INITIAL (3) , MATRIX INITIAL (4) , TYPE_CODE , PARN_COUNT ) FIXED BINARY (15,0) STATIC, ( I , J , BEGINNING_OF_STATEMENT_PTR ♦ K , STK_PTR ) FIXED BINARY (31,0) STATIC, 49 /*****#**♦♦*********************************##***********************/ /* */ /* STATIC POINTER DECLARATIONS */ /* */ ( IDENTIFIER_NODE_POINTER (200) , I DENT I F I ER_NAME_POI NTER (200) , TEMP_P0INTER1 , INTER_PTR3 » AREA_PTR * NODE_POINTER , SP , SUBTREE_PTR ( 50 ) ) POINTER STATIC, /* */ /» STATIC BOOLEAN DECLARATIONS */ /* */ ( YES INITIAL I'l'B) , NO INITIAL <'0'B), POSSIBLE_LARGE_ARRAYS INITIAL I'O'B) , PARTITION_OEFINED , I DENT_DEF INED t I NDIRECT_REFERENCE , UNQUALIFIED , PART I T I ON_USED INITIAL ( 'O'B ) , STATEMENT_PRINTED INITIAL ('O'B) * INTERCHANGE_STATEMENT , COPY_TYPE_SET t SECT I ON_FOUND , SEQUENCES_FOUND, LABELS_FOUND, BLOCK_MATR I X_FOUND, • COMPLEX_IDS, IDENTITIES_FOUND, STRICTLY ) BIT (1) STATIC ALIGNED, /* */ /* STATIC STRING DECLARATIONS */ /* */ ( BLOCK_LABEL_NAME (25) CHAR(32) VARYING, OUTPUT_BUFF ER CHAR(500) VARYING INITIAL (") , A_STRING CHAR(200) VARYING, B_STRING CHAR(200) VARYING , TYPE_PREFIX CHAR (4) , DIGIT_STRINGS (0:25) CHAR(2) VARYING INITIAL CO* , 'l* , '2' , •3 1 , '4' , »5« , '6' , •?• , '8' , '9» , '10' , '11' ♦ •12' , '13' , '14' , '15' , '16' , '17' , '18' , '19' , •20' , '21' , '22' , '23' , '24' , '25' ) ) STATIC, 50 /* »/ /* STACK DECLARATIONS */ /* */ /lit*******************************************************************/ SET_MAX_STACK POINTER CONTROLLED , DCL_ONLY_STACK CHAR(32) VARYING CONTROLLED ♦ 1 DCL_AND_ALLnCATE_STACK CONTROLLED , 2 DCL_NAME CHAR (32) VARYING , 2 DCL_DIM FIXED BIN (15,0) t 1 AREA_STACK CONTROLLED , 2 A_PTR POINTER , 2 A_LEVEL FIXED BIN (15,0) , /* */ /* BASED VARIABLE DECLARATIONS */ /* */ /«♦**#****♦**♦********#*»**♦#******#******************#************♦*/ VARIABLE_AREA AREA ( 2000 ) BASED ( AREA_PTR ) , 1 TREE_NODE BASED ( N0DE_POINTER ) , ( 2 RLINK , 2 LLINK , 2 SEO_#_PTR , 2 STRING_POINTER ) POINTER, ( 2 $#DIMENSIONS, 2 PART_SIZE , 2 #_OF_TIMES_TO_USE ♦ 2 TYPE_EXP , 2 #TEMP_TO_FREE, 2 #CEND_STATEMENTS , 2 #REND_STATEMENTS, 2 $TYPE_CODE ) FIXED BINARY (15,0) , ( 2 NEGATE_TAG , 2 TRANSPOSE_TAG , 2 IDENTITY_TAG ) BIT (1) , 1 VARIABLE_STRING BASED (SP), 2 LEN FIXED BIN (15,0), 2 STRINGS CHAR ( STR ING_LENGTH REFER (LEN)) : 51 /* */ /* COMPILER DIAGNOSTIC MESSAGES */ /* */ DECLARE ERROR_MSG (40) CHAR (120) STATIC INITIAL ( UNDEFINED VARIABLE IN A PARTITION OR INTERCHANGE STMT WAS IGNORED UNMATCHED QUALIFIER SYMBOL - SUBSEQUENT RESULTS UNPREDICTABLE UNMATCHED PARENS IN AN INTERCHANGE VARIABLE EXPRESSION MORE THAN 2 ELEMENTS IN A QUALIFIER - VARIABLE HAS BEEN IGNORED NO VALID ITEMS TO PARTITION - SUBSEQUENT PROCESSING OF STMT OMITTED ROW PARTITIONING VARIABLES APPEAR MORE THAN ONCE IN SAME STMT COL PARTITIONING VARIABLES APPEAR MORE THAN ONCE IN SAME STMT UNMATCHED PARENS IN A PARTITIONING VARIABLE EXPRESSION UNMATCHED PARENS IN A PARTITIONING VARIABLE EXPRESSION UNMATCHED PARENS IN A VARIABLE QUALIFIER UNMATCHED MODULUS SYMBOL - SUBSEQUENT PROCESSING OF STMT UNPREDICT INVALID TYPE USED IN SET STATEMENT - SECTION QUALIFIER IGNORED VARIABLE THAT HAS NOT APPEARED IN A PARTITION STMT IS QUALIFIED MODE ATTRIBUTE ( COMPLEX OR REAL ) HAS APPEARED MORE THAN ONCE BASE ATTRIBUTES ( DECIMAL OR BINARY ) APPEARED MORE THAN ONCE SCALE ATTRIBUTES ( FLOAT OR FIXED ) APPEARED MORE THAN ONCE PRECISION ATTRIBUTES HAVE APPEARED MORE THAN ONCE PRECISION LENGTH SPECIFIED IS NOT POSITIVE UNMATCHED PARENS IN AN INTERCHANGE VARIABLE EXPRESSION EXPRESSION SEQUENCE USED ILLEGALLY IN INTERCHANGE STATEMENT PL1 FUNCTION WITH 0L2 ARGUMENT 1 , PRECISION SPECIFIED IS OUT OF RANGE FOR BASE AND SCALE SPECIFIED MULTIPLY DEFINED OL/2 IDENTIFIER', IMPLEMENTATION RESTRICTION - OL/2 IDENTIFIER IS LONGER THAN 24 CHAR #225' , • #226' , ' *227' , • #228* , • #229' , • #230' , • #231' #232' , • #233' , ' #234' , ' #235' , • #236' , ' #237' , • #238' #239' , • #240' 52 /* */ /* SEMANTIC ACTION ROUTINE NUMBER 5 */ /* */ /* THIS ROUTINE PRINTS OUT THE NEXT OL/2 STATEMENT AS A PL/1 */ /* COMMENT IF IT HAS NOT ALREADY BEEN PRINTED */ /* */ ACTION(5): CALL SK IP_AND_OUTPUT; I=INP; DO WHILE MAX_LABEL_T ABLE THEN CALL #ERR0R(101) GO TO RETURN TO PARSER 54 /* */ /* SEMANTIC ACTION ROUTINE NUMBER 61 */ /* */ /* THIS ROUTINE INSERTS AN OL/2 IDENTIFIER INTO THE IDENTIFIER */ /* TABLE AND SEARCHES THE TABLE FOR MULTIPLE DEFINITIONS */ /* */ /* ERROR NUMBER 102 IS FLAGGED IF THE IDENT TABLE OVERFLOWS */ /* ERROR NUMBER 223 IS FLAGGED ON MULTIPLE DEFINITION */ /* */ ACTI0N(61 ) :IDENTIFIER_NAME_POINTER( CURRENT_ID ) = POINTER_TO_STRING ( TEMPIDENT t VAR I ABLE_ARE A ) IDENTIFIER_LEVEL( CURRENT_ID ) = CURRENT_PROGR AM_LEVEL TEMP_POINTERl = SEARCH ( TEMPIDENT , I ) IF I -.= £ IDENTIFIER_LEVEL( I ) = CURR ENT_PROGR AM_LE VEL THEN CALL #ERROR( 223 ) ; CURRENT_ID = CURRENT_ID + 1 IF CURRENT_ID > MAX_ID_TABLE THEN CALL #ERROR(102) GO TO RETURN TO PARSER /* */ /* SEMANTIC ACTION ROUTINE NUMBER 62 */ /* */ /* THIS IS THE IDENTIFIER PROCESSING INITIALIZATION ROUTINE */ /* */ /******************# *********************** ************#***********#*/ ACTI0N(62) :LAST_ENTRY_NOT_PROCESSED = CURRENT_ID SE0UENCES_FOUNn = NO GO TO RETURN TO PARSER /********************************************************************/ /* */ /* SEMANTIC ACTION ROUTINE NUMBER 63 */ /* */ /* THIS ROUTINE SCANS OVER A DUMMY SEQUENCE EXPRESSION */ /* */ /* ERROR NUMBER 211 IS FLAGGED ON UNMATCHED SEQUENCE SYMBOL */ /* */ /****** **********************************************:****#*********** / ACTI0N(63) :CALL SCAN_UNT I L..P ASS ( • I • « • $ • ) ; SEQUENCES_FOUND = YES ; IF CHAR(INP) = •;• THEN CALL #ERROR ( 211 ) ; GO TO RETURN_TO_PARSER ; 55 /*** /* /* /* /* /» /* /* /* /* /* /* /*** ************************************************************** SEMANTIC ACTION ROUTINES 77 - 85 THESE ROUTINES RECOGNIZE THE CONSTRUCTS AND SET TYPE_COOE PARTITIONING. ROUTINES 77 , VALID SPECIFICATIONS IN THE C BUT THE SAME SYNTAX AND SEMAN MODULE WHERE THE CONSTRUCTS A INTEGER DECLARATIONS FOR THE GEOMETRY SPECIFICATION TO INDICATE DIAGONAL 83 t 84 , AND 85 ARE NOT ASE OF DIAGONAL PARTITIONING TICS ARE USED IN THE DECLARE RE WELL-DEFINED. SEE THE ACTUAL ASSIGNMENT OF CODES ************************************************************** ***/ */ */ */ */ */ */ */ */ */ */ */ ACTION(77) :BLOCK_MATRIX_FOUND = YES GO TO RETURN TO PARSER ACTION(78) :TYPE_CODE = DIAGONAL GO TO RETURN TO PARSER ACTIONI79) :TYPE_CODE = TRIDIAGONAL GO TO RETURN TO PARSER ACTIONOO) .'STRICTLY = YES ; GO TO RETURN TO PARSER ACTIONI81 ) :IF STRICTLY THEN TYPE_CODE = STR I CTLY_UPP ER ELSE TYPE.CODE = UPPER_TRI ANGULAR GO TO RETURN TO PARSER ACTION(82):IF STRICTLY THEN TYPE_CODE = STR I CTLY_LOWER ELSE TYPE_CODE = LOWER_TR I ANGUL AR GO TO RETURN TO PARSER ACTION(83) :TYPE_CODE = SYMMETRIC GO TO RETURN TO PARSER ACTI0NI84) :TYPE_CODE = SELF_ADJOINT GO TO RETURN TO PARSER ACTION(85) :TYPE_CODE = RECTANGULAR GO TO RETURN TO PARSER 56 /* */ /* SEMANTIC ACTION ROUTINE NUMBER 107 */ /* */ /* THIS ROUTINE IS ENTERED WHEN NEITHER A PL/1 NOR AN OL/2 */ /* STATEMENT COULD BE RECOGNIZED. THE ROUTINE PRINTS OUT */ /* A WARNING MESSAGE AND THEN ASSUMES THAT IT IS PL/1 */ /* */ ACTI0NQ07): OUTPUT_BUFFER = •/* **STATEMENT NOT RECOGNIZED AS PL1 OR 0L2** */•; CALL SKIP_AND_OUTPUT; K=INP; CALL SCAN_UNTIL_PASS( •;• ) ; IF CHARUNP) = ' • THEN GO TO SET_OK_ZERO_AND_RETURN ; CALL MOVCHAR(OUTPUT_BUFFER tKtINP ) ; CALL SKIP_AND_OUTPUT ; INP = INP + 1 ; GO TO RETURN_TO_PARSER ; /* */ /* SEMANTIC ACTION ROUTINE NUMBER 110 */ /* */ /* THIS ROUTINE IS ENTERED AFTER RECOGNITION OF THE KEYWORD */ /* 'PARTITION' AND INITIALIZES RELEVANT FLAGSt THE STACK */ /* FOR IDENTIFIERS t AND INCREMENTS THE NUMBER OF PARTITIONS */ /* */ ACTION( 110) :PARTITI0N_DEFINED = NO ; PARTITION_NUMBER = P ART I T I ON_NUMBER + 1 ; INDIRECT_REFERENCE = NO INTERCHANGE_STATEMENT = NO ; STK_PTR = ; GO TO RETURN TO PARSER ; 57 /* */ /* SEMANTIC ACTION ROUTINE NUMBER 111 */ /* */ /* THIS ROUTINE IS CALLED AFTER RECOGNITION OF AN IDENTIFIER */ /* AND IF IT IS LOCATED IN A SEARCH OF THE IDENTIFIER TABLE* */ /* NECESSARY INFORMATION IS EXTRACTED FROM THE TABLEt SUCH */ /* AS ITS GEOMETRIC TYPE, MAXIMUM PARTITION SIZE INDICATOR */ /* AS A RESULT OF PREVIOUS PARTITIONS AND THE ACB POINTER NAME */ /* */ /* ERROR NUMBER 201 IS FLAGGED IF THE IDENTIFIER IS */ /* UNDEFINED AND A FLAG IS SET TO SKIP FURTHER PROCESSING */ /* */ ACTION! Ill ) :N0DE_POINTER = SEARCH ( TEMPIDENT , I ) ; IF NODE_POINTER = NULL I I DENT I F I ER_DI MENSI ON ( I ) = UNDEFINED THEN DO ; CALL #ERROR (201) ; IDENT_DEFINED ■ NO ; GO TO RETURN_TO_PARSER ; END ; SP = STRING_POINTER ; B_STRING = STRINGS ; TEMP_TYPECODE = $TYPE_CODE ; TEMP_PARTSIZE = PART_SIZE ; IDENT_DEFINED = YES ; UNQUALIFIED = YES ; GO TO RETURN TO PARSER ; /* */ /* SEMANTIC ACTION ROUTINE NUMBER 112 ♦/ /* */ /* THIS ROUTINE SCANS OVER A DUMMY SEQUENCE EXPRESSION */ /* */ /* ERROR NUMBER 211 IS FLAGGED ON UNMATCHED SEQUENCE SYMBOL */ /* */ ACTION! 112) :IF CHAR(INP) s • | ■ THEN GO TO SET_OK_ZERO_AND_RETURN ; CALL SCAN_UNTIL_KEEP( ' |» * •;• ) ; IF CHAR(INP) = ';• THEN CALL TERROR (211) GO TO RETURN TO PARSER ; 58 /* */ /* SEMANTIC ACTION ROUTINE NUMBER 113 */ /* */ /* THIS ROUTINE PROCESSES A SET OF PARTITIONING INDICES, */ /* THAT IS, THE ONE OR TWO EXPRESSIONS BETWEEN EACH •<• */ /* AND •>• IMMEDIATELY FOLLOWING AN IDENTIFIER. IF THE */ /* IDENTIFIER WAS UNDEFINED THEN THE ROUTINE IS BYPASSED */ /* */ /* ERROR NUMBER 202 IS FLAGGED IF THERE IS NO CLOSING BRACE */ /* ERROR NUMBER 204 IS FLAGGED FOR MORE THAN 2 EXPRESSIONS */ /* ERROR NUMBER 210 IS FLAGGED FOR AN UNEVEN PAREN COUNT */ /* */ /************ *****#**4:********#* **#************#******* **************/ ACTION( 113) : IF I DENT_DEF INFD = NO THEN DO ; CALL SCAM_UNTIL_PASS ( •>• t • ;• ) ; GO TO RETURN_TO_PARSER END ; /* THE FOLLOWING SECTION OF CODE EXTRACTS EITHER ONE OR TWO */ /* EXPRESSIONS FROM WITHIN THE BRACES. IF ONLY ONE EXPRESSION */ /* WAS PRESENT, THEN THE SECOND ONE IS MADE ZERO */ A_STRI\'G = • • ; PARN_COUNT , COMMA_COUNT = ; DO WHILE ( PARN_COUNT >= ) ; CALL SCAN_U\!TIL_KEEP (')•,•(', »,' , 'S' t •>' ); A_STRING = A_STRING II TEMPSTRING ; IF CHAR( INP) = • ) • THEN DO ; IF PARN_COUNT = THEN DO ; CALL TERROR (210) ; CALL SCAN_UNTIL_PASS ( •>• , »;' ) ; PARN_COUNT = -1 ; GO TO NOT_PAST ; END ; ELSE PARN_COUNT = PARN_COUNT - 1 ; END ; ELSE IF CHAR(INP) = '(• THEN PARN_COUNT = PARN_COUNT + 1 ; ELSE IF CHAR(INP) = •,• THEN IF PARN_COUNT = THEN COMMA_COUMT = COMMA_COUNT + 1 ; ELSE ; ELSE IF CHAR(INP) -.= ',' THEN DO ; IF CHAR( INP) = ' ; • THEN DO ; CALL #ERROR (202) ; IDENT_DEFINED = NO ; GO TO RETURN_TO_PARSER ; END ; PARN_COUNT = -1 ; GO TO NOT_PAST ; END ; A_STRING = A_STRING I I CHAR (INP) ; INP = INP + 1 ; NOT PAST: END ; 59 IF COMMA_COUNT = THEN A_STRING = A_STRING II ',0' ; ELSE IF C0MMA_C0UNT > 1 THEN DO ; CALL #ERR0R(204) ; IDENT_DEFINED = NO ; GO TO RETURN_TO_PARSER ; END ; /* WHEN PARTITIONING INDICES ARE SPECIFIED FOR A VARIABLE */ /* THE VARIABLE'S NAME TO THE COMPILER BECOMES A FUNCTION */ /* REFERENCE WITH THE VARIABLE NAME AND THE EXPRESSIONS */ /* EXTRACTED ABOVE AS PARAMETERS */ /******** x-. «#*******#*****************#**#*********** ***#********#**#*/ B_STRING = •S0L2_L0CATE_SUBARRAY (• I I B_STRING II »♦' II A_STRING I I • ) • ; UNQUALIFIED = NO ; GO TO RETURN TO PARSER ; /* */ /* SEMANTIC ACTION ROUTINE NUMBER 114 */ /* */ /* THIS ROUTINE PROCESSES EACH IDENTIFIER POINTER OR THE */ /* FUNCTION REFERENCE BUILT UP FOR IT IN ROUTINE 113. EACH */ /* IDENTIFIER, IF DEFINED , IS PUT INTO A STACK FOR LATER */ /* PROCESSING. THE MAXIMUM PARTITION SIZE INDICATOR FOR THE */ /* IDENTIFIER, WHETHER IT IS OF GLOBAL TYPE ASSOCIATED WITH A */ /* SPECIFIC ARRAY OR OF THE LOCAL TYPE ASSOCIATED WITH THE */ /* PARTITION STATEMENT, IS ALSO INSERTED IN THE STACK. */ /* AT THIS POINT THE PARTITIONING IS DEFINED FOR AT LEAST */ /* ONE ARRAY AND A FLAG IS SET TO INDICATE TO SUBSEQUENT */ /* ROUTINES THAT AN ATTEMPT SHOULD BE MADE TO GENERATE CODE */ /* */ ACTION( 114) :IF IDENT_DEFINED = NO THEN GO TO R ETURN_TO_PARS ER ; STK_PTR = STK_PTR + 2 ; IF UNQUALIFIED = YES THEN DO ; ALLOCATE SET_MAX_ST ACK ; SET_MAX_STACK = N0DE_POINTER ; A_STRING = STRINGS ; SUBTREE_PTR ( STK_PTR ) = SP ; END ; ELSE DO ; A_STR1NG = 'PARTMAX' || DIGI T_STR I NGS ( PARTITION_NUMBER ) ; SUBTREE_PTR ( STK_PTR ) = POI NTER_TO_STR I NG ( A_STRING , VARIABLE_AREA ) ; INDIRECT_REFERENCE = YES ; END ; SUBTREE_PTR ( STK_PTR - 1 ) = POI NTER_TO_STR I NG ( B_STRING , VARIABLE_AREA ) ; PARTITION_DEFINED = YES GO TO RETURN TO PARSER ; 60 /* */ /* SEMANTIC ACTION ROUTINE NUMBER 115 */ /* */ /* THIS ROUTINE IS CALLED AFTER ALL ARRAYS TO BE PARTITIONED */ /* HAVE BEEN PROCESSED BY 114 AND PLACED IN THE STACK. IF */ /* THERE IS AT LEAST ONE DEFINED VARIABLE, THIS ROUTINE */ /* BEGINS TO GENERATE CODE. THE CODE GENERATED DEPENDS ON */ /* WHETHER THFRE IS ONLY ONE ITEM IN THE STACK OR MORE THAN */ /* ONE. IN THE MULTIPLE CASE, AN EXECUTION-TIME STACK IS */ /* USED TO PASS THE VARIABLES TO A 'DO WHILE 1 LOOP. IN */ /*. THE SINGLE VARIABLE CASE, A SIMPLE ASSIGNMENT STATEMENT IS »/ /* SUFFICIENT. IN BOTH CASES THE CODE GENERATED TO EFFECT */ /* INITIALIZATION OF THE PARTITIONING AND THE EXECUTION-TIME */ /* DATA STRUCTURE IS A SIMPLE FUNCTION REFERENCE */ /* */ /* ERROR NUMBER 205 IS FLAGGED IF THE VARIABLE STACK IS EMPTY */ /* */ ACTION( 115) :ROW_COL_SWITCH = ; SIZE_PART( 1 ), SIZE_PART(2> = 1 ; IF PARTITION_DEFINED = NO THEN CALL #ERROR (205) ; ELSE DO ; IF STK_PTR > 2 THEN DO ; DO I = 2 TO STK_PTR BY 2 ; SP = SUBTREE_PTR ( 1-1 ) ; B_STRING = STRINGS ; SP = SUBTREE_PTR ( I ) ; A_STRING = STRINGS ; OUTPUT_BUFFER = 'ALLOCATE #P ARTI TI ON_STACK ;• ; CALL SKIP_AND_0UTPUT ; OUTPUT_BUFFER = ■ $ROOT_NODE_PTR = • II B_STRING II •;• ; CALL SKIP_AND_OUTPUT ; OUTPUT_BUFFER = • #P ART_S I ZE_MAX = #• II A_STRING II ';• ; CALL SKIP_AND_0UTPUT ; END ; OUTPUT_BUFFER = •DO WHILE ( ALLOCATION ( #PARTI TI ON_STACK )) ;' ; CALL SKIP_AND_OUTPUT ; A_STRING = 'PART^IZE.MAX* ; B_STRING = •$R0OT_NODE_PTR« ; END ; ELSE DO ; SP = SUBTREE_PTR( 1) ; B_STRING = STRINGS ; SP = SUBTREE_PTR(2) ; A_STR1NG = STRINGS ; OUTPUT_BUFFER = • $PART_NODE_PTR = • || B_STRING II »;• 8_STRING = • $PART_NODE_PTR« ; CALL SKIP_AND_OUTPUT ; END ; OUTPUT_BUFFER = •$PCB_PTR = 30L2_INITIALIZE_PCB( • II B_STRING II » t#« II A_STRING I I • ) ; • ; CALL SKIP_AND_OUTPUT ; END ; GO TO RETURN TO PARSER ; 61 /* */ /* SEMANTIC ACTION ROUTINE NUMBER 116 */ /* */ /* THIS ROUTINE IS ENTERED UPON RECOGNITION OF THE KEYWORD */ /* 'ROW* OR 'ROWS' AND CAUSES A SWITCH TO BE SET THAT BOTH */ /* SERVES AS A CHECK. THAT THE SAME KEYWORD IS NOT USED */ /« MORE THAN ONCE AND SERVES AS A SWITCH IN 118 AND 119 TO */ /* INSURE THE CORRECT ORDER OF PARTITIONING CODE GENERATION */ /* */ /* ERROR NUMBER 206 IS FLAGGED IF 'ROW* APPEARS MULTIPLY */ /* */ ACTION( 116) : IF R0W_C0L_SWITCH = 1 THEN DO ; ROW_COL_SWITCH = 3 ; CALL #ERR0R(206) ; END ; ROW__COL_SWITCH = ROW_C0L_SW I TCH +1 ; TYPE_PREFIX = '#ROW« ; GO TO RETURN_TO_PARSER ; /* */ /* SEMANTIC ACTION ROUTINE NUMBER 117 */ /* */ /* THIS ROUTINE IS ENTERED UPON RECOGNITION OF THE KEYWORD */ /* 'COL' OR 'COLS' AND CAUSES A SWITCH TO BE SET THAT BOTH */ /* SERVES AS A CHECK THAT THE SAME KEYWORD IS NOT USED */ /* MORE THAN ONCE AND SERVES AS A SWITCH IN 118 AND 119 TO */ /* INSURE THE CORRECT ORDER OF PARTITIONING CODE GENERATION */ /* */ /* ERROR NUMBER 207 IS FLAGGED IF 'COL' APPEARS MULTIPLY */ /* */ ACTION! 117) :IF ROW__COL_SW ITCH = 2 THEN DO ; R0W_C0L_SWITCH = 3 ; CALL #ERR0R(207) ; END ; r0w_c0l„switch = row_col_sw i tch + 2 ; type_pre"fix = »#col' ; go to return to parser ; 62 /************#******#**♦**##*#************##***************##**##***#/ /* /* /* /* /* /* /* /* /* /* SEMANTIC ACTION ROUTINE NUMBER 118 */ */ */ THIS ROUTINE IS ENTERED AFTER SETTING THE SWITCH FOR EITHER */ ROW OR COLUMN IN 116 OR 117 AND EXTRACTS THE PARTITIONING */ VARIABLES AS AN EXPRESSION SEQUENCE FROM THE STATEMENT */ */ ERROR NUMBER 208 IS FLAGGED FOR AN UNEVEN PAREN COUNT */ ERROR NUMBER 209 IS FLAGGED FOR AN UNEVEN PAREN COUNT */ */ ACTION( 118) :IF PARTITION_DEFINED = NO I ROW_COL_SWI TCH > 3 THEN DO R0W_C0L_SWITCH = ROW_COL_SWI TCH - 3 ; CALL SCAN_UNTIL_PASS ( ';• ) ; GO TO RETURN_TO_PARSER ; END ; /* IF THIS IS THE SECOND TIME THROUGH THE ROUTINE* THIS MUST */ /* BE RECTANGULAR PARTITIONING AND, THEREFORE* A CHECK IS */ /* GENERATED AND INSERTED INTO THE CODE */ IF ROW_COL_SWITCH = 3 THEN DO ; J = 2 ; OUTPUT_BUFFER = 'IF • II B_STRING II • -> #TYPE -= THEN CALL 30L2_DI AGNOST I CS (1) ;•; CALL SKIP_AND_OUTPUT ; END ; ELSE J = 1 ; 1 = 1 ; /* THE FOLLOWING SECTION OF CODE EXTRACTS ONE EXPRESSION */ /* AT A TIME FROM THE EXPRESSION SEQUENCE, GENERATING FOR */ /* EACH ONE AN ASSIGNMENT STATEMENT FOR FILLING IN THE PCB */ 63 EXP_LOOP: 1=1+1; A_STRING = ■ ' 5 PARN_COUNT = ; DO WHILE ( PARN_COUNT >= CALL SCAM_UNTIL_KEEP ( A_STRING = A_STRING I I IF CHAR( INP) = • ) ' IF PARIS! COUNT ) • )• , • ( • t '» • TEMPSTRING ; THEN 00 ; THEN CALL #ERROR l ; t • and • ); (208) ( ' THEN PARN_COUNT = > THEN DO THEN DO ; PARN_COUNT = PARN_COUNT - END ; ELSE IF CHAR( INP) = PARN_COUNT + 1 ; ELSE IF CHAR(INP) -.= •»' £ PARN_COUNT CALL #ERROR (209) PARN_COUNT = -1 ; GO TO EXIT_PAST ; END ; ELSE IF PARN_COUNT = PARN_COUNT = -1 ; GO TO EXIT_PAST ; END ; A_STRING = A_STRING | | EXIT_PAST: INP = INP + END ; TEMPSTRING = OUTPUT_BIJFFER = TEMPSTRING DIGIT_STRINGS ( I ) I I • ) CALL SKIP_AND_OUTPUT ; IF CHAR( INP-1) = ' » ' I CHAR( INP-1 )=• ) ' INP = INP - 1 ; CHAR l ; (INP) TYPE_PREFIX I | • #VARIABLE< ' • I I A STRING I I '.PARTITION. • ; THEN GO TO EXP LOOP /* AFTER THE EXPRESSION SEQUENCE HAS BEEN EXHAUSTED, THE */ /* FINAL ASSIGNMENT STATEMENT REFLECTING THE PARTITION SIZE */ /* IS GENERATED AND THE SIZE IS SAVED FOR COMPUTATION */ /* OF THE MAXIMUM PARTITION SIZE INDICATOR */ OUTPUT_BUFFER = TEMPSTRING DIGIT_STRINGS ( I ) I I • ; • SIZE_PART ( J ) = I ; CALL SKIP_AND_0UTPUT ; GO TO RETURN_TO_PARSER ; I I '#SIZE 64 /* */ /# SEMANTIC ACTION ROUTINE NUMBER 119 */ /* */ /* THIS ROUTINE COMPLETES THE PROCESSING REQUIRED FOR THE */ /* PARTITION STATEMENT. THE CODE IS GENERATED FOR SORTING THE */ /* PARTITION VARIABLES AND FOR COPYING ONE SET OF VARIABLES */ /* INTO THE OTHER IN THE IMPLEMENTATION OF THE REFLECTIVE */ /* PROPERTY OF NONRECTANGUL AR PARTITIONING. THEN FOR MULTIPLE */ /* VARIABLE STATEMENTS THE 'DO WHILE* LOOP IS CLOSED OFF. */ /* IF ANY OF THE LOCAL TYPE OF MAXIMUM PARTITION SIZE */ /* INDICATORS WERE USED THEY ARE DECLARED AT THIS POINT. */ /* IF ANY GLOBAL TYPE MAXIMUM PARTITION SIZE INDICATORS WERE */ /* USED THEY ARE COMPARED WITH PREVIOUS VALUES AND UPDATED. */ /* */ ACTION! 119) :IF PARTITION_DEF INED = NO THEN GO TO R ETURN_TO_P ARSER ; OUTPUT_BUFFER = •CALL 30L2_S0RT_PARTITI0N_VARIABLES ( $PCB_PTR , • II DIGIT_STRINGS ( ROW_COL_SW I TCH ) II • );' ; CALL SKIP_AND_OUTPUT ; IF ROW_COL_SWITCH -i= 3 THEN DO ; SIZE_PART(2) = SIZE_PART(1) ; OUTPUT_BUFFER = 'IF • | IB_STRING| I • -> #TYPE -= THEN CALL • ; IF ROW_COL_SWITCH = 1 THEN OUTPUT_BUFFER=OUTPUT_BUFFER I I •aOL2_NONRECT_PARTITION_BY_ROWS ( SPCB_PTR ) ;• ; ELSE OUTPUT_BUFFER = OUTPUT_BUFFER I | 'S)OL2_NONRECT_PARTITION_BY_COLS ( $PCB_PTR ) ;• ; CALL SKIP_AND_OUTPUT ; END ; IF STK_PTR > 2 THEN DO ; OUTPUT_BUFFER = 'FREE #P ART I T ION_STACK ; END ;• ; CALL SKIP_AND_OUTPUT; END ; SIZE_PART(1) = SIZE_PART(1) * SIZE_PART(2) ; IF INDIRECT_REFERENCE = YES THEN DO OUTPUT_BUFFER = 'DECLARE #PARTMAX' || DIGIT_STRINGS ( PART I T ION_NUMBER ) II • FIXED BIN (15»0) INITIAL ( • II DIGIT_STRINGS ( S I ZE_P ART ( 1 ) ) II • );• ; CALL SKIP_AND_OUTPUT ; END ; DO WHILE ( ALLOCATION ( SET_MAX_STACK ) ) ; SET_MAX_STACK -> PART_SIZE = MAX (SET_MAX_STACK -> PART_SIZE t SIZE_PART(1) ) ; FREE SET_MAX_STACK ; END ; PARTITION_USED = YES ; GO TO RETURN TO PARSER ; 65 /* */ /* SEMANTIC ACTION ROUTINE NUMBER 120 */ /* */ /* THIS ROUTINE IS ENTERED AFTER RECOGNITION OF THE KEYWORD */ /* 'SET* AND INITIALIZES RELEVANT FLAGS AND THE TYPE CODE */ /* */ ACTION( 120) :INTERCHANGE_STATEMENT = NO ; SECTION_FOUND = NO ; BL0CK_MATRIX_F0UND = NO ; STRICTLY = NO ; COPY_TYPE_SET = YES ; TYPE_CODE=0; GO TO RETURN_TO_PARSER ; /* */ /* SEMANTIC ACTION ROUTINE NUMBER 121 */ /* */ /* THIS ROUTINE IS THE FINAL ONE IN THE SET SYNTAX AND HERE */ /* ALL THE INFORMATION NOTED IN ROUTINES 122 THROUGH 126 */ /* IS CORRELATED, RESULTING IN THE CONSTRUCTION OF A COMPILE- */ /* TIME TREE_NODE AND THE SMALL AMOUNT OF CODE GENERATED */ /* FOR THE SET STATEMENTS. IF THE OVERLAY TYPE SET IS USED, */ /* A CALL TO THE ROUTINE 30L2_ACB_DUPL ICATE IS GENERATED AND */ /* IF THE DEFINING TYPE SET IS USED, AN ASSIGNMENT STATEMENT */ /* AND CALLS TO 30L2_L0CATE_PART0F AND / OR */ /* TO aOL2_LOCATE_SUBARRAY ARE GENERATED */ /* */ /* ERROR NUMBER 224 IS FLAGGED IF THE IDENT IS TOO LONG */ /» ERROR NUMBER 213 IS FLAGGED IF PARTITION INDICES ARE USED */ /* WITH A VARIABLE THAT HAS NOT BEEN PARTITIONED */ /* */ ACTION( 121 ) :D0 I = LAST_ENTRY_NOT_PROCESSED TO CURRENT_ID - 1 ; ALLOCATE TREE_NODE IN ( VAR I ABLE_AREA ) IDENTIFIER_NODE_POINTER( I ) = NODE_POINTER RLINK , LLINK = NULL SP = IDENTIFIER_NAME_POINTER(I ) B_STRING = STRINGS A_STRING = •$• || DIGIT_STRINGS( CURRENT_PROGRAM_LEVEL ) II B_STRING II DIGIT_STRINGS( BLOCK_«( CURRENT_PROGRAM_LE VEL ) ) STRING_POINTER = PO I NTER_TO_STR I NG ( A_STRING , VARIABLE_AREA ) $TYPE_CODE = TYPE_CODE $#DIMENSIONS = #_OF_DIMENSIONS PART_SIZE = ; #_OF_TIMES_TO_USE = UNDEFINED SEQ_#_PTR = NULL TRANSPOSE..TAG , NEGATE_TAG = NO IDENTITY TAG = IDENTITIES FOUND 66 IF OVERRIDE < A THEN TYPE_EXP = OVERRIDE ; ELSE IF $#DIMENSIONS=0 THEN TYPE_EXP=SCALAR ; ELSE IF $#DIMENSIONS=l THEN TYPE_EXP=COL_VEC ; ELSE - IF $#DIMENSIONS>=2 THEN TYPE_EXP = MATR I X ; ELSE TYPE_EXP = UNDEFINED ; IF LENGTH( A_STRING ) > 30 THEN CALL #ERROR (224) IDENTIFIER_DIMENSION( I ) = #_OF_DI MENS I ONS IDENTIFIER_TYPECODE( I ) = TYPE_CODE SP = IDENTIFIER_NAME_P0INTER( I ) B_STRING = STRINGS IF POSSIBLE_LARGE_ARRAYS = YES THEN TEMPSTRING = MNDLL). 1 ; ELSE TEMPSTRING = 'tADORM II B_STRING II •),• B_STRING = •••• II B_STRING II •■•■ IF WHICH_ACTION_NUM = 121 THEN GO TO DSETCODE ; END ; /* A LARGE BLOCK OF CODE WHICH IS USED BY THE DECLARE */ /* MODULE HAS BEEN DELETED HERE TO AVOID CONFUSION */ DSETCODE: IF UNQUALIFIED = YES THEN DO ; IF SECTION_FOUND = NO THEN DO ; OUTPUT.BUFFER = 'CALL 30L2_ACB_DUPLICATE ( • II A_STRING| I • , ' I IB_STRING| I ' , • I IOUTPUT_BUFFER| I • ) ;• CALL SKIP_AND_OUTPUT ; ALLOCATE OCL_AND_ALLOCATE_STACK ; DCL_NAME = A_STRING ; OCL_DIM = PARENT_DIMENSIONS ; IDENTIFIER_TYPECODE( I ) , $TYPE_CODE=TEMP_TYPECODE GO TO DSE7B ; END ; ELSE GO TO DSETA ; END ; ELSE IF TEMP_PARTSIZE = THEN CALL #ERROR (213) ; DSETAMF SECTION_FOUND = YES THEN OUTPUT_BUFFER = 'aOL2_LOCATE_PARTOF (' || OUTPUT_BUFFER II •»• II DIGIT_STRINGS(TYPE_CODE) II •)• ; OUTPUT_BUFFER = A_STRING II • = • II OUTPUT_BUFFER II ': CALL SKIP_AND_OUTPUT ; OUTPUT_BUFFER = A„STRING I I • -> #NAME = • II B_STRING I I • ; • CALL SKIP_AND_OUTPUT ; ALLOCATE DCL_ONLY_STACK ; DCL_ONLY_STACK = A_STRING ; DSETB CALL SKIP_AND_0UTPUT OVERRIDE = 4 ; GO TO RETURN_TO_PARSER 67 /****«****4^«#**4^*«««*«««««**«#*««*******£*«*********$**************/ /* /* /* /* /* /* /* /* /* SEMANTIC ACTION ROUTINES 122 , 123 ♦ 124 ROUTINES 122 t 123 , AND 124 ARE ENTERED AFTER THE RECOGNITION OF THE KEYWORDS 'SCALAR' » 'ROW VECTOR' , AND 'COLUMN VECTOR' RESPECTIVELY. THROUGH THE VARIABLE OVERRIDE THESE ROUTINES PASS THE DEGENERACY TO THE EXPRESSION EVALUATION ROUTINES */ */ */ */ */ */ */ */ */ ACTION( 122 ) :«_OF_DIMENSIONS = ; OVERRIDE = SCALAR ; COPY_TYPE_SET = NO ; GO TO RETURN TO PARSER ; ACTION! 123) : #_OF_D IMENS I ONS = 1 OVERRIDE = ROW_VEC ; COPY_TYPE_SET = NO ; GO TO RETURN TO PARSER ACTION( 124) :#_OF_DIMENSIONS = 1 OVERRIDE = COL_VEC ; COPY_TYPE_SET = NO ; GO TO RETURN TO PARSER /* */ /* SEMANTIC ACTION ROUTINE NUMBER 125 */ /* */ /* THIS ROUTINE CHECKS THE GEOMETRIC SECTION SPECIFIED IN */ /* THE STATEMENT FOR VALIDITY, IGNORING IT IF IT IS NOT ALLOWED*/ /* */ /* ERROR NUMBER 212 IS FLAGGED IF AN ILLEGAL GEOM IS SPECIFIED */ /* */ ACTION( 125) :IF TYPE_CODE < 1 I TYPE_CODE > 6 I BLOCK_MATR 1 X_FOUND = YES THEN DO ; CALL #ERROR (212) ; TYPE_CODE = ; END ; ELSE SECTION_FOUND = YES ; GO TO RETURN TO PARSER ; 68 /* */ /* SEMANTIC ACTION ROUTINE NUMBER 126 */ /* */ /* THIS ROUTINE GATHERS INFORMATION ON THE NEW IDENTIFIER */ /* */ ACTION(126) :OVERRIDE = 4 ; PARENT_DIMENSIONS = $#DIMENSIONS ; #_OF_DIMENSIONS = $#OIMENSIONS ; 0UTPUT_8UFFER = B_STRING ; GO TO RETURN_TO_PARSER ; /* */ /* SEMANTIC ACTION ROUTINE NUMBER 138 */ /* */ /* THIS ROUTINE HAS NO ACTIONS IN THE SET STATEMENT CASE */ /* */ ACTION( 138) : IF INTERCHANGE_STATEMENT = YES THEN INTER_PTR3 = POINTER_TO_STRING ( TEMPSTRING t VAR I ABLE_ARE A ) ; GO TO RETURN TO PARSER ; /* */ /* SEMANTIC ACTION ROUTINE NUMBER 140 */ /* */ /* THIS ROUTINE OUTPUTS ALL INPUT UP TO THE NEXT % AS PL/1 COOE */ /* */ ACTION( 140) :D0 WH I L E ( CHAR ( I NP ) = • •); INP=INP+l; END; INP=INP-1; K=INP; CALL SCAN_UNTIL_PASS( • ; ' t '%• ) ; CALL M0VCHAR(0UTPUT_BUFFER,K,INP-1 ); IF CHAR ( INP ) = • ; « THEN OUTPUT_BUFFER = OUTPUT_BUFFER II • ;• ; CALL SKIP_AND_OUTPUT; IF CHAR(INP) = • ' THEN GO TO RETURN_TO_PARSER ; INP=INP+1; IF CHAR( INP-1)='%« THEN GO TO RETURN_TO_PARSER ; ELSE GO TO ACTION ( 140) ; 69 /* */ /* INTERNAL PROCEDURES */ /* */ /* */ /* SKIP_AND_OUTPUT */ /* */ /* THIS PROCEDURE PLACES ALL PL/1 OBJECT CODE ON THE PRINT */ /* AND PUNCH DATA SETS */ /* */ SKIP_AND_OUTPUT : PROCEDURE ; DCL DIVIDE BUILTIN ; DCL ( I t J » K ) FIXED BIN (15»0) ; PUT LIST ( OUTPUT_BUFFER ) SKIP ; I = DIVIDE ( LENGTH ( OUTPUT_BUFF ER ) t 71 , 15 » ) ; J = MOD ( LENGTH ( OUTPUT_BUFFER ) » 71 ) ; DO K = 1 TO I : PUT FILE(SYSPUNCH) EDIT (SUBSTR ( OUTPUT_BUFF ER » 71*K-70 , 71 ) ) ( X(l) , A(79) ) ; END ; PUT FILE(SYSPUNCH) EDIT (SU8STR ( OUTPUT_BUFF ER t 71*1+1 , J ) ) ( X(l) » A(79) ) ; OUTPUT_BUFFER = '• ; END SKIP AND OUTPUT ; /* */ /* TERROR */ /* */ /* THIS PROCEDURE PLACES ALL COMPILER ERROR MESSAGES ON */ /* THE PRINT DATA SET */ /* */ TERROR: PROCEDURE ( ERROR_CODE_# ) ; DECLARE ERROR_CODE_# FIXED BINARY (15,0) ; IF ERROR_CODE_* > 200 THEN PUT SKIP(2) LIST(ERROR_C0DE_#,ERR0R_MSG(ERR0R_CODE_#-200) ) ; ELSE PUT FILE(SYSPRINT ) SKI DECLARE ROW_I (0:6) FIXED BIN (15,0) INITIAL ( 1 , 1 , , 0, -1 , 2 , ) DECLARE DIA_I (0:6) FIXED BIN (15,0) INITIAL (0,1,-1,1,-1,0,0) 74 /* */ /* 30L2_INITIALIZE_PCB */ /* */ /* THIS PROCEDURE FIRST CHECKS TO SEE IF A PARTITIONING */ /* STRUCTURE EXISTS FOR THE ARRAY PASSED AS THE PARAMETER. */ /* IF ONE DOESt THE SIZE OF THE PCB IS CHECKED TO SEE IF IT */ /* IS LARGE ENOUGH. IF IT IS TOO SMALL* THE STRUCTURE IS */ /* PURGED ( 30LFLSH ) AND A NEW PCB IS ALLOCATED AND THAT */ /* PART OF THE PCB STRUCTURE DESCRIBING THE GEOMETRIC SECTIONS */ /* IS REPLACED, THEREBY PRESERVING THAT PART OF THE STRUCTURE. */ /* IF t HOWEVERt THE PCB IS LARGE ENOUGH, THE STRUCTURE */ /* BELOW IS SIMPLY MADE UNDEFINED (SOLERAS) AND THE PCB IS */ /* REINITIALIZED. IF NO STRUCTURE EXISTS, THEN A NEW PCB */ /* IS ALLOCATED AND INITIALIZED. THE PCB POINTER IS RETURNED */ /* */ /*»**i|it**)(;tt********#***********t*******#******************#*********/ aOL2PCB:PROC ( PTR3 , SETMAX ) RETURNS ( POINTER ) RECURSIVE ; $ROOT_PTR = PTR3 ; #SETMAX = SETMAX ; IF $ROOT_PTR= NULL THEN DO ; CALL 30L2_DIAGNOSTICS (6) ; RETURN ( NULL ) ; END ; SAVE_SECTIONS = NULL ; IF $PARTITION_PTR = NULL THEN GO TO GET_NODE ; ELSE DO ; $PCB_PTR = $PARTITION_PTR ; IF #PCB_SIZE >= «SETMAX THEN DO ; CALL SOLERAS ( ( $PARTI T ION_PTR ) ) ; CALL aOLEPCB ; RETURN ( $PCB_PTR ) ; END ; ELSE DO ; SAVE_SECTIOMS = SSECTIOM ; CALL aOLFLSH ( { SPART I T I ON_PTR ) , YES ) ; END ; END ; GET_NODE: ALLOCATE #PART I T I ON_CONTROL_BLOCK ; $PARTITION_PTR = $PCB_PTR ; CALL aOLIPCB ; ^SECTION = SAVE_SECTIONS ; RETURN ( $PCB PTR ) ; 75 /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* ##*******#* ^DEFINED = NO THEN DO CALL 5)OL2_DIAGNOSTICS (9) ; RETURN ( NULL ) ; END IF P IF ( ELSE ELSE $PCB. IF $ END $ROO IF $ TR -> #DIMENSI0NALITY = THEN CALL KTYPE = 5 £ TYPE = 6 ) I #TYPE = IF ( #TYPE = 1 5 ( TYPE = 3 I TYPE = ( #TYPE = 2 £ ( TYPE = 4 I TYPE = CALL 30L2_DIAGN0STICS (14); CHECKOK: _PTR = PTR -> SPARTITION_PTR ; PC8_PTR = NULL THEN DO ; #SETMAX = 1 ; ALLOCATE «PARTITIO\i_CONTROL_BLOCK PTR -> $PARTITION_PTR = $PCB_PTR $ROOT_PTR = PTR ; CALL aOLIPCB ; * T_PTR = SSECTION ( TYPE ) ; ROOT_PTR = NULL THEN DO ; #DIM = PTR -> ^DIMENSIONALITY ; ALLOCATE «ROOT_NODE ; SSECTION ( TYPE ) = SROOT_PTR ; ^DEFINED = NO ; SPARTITION PTR = NULL ; 30L2_DIAGNOSTICS (13) ; THEN GO TO CHECKOK ; 6 ) ) I 6 ) ) THEN GO TO CHECKOK; END IF «DEFINED YES THEN RETURN ( $ROOT PTR ) 76 #NAME = • • ; ^ATTRIBUTES = PTR -> #ATTRIBUTES ; #DIMENSIONALITY = PTR -> #DI MENSI ONALI TY ; ^MODULUS = PTR -> ^MODULUS ; #ROW_INCR = PTR -> #ROW_INCR ; #DIAG_INCR = PTR -> #DIAG_INCR ; #BOUND_PAIR = PTR -> #BOUND_PAIR ; IF ^DIMENSIONALITY >= 2 THEN #EXTENT(1) = MIN ( #EXTENT(1) , #EXTENT(2) ); ELSE #EXTENT(1) = #UPPER(1) = #LOWER(l) + #EXTENT(1) ; IF ^DIMENSIONALITY >= 2 THEN DO ; #UPPER(2) = #LOWER(2) + #EXTENT(1) ; #EXTENT(2) = #EXTENT<1) END ; PTR4 = PTR -> SORIGIN ; IF TYPE = 3 THEN OFFSET = #ROW_INCR * ^PRECISION ; JORIGIN = ADDR ( PTR4- -> DUMMY ( 1 + OFFSET ) ) ; #TYPE = TYPE ; RETURN ( SROOT PTR ) /* */ /* aOL2_NONRECT_PARTITION_BY_ROWS */ /* 30L2_N0NRECT_PARTITI0N_BY_C0LS */ /* */ /* THESE TWO PROCEDURES IMPLEMENT THE REFLECTIVE PROPERTY */ /* OF NONRECTANGULAR PARTITIONING BY COPYING THE ROW */ /* PARTITIONING VARIABLES INTO THE COLUMN PARTITIONING */ /* VARIABLES LIST OR VICE VERSA DEPENDING ON WHETHER ROWS */ /* OR COLUMNS WERE SPECIFIED BY THE OL/2 PROGRAMMER. */ /* */ 30L20WS: ENTRY ( PTR ) ; $PCB_PTR = PTR ; BASE_DIFF = #COL_PARTITION.#VARIABLE( 1 ) -*ROW_P ART I T I ON .# VAR I ABLE ( 1) ; #COL_PARTITION.#SIZE = #ROW_PART I T I ON. #SI Z E ; DO I = 2 TO #ROW_PARTITION.#SIZE #COL_PARTITION.#VARIABLE{ I ) =#ROW_PART I T I ON. #VAR I ABL E ( I ) + BASE_DIFF ; END ; RETURN ; 30L20LS: ENTRY ( PTR ) ; $PCB_PTR = PTR ; BASE_DIFF=#ROW_PARTITION.#VARIABLF< 1 ) -#COL_PARTI T I ON.# VAR I ABLE ( 1) #ROW_PARTITION.#SIZE = #COL_PARTI T I ON. #S I ZE ; DO I ^ 2 TO #COL_PARTITION.#SIZE ; #ROW_PARTITION.#VARIABLE< I ) =#COL_PART I T I ON. #VAR I ABL E ( I ) + BASE_DIFF ; END ; RETURN ; 77 /* /* /* /* /* /* /* /* /* /* /* /* /* ***♦*******♦******#**#***#***#************************#* THIS PROCEDURE BLOCK OF A SUB THIRD PARAMETE PARTITION. IF PARTITIONING I FROM THE PC3. SUBARRAY BUT T AND INITIALIZE REFERENCES TO 30L2_LOCATE_SUB ARRAY RETURNS A POINTER TO THE ARRAY CONTROL ARRAY OF A PARTITIONED ARRAY. THE SECON RS ARE THE ROW AND COLUMN INDICES OF TH THE THIRD PARAMETER IS ZERO, SINGLE DIM S ASSUMED, THE DIMENSION BEING DETERMIN IF THE ACB DOES NOT EXIST FOR THE SPECI HE REFERENCE IS VALID, THEN AN ACB IS C D FOR THE SUBARRAY. NONEXISTENT AND INV SUBARRAYS CAUSE AN ERROR RETURN #******$*************$****************##**************** */ */ */ */ */ */ */ */ */ */ */ */ */ D AND E ENSION ED FIC REATED ALIO 30L2RAY: ENTRY(PTR, ROW, COL ) RETURNS ( POINTER ) ; IF PTR = NULL I PTR -> #DEFINED = NO THEN DO ; CALL 30L2_DIAGNOSTICS (2) ; RETURN { NULL ) ; END ; $PCB_PTR = PTR -> $PARTITION_PTR ; IF $PCB_PTR = NULL THEN CALL 30L2_DI AGNOST I CS (3) ; INDEX = ROW + COL ; IF COL = THEN IF #ROW_PARTITION.#SIZE=l L #COL_P ARTI TION.#S I Z E>=ROW THEN DO; COL = ROW ; ROW = ; END ; ELSE IF #COL_PARTITION.#SIZE = l & #ROW_P ART I TI ON.#S I Z E> = ROW THEN; ELSE CALL 30L2_DI AGNOST I CS (A) ; ELSE INDEX = (ROW - 1 ) * #COL P ART I T I ON.#SI ZE + COL ; I (ROW COL #ROW_PARTITION.#SIZE I #COL_PARTITION.#SIZE) I IF #TYPE (#TYPE = 1 I #TYPE = 3 ) £ COL > ROW (#TYPE = 2 I #TYPE = 4 ) I COL < ROW (#TYPE = 5 I #TYPE = 6 ) & COL ->= ROW CALL aOL2_DIAGNOSTICS (5) ; $ROOT_PTR = SSUBARRAYS ( INDEX ) ; IF $ROOT_PTR = NULL THEN DO ; #DIM = PTR -> ^DIMENSIONALITY ; ALLOCATE #ROOT_NODE ; $SUBARRAYS ( INDEX ) = $ROOT_PTR ; ^DEFINED = NO ; $PARTITION_PTR = NULL ; END ; THEN IF ^DEFINED YES THEN RETURN ( $ROOT PTR ) 78 #NAME = • ' ; ^ATTRIBUTES = PTR -> ^ATTRIBUTES ; ^DIMENSIONALITY = PTR -> UD IMENS IONAL I TY ; ^MODULUS = PTR -> ^MODULUS ; #DIAG_INCR = PTR -> #DIAG_INCR ; #ROW_INCR = PTR -> #ROW_INCR + PTR -> #DIAG_INCR * #ROW_PARTITION.#VARIA8LE ( ROW ) ; IF ROW = COL THEN #TYPE = PTR -> #TYPE ; ELSE #TYPE = ; X = #COL_PARTITION.#VARIABLE( COL ) - #COL_PART I TI ON. # VAR I ABLE ( 1 ) ; Y = #ROW_PARTITION.#VARIA8LE( ROW ) - «ROW_PARTI T ION.# VAR I ABLE ( 1 ) ; ELEM INCR = #PRECISION ; PTR4 = PTR -> SORIGIN ; $ROOT_PTR -> SORIGIN = AODR ( DUMMY ( 1 + ELEM_INCR * ( X + PTR -> #ROW_INCR * Y + PTR -> #DIAG_INCR * ( .5* ( Y*Y-Y ) ) ) ) ) ; #BOUND_PAFR = PTR -> #BOUND_PAIR ; IF ROW -= THEN DO ; #LOWER(l) = 1 ; #UPPER(1) = #ROW_PART ITinN.#VARI ABLE ( ROW + 1 ) - #ROW_PARTITION.#VARIABLE ( ROW ) ; IF #DIMENSIONALITY > 1 THEN DO IF COL is THEN DO ; #LOWER(2) = 1 ; «UPPER(2) = #COL_PARTITION.#VARIABLE ( COL + 1 ) - #COL_PARTITION.#VARIABLE( COL ) ; END ; ELSE ; #EXTENT(2) = #UPPER(2) - #LOWER(2) ; END ; ELSE ; END ; ELSE IF ^DIMENSIONALITY = 1 THEN DO ; #LOWER(l ) = 1 ; #UPPER(1) = #COL_PARTITION.#VARIABLE ( COL + 1 ) - #COL_PARTITION.#VARIABLE< COL ) 5 END ; ELSE DO ; #LOWER(2) = 1 ; #UPPER(2) = #COL_PART I T I ON .#VAR I ABLE ( COL + 1 ) - #COL_PARTITION.tfVARIABLE( COL ) ; #EXTENT(2) = #UPPER(2) - #LOWER(2) ; END ; #EXTENT(1) = #UPPER(1) - #LOWER(l> ; RETURN ( SROOT_PTR ) ; 79 /* /* /* /* /* /* /* /* /* /* /* ****#***<:*S : iS:**<:**«***U:*^*******<:D I *****«*****^*****i********<:** aOL2_SORT_PARTITION_VARIABLES THIS PROCEDURE SORTS THE R OF THE PCR, THE COLUMN PAR SETS DEPENDING ON WHETHER TWO, OR THREE RESPECTIVELY THE BOUNDS OF THE SUBARRAY BOUND OR DOWN TO THE UPPER TWO VARIABLES SERVE AS THE OW PARTITIONING VARIABLES TITIONING VARIABLES, OR BOTH THE SECOND PARAMETER IS ONE, . ANY VARIABLES FALLING OUTSIDE ARE ADJUSTED UP TO THE LOWER BOUND. THE EQUALITY OF ANY DEFINITION OF 'NULL' SUBARRAYS **********#***#*********************#*******************#***** */ */ */ */ */ */ */ */ */ */ */ 30L2LES: ENTRY ( PTR , TYPE ) $PCB PTR = PTR IF TYPE -= 2 IF #ROW THEN DO ; PARTITION. #SIZE > 2 THEN DO ; DO I = DO 2 TO J = I IF END #ROW_PARTITION.#SIZE - 1 ; + 1 TO #ROW_PARTITION.#SIZE ; #ROW_PARTITION.#VARIABLE (I) > ^VARIABLE (J) THEN DO ; TEMP = #ROW_PARTITION.#VARIABLE #ROW_PARTITION.#VARI ABLE (I) = .^VARIABLE (J) ; #ROW PARTITION. #VARI ABLE (J) = TEMP #ROW_PARTITION. ( I ) #ROW PARTITION END ^VARIABLE ^VARIABLE (1 ) (1 ) IF #ROW_PARTITION.#VARIABLE (I) < THEN #ROW_PART I T ION .#VAR I ABLE (I) = #ROW_PARTITION. #ROW PARTITION. ^VARIABLE #VAR1ABLE ( 10) (10) END END ; IF #ROW_PARTITION.#VARIABLE (I) > THEN #ROW_PARTITION.#VARIABLE (I) = #ROW_PARTITION. #ROW PARTITION. IF TYPE = 1 THEN RETURN 80 I = 2 TO DO J II u. IF #COL_PARTITION.#SIZE > 2 THEN DO ; DO I = 2 TO #COL_PARTITION.#SIZE - 1 ; + 1 TO #COL_PARTITION.#SIZE ; #COL_PARTITION.#VARI ABLE (I) > #COL_P ART IT ION. ^VARIABLE (J) THEN DO ; TEMP ■ #COL_PARTITION.#VARI ABLE (I) ; #COL__PARTITION.#VARIABLE (I) = #COL_PARTI TION .^VARIABLE (J) ; #COL_PARTITION.#VARIABI_E (J) = TEMP ; END END IF #COL_PARTITION.#VARIABLE (I) < #COL_P ART I T I ON . ^VARIABLE (1) THEN #COL_PART I T I ON. #VAR I ABLE (I) = #COl_PART I T I ON. ^VARIABLE (1) ; IF #COL_PARTITION.#VARIABLE (I) > #COL_PART I TION. ^VARIABLE (10) THEN *COL_P ART I TI ON .#VAR I ABLE (I) = #COL_PART I T I ON, ^VARIABLE (10) END END ; RETURN ; /* */ /* S0L2_ACB_DUPLICATE */ /* */ /* THIS PROCEDURE COPIES THE INFORMATION FROM THE ARRAY */ /* CONTROL BLOCK OF THE THIRD PARAMETER INTO THE ARRAY CONTROL */ /* BLOCK OF THE FIRST PARAMETERt SUBSTITUTING THE SECOND */ /* PARAMETER AS THE NEW NAME, AND IGNORING THE PARTITIONING */ /* DATA STRUCTURE. THIS ALLOWS MULTIPLE NAMES AND STRUCTURES */ /* TO ASSOCIATE WITH THE SAME PHYSICAL ARRAY. /* */ 30L2ATE: ENTRY ( PTR1 , NAME t PTR ) ; IF PTRi -> #DIMENSI0NALITY -^= PTR -> #DI MENSI ONAL I TY THEN CALL 30L2_DIAGN0STICS (11) ; PTRI -> #ROOT_NODE = PTR -> #ROOT_NODE ; PTRI -> #NAME = NAME ; PTRI -> $PARTITION_PTR = NULL ; RETURN ; 81 /**♦********»*♦*»*»********#***************»***#****♦****************/ /* */ /* 30L2_INITIALIZE_ACB */ /* */ /* THIS PROCEDURE INITIALIZES THE ARRAY CONTROL BLOCK */ /* FOR AN OL/2 ARRAY VARIABLE. IF THE ARRAY IS TOO LARGE */ /* FOR IN-CORE STORAGE, THEN THE CALL TO 30LAL0C SETS UP THE */ /* STORAGE MANAGEMENT FOR THIS ARRAY. */ /* */ 30L2ACB ENTRY(PTR,PTR1 ,L ENGTH , S TOR AGE t NAME , DI M ? SCALE , MODE , SEO » LI » Ul , L2 ♦ U2 U6 L7 L5 , U5 ♦ L 8 THEN CALL 30L2_D I AGNOSTI CS (12) ; SKIP_REST: IF STORAGE = NO THEN DO ; IF TYPE = 4 THEN OFFSET = WIDTH ; SORIGIN = ADDR ( PTR1 -> DUMMY ( 1 - OFFSET ) ) END ; ELSE CALL 30LAL0C ( $ROOT_PTR ) ; IF DIM < 3 THEN DO ; #DIAG_INCR = DIA_I { TYPE ) ; IF TYPE = I TYPE = 2 I TYPE ■ A THEN #ROW_INCR = ROW_I ( TYPE ) + #EXTENT(2) ELSE #ROW_INCR = ROW_I ( TYPE ) ; END ; RETURN ; /* */ /* 30LERAS */ /* */ /* THIS PROCEDURE CANCELS ALL PARTITIONS BELOW THE STRUCTURE */ /* LEVEL SPECIFIED IN THE PARAMETER BY SETTING THE DEFINED */ /* FLAG IN EACH ACB TO THE UNDEFINED VALUE. NOTICE THAT THE */ /* STRUCTURE PHYSICALLY EXISTS FOR FUTURE PARTITIONING. */ /* */ SOLERAS: ENTRY { PTR ) ; IF PTR -> #ROW_PARTITION.#SIZE > 1 I PTR -> #COL_PARTITION.4SIZE > 1 THEN DO I = 1 TO PTR -> #PCB_SIZE ; PTR2 = PTR -> SSUBARRAYS ( I ) ; IF PTR2 -•= NULL THEN DO ; PTR2 -> #DEFINED = NO ; IF PTR2 -> $PARTITION_PTR -.= NULL THEN CALL 30LERAS ((PTR2 -> SPART I TI ON_PTR ) ) ; END ; END ; RETURN 5 83 /* */ /* 30LFLSH */ /* */ /* THIS PROCEDURE PHYSICALLY PURGES THE PARTITIONING STRUCTURE */ /* BELOW THE LEVEL SPECIFIED IN THE PARAMETER. THIS MUST BE */ /*■ DONE IN SOME CASES BECAUSE THE VARIABLE SIZE PCB IS NOT */ /* LARGE ENOUGH TO ACCOMODATE THE NEW STRUCTURE. */ /♦ */ 30LFLSH: ENTRY ( PTR , SAVE ) ; DO I = 1 TO PTR -> #PCB_SIZE ; PTR2 = PTR -> SSUBARRAYS ( I ) ; IF PTR2 -= NULL THEN DO ; IF PTR2 -> $PARTITION_PTR -.= NULL THEN CALL 30LFLSH ((PTR2 -> SPART I TI ON_PTR ) , NO ) #DIM = PTR2 -> ^DIMENSIONALITY ; FREE PTR2 -> #ROOT_NODE ; END ; END ; IF SAVE = NO THEN DO I = 1 TO 6 ; PTR2 = PTR -> SSECTION ( I ) ; IF PTR2 -= NULL THEN DO ; IF PTR2 -> $PARTITION_PTR -.= NULL THEN CALL 30LFLSH ( ( PTR2 -> SP ART I T I ON_PTR ) , NO ) #DIM = PTR2 -> (^DIMENSIONALITY ; FREE PTR2 -> #ROOT_NODE ; END ; END ; #SETMAX = PTR -> #PCB_SIZE ; FREE PTR -> #PARTITION_CONTROL_BLOCK RETURN ; 84 /* */ /* aOLIPCB - 30LEPCB */ /* */ /* 30LIPC8 IS THE PROCEDURE TO INITIALIZE THE FIELDS OF A PCB */ /* THAT HAS JUST BEEN ALLOCATED, THAT IS ONE WITHOUT ANY */ /* SUBSTRUCTURE. ALL POINTERS IN THE PCB ARE SET TO NULL. */ /* */ /* 30LEPCB IS THE PROCEDURE TO INITIALIZE THE FIELDS OF A PCB */ /* THAT IS PART OF AN EXISTING DATA STRUCTURE, THAT IS, NONE */ /* OF THE POINTERS ARE DISTURBED SINCE THEY CONTAIN VALID */ /* LINKS TO LOWER LEVELS IN THE STRUCTURE. */ /* */ solipcb: entry DO I = 1 TO 6 ; $SECTION( I ) = NULL ; END ; DO I = 1 TO #PCB_SIZE ; $SUBARRAYS( I ) = NULL END ; SOLEPCB: ENTRY IF ^DIMENSIONALITY > 2 I #D I MENS I ON AL I TY = THEN CALL aOL2_DIAGNOSTICS <7) J #ROW_PARTITION.«SIZE , #COL_P ART I TI ON .#SI Z E = 1 IF ^DIMENSIONALITY = 2 THEN DO ; LOWER2 = #LOWE»U2) ; UPPER2 = #UPPER(2) ; FND ; #ROW_PARTITION.#VARIABLE( 1) = #LOWER(l) - 1 #COL_PARTITION.#VARIABLE(l ) = LOWER2 - 1 5 DO I = 2 TO 10 ; #ROW_PARTITION.#VARIABLE( I ) = #UPPER(1) ; #C0L_PARTITI0N.#VARIA3LE( I ) = UPPER2 ; END ; RETURN ; END 30L2PCB 85 APPENDIX F 01/2 EXAMPLES THE POLL OF 01/2 DRAWN EX APPEAR I CONSISTS GENFRATF CONSTRUC SET STAT REEN ADO FROM DEF IS A VAL STATEMFN WITH THR FOLLOWIN CODF WIT EACH EXA OWING T PARTI TI CLUSI VE N THF S OF THE BY TH TED TO EMENT, En FOR 1 NIT I ON ID 01/2 TS ARF CODE G G. ALL HOIIT CO MPLE. R WELVE EX ONING AN LY FROM AMF ORDF OL/2 ST F COMPIL ILLMSTRA THE MECE COMPLETF S OF PL/ BLOCK. EMCLOSED FNERATFD ^L/l STA MMENTS. EFER TO AMPLES D SET THF DI R ENCO A T F M F N ER. AL TF A S SSARY NESS A 1 SCAL IN THF IN TH BY TH TEMEMT SPFCIF APPEND ILL STAT SCIIS IJNTE TS F THOU INGL PREL NO C AR V GEN F PL AT S S AP IC c IX E USTR EMFN SI ON RFD OLLO GH M E TY IMIN LARI ARIA FRAT /l C TATE PEAR OMME FOR ATE T TS. T S IN THFRF WED B AMY F PE OF ARY S TY. T BLES, FD CO OMMEN MENT IN T NTS A PROC HE IMP HE EXA THE TE . FAC Y THE XAMPLE PARTI TATEME HUSt A EACH DE ALL TS DEL IMMEDI HE GEN PPFAR EDURE LEMFMTATION MPLFS ARE XT AND H FXAMPI.E PL/1 CODE S ARF TION OR NTS HAVE SIDE EXAMPLE OL/2 IMITERS ATi=L Y FRATFD BEFORE DETAILS. /******:***************#*******************#**#*********#*************/ /* /* /* /* /* /* /* /* /* EXAMPLE 1 - CROOT LU DECOMPOSITION ALGORITHM OF FIGURE 2 CROUT LU DECOMPOSITION OF A SQUARE MATRIX INTO A LOWER TRIANGULAR PART AND STRICTLY UPPER TRIANGULAR PART THE PRODUCT OF WHICH IS THE ORIGINAL MATRIX. IN THIS EXAMPLE THE DEGENERACIES ARE SPECIFIED IN ALL SET STATEMENTS FOR COMPARISON WITH THE NONSPFCIFIED CASE OF EXAMPLE 2. */ */ */ */ */ */ */ */ */ /**********-.*******:;-.*:;: *****£******************* ***********************/ /* */ /* OL/2 SOURCE STATEMENTS */ /* */ / * * $***£#**£** * « ******** ******** ***************** * * * ****** ***********/ CROUT_ALGORITHM: LET A BE AN ( N BY N ) MATRIX ; ON ZERODIVIDE GO TO S I NGUL AR_M ATR I X ; FOR K = 1,2,.. .,N-1 ; PARTITION A AFTER COLUMNS K-1,K AND AFTER ROW K-l ; SET C=A<2,2> COL VECTOR, X=A<1,2> COL VECTOR, AL=A<2,1>, AU=A<1,3> ; PARTITION AL , C , AND A<2,3> AFTER ROW 1 ; SET R=AL<1> ROW VECTOR, 0=C<1> SCALAR, AND B=A<2 , 3>< 1>R0W VEC: C = C - AL * X ; I = MAXRSUB ( C ) ; INTERCHANGE ROWS I AND K OF A ; B = ( B - R * AU ) / D J END ; SET L TO THE LOWER TRIANGULAR PART OF A ; SET U TO THE STRICTLY UPPER TRIANGULAR PART OF A END CROUT_AI.GOR I THM ; 86 /* */ /* OL/2 OBJECT STATEMENTS */ /* */ /* CRni)T_ALGnRITHM: LET A BE AN ( N BY M ) MATRIX */ CRDUT_AlGORITHM: BEGIN /* OL/2_BLOCK */ ; DECLARE ( A ) { (( N -1+1)*(N -1+1) ) ) BINARY FLOAT ( 53 ) ; CALL anL2_lNlTIALlZF_ACB ( $ 1 Al , ADDR ( A ) , ( (( N -1+1)*(N -1 + 1) )) t O ,'A« t 2,0,8rO,0,0,l,l» N ,1,N 1 1 1 1 , 1 t 1 » 1 » 1 ♦ 1 1 1 1 1 » 1 1 1 , 1 ) *, ON ZEROOIVIDE GO TO S I NGUL AR_MATR I X ; /* FOR K = 1 ,2» ... ,N-1 ; */ DO K = 1 TO N-l BY 1 ; /* PARTITION A AFTER COLUMNS K-l t K AND AFTER ROW K-l ; */ $PART_NODE_PTR = $IA1; $PCB_PTR = 30L2_INITIALIZE_PCB( SPART_N0DE_PTR,#$1A1 ) ; *COL_PARTITION.«VARI ARLF(2 ) = K-l; «COL_PARTI TION.#VARI ABLF( 3 ) = K; #COL„PARTITION.#SIZE = 3; IF $PART_NODE_PTR -> #TYPF --= THEN CALL 30L2_DI AGNOSTI C S (1) ; #ROW_PARTITI0N.#VARIABLF (2 ) = K-l ; #ROW_PARTITI0M.*SIZF = 2: CALL 30L2_S0RT_PARTITI0N_VARIABLES ( $PCB_PTR , 3 ); /* SET C=A<2,2> COL VECTOR, X=A<1,2> COL VECTORr AL=A<2»1>, AU=A<1,3> ; */ S1C1 = S)OL2_LOCATE_SUBARRAY ($1A1,2*2); S1C1 -> #NAME = «C' 5 $1X1 ■ S)OL2_LOCATE_SUBARRAY ($1A1,1,2); $1X1 -> #NAME = 'X« ; $1AL1 = aOL2_LOCATE_Sl)BARRAY ($1A1,2,1); $1AL1 -> #NAME = 'AL 1 ; $1AU1 = 30L2_L0CATE_SUBARRAY ($lAl»l t 3); $1AU1 -> #NAME = 'AD' ; 67 /* PARTITION AL , C , AND A<2,3> AFTER ROW 1 ; */ ALLOCATE #PAR T I T I ON.STACK 5 $ROOT_NOOE_PTR = SlALl; *PART_SIZE_MAX = XS1AL1; ALLOCATE "PART I T I ON_ST ACK ; SROOT_NODF_PTR = S1C1~ *P.ART_SIZE_*AX = «41C1: ALLOCATE »PARTITION_STACK ; SROOT_NODF_PTR = 30L2_LOC ATF_SUBARR AY (S1A1,2,3); #PART_SI ZF^AX = *PARTMAX2; DO WHTLE ( ALLOCATION ( #P ART I T I ON_STACK )) ; SPCB.PTR = n10L2_INITIALlZE_PCR( $ROOT_NODE_PTR»#PART_SIZE_MAX ) ; «ROW~PARTITl:iN.*VARI ABI.F (2 ) = 1 ; #ROW_PARTITION.)'SIZF = 2; CALL 30L2_S0RT_PARTITI0N_VARIARLES ( SPCB_PTR , 1 ); IF $ROOT_NOnE_PTR -> #TYPE -•= THEN CALL S)OL 2_NONRECT_P ART I T I ON_8Y_ROW S ( $PCB_PTR ) ; FREE ttPARTI TION_STACK ; END ; DECLARE #PARTMAX2 FIXED BIN (15,0) INITIAL ( A ); /* SET R=AL<1> ROW VECTOR, D=C<1> SCALAR, AND B=A<2 , 3X1 >ROW VEC; */ S1R1 = S)0L2_L0CATE_SUBARRAY ($1AL1,1,0); S1R1 -> #NA*E = 'R' ; S1D1 = ^0L2_L0CATF_SUKARRAY ($1C1,1,0); $101 -> *NAME = '0' ; S1B1 = S0L2_L0CATF_S0BARRAY ( 5)0L 2_L0C ATE_SUBARR AY ( $1 A 1 , 2 , 3 ) , 1 , ) ; SI Bl -> «NAMF = , B' ; /* C C - AL * x ;*/ CALL 30LMULT(S1AL1,0,0,1,0,4,0,$1X1,0,0,1,0,2,0,$TEMP10,0,2,0) ; CALL ^OLSIIB($1C1,0,0,1,0,2,0,STEMP10,0,0,1,0,2,0,$TEMP10,0,2,0); CALL aOLASGNM SIC 1,0, 0,1,0, ST EMP 1 0, , ) ; CALL S)OLFSTR( STFMP10) : /* I = MAXRSUB ( C ) */ #TEMP00=MAXRSOB( S1C1 ) : I = #TEMPOO ; 88 /* INTERCHANGE ROWS I AND K OF A ; */ IF < END FIXED! K) -.= FIXED( I) E $1A1 -> #TYPE = & $1A1 -> #DI MENS I ONAL I TY 3 THEN DO ; ^INTERCHANGE -> ^DIMENSIONALITY = SI A 1->#DI MENSI ONAL I T Y ; CALL 30L2_ACB_DUPLICATF( $ I NTFRCHANGF , • • , $ l A 1 ) ; $PCB_PTR = S10L2_INITI ALIZF_PCR( $ I NTFRCHANGE » 5 ) ; *ROW_PARTITION.*VARIABLE(2) = ( I)-l; #ROW_PARTITION.*\/AR IARLF ( 3 ) = I; #ROW__PARTITION.#VAR I ABLF U) = ( K)-l; #ROW_PARTITION.«VARIABLF (5 ) = K; #ROW_PARTITION.#SIZE = 5 ; CALL SOL2_SORT_PARTITIOM_VARI ABLES( SPCB_PTR, 1 ) : SINTER_VFCTORl = t)OL2_LOC ATE_SUBARR AY ($ I NTFRCHANGE , 2 , ) ; *INTFR_VFCTOR? = 30L2J.OC ATF_SUB ARP AY ( $ I NTFRCHANGE t * , ) ; CALL SO LASGN( STFWPIO, 0,0,1, 0, $ I NTFR_ VECTOR 1 , , 0, ) ; CALL 3>0LASGN( S I NT FR_VECTOR 1 ,0 , 0, 1 , ,$ I MTER_VECT0R2 , , t ) ; CALL 30LASGN( S I NTFR_VECT0R2 , 0, , 1 , 0, STEMP 10 , 0, 0, ) ; CALL SOLFSTR ( STFMP10 ) ; ; ELSE IF S1AI ->*TYPE -= THEN CALL 30L2 01 AGNOSTICS ( 10 ) ; /* B = ( R - R * AU ) / D ; */ CALL aOLMULTt SlRl,0,0,l,0,3,0,$lAUltO,0,l,0,*,0,$TFMP10,0,3,0); CALL SOL SOB ( *lBltO»Otl»0,3»0,STFMPlOtO,0,ltO»3fOtST c MP10,0.3tO): CALL SOLDI VD I tTFMP 1 , ,0 , 1 , , 3 , , 30LSC AL ( S 1D1 ) , , 1 , ,0, , STEMP 10 » 0,3,0) : CALL SOLASGN( URl,0,0,l t O,$TEMP10,0,0); CALL SOLFSTR( tTEMPIO) ; END /* SET L TO THE LOWER TRIANGULAR PART OF A ; */ S 1 L 1 = S0L2_L0CATE_PART0F ( S I A 1 , 1 ) ; S1L1 -> #NAMF = «L' ; /* SET (J TO THE STRICTLY UPPER TRIANGULAR PART OF A ; */ $1U1 = 30L2_L0CATF_PART0F ($1A1,4); $1U1 -> *NAME = 'U' ; /* END CROUT_ALGORITHM ; */ DECLARE #tlALl FIXED BIN (15,0) INITIAL(4) ; DECLARE #$1C1 FIXFD BIN (15,0) INITIAL!*) ; DECLARE #$1A1 FIXED BIN (15,0) INITIAL(6) ; END CROUT ALGORITHM /* OL/2 BLOCK */ 89 /*$*********$*****************#**********#***************************/ /* */ /* EXAMPLE 2 - CROUT LU DECOMPOSITION ALGORITHM OF FIGURE 2 */ /* */ /* THIS EXAMPLE IS THE SAME AS EXAMPLE 1 WITH THE EXCEPTION */ /* THAT THE DEGENERACIES ARE NOT SPECIFIED IN THE SET */ /* STATEMENTS IN ORDER TO PROVIDF A COMPARISON OF GENERATED */ /* CODE FOR THE ASSIGNMENT STATEMENTS OF THE TWO EXAMPLES */ /* */ /************* * ************************************************* *****/ /* */ /* OL/2 SOURCE STATEMENTS */ /* */ /*******:£************************************************************/ CROUT_ALGORITHM2: LET A BE AN { N BY N ) MATRIX ; ON ZEROOIVIDE GO TO S I NGULAR_MATR I X ; FOR K = 1,2,...,N-1 ; PARTITION A AFTER COLUMNS K-ltK AND AFTER ROW K-l ; SET C=A<2,2> , X=A<1,2> • AL=A<2,1>, AND AU=A<1,3> ; PARTITION AL , C , AND A<2,3> AFTER ROW 1 ; SET R = AL<1> i D = C<1> t AND B=A<2,3><1> ; C = C - AL * X ; I = MAXRSUB ( C ) ; INTERCHANGF ROWS I AND K OF A B=(B-R*AU)/D ; END ; SET L TO THE LOWER TRIANGULAR PART OF A ; SET U TO THE STRICTLY UPPER TRIANGULAR PART OF A ; END CROUT ALGORITHM2 5 /********************************************************************/ /* */ /* OL/2 OBJECT STATEMENTS */ /* */ /******************; ff. **************************** *********************/ /* CROUT_ALGORITHM2: LET A BE AN ( N BY N ) MATRIX ; */ CROUT_ALGORITHM2 : BEGIN /* OL/2_BLOCK */ ; DECLARE ( A ) ( (( N -1+1)*(N -1+1) ) ) BINARY FLOAT ( 53 ) ; CALL ^)0L2_INITIALIZE_ACB ( $1 A 1 , ADDR ( A ) , ( (( N -1+1)*(N -1 + 1) )) ,0 ,^',2,0,8,0,0,0,1 ,1 , N ,1,N ,1,1,1,1,1,1,1,1,1,1,1,1 ) ; ON ZEROOIVIDE GO TO SINGULAR MATRIX 90 /* FOR K = 1*2,... T N-1 ; */ DO K = 1 TO N-l BY 1 ; /* PARTITION A AFTFR COLUMNS K-1,K AND AFTER ROW K-l ; */ $PART_NOOF_PTR = S1A1; $PCR_PTR = 30L2_INITI AL I Z E_PCB ( $P ART_NODE_PTR ,#$1A1 ) ; #D"1L_PARTITI0NJ.«VARI A3LE( 2 ) = K-l; *iCnL_PARTITIOM.#VARIARLE(3> = K; #C0l_PARTITJ0N.*SIZF = 3; IF $PART_NODE_PTR -> *TYPE -»= THEN CALL 30L2_DI AGNOSTI CS (1) ; #ROW_PARTITION.«VARI ARLE(2 ) = K-l ; «Rnw_PARTITIOW.*SIZF = 2; CALL 30L2_S0RT_PARTITI0N_VARIABLES ( SPCB_PTR , 3 ); /* SET C = A<2t2> , X=A<1,2> ♦ AL = A<2tl>» AND AII = A<1,3> ; */ tlCl = 30L2_L0CATE_SUBARRAY ($1A1,2,2K $1C1 -> «NAME = 'C ; $1X1 = 3nL2_L0CATF_SUBARRAY ($1A1,1,2); tlXl -> #NAME = 'X« : S1AL1 = 30L2_L0CATE_SOBARRAY ($lAl,2tl>; S1AL1 -> #NAME = «AL' 5 S1AU1 = 30L2_L0CATF_SUBARRAY ($lAl t l,3); $1AI)1 -> #NAME = 'AIM ; /* PARTITION AL , C t AND A<2 r 3> AFTER ROW 1 ; */ ALLOCATE #PART I T I ON_ST ACK ; SR0OT_NODE_PTR = S1AL1; *PART_S IZF_MAX = «$1AL1; ALLOCATE ""*PART I T I ON_STACK ; $R0OT_NODF_PTR = $1C1; *PART_SIZE_MAX = #$1C1; ALLOCATE #PART I T I ON_ST ACK ; $R00T_NODE_PTR = 30L2_L0C ATE_SUBARRA Y (SlAl,2t3); #PART_S IZE_MAX ~ «PARTMAX2? DO WHILE ( ALLOCATION ( UP ART I T I ON_STACK )) ; SPCB_PTR = 3lOL2_INITI ALlZE_PCB($ROOT_NODE_PTR,#PART_SIZE_MAX) ; #ROW_PARTI TIMM. 4VARI ARLE( 2 ) = 1 ; #ROW_PARTITION.#SIZF = 2: CALL 30L2_S0RT_PARTITinN_VARIABLES ( $PC8_PTR , 1 ); IF $ROOT_NODE_PTR -> *TYPE -= THEN CALL 30L2_N0NRECT_PAR T I T I ON_BY_ROW S ( $PCB_PTR ) ; FREE «PARTITI0N STACK ; ENO ; DECLARE «PARTMAX2 FIXED RIN (15»0) INITIAL ( 4 ); 91 /* SET R = AL<1> t 0=C<1> , AND B=A<2,3><1> ; */ S1R1 = S)0L2_LQCATE_SUBARRAY ($1AL1,1,0); $ 1R 1 -> tfNAME = 'R' ; $1D1 = 30L2_L0CATF_SUBARRAY ($IC1,1,0); $101 -> rfNAME = '0' ; $1B1 = 510L2_LOCATF_SUBARRAY ( @0L2_L0CATE_SIIBARR AY ( $ 1 Al , 2 , 3 ) ♦ 1 ,0 ) SIR 1 -> *NAMF = 'B' 5 /* C = C - AL * X */ CALL anLMI)LT($l AL 1, 0, 0, 1, 0,4,0, $1X1, 0,0, 1,0, 4, 0,$TFMP20, 0,4,0); CALL 9fJLSUB($lCl,0,0,l,0,4,0,$TFMP20,0,0,l,0,4,0,$TEMP20,0,4,0) CALL 30LASGNI $1C1,0,0,1,0,$TFMP20,0,0); CALL aOLFSTRf STEMP20) 5 /* I = MAXRSDB ( C ) ; */ #TEMP00 = MAXRSUB( SIC 1 ) ; I = #tempoo ; /* INTERCHANGE ROWS I AND K OF A ; */ IF FIXE < 3 TH $IN CAL $PC «R0 «R0 #R0 #R0 #R0 CAL SIN SIN CAL CAL CAL CAL E END 0( K ) EN DO TERCHA L 3HL2 B_PTR W_PART W_PART W_PART W_PART W_PART L S0L2 TER_VF TER_VE L 5)0LA L 30LA L SOLA L 30LF LSE IF -.= FIXEO( I) E $1 Al -> #TYPE = & $1A1 -> #01 MFNS I ONAL I TY ♦ NGF -> ^DIMENSIONALITY = $1 A 1->#DI MENSI ONAL I TY ; _ACB_OUPLICATF ($ INTERCHANGE , ' • ,$1A1 ) ; a S)0L2_INITIALIZF_PCB($IMTFRCHANGE,5) ; ITI0N.#VARIABLE(2> = ( I)-l; ITION.#VARI ABLE (3 ) = I; ITI0N.«VARIABLE(4) = ( K)-l; ITIOM.flVARI ABLE ( 5 ) = K? ITION.tfSIZE = 5 ; _SORT_PARTITION_VARI ABLFS( $PCB_PTR, 1 ) ; CT0H1 = aOL2_LOCATE_SUBARRAY($INTFRCHAMGE,2,0) ; CT0R2 = anL2_L0CATF_SUBARRAY( $INTFRCHANGF,4,0) ; SGN($TF MP 10, 0,0,1,0,$INTFR_ VECTOR 1,0, 0,0); S GN (SINTER _V EC TORI, 0,0,1 , ,$ INTER J'ECTOR 2 , ,0 , ) ; SGN( SIN Ti=R_ VECTOR 2, 0,0, 1,0,STFMP10,0, 0,0); STR ( STFMP10 ) ; $1A1 ->*TYPF -,s THEN CALL 30L2 01 AGNOST I C S ( 1 ) ; 92 /* B ( B - R * AU ) / D ; */ DO tfCOLl = $TFMP2n->#LOl#UPP FR ( 2 ) ; CALL aOLMULTI $lRl,0,0,l,0,4,0,$lAUl,0,0,l,0,2,#C0Llt$TEMP10,0,2,0); CALL SOL SUB ( S1B1 ,0,0,1 ,0 ,2 , #COL 1 , STFMP 10 ,0 , , 1 , , 2 t #C0L1 » STEMP 10 , 0,2,0) ; CALL 30LDIVD($TEMP10,0,0,l,0,2,0,aOLSCAL($101),0,l,0,0,0,$TENIP20, ■0,2,#C0L1 ) ; ENO; CALL 30LFSTR( STEMP10) ; CALL »OLASGN($1B1,0,0,1,0,$TEMP20,0,0) ; CALL SOLFSTRI STFMP20) ; END /* SET L TO THE LOWER TRIANGULAR PART OF A ; */ S1L1 = @0L2_L0CATF_PART0F ($1A1,1); SKI -> #NAME = 'L 1 5 /* SET U TO THE STRICTLY UPPER TRIANGULAR PART OF A ; */ MU1 = 30L2_L0CATF_PART0F ($1A1,4); $1U1 -> #NAME = 'U' ; /* END CROUT ALG0RITHM2 ; */ DECLARE #$1AL1 FIXED BIN (15,0) INITIALU) ; DFCLARE « S1C1 FIXFD BIN (15,0) INITIALS) ; DECLARE #S1A1 FIXED BIN (15,0) INITIALS) ; END CROUT ALG0RITHM2 /* OL/2 BLOCK */ 93 /* */ /* EXAMPLE 3 - CHOIESKY DFCOMPDS I T I ON ALGORITHM OF FIGURE 3 */ /* */ /* CHOLESKY DECOMPOSITION OF A POSITIVE DEFINITE SYMMETRIC */ /* MATRIX STORED AS A LOWER TRIANGULAR MATRIX INTO A */ /* LOWER TRIANGULAR MATRIX . THE PRODUCT OF THE RESULTANT «/ /* MATRIX AND ITS TRANSPOSE IS THE ORIGINAL MATRIX. */ /* */ /* */ /* OL/2 SOURCE STATEMENTS */ /• */ CHOLESKY_ALGORI THM: LET A BE A LOWER TRIANGULAR MATRIX OF ORDER < N ) ; ON ZERODIVIDE GO TO S I NGUL AR_MATR I X ; FOR K = 1,2,...,N-1 PARTITION A AFTER ROWS K-1,K ; SET R=A<2tl> ROW VECTOR, D = A<2 , 2>SCALAR , M= A<3 , 1> , AND C=A<3,2> COLUMN VECTOR ; D = SORT ( D - (R,R ) ) ; C=(C-M*R')/D ; END ; END CHOLESKY ALGORITHM ; /* */ /* OL/2 OBJECT STATEMENTS */ /* */ /******«**#*#*******«#*##****#*#*«********************«##*#* 4=********/ /* CHOLESKY_ALGORITHM : LET A BE A LOWER TRIANGULAR MATRIX OF ORDER ( N ) ; */ CHOLESKY_ALGORI THM: BEGIN /* OL/2_BLOCK */ ; DECLARE ( A ) ( (( N -1+1)*( N -1+21/2) ) BINARY FLOAT ( 53 ) ; CALL 30L2_INITI ALIZE_ACB ( $ 1 Al , ADDR ( A ) , ( (( N -i+n*( N -1 + 21/2)) » 0, 'A', 2, 1,8, 0,0, 0,1,1, N ,1, N ,1,1,1,1,1,1,1,1,1,1,1,1 ) : ON ZERODIVIDE GO TO SINGULAR MATRIX /* FOR K = 1,2, ...,N-1 ; */ DO K = 1 TO N-l BY 1 ; 94 /* PARTITION A AFTER ROWS K-1,K ; */ $PART_NODF_PTR = $IA1; $PCB_PTR = aOL2_INITIAL IZF_PCB( $PART_N0DE_PTR,#$1A1 ) ; #ROW_PARTITION.#VAR I ABLE (2 ) = K-l ; #ROW_PARTITION.#VARI ABLF( 3) = K ; #ROW_PARTITIO(V.#SIZE = 3; CALL~30L2_S0RT_PARTITI0N_VARIARLFS ( $PCB_PTR , 1 ); IF $PART_NODE_PTR -> #TYPE -.= THEM CALL 30L 2JMONR ECT_P ART I T I nN_BY_ROW S ( SPCB PTR ) ; /* SET R=A<2,1> ROW VECTOR, 0=A<2 , 2>SCAL AR , M=A<3 , 1 >, ANO C=A<3,2> COLUMN VECTOR ; */ $ 1R 1 = 30L2_L0CATF_SURARRAY ($1A1,2,1); S 1 R 1 -> dNAMP = »R» ; $101 = 30L2_L0CATF_SUBARRAY ($1A1,2,2); $101 -> «NAMF = «D' ; $1M1 = 30L2_L0CAT> :: _St)BARRAY ($1A1,3,1): $1M1 -> «NAME = •M" ; S1CI = aOL2_LOCATF_SUBARRAY ($1A1,3,2); SIC 1 -> «NAME = 'C ; /* D = SORT ( - (R,R ) ) */ *TFMP 00 = aOLIPRD($lRl,0,0,l,0,$lRl, 0,0,1,0); # TEMPO 1 = SORT! POOL SCAL ( $ 1 01 )-#T FMPOO ) ; CALL VIOLAS GN( $101, 0,0,l,0,«TEMP01,OtO); /* C ( c - M * R» ) / n */ CALL 30LMULTI $1M1,0,0,1,0,^,0,$1R1,0,1,1,0,2,0,$TE M P10,0,2,0); CALL 30LSUBU1C1 ,0,0,l,0,2,n,$TFMP10,0,0,l,0,2,0,$TFMPin,0,2,0); CALL 30LOIVO($TEMP10,0,0,l,0,2,0,?i!OLSCAL($101),0,l,0,0,0,$TFMP10, 0,2,0 ) : CALL o)OLASGM( $1C 1,0,0, 1,0, $TEMP1 0,0,0) ; CALL aOLFSTRt STEMP10) ; ENO /* ENO CHOLESKY_ALGORITHM ; */ DECLARE HUM FIXFO BIN (1S,C) INITIAL(9) ; ENO CHOLESKY ALGORITHM /* OL/2 BLOCK */ ; 95 /* */ /* EXAMPLE U - THE EXAMPLE OF SECTION 3.4 ILLUSTRATING */ /* */ /* THE PARTITIONING STRUCTURE AND ITS FORMULATION */ /* */ /£$$*«::jc$4:*:}:£S *:#********#**** * * * * *******#**#******#********** :;:***#**$*/ /* */ /* OL/2 SOURCE STATEMENTS */ /* */ EXAMPLE^: LET A RF A ( 15 BY 15 ) LOWER TRIANGULAR ARRAY ; PARTITION A AFTER ROWS 7 , R ; SET B=A<2,1> ROW VECTOR, C=A<2,2> SCALAR, AND D=A<3,2> COL VECTOR; PARTITION A<3,1> AFTER ROW 2 AMD COLUMN 2 ; SET E TO THE DIAGONAL PART OF A<3,1><2,2> ; PARTITION E AFTER ROW 3 ; SET F TO F<1,1> ; END EXAMPLE^; /* */ /* OL/2 OBJECT STATEMENTS */ /* */ /# LET A BE A ( 15 BY 15 ) LOWER TRIANGULAR ARRAY ; */ EXAMPLES : BEGIN /* OL/2_BLOCK */ ; DECLARE ( A ) { (( 15 -1+1)*(15 -1 + 2)72) ) BINARY FLOAT ( 53 ) ; CALL aOL2_INITIALlZE_ACB ( $1 A 1 , ADDR ( A ) , ( (( 15 -1 + D-M15 -l + 2)/2)) ,0,' A" ,2,1,8,0,0,0,1,1, 15 ,1,15 ,1,1,1,1,1,1,1,1,1,1,1, ) ; /* PARTITION A AFTER ROWS 7,8 ; */ SPART_NODE_PTR = $1A1; $PCB_PTR = 5)OL2_INITI ALIZF_PCB( SPART_N0DE_PTR,#$1A1 ) ; #ROW_PARTITION.*VARI ABLF(2) = 7 ; «ROW_PARTITI0N.#VARIABLE ( 3) = 8 ; #ROW_PARTITION.#SIZE = 3; CALL 50L2_S0RT_PARTITI0\'_\/ARIABLES ( *PCB_PTR , 1 ); IF SPART_NODF_PTR -> #TYPE -• = THEN CALL 30L 2_N0MRECT_P ART I T I ON_BY_ROW S ( SPCB PTR ) ; 96 /*SET B=A<2,1> ROW VECTOR, C=A<2,2> SCALAR, AND D=A<3,2> COL VECTOR;*/ S1B1 = 30L2_L0CATE_SUBARRAY ($1A1,2,1); $1B1 -> «NAME = 'B* ; $1C1 = 30L2_L0CATE_SUBARRAY ($1A1,2,2); S1C1 -> #NAME s 'C 1 ; $101 = 3OL2_L0CATE_SUBARRAY ($1A1,3,2); $101 -> «MAME = • 0« ; /* PARTITION A<3,1> AFTER ROW 2 AND COLUMN 2 */ $PART_NO0F„PTR = 30L2_L0C ATE_SUBARR AY ($1A1,3,1)5 $PCB_PTR ="30L2_1 NITI ALIZF_PCB( $PART_N0DE_PTR,#PARTMAX1 } ; #ROW_PARTITI0M.*VARIABLE(2 ) = 2 ', #ROW_PARTITION.#SIZF = 2; IF $PART_NODE_PTR -> STYPE -= THEM CALL 30L 2_0I AGNOST I C S (1) : #COL_PARTITION.*VARI ABLFI2) = 2 ; #CDL_PARTITION.#SIZF = 2; CALL 3OL2_S0RT_PARTITION_VARIABLFS ( $PCB_PTR , 3 ); DECLARE #PARTMAX1 FIXFD BIN (15,0) INITIAL < 4 ); /* SET F TO THE DIAGONAL PART OF A<3,1><2,2> ; */ $1E1 = S)0L2_L0CATE_PART0F ( 30L2_L0CATE_SOBARR AY (30L2_L0C ATF_SUBARR AY ($1A1 ,3,1 ) ,2,2) ,6) ; S1E1 -> «NAME = 'E« ; /* PARTITION E AFTER ROW 3 */ $PART_NOOF_PTR = $ 1 F 1 ; $PCB_PTR = ~30L2_INITI A!_IZF_PCrt ($PART_NODE_PTR ,#$1E1 ) ; #ROW_PARTITION.«VARI A6LF12 ) = 3 ; #ROW_PARTI IinN.rtSIZF = 2; CALL 30L2_SCRT_PARTITI0N_VARIABLFS ( $PCB_PTR , 1 ); IF $PART_NODE_PTR -> *TYPE -= THEN CALL 30L 2_N0NR FCT_P ART I T I 0\J_8Y_R0W S ( SPCB PFR ) : /* SET F TO E<1,1> */ S1F1 = 3OL2_L0CATE_SUBARRAY (S1E1,1,1); $1F1 -> #NAME = 'F' ; /* END EXAMPLES */ DECLARE #$1A1 FIXED BIN ( 1 S , ) INITIAL(9) DECLARE #S1 El FIXED BIN (15,0) INITIALS) END EXAMPLES ; /* 0L/2 BLOCK */ 97 /* */ /* EXAMPLE 5 - SIMPLE ONE VARIABLE PARTITION STATEMENT FROM */ /* SECTION 4.2 J*/ /* */ /********«**#*#********#***#****#***#**#*********#*******##****#**#**/ /* */ /* OL/2 SOURCE STATEMENTS */ /* */ EXAMPLES: LET A RE AN < N BY N ) ARRAY ; PARTITION A AFTER ROWS I , J ANO AFTER COLUMNS K t L END EXAMPLES; /* */ /* OL/2 OBJECT STATEMENTS */ /* */ /* LET A BE AN ( N BY N ) ARRAY */ EXAMPLE5 : BEGIN /* OL/2_BLOCK */ ; DECLARE ( A ) ( ({ N -1+1)*(N -1+1) ) ) BINARY FLOAT ( 53 ) CALL aOL2_IMITI ALIZF_ACB ( $ 1 Al , ADDR ( A ) , ( (< N -1+1)*(N -1 + 1) ,«A« ,2,0,8,0,0,0,1,1, N ,1,N ,1,1,1,1,1,1,1,1,1,1,1,1 ) : ) ) ,0 /* PARTITION A AFTER ROWS I , J AND AFTER COLUMNS K , L */ $PART_MODE_PTR = $1A1; $PCB_PTR = aOL2_lNITIALIZE_PCB( *PART_NODE_PTR, #$1 A 1 ) ; #ROW_PARTITION.*VAR IARLE (2 ) = I ; *R0W_PARTITI0N. *VARI ABLE( 3) = J; «ROW~PARTITI0N.*SIZE = 3; IF $PART_MODE_PTR -> #TYPE -» = THEN CALL 30L 2_DI AGNOST I C S (1) «COL_PARTI TIOf.'.*VAR I ABLE (2 ) = K ; #COL_PARTI TION.rfVARI ABLF( 3 ) = L ; «COL_PARTITIUN.«SIZE = 3; CALL aOL2_SORT_PARTITION_VARIABLFS ( $PCB_PTR , 3 )1 /* END EXAMPLES : */ DECLARE (KtlAl FIXED BIN (15,0) INITIALI9) ; END EXAMPLE5 ; /* OL/2 BLOCK */ 98 /* */ /* EXAMPLE 6 - ONE VARIABLE PARTITION STATEMENT WITH AN */ /* INDIRECT REFERENCE TO A SUBARRAY, FROM SECTION 4.2 */ /* */ /***^**#**************#$«**##****** «**##*********** *********#**#*****/ /* */ /* OL/2 SOURCE STATEMENTS */ /* */ EXAMPLE6: LET B BE AN ( N BY N ) ARRAY ; PARTITION! B AFTER ROWS I , J AND AFTER COLUMNS K » L ; PARTITION B<3,1> AFTER ROWS II, JJ AND AFTER COLUMNS KK,LL ; PARTITION B<3,1><2,2> AFTER ROWS I , J AND AFTER COLUMNS K , L END EXAMPLE6; /* */ /* OL/2 OBJECT STATEMENTS */ /* */ /* LET B BE AN ( N BY N ) ARRAY ; */ EXAMPLE6 : BEGIN /* OL/2_BLOCK */ ; DECLARE ( B ) ( (( N -1+1)*(N -1+1) ) ) BINARY FLOAT < 53 ) ; CALL H)OL2_INITIALIZE_ACB ( $1B 1 , ADDR ( B ) , ( <( N -1+1)*(N -1 + 1) )) ,0 , • B ' ,2,0,8,0,0,0,1,1, N ,1,N ,1,1,1,1,1,1,1,1,1,1,1,1 ) ; /* PARTITION B AFTER ROWS I , J AMD AFTER COLUMNS K , L */ $PART_NODF_PTR = S1B1 ; $PCB_PTR = 30L2_INITI ALIZF_PCB($PART_N0DE_PTR,#$1B1 ) ; #ROW_PARTITI0N.#VARIABLF(2 ) = I ; #R0W_PARTITI0N.*VARIARLE (3) = J; #ROW_PARTITION.#SIZE = 3; IF $PART_NODE_PTR -> #TYPE -•= THEN CALL S)OL 2_DI AGNOSTI C S (1) #C0L_PARTITI0N.*VARIABLF(2) = K ; #C0L_PARTITI0N.S!VARIABLE(3) = L ; #COL_PARTITION.#SIZE = 3; CALL 30L2_SORT_PARTlTlON_VARIABi_ES ( $PCB_PTR , 3 ); 99 /* PARTITION B<3,1> AFTER ROWS II, JJ AND AFTER COLUMNS KK,LL ; */ $PART_NODE_PTR = 30L2_LOCATF_SUBARR AY (S1B1,3,1)J $PCB_PTR = 3ni2_INITIALIZE_PCB( $PART_NODE_PTR , #PARTMAX 1 ) ; *ROW_PARTI TIMN.aVAR I ABLE(2 ) = II; #ROW_PARTITION.*VARI ABLF( 3) = J J ; #ROW_PARTI TION.tfSIZE = 3; IF $PART_NODE_PTR -> *TYPF -»■ THEN CALL 3DL2_D I AGNOSTI C S (1) : *COL_PARTITIOM.#VARIABLE(2 ) = KK ; «CnL.I p ARTITmN.#VARI ABLFI 3) = LL ; #COL_PARTITION.#SIZE = 3; CALL 30L2_SORT_PARTITION_VARIABLES ( $PCB_PTR , 3 ); DECLARE #PARTMAX1 FIXED BIN 115,0) INITIAL ( 4 ); /* PARTITION 8<3,1><2,2> AFTER ROWS I , J AND AFTER COLUMNS K , L ; */ SPART 2,2)', SPCB_P *ROW_P #ROW_P #ROW_P IF SPA #COL_P *COL_P #COL_P CALL 3 _NHDE_PTR = 30L2_L0CATE_SUBARRAY ( S)0L2_L0CATE_SUBARR AY ($181,3,1), TR = S)0L2_INITI ALIZE_PCB($PART_N0DE_PTR,#PARTMAX2) ; ARTITION.«VARI ABLE(2) = I ; ARTI TION.*VARI ABLE( 3) = J; ARTITION.«SIZE = 3: RT_NODE_PTR -> #TYPE -•= THEN CALL 30L 2_DI AGNOST I C S (1) K ; L ; ARTITI0N.«VARIABLF(2) = ARTITI0N.*VARIABLE(3) = ART lTION.rtSIZE = 3; 0L2 SORT PARTITION VARIABLES ( SPCB PTR 3 ) ; DECLARE «PARTMAX2 FIXED BIN (15,0) INITIAL ( 4 ); /* END FXAMPLE6 ; */ DECLARE «$1B1 FIXED BIN (15,0) INITIALS) ? END EXAMPLE6 ; /* OL/2 BLOCK */ 100 /****************************#***************************************/ /* */ /* EXAMPLE 7 - COMBINATION OF EXAMPLES 5 AND fe INTO A */ /* SINGLE PARTITION STATEMENT WITH TWO VARIABLES, FROM 4.2 */ /* */ /******************************** ************************************/ /* */ /* OL/2 SOURCE STATEMENTS */ /* */ / aSc afe it it it sit sit ± ate & & & afc i: afe i!x A it aflt sit it it ak afis afic ate 2: ate A & ate A ate ate ate ± at ate A ate & 3k A & it A ate A: 4c ate A ate A ate ate ate A sic at ate. ate jic ate i: ate at ± A / EXAMPLE7: LET A BF AN ( N BY N ) ARRAY ; LET B BE AN ( M BY N ) ARRAY ; PARTITION B AFTER ROWS I , J AND AFTER COLUMNS K , L ; PARTITION B<3,1> AFTFR ROWS I I ♦ J J ANO AFTER COLUMNS KK,LL ; PARTITION A ANO B<3,1><2,2> AFTER ROWS I, J AND AFTER COLUMNS K,L5 END EXAMPLE7; /********************************************************************/ /* */ /* OL/2 OBJECT STATEMENTS */ /* */ /********************************************************************/ /* LET A BE AN ( N BY N ) ARRAY */ FXAMPLE7 : BEGIN /* 0L/2_BL0CK */ ; DECLARE ( A ) ( (( N -1+1)*(N -1+1) ) ) BINARY FLOAT ( 53 ) /* LET B BE AN ( N BY N ) ARRAY ; */ DECLARE ( B ) ( (( N -1+1)*(N -1+1) ) ) BINARY FLOAT ( 53 ) CALL 30L2_INITIALIZE_ACB ( $ 1 31 , ADDR ( B ) , ( (< N -1 + 1)*(N -1 + 1) )) ,0 ,'B 1 ,2, 0,8,0,0,0, 1 ,1, N ,1,N ,1,1,1,1,1,1,1,1,1,1,1,1 ) ; CALL aOL2_INITIALlZE_ACB ( $ 1 Al , ADDR ( A ) , ( (( N -1+1)*(N -1 + 1) )) ,0 ,'A« ,2,0,8,0,0,0,1,1, N ,1,N ,1,1,1,1,1,1,1,1,1,1,1,1 ) ; /* PARTITION B AFTER ROWS I , J AND AFTER COLUMNS K , L */ $PART_NODE_PTR = $1B1; $PCB_PTR =~30L2_INIT1 ALIZE_PCB( SPART_N0DE_PTR,#$181 ) ; #ROW_PARTITION.#VARI ABLE (2 ) = I ; #ROW_PARTITI0N.*VARI ABLF( 3) = J; #ROW_PARTITION.#SIZE = 3; IF $PART_NODE_PTR -> «TYPE -.= THEN CALL SOL 2_DI AGNOST I CS (1) #C0L_PARTITI0N.#VARIABLE(2 ) = K ; #C0L_PARTITI0N.#VAKI A«LF(3) = L ; *C0L_PARTITION.#SIZE = 3; CALL S0L2 SORT PARTITION VARIABLES ( SPCB PTR , 3 ); 101 /* PARTITION B<3,1> AFTER ROWS II, JJ AND AFTER COLUMNS KK,l_l ; */ SPART_NODE_PTR = 30L 2_10C ATE_SIJBARRA Y ($1B1,3,1): SPCB_PTR = 30L2_INITI ALIZE_PCB( $PART_NODE_PTR ,*PARTMAX1 ) #ROW_PARTITION.*VARI ABLE(2 ) = II; «R0W_PARTITI0N.*VARIABLE(3) = JJ; #ROW_PARTI TION.tfSIZE = 3; IF $PART_NODE_PTR -> KTYPE -= THEN #COL_PARTITION.*VARI ABLE(2 ) = KK; #C0L_PARTITI0N.#VARIABLE(3) = LL *COL_PARTITION.*SIZE = 3; CALL 3OL2_S0RT_PARTITI0N_VARIABLES ( $PCB_PTR CALL aOL2_DIAGNOSTICS (1) 3 ) DECLARE *PARTMAX1 FIXED BIN (15,0) INITIAL ( 4 ) /* PARTITION A AND B<3,1><2,2> AFTER ROWS I, J AND AFTER COLUMNS K,L; */ ALLOCATE $R00T_NODF, #parOize^ allocate #PARTITION_STACK .PTR = $1A1 ; .MAX = #$1A1; ^PARTITION STACK aOLZ_LOCATE_SUBARRAY ( aOL2_LOCATE_SUBARR AY ($1B1,3,1), $ROOT_NODE_PTR 2,2) ; #PART_SI ZE_MAX = #PARTMAX2 ; DO WHILE ( ALLOCATION ( UP ART I T IOM_STACK )) ; $PCB_PTR = aOL2_INITIALIZE_PCB( SROOT_NODE_P TR , #PART_S I Z E_MAX ) #R0W_PART1TI0N.#VARIABLE(2 ) = I; «ROW_PARTITION.*VARI ABLE( 3) = J; #ROW_PARTITION.«SIZE = 3; IF $ROOT_NODE_PTR -> #TYPE --= THEN #C0L_PARTITI0N.#VARIABLE(2 ) = K; #COL_PARTITION.#VARI ABLE( 3) = L; #COL_PARTITION.#SIZE = 3; CALL aOL2_SORT_PART!TION_VARIABLFS ( SPCB_PTR FREE ^PARTITION STACK ; END ; CALL 30L2_DIAGN0STICS (1) 3 ) DECLARE #PARTMAX2 FIXED BIN (15,0) INITIAL ( 9 ); /* END EXAMPLE? */ DECLARE DECLARE #$1A1 *sibi FIXED BIN FIXED BIN (15,0) ( 15,0) INITIAK9) INITIAL(9) END EXAMPLE7 /* OL/2 BLOCK */ 102 /* */ /* EXAMPLE 8 - REFLECTIVE PARTITIONING OF A NONRECTANGUL AR */ /* ARRAY AND ONE-OI MENS I ON AL PARTITIONING OF A RECTANGULAR */ /* ARRAYt FROM SECTION 4.2. */ /* »/ /*«****************************************#******#*************#****/ /* */ /* OL/2 SOURCE STATEMENTS */ /* */ EXAMPLE8: LET A BE A LOWER TRIANGULAR ARRAY OF ORDER ( N ) ; LET B BE AN ( N BY N ) ARRAY ; PARTITION B AFTER ROWS I , J AND AFTER COLUMNS K , L ; PARTITION B<3,1> AFTER ROWS II, JJ AMD AFTER COLUMNS KK»LL ; PARTITION A AND B<3,1><2,2> AFTER ROWS ItJ ; END EXAMPLES; /* */ /* OL/2 OBJECT STATEMENTS */ /* */ /******************#**#***********************#*#********************/ /* LET A BE A LOWER TRIANGULAR ARRAY OF ORDER ( N ) { */ EXAMPLES : BEGIN /* 0L/2_BL0CK */ ; DECLARE ( A ) ( (( N -1+1)*( N -l+2)/2) ) BINARY FLOAT ( 53 ) ; /* LET B BE AN ( N BY N ) ARRAY : */ DECLARE ( B ) ( (( N -1+1)*(N -1+1) ) ) BINARY FLOAT ( 53 ) ; CALL S)OL?_INITIALIZE_ACB ( *1B 1 , ADDR ( B ) , ( (( N -1+1)*(N -1 + 1) )) ,0 , 'B' ,2,0,8,0,0,0,1 , I, N tl»N , 1 1 I ♦ 1 ♦ 1 » 1 ♦ 1 * 1 ♦ 1 1 1 1 1 » 1 » 1 ) ; CALL 30L2_INITIALIZE_ACB ( $1 A 1 , ADDR ( A ) , ( (( N -1 + 1)*( N -l + 2)/2)) , 0, 'A' ,2, 1,8,0,0,0,1,1, N ,1, N ,1,1,1,1,1,1,1,1,1,1,1,1 ) ; /* PARTITION B AFTER ROWS I , J AND AFTER COLUMNS K , L */ $PART_NODE_PTR = $1B1; $PCB_PTR = aOL2_INITIALIZE_PCB($PART_NODE_PTRt#$lBl ) ; #R0W_PARTITI0M.«VARI ABLE(2) = I ; *R0W_PARTITI0N.#VARIABLE(3) = J; #R0W_PARTITI0N.«SIZE = 3; IF $PART_NODE_PTR -> ttTYPE -= THEN CALL 30L 2_DI AGNOST I C S (1) #COL..PARTITION.«VARI ABLF(2) = K ; #C0L_PARTITI0N.#VARIABLE(3) = L ; #COL_PARTITION.#SIZE = 3; CALL 30L2 SORT PARTITION VARIABLES ( $PCB PTR , 3 ); 103 /* PARTITION B<3tl> AFTER ROWS II, JJ AND AFTER COLUMNS KK,LL */ SPART_NODE_PTR = S0L2_L0CATE_SUBARR AY ($1B1,3,1); $PCB_PTR = aOL2_INITIALIZE_PCB($PART_NODE_PTR,#PARTMAXl ) #ROW_PARTITION.#VAR I ABLE(2 ) = II; #ROW_PARTITI0N.«VARI AHLE( 3) = JJ; *ROW_PARTITION.*SIZE = 3; IF $PART_NOOE_PTR -> ttTYPE -= THEN *COL_PARTITION.#VARI ABLE (2 ) = KK ; XC0L_PARTITI0N.4VARI ABLE( 3) = LL ; *COL_PARTITION.#SIZE = 3; CALL aOL2 SORT PARTITION VARIABLES ( 1PCB_PTR CALL 30L2 DIAGNOSTICS (1) 3 ) DECLARE #PARTMAX1 FIXED BIN (15,0) INITIAL ( 4 ) /* PARTITION A AND B<3,1><2,2> AFTER ROWS I, J ; */ STACK *PARTITION_ .PTR = tlAl; .MAX = tfSlAl ; '#PARTI TION_STACK ; .PTR = S)0L2_L0CATE_SIJBARRAY ( 30L2_L0CATE_ ALLOCATE $ROOT_NODE, *PART_SIZE. ALLOCATE $RnOT_MODE 2*2); #PART._SIZE_MAX = #PARTMAX2 ; DO WHRE ( ALLOCATION ( UP ART I TI ON_STACK )) ; SPCB_PTR = @0L2_INITI AL I Z F_PCB ( $ROOT_NODE_PTR ,«P AR T_S I Z E_ #ROW_PARTITION.#VARI ABLE(2) = I; «ROW_PARTI TION.ttVARIABLE (3) = J ; #ROW_PARTITIOM.#SIZE = 3; CALL S)0L2_S0RT_PARTITI0N_VARIABLES ( $PCB_PTR , 1 ); IF $ROOT_NODE_PTR -> «TYPE ->= THEN CALL SOL 2_N0NRECT_P ART I T I 0N_8Y_R0W S ( SPCB_PTR ) ; FREE ^PARTITION STACK ; END ; SUBARRAY ($1B1,3,1), MAX) DECLARE *PARTMAX2 FIXED BIN (15,0) INITIAL ( 4 ); /* END EXAMPLE8 */ DECLARE *$1A1 FIXED BIN (15,0) INITIAL(9) DECLARE *$1B1 F1XFD BIN (15,0) INITIALI9) END EXAMPLES /* OL/2 BLOCK */ 104 /* */ /* EXAMPLE 9 - OVERLAY SET STATEMENT FROM SECTION 4.3. */ /* */ /is*******************************************************************/ /* */ /* OL/2 SOURCE STATEMENTS */ /* */ EXAMPLE9: LET A BE AN ( N BY N ) ARRAY SET C = A ; END EXAMPLE9; /* */ /* OL/2 OBJECT STATEMENTS */ /* */ /**##*4:***#********#***** ******************** ***********************♦/ /* LET A BE AN ( N BY N ) ARRAY ; */ EXAMPLE9 : BEGIN /* 0L/2_BL0CK */ ; DECLARE ( A ) ( (( N -1+1)*(N -1+1) ) ) BINARY FLOAT ( 53 ) ; CALL 30L2_INITIALIZE_ACB ( $ 1 Al , ADDR < A ) , ( (( N-1+1)*(N -1 + 1) )) »0 ,^•,2,0,8,0,0,0,1,1, N ,1,N ,1,1,1,1,1,1,1,1,1,1,1,1 ) ; /* SET C = A ; */ CALL 30L2_ACB_DUPL1CATE ( tlC 1 , * C ' , $1 Al ) ; /* END EXAMPLE9 ; */ ENO EXAMPLE9 ; /* OL/2 BLOCK */ 105 /* */ /* EXAMPLE 10 - SIMPLE SUBARRAY DEFINING SET STATEMENT */ /* FROM SECTION 4.3 */ /* */ /************«*###****************«:***********************#***«******/ /* */ /* OL/2 SOURCE STATEMENTS */ /* */ EXAMPLE10: LET A BE AN ( N BY N ) ARRAY ; PARTITION A AFTER ROWS I , J AND AFTER COLUMNS K » L ; SFT D = A ; END EXAMPLE10; /* */ /* OL/2 OBJECT STATEMENTS */ /* */ /* LET A BE AN { N BY N ) ARRAY */ EXAMPLE10: BEGIN /* 0L/2_BL0CK */ ; DECLARE < A ) ( (( N -1+1)*(N -1+1) ) ) BINARY FLOAT ( 53 ) ; CALL *0L2_INITIALIZE_ACB ( S1A1 , ADDR ( A ) ♦ { (( N-1+1)*(N -1 + 1) )) ,0 »'A« f 2»0,8,0,0,0,l,l» N tltN ,1,1,1,1,1,1,1,1,1,1,1,1 ) ; /* PARTITION A AFTER ROWS I , J AND AFTER COLUMNS K , L ; */ $PART_MODE_PTR = $1A1; $PCB_PTR = aOL2_INITIALIZE_PCB($PART_NODE_PTR»#$lAl ) ; «ROW_PARTITION.«VARI ABLE (2 ) = I ; #ROW_PARTI TI0N.8VARI A8LE( 3) = J; #ROW_PARTITION.#SIZE = 3; IF $PART_NODE_PTR -> #TYPE -•■ THEN CALL 30L2_DI AGNOSTICS (1) ; *COL_PARTITION.«VARIABLE (2 ) = K ; XC0L_PARTITI0N.«VARIABLE(3) = L : #COL_PARTITI0N.#SIZE = 3; CALL 5)OL2_SORT_PARTITION_VARIABLES ( $PCB_PTR , 3 ); /* SET A ■/ $101 = 30L2_L0CATF_SUBARRAY ($1A1,N,M); S1D1 -> #NAME = 'D» ; /* END EXAMPLE10; */ DECLARE *$1A1 FIXED BIN (15,0) INITIAL(9) ; END EXAMPLE10; /* OL/2 BLOCK */ 106 /********************************************************************/ /* */ /* EXAMPLE 11 - DIAGONAL PARTITIONING DEFINING SET STATEMENT */ /* FROM SECTION 4.3 */ /* */ /**- »u -i- J. .l .i. j. J. ,1, „ j, j. j. * j. ^. * ,y * J, * * .k * j, * * * A * J. .k J, ^, ,>, J. j. X J, a. .t j, ,', -i- J- *»- ^i, Ok. O, .«. ,v J. tb J. J* ^ >^ X ,l< / EXAMPLE11 : LET A BE AN ( N BY N ) ARRAY ; PARTITION A AFTER ROWS I t J AND AFTER COLUMNS K , L ; SET E = A<3 t 4> LOWER TRIANGULAR ; END EXAMPLE11; /***:******:!:**********************************************************/ /* */ /* OL/2 OBJECT STATEMENTS */ /* */ /********************************************************************/ /* LET A BE AN ( N BY N ) ARRAY */ EXAMPLE11 : BEGIN /* OL/2_BLOCK */ ; DECLARE ( A ) ( (( N -1+1)*(N -1+1) ) ) BINARY FLOAT ( 53 ) CALL ?30L2_INITIALIZE_ACB ( $1 A 1 » ADDR ( A ) , ( (( N -1+1)*(N -1 + 1) f'A',2,0,8,OfO,Otl,l, N ,1,N ♦ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ) ; ) ) ,0 /* PARTITION A AFTER ROWS I , J AND AFTER COLUMNS K » L ; */ $PART_NODE_PTR - $1A1; $PCB_PTR = 30L2_INITIALIZE_PCB($PART_M0DE_PTR,#$1A1 ) ; #ROW_PARTITION.#VARI ABLE(2 ) = I ; #ROW_PARTITI0N.#VARI ABLE ( 3) = J; #ROW_PARTITION.«SIZE = 3; IF $PART_MODE_PTR -> #TYPE -= THEM CALL 30L2_DI AGNOSTICS (1) #COL_PARTITION.«VARI ABLE(2 ) = K ; #C0L_PARTITI0N.«VARIABLE(3) = L ; «COL_PARTITION.«SIZE = 3; CALL 30L2„SORT_PARTITION_VAR1ABLES ( $PCB_PTR , 3 ); /* SET E = A<3»4> LOWER TRIANGULAR ; */ S1E1 = 30L2_L0CATE_PART0F ( 30L2_L0CATE_SUBARR AY ( $1 Al , 3 t 4 ) , 1 ) ; SI E 1 -> #NAMF = »E' ; /* END EXAMPLEll; */ DECLARE #$1A1 FIXED BIN (15,0) INITIAU9) END EXAMPLEll; /* OL/2 BLOCK */ 107 /* */ /* EXAMPLE 12 */ /* ALTERNATE FORM OF EXAMPLE lit FROM SECTION 4.3 */ /* */ /*S$Xc:S***S;***^;*:*X:*:*$3* ***********************************************/ /* */ /* OL/2 SOURCE STATEMENTS */ /* */ /si********:**:?*:?*** ******************************* *********#*********/ EXAMPLE12: LET A BE AN ( N BY N ) ARRAY ; PARTITION A AFTER ROWS I , J AND AFTER COLUMNS K t L ; SET E TO THE LOWER TRIANGULAR PART OF A<3,4> ; END EXAMPLF12; /********************************************************************/ /* */ /* OL/2 OBJECT STATFMFNTS */ /* */ /***********:*********************************************************/ /* LET A BE AN ( N BY N ) ARRAY */ EXAMPLE12: BEGIN /* 0L/2_BL0CK */ ; DECLARE ( A ) ( (( N -1+1)*(N -1+1) ) ) BINARY FLOAT ( 53 ) ; CALL aOL2_INI riALlZE_ACB ( $ 1 Al ♦ ADDR ( A ) , ( <( N -1+1)*(N -1 + 1) )) ,0 0,'A' ,2,0,8,0,0,0,1,1 , M ,1,N ,1,1,1,1,1,1,1,1,1,1,1,1 ) ; /* PARTITION A AFTER ROWS I , J AND AFTER COLUMNS K , L */ $PART_MODE_PTR = $1A1; SPCB_PTR = rJ0L2_INITIALIZE_PCB($PART_N0DE_PTR t #$lAl ) ; #ROW_PARTITION.*VARI ABLE (2 ) = I ; »ROW_PARTITIQM.#VARI ABLE! 3) = J; *ROW_PARTITION.*«SIZE = 3: IF $PART_NOOE_PTR -> ttTYPF ^= THEN CALL 30L2_D 1 AGNOST I C S (1) *C0L_PARTITI0N.«M/ARIABLE(2 ) = K ; #COL_PARTITlON.#VARI ABLE(3) = L ; *COL_PARTITION.#SIZE = 3; CALL 20L2_S0RT_PARTITI0N_VARIABLFS ( $PCB_PTR , 3 ): /* SFT E TO THE LOWER TRIANGULAR PART OF A<3,4> */ S1E1 = 5)OL2_LOCATE_PARTOF ( 30L 2_L0C ATE_SUBARR AY ($1A1 ,3,4),1); S1E1 -> #NAMF = «F' ; /* END EXAMPLE12; */ DECLARE #$ifll FIXFD BIN (15,0) INITIAL19) ; END EXAVPLE12; /* OL/2 BLOCK */ NOV Z \ tiff*