/*
This file is part of JOP, the Java Optimized Processor
see <http://www.jopdesign.com/>
Copyright (C) 2008, Jack Whitham
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package test;
import com.jopdesign.io.JeopardIOFactory;
import com.jopdesign.sys.*;
/**
* @author jack
*
*/
public class HWMethTest {
public static void main(String[] args) {
HWMethTest h = new HWMethTest () ;
h.HWM_Start () ;
h.MAC_Start () ;
}
public final static int max_mac_size = 10000 ;
public final static int max_cycles = 100 ;
public int [] array1 ;
public int [] array2 ;
public mac_coprocessor m ;
public bitcount_maxsearch bcms ;
public void MAC_Start()
{
array1 = new int [ max_mac_size + 1 ] ;
array2 = new int [ max_mac_size + 1 ] ;
m = mac_coprocessor.getInstance () ;
int icount = 0 ;
boolean error = false ;
for ( int mac_size = 1 ;
( mac_size < max_mac_size ) && ! error ; icount ++ )
{
error = MAC_Measure ( mac_size ) ;
mac_size ++ ;
if ( icount > 100 )
{
mac_size += mac_size / 4 ;
}
}
if ( ! error )
{
MAC_Measure ( max_mac_size ) ;
}
}
public boolean MAC_Measure( int mac_size )
{
int i, expect = 0;
boolean error = false;
for ( i = 0 ; i < mac_size ; i ++ )
{
array1 [ i ] = mac_size + 123 + ( i * 99 ) + ( i * i * 12 ) ;
array2 [ i ] = mac_size + 456 + ( i * 78 ) + ( i * i * 9 ) ;
expect += array1 [ i ] * array2 [ i ] ;
}
// sentinel: don't mac this!
array1 [ mac_size ] = 20576 ;
array2 [ mac_size ] = 6 ;
int ts = Native.rdMem(Const.IO_CNT);
int te = Native.rdMem(Const.IO_CNT);
int to = te-ts;
System.out.print(mac_size);
System.out.print(" ");
int max_time = 0;
int min_time = 1 << 30;
int total_time = 0;
// Warmup method cache
int out = m.mac1(mac_size, array1, array2);
for ( i = 0 ; i < max_cycles ; i ++ )
{
ts = Native.rdMem(Const.IO_CNT);
out = m.mac1(mac_size, array1, array2);
te = Native.rdMem(Const.IO_CNT);
int time = te - ts - to;
if ( time > max_time )
{
max_time = time;
}
if ( time < min_time )
{
min_time = time;
}
total_time += time;
if ( out != expect )
{
error = true;
break ;
}
}
if ( error )
{
System.out.print(" - Unexpected value! hw ");
System.out.print(out);
System.out.print(" expect ");
System.out.println(expect);
return true;
}
System.out.print(min_time);
System.out.print(" ");
System.out.print(total_time / max_cycles);
System.out.print(" ");
System.out.println(max_time);
return false;
}
public static int [] lut ;
public final int max_test_size = max_mac_size ;
public int [] test_vector ;
public void HWM_Start ()
{
// Build LUT
int i ;
int [] data = new int [ 1 ] ;
lut = new int [ 256 ] ;
for ( i = 0 ; i < 256 ; i ++ )
{
data [ 0 ] = i ;
lut [ i ] = bit_count1 ( 1 , data ) ;
}
bcms = new bitcount_maxsearch () ;
test_vector = new int [ max_test_size + 1 ] ;
boolean error = false;
for ( i = 1 ; i <= max_cycles ; i ++ )
{
Prepare_Noisy_Vector ( i ) ;
error = HWM_SW_Measure ( i ) ;
if ( error ) return ;
}
System.out.print("v=0 ");
Prepare_Fill_Vector ( max_test_size , 0 ) ;
error = HWM_SW_Measure ( max_test_size ) ;
if ( error ) return ;
System.out.print("v=0..9 ");
for ( i = 0 ; i < 10 ; i ++ )
{
test_vector[ i ] = i ;
}
error = HWM_SW_Measure ( max_test_size ) ;
if ( error ) return ;
Prepare_Fill_Vector ( max_test_size , 0x7fffffff ) ;
System.out.print("v=-1 ");
error = HWM_SW_Measure ( max_test_size ) ;
if ( error ) return ;
System.out.print("v=Noise ");
Prepare_Noisy_Vector ( max_test_size ) ;
error = HWM_SW_Measure ( max_test_size ) ;
if ( error ) return ;
System.out.print("v=1..N ");
for ( i = 0 ; i < max_test_size ; i ++ )
{
test_vector [ i ] = i + 1 ;
}
error = HWM_SW_Measure ( max_test_size ) ;
if ( error ) return ;
}
public void Prepare_Fill_Vector ( int test_size , int fill )
{
for ( int i = 0 ; i < test_size ; i ++ )
{
test_vector [ i ] = fill ;
}
}
public void Prepare_Noisy_Vector ( int test_size )
{
for ( int i = 0 ; i < test_size ; i ++ )
{
test_vector [ i ] = test_size +
((((((( 1 + i ) * i ) + 3 ) * i ) + 7 ) * i ) + 11 ) ;
}
}
public boolean HWM_SW_Measure( int test_size )
{
int ts = Native.rdMem(Const.IO_CNT);
int te = Native.rdMem(Const.IO_CNT);
int to = te-ts;
boolean error = false;
System.out.print(test_size);
test_vector [ test_size ] = 0x7fffffff ;
mac (test_size, test_vector, test_vector);
ts = Native.rdMem(Const.IO_CNT);
mac (test_size, test_vector, test_vector);
te = Native.rdMem(Const.IO_CNT);
System.out.print(" ");
System.out.print(te - ts - to);
int bc1 = bit_count1 ( test_size , test_vector ) ;
ts = Native.rdMem(Const.IO_CNT);
bit_count1 ( test_size , test_vector ) ;
te = Native.rdMem(Const.IO_CNT);
System.out.print(" ");
System.out.print(te - ts - to);
int bc2 = bit_count2 ( test_size , test_vector ) ;
ts = Native.rdMem(Const.IO_CNT);
bit_count2 ( test_size , test_vector ) ;
te = Native.rdMem(Const.IO_CNT);
System.out.print(" ");
System.out.print(te - ts - to);
int sm = search_max ( test_size , test_vector ) ;
ts = Native.rdMem(Const.IO_CNT);
search_max ( test_size , test_vector ) ;
te = Native.rdMem(Const.IO_CNT);
System.out.print(" ");
System.out.print(te - ts - to);
int bchw1 = bcms.bitcount ( test_size , test_vector ) ;
ts = Native.rdMem(Const.IO_CNT);
int bchw2 = bcms.bitcount ( test_size , test_vector ) ;
te = Native.rdMem(Const.IO_CNT);
int bchw_time = te - ts - to;
int smhw1 = bcms.maxsearch ( test_size , test_vector ) ;
ts = Native.rdMem(Const.IO_CNT);
int smhw2 = bcms.maxsearch ( test_size , test_vector ) ;
te = Native.rdMem(Const.IO_CNT);
int smhw_time = te - ts - to;
System.out.print(" ");
System.out.print(bchw_time);
System.out.println("");
if ( smhw_time != bchw_time )
{
System.out.print("Discrepancy on smhw/bchw time: ");
System.out.print(bchw_time);
System.out.print(" ");
System.out.print(smhw_time);
System.out.println("");
error = true ;
}
if (( bc1 != bc2 )
|| ( bc1 != bchw1 )
|| ( bc1 != bchw2 ))
{
System.out.print("Discrepancy on bitcount results: ");
System.out.print(bc1);
System.out.print(" ");
System.out.print(bc2);
System.out.print(" ");
System.out.print(bchw1);
System.out.print(" ");
System.out.print(bchw2);
System.out.println("");
error = true ;
}
if (( sm != smhw1 )
|| ( sm != smhw2 ))
{
System.out.print("Discrepancy on searchmax results: ");
System.out.print(sm);
System.out.print(" ");
System.out.print(smhw1);
System.out.print(" ");
System.out.print(smhw2);
System.out.println("");
error = true ;
}
return error ;
}
public int bit_count1(int size, int[]data) {
int count = 0;
for ( int i = 0 ; i < size ; i ++ ) // @WCA loop<=10000
{
int d = data [ i ];
for ( int j = 0 ; j < 32 ; j ++ ) // @WCA loop=32
{
if (( d & 1 ) == 1 ) count ++ ;
d = d >> 1 ;
}
}
return count;
}
public int bit_count2(int size, int[]data) {
int count = 0;
for ( int i = 0 ; i < size ; i ++ ) // @WCA loop<=10000
{
int d = data [ i ];
for ( int j = 0 ; j < 4 ; j ++ ) // @WCA loop=4
{
count += lut [ d & 255 ] ;
d = d >> 8 ;
}
}
return count;
}
public int search_max(int size, int[]data) {
int max = 0;
for ( int i = 0 ; i < size ; i ++ ) // @WCA loop<=10000
{
int d = data [ i ];
if ( d > max ) max = d ;
}
return max ;
}
public int mac(int size, int[] array1, int[] array2) {
int val = 0;
for ( int i = 0 ; i < size ; i ++ ) // @WCA loop<=10000
{
val += array1 [ i ] * array2 [ i ] ;
}
return val ;
}
}