Skip to content

Commit 240a527

Browse files
Add Driver build, Nets-Validation and CodeQL (#51)
* Add Driver build * Refactoring * Introduce Nets-Validation * Add more models * Refactoring * Divided u22 and u24 * Pin dependencies * Add CodeQL scan * Pin deps * Fix env setup
1 parent ea47b47 commit 240a527

33 files changed

+3561
-361
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
name: 'Compile Models'
2+
description: 'Compile models for NPU'
3+
4+
inputs:
5+
compiler-type:
6+
description: 'MLIR|DRIVER'
7+
type: string
8+
required: true
9+
npu-platform:
10+
description: 'NPU.XXXX'
11+
type: string
12+
required: true
13+
install-package-dir:
14+
description: 'OV|Driver build artifacts with compile_tool and NPU compiler libs'
15+
type: string
16+
required: true
17+
models-dir:
18+
description: 'Path to a directory with downloaded models'
19+
type: string
20+
required: true
21+
blobs-dir:
22+
description: 'Path to a directory where to save model compilation logs'
23+
type: string
24+
required: true
25+
models-config:
26+
description: 'Path to models config'
27+
type: string
28+
required: true
29+
logs-dir:
30+
description: 'Path to a directory where to save model compilation logs'
31+
type: string
32+
required: true
33+
34+
runs:
35+
using: 'composite'
36+
steps:
37+
- name: Install dependencies
38+
shell: bash
39+
run: |
40+
python3 -m pip install --upgrade pip
41+
python3 -m pip install -r ${{ github.action_path }}/requirements.txt
42+
43+
- name: Prepare OpenVINO environment
44+
if: ${{ inputs.compiler-type == 'MLIR' }}
45+
shell: bash
46+
run: |
47+
cat <<'EOF' > prepare_env.sh
48+
#!/usr/bin/env bash
49+
set -e
50+
INSTALL_PACKAGE_ABS_PATH=$(realpath ${{ inputs.install-package-dir }})
51+
source ${INSTALL_PACKAGE_ABS_PATH}/setupvars.sh
52+
export COMPILE_TOOL=${INSTALL_PACKAGE_ABS_PATH}/tools/compile_tool/compile_tool
53+
EOF
54+
INSTALL_PACKAGE_ABS_PATH=$(realpath ${{ inputs.install-package-dir }})
55+
chmod +x ${INSTALL_PACKAGE_ABS_PATH}/setupvars.sh
56+
chmod +x ${INSTALL_PACKAGE_ABS_PATH}/tools/compile_tool/compile_tool
57+
chmod +x prepare_env.sh
58+
59+
- name: Prepare Driver environment
60+
if: ${{ inputs.compiler-type == 'DRIVER' }}
61+
shell: bash
62+
run: |
63+
cat <<'EOF' > prepare_env.sh
64+
#!/usr/bin/env bash
65+
set -e
66+
if [[ "${{ inputs.npu-platform }}" == "NPU.3720" ]]; then
67+
PLATFORM="METEORLAKE"
68+
elif [[ "${{ inputs.npu-platform }}" == "NPU.4000" ]]; then
69+
PLATFORM="LUNARLAKE"
70+
else
71+
PLATFORM="not_valid_platform"
72+
fi
73+
INSTALL_PACKAGE_ABS_PATH=$(realpath ${{ inputs.install-package-dir }})
74+
export LD_LIBRARY_PATH=${INSTALL_PACKAGE_ABS_PATH}/usr/lib/:$LD_LIBRARY_PATH
75+
export ZE_INTEL_NPU_PLATFORM_OVERRIDE=${PLATFORM}
76+
export COMPILE_TOOL=${INSTALL_PACKAGE_ABS_PATH}/usr/bin/compile_tool
77+
EOF
78+
chmod +x prepare_env.sh
79+
80+
- name: Compile models for ${{ inputs.npu-platform }} with ${{ inputs.compiler-type }} compiler
81+
shell: bash
82+
run: |
83+
source prepare_env.sh
84+
python3 ${{ github.action_path }}/compile_models.py \
85+
--compiler-type "${{ inputs.compiler-type }}" \
86+
--compile-tool "${COMPILE_TOOL}" \
87+
--models-config "${{ inputs.models-config }}" \
88+
--models-dir "${{ inputs.models-dir }}" \
89+
--blobs-dir "${{ inputs.blobs-dir }}" \
90+
--logs-dir "${{ inputs.logs-dir }}"
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
"""
2+
Parses command line arguments
3+
"""
4+
5+
import argparse
6+
from pathlib import Path
7+
8+
9+
def parse_arguments():
10+
"""Parses command line arguments"""
11+
parser = argparse.ArgumentParser(
12+
description="Compiling AI models from different sources specified in a json config."
13+
)
14+
parser.add_argument(
15+
"--compiler-type",
16+
type=str,
17+
required=True,
18+
choices=["MLIR", "DRIVER"],
19+
help="MLIR|DRIVER",
20+
)
21+
parser.add_argument(
22+
"--compile-tool",
23+
type=Path,
24+
required=True,
25+
help="Path to the compile_tool executable",
26+
)
27+
parser.add_argument(
28+
"--models-config",
29+
type=Path,
30+
required=True,
31+
help="Path to a JSON configuration file describing models to validate",
32+
)
33+
parser.add_argument(
34+
"--models-dir",
35+
type=Path,
36+
required=True,
37+
help="Path to a directory with models to validate",
38+
)
39+
parser.add_argument(
40+
"--blobs-dir",
41+
type=Path,
42+
required=False,
43+
default=Path("./blobs"),
44+
help="Path to a directory to save compiled models",
45+
)
46+
parser.add_argument(
47+
"--configs-dir",
48+
type=Path,
49+
required=False,
50+
default=Path("./configs"),
51+
help="Path to a directory where to save compilation configs",
52+
)
53+
parser.add_argument(
54+
"--logs-dir",
55+
type=Path,
56+
required=False,
57+
default=Path("./logs"),
58+
help="Path to a directory where to save compilation logs",
59+
)
60+
parser.add_argument(
61+
"--jobs",
62+
type=int,
63+
required=False,
64+
default=4,
65+
help="Number of parallel jobs",
66+
)
67+
args = parser.parse_args()
68+
return args
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""
2+
Enums declaration
3+
"""
4+
5+
from enum import Enum
6+
7+
8+
class Status(Enum):
9+
"""Enum class defining possible compilation statuses"""
10+
11+
SUCCESS = 1
12+
SKIPPED = 2
13+
DISABLED = 3
14+
FAILED = 4
15+
TIMEOUT = 5
16+
MODEL_NOT_FOUND = 6
17+
18+
@classmethod
19+
def get_ok_statuses(cls):
20+
"""Returns a set of statuses that don't throw an error"""
21+
return {cls.SUCCESS, cls.SKIPPED, cls.DISABLED}
22+
23+
@classmethod
24+
def get_error_statuses(cls):
25+
"""Returns a set of statuses that causes the script to fail"""
26+
return {cls.FAILED, cls.TIMEOUT, cls.MODEL_NOT_FOUND}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""
2+
Declares and configures loggers
3+
"""
4+
5+
import logging
6+
7+
8+
def setup_thread_file_logger(logs_dir: str, log_file_name: str) -> logging.Logger:
9+
"""Configures and returns a thread-safe file-based logger"""
10+
logger = logging.getLogger(f"logger_{log_file_name}")
11+
logger.setLevel(logging.INFO)
12+
logger.propagate = False
13+
logger.handlers.clear()
14+
15+
log_file_path = logs_dir / f"{log_file_name}.log"
16+
log_file_path.parent.mkdir(parents=True, exist_ok=True)
17+
file_handler = logging.FileHandler(log_file_path, encoding="utf-8")
18+
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
19+
file_handler.setFormatter(formatter)
20+
21+
logger.addHandler(file_handler)
22+
return logger
23+
24+
25+
def setup_console_logger() -> logging.Logger:
26+
"""Configures and returns a console logger"""
27+
logger = logging.getLogger("console_logger")
28+
logger.setLevel(logging.INFO)
29+
logger.propagate = False
30+
logger.handlers.clear()
31+
32+
console_handler = logging.StreamHandler()
33+
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
34+
console_handler.setFormatter(formatter)
35+
36+
logger.addHandler(console_handler)
37+
return logger
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"""
2+
compile-models library helpers
3+
"""
4+
5+
import json
6+
import logging
7+
from collections import Counter
8+
from pathlib import Path
9+
10+
from common.enums import Status
11+
12+
13+
def read_models_from_config(models_config: Path, logger: logging.Logger) -> list:
14+
"""Parses a JSON config and returns a list of model configs as dictionaries"""
15+
with open(models_config, "r", encoding="utf-8") as f:
16+
config = json.load(f)
17+
models = config.get("models", [])
18+
return models
19+
20+
21+
def write_extra_config(args: dict, model: dict) -> tuple:
22+
"""Writes key-value pairs to compile_tool extra config"""
23+
extra_config_path = args.configs_dir / f"{model.get('name')}_config.conf"
24+
extra_config_path.parent.mkdir(parents=True, exist_ok=True)
25+
26+
lines = [f"{key} {value}\n" for key, value in model.get("extra_config", "").items()]
27+
content = "".join(lines)
28+
with open(extra_config_path, "w", encoding="utf-8") as f:
29+
f.write(content)
30+
return extra_config_path, content
31+
32+
33+
def analyze_results(compilation_results: dict, logger: logging.Logger) -> Status:
34+
"""Prints compile_tool statistics across all configured models"""
35+
for model_name, result in compilation_results.items():
36+
if result in Status.get_ok_statuses():
37+
logger.info("%s - %s", result, model_name)
38+
else:
39+
logger.error("%s - %s", result, model_name)
40+
logger.info("Compilation summary:")
41+
counter = Counter(compilation_results.values())
42+
for status in Status:
43+
logger.info("\t%s: %d", status.name, counter.get(status, 0))
44+
if any(counter.get(status, 0) for status in Status.get_error_statuses()):
45+
return Status.FAILED
46+
return Status.SUCCESS

0 commit comments

Comments
 (0)