HideIron commited on
Commit
d4d59cd
·
verified ·
1 Parent(s): e7fb527

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. inference.py +17 -24
  2. server/compiler_env_environment.py +100 -8
inference.py CHANGED
@@ -86,10 +86,8 @@ SYSTEM_PROMPT = textwrap.dedent(
86
  Each turn you must reply with exactly ONE tool call. Available tools:
87
  - add_pass(pass_name): Try adding a pass. Auto-compiled and evaluated.
88
  - remove_pass(pass_name): Remove a previously kept pass (-0.05 penalty).
 
89
  - finalize(): End the episode. You receive a final bonus based on baselines.
90
- - get_program_info(): Get program name and baseline execution times
91
- - list_passes(): List all 19 valid LLVM optimization passes
92
- - get_current_sequence(): Get kept passes and current best time
93
 
94
  Available 19 passes (use exact names):
95
  MEMORY:
@@ -169,32 +167,25 @@ TOOLS = [
169
  {
170
  "type": "function",
171
  "function": {
172
- "name": "finalize",
173
- "description": "End the episode. Computes final bonus based on how your best time compares to O0/O1/O2/O3 baselines. Call this when you are satisfied with your pass sequence.",
174
- "parameters": {"type": "object", "properties": {}},
175
- },
176
- },
177
- {
178
- "type": "function",
179
- "function": {
180
- "name": "get_program_info",
181
- "description": "Get information about the current program and its baseline execution times.",
182
- "parameters": {"type": "object", "properties": {}},
183
- },
184
- },
185
- {
186
- "type": "function",
187
- "function": {
188
- "name": "list_passes",
189
- "description": "List all valid LLVM optimization passes.",
190
- "parameters": {"type": "object", "properties": {}},
191
  },
192
  },
193
  {
194
  "type": "function",
195
  "function": {
196
- "name": "get_current_sequence",
197
- "description": "Get the current kept pass sequence and best execution time.",
198
  "parameters": {"type": "object", "properties": {}},
199
  },
200
  },
@@ -322,6 +313,8 @@ def tool_call_to_action(tool_name: str, tool_args: dict) -> str:
322
  return f"add_pass:{tool_args.get('pass_name', '')}"
323
  if tool_name == "remove_pass":
324
  return f"remove_pass:{tool_args.get('pass_name', '')}"
 
 
325
  return tool_name
326
 
327
 
 
86
  Each turn you must reply with exactly ONE tool call. Available tools:
87
  - add_pass(pass_name): Try adding a pass. Auto-compiled and evaluated.
88
  - remove_pass(pass_name): Remove a previously kept pass (-0.05 penalty).
89
+ - reorder_sequence(new_order): Reorder passes. +0.1 if improves, -0.05 if not (reverts).
90
  - finalize(): End the episode. You receive a final bonus based on baselines.
 
 
 
91
 
92
  Available 19 passes (use exact names):
93
  MEMORY:
 
167
  {
168
  "type": "function",
169
  "function": {
170
+ "name": "reorder_sequence",
171
+ "description": "Reorder the current pass sequence. Provide the same passes in a new order. Auto-compiles: +0.1 if time improves (keeps new order), -0.05 if not (reverts).",
172
+ "parameters": {
173
+ "type": "object",
174
+ "properties": {
175
+ "new_order": {
176
+ "type": "string",
177
+ "description": "Comma-separated pass names in the desired new order, e.g. 'gvn,mem2reg,simplifycfg'",
178
+ }
179
+ },
180
+ "required": ["new_order"],
181
+ },
 
 
 
 
 
 
 
182
  },
183
  },
184
  {
185
  "type": "function",
186
  "function": {
187
+ "name": "finalize",
188
+ "description": "End the episode. Computes final bonus based on how your best time compares to O0/O1/O2/O3 baselines. Call this when you are satisfied with your pass sequence.",
189
  "parameters": {"type": "object", "properties": {}},
190
  },
191
  },
 
313
  return f"add_pass:{tool_args.get('pass_name', '')}"
314
  if tool_name == "remove_pass":
315
  return f"remove_pass:{tool_args.get('pass_name', '')}"
316
+ if tool_name == "reorder_sequence":
317
+ return f"reorder_sequence:{tool_args.get('new_order', '')}"
318
  return tool_name
319
 
320
 
server/compiler_env_environment.py CHANGED
@@ -99,8 +99,7 @@ class CompilerEnvironment(Environment):
99
 
100
  self.max_steps = 30
101
  self.action_space = [
102
- "add_pass", "remove_pass", "finalize", "get_program_info",
103
- "list_passes", "get_current_sequence",
104
  ]
105
  self.current_sequence = []
106
  self.valid_passes = ALL_PASSES
@@ -239,14 +238,10 @@ class CompilerEnvironment(Environment):
239
  obs_data, status, message = self._add_pass(action_arg)
240
  elif action_name == "remove_pass":
241
  obs_data, status, message = self._remove_pass(action_arg)
 
 
242
  elif action_name == "finalize":
243
  obs_data, status, message = self._finalize()
244
- elif action_name == "get_program_info":
245
- obs_data, status, message = self._get_program_info()
246
- elif action_name == "list_passes":
247
- obs_data, status, message = self._list_passes()
248
- elif action_name == "get_current_sequence":
249
- obs_data, status, message = self._get_current_sequence()
250
  else:
251
  raise ValueError(f"Unknown action: {action_name}")
252
 
@@ -412,6 +407,103 @@ class CompilerEnvironment(Environment):
412
  f"Pass '{pass_name}' removed from sequence. Reward: -0.05. Current sequence: {self.current_sequence}",
413
  )
414
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
415
  def _get_program_info(self):
416
  """Return program name and baselines."""
417
  return (
 
99
 
100
  self.max_steps = 30
101
  self.action_space = [
102
+ "add_pass", "remove_pass", "reorder_sequence", "finalize",
 
103
  ]
104
  self.current_sequence = []
105
  self.valid_passes = ALL_PASSES
 
238
  obs_data, status, message = self._add_pass(action_arg)
239
  elif action_name == "remove_pass":
240
  obs_data, status, message = self._remove_pass(action_arg)
241
+ elif action_name == "reorder_sequence":
242
+ obs_data, status, message = self._reorder_sequence(action_arg)
243
  elif action_name == "finalize":
244
  obs_data, status, message = self._finalize()
 
 
 
 
 
 
245
  else:
246
  raise ValueError(f"Unknown action: {action_name}")
247
 
 
407
  f"Pass '{pass_name}' removed from sequence. Reward: -0.05. Current sequence: {self.current_sequence}",
408
  )
409
 
410
+ def _reorder_sequence(self, new_order_str):
411
+ """
412
+ Reorder the current pass sequence. Agent provides a comma-separated
413
+ list of the same passes in a new order.
414
+
415
+ - Must contain exactly the same passes (no additions/removals)
416
+ - Auto-compiles and measures
417
+ - If time improves -> keep new order (+0.1)
418
+ - If not -> revert to old order (-0.05)
419
+ """
420
+ base_data = {
421
+ "current_sequence": list(self.current_sequence),
422
+ "sequence_length": len(self.current_sequence),
423
+ "best_time": self.best_time,
424
+ "steps_remaining": self.max_steps - self._state.step_count,
425
+ }
426
+
427
+ if not new_order_str:
428
+ self.episode_reward -= 0.1
429
+ return (
430
+ {**base_data, "reason": "missing_order"},
431
+ "error",
432
+ "No pass order provided. Provide comma-separated pass names.",
433
+ )
434
+
435
+ new_order = [p.strip() for p in new_order_str.split(",") if p.strip()]
436
+
437
+ # Validate: must be the same passes, just reordered
438
+ if sorted(new_order) != sorted(self.current_sequence):
439
+ self.episode_reward -= 0.1
440
+ return (
441
+ {**base_data, "reason": "invalid_order", "provided": new_order},
442
+ "error",
443
+ f"Invalid reorder. Must contain exactly the same passes. Current: {self.current_sequence}, Got: {new_order}",
444
+ )
445
+
446
+ # Same order as before — no-op
447
+ if new_order == self.current_sequence:
448
+ return (
449
+ base_data,
450
+ "success",
451
+ "Sequence unchanged — already in this order.",
452
+ )
453
+
454
+ # Tentatively apply new order
455
+ old_sequence = list(self.current_sequence)
456
+ self.current_sequence = new_order
457
+
458
+ try:
459
+ new_time = self._auto_compile_and_measure()
460
+ except (RuntimeError, subprocess.CalledProcessError, subprocess.TimeoutExpired) as e:
461
+ self.current_sequence = old_sequence
462
+ self.episode_reward -= 0.1
463
+ return (
464
+ {**base_data, "reason": "compile_failed"},
465
+ "compile_failed",
466
+ f"Compilation failed after reorder: {str(e)[:200]}",
467
+ )
468
+
469
+ self.current_time = new_time
470
+
471
+ if new_time < self.best_time:
472
+ old_best = self.best_time
473
+ self.best_time = new_time
474
+ self.episode_reward += 0.1
475
+ return (
476
+ {
477
+ "reordered": True,
478
+ "improved": True,
479
+ "execution_time": new_time,
480
+ "best_time": self.best_time,
481
+ "old_best_time": old_best,
482
+ "current_sequence": list(self.current_sequence),
483
+ "sequence_length": len(self.current_sequence),
484
+ "steps_remaining": self.max_steps - self._state.step_count,
485
+ },
486
+ "reorder_improved",
487
+ f"Reorder improved time! {new_time:.4f}s (was {old_best:.4f}s). New order: {self.current_sequence}",
488
+ )
489
+ else:
490
+ # Revert
491
+ self.current_sequence = old_sequence
492
+ self.episode_reward -= 0.05
493
+ return (
494
+ {
495
+ "reordered": False,
496
+ "improved": False,
497
+ "execution_time": new_time,
498
+ "best_time": self.best_time,
499
+ "current_sequence": list(self.current_sequence),
500
+ "sequence_length": len(self.current_sequence),
501
+ "steps_remaining": self.max_steps - self._state.step_count,
502
+ },
503
+ "reorder_reverted",
504
+ f"Reorder did NOT improve. Reverted. Time: {new_time:.4f}s vs best: {self.best_time:.4f}s",
505
+ )
506
+
507
  def _get_program_info(self):
508
  """Return program name and baselines."""
509
  return (