def EndEpisodeStep(self) -> random_opt_pb2.DelayedRewardStep: start_ms = labdate.MillisecondsTimestamp() step = random_opt_pb2.DelayedRewardStep(start_time_epoch_ms=start_ms, ) try: clang.Compile([self.working_bytecode_path], self.binary_path, copts=["-O0"]) try: runtimes = self.GetRuntimes() self.episodes[-1].binary_runtime_ms.extend(runtimes) if self.BinaryIsValid(): step.reward = self.runtime_reward( sum(runtimes) / len(runtimes)) else: self.episodes[ -1].outcome = random_opt_pb2.DelayedRewardEpisode.EVAL_FAILED step.reward = self.eval_failed_reward except ValueError as e: self.episodes[-1].outcome = random_opt_pb2.Step.EXEC_FAILED self.episodes[-1].outcome_error_msg = text.truncate( str(e), 255) step.reward = self.exec_failed_reward except clang.ClangException as e: self.episodes[ -1].outcome = random_opt_pb2.DelayedRewardEpisode.COMPILE_FAILED self.episodes[-1].outcome_error_msg = text.truncate(str(e), 255) step.reward = self.compile_failed_reward obs = self.observation_space.sample() step.total_step_runtime_ms = labdate.MillisecondsTimestamp() - start_ms self.episodes[-1].step.extend([step]) return obs, step.reward, True, {}
def reset(self): app.Log(2, "$ cp %s %s", self.bytecode_path, self.working_bytecode_path) shutil.copyfile(self.bytecode_path, self.working_bytecode_path) clang.Compile([self.working_bytecode_path], self.binary_path, copts=["-O0"]) start_time = labdate.MillisecondsTimestamp() self.RunSetupCommand() self.RunBinary() if not self.BinaryIsValid(): raise ValueError(f"Failed to validate base binary.") self.episodes.append( random_opt_pb2.Episode(step=[ random_opt_pb2.Step( start_time_epoch_ms=start_time, status=random_opt_pb2.Step.PASS, binary_runtime_ms=self.GetRuntimes(), reward=0, total_reward=0, speedup=1.0, total_speedup=1.0, ) ])) self.episodes[-1].step[0].total_step_runtime_ms = ( labdate.MillisecondsTimestamp() - start_time)
def reset(self): """Reset the environment state.""" app.Log(2, "$ cp %s %s", self.bytecode_path, self.working_bytecode_path) shutil.copyfile(self.bytecode_path, self.working_bytecode_path) clang.Compile([self.bytecode_path], self.binary_path, copts=["-O0"]) self.RunSetupCommand() self.episodes.append( random_opt_pb2.DelayedRewardEpisode(step=[ random_opt_pb2.DelayedRewardStep( start_time_epoch_ms=labdate.MillisecondsTimestamp(), ) ]))
def test_benchmarks(benchmark: benchmarks_pb2.Benchmark): """Test attributes of protos.""" assert benchmark.name assert pathlib.Path(benchmark.binary).is_file() for path in benchmark.srcs: assert pathlib.Path(path).is_file() for path in benchmark.hdrs: assert pathlib.Path(path).is_file() # Compile the sources. with tempfile.TemporaryDirectory() as d: clang.Compile([pathlib.Path(x) for x in benchmark.srcs], pathlib.Path(d) / 'exe') assert (pathlib.Path(d) / 'exe').is_file()
def ProduceBytecodeFromSources( input_paths: typing.List[pathlib.Path], output_path: pathlib.Path, copts: typing.Optional[typing.List[str]] = None, linkopts: typing.Optional[typing.List[str]] = None, timeout_seconds: int = 60, ) -> pathlib.Path: """Produce a single bytecode file for a set of sources. Args: input_paths: A list of input source files. output_path: The file to generate. copts: A list of additional flags to pass to clang. linkopts: A list of additional flags to pass to llvm-link. timeout_seconds: The number of seconds to allow clang to run for. Returns: The output_path. """ copts = copts or [] if output_path.is_file(): output_path.unlink() # Compile each input source to a bytecode file. with tempfile.TemporaryDirectory() as d: d = pathlib.Path(d) input_srcs = [ d / (crypto.sha256_str(str(src)) + ".l") for src in input_paths ] for src, input_src in zip(input_paths, input_srcs): clang.Compile( [src], input_src, copts=copts + ["-O0", "-emit-llvm", "-S", "-c"], timeout_seconds=timeout_seconds, ) # Link the separate bytecode files. llvm_link.LinkBitcodeFilesToBytecode(input_srcs, output_path, linkopts, timeout_seconds=timeout_seconds) return output_path
def Step(self, step: random_opt_pb2.Step) -> random_opt_pb2.Step: """Run a step. Args: step: A step proto with field 'opt_pass' set. Returns: The input step. """ start_time = labdate.MillisecondsTimestamp() step.start_time_epoch_ms = start_time step.status = random_opt_pb2.Step.PASS temp_bytecode = self.working_dir / "temp_src.ll" temp_binary = self.working_dir / "temp_binary" # Run the pass. try: opt.RunOptPassOnBytecode(self.working_bytecode_path, temp_bytecode, list(step.opt_pass)) except llvm.LlvmError as e: step.status = random_opt_pb2.Step.OPT_FAILED step.status_msg = text.truncate(str(e), 255) if step.status == random_opt_pb2.Step.PASS: # Update bytecode file. app.Log(2, "$ mv %s %s", temp_bytecode, self.working_bytecode_path) step.bytecode_changed = BytecodesAreEqual( temp_bytecode, self.working_bytecode_path) os.rename(str(temp_bytecode), str(self.working_bytecode_path)) # Compile a new binary. try: clang.Compile([self.working_bytecode_path], temp_binary, copts=["-O0"]) step.binary_changed = BinariesAreEqual(temp_binary, self.binary_path) os.rename(str(temp_binary), str(self.binary_path)) except llvm.LlvmError as e: step.status = random_opt_pb2.Step.COMPILE_FAILED step.status_msg = text.truncate(str(e), 255) if step.status == random_opt_pb2.Step.PASS: # Get the binary runtime. try: step.binary_runtime_ms.extend(self.GetRuntimes()) except ValueError as e: step.status = random_opt_pb2.Step.EXEC_FAILED step.status_msg = text.truncate(str(e), 255) if step.status == random_opt_pb2.Step.PASS: if self.BinaryIsValid(): step.speedup = ( sum(self.episodes[-1].step[-1].binary_runtime_ms) / len(self.episodes[-1].step[-1].binary_runtime_ms)) / (sum( step.binary_runtime_ms) / len(step.binary_runtime_ms)) step.total_speedup = ( sum(self.episodes[-1].step[0].binary_runtime_ms) / len(self.episodes[-1].step[0].binary_runtime_ms)) / (sum( step.binary_runtime_ms) / len(step.binary_runtime_ms)) else: step.status = random_opt_pb2.Step.EVAL_FAILED step.reward = self.Reward(step.status, step.speedup) step.total_reward = self.episodes[-1].step[ -1].total_reward + step.reward step.total_step_runtime_ms = labdate.MillisecondsTimestamp( ) - start_time return step