WarpEngine Test Programs

The following is a listing of the programs the Richard Littin wrote for the WarpEngine, version 2 of the instruction set.
Matrix multiplication asm C
Transitive closure asm C
Gauss-Jordan elimination asm C
Heapsort asm C
Quicksort (version 1) asm C
Quicksort (version 2) asm C
Naive binary tree insertion asm C
AVL binary tree insertion asm C
Recursive Fibonacci number generation asm C
Recursive Fibonacci number generation (data flow) asm C

C Code

Matrix multiplication

float A[N][N], B[N][N], C[N][N];

void Mult(void) {
    int i,j,k;
    float t;

    for (i=0;i<N;i++)
        for (j=0;j<N;j++) {
            t = 0;
            for (k=0;k<N;k++)
                t += A[i][k] * B[k][j];
            C[i][j] = t;
        }
}

Transitive closure

int a[NUM_VERT+1][NUM_VERT][NUM_VERT];

void Trans() {
    int i,j,k;
    for (k=0;k<NUM_VERT;k++)
        for (i=0;i<NUM_VERT;i++)
            for (j=0;j<NUM_VERT;j++)
                a[k+1][i][j] = (a[k][i][j] || (a[k][i][k] && a[k][k][j]));
}

Gauss-Jordan elimination

float A[N*N];

float ABS(i) {
  if (i > 0)
    return i;
  return -i;
}

void gaussj(float *a, int n) {
  float big, dum, pivinv;
  long int i, icol, irow, j, k, l, ll;
  long int indxc[N], indxr[N], ipiv[N];

  for (j=0;j<n;j++) {
    indxc[j] = 0;
    indxr[j] = 0;
    ipiv[j] = 0;
  }
  for (i=0;i<n;i++) {
    big = 0.0;
    for (j=0;j<n;j++)
      if (ipiv[j] != 1)
	for (k=0;k<n;k++)
	  if (ipiv[k] == 0) {
	    if (ABS(a[j*N+k]) >= big) {
	      big = ABS(a[j*N+k]);
	      irow = j;
	      icol = k;
	    }
	  }
	  else if (ipiv[k] > 1) {
	    printf("pause 1 in GAUSSJ - singular matrix\n");
	    getc(stdin);
	  }
    ipiv[icol] = ipiv[icol] + 1;
    if (irow != icol) {
      for (l=0;l<n;l++) {
	dum = a[irow*N+l];
	a[irow*N+l] = a[icol*N+l];
	a[icol*N+l] = dum;
      }
    }
    indxr[i] = irow;
    indxc[i] = icol;
    if (a[icol*N+icol] == 0.0) {
      printf("pause 2 in GAUSSJ - singular matrix\n");
      getc(stdin);
    }
    pivinv = 1.0 / a[icol*N+icol];
    a[icol*N+icol] = 1.0;
    for (l=0;l<n;l++) {
      a[icol*N+l] = a[icol*N+l]*pivinv;
    }
    for (ll=0;ll<n;ll++)
      if (ll != icol) {
	dum = a[ll*N+icol];
	a[ll*N+icol] = 0.0;
	for (l=0;l<n;l++) {
	  a[ll*N+l] = a[ll*N+l] - a[icol*N+l] * dum;
	}
      }
  }
  for (l=n-1;l>=0;l--)
    if (indxr[l] != indxc[l])
      for (k=0;k<n;k++) {
	dum = a[k*N+indxr[l]];
	a[k*N+indxr[l]] = a[k*N+indxc[l]];
	a[k*N+indxc[l]] = dum;
      }
}

Heapsort

int table[TABLE_SIZE];

void Swap(int *a, int *b) {
    int temp;
    temp = *a; *a = *b; *b = temp;
}

void Heapify(int i, int j) {
    if ((RC(j) >= i) && (table[RC(j)] <= table[LC(j)]) && (table[RC(j)] < table[j])) {
        Swap(&(table[j]),&(table[RC(j)]));
        Heapify(i, RC(j));
    }
    else if ((LC(j) >= i) && (table[LC(j)] < table[j])) {
        Swap(&(table[j]),&(table[LC(j)]));
        Heapify(i, LC(j));	
    }
}

void InitialiseHeap() {
    int i;
    for (i=0;i<TABLE_SIZE;i++) {
        Heapify(0,i);
    }
}

void HeapSort() {
    int i;
    InitialiseHeap();
    for (i=0;i<TABLE_SIZE-1;i++) {
        Swap(&(table[i]),&(table[TABLE_SIZE-1]));
        Heapify(i+1,TABLE_SIZE-1);
    }
}

Quicksort (version 1)

