Source code for spinn_machine.version.version_factory

# Copyright (c) 2023 The University of Manchester
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import annotations
import logging
import sys
from typing import Optional, TYPE_CHECKING

from typing_extensions import Never

from spinn_utilities.config_holder import (
    get_config_bool, get_config_int_or_none, get_config_str_or_none)
from spinn_utilities.log import FormatAdapter
from spinn_machine.exceptions import SpinnMachineException
from .version_strings import VersionStrings
if TYPE_CHECKING:
    from .abstract_version import AbstractVersion

logger = FormatAdapter(logging.getLogger(__name__))

# Constant when wanting a specific version
THREE = 3
FIVE = 5
# New value subject to change
SPIN2_1CHIP = 201
SPIN2_48CHIP = 248


[docs] def version_factory() -> AbstractVersion: """ Creates a Machine Version class based on cfg settings. :return: A subclass of AbstractVersion :raises SpinnMachineException: If the cfg version is not set correctly """ cfg_version = _get_cfg_version() url_version = _get_url_version() size_version = _get_size_version() version: Optional[AbstractVersion] = None if cfg_version is None: if url_version is None: version = None else: version = _number_to_version(url_version) else: if url_version is None: version = _number_to_version(cfg_version) else: version_cfg = _number_to_version(cfg_version) version_url = _number_to_version(url_version) if version_cfg == version_url: version = version_cfg else: raise_version_error("Incorrect version", cfg_version) if size_version is None: if version is None: raise_version_error("No version", None) else: return version else: if version is None: logger.warning("Please add a version to your cfg file.") return _number_to_version(size_version) else: version_sized = _number_to_version(size_version) if version == version_sized: return version else: raise SpinnMachineException( "cfg width and height do not match other cfg setting.") raise SpinnMachineException("Should not get here")
def _get_cfg_version() -> Optional[int]: version = get_config_int_or_none("Machine", "version") versions = get_config_str_or_none("Machine", "versions") if versions is not None: if version is not None: raise SpinnMachineException( f"Both {version=} and {versions=} found in cfg") vs = VersionStrings.from_string(versions) options = vs.options # Use the fact that we run actions against different python versions minor = sys.version_info.minor version = options[minor % len(options)] if version is None: logger.warning( "The cfg has no version. This is deprecated! Please add a version") return version def _get_url_version() -> Optional[int]: spalloc_server = get_config_str_or_none("Machine", "spalloc_server") remote_spinnaker_url = get_config_str_or_none( "Machine", "remote_spinnaker_url") machine_name = get_config_str_or_none("Machine", "machine_name") virtual_board = get_config_bool("Machine", "virtual_board") if spalloc_server is not None: if remote_spinnaker_url is not None: raise SpinnMachineException( "Both spalloc_server and remote_spinnaker_url " "specified in cfg") if machine_name is not None: raise SpinnMachineException( "Both spalloc_server and machine_name specified in cfg") if virtual_board: raise SpinnMachineException( "Both spalloc_server and virtual_board specified in cfg") return 5 if remote_spinnaker_url is not None: if machine_name is not None: raise SpinnMachineException( "Both remote_spinnaker_url and machine_name specified in cfg") if virtual_board: raise SpinnMachineException( "Both remote_spinnaker_url and virtual_board specified in cfg") return 5 if machine_name is not None: if virtual_board: raise SpinnMachineException( "Both machine_name and virtual_board specified in cfg") return None def _get_size_version() -> Optional[int]: height = get_config_int_or_none("Machine", "height") width = get_config_int_or_none("Machine", "width") if height is None: if width is None: return None else: raise SpinnMachineException("cfg has width but not height") else: if width is None: raise SpinnMachineException("cfg has height but not width") else: if height == width == 2: return 3 elif height == width == 1: return 201 # if width and height are valid checked later return 5 def _number_to_version(version: int) -> AbstractVersion: # Delayed import to avoid circular imports # pylint: disable=import-outside-toplevel from .version_3 import Version3 from .version_5 import Version5 from .version_201 import Version201 from .version_248 import Version248 if version in [2, 3]: return Version3() if version in [4, 5]: return Version5() if version == SPIN2_1CHIP: return Version201() if version == SPIN2_48CHIP: return Version248() raise SpinnMachineException(f"Unexpected cfg [Machine]version {version}") def raise_version_error(error: str, version: Optional[int]) -> Never: """ Collects main cfg values and raises an exception :param error: message for the exception :param version: version claimed :raises SpinnMachineException: Always! """ height = get_config_int_or_none("Machine", "height") width = get_config_int_or_none("Machine", "width") spalloc_server = get_config_str_or_none("Machine", "spalloc_server") remote_spinnaker_url = get_config_str_or_none( "Machine", "remote_spinnaker_url") machine_name = get_config_str_or_none("Machine", "machine_name") virtual_board = get_config_bool("Machine", "virtual_board") raise SpinnMachineException( f"{error} with cfg [Machine] values {version=}, " f"{machine_name=}, {spalloc_server=}, {remote_spinnaker_url=}, " f"{virtual_board=}, {width=}, and {height=}")