User Tools

Site Tools


kernels_auto_input_generate_test

Kernels auto input geterate/test

Currently working

  • bubblesort
  • quicksort
  • shellsort
  • binary search
  • hamming1
  • hamming1_unrolled
  • hamming2
  • hamming2_unrolled
  • gray
  • gcd
  • sqrt
  • intmatmult3x3
  • intmatmult4x4
  • strcmp
  • arrcmp32 (Hardware producing wrong output)
  • bytesum4

Input/Script

Skeleton used for automatically generating main with multiple function calls to test correctness of hardware.

1. foo1.c

A function to test (example-returns absolute difference of the sum of the first two integers and third)

int foo1(int a, int b, int c){
	int temp;
	temp = a + b;
	if (temp > c)
		return (temp - c);
	else
		return (c - temp);
}

2. test.data

Function signature. Only the function name and number of arguments are used as of now.

Update: now recognizes signed and unsigned.

Format:

<funcName> <type1> <type2>...
foo1 unsigned signed unsigned

3. genInput.pl

Script to generates random sets of input, and create a c program with the function and main.

To run:

perl genInput.pl test.data <# of tests>

Code:

#test.data in the form: FuncName Type1 Type2.....
#Type => input data type

#Number of Test Sets
$Nvectors = $ARGV[1]; 

print "#include <stdio.h>\n\n";
print "int main(void) {\n";

print "int ret;\n";

open (FILE, "$ARGV[0]");

while (<FILE>) {
	chop; # remove newline
	@tokens = split(/ +/);
	$funcName = $tokens[0];
	
#	print "//CHECK: $#tokens\n";

	for ($i = 0; $i < $Nvectors; $i++) {
		print "\nret = $funcName(";
		$count = 1;

		#Generate random integer for each input
		for ($j = 1; $j <= $#tokens; $j++) {
			$randInt = int(rand(100));
			$vec[$count] = $randInt;  #Stores generated input
			$count++;
			print "$randInt";

			#',' if not the last argument, ')' if last
			if ($j < $#tokens) {
				print ", ";
			}
			else {
				print ");\n";
			}
		}
		print "printf(\"";
		for ($j = 1; $j < $count; $j++) {
			$temp = $vec[$j];
			print "$temp ";
		}
		print "%d\\n\", ret);\n";
	
	}	

}
close (FILE);
print "\nreturn 0;\n}\n";

4. test.pl

Script to run genInput.pl, compile c program produced with output stored in output.data, generates a second c program with same input and compares output with correct output produced from first c program.

To run:

perl test.pl test.data <# of tests>

Code:

$Nvectors = $ARGV[1];

open (INPUT, "$ARGV[0]");
while (<INPUT>){
	chop;
	@temp = split(/ +/);
	$funcName = $temp[0];
}
close (INPUT);

system ("rm gen_out.c a.out output.data test.c");
system ("cp foo1.c gen_out.c");
system ("perl genInput.pl test.data $Nvectors >> gen_out.c");
system ("gcc gen_out.c");
system ("./a.out > output.data");

system ("cp foo1.c test.c");

open (DATA, 'output.data');
open (TEST, '>>test.c');

print TEST "#include <stdio.h>\n\n";
print TEST "int main(void) {\n";

print TEST "	int output[$Nvectors];\n";

@correct_output;
$count = 0;
while (<DATA>){
	chomp;
	@tokens = split (/ +/);
	$out_index = $#tokens;
	$correct_output[$count] = $tokens[$out_index];
	
	print TEST "	output[$count] = $funcName(";
	for ($i = 0; $i < $out_index; $i++){
		print TEST ("$tokens[$i]");
		if ($i < ($out_index-1)) {
			print TEST ", ";
		}
		else {
			print TEST ");\n"
		}
	}
	$count++;
}

close (DATA);

print TEST "\n	int correct_output[$Nvectors] = {";
for ($j = 0; $j <= $#correct_output; $j++){
	print TEST ("$correct_output[$j]");
	if ($j < $#correct_output){
		print TEST (", ");
	}
}
print TEST ("};\n\n");

print TEST ("	int i;\n");
print TEST ("	int count = 0;\n");
print TEST ("	for (i=0; i < $Nvectors; i++){\n");
print TEST ("		if (output[i] == correct_output[i]){\n");
print TEST ("			count++;\n");
print TEST ("		}\n");
print TEST ("	}\n");
print TEST ("	printf(\"\%d\\n\", count);\n");
print TEST ("	return count;\n");
print TEST ("}\n");

close (TEST);

Script Output

5. gen_out.c

Output from genInput.pl

int foo1(int a, int b, int c){
	int temp;
	temp = a + b;
	if (temp > c)
		return (temp - c);
	else
		return (c - temp);
}
#include <stdio.h>

int main(void) {
int ret;

ret = foo1(11, 56, 40);
printf("11 56 40 %d\n", ret);

ret = foo1(44, 95, 66);
printf("44 95 66 %d\n", ret);

ret = foo1(90, 34, 23);
printf("90 34 23 %d\n", ret);

ret = foo1(7, 22, 17);
printf("7 22 17 %d\n", ret);

ret = foo1(61, 28, 18);
printf("61 28 18 %d\n", ret);

ret = foo1(79, 64, 66);
printf("79 64 66 %d\n", ret);

ret = foo1(20, 57, 40);
printf("20 57 40 %d\n", ret);

ret = foo1(83, 83, 34);
printf("83 83 34 %d\n", ret);

ret = foo1(93, 70, 49);
printf("93 70 49 %d\n", ret);

ret = foo1(94, 22, 24);
printf("94 22 24 %d\n", ret);

return 0;
}

6. output.data

Output (also contains input used) from gen_out

Format:

<input1> <input2>.....<output>
11 56 40 27
44 95 66 73
90 34 23 101
7 22 17 12
61 28 18 71
79 64 66 77
20 57 40 37
83 83 34 132
93 70 49 114
94 22 24 92

7. test.c

Final c program that test hardware functionality correctness.

int foo1(int a, int b, int c){
	int temp;
	temp = a + b;
	if (temp > c)
		return (temp - c);
	else
		return (c - temp);
}
#include <stdio.h>

int main(void) {
	int output[10];
	output[0] = foo1(11, 56, 40);
	output[1] = foo1(44, 95, 66);
	output[2] = foo1(90, 34, 23);
	output[3] = foo1(7, 22, 17);
	output[4] = foo1(61, 28, 18);
	output[5] = foo1(79, 64, 66);
	output[6] = foo1(20, 57, 40);
	output[7] = foo1(83, 83, 34);
	output[8] = foo1(93, 70, 49);
	output[9] = foo1(94, 22, 24);

	int correct_output[10] = {27, 73, 101, 12, 71, 77, 37, 132, 114, 92};

	int i;
	int count = 0;
	for (i=0; i < 10; i++){
		if (output[i] == correct_output[i]){
			count++;
		}
	}
	printf("%d\n", count);
	return count;
}
kernels_auto_input_generate_test.txt · Last modified: 2012/06/15 10:56 by xiryan