int v[ARRAY_SIZE];

void QSort(int left,int right) {
    int i,piv,temp,cmp;
    
    if (left >= right)
        return;
    cmp = v[left];
    piv = left;
    for (i=left+1;i<=right;i++)
        if (v[i] < cmp) {
            piv++;
            temp = v[piv]; v[piv] = v[i]; v[i] = temp;      
        }
    temp = v[piv]; v[piv] = v[left]; v[left] = temp;
    QSort(left,piv-1);
    QSort(piv+1,right);
}

Quicksort (version 2)

int v[ARRAY_SIZE];

void QSort(int left,int right)
{
    int temp = v[left];
    int i = left, j = right;

    if (j > i) {
        while (j>i) {
            while ((j >= i) && (temp < v[j]))
                j--;
            if (j<=i)
                v[i] = temp;
            else {
                v[i] = v[j];
                i++;
                while ((i <= j) && (v[i] < temp))
                    i++;
                if (j>i) {
                    v[j] = v[i];
                    j--;
                }
                if (j<=i)
                    v[j] = temp;
            }
        }
        QSort(left,j-1);
        QSort(j+1,right);
    }
}

Naive binary tree insertion

typedef struct node node;

struct node {
    int key;
    node *left, *right;
};

node *New(int key) {
    node *new_node = (node *)malloc(sizeof(node));

    new_node->key = key;
    new_node->left = NULL;
    new_node->right = NULL;
    return new_node;
}

void Insert(node **root, int key) {
    if ((*root) == NULL)
        *root = New(key);
    else if (key < (*root)->key)
        Insert(&((*root)->left),key);
    else if (key > (*root)->key)
        Insert(&((*root)->right),key);
}

AVL binary tree insertion

struct node {
    int key;
    int bal;
    node *left, *right;
};

node *New(int key) {
  node *n = (node *)malloc(sizeof(node));

  n->key = key;
  n->bal = 0;
  n->left = NULL;
  n->right = NULL;
  return n;
}

void ShiftNode(int *d,node **c,int key,node **p) {
  if (key == (*p)->key) {
    *d = 0;
    *c = *p;
  }
  else if (key < (*p)->key) {
    *d = -1;
    *c = (*p)->left;
  }
  else {
    *d = 1;
    *c = (*p)->right;
  }
}

void Rotate(node **p, int d,node **par, int cd,node **root) {
  node *P = *p;

  if (d == -1) {
    *p = (*p)->right;
    P->right = (*p)->left;
    (*p)->left = P;
  }
  else {
    *p = (*p)->left;
    P->left = (*p)->right;
    (*p)->right = P;
  }

  if (cd == -1)
    (*par)->left = *p;
  else if (cd == 1)
    (*par)->right = *p;
  else 
    *root = *p;
}

void AVLInsert(node **root,int key) {
  int d1, d2, d3, critnodefound = 0, critdir, dir = 0;
  node *n, *a, *b, *c, *cp, *p, *r;

  p = n = *root;

  while ((n != NULL) && (n->key != key)) {
    if (n->bal != 0) {
      c = n;
      cp = p;
      critnodefound = 1;
      critdir = dir;
    }
    if (key < n->key) {
      p = n;
      n = n->left;
      dir = -1;
    }
    else {
      p = n;
      n = n->right;
      dir = 1;
    }
  }

  if (n == NULL) {
    if (p == NULL)
      *root = New(key);
    else if (dir == -1)
      p->left = New(key);
    else
      p->right = New(key);

    if (!critnodefound)
      r = *root;
    else {
      ShiftNode(&d1,&a,key,&c);
      if (c->bal != d1) {
	c->bal = 0;
	r = a;
      }
      else {
	ShiftNode(&d2,&b,key,&a);
	if (d2 == d1) {
	  c->bal = 0;
	  r = b;
	  Rotate(&c,-d1,&cp,critdir,root);
	}
	else {
	  ShiftNode(&d3,&r,key,&b);
	  if (d3 == d2) {
	    c->bal = 0;
	    a->bal = d1;
	  }
	  else if (d3 == -d2)
	    c->bal = d2;
	  else
	    c->bal = 0;
	  Rotate(&a,-d2,&c,d1,root);
	  Rotate(&c,-d1,&cp,critdir,root);
	}
      }
    }
    while (r->key != key) {
      ShiftNode(&(r->bal),&r,key,&r);
    }
  }
}

Recursive Fibonacci number generation

int Fib(int n) {
    if (n == 0)
        return 0;
    else if (n == 1)
        return 1;
    else
        return Fib(n-1) + Fib(n-2);
}