The polyhedral model (also called the polytope method) is a mathematical framework for programs that perform large numbers of operations -- too large to be explicitly enumerated -- thereby requiring a compact representation. Nested loop programs are the typical, but not the only example, and the most common use of the model is for loop nest optimization in program optimization. The polyhedral method treats each loop iteration within nested loops as lattice points inside mathematical objects called polyhedra, performs affine transformations or more general non-affine transformations such as tiling on the polytopes, and then converts the transformed polytopes into equivalent, but optimized (depending on targeted optimization goal), loop nests through polyhedra scanning.
Consider the following example written in C:
constintn=100;inti,j,a[n][n];for(i=1;i<n;i++){for(j=1;j<(i+2)&&j<n;j++){a[i][j]=a[i-1][j]+a[i][j-1];}}
The essential problem with this code is that each iteration of the inner loop on a[i][j]
requires that the previous iteration's result, a[i][j - 1]
, be available already. Therefore, this code cannot be parallelized or pipelined as it is currently written.
An application of the polytope model, with the affine transformation and the appropriate change in the boundaries, will transform the nested loops above into:
a[i-j][j]=a[i-j-1][j]+a[i-j][j-1];
In this case, no iteration of the inner loop depends on the previous iteration's results; the entire inner loop can be executed in parallel. Indeed, given a(i, j) = a[i-j][j]
then a(i, j)
only depends on a(i - 1, x)
, with . (However, each iteration of the outer loop does depend on previous iterations.)
The following C code implements a form of error-distribution dithering similar to Floyd–Steinberg dithering, but modified for pedagogical reasons. The two-dimensional array src
contains h
rows of w
pixels, each pixel having a grayscale value between 0 and 255 inclusive. After the routine has finished, the output array dst
will contain only pixels with value 0 or value 255. During the computation, each pixel's dithering error is collected by adding it back into the src
array. (Notice that src
and dst
are both read and written during the computation; src
is not read-only, and dst
is not write-only.)
Each iteration of the inner loop modifies the values in src[i][j]
based on the values of src[i-1][j]
, src[i][j-1]
, and src[i+1][j-1]
. (The same dependencies apply to dst[i][j]
. For the purposes of loop skewing, we can think of src[i][j]
and dst[i][j]
as the same element.) We can illustrate the dependencies of src[i][j]
graphically, as in the diagram on the right.
#define ERR(x, y) (dst[x][y] - src[x][y])voiddither(unsignedchar**src,unsignedchar**dst,intw,inth){inti,j;for(j=0;j<h;++j){for(i=0;i<w;++i){intv=src[i][j];if(i>0)v-=ERR(i-1,j)/2;if(j>0){v-=ERR(i,j-1)/4;if(i<w-1)v-=ERR(i+1,j-1)/4;}dst[i][j]=(v<128)?0:255;src[i][j]=(v<0)?0:(v<255)?v:255;}}} |
Performing the affine transformation on the original dependency diagram gives us a new diagram, which is shown in the next image. We can then rewrite the code to loop on p
and t
instead of i
and j
, obtaining the following "skewed" routine.
voiddither_skewed(unsignedchar**src,unsignedchar**dst,intw,inth){intt,p;for(t=0;t<(w+(2*h));++t){intpmin=max(t%2,t-(2*h)+2);intpmax=min(t,w-1);for(p=pmin;p<=pmax;p+=2){inti=p;intj=(t-p)/2;intv=src[i][j];if(i>0)v-=ERR(i-1,j)/2;if(j>0)v-=ERR(i,j-1)/4;if(j>0&&i<w-1)v-=ERR(i+1,j-1)/4;dst[i][j]=(v<128)?0:255;src[i][j]=(v<0)?0:(v<255)?v:255;}}} |
In geometry, a polyhedron is a three-dimensional shape with flat polygonal faces, straight edges and sharp corners or vertices.
In geometry, a 4-polytope is a four-dimensional polytope. It is a connected and closed figure, composed of lower-dimensional polytopal elements: vertices, edges, faces (polygons), and cells (polyhedra). Each face is shared by exactly two cells. The 4-polytopes were discovered by the Swiss mathematician Ludwig Schläfli before 1853.
In geometry, the Schläfli symbol is a notation of the form that defines regular polytopes and tessellations.
In computer science and particularly in compiler design, loop nest optimization (LNO) is an optimization technique that applies a set of loop transformations for the purpose of locality optimization or parallelization or another loop overhead reduction of the loop nests. One classical usage is to reduce memory access latency or the cache bandwidth necessary due to cache reuse for some common linear algebra algorithms.
In geometry, a net of a polyhedron is an arrangement of non-overlapping edge-joined polygons in the plane which can be folded to become the faces of the polyhedron. Polyhedral nets are a useful aid to the study of polyhedra and solid geometry in general, as they allow for physical models of polyhedra to be constructed from material such as thin cardboard.
In compiler theory, loop optimization is the process of increasing execution speed and reducing the overheads associated with loops. It plays an important role in improving cache performance and making effective use of parallel processing capabilities. Most execution time of a scientific program is spent on loops; as such, many compiler optimization techniques have been developed to make them faster.
In compiler theory, loop interchange is the process of exchanging the order of two iteration variables used by a nested loop. The variable used in the inner loop switches to the outer loop, and vice versa. It is often done to ensure that the elements of a multi-dimensional array are accessed in the order in which they are present in memory, improving locality of reference.
In computer science, loop dependence analysis is a process which can be used to find dependencies within iterations of a loop with the goal of determining different relationships between statements. These dependent relationships are tied to the order in which different statements access memory locations. Using the analysis of these relationships, execution of the loop can be organized to allow multiple processors to work on different portions of the loop in parallel. This is known as parallel processing. In general, loops can consume a lot of processing time when executed as serial code. Through parallel processing, it is possible to reduce the total execution time of a program through sharing the processing load among multiple processors.
Automatic parallelization, also auto parallelization, or autoparallelization refers to converting sequential code into multi-threaded and/or vectorized code in order to use multiple processors simultaneously in a shared-memory multiprocessor (SMP) machine. Fully automatic parallelization of sequential programs is a challenge because it requires complex program analysis and the best approach may depend upon parameter values that are not known at compilation time.
Automatic vectorization, in parallel computing, is a special case of automatic parallelization, where a computer program is converted from a scalar implementation, which processes a single pair of operands at a time, to a vector implementation, which processes one operation on multiple pairs of operands at once. For example, modern conventional computers, including specialized supercomputers, typically have vector operations that simultaneously perform operations such as the following four additions :
A manifest expression is a programming language construct that a compiler can analyse to deduce which values it can take without having to execute the program. This information can enable compiler optimizations, in particular loop nest optimization, and parallelization through data dependency analysis. An expression is called manifest if it is computed only from outer loop counters and constants.
Use of the polyhedral model within a compiler requires software to represent the objects of this framework and perform operations upon them.
In polyhedral combinatorics, a branch of mathematics, Steinitz's theorem is a characterization of the undirected graphs formed by the edges and vertices of three-dimensional convex polyhedra: they are exactly the 3-vertex-connected planar graphs. That is, every convex polyhedron forms a 3-connected planar graph, and every 3-connected planar graph can be represented as the graph of a convex polyhedron. For this reason, the 3-connected planar graphs are also known as polyhedral graphs.
Polymake is software for the algorithmic treatment of convex polyhedra.
The study of integer points in convex polyhedra is motivated by questions such as "how many nonnegative integer-valued solutions does a system of linear equations with nonnegative coefficients have" or "how many solutions does an integer linear program have". Counting integer points in polyhedra or other questions about them arise in representation theory, commutative algebra, algebraic geometry, statistics, and computer science.
For several years parallel hardware was only available for distributed computing but recently it is becoming available for the low end computers as well. Hence it has become inevitable for software programmers to start writing parallel applications. It is quite natural for programmers to think sequentially and hence they are less acquainted with writing multi-threaded or parallel processing applications. Parallel programming requires handling various issues such as synchronization and deadlock avoidance. Programmers require added expertise for writing such applications apart from their expertise in the application domain. Hence programmers prefer to write sequential code and most of the popular programming languages support it. This allows them to concentrate more on the application. Therefore, there is a need to convert such sequential applications to parallel applications with the help of automated tools. The need is also non-trivial because large amount of legacy code written over the past few decades needs to be reused and parallelized.
isl is a portable C library for manipulating sets and relations of integer points bounded by linear constraints.
The binding properties pattern is combining multiple observers to force properties in different objects to be synchronized or coordinated in some way. This pattern was first described as a technique by Victor Porton. This pattern comes under concurrency patterns.
In mathematics, a polyhedral complex is a set of polyhedra in a real vector space that fit together in a specific way. Polyhedral complexes generalize simplicial complexes and arise in various areas of polyhedral geometry, such as tropical geometry, splines and hyperplane arrangements.
In the mathematical discipline of polyhedral combinatorics, the Gale transform turns the vertices of any convex polytope into a set of vectors or points in a space of a different dimension, the Gale diagram of the polytope. It can be used to describe high-dimensional polytopes with few vertices, by transforming them into sets with the same number of points, but in a space of a much lower dimension. The process can also be reversed, to construct polytopes with desired properties from their Gale diagrams. The Gale transform and Gale diagram are named after David Gale, who introduced these methods in a 1956 paper on neighborly polytopes.