|
1 | | -import os, typing, hashlib, dataclasses |
| 1 | +import os, typing, dataclasses |
| 2 | +import re |
| 3 | +import pathlib |
| 4 | +import subprocess |
| 5 | +import tempfile |
2 | 6 |
|
3 | 7 | from .case import Case |
4 | 8 | from .printer import cons |
@@ -32,19 +36,81 @@ def compute(self) -> typing.Set: |
32 | 36 | def __hash__(self) -> int: |
33 | 37 | return hash(self.name) |
34 | 38 |
|
| 39 | + def get_compiler_info(self) -> str: |
| 40 | + with tempfile.TemporaryDirectory() as build_dir: |
| 41 | + subprocess.run( |
| 42 | + ["cmake", "-B", build_dir, "-S", ".", "-DCMAKE_VERBOSE_MAKEFILE=ON"], |
| 43 | + check=True, |
| 44 | + stdout=subprocess.DEVNULL, |
| 45 | + stderr=subprocess.DEVNULL, |
| 46 | + ) |
| 47 | + |
| 48 | + cache = pathlib.Path(build_dir) / "CMakeCache.txt" |
| 49 | + if not cache.exists(): |
| 50 | + return "unknown" |
| 51 | + |
| 52 | + pat = re.compile(r"CMAKE_.*_COMPILER:FILEPATH=(.+)", re.IGNORECASE) |
| 53 | + compiler_name = "" |
| 54 | + |
| 55 | + for line in cache.read_text(errors="ignore").splitlines(): |
| 56 | + if "fortran" in line.lower(): |
| 57 | + m = pat.search(line) |
| 58 | + if m: |
| 59 | + compiler_name = pathlib.Path(m.group(1).strip()).name |
| 60 | + break |
| 61 | + |
| 62 | + name = compiler_name.lower() |
| 63 | + if "gfortran" in name: |
| 64 | + return "gnu" |
| 65 | + if "ifort" in name or "ifx" in name: |
| 66 | + return "intel" |
| 67 | + if "nvfortran" in name: |
| 68 | + return "nvhpc" |
| 69 | + if name == "ftn" or "cray" in name: |
| 70 | + return "cray" |
| 71 | + if "pgfortran" in name: |
| 72 | + return "pgi" |
| 73 | + if "clang" in name: |
| 74 | + return "clang" |
| 75 | + if "flang" in name: |
| 76 | + return "flang" |
| 77 | + return "unknown" |
| 78 | + |
35 | 79 | def get_slug(self, case: Case ) -> str: |
36 | 80 | if self.isDependency: |
37 | 81 | return self.name |
38 | 82 |
|
39 | | - m = hashlib.sha256() |
40 | | - m.update(self.name.encode()) |
41 | | - m.update(CFG().make_slug().encode()) |
42 | | - m.update(case.get_fpp(self, False).encode()) |
43 | | - |
| 83 | + # Start with target name |
| 84 | + parts = [self.name] |
| 85 | + |
| 86 | + # Add active configuration options |
| 87 | + cfg = CFG() |
| 88 | + cfg_parts = [] |
| 89 | + for key, value in sorted(cfg.items()): |
| 90 | + if value: # Only include enabled options |
| 91 | + cfg_parts.append(key) |
| 92 | + |
| 93 | + if cfg_parts: |
| 94 | + parts.append('-'.join(cfg_parts)) |
| 95 | + |
| 96 | + # Add chemistry info if enabled |
44 | 97 | if case.params.get('chemistry', 'F') == 'T': |
45 | | - m.update(case.get_cantera_solution().name.encode()) |
46 | | - |
47 | | - return m.hexdigest()[:10] |
| 98 | + parts.append(f"chem-{case.get_cantera_solution().name}") |
| 99 | + |
| 100 | + # Add case optimization if enabled |
| 101 | + if case.params.get('case_optimization', False): |
| 102 | + parts.append('opt') |
| 103 | + |
| 104 | + # Add compiler identifier |
| 105 | + try: |
| 106 | + compiler_id = self.get_compiler_info() |
| 107 | + if compiler_id and compiler_id != 'unknown': |
| 108 | + parts.append(f"fc-{compiler_id}") |
| 109 | + except: |
| 110 | + parts.append(f"fc-unknown") |
| 111 | + |
| 112 | + # Join all parts with underscores |
| 113 | + return '_'.join(parts) |
48 | 114 |
|
49 | 115 | # Get path to directory that will store the build files |
50 | 116 | def get_staging_dirpath(self, case: Case ) -> str: |
|
0 commit comments