/*
 * Copyright (c) 2005, University of Massachusetts
 * All Rights Reserved.
 * 
 * Name:           matmat_support.c 
 * Last modified:  30 Mar 2005
 * Author:         Stephen Siegel <siegel@cs.umass.edu>
 *
 * Support C code for matrix-matrix multiplication model.
 */

#include "seqpar.c"

struct A_matrix A_global;
struct B_matrix B_global;
int widths_A[A_ROWS][A_COLS];
int column_widths_A[A_COLS];
int widths_B[B_ROWS][B_COLS];
int column_widths_B[B_COLS];
int widths_C[C_ROWS][C_COLS];
int column_widths_C[C_COLS];


extern void prettyprintMatrix_A();
extern void prettyprintMatrix_B();
extern void prettyprintMatrix_C();

void initializeSystem() {
  int i,j,count;

  init_seqpar();
  count = 0;
  for (i=0; i<A_ROWS; i++) {
    for (j=0; j<A_COLS; j++) {
      A_global.entryAt[i].entryAt[j] = SYM_symbolicConstant_0(count);
      count++;
    }
  }
  for (i=0; i<B_ROWS; i++) {
    for (j=0; j<B_COLS; j++) {
      B_global.entryAt[i].entryAt[j] = SYM_symbolicConstant_0(count);
      count++;
    }
  }
  for (i=0; i<C_ROWS; i++) {
    for (j=0; j<C_COLS; j++) {
      now.C_global.entryAt[i].entryAt[j] = SYM_ZERO;
    }
  }
  printf("Matrix A: \n");
  prettyprintMatrix_A();
  printf("Matrix B: \n");
  prettyprintMatrix_B();
  printf("-------------------------------");
  printf("--------------------------------------\n\n");
}


void printSolution() {
  update_seqpar();
#if VERBOSE>0
  printf("Matrix C: \n\n");
  prettyprintMatrix_C();
#endif
}



void report_par_error(int row, int col, int seqExpr, int parExpr) {
  incr_error();
  printf("\nParralel solution matrix differs in row %d column %d:\n\n",
         row, col);
  SYM_printExpr(seqExpr);
  printf("\n\n");
  SYM_printExpr(parExpr);
  printf("\n");
}


void calculateWidths_A() {
  int col, row, expr, width;
  
  for (col = 0; col < A_COLS; col++) {
    column_widths_A[col] = 0;
    for (row = 0; row < A_ROWS; row++) {
      expr = A_global.entryAt[row].entryAt[col];
      width = SYM_exprLength(expr);
      widths_A[row][col] = width;
      if (width>column_widths_A[col]) {
	column_widths_A[col] = width;
      }
    }
    column_widths_A[col]++;
  }
}

void calculateWidths_B() {
  int col, row, expr, width;
  
  for (col = 0; col < B_COLS; col++) {
    column_widths_B[col] = 0;
    for (row = 0; row < B_ROWS; row++) {
      expr = B_global.entryAt[row].entryAt[col];
      width = SYM_exprLength(expr);
      widths_B[row][col] = width;
      if (width>column_widths_B[col]) {
	column_widths_B[col] = width;
      }
    }
    column_widths_B[col]++;
  }
}

void calculateWidths_C() {
  int col, row, expr, width;
  
  for (col = 0; col < C_COLS; col++) {
    column_widths_C[col] = 0;
    for (row = 0; row < C_ROWS; row++) {
      expr = now.C_global.entryAt[row].entryAt[col];
      width = SYM_exprLength(expr);
      widths_C[row][col] = width;
      if (width>column_widths_C[col]) {
	column_widths_C[col] = width;
      }
    }
    column_widths_C[col]++;
  }
}


void prettyprintMatrix_A() {
  int row, col, spaces, i;
  
  calculateWidths_A();
  for (row = 0; row < A_ROWS; row++) {
    for (col = 0; col < A_COLS; col++) {
      SYM_printExpr(A_global.entryAt[row].entryAt[col]);
      if (col < A_COLS-1) {
	spaces = column_widths_A[col]-widths_A[row][col];
	for (i = 0; i < spaces; i++) printf(" ");
      }
    }
    printf("\n");
  }
  printf("\n");
}

void prettyprintMatrix_B() {
  int row, col, spaces, i;
  
  calculateWidths_B();
  for (row = 0; row < B_ROWS; row++) {
    for (col = 0; col < B_COLS; col++) {
      SYM_printExpr(B_global.entryAt[row].entryAt[col]);
      if (col < B_COLS-1) {
	spaces = column_widths_B[col]-widths_B[row][col];
	for (i = 0; i < spaces; i++) printf(" ");
      }
    }
    printf("\n");
  }
  printf("\n");
}

void prettyprintMatrix_C() {
  int row, col, spaces, i;
  
  calculateWidths_C();
  for (row = 0; row < C_ROWS; row++) {
    for (col = 0; col < C_COLS; col++) {
      SYM_printExpr(now.C_global.entryAt[row].entryAt[col]);
      if (col < C_COLS-1) {
	spaces = column_widths_C[col]-widths_C[row][col];
	for (i = 0; i < spaces; i++) printf(" ");
      }
    }
    printf("\n");
  }
  printf("\n");
}

