Repository: quic/efficient-transformers
Pull request #379: [Bug Fix]: qpc sdk config dump issue fixing
Author: login: abukhoy
Labels: name: 1.20.0
Created: 2025-04-23T09:16:13Z | Merged: 2025-05-08T17:51:12Z

This PR addresses an issue causing the qconfig dump to fail when QAIC is not installed but QNN is present. With this update, the qconfig will be successfully dumped in both QAIC and QNN environments.


Diff:
diff --git a/QEfficient/utils/_utils.py b/QEfficient/utils/_utils.py
index b6af66be5..564bdd94d 100644
--- a/QEfficient/utils/_utils.py
+++ b/QEfficient/utils/_utils.py
@@ -521,27 +521,57 @@ def __repr__(self):
 def dump_qconfig(func):
     def wrapper(self, *args, **kwargs):
         result = func(self, *args, **kwargs)
-        create_and_dump_qconfigs(
-            self.qpc_path,
-            self.onnx_path,
-            self.get_model_config,
-            [cls.__name__ for cls in self._pytorch_transforms],
-            [cls.__name__ for cls in self._onnx_transforms],
-            kwargs.get("specializations"),
-            kwargs.get("mdp_ts_num_devices", 1),
-            kwargs.get("num_speculative_tokens"),
-            **{
-                k: v
-                for k, v in kwargs.items()
-                if k
-                not in ["specializations", "mdp_ts_num_devices", "num_speculative_tokens", "custom_io", "onnx_path"]
-            },
-        )
+        try:
+            create_and_dump_qconfigs(
+                self.qpc_path,
+                self.onnx_path,
+                self.get_model_config,
+                [cls.__name__ for cls in self._pytorch_transforms],
+                [cls.__name__ for cls in self._onnx_transforms],
+                kwargs.get("specializations"),
+                kwargs.get("mdp_ts_num_devices", 1),
+                kwargs.get("num_speculative_tokens"),
+                **{
+                    k: v
+                    for k, v in kwargs.items()
+                    if k
+                    not in ["specializations", "mdp_ts_num_devices", "num_speculative_tokens", "custom_io", "onnx_path"]
+                },
+            )
+        except Exception as e:
+            print(f"An unexpected error occurred while dumping the qconfig: {e}")
         return result
 
     return wrapper
 
 
