Ignore:
Timestamp:
Jun 12, 2024, 6:41:53 PM (3 weeks ago)
Author:
Michael Brooks <mlbrooks@…>
Branches:
master
Children:
1725989
Parents:
b166b1c
Message:

Elaborate the description and context of the md-array subscripting figure.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/mike_brooks_MMath/array.tex

    rb166b1c r77328d0  
    248248\begin{figure}
    249249\includegraphics{measuring-like-layout}
    250 \caption{Visualization of subscripting by value and by \lstinline[language=CFA,basicstyle=\ttfamily]{all}, for \lstinline[language=CFA,basicstyle=\ttfamily]{a} of type \lstinline[language=CFA,basicstyle=\ttfamily]{array( float, 5, 7 )}.
    251 The horizontal dimension represents memory addresses while vertical layout is conceptual.}
     250\caption{Visualization of subscripting, by numeric value, and by \lstinline[language=CFA]{all}.
     251        Here \lstinline[language=CFA]{x} has type \lstinline[language=CFA]{array( float, 5, 7 )}, understood as 5 rows by 7 columns.
     252        The horizontal layout represents contiguous memory addresses while the vertical layout uses artistic license.
     253        The vertical shaded band highlights the location of the targeted element, 2.3.
     254        Any such vertical contains various interpretations of a single address.}
    252255\label{fig:subscr-all}
    253256\end{figure}
    254257
    255 \noindent While the latter description implies overlapping elements, Figure \ref{fig:subscr-all} shows that the overlaps only occur with unused spaces between elements.
    256 Its depictions of @a[all][...]@ show the navigation of a memory layout with nontrivial strides, that is, with ``spaced \_ floats apart'' values that are greater or smaller than the true count of valid indices times the size of a logically indexed element.
    257 Reading from the bottom up, the expression @a[all][3][2]@ shows a float, that is masquerading as a @float[7]@, for the purpose of being arranged among its peers; five such occurrences form @a[all][3]@.
    258 The tail of flatter boxes extending to the right of a proper element represents this stretching.
    259 At the next level of containment, the structure @a[all][3]@ masquerades as a @float[1]@, for the purpose of being arranged among its peers; seven such occurrences form @a[all]@.
    260 The vertical staircase arrangement represents this compression, and resulting overlapping.
     258\noindent BEGIN: Paste looking for a home
     259
     260The world of multidimensional array implementation has, or abuts, four relevant levels of abstraction, highest to lowest:
     261
     2621, purpose:
     263If you are doing linear algebra, you might call its dimensions, "column" and "row."
     264If you are treating an acrostic poem as a grid of characters, you might say,
     265the direction of reading the phrases vs the direction of reading the keyword.
     266
     2672, flexible-stride memory:
     268assuming, from here on, a need to see/use contiguous memory,
     269this model offers the ability to slice by (provide an index for) any dimension
     270
     2713, fixed-stride memory:
     272this model offers the ability to slice by (provide an index for) only the coarsest dimension
     273
     2744, explicit-displacement memory:
     275no awareness of dimensions, so no distinguishing them; just the ability to access memory at a distance from a reference point
     276
     277C offers style-3 arrays.  Fortran, Matlab and APL offer style-2 arrays.
     278Offering style-2 implies offering style-3 as a sub-case.
     279My CFA arrays are style-2.
     280
     281Some debate is reasonable as to whether the abstraction actually goes $ 1 < \{2, 3\} < 4 $,
     282rather than my numerically-ordered chain.
     283According to the diamond view, styles 2 and 3 are at the same abstraction level, just with 3 offering a more limited set of functionality.
     284The chain view reflects the design decision I made in my mission to offer a style-2 abstraction;
     285I chose to build it upon a style-3 abstraction.
     286(Justification of the decision follows, after the description of the design.)
     287
     288The following discussion first dispenses with API styles 1 and 4, then elaborates on my work with styles 2 and 3.
     289
     290Style 1 is not a concern of array implementations.
     291It concerns documentation and identifier choices of the purpose-specific API.
     292If one is offering a matrix-multiply function, one must specify which dimension(s) is/are being summed over
     293(or rely on the familiar convention of these being the first argument's rows and second argument's columns).
     294Some libraries offer a style-1 abstraction that is not directly backed by a single array
     295(e.g. make quadrants contiguous, as may help cache coherence during a parallel matrix multiply),
     296but such designs are out of scope for a discussion on arrays; they are applications of several arrays.
     297I typically include style-1 language with examples to help guide intuition.
     298
     299It is often said that C has row-major arrays while Fortran has column-major arrays.
     300This comparison brings an unhelpful pollution of style-1 thinking into issues of array implementation.
     301Unfortunately, ``-major'' has two senses: the program's order of presenting indices and the array's layout in memory.
     302(The program's order could be either lexical, as in @x[1,2,3]@ subscripting, or runtime, as in the @x[1][2][3]@ version.)
     303Style 2 is concerned with introducing a nontrivial relationship between program order and memory order,
     304while style 3 sees program order identical with memory order.
     305Both C and (the style-3 subset of) Fortran actually use the same relationship here:
     306an earlier subscript in program order controls coarser steps in memory.
     307The job of a layer-2/3 system is to implement program-ordered subscripting according to a defined memory layout.
     308C and Fortran do not use opposite orders in doing this job.
     309Fortran is only ``backward'' in its layer-1 conventions for reading/writing and linear algebra.
     310Fortran subscripts as $m(c,r)$.  When I use style-1 language, I am following the C/mathematical convention of $m(r,c)$.
     311
     312Style 4 is the inevitable target of any array implementation.
     313The hardware offers this model to the C compiler, with bytes as the unit of displacement.
     314C offers this model to its programmer as pointer arithmetic, with arbitrary sizes as the unit.
     315I consider casting a multidimensional array as a single-dimensional array/pointer,
     316then using @x[i]@ syntax to access its elements, to be a form of pointer arithmetic.
     317But style 4 is not offering arrays.
     318
     319Now stepping into the implementation
     320of CFA's new type-3 multidimensional arrays in terms of C's existing type-2 multidimensional arrays,
     321it helps to clarify that even the interface is quite low-level.
     322A C/CFA array interface includes the resulting memory layout.
     323The defining requirement of a type-3 system is the ability to slice a column from a column-finest matrix.
     324The required memory shape of such a slice is set, before any discussion of implementation.
     325The implementation presented here is how the CFA array library wrangles the C type system,
     326to make it do memory steps that are consistent with this layout.
     327TODO: do I have/need a presentation of just this layout, just the semantics of -[all]?
     328
     329Figure~\ref{fig:subscr-all} shows one element (in the shaded band) accessed two different ways: as @x[2][3]@ and as @x[all][3][2]@.
     330In both cases, value 2 selects from the coarser dimension (rows of @x@),
     331while the value 3 selects from the finer dimension (columns of @x@).
     332The figure illustrates the value of each subexpression, comparing how numeric subscripting proceeds from @x@, vs from @x[all]@.
     333Proceeding from @x@ gives the numeric indices as coarse then fine, while proceeding from @x[all]@ gives them fine then coarse.
     334These two starting expressions, which are the example's only multidimensional subexpressions
     335(those that received zero numeric indices so far), are illustrated with vertical steps where a \emph{first} numeric index would select.
     336
     337The figure's presentation offers an intuition answering, What is an atomic element of @x[all]@?
     338From there, @x[all]@ itself is simply a two-dimensional array, in the strict C sense, of these strange building blocks.
     339An atom (like the bottommost value, @x[all][3][2]@), is the contained value (in the square box)
     340and a lie about its size (the wedge above it, growing upward).
     341An array of these atoms (like the intermediate @x[all][3]@) is just a contiguous arrangement of them,
     342done according to their size, as announced.  Call such an array a column.
     343A column is almost ready to be arranged into a matrix; it is the \emph{contained value} of the next-level building block,
     344but another lie about size is required.
     345At first, an atom needed to be arranged as if it were bigger,
     346but now a column needs to be arranged as if it is smaller (the wedge above it, shrinking upward).
     347These lying columns, arranged contiguously according to their size (as announced) form the matrix @x[all]@.
     348Because @x[all]@ takes indices, first for the fine stride, then for the coarse stride,
     349it achieves the requirement of representing the transpose of @x@.
     350Yet every time the programmer presents an index, a mere C-array subscript is achieving the offset calculation.
     351
     352In the @x[all]@ case, after the finely strided subscript is done (column 3 is selected),
     353the locations referenced by the coarse subscript options (rows 0..4) are offset by 3 floats,
     354compared with where analogous rows appear when the row-level option is presented for @x@.
     355
     356These size lies create an appearance of overlap.
     357For example, in @x[all]@, the shaded band touches atoms 2.0, 2.1, 2.2, 2.3, 1.4, 1.5 and 1.6.
     358But only the atom 2.3 is storing its value there.
     359The rest are lying about (conflicting) claims on this location, but never exercising these alleged claims.
     360
     361Lying is implemented as casting.
     362The arrangement just described is implemented in the structure @arpk@.
     363This structure uses one type in its internal field declaration and offers a different type as the return of its subscript operator.
     364The field within is a plain-C array of the fictional type, which is 7 floats long for @x[all][3][2]@ and 1 float long for @x[all][3]@.
     365The subscript operator presents what's really inside, by casting to the type below the wedge of lie.
     366
     367%  Does x[all] have to lie too?  The picture currently glosses over how it it advertizes a size of 7 floats.  I'm leaving that as an edge case benignly misrepresented in the picture.  Edge cases only have to be handled right in the code.
     368
     369Casting, overlapping and lying are unsafe.
     370The mission here is to implement a style-2 feature that the type system helps the programmer use safely.
     371The offered style-2 system is allowed to be internally unsafe,
     372just as C's implementation of a style-3 system (upon a style-4 system) is unsafe within,
     373even when the programmer is using it without casts or pointer arithmetic.
     374Having a style-2 system relieves the programmer from resorting to unsafe pointer arithmetic when working with noncontiguous slices.
     375
     376The choice to implement this style-2 system upon C's style-3 arrays, rather than its style-4 pointer arithmetic,
     377reduces the attack surface of unsafe code.
     378My casting is unsafe, but I do not do any pointer arithmetic.
     379When a programmer works in the common-case style-3 subset (in the no-@[all]@ top of Figure~\ref{fig:subscr-all}),
     380my casts are identities, and the C compiler is doing its usual displacement calculations.
     381If I had implemented my system upon style-4 pointer arithmetic,
     382then this common case would be circumventing C's battle-hardened displacement calculations in favour of my own.
     383
     384\noindent END: Paste looking for a home
    261385
    262386The new-array library defines types and operations that ensure proper elements are accessed soundly in spite of the overlapping.
Note: See TracChangeset for help on using the changeset viewer.