CGP tests; reversed output order

This commit is contained in:
Vojta Mrazek 2021-06-23 13:43:58 +02:00
parent 5228923b69
commit c6e542231c
5 changed files with 155 additions and 23 deletions

View File

@ -53,6 +53,12 @@ jobs:
run: |
cd tests
bash test_circuits.sh
cd ..
- name: Run 8b CGP testing
run: |
cd tests
bash test_circuits_cgp.sh
cd ..
# Only on main thread
documentation:

1
.gitignore vendored
View File

@ -7,5 +7,6 @@ build/
dist/
test_circuits/
tests/tmp.exe
tests/tmp.c
*.egg-info

View File

@ -687,7 +687,7 @@ class ArithmeticCircuit():
Returns:
str: List of arithmetic circuit's output wire indexes.
"""
return "(" + ",".join([str(self.get_circuit_wire_index(o)) for o in self.out.bus[::-1]]) + ")"
return "(" + ",".join([str(self.get_circuit_wire_index(o)) for o in self.out.bus]) + ")"
# Generating flat CGP chromosome representation of circuit
def get_cgp_code_flat(self, file_object):

View File

@ -1,15 +1,16 @@
#!/usr/bin/python3
# A simple script to convert the input CGP chromosome to the corresponding output in C code
# Script originally written by Vojtech Mrazek
# Modifications to suite the appropriate needs of ArithsGen made by Jan Klhufek
# Requires python2!
import sys
import re
import numpy as np
import argparse
# Parse all nodes present in input CGP
def parse_node(n):
return map(int, re.match(r"(\d+),(\d+),(\d+)", n).groups())
return list(map(int, re.match(r"(\d+),(\d+),(\d+)", n).groups()))
# Recursively detect wires required to get the result wire with id 'id' and activate them (will be generated)
@ -30,26 +31,26 @@ def activate(id, act, c_in, cdata_dict):
# Declare new output logic gate's wire if it has not been declared yet (and then assign it the result of corresponding logical function)
# Or return previously declared wire (which is used as an input into corresponding logical function)
def get_sig(name, trans, create=False):
if create is True and int(name) not in trans.keys():
if create is True and int(name) not in list(trans.keys()):
trans[name] = "sig_%d" % name
return trans[name]
# Parse and convert the input CGP chromosome to output C code representation
if __name__ == "__main__":
def parse_chromosome(chromosome, signed=False, function=None):
# Load input CGP
f = open(sys.argv[1], "r")
f = open(chromosome, "r")
chrom = "\n".join([x for x in f])
f.close()
print "// ", sys.argv[1]
output = ["// " + chromosome]
# Splitting input representation into three parts
preamble, data, outputs = re.match(r"\{(.*)\}\((.*)\)\(([^\)]+)\)", chrom).groups()
# Parsing CGP preamble parameters
c_in, c_out, c_rows, c_cols, c_ni, c_no, c_lback = map(int, preamble.split(","))
c_in, c_out, c_rows, c_cols, c_ni, c_no, c_lback = list(map(int, preamble.split(",")))
# Parsing all present nodes
cdata = map(parse_node, data.split(")("))
cdata = list(map(parse_node, data.split(")(")))
# Parse position and corresponding information regarding each chromosome
cdata_dict = [None for i in range(0, c_cols * c_rows)]
@ -69,27 +70,36 @@ if __name__ == "__main__":
act[1] = True
# Obtaining all output wires (MSB to LSB)
outs = map(int, outputs.split(","))
outs = list(map(int, outputs.split(",")))
# Recursively activate all (node) wires needed to obtain the corresponding result wire
for o in outs:
activate(o, act, c_in, cdata_dict)
# Export converted input declarations into C code function header / body start
print "#include <stdint.h>"
print "uint64_t circuit%d(uint64_t a, uint64_t b) {" % (c_in / 2)
print " int wa[%d];" % (c_in/2)
print " int wb[%d];" % (c_in/2)
print " uint64_t y = 0;"
output.append("#include <stdint.h>")
if not function:
function = f"circuit{c_in/2:.0f}"
if signed:
dtype = "int64_t"
else:
dtype = "uint64_t"
output.append(f"{dtype} {function}({dtype} a, {dtype} b) {{")
output.append(" int wa[%d];" % int(c_in/2))
output.append(" int wb[%d];" % int(c_in/2))
output.append(" uint64_t y = 0;")
# Export converted input assignments into C code function body
trans = {}
trans[0] = "0x00"
trans[1] = "0x01"
for i in range(0, (c_in/2)):
for i in range(0, int(c_in/2)):
trans[i+2] = "wa[%d]" % i
print " wa[%d] = (a >> %d) & 0x01;" % (i, i)
output.append(" wa[%d] = (a >> %d) & 0x01;" % (i, i))
trans[i + (c_in/2)+2] = "wb[%d]" % i
print " wb[%d] = (b >> %d) & 0x01;" % (i, i)
output.append(" wb[%d] = (b >> %d) & 0x01;" % (i, i))
# Lists representing individual nodes (lines), output wires (lines_end)
lines = []
@ -119,11 +129,26 @@ if __name__ == "__main__":
# Export converted outputs into C code function body
for i in range(0, c_out):
if outs[i] in trans:
lines_end.append(" y |= (%s & 0x01) << %d; // default output" % (trans[outs[i]], (len(outs)-1) - i))
lines_end.append(" y |= (%s & 0x01) << %d; // default output" % (trans[outs[i]], i))
else:
assert False
# Print final result return in C code function body and close it
lines_end.append(" return y;")
print "\n".join(lines + lines_end)
print "}"
lines_end.append(" return y;")
output += lines
output += lines_end;
output.append("}")
return "\n".join(output)
# Parse and convert the input CGP chromosome to output C code representation
if __name__ == "__main__":
argparse.ArgumentParser()
parser = argparse.ArgumentParser()
parser.add_argument("chromosome", help="Path to CGP file")
parser.add_argument("--signed", action="store_true")
parser.add_argument("--function", default=None)
args = parser.parse_args()
print(parse_chromosome(**vars(args)))

100
tests/test_circuits_cgp.sh Executable file
View File

@ -0,0 +1,100 @@
#!/usr/bin/bash
valid=1
test_circuit () {
local type=$1
local circuit=$2
mode="flat"
echo -e "===== Testing CGP version \e[33m$circuit\e[0m ($mode) ======"
s=""
if [[ $type == *"_signed" ]]; then
s="--signed"
fi
python3 ../chr2c.py $s ../test_circuits/cgp_circuits/$mode/$circuit.cgp > tmp.c
g++ -std=c++11 -pedantic -g -std=c++11 -pedantic -DCNAME="circuit8" $type.c tmp.c -o tmp.exe
if ./tmp.exe ; then
echo -e "[\e[32mok\e[0m]"
else
echo -e "[\e[31mfail\e[0m]"
valid=0
fi
}
test_circuit "adder_signed" "s_rca8"
test_circuit "adder_signed" "s_pg_rca8"
test_circuit "adder_signed" "s_cska8"
test_circuit "adder_signed" "s_cla8"
test_circuit "adder_unsigned" "u_rca8"
test_circuit "adder_unsigned" "u_pg_rca8"
test_circuit "adder_unsigned" "u_cska8"
test_circuit "adder_unsigned" "u_cla8"
test_circuit "multiplier_signed" "s_arrmul8"
test_circuit "multiplier_signed" "s_wallace_cla8"
test_circuit "multiplier_signed" "s_wallace_rca8"
test_circuit "multiplier_signed" "s_wallace_pg_rca8"
test_circuit "multiplier_signed" "s_wallace_cska8"
test_circuit "multiplier_signed" "s_dadda_cla8"
test_circuit "multiplier_signed" "s_dadda_rca8"
test_circuit "multiplier_signed" "s_dadda_pg_rca8"
test_circuit "multiplier_signed" "s_dadda_cska8"
test_circuit "multiplier_unsigned" "u_arrmul8"
test_circuit "multiplier_unsigned" "u_wallace_cla8"
test_circuit "multiplier_unsigned" "u_wallace_rca8"
test_circuit "multiplier_unsigned" "u_wallace_pg_rca8"
test_circuit "multiplier_unsigned" "u_wallace_cska8"
test_circuit "multiplier_unsigned" "u_dadda_cla8"
test_circuit "multiplier_unsigned" "u_dadda_rca8"
test_circuit "multiplier_unsigned" "u_dadda_pg_rca8"
test_circuit "multiplier_unsigned" "u_dadda_cska8"
if [ $valid -eq 1 ]; then
echo "all tests passed"
exit 0
else
echo "some of tests failed"
exit 1
fi
# exporting s_rca8
# exporting s_pg_rca8
# exporting s_cska8
# exporting s_cla8
# exporting s_arrmul8
# exporting s_wallace_cla8
# exporting s_wallace_rca8
# exporting s_wallace_pg_rca8
# exporting s_wallace_cska8
# exporting s_dadda_cla8
# exporting s_dadda_rca8
# exporting s_dadda_pg_rca8
# exporting s_dadda_cska8
# exporting u_rca8
# exporting u_pg_rca8
# exporting u_cska8
# exporting u_cla8
# exporting u_arrmul8
# exporting u_wallace_cla8
# exporting u_wallace_rca8
# exporting u_wallace_pg_rca8
# exporting u_wallace_cska8
# exporting u_dadda_cla8
# exporting u_dadda_rca8
# exporting u_dadda_pg_rca8
# exporting u_dadda_cska8
# exporting arrdiv8