|
34 | 34 | from intelliperf.utils import process |
35 | 35 | from intelliperf.utils.env import ( |
36 | 36 | get_guided_tuning_path, |
37 | | - get_nexus_path, |
38 | 37 | get_rocprofiler_path, |
39 | 38 | ) |
40 | 39 | from intelliperf.utils.process import capture_subprocess_output, exit_on_fail |
@@ -224,26 +223,65 @@ def clone(self): |
224 | 223 | ) |
225 | 224 |
|
226 | 225 | def collect_source_code(self): |
227 | | - nexus_directory = get_nexus_path() |
228 | | - lib = os.path.join(nexus_directory, "build", "lib", "libnexus.so") |
229 | | - env = os.environ.copy() |
230 | | - |
231 | | - with tempfile.TemporaryDirectory() as tmp: |
232 | | - json_result_file = os.path.join(tmp, "nexus_output.json") |
233 | | - |
234 | | - env["HSA_TOOLS_LIB"] = lib |
235 | | - env["NEXUS_LOG_LEVEL"] = "2" |
236 | | - env["NEXUS_OUTPUT_FILE"] = json_result_file |
237 | | - env["TRITON_ALWAYS_COMPILE"] = "1" |
238 | | - env["TRITON_DISABLE_LINE_INFO"] = "0" |
239 | | - capture_subprocess_output(self.get_app_cmd(), new_env=env, working_directory=self.get_project_directory()) |
240 | | - |
241 | | - if os.path.exists(json_result_file): |
242 | | - df_results = json.loads(open(json_result_file).read()) |
| 226 | + """ |
| 227 | + Collect source code for GPU kernels using Nexus. |
| 228 | +
|
| 229 | + Returns: |
| 230 | + dict: Dictionary containing kernel information with assembly, HIP source, files, and line numbers |
| 231 | + """ |
| 232 | + try: |
| 233 | + from nexus import Nexus |
| 234 | + except ImportError: |
| 235 | + logging.error("Nexus Python API not found. Please install it: pip install git+https://github.com/AMDResearch/nexus.git@main") |
| 236 | + return {"kernels": {}} |
| 237 | + |
| 238 | + try: |
| 239 | + # Map Python logging level to Nexus log level |
| 240 | + # Python: NOTSET=0, DEBUG=10, INFO=20, WARNING=30, ERROR=40, CRITICAL=50 |
| 241 | + # Nexus: 0=none, 1=info, 2=warning, 3=error, 4=detail |
| 242 | + current_level = logging.getLogger().getEffectiveLevel() |
| 243 | + if current_level <= logging.DEBUG: |
| 244 | + nexus_log_level = 4 # detail (most verbose) |
| 245 | + elif current_level <= logging.INFO: |
| 246 | + nexus_log_level = 1 # info |
| 247 | + elif current_level <= logging.WARNING: |
| 248 | + nexus_log_level = 2 # warning |
243 | 249 | else: |
244 | | - df_results = {"kernels": {}} |
| 250 | + nexus_log_level = 0 # none |
| 251 | + |
| 252 | + # Create Nexus tracer with inherited log level |
| 253 | + nexus = Nexus(log_level=nexus_log_level) |
| 254 | + |
| 255 | + # Additional environment for Triton kernels |
| 256 | + triton_env = { |
| 257 | + "TRITON_ALWAYS_COMPILE": "1", |
| 258 | + "TRITON_DISABLE_LINE_INFO": "0", |
| 259 | + } |
| 260 | + |
| 261 | + # Run the application and capture kernel trace |
| 262 | + trace = nexus.run( |
| 263 | + command=self.get_app_cmd(), |
| 264 | + env=triton_env, |
| 265 | + cwd=self.get_project_directory(), |
| 266 | + ) |
| 267 | + |
| 268 | + # Convert trace to the expected format |
| 269 | + df_results = {"kernels": {}} |
| 270 | + for kernel in trace: |
| 271 | + df_results["kernels"][kernel.name] = { |
| 272 | + "assembly": kernel.assembly, |
| 273 | + "hip": kernel.hip, |
| 274 | + "files": kernel.files, |
| 275 | + "lines": kernel.lines, |
| 276 | + "signature": kernel.signature, |
| 277 | + } |
| 278 | + |
245 | 279 | return df_results |
246 | 280 |
|
| 281 | + except Exception as e: |
| 282 | + logging.error(f"Failed to collect source code with Nexus: {e}") |
| 283 | + return {"kernels": {}} |
| 284 | + |
247 | 285 | def get_binary_absolute_path(self): |
248 | 286 | if self.get_project_directory() != "": |
249 | 287 | binary = self.get_app_cmd_without_args() |
|
0 commit comments