From bebb7532e83ea6f40432d7251f906d185e9f6978 Mon Sep 17 00:00:00 2001 From: "Rojas Chaves, Jose" Date: Fri, 30 May 2025 23:05:27 +0000 Subject: [PATCH 1/8] Enabling configurable mem specifications --- .../assembler/common/constants.py | 228 ++++- .../assembler/common/run_config.py | 37 +- .../assembler/memory_model/__init__.py | 13 +- .../assembler/memory_model/register_file.py | 4 +- .../assembler/spec_config/__init__.py | 0 .../assembler/spec_config/cinst/__init__.py | 638 ++++++++++++ .../__init__.py => spec_config/isa_spec.py} | 2 +- .../assembler/spec_config/mem_spec.py | 93 ++ .../assembler/spec_config/minst/__init__.py | 152 +++ .../assembler/spec_config/xinst/__init__.py | 919 ++++++++++++++++++ .../assembler/stages/asm_scheduler.py | 7 +- .../hec-assembler-tools/config/mem_spec.json | 21 + assembler_tools/hec-assembler-tools/he_as.py | 74 +- .../hec-assembler-tools/he_link.py | 35 +- .../hec-assembler-tools/he_prep.py | 12 +- .../linker/steps/program_linker.py | 2 +- 16 files changed, 2126 insertions(+), 111 deletions(-) create mode 100644 assembler_tools/hec-assembler-tools/assembler/spec_config/__init__.py create mode 100644 assembler_tools/hec-assembler-tools/assembler/spec_config/cinst/__init__.py rename assembler_tools/hec-assembler-tools/assembler/{isa_spec/__init__.py => spec_config/isa_spec.py} (99%) create mode 100644 assembler_tools/hec-assembler-tools/assembler/spec_config/mem_spec.py create mode 100644 assembler_tools/hec-assembler-tools/assembler/spec_config/minst/__init__.py create mode 100644 assembler_tools/hec-assembler-tools/assembler/spec_config/xinst/__init__.py create mode 100644 assembler_tools/hec-assembler-tools/config/mem_spec.json diff --git a/assembler_tools/hec-assembler-tools/assembler/common/constants.py b/assembler_tools/hec-assembler-tools/assembler/common/constants.py index 9c11090c..16449667 100644 --- a/assembler_tools/hec-assembler-tools/assembler/common/constants.py +++ b/assembler_tools/hec-assembler-tools/assembler/common/constants.py @@ -23,6 +23,9 @@ class Constants: OPERATIONS (list): List of high-level operations supported by the system. """ + __MAX_BUNDLE_SIZE: int # = 64 + __XINSTRUCTION_SIZE_BYTES: int # = 8 + # Data Constants # -------------- @@ -70,12 +73,12 @@ def REPLACEMENT_POLICIES(cls) -> tuple: @classproperty def XINSTRUCTION_SIZE_BYTES(cls) -> int: """Size of an x-instruction in bytes.""" - return 8 + return cls.__XINSTRUCTION_SIZE_BYTES @classproperty def MAX_BUNDLE_SIZE(cls) -> int: """Maximum number of instructions in a bundle.""" - return 64 + return cls.__MAX_BUNDLE_SIZE @classproperty def MAX_BUNDLE_SIZE_BYTES(cls) -> int: @@ -98,6 +101,25 @@ def OPERATIONS(cls) -> list: "square", "add_plain", "add_corrected", "mul_plain", "rescale", "boot_dot_prod", "boot_mod_drop_scale", "boot_mul_const", "boot_galois_plain" ] + @classmethod + def hw_spec_as_dict(cls) -> dict: + """ + Returns hw configurable attributes as dictionary. + """ + dict = {"bytes_per_xinstruction": cls.XINSTRUCTION_SIZE_BYTES, + "max_instructions_per_bundle": cls.MAX_BUNDLE_SIZE} + return dict + + @classmethod + def setMaxBundleSize(cls, val: int): + """Updates max bundle size""" + cls.__MAX_BUNDLE_SIZE = val + + @classmethod + def setXInstructionSizeBytes(cls, val: int): + """Updates size of single XInstruction""" + cls.__XINSTRUCTION_SIZE_BYTES = val + def convertBytes2Words(bytes: int) -> int: """ Converts a size in bytes to the equivalent number of words. @@ -290,14 +312,21 @@ class MemoryModel: HBM and SPAD. """ - __XINST_QUEUE_MAX_CAPACITY = 1 * Constants.MEGABYTE - __XINST_QUEUE_MAX_CAPACITY_WORDS = convertBytes2Words(__XINST_QUEUE_MAX_CAPACITY) - __CINST_QUEUE_MAX_CAPACITY = 128 * Constants.KILOBYTE - __CINST_QUEUE_MAX_CAPACITY_WORDS = convertBytes2Words(__CINST_QUEUE_MAX_CAPACITY) - __MINST_QUEUE_MAX_CAPACITY = 128 * Constants.KILOBYTE - __MINST_QUEUE_MAX_CAPACITY_WORDS = convertBytes2Words(__MINST_QUEUE_MAX_CAPACITY) - __STORE_BUFFER_MAX_CAPACITY = 128 * Constants.KILOBYTE - __STORE_BUFFER_MAX_CAPACITY_WORDS = convertBytes2Words(__STORE_BUFFER_MAX_CAPACITY) + __XINST_QUEUE_MAX_CAPACITY: int # = 1 * Constants.MEGABYTE + __CINST_QUEUE_MAX_CAPACITY: int # = 128 * Constants.KILOBYTE + __MINST_QUEUE_MAX_CAPACITY: int # = 128 * Constants.KILOBYTE + __STORE_BUFFER_MAX_CAPACITY: int # = 128 * Constants.KILOBYTE + + # Class-level attributes + __NUM_BLOCKS_PER_TWID_META_WORD: int # = 4 + __NUM_BLOCKS_PER_KGSEED_META_WORD: int # = 4 + __NUM_ROUTING_TABLE_REGISTERS: int # = 1 + __NUM_ONES_META_REGISTERS: int # = 1 + __NUM_TWIDDLE_META_REGISTERS: int # = 32 * __NUM_ONES_META_REGISTERS + __TWIDDLE_META_REGISTER_SIZE_BYTES: int # = 8 * Constants.KILOBYTE + __MAX_RESIDUALS: int # = __NUM_TWIDDLE_META_REGISTERS * 2 + __NUM_REGISTER_BANKS: int # = 4 + __NUM_REGISTERS_PER_BANK: int # = 72 @classproperty def XINST_QUEUE_MAX_CAPACITY(cls): @@ -306,7 +335,7 @@ def XINST_QUEUE_MAX_CAPACITY(cls): @classproperty def XINST_QUEUE_MAX_CAPACITY_WORDS(cls): """Maximum capacity of the XINST queue in words.""" - return cls.__XINST_QUEUE_MAX_CAPACITY_WORDS + return convertBytes2Words(cls.__XINST_QUEUE_MAX_CAPACITY) @classproperty def CINST_QUEUE_MAX_CAPACITY(cls): """Maximum capacity of the CINST queue in bytes.""" @@ -314,7 +343,7 @@ def CINST_QUEUE_MAX_CAPACITY(cls): @classproperty def CINST_QUEUE_MAX_CAPACITY_WORDS(cls): """Maximum capacity of the CINST queue in words.""" - return cls.__CINST_QUEUE_MAX_CAPACITY_WORDS + return convertBytes2Words(cls.__CINST_QUEUE_MAX_CAPACITY) @classproperty def MINST_QUEUE_MAX_CAPACITY(cls): """Maximum capacity of the MINST queue in bytes.""" @@ -322,7 +351,7 @@ def MINST_QUEUE_MAX_CAPACITY(cls): @classproperty def MINST_QUEUE_MAX_CAPACITY_WORDS(cls): """Maximum capacity of the MINST queue in words.""" - return cls.__MINST_QUEUE_MAX_CAPACITY_WORDS + return convertBytes2Words(cls.__MINST_QUEUE_MAX_CAPACITY) @classproperty def STORE_BUFFER_MAX_CAPACITY(cls): """Maximum capacity of the store buffer in bytes.""" @@ -330,17 +359,17 @@ def STORE_BUFFER_MAX_CAPACITY(cls): @classproperty def STORE_BUFFER_MAX_CAPACITY_WORDS(cls): """Maximum capacity of the store buffer in words.""" - return cls.__STORE_BUFFER_MAX_CAPACITY_WORDS + return convertBytes2Words(cls.__STORE_BUFFER_MAX_CAPACITY) @classproperty def NUM_BLOCKS_PER_TWID_META_WORD(cls) -> int: """Number of blocks per twiddle metadata word.""" - return 4 + return cls.__NUM_BLOCKS_PER_TWID_META_WORD @classproperty def NUM_BLOCKS_PER_KGSEED_META_WORD(cls) -> int: """Number of blocks per key generation seed metadata word.""" - return 4 + return cls.__NUM_BLOCKS_PER_KGSEED_META_WORD @classproperty def NUM_ROUTING_TABLE_REGISTERS(cls) -> int: @@ -351,7 +380,7 @@ def NUM_ROUTING_TABLE_REGISTERS(cls) -> int: at the same time, since rshuffle instructions will pick a routing table to use to compute the shuffled result. """ - return 1 + return cls.__NUM_ROUTING_TABLE_REGISTERS @classproperty def NUM_ONES_META_REGISTERS(cls) -> int: @@ -361,7 +390,7 @@ def NUM_ONES_META_REGISTERS(cls) -> int: This directly affects the maximum number of residuals that can be processed in the CE without needing to load new metadata. """ - return 1 + return cls.__NUM_ONES_META_REGISTERS @classproperty def NUM_TWIDDLE_META_REGISTERS(cls) -> int: @@ -371,14 +400,14 @@ def NUM_TWIDDLE_META_REGISTERS(cls) -> int: This directly affects the maximum number of residuals that can be processed in the CE without needing to load new metadata. """ - return 32 * cls.NUM_ONES_META_REGISTERS + return cls.__NUM_TWIDDLE_META_REGISTERS @classproperty def TWIDDLE_META_REGISTER_SIZE_BYTES(cls) -> int: """ Size, in bytes, of a twiddle factor metadata register. """ - return 8 * Constants.KILOBYTE + return cls.__TWIDDLE_META_REGISTER_SIZE_BYTES @classproperty def MAX_RESIDUALS(cls) -> int: @@ -386,17 +415,128 @@ def MAX_RESIDUALS(cls) -> int: Maximum number of residuals that can be processed in the CE without needing to load new metadata. """ - return cls.NUM_TWIDDLE_META_REGISTERS * 2 + return cls.__MAX_RESIDUALS @classproperty def NUM_REGISTER_BANKS(cls) -> int: """Number of register banks in the CE""" - return 4 + return cls.__NUM_REGISTER_BANKS @classproperty - def NUM_REGISTER_PER_BANKS(cls) -> int: + def NUM_REGISTERS_PER_BANK(cls) -> int: """Number of register per register banks in the CE""" - return 72 + return cls.__NUM_REGISTERS_PER_BANK + + @classmethod + def hw_spec_as_dict(cls) -> dict: + """ + Returns hw configurable attributes as dictionary. + """ + dict = {"xinst_queue_size_in_bytes": cls.__XINST_QUEUE_MAX_CAPACITY, + "cinst_queue_size_in_bytes": cls.__CINST_QUEUE_MAX_CAPACITY, + "minst_queue_size_in_bytes": cls.__MINST_QUEUE_MAX_CAPACITY, + "store_buffer_size_in_bytes": cls.__STORE_BUFFER_MAX_CAPACITY, + "num_blocks_per_twid_meta_word": cls.NUM_BLOCKS_PER_TWID_META_WORD, + "num_blocks_per_kgseed_meta_word": cls.NUM_BLOCKS_PER_KGSEED_META_WORD, + "num_routing_table_registers": cls.NUM_ROUTING_TABLE_REGISTERS, + "num_ones_meta_registers": cls.NUM_ONES_META_REGISTERS, + "num_twiddle_meta_registers": cls.NUM_TWIDDLE_META_REGISTERS, + "twiddle_meta_register_size_in_bytes": cls.TWIDDLE_META_REGISTER_SIZE_BYTES, + "max_residuals": cls.MAX_RESIDUALS, + "num_register_banks": cls.NUM_REGISTER_BANKS, + "num_registers_per_bank": cls.NUM_REGISTERS_PER_BANK} + return dict + + @classmethod + def setMaxXInstQueueCapacity(cls, val: int): + """ + Sets max XInst queue capacity + """ + cls.__XINST_QUEUE_MAX_CAPACITY = val + + @classmethod + def setMaxCInstQueueCapacity(cls, val: int): + """ + Sets max CInst queue capacity + """ + cls.__CINST_QUEUE_MAX_CAPACITY = val + + @classmethod + def setMaxMInstQueueCapacity(cls, val: int): + """ + Sets max MInst queue capacity + """ + cls.__MINST_QUEUE_MAX_CAPACITY = val + + @classmethod + def setMaxStoreBufferCapacity(cls, val: int): + """ + Sets max store buffer capacity + """ + cls.__STORE_BUFFER_MAX_CAPACITY = val + + @classmethod + def setNumBlocksPerTwidMetaWord(cls, val: int): + """ + Sets the number of blocks per twiddle metadata word. + """ + cls.__NUM_BLOCKS_PER_TWID_META_WORD = val + + @classmethod + def setNumBlocksPerKgseedMetaWord(cls, val: int): + """ + Sets the number of blocks per key generation seed metadata word. + """ + cls.__NUM_BLOCKS_PER_KGSEED_META_WORD = val + + @classmethod + def setNumRoutingTableRegisters(cls, val: int): + """ + Sets the number of routing table registers. + """ + cls.__NUM_ROUTING_TABLE_REGISTERS = val + + @classmethod + def setNumOnesMetaRegisters(cls, val: int): + """ + Sets the number of ones metadata registers. + """ + cls.__NUM_ONES_META_REGISTERS = val + + @classmethod + def setNumTwiddleMetaRegisters(cls, val: int): + """ + Sets the number of twiddle metadata registers. + """ + cls.__NUM_TWIDDLE_META_REGISTERS = val + + @classmethod + def setTwiddleMetaRegisterSizeBytes(cls, val: int): + """ + Sets the size of twiddle metadata register in bytes. + """ + cls.__TWIDDLE_META_REGISTER_SIZE_BYTES = val + + @classmethod + def setMaxResiduals(cls, val: int): + """ + Sets the maximum number of residuals. + """ + cls.__MAX_RESIDUALS = val + + @classmethod + def setNumRegisterBanks(cls, val: int): + """ + Sets the number of register banks. + """ + cls.__NUM_REGISTER_BANKS = val + + @classmethod + def setNumRegistersPerBank(cls, val: int): + """ + Sets the number of registers per bank. + """ + cls.__NUM_REGISTERS_PER_BANK = val class HBM: """ @@ -404,8 +544,7 @@ class HBM: This class defines the maximum capacity of HBM in both bytes and words. """ - __MAX_CAPACITY = 64 * Constants.GIGABYTE - __MAX_CAPACITY_WORDS = convertBytes2Words(__MAX_CAPACITY) + __MAX_CAPACITY: int # = 64 * Constants.GIGABYTE @classproperty def MAX_CAPACITY(cls) -> int: @@ -415,7 +554,22 @@ def MAX_CAPACITY(cls) -> int: @classproperty def MAX_CAPACITY_WORDS(cls) -> int: """Total capacity of HBM in Words""" - return cls.__MAX_CAPACITY_WORDS + return convertBytes2Words(cls.__MAX_CAPACITY) + + @classmethod + def hw_spec_as_dict(cls) -> dict: + """ + Returns hw configurable attributes as dictionary. + """ + dict = {"hbm_size_in_bytes": cls.__MAX_CAPACITY} + return dict + + @classmethod + def setMaxCapacity(cls, val: int): + """ + Sets max SPAD Capacity + """ + cls.__MAX_CAPACITY = val class SPAD: """ @@ -423,8 +577,7 @@ class SPAD: This class defines the maximum capacity of SPAD in both bytes and words. """ - __MAX_CAPACITY = 64 * Constants.MEGABYTE - __MAX_CAPACITY_WORDS = convertBytes2Words(__MAX_CAPACITY) + __MAX_CAPACITY: int # = 64 * Constants.MEGABYTE # Class methods and properties # ---------------------------- @@ -437,4 +590,19 @@ def MAX_CAPACITY(cls) -> int: @classproperty def MAX_CAPACITY_WORDS(cls) -> int: """Total capacity of SPAD in Words""" - return cls.__MAX_CAPACITY_WORDS + return convertBytes2Words(cls.__MAX_CAPACITY) + + @classmethod + def hw_spec_as_dict(cls) -> dict: + """ + Returns hw configurable attributes as dictionary. + """ + dict = {"cache_size_in_bytes": cls.__MAX_CAPACITY} + return dict + + @classmethod + def setMaxCapacity(cls, val: int): + """ + Sets max SPAD Capacity + """ + cls.__MAX_CAPACITY = val diff --git a/assembler_tools/hec-assembler-tools/assembler/common/run_config.py b/assembler_tools/hec-assembler-tools/assembler/common/run_config.py index 83e9d06e..296da3fe 100644 --- a/assembler_tools/hec-assembler-tools/assembler/common/run_config.py +++ b/assembler_tools/hec-assembler-tools/assembler/common/run_config.py @@ -1,25 +1,9 @@ import io +from .decorators import * from . import constants from .config import GlobalConfig -def static_initializer(cls): - """ - Decorator to initialize static members of a class. - - This decorator calls the `init_static` method of the class to initialize - any static members or configurations. - - Args: - cls: The class to be initialized. - - Returns: - The class with initialized static members. - """ - cls.init_static() - return cls - -@static_initializer class RunConfig: """ Configuration class for running the assembler with specific settings. @@ -31,11 +15,6 @@ class RunConfig: __initialized = False # Specifies whether static members have been initialized __default_config = {} # Dictionary of all configuration items supported and their default values - # Config defaults - DEFAULT_HBM_SIZE_KB = int(constants.MemoryModel.HBM.MAX_CAPACITY / constants.Constants.KILOBYTE) - DEFAULT_SPAD_SIZE_KB = int(constants.MemoryModel.SPAD.MAX_CAPACITY / constants.Constants.KILOBYTE) - DEFAULT_REPL_POLICY = constants.Constants.REPLACEMENT_POLICY_FTBU - def __init__(self, **kwargs): """ @@ -74,13 +53,26 @@ def __init__(self, """ # Initialize class members + print(f"ROCHA default configs {self.__default_config.items()}") for config_name, default_value in self.__default_config.items(): + print(f"ROCHA Setting attribute {config_name}") setattr(self, config_name, kwargs.get(config_name, default_value)) # Validate inputs if self.repl_policy not in constants.Constants.REPLACEMENT_POLICIES: raise ValueError('Invalid `repl_policy`. "{}" not in {}'.format(self.repl_policy, constants.Constants.REPLACEMENT_POLICIES)) + @classproperty + def DEFAULT_HBM_SIZE_KB(cls) -> int: + return int(constants.MemoryModel.HBM.MAX_CAPACITY / constants.Constants.KILOBYTE) + + @classproperty + def DEFAULT_SPAD_SIZE_KB(cls) -> int: + return int(constants.MemoryModel.SPAD.MAX_CAPACITY / constants.Constants.KILOBYTE) + + @classproperty + def DEFAULT_REPL_POLICY(cls) -> int: + return constants.Constants.REPLACEMENT_POLICY_FTBU @classmethod def init_static(cls): @@ -90,6 +82,7 @@ def init_static(cls): This method sets up default configuration values for the class, ensuring that they are only initialized once. """ + print("ROCHA Super init static") if not cls.__initialized: cls.__default_config["hbm_size"] = cls.DEFAULT_HBM_SIZE_KB cls.__default_config["spad_size"] = cls.DEFAULT_SPAD_SIZE_KB diff --git a/assembler_tools/hec-assembler-tools/assembler/memory_model/__init__.py b/assembler_tools/hec-assembler-tools/assembler/memory_model/__init__.py index 2dfbb96b..7bf6ccfa 100644 --- a/assembler_tools/hec-assembler-tools/assembler/memory_model/__init__.py +++ b/assembler_tools/hec-assembler-tools/assembler/memory_model/__init__.py @@ -31,10 +31,6 @@ class StoreBufferValueType(NamedTuple): variable: Variable dest_spad_address: int - __MAX_TWIDDLE_META_VARS_PER_SEGMENT = math.ceil(constants.MemoryModel.NUM_TWIDDLE_META_REGISTERS * \ - constants.MemoryModel.TWIDDLE_META_REGISTER_SIZE_BYTES / \ - constants.Constants.WORD_SIZE) - @classproperty def MAX_TWIDDLE_META_VARS_PER_SEGMENT(cls): """ @@ -43,8 +39,9 @@ def MAX_TWIDDLE_META_VARS_PER_SEGMENT(cls): Returns: int: The number of variables per segment. """ - return cls.__MAX_TWIDDLE_META_VARS_PER_SEGMENT - + return math.ceil(constants.MemoryModel.NUM_TWIDDLE_META_REGISTERS * \ + constants.MemoryModel.TWIDDLE_META_REGISTER_SIZE_BYTES / \ + constants.Constants.WORD_SIZE) # Constructor # ----------- @@ -52,7 +49,7 @@ def MAX_TWIDDLE_META_VARS_PER_SEGMENT(cls): def __init__(self, hbm_capacity_words: int, spad_capacity_words: int, - num_register_banks: int = constants.MemoryModel.NUM_REGISTER_BANKS, + num_register_banks: int, register_range: range = None): """ Initializes a new MemoryModel object. @@ -74,7 +71,7 @@ def __init__(self, raise ValueError(('`num_register_banks`: there must be at least {} register banks, ' 'but {} requested.').format(constants.MemoryModel.NUM_REGISTER_BANKS, num_register_banks)) - self.__register_range = range(constants.MemoryModel.NUM_REGISTER_PER_BANKS) if not register_range else register_range + self.__register_range = range(constants.MemoryModel.NUM_REGISTERS_PER_BANK) if not register_range else register_range # initialize members self.__store_buffer = QueueDict() # QueueDict(var_name: str, StoreBufferValueType) self.__variables = {} # dict(var_name, Variable) diff --git a/assembler_tools/hec-assembler-tools/assembler/memory_model/register_file.py b/assembler_tools/hec-assembler-tools/assembler/memory_model/register_file.py index 9925be9f..51868e8d 100644 --- a/assembler_tools/hec-assembler-tools/assembler/memory_model/register_file.py +++ b/assembler_tools/hec-assembler-tools/assembler/memory_model/register_file.py @@ -231,8 +231,8 @@ def __init__(self, Raises: ValueError: If the register index is out of the valid range. """ - if register_index < 0 or register_index >= constants.MemoryModel.NUM_REGISTER_PER_BANKS: - raise ValueError((f'`register_index`: expected an index for register in the range [0, {constants.MemoryModel.NUM_REGISTER_PER_BANKS}), ' + if register_index < 0 or register_index >= constants.MemoryModel.NUM_REGISTERS_PER_BANK: + raise ValueError((f'`register_index`: expected an index for register in the range [0, {constants.MemoryModel.NUM_REGISTERS_PER_BANK}), ' f'but {register_index} received.')) super().__init__((0, 0)) self.register_dirty = False diff --git a/assembler_tools/hec-assembler-tools/assembler/spec_config/__init__.py b/assembler_tools/hec-assembler-tools/assembler/spec_config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/assembler_tools/hec-assembler-tools/assembler/spec_config/cinst/__init__.py b/assembler_tools/hec-assembler-tools/assembler/spec_config/cinst/__init__.py new file mode 100644 index 00000000..6e827e85 --- /dev/null +++ b/assembler_tools/hec-assembler-tools/assembler/spec_config/cinst/__init__.py @@ -0,0 +1,638 @@ +from .. import ISASpecInstruction + +class BLoad(ISASpecInstruction): + """ + Represents a `bload` instruction. + + This instruction loads metadata from scratchpad to register file. + + For more information, check the `bload` Specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_bload.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 0. + """ + return 0 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 1. + """ + return 1 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 5. + """ + return 5 + +class BOnes(ISASpecInstruction): + """ + Represents a `bones` instruction. + + The `bones` instruction loads metadata of identity (one) from the scratchpad to the register file. + + For more information, check the `bones` Specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_bones.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 0. + """ + return 0 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 1. + """ + return 1 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 5. + """ + return 5 + +class Exit(ISASpecInstruction): + """ + Represents an `cexit` instruction. + + This instruction terminates execution of a HERACLES program. + + For more information, check the `cexit` Specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_cexit.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 0. + """ + return 0 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 0. + """ + return 0 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 1. + """ + return 1 + +class CLoad(ISASpecInstruction): + """ + Represents a `cload` instruction. + + This instruction loads a single polynomial residue from scratchpad into a register. + + For more information, check the `cload` Specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_cload.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 1. + """ + return 1 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 1. + """ + return 1 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 4. + """ + return 4 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 4. + """ + return 4 + +class Nop(ISASpecInstruction): + """ + Represents a `nop` instruction. + + This instruction adds desired amount of idle cycles in the Cfetch flow. + + For more information, check the `nop` Specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_nop.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 0. + """ + return 0 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 0. + """ + return 0 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 1. + """ + return 1 + +class CStore(ISASpecInstruction): + """ + Represents a `cstore` instruction. + + This instruction fetchs a single polynomial residue from the intermediate data buffer and store back to SPAD. + + For more information, check the `cstore` Specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_cstore.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 0. + """ + return 0 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 0. + """ + return 0 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 5. + """ + return 5 + +class CSyncM(ISASpecInstruction): + """ + Represents a `csyncm` instruction. + + Wait instruction similar to a barrier that stalls the execution of CINST + queue until the specified instruction from MINST queue has completed. + + For more information, check the `csyncm` Specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_csyncm.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 0. + """ + return 0 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 0. + """ + return 0 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 1. + """ + return 1 + +class iFetch(ISASpecInstruction): + """ + Represents an `ifetch` instruction. + + This instruction fetchs a bundle of instructions from the XINST queue and send it to the CE for execution. + + For more information, check the `ifetch` Specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_ifetch.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 0. + """ + return 0 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 0. + """ + return 0 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 5. + """ + return 5 + +class KGLoad(ISASpecInstruction): + """ + Represents a `kgload` instruction. + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 1. + """ + return 1 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 0. + """ + return 0 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 4. + """ + return 4 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 40. + """ + return 40 + +class KGSeed(ISASpecInstruction): + """ + Represents a `kgseed` instruction. + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 0. + """ + return 0 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 1. + """ + return 1 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 1. + """ + return 1 + +class KGStart(ISASpecInstruction): + """ + Represents a `kgstart` instruction. + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 0. + """ + return 0 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 0. + """ + return 0 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 40. + """ + return 40 + +class NLoad(ISASpecInstruction): + """ + Represents a `nload` instruction. + + This instruction loads metadata (for NTT/iNTT routing mapping) from + scratchpad into a special routing table register. + + For more information, check the `nload` Specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_nload.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 0. + """ + return 0 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 1. + """ + return 1 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 4. + """ + return 4 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 4. + """ + return 4 + +class XInstFetch(ISASpecInstruction): + """ + Represents an `xinstfetch` instruction. + + Fetches instructions from the HBM and sends it to the XINST queue. + + For more information, check the `xinstfetch` Specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_xinstfetch.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 0. + """ + return 0 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 0. + """ + return 0 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 1. + """ + return 1 \ No newline at end of file diff --git a/assembler_tools/hec-assembler-tools/assembler/isa_spec/__init__.py b/assembler_tools/hec-assembler-tools/assembler/spec_config/isa_spec.py similarity index 99% rename from assembler_tools/hec-assembler-tools/assembler/isa_spec/__init__.py rename to assembler_tools/hec-assembler-tools/assembler/spec_config/isa_spec.py index eff3f06a..4476dd86 100644 --- a/assembler_tools/hec-assembler-tools/assembler/isa_spec/__init__.py +++ b/assembler_tools/hec-assembler-tools/assembler/spec_config/isa_spec.py @@ -4,7 +4,7 @@ import assembler.instructions.minst as minst import assembler.instructions.xinst as xinst -class SpecConfig: +class ISASpecConfig: __target_cops = { "bload" : cinst.bload.Instruction, "bones" : cinst.bones.Instruction, diff --git a/assembler_tools/hec-assembler-tools/assembler/spec_config/mem_spec.py b/assembler_tools/hec-assembler-tools/assembler/spec_config/mem_spec.py new file mode 100644 index 00000000..0d37dd16 --- /dev/null +++ b/assembler_tools/hec-assembler-tools/assembler/spec_config/mem_spec.py @@ -0,0 +1,93 @@ +import os +import json +from assembler.common.constants import Constants, MemoryModel + +class MemSpecConfig: + + _target_attributes = { + "bytes_per_xinstruction": Constants.setXInstructionSizeBytes, + "max_instructions_per_bundle": Constants.setMaxBundleSize, + "xinst_queue_size_in_bytes": MemoryModel.setMaxXInstQueueCapacity, + "cinst_queue_size_in_bytes": MemoryModel.setMaxCInstQueueCapacity, + "minst_queue_size_in_bytes": MemoryModel.setMaxMInstQueueCapacity, + "store_buffer_size_in_bytes": MemoryModel.setMaxStoreBufferCapacity, + "num_blocks_per_twid_meta_word": MemoryModel.setNumBlocksPerTwidMetaWord, + "num_blocks_per_kgseed_meta_word": MemoryModel.setNumBlocksPerKgseedMetaWord, + "num_routing_table_registers": MemoryModel.setNumRoutingTableRegisters, + "num_ones_meta_registers": MemoryModel.setNumOnesMetaRegisters, + "num_twiddle_meta_registers": MemoryModel.setNumTwiddleMetaRegisters, + "twiddle_meta_register_size_in_bytes": MemoryModel.setTwiddleMetaRegisterSizeBytes, + "max_residuals": MemoryModel.setMaxResiduals, + "num_register_banks": MemoryModel.setNumRegisterBanks, + "num_registers_per_bank": MemoryModel.setNumRegistersPerBank, + "hbm_size_in_bytes": MemoryModel.HBM.setMaxCapacity, + "cache_size_in_bytes": MemoryModel.SPAD.setMaxCapacity, + } + + @classmethod + def dump_mem_spec_to_json(cls, filename): + """ + Dumps the attributes of all classes as a JSON file under the "mem_spec" section. + + Args: + filename (str): The name of the JSON file to write to. + """ + + # Initialize an empty dictionary to hold all hardware specifications + hw_specs = {} + + # Aggregate hardware specifications from each class into a single dictionary + hw_specs.update(Constants.hw_spec_as_dict()) + hw_specs.update(MemoryModel.hw_spec_as_dict()) + hw_specs.update(MemoryModel.HBM.hw_spec_as_dict()) + hw_specs.update(MemoryModel.SPAD.hw_spec_as_dict()) + + # Wrap the hw_specs in a top-level dictionary + output_dict = {"mem_spec": hw_specs} + + # Write the dictionary to a JSON file + with open(filename, 'w') as json_file: + json.dump(output_dict, json_file, indent=4) + + @classmethod + def init_mem_spec_from_json(cls, filename): + """ + Updates class attributes using methods specified in the target_attributes dictionary based on a JSON file. + This method checks wether values found on json file exists in target dictionaries. + + Args: + filename (str): The name of the JSON file to read from. + """ + with open(filename, 'r') as json_file: + data = json.load(json_file) + + # Check for the "mem_spec" section + if "mem_spec" not in data: + raise ValueError("The JSON file does not contain the 'mem_spec' section.") + + mem_spec = data["mem_spec"] + + for key, value in mem_spec.items(): + if key not in cls._target_attributes: + raise ValueError(f"Attribute key '{key}' is not valid.") + else: + update_method = cls._target_attributes[key] + update_method(value) + + @classmethod + def initialize_mem_spec(cls, module_dir, mem_spec_file): + + if not mem_spec_file: + mem_spec_file = os.path.join(module_dir, "config/mem_spec.json") + mem_spec_file = os.path.abspath(mem_spec_file) + + if not os.path.exists(mem_spec_file): + raise FileNotFoundError( + f"Required Mem Spec file not found: {mem_spec_file}\n" + "Please provide a valid path using the `mem_spec` option, " + "or use a valid default file at: `/config/mem_spec.json`." + ) + + cls.init_mem_spec_from_json(mem_spec_file) + + return mem_spec_file diff --git a/assembler_tools/hec-assembler-tools/assembler/spec_config/minst/__init__.py b/assembler_tools/hec-assembler-tools/assembler/spec_config/minst/__init__.py new file mode 100644 index 00000000..463df89b --- /dev/null +++ b/assembler_tools/hec-assembler-tools/assembler/spec_config/minst/__init__.py @@ -0,0 +1,152 @@ +from .. import ISASpecInstruction + +class MLoad(ISASpecInstruction): + """ + Represents an `mload` instruction, inheriting from ISASpecInstruction. + + This instruction loads a single polynomial residue from local memory to scratchpad. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/minst/minst_mload.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands for the instruction. + + Returns: + int: The number of destination operands, which is 1. + """ + return 1 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands for the instruction. + + Returns: + int: The number of source operands, which is 1. + """ + return 1 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 1. + """ + return 1 + +class MStore(ISASpecInstruction): + """ + Represents an `mstore` instruction, inheriting from ISASpecInstruction. + + This instruction stores a single polynomial residue from scratchpad to local memory. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/minst/minst_mstore.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands for the instruction. + + Returns: + int: The number of destination operands, which is 1. + """ + return 1 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands for the instruction. + + Returns: + int: The number of source operands, which is 1. + """ + return 1 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 1. + """ + return 1 + +class MSyncC(ISASpecInstruction): + """ + Represents an MSyncC instruction, inheriting from ISASpecInstruction. + + Wait instruction similar to a barrier that stalls the execution of MINST + queue until the specified instruction from CINST queue has completed. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/minst/minst_msyncc.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands for the instruction. + + Returns: + int: The number of destination operands, which is 0. + """ + return 0 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands for the instruction. + + Returns: + int: The number of source operands, which is 0. + """ + return 0 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 1. + """ + return 1 \ No newline at end of file diff --git a/assembler_tools/hec-assembler-tools/assembler/spec_config/xinst/__init__.py b/assembler_tools/hec-assembler-tools/assembler/spec_config/xinst/__init__.py new file mode 100644 index 00000000..0fd3e554 --- /dev/null +++ b/assembler_tools/hec-assembler-tools/assembler/spec_config/xinst/__init__.py @@ -0,0 +1,919 @@ +from assembler.common.decorators import * +from .. import ISASpecInstruction + +class Add(ISASpecInstruction): + """ + Represents an `add` instruction. + + This instructions adds two polynomials stored in the register file and + store the result in a register. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_add.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 1. + """ + return 1 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 2. + """ + return 2 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 6. + """ + return 6 + +class Copy(ISASpecInstruction): + """ + Represents a Copy instruction. + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 1. + """ + return 1 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 1. + """ + return 1 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 6. + """ + return 6 + +class Exit(ISASpecInstruction): + """ + Represents an `exit` instruction. + + This instruction terminates execution of an instruction bundle. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_exit.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 0. + """ + return 0 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 0. + """ + return 0 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 1. + """ + return 1 + +class iNTT(ISASpecInstruction): + """ + Represents an `intt` instruction. + + The Inverse Number Theoretic Transform (iNTT), converts NTT form to positional form. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_intt.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 2. + """ + return 2 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 3. + """ + return 3 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 6. + """ + return 6 + +class irShuffle(ISASpecInstruction): + """ + Represents an irShuffle instruction with special latency properties. + + Properties: + SpecialLatency: Indicates the first increment at which another irshuffle instruction + can be scheduled within `SpecialLatencyMax` latency. + SpecialLatencyMax: Cannot enqueue any other irshuffle instruction within this latency + unless it is in `SpecialLatencyIncrement`. + SpecialLatencyIncrement: Can only enqueue any other irshuffle instruction + within `SpecialLatencyMax` only in increments of this value. + """ + + @classproperty + def SpecialLatency(cls): + """ + Special latency (indicates the first increment at which another irshuffle instruction + can be scheduled within `SpecialLatencyMax` latency). + + Returns: + int: The special latency increment. + """ + return cls.SpecialLatencyIncrement + + @classproperty + def SpecialLatencyMax(cls): + """ + Special latency maximum (cannot enqueue any other irshuffle instruction within this latency + unless it is in `SpecialLatencyIncrement`). + + Returns: + int: The special latency maximum, which is 17. + """ + return 17 + + @classproperty + def SpecialLatencyIncrement(cls): + """ + Special latency increment (can only enqueue any other irshuffle instruction + within `SpecialLatencyMax` only in increments of this value). + + Returns: + int: The special latency increment, which is 5. + """ + return 5 + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 2. + """ + return 2 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 2. + """ + return 2 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 23. + """ + return 23 + +class Mac(ISASpecInstruction): + """ + Represents a `mac` instruction. + + Element-wise polynomial multiplication and accumulation. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_mac.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 1. + """ + return 1 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 2. + """ + return 2 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 6. + """ + return 6 + +class Maci(ISASpecInstruction): + """ + Represents a `maci` instruction. + + Element-wise polynomial scaling by an immediate value and accumulation. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_maci.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 1. + """ + return 1 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 1. + """ + return 1 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 6. + """ + return 6 + +class Move(ISASpecInstruction): + """ + Represents a `move` instruction. + + This instruction copies data from one register to a different one. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_move.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 1. + """ + return 1 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 1. + """ + return 1 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 6. + """ + return 6 + +class Mul(ISASpecInstruction): + """ + Represents a `mul` instruction. + + This instructions performs element-wise polynomial multiplication. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_mul.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 1. + """ + return 1 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 2. + """ + return 2 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 6. + """ + return 6 + +class Muli(ISASpecInstruction): + """ + Represents a Muli instruction. + + This instruction performs element-wise polynomial scaling by an immediate value. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_muli.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 1. + """ + return 1 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 1. + """ + return 1 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 6. + """ + return 6 + +class Nop(ISASpecInstruction): + """ + Represents a `nop` instruction. + + This instruction adds a desired amount of idle cycles to the compute flow. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_nop.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 0. + """ + return 0 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 0. + """ + return 0 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 1. + """ + return 1 + +class NTT(ISASpecInstruction): + """ + Represents an `ntt` instruction (Number Theoretic Transform). + Converts positional form to NTT form. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_ntt.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 2. + """ + return 2 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 3. + """ + return 3 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 6. + """ + return 6 + +class rShuffle(ISASpecInstruction): + """ + Represents an rShuffle instruction with special latency properties. + + Properties: + SpecialLatency: Indicates the first increment at which another rshuffle instruction + can be scheduled within `SpecialLatencyMax` latency. + SpecialLatencyMax: Cannot enqueue any other rshuffle instruction within this latency + unless it is in `SpecialLatencyIncrement`. + SpecialLatencyIncrement: Can only enqueue any other rshuffle instruction + within `SpecialLatencyMax` only in increments of this value. + """ + + @classproperty + def SpecialLatency(cls): + """ + Special latency (indicates the first increment at which another rshuffle instruction + can be scheduled within `SpecialLatencyMax` latency). + + Returns: + int: The special latency increment. + """ + return cls.SpecialLatencyIncrement + + @classproperty + def SpecialLatencyMax(cls): + """ + Special latency maximum (cannot enqueue any other rshuffle instruction within this latency + unless it is in `SpecialLatencyIncrement`). + + Returns: + int: The special latency maximum, which is 17. + """ + return 17 + + @classproperty + def SpecialLatencyIncrement(cls): + """ + Special latency increment (can only enqueue any other rshuffle instruction + within `SpecialLatencyMax` only in increments of this value). + + Returns: + int: The special latency increment, which is 5. + """ + return 5 + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 2. + """ + return 2 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 2. + """ + return 2 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 23. + """ + return 23 + +class Sub(ISASpecInstruction): + """ + Represents a `sub` instruction. + + Element-wise polynomial subtraction. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_sub.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 1. + """ + return 1 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 2. + """ + return 2 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 6. + """ + return 6 + +class twiNTT(ISASpecInstruction): + """ + Represents a `twintt` instruction. + + This instruction performs on-die generation of twiddle factors for the next stage of iNTT. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_twintt.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 1. + """ + return 1 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 1. + """ + return 1 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 6. + """ + return 6 + +class twNTT(ISASpecInstruction): + """ + Represents a `twntt` instruction. + + This instruction performs on-die generation of twiddle factors for the next stage of NTT. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_twntt.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 1. + """ + return 1 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 1. + """ + return 1 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 6. + """ + return 6 + +class xStore(ISASpecInstruction): + """ + Represents an `xstore` instruction. + + This instruction transfers data from a register into the intermediate data buffer for subsequent transfer into SPAD. + + For more information, check the specification: + https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_xstore.md + """ + + @classmethod + def _get_numDests(cls) -> int: + """ + Gets the number of destination operands. + + Returns: + int: The number of destination operands, which is 1. + """ + return 1 + + @classmethod + def _get_numSources(cls) -> int: + """ + Gets the number of source operands. + + Returns: + int: The number of source operands, which is 1. + """ + return 1 + + @classmethod + def _get_throughput(cls) -> int: + """ + Gets the throughput of the instruction. + + Returns: + int: The throughput, which is 1. + """ + return 1 + + @classmethod + def _get_latency(cls) -> int: + """ + Gets the latency of the instruction. + + Returns: + int: The latency, which is 6. + """ + return 6 \ No newline at end of file diff --git a/assembler_tools/hec-assembler-tools/assembler/stages/asm_scheduler.py b/assembler_tools/hec-assembler-tools/assembler/stages/asm_scheduler.py index 29e38374..59a3d9b3 100644 --- a/assembler_tools/hec-assembler-tools/assembler/stages/asm_scheduler.py +++ b/assembler_tools/hec-assembler-tools/assembler/stages/asm_scheduler.py @@ -204,8 +204,6 @@ class Simulation: INSTRUCTION_WINDOW_SIZE = 100 MIN_INSTRUCTIONS_IN_TOPO_SORT = 10 - # Amount of instructions for a bundle to be considered short - BUNDLE_INSTRUCTION_MIN_LIMIT = Constants.MAX_BUNDLE_SIZE // 4 # 10 def __init__(self, dependency_graph: nx.DiGraph, @@ -351,6 +349,11 @@ def __init__(self, self.scheduled_xinsts_count = 0 self.verbose = progress_verbose + # Amount of instructions for a bundle to be considered short + @property + def BUNDLE_INSTRUCTION_MIN_LIMIT(self): + return Constants.MAX_BUNDLE_SIZE // 4 # 10 + @property def last_xinstr(self) -> object: """ diff --git a/assembler_tools/hec-assembler-tools/config/mem_spec.json b/assembler_tools/hec-assembler-tools/config/mem_spec.json new file mode 100644 index 00000000..c48c3356 --- /dev/null +++ b/assembler_tools/hec-assembler-tools/config/mem_spec.json @@ -0,0 +1,21 @@ +{ + "mem_spec": { + "cache_size_in_bytes": 67108864, + "hbm_size_in_bytes": 68719476736, + "xinst_queue_size_in_bytes": 1048576, + "cinst_queue_size_in_bytes": 131072, + "minst_queue_size_in_bytes": 131072, + "store_buffer_size_in_bytes": 131072, + "num_register_banks": 4, + "num_registers_per_bank": 72, + "bytes_per_xinstruction": 8, + "max_instructions_per_bundle": 64, + "num_blocks_per_twid_meta_word": 4, + "num_blocks_per_kgseed_meta_word": 4, + "num_routing_table_registers": 1, + "num_ones_meta_registers": 1, + "num_twiddle_meta_registers": 32, + "twiddle_meta_register_size_in_bytes": 8192, + "max_residuals": 64 + } +} \ No newline at end of file diff --git a/assembler_tools/hec-assembler-tools/he_as.py b/assembler_tools/hec-assembler-tools/he_as.py index 2ee92c49..2f1409b5 100644 --- a/assembler_tools/hec-assembler-tools/he_as.py +++ b/assembler_tools/hec-assembler-tools/he_as.py @@ -29,13 +29,13 @@ import time from assembler.common.run_config import RunConfig -from assembler.common.run_config import static_initializer from assembler.common import constants from assembler.common import makeUniquePath from assembler.common.config import GlobalConfig from assembler.common.counter import Counter -from assembler.isa_spec import SpecConfig +from assembler.spec_config.isa_spec import ISASpecConfig +from assembler.spec_config.mem_spec import MemSpecConfig from assembler.instructions import xinst from assembler.stages import scheduler from assembler.stages.asm_scheduler import scheduleASMISAInstructions @@ -50,7 +50,6 @@ DEFAULT_MINST_FILE_EXT = "minst" DEFAULT_MEM_FILE_EXT = "mem" -@static_initializer class AssemblerRunConfig(RunConfig): """ Maintains the configuration data for the run. @@ -93,15 +92,20 @@ def __init__(self, **kwargs): At least, one of the arguments passed is invalid. """ - super().__init__(**kwargs) - + self.init_default_config() # class members based on configuration + print("ROCHA RUN") for config_name, default_value in self.__default_config.items(): - assert(not hasattr(self, config_name)) - setattr(self, config_name, kwargs.get(config_name, default_value)) - if getattr(self, config_name) is None: - raise TypeError(f'Expected value for configuration `{config_name}`, but `None` received.') + value = kwargs.get(config_name) + if value is not None: + assert(not hasattr(self, config_name)) + setattr(self, config_name, value) + else: + if not hasattr(self, config_name): + setattr(self, config_name, default_value) + if getattr(self, config_name) is None: + raise TypeError(f'Expected value for configuration `{config_name}`, but `None` received.') # class members self.input_prefix = "" @@ -122,16 +126,23 @@ def __init__(self, **kwargs): self.input_mem_file = makeUniquePath(self.input_mem_file) @classmethod - def init_static(cls): + def init_default_config(cls): """ Initializes static members of the class. """ if not cls.__initialized: - cls.__default_config["input_file"] = None - cls.__default_config["input_mem_file"] = "" - cls.__default_config["output_dir"] = "" - cls.__default_config["output_prefix"] = "" - cls.__default_config["has_hbm"] = True + cls.__default_config["input_file"] = None + cls.__default_config["input_mem_file"] = "" + cls.__default_config["output_dir"] = "" + cls.__default_config["output_prefix"] = "" + cls.__default_config["has_hbm"] = True + print(f"ROCHA Default HBM SIZE in KB {cls.DEFAULT_HBM_SIZE_KB}") + cls.__default_config["hbm_size"] = cls.DEFAULT_HBM_SIZE_KB + cls.__default_config["spad_size"] = cls.DEFAULT_SPAD_SIZE_KB + cls.__default_config["repl_policy"] = cls.DEFAULT_REPL_POLICY + cls.__default_config["use_xinstfetch"] = GlobalConfig.useXInstFetch + cls.__default_config["suppress_comments"] = GlobalConfig.suppressComments + cls.__default_config["debug_verbose"] = GlobalConfig.debugVerbose cls.__initialized = True def __str__(self): @@ -186,7 +197,10 @@ def asmisaAssemble(run_config, input_filename: str = run_config.input_file mem_filename: str = run_config.input_mem_file + print(f"ROCHA HBM Size {run_config.hbm_size}") + print(f"ROCHA HBM Size in bytes {run_config.hbm_size * constants.Constants.KILOBYTE}") hbm_capcity_words: int = constants.convertBytes2Words(run_config.hbm_size * constants.Constants.KILOBYTE) + print(f"ROCHA HBM Size in words {hbm_capcity_words}") spad_capacity_words: int = constants.convertBytes2Words(run_config.spad_size * constants.Constants.KILOBYTE) num_register_banks: int = constants.MemoryModel.NUM_REGISTER_BANKS register_range: range = None @@ -316,7 +330,7 @@ def main(config: AssemblerRunConfig, verbose: bool = False): GlobalConfig.useHBMPlaceHolders = True #config.use_hbm_placeholders GlobalConfig.useXInstFetch = config.use_xinstfetch - GlobalConfig.supressComments = config.suppress_comments + GlobalConfig.suppressComments = config.suppress_comments GlobalConfig.hasHBM = config.has_hbm GlobalConfig.debugVerbose = config.debug_verbose @@ -358,6 +372,8 @@ def parse_args(): "File must be the result of pre-processing a P-ISA kernel with he_prep.py")) parser.add_argument("--isa_spec", default="", dest="isa_spec_file", help=("Input ISA specification (.json) file.")) + parser.add_argument("--mem_spec", default="", dest="mem_spec_file", + help=("Input Mem specification (.json) file.")) parser.add_argument("--input_mem_file", default="", help=("Input memory mapping file associated with the kernel. " "Defaults to the same name as the input file, but with `.mem` extension.")) parser.add_argument("--output_dir", default="", help=("Directory where to store all intermediate files and final output. " @@ -365,21 +381,17 @@ def parse_args(): "Defaults to the same directory as the input file.")) parser.add_argument("--output_prefix", default="", help=("Prefix for the output files. " "Defaults to the same the input file without extension.")) - parser.add_argument("--spad_size", type=int, default=AssemblerRunConfig.DEFAULT_SPAD_SIZE_KB, - help="Scratchpad size in KB. Defaults to {} KB.".format(AssemblerRunConfig.DEFAULT_SPAD_SIZE_KB)) - parser.add_argument("--hbm_size", type=int, default=AssemblerRunConfig.DEFAULT_HBM_SIZE_KB, - help="HBM size in KB. Defaults to {} KB.".format(AssemblerRunConfig.DEFAULT_HBM_SIZE_KB)) + parser.add_argument("--spad_size", type=int, help="Scratchpad size in KB.") + parser.add_argument("--hbm_size", type=int, help="HBM size in KB.") parser.add_argument("--no_hbm", dest="has_hbm", action="store_false", help="If set, this flag tells he_prep there is no HBM in the target chip.") - parser.add_argument("--repl_policy", default=AssemblerRunConfig.DEFAULT_REPL_POLICY, - choices=constants.Constants.REPLACEMENT_POLICIES, - help="Replacement policy for cache evictions. Defaults to {}.".format(AssemblerRunConfig.DEFAULT_REPL_POLICY)) + parser.add_argument("--repl_policy", choices=constants.Constants.REPLACEMENT_POLICIES, + help="Replacement policy for cache evictions.") parser.add_argument("--use_xinstfetch", dest="use_xinstfetch", action="store_true", help=("When enabled, `xinstfetch` instructions are generated in the CInstQ.")) parser.add_argument("--suppress_comments", "--no_comments", dest="suppress_comments", action="store_true", help=("When enabled, no comments will be emited on the output generated by the assembler.")) - parser.add_argument("--debug_verbose", type=int, default=0) - parser.add_argument("-v", "--verbose", dest="verbose", action="count", default=0, + parser.add_argument("-v", "--verbose", dest="debug_verbose", action="count", default=0, help=("If enabled, extra information and progress reports are printed to stdout. " "Increase level of verbosity by specifying flag multiple times, e.g. -vv")) args = parser.parse_args() @@ -390,12 +402,14 @@ def parse_args(): module_dir = os.path.dirname(__file__) module_name = os.path.basename(__file__) + # Initialize Defaults args = parse_args() - args.isa_spec_file = SpecConfig.initialize_isa_spec(module_dir, args.isa_spec_file) + args.isa_spec_file = ISASpecConfig.initialize_isa_spec(module_dir, args.isa_spec_file) + args.mem_spec_file = MemSpecConfig.initialize_mem_spec(module_dir, args.mem_spec_file) config = AssemblerRunConfig(**vars(args)) # convert argsparser into a dictionary - if args.verbose > 0: + if args.debug_verbose > 0: print(module_name) print() print("Run Configuration") @@ -403,9 +417,9 @@ def parse_args(): print(config) print("=================") print() + print(f"ROCHA he_as config {config}") + main(config, verbose = args.debug_verbose > 1) - main(config, verbose = args.verbose > 1) - - if args.verbose > 0: + if args.debug_verbose > 0: print() print(module_name, "- Complete") diff --git a/assembler_tools/hec-assembler-tools/he_link.py b/assembler_tools/hec-assembler-tools/he_link.py index b68439fe..e6296a0f 100644 --- a/assembler_tools/hec-assembler-tools/he_link.py +++ b/assembler_tools/hec-assembler-tools/he_link.py @@ -38,14 +38,13 @@ from assembler.common import makeUniquePath from assembler.common.counter import Counter from assembler.common.run_config import RunConfig -from assembler.common.run_config import static_initializer from assembler.common.config import GlobalConfig from assembler.memory_model import mem_info +from assembler.spec_config.mem_spec import MemSpecConfig from linker import loader from linker.steps import variable_discovery from linker.steps import program_linker -@static_initializer class LinkerRunConfig(RunConfig): """ Maintains the configuration data for the run. @@ -92,22 +91,26 @@ def __init__(self, **kwargs): At least, one of the arguments passed is invalid. """ - super().__init__(**kwargs) - - + self.init_default_config() + # class members based on configuration for config_name, default_value in self.__default_config.items(): - assert(not hasattr(self, config_name)) - setattr(self, config_name, kwargs.get(config_name, default_value)) - if getattr(self, config_name) is None: - raise TypeError(f'Expected value for configuration `{config_name}`, but `None` received.') + value = kwargs.get(config_name) + if value is not None: + assert(not hasattr(self, config_name)) + setattr(self, config_name, value) + else: + if not hasattr(self, config_name): + setattr(self, config_name, default_value) + if getattr(self, config_name) is None: + raise TypeError(f'Expected value for configuration `{config_name}`, but `None` received.') # fix file names self.output_dir = makeUniquePath(self.output_dir) self.input_mem_file = makeUniquePath(self.input_mem_file) @classmethod - def init_static(cls): + def init_default_config(cls): """ Initializes static members of the class. """ @@ -117,6 +120,9 @@ def init_static(cls): cls.__default_config["output_dir"] = os.getcwd() cls.__default_config["output_prefix"] = None cls.__default_config["has_hbm"] = True + cls.__default_config["hbm_size"] = cls.DEFAULT_HBM_SIZE_KB + cls.__default_config["use_xinstfetch"] = GlobalConfig.useXInstFetch + cls.__default_config["suppress_comments"] = GlobalConfig.suppressComments cls.__initialized = True @@ -327,6 +333,8 @@ def parse_args(): help=("List of input prefixes, including full path. For an input prefix, linker will " "assume three files exist named `input_prefixes[i] + '.minst'`, " "`input_prefixes[i] + '.cinst'`, and `input_prefixes[i] + '.xinst'`.")) + parser.add_argument("--mem_spec", default="", dest="mem_spec_file", + help=("Input Mem specification (.json) file.")) parser.add_argument("-im", "--input_mem_file", dest="input_mem_file", required=True, help=("Input memory mapping file associated with the resulting program. " "Specifies the names for input, output, and metadata variables for the full program. " @@ -343,8 +351,7 @@ def parse_args(): help=("Directory where to store all intermediate files and final output. " "This will be created if it doesn't exists. " "Defaults to current working directory.")) - parser.add_argument("--hbm_size", type=int, default=LinkerRunConfig.DEFAULT_HBM_SIZE_KB, - help="HBM size in KB. Defaults to {} KB.".format(LinkerRunConfig.DEFAULT_HBM_SIZE_KB)) + parser.add_argument("--hbm_size", type=int, help="HBM size in KB.") parser.add_argument("--no_hbm", dest="has_hbm", action="store_false", help="If set, this flag tells he_prep there is no HBM in the target chip.") parser.add_argument("--suppress_comments", "--no_comments", dest="suppress_comments", action="store_true", @@ -357,9 +364,12 @@ def parse_args(): return args if __name__ == "__main__": + module_dir = os.path.dirname(__file__) module_name = os.path.basename(__file__) args = parse_args() + args.mem_spec_file = MemSpecConfig.initialize_mem_spec(module_dir, args.mem_spec_file) + config = LinkerRunConfig(**vars(args)) # convert argsparser into a dictionary if args.verbose > 0: @@ -371,6 +381,7 @@ def parse_args(): print("=================") print() + print(f"ROCHA he_link config {config}") main(config, sys.stdout if args.verbose > 1 else None) if args.verbose > 0: diff --git a/assembler_tools/hec-assembler-tools/he_prep.py b/assembler_tools/hec-assembler-tools/he_prep.py index 7c207e99..234058cf 100644 --- a/assembler_tools/hec-assembler-tools/he_prep.py +++ b/assembler_tools/hec-assembler-tools/he_prep.py @@ -23,7 +23,8 @@ import time from assembler.common import constants -from assembler.isa_spec import SpecConfig +from assembler.spec_config.isa_spec import ISASpecConfig +from assembler.spec_config.mem_spec import MemSpecConfig from assembler.stages import preprocessor from assembler.memory_model import MemoryModel @@ -76,7 +77,8 @@ def main(output_file_name: str, output_file_name = ''.join(output_file_name[:-1] + (".tw",) + output_file_name[-1:]) hec_mem_model = MemoryModel(constants.MemoryModel.HBM.MAX_CAPACITY_WORDS, - constants.MemoryModel.SPAD.MAX_CAPACITY_WORDS) + constants.MemoryModel.SPAD.MAX_CAPACITY_WORDS, + constants.MemoryModel.NUM_REGISTER_BANKS) insts_listing = [] start_time = time.time() @@ -124,6 +126,8 @@ def parse_args(): parser.add_argument("output_file_name", nargs="?", help="Output file name. Defaults to .tw.") parser.add_argument("--isa_spec", default="", dest="isa_spec_file", help=("Input ISA specification (.json) file.")) + parser.add_argument("--mem_spec", default="", dest="mem_spec_file", + help=("Input Mem specification (.json) file.")) parser.add_argument("-v", "--verbose", dest="verbose", action="count", default=0, help=("If enabled, extra information and progress reports are printed to stdout. " "Increase level of verbosity by specifying flag multiple times, e.g. -vv")) @@ -137,7 +141,8 @@ def parse_args(): args = parse_args() - args.isa_spec_file = SpecConfig.initialize_isa_spec(module_dir, args.isa_spec_file) + args.isa_spec_file = ISASpecConfig.initialize_isa_spec(module_dir, args.isa_spec_file) + args.mem_spec_file = MemSpecConfig.initialize_mem_spec(module_dir, args.mem_spec_file) if args.verbose > 0: print(module_name) @@ -145,6 +150,7 @@ def parse_args(): print("Input: {0}".format(args.input_file_name)) print("Output: {0}".format(args.output_file_name)) print("ISA Spec: {0}".format(args.isa_spec_file)) + print("Mem Spec: {0}".format(args.mem_spec_file)) main(output_file_name=args.output_file_name, input_file_name=args.input_file_name, diff --git a/assembler_tools/hec-assembler-tools/linker/steps/program_linker.py b/assembler_tools/hec-assembler-tools/linker/steps/program_linker.py index d1377e39..89be1cbc 100644 --- a/assembler_tools/hec-assembler-tools/linker/steps/program_linker.py +++ b/assembler_tools/hec-assembler-tools/linker/steps/program_linker.py @@ -2,7 +2,7 @@ from linker import MemoryModel from linker.instructions import minst, cinst, xinst from assembler.common.config import GlobalConfig -from assembler.isa_spec import cinst as ISACInst +from assembler.instructions import cinst as ISACInst class LinkedProgram: """ From b98b244d7e0f120b7181957c476f1df408ef7188 Mon Sep 17 00:00:00 2001 From: "Rojas Chaves, Jose" Date: Tue, 3 Jun 2025 21:36:59 +0000 Subject: [PATCH 2/8] Refactoring json load --- .../assembler/common/run_config.py | 3 -- .../assembler/spec_config/mem_spec.py | 29 +++++++++++++++++++ assembler_tools/hec-assembler-tools/he_as.py | 7 +---- .../hec-assembler-tools/he_link.py | 1 - 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/assembler_tools/hec-assembler-tools/assembler/common/run_config.py b/assembler_tools/hec-assembler-tools/assembler/common/run_config.py index 296da3fe..9737a962 100644 --- a/assembler_tools/hec-assembler-tools/assembler/common/run_config.py +++ b/assembler_tools/hec-assembler-tools/assembler/common/run_config.py @@ -53,9 +53,7 @@ def __init__(self, """ # Initialize class members - print(f"ROCHA default configs {self.__default_config.items()}") for config_name, default_value in self.__default_config.items(): - print(f"ROCHA Setting attribute {config_name}") setattr(self, config_name, kwargs.get(config_name, default_value)) # Validate inputs @@ -82,7 +80,6 @@ def init_static(cls): This method sets up default configuration values for the class, ensuring that they are only initialized once. """ - print("ROCHA Super init static") if not cls.__initialized: cls.__default_config["hbm_size"] = cls.DEFAULT_HBM_SIZE_KB cls.__default_config["spad_size"] = cls.DEFAULT_SPAD_SIZE_KB diff --git a/assembler_tools/hec-assembler-tools/assembler/spec_config/mem_spec.py b/assembler_tools/hec-assembler-tools/assembler/spec_config/mem_spec.py index 0d37dd16..84b95602 100644 --- a/assembler_tools/hec-assembler-tools/assembler/spec_config/mem_spec.py +++ b/assembler_tools/hec-assembler-tools/assembler/spec_config/mem_spec.py @@ -1,4 +1,5 @@ import os +import re import json from assembler.common.constants import Constants, MemoryModel @@ -49,6 +50,7 @@ def dump_mem_spec_to_json(cls, filename): with open(filename, 'w') as json_file: json.dump(output_dict, json_file, indent=4) + @classmethod def init_mem_spec_from_json(cls, filename): """ @@ -67,10 +69,37 @@ def init_mem_spec_from_json(cls, filename): mem_spec = data["mem_spec"] + # Check for missing attributes + missing_keys = set(cls._target_attributes.keys()) - set(mem_spec.keys()) + if missing_keys: + raise ValueError(f"The JSON file is missing the following attributes: {', '.join(missing_keys)}") + + # Internal function to convert size expressions to bytes + def parse_size_expression(value): + size_map = { + 'kb': Constants.KILOBYTE, + 'mb': Constants.MEGABYTE, + 'gb': Constants.GIGABYTE, + 'kib': Constants.KILOBYTE, + 'mib': Constants.MEGABYTE, + 'gib': Constants.GIGABYTE, + 'b': 1 + } + value = value.strip() + match = re.match(r'^\s*(\d+(\.\d+)?)\s*(b|kb|mb|gb|tb|kib|mib|gib|tib)?\s*$', value.lower()) + if not match: + raise ValueError(f"Invalid size expression: {value}") + number, _, unit = match.groups() + unit = unit or 'b' # Default to bytes if no unit is specified + return int(float(number) * size_map[unit]) + for key, value in mem_spec.items(): if key not in cls._target_attributes: raise ValueError(f"Attribute key '{key}' is not valid.") else: + # Convert value to bytes if necessary + if 'bytes' in key: + value = parse_size_expression(str(value)) update_method = cls._target_attributes[key] update_method(value) diff --git a/assembler_tools/hec-assembler-tools/he_as.py b/assembler_tools/hec-assembler-tools/he_as.py index 2f1409b5..1facbf66 100644 --- a/assembler_tools/hec-assembler-tools/he_as.py +++ b/assembler_tools/hec-assembler-tools/he_as.py @@ -95,7 +95,6 @@ def __init__(self, **kwargs): self.init_default_config() # class members based on configuration - print("ROCHA RUN") for config_name, default_value in self.__default_config.items(): value = kwargs.get(config_name) if value is not None: @@ -136,7 +135,6 @@ def init_default_config(cls): cls.__default_config["output_dir"] = "" cls.__default_config["output_prefix"] = "" cls.__default_config["has_hbm"] = True - print(f"ROCHA Default HBM SIZE in KB {cls.DEFAULT_HBM_SIZE_KB}") cls.__default_config["hbm_size"] = cls.DEFAULT_HBM_SIZE_KB cls.__default_config["spad_size"] = cls.DEFAULT_SPAD_SIZE_KB cls.__default_config["repl_policy"] = cls.DEFAULT_REPL_POLICY @@ -197,10 +195,7 @@ def asmisaAssemble(run_config, input_filename: str = run_config.input_file mem_filename: str = run_config.input_mem_file - print(f"ROCHA HBM Size {run_config.hbm_size}") - print(f"ROCHA HBM Size in bytes {run_config.hbm_size * constants.Constants.KILOBYTE}") hbm_capcity_words: int = constants.convertBytes2Words(run_config.hbm_size * constants.Constants.KILOBYTE) - print(f"ROCHA HBM Size in words {hbm_capcity_words}") spad_capacity_words: int = constants.convertBytes2Words(run_config.spad_size * constants.Constants.KILOBYTE) num_register_banks: int = constants.MemoryModel.NUM_REGISTER_BANKS register_range: range = None @@ -417,7 +412,7 @@ def parse_args(): print(config) print("=================") print() - print(f"ROCHA he_as config {config}") + main(config, verbose = args.debug_verbose > 1) if args.debug_verbose > 0: diff --git a/assembler_tools/hec-assembler-tools/he_link.py b/assembler_tools/hec-assembler-tools/he_link.py index e6296a0f..21b834fd 100644 --- a/assembler_tools/hec-assembler-tools/he_link.py +++ b/assembler_tools/hec-assembler-tools/he_link.py @@ -381,7 +381,6 @@ def parse_args(): print("=================") print() - print(f"ROCHA he_link config {config}") main(config, sys.stdout if args.verbose > 1 else None) if args.verbose > 0: From 7c1d10edcd3b41b4b8f078c1438b835e5023114a Mon Sep 17 00:00:00 2001 From: "Rojas Chaves, Jose" Date: Tue, 3 Jun 2025 21:56:19 +0000 Subject: [PATCH 3/8] Cleaning --- .../assembler/common/constants.py | 4 +- .../assembler/spec_config/__init__.py | 0 .../assembler/spec_config/cinst/__init__.py | 638 ------------ .../assembler/spec_config/minst/__init__.py | 152 --- .../assembler/spec_config/xinst/__init__.py | 919 ------------------ .../hec-assembler-tools/config/mem_spec.json | 2 +- 6 files changed, 3 insertions(+), 1712 deletions(-) delete mode 100644 assembler_tools/hec-assembler-tools/assembler/spec_config/__init__.py delete mode 100644 assembler_tools/hec-assembler-tools/assembler/spec_config/cinst/__init__.py delete mode 100644 assembler_tools/hec-assembler-tools/assembler/spec_config/minst/__init__.py delete mode 100644 assembler_tools/hec-assembler-tools/assembler/spec_config/xinst/__init__.py diff --git a/assembler_tools/hec-assembler-tools/assembler/common/constants.py b/assembler_tools/hec-assembler-tools/assembler/common/constants.py index 16449667..1d9f9c29 100644 --- a/assembler_tools/hec-assembler-tools/assembler/common/constants.py +++ b/assembler_tools/hec-assembler-tools/assembler/common/constants.py @@ -23,8 +23,8 @@ class Constants: OPERATIONS (list): List of high-level operations supported by the system. """ - __MAX_BUNDLE_SIZE: int # = 64 - __XINSTRUCTION_SIZE_BYTES: int # = 8 + __MAX_BUNDLE_SIZE: int + __XINSTRUCTION_SIZE_BYTES: int # Data Constants # -------------- diff --git a/assembler_tools/hec-assembler-tools/assembler/spec_config/__init__.py b/assembler_tools/hec-assembler-tools/assembler/spec_config/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/assembler_tools/hec-assembler-tools/assembler/spec_config/cinst/__init__.py b/assembler_tools/hec-assembler-tools/assembler/spec_config/cinst/__init__.py deleted file mode 100644 index 6e827e85..00000000 --- a/assembler_tools/hec-assembler-tools/assembler/spec_config/cinst/__init__.py +++ /dev/null @@ -1,638 +0,0 @@ -from .. import ISASpecInstruction - -class BLoad(ISASpecInstruction): - """ - Represents a `bload` instruction. - - This instruction loads metadata from scratchpad to register file. - - For more information, check the `bload` Specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_bload.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 0. - """ - return 0 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 1. - """ - return 1 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 5. - """ - return 5 - -class BOnes(ISASpecInstruction): - """ - Represents a `bones` instruction. - - The `bones` instruction loads metadata of identity (one) from the scratchpad to the register file. - - For more information, check the `bones` Specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_bones.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 0. - """ - return 0 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 1. - """ - return 1 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 5. - """ - return 5 - -class Exit(ISASpecInstruction): - """ - Represents an `cexit` instruction. - - This instruction terminates execution of a HERACLES program. - - For more information, check the `cexit` Specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_cexit.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 0. - """ - return 0 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 0. - """ - return 0 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 1. - """ - return 1 - -class CLoad(ISASpecInstruction): - """ - Represents a `cload` instruction. - - This instruction loads a single polynomial residue from scratchpad into a register. - - For more information, check the `cload` Specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_cload.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 1. - """ - return 1 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 1. - """ - return 1 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 4. - """ - return 4 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 4. - """ - return 4 - -class Nop(ISASpecInstruction): - """ - Represents a `nop` instruction. - - This instruction adds desired amount of idle cycles in the Cfetch flow. - - For more information, check the `nop` Specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_nop.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 0. - """ - return 0 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 0. - """ - return 0 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 1. - """ - return 1 - -class CStore(ISASpecInstruction): - """ - Represents a `cstore` instruction. - - This instruction fetchs a single polynomial residue from the intermediate data buffer and store back to SPAD. - - For more information, check the `cstore` Specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_cstore.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 0. - """ - return 0 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 0. - """ - return 0 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 5. - """ - return 5 - -class CSyncM(ISASpecInstruction): - """ - Represents a `csyncm` instruction. - - Wait instruction similar to a barrier that stalls the execution of CINST - queue until the specified instruction from MINST queue has completed. - - For more information, check the `csyncm` Specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_csyncm.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 0. - """ - return 0 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 0. - """ - return 0 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 1. - """ - return 1 - -class iFetch(ISASpecInstruction): - """ - Represents an `ifetch` instruction. - - This instruction fetchs a bundle of instructions from the XINST queue and send it to the CE for execution. - - For more information, check the `ifetch` Specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_ifetch.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 0. - """ - return 0 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 0. - """ - return 0 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 5. - """ - return 5 - -class KGLoad(ISASpecInstruction): - """ - Represents a `kgload` instruction. - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 1. - """ - return 1 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 0. - """ - return 0 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 4. - """ - return 4 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 40. - """ - return 40 - -class KGSeed(ISASpecInstruction): - """ - Represents a `kgseed` instruction. - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 0. - """ - return 0 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 1. - """ - return 1 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 1. - """ - return 1 - -class KGStart(ISASpecInstruction): - """ - Represents a `kgstart` instruction. - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 0. - """ - return 0 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 0. - """ - return 0 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 40. - """ - return 40 - -class NLoad(ISASpecInstruction): - """ - Represents a `nload` instruction. - - This instruction loads metadata (for NTT/iNTT routing mapping) from - scratchpad into a special routing table register. - - For more information, check the `nload` Specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_nload.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 0. - """ - return 0 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 1. - """ - return 1 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 4. - """ - return 4 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 4. - """ - return 4 - -class XInstFetch(ISASpecInstruction): - """ - Represents an `xinstfetch` instruction. - - Fetches instructions from the HBM and sends it to the XINST queue. - - For more information, check the `xinstfetch` Specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/cinst/cinst_xinstfetch.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 0. - """ - return 0 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 0. - """ - return 0 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 1. - """ - return 1 \ No newline at end of file diff --git a/assembler_tools/hec-assembler-tools/assembler/spec_config/minst/__init__.py b/assembler_tools/hec-assembler-tools/assembler/spec_config/minst/__init__.py deleted file mode 100644 index 463df89b..00000000 --- a/assembler_tools/hec-assembler-tools/assembler/spec_config/minst/__init__.py +++ /dev/null @@ -1,152 +0,0 @@ -from .. import ISASpecInstruction - -class MLoad(ISASpecInstruction): - """ - Represents an `mload` instruction, inheriting from ISASpecInstruction. - - This instruction loads a single polynomial residue from local memory to scratchpad. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/minst/minst_mload.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands for the instruction. - - Returns: - int: The number of destination operands, which is 1. - """ - return 1 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands for the instruction. - - Returns: - int: The number of source operands, which is 1. - """ - return 1 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 1. - """ - return 1 - -class MStore(ISASpecInstruction): - """ - Represents an `mstore` instruction, inheriting from ISASpecInstruction. - - This instruction stores a single polynomial residue from scratchpad to local memory. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/minst/minst_mstore.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands for the instruction. - - Returns: - int: The number of destination operands, which is 1. - """ - return 1 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands for the instruction. - - Returns: - int: The number of source operands, which is 1. - """ - return 1 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 1. - """ - return 1 - -class MSyncC(ISASpecInstruction): - """ - Represents an MSyncC instruction, inheriting from ISASpecInstruction. - - Wait instruction similar to a barrier that stalls the execution of MINST - queue until the specified instruction from CINST queue has completed. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/minst/minst_msyncc.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands for the instruction. - - Returns: - int: The number of destination operands, which is 0. - """ - return 0 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands for the instruction. - - Returns: - int: The number of source operands, which is 0. - """ - return 0 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 1. - """ - return 1 \ No newline at end of file diff --git a/assembler_tools/hec-assembler-tools/assembler/spec_config/xinst/__init__.py b/assembler_tools/hec-assembler-tools/assembler/spec_config/xinst/__init__.py deleted file mode 100644 index 0fd3e554..00000000 --- a/assembler_tools/hec-assembler-tools/assembler/spec_config/xinst/__init__.py +++ /dev/null @@ -1,919 +0,0 @@ -from assembler.common.decorators import * -from .. import ISASpecInstruction - -class Add(ISASpecInstruction): - """ - Represents an `add` instruction. - - This instructions adds two polynomials stored in the register file and - store the result in a register. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_add.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 1. - """ - return 1 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 2. - """ - return 2 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 6. - """ - return 6 - -class Copy(ISASpecInstruction): - """ - Represents a Copy instruction. - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 1. - """ - return 1 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 1. - """ - return 1 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 6. - """ - return 6 - -class Exit(ISASpecInstruction): - """ - Represents an `exit` instruction. - - This instruction terminates execution of an instruction bundle. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_exit.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 0. - """ - return 0 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 0. - """ - return 0 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 1. - """ - return 1 - -class iNTT(ISASpecInstruction): - """ - Represents an `intt` instruction. - - The Inverse Number Theoretic Transform (iNTT), converts NTT form to positional form. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_intt.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 2. - """ - return 2 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 3. - """ - return 3 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 6. - """ - return 6 - -class irShuffle(ISASpecInstruction): - """ - Represents an irShuffle instruction with special latency properties. - - Properties: - SpecialLatency: Indicates the first increment at which another irshuffle instruction - can be scheduled within `SpecialLatencyMax` latency. - SpecialLatencyMax: Cannot enqueue any other irshuffle instruction within this latency - unless it is in `SpecialLatencyIncrement`. - SpecialLatencyIncrement: Can only enqueue any other irshuffle instruction - within `SpecialLatencyMax` only in increments of this value. - """ - - @classproperty - def SpecialLatency(cls): - """ - Special latency (indicates the first increment at which another irshuffle instruction - can be scheduled within `SpecialLatencyMax` latency). - - Returns: - int: The special latency increment. - """ - return cls.SpecialLatencyIncrement - - @classproperty - def SpecialLatencyMax(cls): - """ - Special latency maximum (cannot enqueue any other irshuffle instruction within this latency - unless it is in `SpecialLatencyIncrement`). - - Returns: - int: The special latency maximum, which is 17. - """ - return 17 - - @classproperty - def SpecialLatencyIncrement(cls): - """ - Special latency increment (can only enqueue any other irshuffle instruction - within `SpecialLatencyMax` only in increments of this value). - - Returns: - int: The special latency increment, which is 5. - """ - return 5 - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 2. - """ - return 2 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 2. - """ - return 2 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 23. - """ - return 23 - -class Mac(ISASpecInstruction): - """ - Represents a `mac` instruction. - - Element-wise polynomial multiplication and accumulation. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_mac.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 1. - """ - return 1 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 2. - """ - return 2 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 6. - """ - return 6 - -class Maci(ISASpecInstruction): - """ - Represents a `maci` instruction. - - Element-wise polynomial scaling by an immediate value and accumulation. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_maci.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 1. - """ - return 1 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 1. - """ - return 1 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 6. - """ - return 6 - -class Move(ISASpecInstruction): - """ - Represents a `move` instruction. - - This instruction copies data from one register to a different one. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_move.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 1. - """ - return 1 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 1. - """ - return 1 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 6. - """ - return 6 - -class Mul(ISASpecInstruction): - """ - Represents a `mul` instruction. - - This instructions performs element-wise polynomial multiplication. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_mul.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 1. - """ - return 1 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 2. - """ - return 2 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 6. - """ - return 6 - -class Muli(ISASpecInstruction): - """ - Represents a Muli instruction. - - This instruction performs element-wise polynomial scaling by an immediate value. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_muli.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 1. - """ - return 1 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 1. - """ - return 1 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 6. - """ - return 6 - -class Nop(ISASpecInstruction): - """ - Represents a `nop` instruction. - - This instruction adds a desired amount of idle cycles to the compute flow. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_nop.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 0. - """ - return 0 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 0. - """ - return 0 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 1. - """ - return 1 - -class NTT(ISASpecInstruction): - """ - Represents an `ntt` instruction (Number Theoretic Transform). - Converts positional form to NTT form. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_ntt.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 2. - """ - return 2 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 3. - """ - return 3 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 6. - """ - return 6 - -class rShuffle(ISASpecInstruction): - """ - Represents an rShuffle instruction with special latency properties. - - Properties: - SpecialLatency: Indicates the first increment at which another rshuffle instruction - can be scheduled within `SpecialLatencyMax` latency. - SpecialLatencyMax: Cannot enqueue any other rshuffle instruction within this latency - unless it is in `SpecialLatencyIncrement`. - SpecialLatencyIncrement: Can only enqueue any other rshuffle instruction - within `SpecialLatencyMax` only in increments of this value. - """ - - @classproperty - def SpecialLatency(cls): - """ - Special latency (indicates the first increment at which another rshuffle instruction - can be scheduled within `SpecialLatencyMax` latency). - - Returns: - int: The special latency increment. - """ - return cls.SpecialLatencyIncrement - - @classproperty - def SpecialLatencyMax(cls): - """ - Special latency maximum (cannot enqueue any other rshuffle instruction within this latency - unless it is in `SpecialLatencyIncrement`). - - Returns: - int: The special latency maximum, which is 17. - """ - return 17 - - @classproperty - def SpecialLatencyIncrement(cls): - """ - Special latency increment (can only enqueue any other rshuffle instruction - within `SpecialLatencyMax` only in increments of this value). - - Returns: - int: The special latency increment, which is 5. - """ - return 5 - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 2. - """ - return 2 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 2. - """ - return 2 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 23. - """ - return 23 - -class Sub(ISASpecInstruction): - """ - Represents a `sub` instruction. - - Element-wise polynomial subtraction. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_sub.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 1. - """ - return 1 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 2. - """ - return 2 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 6. - """ - return 6 - -class twiNTT(ISASpecInstruction): - """ - Represents a `twintt` instruction. - - This instruction performs on-die generation of twiddle factors for the next stage of iNTT. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_twintt.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 1. - """ - return 1 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 1. - """ - return 1 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 6. - """ - return 6 - -class twNTT(ISASpecInstruction): - """ - Represents a `twntt` instruction. - - This instruction performs on-die generation of twiddle factors for the next stage of NTT. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_twntt.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 1. - """ - return 1 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 1. - """ - return 1 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 6. - """ - return 6 - -class xStore(ISASpecInstruction): - """ - Represents an `xstore` instruction. - - This instruction transfers data from a register into the intermediate data buffer for subsequent transfer into SPAD. - - For more information, check the specification: - https://github.com/IntelLabs/hec-assembler-tools/blob/master/docsrc/inst_spec/xinst/xinst_xstore.md - """ - - @classmethod - def _get_numDests(cls) -> int: - """ - Gets the number of destination operands. - - Returns: - int: The number of destination operands, which is 1. - """ - return 1 - - @classmethod - def _get_numSources(cls) -> int: - """ - Gets the number of source operands. - - Returns: - int: The number of source operands, which is 1. - """ - return 1 - - @classmethod - def _get_throughput(cls) -> int: - """ - Gets the throughput of the instruction. - - Returns: - int: The throughput, which is 1. - """ - return 1 - - @classmethod - def _get_latency(cls) -> int: - """ - Gets the latency of the instruction. - - Returns: - int: The latency, which is 6. - """ - return 6 \ No newline at end of file diff --git a/assembler_tools/hec-assembler-tools/config/mem_spec.json b/assembler_tools/hec-assembler-tools/config/mem_spec.json index c48c3356..085ae6c6 100644 --- a/assembler_tools/hec-assembler-tools/config/mem_spec.json +++ b/assembler_tools/hec-assembler-tools/config/mem_spec.json @@ -18,4 +18,4 @@ "twiddle_meta_register_size_in_bytes": 8192, "max_residuals": 64 } -} \ No newline at end of file +} From 269d043d6475475d4d995efddc432dd9814b5277 Mon Sep 17 00:00:00 2001 From: "Rojas Chaves, Jose" Date: Tue, 3 Jun 2025 21:56:19 +0000 Subject: [PATCH 4/8] Cleaning --- .../assembler/common/constants.py | 26 +++++++++---------- .../assembler/stages/asm_scheduler.py | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/assembler_tools/hec-assembler-tools/assembler/common/constants.py b/assembler_tools/hec-assembler-tools/assembler/common/constants.py index 1d9f9c29..24666034 100644 --- a/assembler_tools/hec-assembler-tools/assembler/common/constants.py +++ b/assembler_tools/hec-assembler-tools/assembler/common/constants.py @@ -312,21 +312,21 @@ class MemoryModel: HBM and SPAD. """ - __XINST_QUEUE_MAX_CAPACITY: int # = 1 * Constants.MEGABYTE - __CINST_QUEUE_MAX_CAPACITY: int # = 128 * Constants.KILOBYTE - __MINST_QUEUE_MAX_CAPACITY: int # = 128 * Constants.KILOBYTE - __STORE_BUFFER_MAX_CAPACITY: int # = 128 * Constants.KILOBYTE + __XINST_QUEUE_MAX_CAPACITY: int + __CINST_QUEUE_MAX_CAPACITY: int + __MINST_QUEUE_MAX_CAPACITY: int + __STORE_BUFFER_MAX_CAPACITY: int # Class-level attributes - __NUM_BLOCKS_PER_TWID_META_WORD: int # = 4 - __NUM_BLOCKS_PER_KGSEED_META_WORD: int # = 4 - __NUM_ROUTING_TABLE_REGISTERS: int # = 1 - __NUM_ONES_META_REGISTERS: int # = 1 - __NUM_TWIDDLE_META_REGISTERS: int # = 32 * __NUM_ONES_META_REGISTERS - __TWIDDLE_META_REGISTER_SIZE_BYTES: int # = 8 * Constants.KILOBYTE - __MAX_RESIDUALS: int # = __NUM_TWIDDLE_META_REGISTERS * 2 - __NUM_REGISTER_BANKS: int # = 4 - __NUM_REGISTERS_PER_BANK: int # = 72 + __NUM_BLOCKS_PER_TWID_META_WORD: int + __NUM_BLOCKS_PER_KGSEED_META_WORD: int + __NUM_ROUTING_TABLE_REGISTERS: int + __NUM_ONES_META_REGISTERS: int + __NUM_TWIDDLE_META_REGISTERS: int + __TWIDDLE_META_REGISTER_SIZE_BYTES: int + __MAX_RESIDUALS: int + __NUM_REGISTER_BANKS: int + __NUM_REGISTERS_PER_BANK: int @classproperty def XINST_QUEUE_MAX_CAPACITY(cls): diff --git a/assembler_tools/hec-assembler-tools/assembler/stages/asm_scheduler.py b/assembler_tools/hec-assembler-tools/assembler/stages/asm_scheduler.py index 59a3d9b3..c895dbe8 100644 --- a/assembler_tools/hec-assembler-tools/assembler/stages/asm_scheduler.py +++ b/assembler_tools/hec-assembler-tools/assembler/stages/asm_scheduler.py @@ -352,7 +352,7 @@ def __init__(self, # Amount of instructions for a bundle to be considered short @property def BUNDLE_INSTRUCTION_MIN_LIMIT(self): - return Constants.MAX_BUNDLE_SIZE // 4 # 10 + return Constants.MAX_BUNDLE_SIZE // 4 @property def last_xinstr(self) -> object: From b4d887c9ee11c06b09a7da8635df05e7b573a9c7 Mon Sep 17 00:00:00 2001 From: "Rojas Chaves, Jose" Date: Tue, 3 Jun 2025 21:56:19 +0000 Subject: [PATCH 5/8] Change key naming --- .../assembler/common/constants.py | 16 ++++++++-------- .../assembler/spec_config/mem_spec.py | 12 ++++++------ .../hec-assembler-tools/config/mem_spec.json | 12 ++++++------ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/assembler_tools/hec-assembler-tools/assembler/common/constants.py b/assembler_tools/hec-assembler-tools/assembler/common/constants.py index 24666034..999f84f3 100644 --- a/assembler_tools/hec-assembler-tools/assembler/common/constants.py +++ b/assembler_tools/hec-assembler-tools/assembler/common/constants.py @@ -432,10 +432,10 @@ def hw_spec_as_dict(cls) -> dict: """ Returns hw configurable attributes as dictionary. """ - dict = {"xinst_queue_size_in_bytes": cls.__XINST_QUEUE_MAX_CAPACITY, - "cinst_queue_size_in_bytes": cls.__CINST_QUEUE_MAX_CAPACITY, - "minst_queue_size_in_bytes": cls.__MINST_QUEUE_MAX_CAPACITY, - "store_buffer_size_in_bytes": cls.__STORE_BUFFER_MAX_CAPACITY, + dict = {"max_xinst_queue_size_in_bytes": cls.__XINST_QUEUE_MAX_CAPACITY, + "max_cinst_queue_size_in_bytes": cls.__CINST_QUEUE_MAX_CAPACITY, + "max_minst_queue_size_in_bytes": cls.__MINST_QUEUE_MAX_CAPACITY, + "max_store_buffer_size_in_bytes": cls.__STORE_BUFFER_MAX_CAPACITY, "num_blocks_per_twid_meta_word": cls.NUM_BLOCKS_PER_TWID_META_WORD, "num_blocks_per_kgseed_meta_word": cls.NUM_BLOCKS_PER_KGSEED_META_WORD, "num_routing_table_registers": cls.NUM_ROUTING_TABLE_REGISTERS, @@ -544,7 +544,7 @@ class HBM: This class defines the maximum capacity of HBM in both bytes and words. """ - __MAX_CAPACITY: int # = 64 * Constants.GIGABYTE + __MAX_CAPACITY: int @classproperty def MAX_CAPACITY(cls) -> int: @@ -561,7 +561,7 @@ def hw_spec_as_dict(cls) -> dict: """ Returns hw configurable attributes as dictionary. """ - dict = {"hbm_size_in_bytes": cls.__MAX_CAPACITY} + dict = {"max_hbm_size_in_bytes": cls.__MAX_CAPACITY} return dict @classmethod @@ -577,7 +577,7 @@ class SPAD: This class defines the maximum capacity of SPAD in both bytes and words. """ - __MAX_CAPACITY: int # = 64 * Constants.MEGABYTE + __MAX_CAPACITY: int # Class methods and properties # ---------------------------- @@ -597,7 +597,7 @@ def hw_spec_as_dict(cls) -> dict: """ Returns hw configurable attributes as dictionary. """ - dict = {"cache_size_in_bytes": cls.__MAX_CAPACITY} + dict = {"max_cache_size_in_bytes": cls.__MAX_CAPACITY} return dict @classmethod diff --git a/assembler_tools/hec-assembler-tools/assembler/spec_config/mem_spec.py b/assembler_tools/hec-assembler-tools/assembler/spec_config/mem_spec.py index 84b95602..0fb5a061 100644 --- a/assembler_tools/hec-assembler-tools/assembler/spec_config/mem_spec.py +++ b/assembler_tools/hec-assembler-tools/assembler/spec_config/mem_spec.py @@ -8,10 +8,10 @@ class MemSpecConfig: _target_attributes = { "bytes_per_xinstruction": Constants.setXInstructionSizeBytes, "max_instructions_per_bundle": Constants.setMaxBundleSize, - "xinst_queue_size_in_bytes": MemoryModel.setMaxXInstQueueCapacity, - "cinst_queue_size_in_bytes": MemoryModel.setMaxCInstQueueCapacity, - "minst_queue_size_in_bytes": MemoryModel.setMaxMInstQueueCapacity, - "store_buffer_size_in_bytes": MemoryModel.setMaxStoreBufferCapacity, + "max_xinst_queue_size_in_bytes": MemoryModel.setMaxXInstQueueCapacity, + "max_cinst_queue_size_in_bytes": MemoryModel.setMaxCInstQueueCapacity, + "max_minst_queue_size_in_bytes": MemoryModel.setMaxMInstQueueCapacity, + "max_store_buffer_size_in_bytes": MemoryModel.setMaxStoreBufferCapacity, "num_blocks_per_twid_meta_word": MemoryModel.setNumBlocksPerTwidMetaWord, "num_blocks_per_kgseed_meta_word": MemoryModel.setNumBlocksPerKgseedMetaWord, "num_routing_table_registers": MemoryModel.setNumRoutingTableRegisters, @@ -21,8 +21,8 @@ class MemSpecConfig: "max_residuals": MemoryModel.setMaxResiduals, "num_register_banks": MemoryModel.setNumRegisterBanks, "num_registers_per_bank": MemoryModel.setNumRegistersPerBank, - "hbm_size_in_bytes": MemoryModel.HBM.setMaxCapacity, - "cache_size_in_bytes": MemoryModel.SPAD.setMaxCapacity, + "max_hbm_size_in_bytes": MemoryModel.HBM.setMaxCapacity, + "max_cache_size_in_bytes": MemoryModel.SPAD.setMaxCapacity, } @classmethod diff --git a/assembler_tools/hec-assembler-tools/config/mem_spec.json b/assembler_tools/hec-assembler-tools/config/mem_spec.json index 085ae6c6..1a849839 100644 --- a/assembler_tools/hec-assembler-tools/config/mem_spec.json +++ b/assembler_tools/hec-assembler-tools/config/mem_spec.json @@ -1,11 +1,11 @@ { "mem_spec": { - "cache_size_in_bytes": 67108864, - "hbm_size_in_bytes": 68719476736, - "xinst_queue_size_in_bytes": 1048576, - "cinst_queue_size_in_bytes": 131072, - "minst_queue_size_in_bytes": 131072, - "store_buffer_size_in_bytes": 131072, + "max_cache_size_in_bytes": 67108864, + "max_hbm_size_in_bytes": 68719476736, + "max_xinst_queue_size_in_bytes": 1048576, + "max_cinst_queue_size_in_bytes": 131072, + "max_minst_queue_size_in_bytes": 131072, + "max_store_buffer_size_in_bytes": 131072, "num_register_banks": 4, "num_registers_per_bank": 72, "bytes_per_xinstruction": 8, From 5104bea4e5e8ca045a21ad3292ee194e1d22ebce Mon Sep 17 00:00:00 2001 From: "Rojas Chaves, Jose" Date: Wed, 4 Jun 2025 15:33:11 +0000 Subject: [PATCH 6/8] Adding documentation --- assembler_tools/hec-assembler-tools/README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/assembler_tools/hec-assembler-tools/README.md b/assembler_tools/hec-assembler-tools/README.md index a410b92f..ec3456dd 100644 --- a/assembler_tools/hec-assembler-tools/README.md +++ b/assembler_tools/hec-assembler-tools/README.md @@ -9,6 +9,7 @@ The tools in this directory are the reference implementation of and Assembler co 1. [Assembler Instruction Specs](#asm_specs) 4. [Executing the Assembler](#executing_asm) 1. [Running for a Pre-Generated Kernel](#executing_single) + 2. [Hardware Spec Configuration](#spec_configuration) 5. [Debug Tools](./debug_tools/README.md) ## Dependencies @@ -98,3 +99,21 @@ python3 he_prep.py -h python3 he_as.py -h python3 he_link.py -h ``` + +### Hardware Spec Configuration + +#### Default Configuration +The HERACLES assembler comes with default configurations for ISA and Memory parameters. These configurations are defined in JSON files located in the config folder: +- **ISA Specification:** config/isa_spec.json +- **Memory Specification:** config/mem_spec.json + +These files contain default values for various parameters that affect the behavior of the assembler and linker. Users can modify these files directly, but it is recommended to create a copy and use the command-line flags to specify the path to the modified configuration files. This approach ensures that the original default files remain unchanged and can be used as a reference. + +#### Modifying Configuration +To modify the ISA or Memory specifications, follow these steps: +- Create a Copy: Copy the default JSON files from the config folder to a new location. +- Edit the Copy: Modify the parameters in the copied JSON files as needed. +- **Specify the Path:** Use the **--isa_spec** and **--mem_spec** command-line flags to specify the path to your modified configuration files when running the scripts. + +#### Additional Notes +Memory Parameters: For he_as.py and he_link.py, certain memory parameters like spad_size and hbm_size can be overwritten directly from the command line, providing flexibility in configuration without modifying the JSON files. \ No newline at end of file From e06b69a9f5b33eaa4816a79917548ba04fe56ca7 Mon Sep 17 00:00:00 2001 From: "Rojas Chaves, Jose" Date: Thu, 5 Jun 2025 17:00:53 +0000 Subject: [PATCH 7/8] Config format --- .../hec-assembler-tools/config/mem_spec.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assembler_tools/hec-assembler-tools/config/mem_spec.json b/assembler_tools/hec-assembler-tools/config/mem_spec.json index 1a849839..503b47d6 100644 --- a/assembler_tools/hec-assembler-tools/config/mem_spec.json +++ b/assembler_tools/hec-assembler-tools/config/mem_spec.json @@ -1,21 +1,21 @@ { "mem_spec": { - "max_cache_size_in_bytes": 67108864, - "max_hbm_size_in_bytes": 68719476736, - "max_xinst_queue_size_in_bytes": 1048576, - "max_cinst_queue_size_in_bytes": 131072, - "max_minst_queue_size_in_bytes": 131072, - "max_store_buffer_size_in_bytes": 131072, + "max_cache_size_in_bytes": "64 MiB", + "max_hbm_size_in_bytes": "64 GiB", + "max_xinst_queue_size_in_bytes": "1 MiB", + "max_cinst_queue_size_in_bytes": "128 KiB", + "max_minst_queue_size_in_bytes": "128 KiB", + "max_store_buffer_size_in_bytes": "128 KiB", "num_register_banks": 4, "num_registers_per_bank": 72, "bytes_per_xinstruction": 8, "max_instructions_per_bundle": 64, "num_blocks_per_twid_meta_word": 4, "num_blocks_per_kgseed_meta_word": 4, - "num_routing_table_registers": 1, + "num_routing_table_registers": 2, "num_ones_meta_registers": 1, "num_twiddle_meta_registers": 32, - "twiddle_meta_register_size_in_bytes": 8192, + "twiddle_meta_register_size_in_bytes": "8 KiB", "max_residuals": 64 } } From cbdaf3893ff3fdcde95a3b6dbdf8248a57ab6814 Mon Sep 17 00:00:00 2001 From: "Rojas Chaves, Jose" Date: Thu, 5 Jun 2025 17:02:17 +0000 Subject: [PATCH 8/8] Fix Config Value --- assembler_tools/hec-assembler-tools/config/mem_spec.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assembler_tools/hec-assembler-tools/config/mem_spec.json b/assembler_tools/hec-assembler-tools/config/mem_spec.json index 503b47d6..c417d12c 100644 --- a/assembler_tools/hec-assembler-tools/config/mem_spec.json +++ b/assembler_tools/hec-assembler-tools/config/mem_spec.json @@ -12,7 +12,7 @@ "max_instructions_per_bundle": 64, "num_blocks_per_twid_meta_word": 4, "num_blocks_per_kgseed_meta_word": 4, - "num_routing_table_registers": 2, + "num_routing_table_registers": 1, "num_ones_meta_registers": 1, "num_twiddle_meta_registers": 32, "twiddle_meta_register_size_in_bytes": "8 KiB",