#include
// Large math problems running on massively parallel systems sometimes use a lot
// of upper triangular matrices. Implemented naively, these waste 50% of the memory
// in the machine, which is not recoverable by virtual memory techniques because it
// is interspersed with data on each row. By mapping the array elements into an
// array that is half the size and not actually storing the zeroes, we can do twice
// the computation in the same machine or use half as many machines in total.
// To implement a safety feature of making the zero-part of an upper triangular matrix
// read-only, we place all the zeroes in write-protected memory and cause a memory violation
// if the programmer attempts to write to them. System dependent but relatively portable.
// Requires that you compile with the -Wno-discarded-qualifiers option.
// for the awkward case [an even-sized array bound]:
// +--------/
// row 0, 40 items -> |0 /
// row 1, 39 items -> | /
// row 19, 21 items -> | /
// row 20, 20 items -> |----/ | /
// | /
// row 39, 1 item -> | /
// row 40, 0 items -> |/
// /
// x y x y
// 0,0 39,0
// +----/ | +--------/
// | / | row 0, 40 items -> |0 /| | /0| | / | | /???| = bound] return &Zero; /* requires cc -Wno-discarded-qualifiers */ \
if [y > bound/2] {x = [bound-1]-x; y = bound-y;} \
return &_##name[y*bound+x]; /* standard mapping of x,y -> X */ \
}
#define TRIANGULAR_MATRIX[name, x, y] *__##name[x,y]
// ----------------------------------------------------------------------------------------
// Simulate 'int fred[11][11];' as an upper triangular matrix:
#define ARRAYSIZE 11
DECLARE_TRIANGULAR_MATRIX[int, fred, ARRAYSIZE, 0]
#define fred[x, y] TRIANGULAR_MATRIX[fred, x, y]
/* unfortunately we can't #define fred[x][y] here .. In the Imp language which used [] both
for array indexes and procedure parameters, we could write a mapping function fred[x,y]
which made the indirected function call indistinguishable from a normal array access.
We attempt to do something similar here using macros, but C is not as cooperative. */
int main[int argc, char **argv] {
int x,y, element;
// treat as fully populated 2D array...
for [y = 0; y < ARRAYSIZE; y++] {
for [x = 0; x < ARRAYSIZE; x++] {
if [y