LLVM 24.0.0git
interactive_host.py
Go to the documentation of this file.
1"""Utility for testing InteractiveModelRunner.
2
3Use it from pass-specific tests by providing a main .py which calls this library's
4`run_interactive` with an appropriate callback to provide advice.
5
6From .ll tests, just call the above-mentioned main as a prefix to the opt/llc
7invocation (with the appropriate flags enabling the interactive mode)
8
9Examples:
10test/Transforms/Inline/ML/interactive-mode.ll
11test/CodeGen/MLRegAlloc/interactive-mode.ll
12"""
13
14import ctypes
15import log_reader
16import io
17import math
18import os
19import subprocess
20from typing import Callable, List, Union
21
22
23def send(f: io.BufferedWriter, value: Union[int, float], spec: log_reader.TensorSpec):
24 """Send the `value` - currently just a scalar - formatted as per `spec`."""
25
26 if spec.element_type == ctypes.c_int64:
27 to_send = ctypes.c_int64(int(value))
28 elif spec.element_type == ctypes.c_float:
29 to_send = ctypes.c_float(float(value))
30 else:
31 raise ValueError(f"unsupported advice element type {spec.element_type}")
32 assert f.write(bytes(to_send)) == ctypes.sizeof(spec.element_type) * math.prod(
33 spec.shape
34 )
35 f.flush()
36
37
39 temp_rootname: str,
40 make_response: Callable[[List[log_reader.TensorValue]], Union[int, float]],
41 process_and_args: List[str],
42):
43 """Host the compiler.
44 Args:
45 temp_rootname: the base file name from which to construct the 2 pipes for
46 communicating with the compiler.
47 make_response: a function that, given the current tensor values, provides a
48 response.
49 process_and_args: the full commandline for the compiler. It it assumed it
50 contains a flag poiting to `temp_rootname` so that the InteractiveModeRunner
51 would attempt communication on the same pair as this function opens.
52
53 This function sets up the communication with the compiler - via 2 files named
54 `temp_rootname`.in and `temp_rootname`.out - prints out the received features,
55 and sends back to the compiler an advice (which it gets from `make_response`).
56 It's used for testing, and also to showcase how to set up communication in an
57 interactive ML ("gym") environment.
58 """
59 to_compiler = temp_rootname + ".in"
60 from_compiler = temp_rootname + ".out"
61 try:
62 os.mkfifo(to_compiler, 0o666)
63 os.mkfifo(from_compiler, 0o666)
64 compiler_proc = subprocess.Popen(
65 process_and_args, stderr=subprocess.PIPE, stdout=subprocess.DEVNULL
66 )
67 with io.BufferedWriter(io.FileIO(to_compiler, "wb")) as tc:
68 with io.BufferedReader(io.FileIO(from_compiler, "rb")) as fc:
69 tensor_specs, _, advice_spec = log_reader.read_header(fc)
70 context = None
71 while compiler_proc.poll() is None:
72 next_event = fc.readline()
73 if not next_event:
74 break
75 (
76 last_context,
77 observation_id,
78 features,
79 _,
81 context, next_event, fc, tensor_specs, None
82 )
83 if last_context != context:
84 print(f"context: {last_context}")
85 context = last_context
86 print(f"observation: {observation_id}")
87 tensor_values = []
88 for fv in features:
90 tensor_values.append(fv)
91 send(tc, make_response(tensor_values), advice_spec)
92 _, err = compiler_proc.communicate()
93 print(err.decode("utf-8"))
94 compiler_proc.wait()
95
96 finally:
97 os.unlink(to_compiler)
98 os.unlink(from_compiler)
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
run_interactive(str temp_rootname, Callable[[List[log_reader.TensorValue]], Union[int, float]] make_response, List[str] process_and_args)
send(io.BufferedWriter f, Union[int, float] value, log_reader.TensorSpec spec)
pretty_print_tensor_value(TensorValue tv)
Definition log_reader.py:75
read_one_observation(Optional[str] context, str event_str, io.BufferedReader f, List[TensorSpec] tensor_specs, Optional[TensorSpec] score_spec)
Definition log_reader.py:93
read_header(io.BufferedReader f)
Definition log_reader.py:79