[I2 logo] [RWTH logo] MOVES: Software Modeling and Verification
(Informatik 2)
Computer Science / RWTH / I2 / Research / Skil / Examples / Matmult
Printer-friendly
Skil Sample Applications

Matrix Multiplication



#include "Par/par.c"
#include "Array/array.h"
#include "Include/math.h"
#include "Include/stdio.h"


static void pck_f ($t v, Buff buff)
{
   return ;
}


static void upck_f (Buff buff, $t *vptr)
{
   return ;
}


static int *def_lowerbd (Index totalsize, int procNr)
{
   int *res, hSize, vSize, hBlockSize, vBlockSize ;

   vSize = totalsize[0] ;
   hSize = totalsize[1] ;

   vBlockSize = vSize / yNetDim ;
   if (vBlockSize * yNetDim < vSize)
      vBlockSize++ ;
   
   hBlockSize = hSize / xNetDim ;
   if (hBlockSize * xNetDim < hSize)
      hBlockSize++ ;

   res = (int *) VMalloc (2 * sizeof (int), "def_lowerbd") ;

   res[0] = (procNr / xNetDim) * vBlockSize ;
   res[1] = (procNr % xNetDim) * hBlockSize ;

   return (res) ;
}


static $t zero (Index ix)
{
   return (0) ;
}


static $t rand1 (Index ix)
{
   return (ix[0] + ix[1]) ;
}


static $t rand2 (Index ix)
{
   return (ix[0] + 2 * ix[1]) ;
}


static int left_1 (int procNr)
{
   int ret, xnetsize = (int) sqrt ((double) netSize) ;

   ret = procNr - 1 ;

   if (ret < 0 || ret/xnetsize != procNr/xnetsize)
      ret += xnetsize ;

   return (ret) ;
}


static int upper_1 (int procNr)
{
   int ret, ynetsize = (int) sqrt ((double) netSize) ;

   ret = procNr - ynetsize ;

   if (ret < 0)
      ret += netSize ;

   return (ret) ;
}


static int left_i (int procNr)
{
   int ret, xnetsize = (int) sqrt ((double) netSize) ;

   ret = procNr - procNr/xnetsize ;

   if (ret < 0 || ret/xnetsize != procNr/xnetsize)
      ret += xnetsize ;

   return (ret) ;
}


static int upper_i (int procNr)
{
   int ret, ynetsize = (int) sqrt ((double) netSize) ;

   ret = procNr - (procNr%ynetsize) * ynetsize ;

   if (ret < 0)
      ret += netSize ;

   return (ret) ;
}


static void destroy_f ($t v)
{
   return ;
}


static $t local_sprod (array <$t> a, array <$t> b, $t v, Index ix)
{
#if 1
/* empolying a transformation to local coordinates done by the user */
   int    k, a_hSize               ;
   Bounds a_bds, b_bds             ;
   Index  elem_index1, elem_index2 ;

   a_bds = array_block_bounds (a) ;
   b_bds = array_block_bounds (b) ;

   elem_index1[0] = ix[0] - a_bds->lowerBd[0] ;
   elem_index2[1] = ix[1] - b_bds->lowerBd[1] ;

   a_hSize = a_bds->upperBd[1] - a_bds->lowerBd[1] ;

   for (k = 0 ; k < a_hSize ; k++)
   {
      elem_index1[1] = k ;
      elem_index2[0] = k ;

      v += array_get_local_elem (a, elem_index1) *
	   array_get_local_elem (b, elem_index2)   ;
   }

#else
/* employing a transformation to local coordinates transparent to the user */
   int    k, a_hLowerBd, a_hUpperBd ;
   Bounds a_bds                     ;
   Index  elem_index1, elem_index2  ;

   a_bds = array_block_bounds (a) ;

   a_hLowerBd = a_bds->lowerBd[1] ;
   a_hUpperBd = a_bds->upperBd[1] ;

   for (k = a_hLowerBd ; k < a_hUpperBd ; k++)
   {
      elem_index1[0] = ix[0] ;
      elem_index1[1] = k     ;
      elem_index2[0] = k     ;
      elem_index2[1] = ix[1] ;

      v += array_get_elem (a, elem_index1) * array_get_elem (b, elem_index2) ;
   }

#endif

   return (v) ;
}


static void matmult (array <$t> a, array <$t> b, array <$t> c, int cnt)
{
   int i ;

   array_permute_blocks (a,  left_i, pck_f, upck_f) ;
   array_permute_blocks (b, upper_i, pck_f, upck_f) ;

   array_map (local_sprod (a, b), c, c) ;

   for (i = 0 ; i < cnt ; i++)
   {
      array_permute_blocks (a,  left_1, pck_f, upck_f) ;
      array_permute_blocks (b, upper_1, pck_f, upck_f) ;

      array_map (local_sprod (a, b), c, c) ;
   }

   return ;
}


int main (int argc, char **argv)
{
   array <int> a, b, c               ;
   int         size                  ;
   Index       totalsize, def_blsize ;

   size = atoi (argv[1]) ;

   par_init   () ;
   array_init () ;

   totalsize[0] = size ;
   totalsize[1] = size ;

   def_blsize[0] = 0 ;
   def_blsize[1] = 0 ;

   a = array_create (2, totalsize, def_blsize, def_lowerbd (totalsize), rand1) ;
   b = array_create (2, totalsize, def_blsize, def_lowerbd (totalsize), rand2) ;
   c = array_create (2, totalsize, def_blsize, def_lowerbd (totalsize), zero ) ;

   matmult (a, b, c, xNetDim - 1) ;

   array_destroy (a, destroy_f) ;
   array_destroy (b, destroy_f) ;
   array_destroy (c, destroy_f) ;

   array_close () ;
   par_close   () ;

   return (0) ;
}


Back to the Skil home page

Valid HTML 4.01 Strict! Valid CSS!