+def get_qaic_sdk_version(qaic_sdk_xml_path: str) -> Optional[str]:
+    """
+    Extracts the QAIC SDK version from the given SDK XML file.
+
+    Args:
+        qaic_sdk_xml_path (str): Path to the SDK XML file.
+    Returns:
+        The SDK version as a string if found, otherwise None.
+    """
+    qaic_sdk_version = None
+
+    # Check and extract version from the given SDK XML file
+    if os.path.exists(qaic_sdk_xml_path):
+        try:
+            tree = ET.parse(qaic_sdk_xml_path)
+            root = tree.getroot()
+            base_version_element = root.find(".//base_version")
+            if base_version_element is not None:
+                qaic_sdk_version = base_version_element.text
+        except ET.ParseError as e:
+            print(f"Error parsing XML file {qaic_sdk_xml_path}: {e}")
+        except Exception as e:
+            print(f"An unexpected error occurred while processing {qaic_sdk_xml_path}: {e}")
+
+    return qaic_sdk_version
+
+
 def create_and_dump_qconfigs(
     qpc_path,
     onnx_path,
@@ -558,29 +588,12 @@ def create_and_dump_qconfigs(
     Such as huggingface configs, QEff transforms, QAIC sdk version, QNN sdk, compilation dir, qpc dir and
     many other compilation options.
     """
-    qnn_config = compiler_options["qnn_config"] if "qnn_config" in compiler_options else None
-    enable_qnn = True if "qnn_config" in compiler_options else None
-
+    enable_qnn = compiler_options.get("enable_qnn", False)
+    qnn_config_path = compiler_options.get("qnn_config", None)
     qconfig_file_path = os.path.join(os.path.dirname(qpc_path), "qconfig.json")
     onnx_path = str(onnx_path)
     specializations_file_path = str(os.path.join(os.path.dirname(qpc_path), "specializations.json"))
     compile_dir = str(os.path.dirname(qpc_path))
-    qnn_config_path = (
-        (qnn_config if qnn_config is not None else "QEfficient/compile/qnn_config.json") if enable_qnn else None
-    )
-
-    # Extract QAIC SDK Apps Version from SDK XML file
-    tree = ET.parse(Constants.SDK_APPS_XML)
-    root = tree.getroot()
-    qaic_version = root.find(".//base_version").text
-
-    # Extract QNN SDK details from YAML file if the environment variable is set
-    qnn_sdk_details = None
-    qnn_sdk_path = os.getenv(QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME)
-    if enable_qnn and qnn_sdk_path:
-        qnn_sdk_yaml_path = os.path.join(qnn_sdk_path, QnnConstants.QNN_SDK_YAML)
-        with open(qnn_sdk_yaml_path, "r") as file:
-            qnn_sdk_details = yaml.safe_load(file)
 
     # Ensure all objects in the configs dictionary are JSON serializable
     def make_serializable(obj):
@@ -602,29 +615,38 @@ def make_serializable(obj):
                 "onnx_transforms": make_serializable(onnx_transforms),
                 "onnx_path": onnx_path,
             },
+            "compiler_config": {
+                "enable_qnn": enable_qnn,
+                "compile_dir": compile_dir,
+                "specializations_file_path": specializations_file_path,
+                "specializations": make_serializable(specializations),
+                "mdp_ts_num_devices": mdp_ts_num_devices,
+                "num_speculative_tokens": num_speculative_tokens,
+                **compiler_options,
+            },
+            "aic_sdk_config": {
+                "qaic_apps_version": get_qaic_sdk_version(Constants.SDK_APPS_XML),
+                "qaic_platform_version": get_qaic_sdk_version(Constants.SDK_PLATFORM_XML),
+            },
         },
     }
 
-    aic_compiler_config = {
-        "apps_sdk_version": qaic_version,
-        "compile_dir": compile_dir,
-        "specializations_file_path": specializations_file_path,
-        "specializations": make_serializable(specializations),
-        "mdp_ts_num_devices": mdp_ts_num_devices,
-        "num_speculative_tokens": num_speculative_tokens,
-        **compiler_options,
-    }
-    qnn_config = {
-        "enable_qnn": enable_qnn,
-        "qnn_config_path": qnn_config_path,
-    }
-    # Put AIC or qnn details.
     if enable_qnn:
+        qnn_sdk_path = os.getenv(QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME)
+        if not qnn_sdk_path:
+            raise EnvironmentError(
+                f"QNN_SDK_PATH {qnn_sdk_path} is not set. Please set {QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME}"
+            )
+        qnn_sdk_yaml_path = os.path.join(qnn_sdk_path, QnnConstants.QNN_SDK_YAML)
+        qnn_sdk_details = load_yaml(
+            qnn_sdk_yaml_path
+        )  # Extract QNN SDK details from YAML file if the environment variable is set
+        qnn_config = {
+            "qnn_config_path": qnn_config_path,
+        }
         qconfigs["qpc_config"]["qnn_config"] = qnn_config
         if qnn_sdk_details:
             qconfigs["qpc_config"]["qnn_config"].update(qnn_sdk_details)
-    else:
-        qconfigs["qpc_config"]["aic_compiler_config"] = aic_compiler_config
 
     create_json(qconfig_file_path, qconfigs)
 
diff --git a/QEfficient/utils/constants.py b/QEfficient/utils/constants.py
index b1ff9701e..c8f74907a 100644
--- a/QEfficient/utils/constants.py
+++ b/QEfficient/utils/constants.py
@@ -97,7 +97,10 @@ class Constants:
     MAX_QPC_LIMIT = 30
     MAX_RETRIES = 10  # This constant will be used set the maximum number of retry attempts for downloading a model using huggingface_hub snapshot_download
     NUM_SPECULATIVE_TOKENS = 2
-    SDK_APPS_XML = "/opt/qti-aic/versions/apps.xml"  # This xml file is parsed to find out the SDK version.
+    SDK_APPS_XML = "/opt/qti-aic/versions/apps.xml"  # This xml file is parsed to find out the SDK apps version.
+    SDK_PLATFORM_XML = (
+        "/opt/qti-aic/versions/platform.xml"  # This xml file is parsed to find out the SDK platform version.
+    )
 
 
 @dataclass


Reviews:
user: login: asmigosw
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-24T12:15:46Z
user: login: quic-rishinr
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-25T04:04:10Z
user: login: abukhoy
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-25T05:21:05Z
user: login: abukhoy
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-25T05:23:45Z
user: login: quic-rishinr
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-28T17:38:18Z
user: login: abukhoy
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-30T08:14:55Z
user: login: quic-rishinr
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T14:31:42Z
user: login: abukhoy
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T06:19:32Z
user: login: asmigosw
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T06:23:39Z
user: login: shubhagr-qc
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T05:43:15Z
user: login: quic-hemagnih
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T10:07:26Z
user: login: quic-rishinr
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T15:54:21Z
user: login: asmigosw
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T16:01:17Z

Review comments:
diff_hunk: @@ -538,25 +525,49 @@ def make_serializable(obj):
         },
     }
 
-    aic_compiler_config = {
-        "apps_sdk_version": qaic_version,
-        "compile_dir": compile_dir,
-        "specializations_file_path": specializations_file_path,
-        "specializations": make_serializable(specializations),
-        "mdp_ts_num_devices": mdp_ts_num_devices,
-        "num_speculative_tokens": num_speculative_tokens,
-        **compiler_options,
-    }
-    qnn_config = {
-        "enable_qnn": enable_qnn,
-        "qnn_config_path": qnn_config_path,
-    }
-    # Put AIC or qnn details.
     if enable_qnn:
+        # Extract QNN SDK details from YAML file if the environment variable is set
+        qnn_sdk_path = os.getenv(QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME)
+        if not qnn_sdk_path:
+            raise EnvironmentError(
+                f"QNN_SDK_PATH {qnn_sdk_path} is not set. Please set {QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME}"
+            )
+        qnn_sdk_yaml_path = os.path.join(qnn_sdk_path, QnnConstants.QNN_SDK_YAML)
+        with open(qnn_sdk_yaml_path, "r") as file:
+            qnn_sdk_details = yaml.safe_load(file)
path: QEfficient/utils/_utils.py
user: login: asmigosw
body: `qnn_sdk_details` is not declared earlier, what if `qnn_sdk_yaml_path` is None, then this variable will not be initialized and will give error at line 544. Please declare `qnn_sdk_details = None` before file open.
created_at: 2025-04-24T12:13:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -538,25 +525,49 @@ def make_serializable(obj):
         },
     }
 
-    aic_compiler_config = {
-        "apps_sdk_version": qaic_version,
-        "compile_dir": compile_dir,
-        "specializations_file_path": specializations_file_path,
-        "specializations": make_serializable(specializations),
-        "mdp_ts_num_devices": mdp_ts_num_devices,
-        "num_speculative_tokens": num_speculative_tokens,
-        **compiler_options,
-    }
-    qnn_config = {
-        "enable_qnn": enable_qnn,
-        "qnn_config_path": qnn_config_path,
-    }
-    # Put AIC or qnn details.
     if enable_qnn:
+        # Extract QNN SDK details from YAML file if the environment variable is set
+        qnn_sdk_path = os.getenv(QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME)
+        if not qnn_sdk_path:
+            raise EnvironmentError(
+                f"QNN_SDK_PATH {qnn_sdk_path} is not set. Please set {QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME}"
+            )
+        qnn_sdk_yaml_path = os.path.join(qnn_sdk_path, QnnConstants.QNN_SDK_YAML)
+        with open(qnn_sdk_yaml_path, "r") as file:
+            qnn_sdk_details = yaml.safe_load(file)
+
+        qnn_config = {
+            "enable_qnn": enable_qnn,
+            "qnn_config_path": qnn_config_path,
+        }
         qconfigs["qpc_config"]["qnn_config"] = qnn_config
         if qnn_sdk_details:
             qconfigs["qpc_config"]["qnn_config"].update(qnn_sdk_details)
+
     else:
+        # Extract QAIC SDK Apps or Platform Version from SDK XML file
+        sdk_xml_file = (
+            Constants.SDK_APPS_XML
+            if os.path.exists(Constants.SDK_APPS_XML)
+            else Constants.SDK_PLATFORM_XML
+            if os.path.exists(Constants.SDK_PLATFORM_XML)
+            else None
+        )
+        qaic_version = None
+        if sdk_xml_file is not None:
path: QEfficient/utils/_utils.py
user: login: asmigosw
body: What if `sdk_xml_file` is None?
created_at: 2025-04-24T12:14:00Z
author_association: CONTRIBUTOR
diff_hunk: @@ -492,7 +492,7 @@ def create_and_dump_qconfigs(
     many other compilation options.
     """
     qnn_config = compiler_options["qnn_config"] if "qnn_config" in compiler_options else None
-    enable_qnn = True if "qnn_config" in compiler_options else None
+    enable_qnn = True if "qnn_config" in compiler_options else False
path: QEfficient/utils/_utils.py
user: login: quic-rishinr
body: are we supposed to check 'qnn_config' or 'enable_qnn' compiler_options here? we set enable_qnn flag for switching between qnn and qaic workflow. qnn_config is an optional parameter. 
created_at: 2025-04-25T03:50:42Z
author_association: CONTRIBUTOR
diff_hunk: @@ -492,7 +492,7 @@ def create_and_dump_qconfigs(
     many other compilation options.
     """
     qnn_config = compiler_options["qnn_config"] if "qnn_config" in compiler_options else None
path: QEfficient/utils/_utils.py
user: login: quic-rishinr
body: you can replace it as compiler_options.get("qnn_config", None) 
created_at: 2025-04-25T03:51:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -538,25 +525,49 @@ def make_serializable(obj):
         },
     }
 
-    aic_compiler_config = {
-        "apps_sdk_version": qaic_version,
-        "compile_dir": compile_dir,
-        "specializations_file_path": specializations_file_path,
-        "specializations": make_serializable(specializations),
-        "mdp_ts_num_devices": mdp_ts_num_devices,
-        "num_speculative_tokens": num_speculative_tokens,
-        **compiler_options,
-    }
-    qnn_config = {
-        "enable_qnn": enable_qnn,
-        "qnn_config_path": qnn_config_path,
-    }
-    # Put AIC or qnn details.
     if enable_qnn:
+        # Extract QNN SDK details from YAML file if the environment variable is set
+        qnn_sdk_path = os.getenv(QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME)
+        if not qnn_sdk_path:
+            raise EnvironmentError(
+                f"QNN_SDK_PATH {qnn_sdk_path} is not set. Please set {QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME}"
+            )
+        qnn_sdk_yaml_path = os.path.join(qnn_sdk_path, QnnConstants.QNN_SDK_YAML)
+        with open(qnn_sdk_yaml_path, "r") as file:
path: QEfficient/utils/_utils.py
user: login: quic-rishinr
body: better to create a load yaml method. Check if the file is available, add proper exception handling and load the yaml file. if there is an uncaught exception in this method it will impact the complete run. 
created_at: 2025-04-25T03:56:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -538,25 +525,49 @@ def make_serializable(obj):
         },
     }
 
-    aic_compiler_config = {
-        "apps_sdk_version": qaic_version,
-        "compile_dir": compile_dir,
-        "specializations_file_path": specializations_file_path,
-        "specializations": make_serializable(specializations),
-        "mdp_ts_num_devices": mdp_ts_num_devices,
-        "num_speculative_tokens": num_speculative_tokens,
-        **compiler_options,
-    }
-    qnn_config = {
-        "enable_qnn": enable_qnn,
-        "qnn_config_path": qnn_config_path,
-    }
-    # Put AIC or qnn details.
     if enable_qnn:
+        # Extract QNN SDK details from YAML file if the environment variable is set
+        qnn_sdk_path = os.getenv(QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME)
+        if not qnn_sdk_path:
+            raise EnvironmentError(
+                f"QNN_SDK_PATH {qnn_sdk_path} is not set. Please set {QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME}"
+            )
+        qnn_sdk_yaml_path = os.path.join(qnn_sdk_path, QnnConstants.QNN_SDK_YAML)
+        with open(qnn_sdk_yaml_path, "r") as file:
+            qnn_sdk_details = yaml.safe_load(file)
+
+        qnn_config = {
+            "enable_qnn": enable_qnn,
+            "qnn_config_path": qnn_config_path,
+        }
         qconfigs["qpc_config"]["qnn_config"] = qnn_config
         if qnn_sdk_details:
             qconfigs["qpc_config"]["qnn_config"].update(qnn_sdk_details)
+
     else:
+        # Extract QAIC SDK Apps or Platform Version from SDK XML file
+        sdk_xml_file = (
path: QEfficient/utils/_utils.py
user: login: quic-rishinr
body: 1. create a method for fetching the apps and platform sdk. 
2. Its better to capture platform sdk as well if its installed. it will be useful while debugging
created_at: 2025-04-25T04:01:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -538,25 +525,49 @@ def make_serializable(obj):
         },
     }
 
-    aic_compiler_config = {
-        "apps_sdk_version": qaic_version,
-        "compile_dir": compile_dir,
-        "specializations_file_path": specializations_file_path,
-        "specializations": make_serializable(specializations),
-        "mdp_ts_num_devices": mdp_ts_num_devices,
-        "num_speculative_tokens": num_speculative_tokens,
-        **compiler_options,
-    }
-    qnn_config = {
-        "enable_qnn": enable_qnn,
-        "qnn_config_path": qnn_config_path,
-    }
-    # Put AIC or qnn details.
     if enable_qnn:
+        # Extract QNN SDK details from YAML file if the environment variable is set
+        qnn_sdk_path = os.getenv(QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME)
+        if not qnn_sdk_path:
+            raise EnvironmentError(
+                f"QNN_SDK_PATH {qnn_sdk_path} is not set. Please set {QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME}"
+            )
+        qnn_sdk_yaml_path = os.path.join(qnn_sdk_path, QnnConstants.QNN_SDK_YAML)
+        with open(qnn_sdk_yaml_path, "r") as file:
+            qnn_sdk_details = yaml.safe_load(file)
+
+        qnn_config = {
+            "enable_qnn": enable_qnn,
+            "qnn_config_path": qnn_config_path,
+        }
         qconfigs["qpc_config"]["qnn_config"] = qnn_config
         if qnn_sdk_details:
             qconfigs["qpc_config"]["qnn_config"].update(qnn_sdk_details)
+
     else:
+        # Extract QAIC SDK Apps or Platform Version from SDK XML file
+        sdk_xml_file = (
+            Constants.SDK_APPS_XML
+            if os.path.exists(Constants.SDK_APPS_XML)
+            else Constants.SDK_PLATFORM_XML
+            if os.path.exists(Constants.SDK_PLATFORM_XML)
+            else None
+        )
+        qaic_version = None
+        if sdk_xml_file is not None:
+            tree = ET.parse(sdk_xml_file)
+            root = tree.getroot()
+            qaic_version = root.find(".//base_version").text
+
+        aic_compiler_config = {
path: QEfficient/utils/_utils.py
user: login: quic-rishinr
body: These details will not be captured while qnn is enabled. Which is not correct. its better to keep sdk check and others outside as we had done it earlier. if SDK are installed, we will capture that
created_at: 2025-04-25T04:04:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -492,7 +492,7 @@ def create_and_dump_qconfigs(
     many other compilation options.
     """
     qnn_config = compiler_options["qnn_config"] if "qnn_config" in compiler_options else None
-    enable_qnn = True if "qnn_config" in compiler_options else None
+    enable_qnn = True if "qnn_config" in compiler_options else False
path: QEfficient/utils/_utils.py
user: login: abukhoy
body: But this` qconfig_dump` function is being called from `QEFFBaseModel`'s `_compile` method in which we have `qnn_config` and  `enable_qnn` params. Here, we need for dumping the specific configs whether it is aic or qnn.

created_at: 2025-04-25T05:21:05Z
author_association: CONTRIBUTOR
diff_hunk: @@ -538,25 +525,49 @@ def make_serializable(obj):
         },
     }
 
-    aic_compiler_config = {
-        "apps_sdk_version": qaic_version,
-        "compile_dir": compile_dir,
-        "specializations_file_path": specializations_file_path,
-        "specializations": make_serializable(specializations),
-        "mdp_ts_num_devices": mdp_ts_num_devices,
-        "num_speculative_tokens": num_speculative_tokens,
-        **compiler_options,
-    }
-    qnn_config = {
-        "enable_qnn": enable_qnn,
-        "qnn_config_path": qnn_config_path,
-    }
-    # Put AIC or qnn details.
     if enable_qnn:
+        # Extract QNN SDK details from YAML file if the environment variable is set
+        qnn_sdk_path = os.getenv(QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME)
+        if not qnn_sdk_path:
+            raise EnvironmentError(
+                f"QNN_SDK_PATH {qnn_sdk_path} is not set. Please set {QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME}"
+            )
+        qnn_sdk_yaml_path = os.path.join(qnn_sdk_path, QnnConstants.QNN_SDK_YAML)
+        with open(qnn_sdk_yaml_path, "r") as file:
+            qnn_sdk_details = yaml.safe_load(file)
+
+        qnn_config = {
+            "enable_qnn": enable_qnn,
+            "qnn_config_path": qnn_config_path,
+        }
         qconfigs["qpc_config"]["qnn_config"] = qnn_config
         if qnn_sdk_details:
             qconfigs["qpc_config"]["qnn_config"].update(qnn_sdk_details)
+
     else:
+        # Extract QAIC SDK Apps or Platform Version from SDK XML file
+        sdk_xml_file = (
+            Constants.SDK_APPS_XML
+            if os.path.exists(Constants.SDK_APPS_XML)
+            else Constants.SDK_PLATFORM_XML
+            if os.path.exists(Constants.SDK_PLATFORM_XML)
+            else None
+        )
+        qaic_version = None
+        if sdk_xml_file is not None:
path: QEfficient/utils/_utils.py
user: login: abukhoy
body: Then `aic_version` would be None.
created_at: 2025-04-25T05:23:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -492,7 +492,7 @@ def create_and_dump_qconfigs(
     many other compilation options.
     """
     qnn_config = compiler_options["qnn_config"] if "qnn_config" in compiler_options else None
-    enable_qnn = True if "qnn_config" in compiler_options else None
+    enable_qnn = True if "qnn_config" in compiler_options else False
path: QEfficient/utils/_utils.py
user: login: quic-rishinr
body: Agree. But QNN is enabled by passing enable_qnn flag. Qnn_config is an optional param. if its passed we need to add it to the configs. But in this case if the qnn_config is None and enable_qnn is true we would not be creating the qnn config. 
created_at: 2025-04-28T17:38:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -538,25 +525,49 @@ def make_serializable(obj):
         },
     }
 
-    aic_compiler_config = {
-        "apps_sdk_version": qaic_version,
-        "compile_dir": compile_dir,
-        "specializations_file_path": specializations_file_path,
-        "specializations": make_serializable(specializations),
-        "mdp_ts_num_devices": mdp_ts_num_devices,
-        "num_speculative_tokens": num_speculative_tokens,
-        **compiler_options,
-    }
-    qnn_config = {
-        "enable_qnn": enable_qnn,
-        "qnn_config_path": qnn_config_path,
-    }
-    # Put AIC or qnn details.
     if enable_qnn:
+        # Extract QNN SDK details from YAML file if the environment variable is set
+        qnn_sdk_path = os.getenv(QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME)
+        if not qnn_sdk_path:
+            raise EnvironmentError(
+                f"QNN_SDK_PATH {qnn_sdk_path} is not set. Please set {QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME}"
+            )
+        qnn_sdk_yaml_path = os.path.join(qnn_sdk_path, QnnConstants.QNN_SDK_YAML)
+        with open(qnn_sdk_yaml_path, "r") as file:
+            qnn_sdk_details = yaml.safe_load(file)
+
+        qnn_config = {
+            "enable_qnn": enable_qnn,
+            "qnn_config_path": qnn_config_path,
+        }
         qconfigs["qpc_config"]["qnn_config"] = qnn_config
         if qnn_sdk_details:
             qconfigs["qpc_config"]["qnn_config"].update(qnn_sdk_details)
+
     else:
+        # Extract QAIC SDK Apps or Platform Version from SDK XML file
+        sdk_xml_file = (
+            Constants.SDK_APPS_XML
+            if os.path.exists(Constants.SDK_APPS_XML)
+            else Constants.SDK_PLATFORM_XML
+            if os.path.exists(Constants.SDK_PLATFORM_XML)
+            else None
+        )
+        qaic_version = None
+        if sdk_xml_file is not None:
+            tree = ET.parse(sdk_xml_file)
+            root = tree.getroot()
+            qaic_version = root.find(".//base_version").text
+
+        aic_compiler_config = {
path: QEfficient/utils/_utils.py
user: login: abukhoy
body: `aic_compiler_config` only for qaic not for qnn, earlier also it was same. If I need to change something, please let me know.
created_at: 2025-04-30T08:14:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -495,6 +495,23 @@ def wrapper(self, *args, **kwargs):
     return wrapper
 
 
+def get_qaic_sdk_version():
+    # Extract QAIC SDK Apps or Platform Version from SDK XML file
+    sdk_xml_file = (
path: QEfficient/utils/_utils.py
user: login: quic-rishinr
body: platform and apps sdk can be different. This method should return both
created_at: 2025-05-06T14:20:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -495,6 +495,23 @@ def wrapper(self, *args, **kwargs):
     return wrapper
 
 
+def get_qaic_sdk_version():
+    # Extract QAIC SDK Apps or Platform Version from SDK XML file
+    sdk_xml_file = (
+        Constants.SDK_APPS_XML
+        if os.path.exists(Constants.SDK_APPS_XML)
+        else Constants.SDK_PLATFORM_XML
+        if os.path.exists(Constants.SDK_PLATFORM_XML)
+        else None
+    )
+    qaic_version = None
+    if sdk_xml_file is not None:
+        tree = ET.parse(sdk_xml_file)
+        root = tree.getroot()
+        qaic_version = root.find(".//base_version").text
path: QEfficient/utils/_utils.py
user: login: quic-rishinr
body: if its not able to find ".//base_version" it would cause an attribute error while trying to access .text. check if root.find(".//base_version") is not none and then call .text
created_at: 2025-05-06T14:22:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -495,6 +495,23 @@ def wrapper(self, *args, **kwargs):
     return wrapper
 
 
+def get_qaic_sdk_version():
+    # Extract QAIC SDK Apps or Platform Version from SDK XML file
+    sdk_xml_file = (
+        Constants.SDK_APPS_XML
+        if os.path.exists(Constants.SDK_APPS_XML)
+        else Constants.SDK_PLATFORM_XML
+        if os.path.exists(Constants.SDK_PLATFORM_XML)
+        else None
+    )
+    qaic_version = None
+    if sdk_xml_file is not None:
+        tree = ET.parse(sdk_xml_file)
path: QEfficient/utils/_utils.py
user: login: quic-rishinr
body: better to have an exception hander here as well. 
created_at: 2025-05-06T14:25:30Z
author_association: CONTRIBUTOR
diff_hunk: @@ -511,29 +528,13 @@ def create_and_dump_qconfigs(
     Such as huggingface configs, QEff transforms, QAIC sdk version, QNN sdk, compilation dir, qpc dir and
     many other compilation options.
     """
-    qnn_config = compiler_options["qnn_config"] if "qnn_config" in compiler_options else None
-    enable_qnn = True if "qnn_config" in compiler_options else None
-
+    enable_qnn = compiler_options.get("enable_qnn", None)
+    qnn_config = compiler_options.get("qnn_config", None)
     qconfig_file_path = os.path.join(os.path.dirname(qpc_path), "qconfig.json")
     onnx_path = str(onnx_path)
     specializations_file_path = str(os.path.join(os.path.dirname(qpc_path), "specializations.json"))
     compile_dir = str(os.path.dirname(qpc_path))
-    qnn_config_path = (
-        (qnn_config if qnn_config is not None else "QEfficient/compile/qnn_config.json") if enable_qnn else None
-    )
-
-    # Extract QAIC SDK Apps Version from SDK XML file
-    tree = ET.parse(Constants.SDK_APPS_XML)
-    root = tree.getroot()
-    qaic_version = root.find(".//base_version").text
-
-    # Extract QNN SDK details from YAML file if the environment variable is set
-    qnn_sdk_details = None
-    qnn_sdk_path = os.getenv(QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME)
-    if enable_qnn and qnn_sdk_path:
-        qnn_sdk_yaml_path = os.path.join(qnn_sdk_path, QnnConstants.QNN_SDK_YAML)
-        with open(qnn_sdk_yaml_path, "r") as file:
-            qnn_sdk_details = yaml.safe_load(file)
+    qnn_config_path = qnn_config if qnn_config is not None else "QEfficient/compile/qnn_config.json"
path: QEfficient/utils/_utils.py
user: login: quic-rishinr
body: better to fetch the path from constant file than hardcoding here
created_at: 2025-05-06T14:27:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -495,6 +495,23 @@ def wrapper(self, *args, **kwargs):
     return wrapper
 
 
+def get_qaic_sdk_version():
+    # Extract QAIC SDK Apps or Platform Version from SDK XML file
+    sdk_xml_file = (
path: QEfficient/utils/_utils.py
user: login: abukhoy
body: But I am seeing that both are same! 
Okay, if they are different then let's dump both versions into the qconfig. What do you think?
created_at: 2025-05-07T06:19:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -495,6 +495,23 @@ def wrapper(self, *args, **kwargs):
     return wrapper
 
 
+def get_qaic_sdk_version():
+    # Extract QAIC SDK Apps or Platform Version from SDK XML file
+    sdk_xml_file = (
path: QEfficient/utils/_utils.py
user: login: asmigosw
body: We keep them same generally, but they can be different as well so it's better to track both.
created_at: 2025-05-07T06:23:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -558,29 +585,13 @@ def create_and_dump_qconfigs(
     Such as huggingface configs, QEff transforms, QAIC sdk version, QNN sdk, compilation dir, qpc dir and
     many other compilation options.
     """
-    qnn_config = compiler_options["qnn_config"] if "qnn_config" in compiler_options else None
-    enable_qnn = True if "qnn_config" in compiler_options else None
-
+    enable_qnn = compiler_options.get("enable_qnn", None)
+    qnn_config = compiler_options.get("qnn_config", None)
     qconfig_file_path = os.path.join(os.path.dirname(qpc_path), "qconfig.json")
     onnx_path = str(onnx_path)
     specializations_file_path = str(os.path.join(os.path.dirname(qpc_path), "specializations.json"))
     compile_dir = str(os.path.dirname(qpc_path))
-    qnn_config_path = (
-        (qnn_config if qnn_config is not None else "QEfficient/compile/qnn_config.json") if enable_qnn else None
-    )
-
-    # Extract QAIC SDK Apps Version from SDK XML file
-    tree = ET.parse(Constants.SDK_APPS_XML)
-    root = tree.getroot()
-    qaic_version = root.find(".//base_version").text
-
-    # Extract QNN SDK details from YAML file if the environment variable is set
-    qnn_sdk_details = None
-    qnn_sdk_path = os.getenv(QnnConstants.QNN_SDK_PATH_ENV_VAR_NAME)
-    if enable_qnn and qnn_sdk_path:
-        qnn_sdk_yaml_path = os.path.join(qnn_sdk_path, QnnConstants.QNN_SDK_YAML)
-        with open(qnn_sdk_yaml_path, "r") as file:
-            qnn_sdk_details = yaml.safe_load(file)
+    qnn_config_path = qnn_config if qnn_config is not None else QnnConstants.QNN_DEFAULT_CONFIG_PATH
path: QEfficient/utils/_utils.py
user: login: shubhagr-qc
body: If qnn_config is passed as None, we should be mentioning qnn_config_path as None only, since QNN_DEFAULT_CONFIG_PATH will not be used here. Also, in case where we are using qefficient as a package and dont have access to the qefficient repository, qnn_config will not be present in the default path. 

@quic-rishinr Please validate the observation.  
created_at: 2025-05-08T05:43:15Z
author_association: CONTRIBUTOR

PR comments:
user: login: asmigosw
created_at: 2025-05-05T10:14:23Z
body: LGTM
author_association: CONTRIBUTOR
user: login: shubhagr-qc
created_at: 2025-05-08T08:43:50Z
body: Thanks @abukhoy for incorporating the comment. LGTM
author_association: CONTRIBUTOR