diff --git a/ex.py b/ex.py index d0f4abe..41a69b6 100644 --- a/ex.py +++ b/ex.py @@ -1,3 +1,4 @@ +from gbso.program.mutate import create_random_program from time import time from gbso.cpu.state import CPUState @@ -20,11 +21,12 @@ prgm = Program( outputs = [R8.A] test_cases = [TestCase()] max_size = 4 -num_iters = 100_000_000 +num_iters = 1_000_000 initial_cost = cost(prgm, test_cases, outputs, prgm) initial_cycles = prgm.perf() +print("Program to optimize:") prgm.display() print(f"Cost: {initial_cost}") @@ -34,6 +36,7 @@ start_time = time() optimized_prgm = optimize( prgm, + init_prgm=create_random_program(max_size), max_size=max_size, test_cases=test_cases, outputs=outputs, @@ -42,6 +45,7 @@ optimized_prgm = optimize( end_time = time() +print("Optimized result:") optimized_prgm.display() optimized_cost = cost(prgm, test_cases, outputs, optimized_prgm) diff --git a/gbso/optimize.py b/gbso/optimize.py index b20f167..881e472 100644 --- a/gbso/optimize.py +++ b/gbso/optimize.py @@ -1,6 +1,6 @@ -from math import exp, log +from math import log from random import random -from typing import List, Tuple +from typing import List, Optional, Tuple from gbso.program.test_case import Output, TestCase, eq_on_testcase from gbso.program.mutate import mutate_program @@ -31,11 +31,12 @@ def cost(orig_prgm, test_cases, outputs, prgm) -> Tuple[int, bool]: def optimize( - prgm: Program, + target_prgm: Program, max_size: int, test_cases: List[TestCase], outputs: List[Output], beta: int = 0.5, # How far away in cost you are allowed to search + init_prgm: Optional[Program] = None, num_iters: int = DEFAULT_NUM_ITERS, prob_opcode: float = DEFAULT_PROB_OPCODE, prob_operand: float = DEFAULT_PROB_OPERAND, @@ -43,31 +44,32 @@ def optimize( prob_insn: float = DEFAULT_PROB_INSN, prob_insn_unused: float = DEFAULT_PROB_INSN_UNUSED, ) -> Program: - padded_prgm = prgm.pad(max_size) + padded_prgm = (init_prgm or target_prgm).pad(max_size) last_prgm = padded_prgm - last_cost, _last_eq = cost(padded_prgm, test_cases, outputs, last_prgm) + last_cost, _last_eq = cost(target_prgm, test_cases, outputs, last_prgm) - best_prgm = padded_prgm - best_cost = last_cost + best_prgm = target_prgm.pad(max_size) + best_cost = 0 + + num_candidates = 0 for _ in range(num_iters): candidate_prgm = mutate_program( last_prgm, prob_opcode, prob_operand, prob_swap, prob_insn, prob_insn_unused ) candidate_cost, candidate_eq = cost( - padded_prgm, test_cases, outputs, candidate_prgm + target_prgm, test_cases, outputs, candidate_prgm ) if candidate_cost < best_cost and candidate_eq: best_prgm = candidate_prgm best_cost = candidate_cost + num_candidates += 1 if candidate_cost < last_cost - log(random()) / beta: last_prgm = candidate_prgm last_cost = candidate_cost - print("last") - last_prgm.display() - + print(f"Optimization complete. Total candidates: {num_candidates}") return best_prgm diff --git a/gbso/program/mutate.py b/gbso/program/mutate.py index 8c1cd3f..025bdd3 100644 --- a/gbso/program/mutate.py +++ b/gbso/program/mutate.py @@ -146,3 +146,13 @@ def create_random_operand(op: Operand) -> Union[int, R8, R16]: value = randint(-128, 127) return value + + +def create_random_program(size: int) -> Program: + insns = [] + + for _ in range(size): + cls = choice(ALL_INSN_CLASSES + [UNUSED]) + insns.append(create_random_insn(cls)) + + return Program(insns=insns)