X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=mt%2Fae_matmul%2Fmatmul_gendata.pl;fp=mt%2Fae_matmul%2Fmatmul_gendata.pl;h=f21bb4624e0fd0a1a3c25279a27e6f8fe3411968;hb=60f056880ec6929c5f23af4d66aea0f0cb7b0245;hp=0000000000000000000000000000000000000000;hpb=4412b96c81ca09dcce6305579dd86d4bf3b808da;p=riscv-tests.git diff --git a/mt/ae_matmul/matmul_gendata.pl b/mt/ae_matmul/matmul_gendata.pl new file mode 100755 index 0000000..f21bb46 --- /dev/null +++ b/mt/ae_matmul/matmul_gendata.pl @@ -0,0 +1,200 @@ +#!/usr/bin/perl -w +#========================================================================== +# matmul_gendata.pl +# +# Author : Christopher Batten (cbatten@mit.edu) +# Date : April 29, 2005 +# +(our $usageMsg = <<'ENDMSG') =~ s/^\#//gm; +# +# Simple script which creates an input data set and the reference data +# for the matmul benchmark. +# +ENDMSG + +use strict "vars"; +use warnings; +no warnings("once"); +use Getopt::Long; + +#-------------------------------------------------------------------------- +# Command line processing +#-------------------------------------------------------------------------- + +our %opts; + +sub usage() +{ + + print "\n"; + print " Usage: matmul_gendata.pl [options] \n"; + print "\n"; + print " Options:\n"; + print " --help print this message\n"; + print " --size size of input data [1000]\n"; + print " --seed random seed [1]\n"; + print "$usageMsg"; + + exit(); +} + +sub processCommandLine() +{ + + $opts{"help"} = 0; + $opts{"size"} = 1000; + $opts{"seed"} = 1; + Getopt::Long::GetOptions( \%opts, 'help|?', 'size:i', 'seed:i' ) or usage(); + $opts{"help"} and usage(); + +} + +#-------------------------------------------------------------------------- +# Helper Functions +#-------------------------------------------------------------------------- + +sub printArray +{ + my $arrayName = $_[0]; + my $arrayRef = $_[1]; + + my $numCols = 20; + my $arrayLen = scalar(@{$arrayRef}); + + print "static data_t ".$arrayName."[ARRAY_SIZE] = \n"; + print "{\n"; + + if ( $arrayLen <= $numCols ) { + print " "; + for ( my $i = 0; $i < $arrayLen; $i++ ) { + print sprintf("%3d",$arrayRef->[$i]); + if ( $i != $arrayLen-1 ) { + print ", "; + } + } + print "\n"; + } + + else { + my $numRows = int($arrayLen/$numCols); + for ( my $j = 0; $j < $numRows; $j++ ) { + print " "; + for ( my $i = 0; $i < $numCols; $i++ ) { + my $index = $j*$numCols + $i; + print sprintf("%3d",$arrayRef->[$index]); + if ( $index != $arrayLen-1 ) { + print ", "; + } + } + print "\n"; + } + + if ( $arrayLen > ($numRows*$numCols) ) { + print " "; + for ( my $i = 0; $i < ($arrayLen-($numRows*$numCols)); $i++ ) { + my $index = $numCols*$numRows + $i; + print sprintf("%3d",$arrayRef->[$index]); + if ( $index != $arrayLen-1 ) { + print ", "; + } + } + print "\n"; + } + + } + + print "};\n\n"; +} + + + +#-------------------------------------------------------------------------- +# Matmul +#-------------------------------------------------------------------------- + +# http://answers.oreilly.com/topic/418-how-to-multiply-matrices-in-perl/ + +sub mmult { + my ($m1,$m2) = @_; + my ($m1rows,$m1cols) = matdim($m1); + my ($m2rows,$m2cols) = matdim($m2); + + my $result = [ ]; + my ($i, $j, $k); + + for $i (range($m1rows)) { + for $j (range($m2cols)) { + for $k (range($m1cols)) { + $result->[$i][$j] += $m1->[$i][$k] * $m2->[$k][$j]; + } + } + } + return $result; +} + +sub range { 0 .. ($_[0] - 1) } + + +sub veclen { + my $ary_ref = $_[0]; + my $type = ref $ary_ref; + if ($type ne "ARRAY") { die "$type is bad array ref for $ary_ref" } + return scalar(@$ary_ref); +} + +sub matdim { + my $matrix = $_[0]; + my $rows = veclen($matrix); + my $cols = veclen($matrix->[0]); + return ($rows, $cols); +} + +#-------------------------------------------------------------------------- +# Main +#-------------------------------------------------------------------------- + +sub main() +{ + + processCommandLine(); + srand($opts{"seed"}); + + # create random input arrays + my $mat_values1; + my $mat_values2; + for ( my $i = 0; $i < $opts{"size"}; $i++ ) { + for ( my $j = 0; $j < $opts{"size"}; $j++ ) { + $mat_values1->[$i][$j] = int(rand(4)); + $mat_values2->[$i][$j] = int(rand(4)); + } + } + + # perform matmul + my $mat_results = mmult( $mat_values1, $mat_values2 ); + + # translate 2d arrays to 1d-somethings (I don't know how to code in perl - Chris) + my @values1; + my @values2; + my @results; + for ( my $i = 0; $i < $opts{"size"}; $i++ ) { + for ( my $j = 0; $j < $opts{"size"}; $j++ ) { + my $value1 = $mat_values1->[$i][$j]; + my $value2 = $mat_values2->[$i][$j]; + my $result = $mat_results->[$i][$j]; + push( @values1, $value1 ); + push( @values2, $value2 ); + push( @results, $result ); + } + } + + print "\n\#define ARRAY_SIZE ".($opts{"size"}*$opts{"size"})." \n\n"; + print "\n\#define DIM_SIZE ".$opts{"size"}." \n\n"; + + printArray( "input1_data", \@values1 ); + printArray( "input2_data", \@values2 ); + printArray( "verify_data", \@results); + +} + +main(); +