Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions assembler_tools/hec-assembler-tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <a name="dependencies"></a>
Expand Down Expand Up @@ -98,3 +99,21 @@ python3 he_prep.py -h
python3 he_as.py -h
python3 he_link.py -h
```

### Hardware Spec Configuration <a name="spec_configuration"></a>

#### 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.
228 changes: 198 additions & 30 deletions assembler_tools/hec-assembler-tools/assembler/common/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ class Constants:
OPERATIONS (list): List of high-level operations supported by the system.
"""

__MAX_BUNDLE_SIZE: int
__XINSTRUCTION_SIZE_BYTES: int

# Data Constants
# --------------

Expand Down Expand Up @@ -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:
Expand All @@ -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.
Expand Down Expand Up @@ -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
__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
__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):
Expand All @@ -306,41 +335,41 @@ 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."""
return cls.__CINST_QUEUE_MAX_CAPACITY
@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."""
return cls.__MINST_QUEUE_MAX_CAPACITY
@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."""
return cls.__STORE_BUFFER_MAX_CAPACITY
@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:
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -371,41 +400,151 @@ 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:
"""
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 = {"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,
"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:
"""
Constants related to High Bandwidth Memory (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

@classproperty
def MAX_CAPACITY(cls) -> int:
Expand All @@ -415,16 +554,30 @@ 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 = {"max_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:
"""
Constants related to Scratchpad Memory (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

# Class methods and properties
# ----------------------------
Expand All @@ -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 = {"max_cache_size_in_bytes": cls.__MAX_CAPACITY}
return dict

@classmethod
def setMaxCapacity(cls, val: int):
"""
Sets max SPAD Capacity
"""
cls.__MAX_CAPACITY = val
Loading