Skip to content

Commit a06a537

Browse files
authored
[hec-assembler]: Enables splitting at he_prep (#140)
* Adding Kernel Splitter * Updating tests moving dinst
1 parent b7da02c commit a06a537

File tree

27 files changed

+1333
-116
lines changed

27 files changed

+1333
-116
lines changed

assembler_tools/hec-assembler-tools/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ Given a P-ISA kernel (`filename.csv`) and corresponding memory mapping file (`fi
6565
python3 he_prep.py filename.csv
6666
```
6767

68+
The preprocessing program can split kernels (see he_prep.py -h for details). Use the split options if you encounter physical memory constraints.
69+
70+
# pre-process kernel: outputs filename1.tw_<#>.csv & filename1.tw_deps_<#>.csv
71+
python3 he_prep.py filename1.csv --mem_file filename0.mem --split_vars_limit <val> --split_inst_limit <val>
72+
```
73+
6874
2. Assemble the pre-processed result using `he_as.py`.
6975
7076
```bash

assembler_tools/hec-assembler-tools/linker/instructions/dinst/dinstruction.py renamed to assembler_tools/hec-assembler-tools/assembler/common/dinst/dinstruction.py

Lines changed: 86 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@
1111
assembly process, providing common functionality and interfaces.
1212
"""
1313

14+
from assembler.common.config import GlobalConfig
1415
from assembler.common.counter import Counter
1516
from assembler.common.decorators import classproperty
1617
from assembler.memory_model.mem_info import MemInfo
1718

18-
from linker.instructions.instruction import BaseInstruction
1919

20-
21-
class DInstruction(BaseInstruction):
20+
class DInstruction:
2221
"""
2322
@brief Represents a DInstruction, inheriting from BaseInstruction.
2423
"""
@@ -27,16 +26,6 @@ class DInstruction(BaseInstruction):
2726
_var: str = ""
2827
_address: int = 0
2928

30-
@classmethod
31-
def _get_name(cls) -> str:
32-
"""
33-
@brief Derived classes should implement this method and return correct
34-
name for the instruction.
35-
36-
@throws NotImplementedError Abstract method. This base method should not be called.
37-
"""
38-
raise NotImplementedError()
39-
4029
@classmethod
4130
def _get_name_token_index(cls) -> int:
4231
"""
@@ -90,13 +79,13 @@ def __init__(self, tokens: list, comment: str = ""):
9079
@param tokens List of tokens for the instruction.
9180
@param comment Optional comment for the instruction.
9281
"""
93-
# Do not increment the global instruction count; skip BaseInstruction's __init__ logic for __id
94-
# Perform our own initialization
95-
super().__init__(tokens, comment=comment, count=False)
82+
assert self.name_token_index < self.num_tokens
83+
84+
self._validate_tokens(tokens)
9685

9786
self.comment = comment
9887
self._tokens = list(tokens)
99-
self._local_id = next(DInstruction._local_id_count)
88+
self._id = next(DInstruction._local_id_count)
10089

10190
try:
10291
miv, _ = MemInfo.get_meminfo_var_from_tokens(tokens)
@@ -107,6 +96,20 @@ def __init__(self, tokens: list, comment: str = ""):
10796
except RuntimeError as e:
10897
raise ValueError(f"Failed to parse memory info from tokens: {tokens}. Error: {str(e)}") from e
10998

99+
def __repr__(self):
100+
retval = f"<{type(self).__name__}({self.name}, id={self.id}) object at {hex(id(self))}>(tokens={self.tokens})"
101+
return retval
102+
103+
def __eq__(self, other):
104+
# Equality operator== overload
105+
return self is other
106+
107+
def __hash__(self):
108+
return hash(self.id)
109+
110+
def __str__(self):
111+
return f"{self.name}({self.id})"
112+
110113
@property
111114
def id(self):
112115
"""
@@ -116,7 +119,7 @@ def id(self):
116119
117120
@return (client_id: int, nonce: int) where client_id is the id specified at construction.
118121
"""
119-
return self._local_id
122+
return self._id
120123

121124
@property
122125
def var(self) -> str:
@@ -153,3 +156,68 @@ def address(self, value: int):
153156
@param value The new memory address (string or integer).
154157
"""
155158
self._address = value
159+
160+
@classproperty
161+
def name(self) -> str:
162+
"""
163+
@brief Name for the instruction.
164+
165+
@return The name of the instruction.
166+
"""
167+
return self._get_name()
168+
169+
@classmethod
170+
def _get_name(cls) -> str:
171+
"""
172+
@brief Derived classes should implement this method and return correct
173+
name for the instruction.
174+
175+
@throws NotImplementedError Abstract method. This base method should not be called.
176+
"""
177+
raise NotImplementedError()
178+
179+
@classproperty
180+
def name_token_index(self) -> int:
181+
"""
182+
@brief Index for the token containing the name of the instruction
183+
in the list of tokens.
184+
185+
@return The index of the name token.
186+
"""
187+
return self._get_name_token_index()
188+
189+
@classmethod
190+
def dump_instructions_to_file(cls, instructions: list, filename: str):
191+
"""
192+
@brief Writes a list of instruction objects to a file, one per line.
193+
194+
Each instruction is converted to its string representation using the `to_line()` method.
195+
196+
@param instructions List of instruction objects (must have a to_line() method).
197+
@param filename Path to the output file.
198+
"""
199+
with open(filename, "w", encoding="utf-8") as f:
200+
for instr in instructions:
201+
f.write(instr.to_line() + "\n")
202+
203+
@property
204+
def tokens(self) -> list:
205+
"""
206+
@brief Gets the list of tokens for the instruction.
207+
208+
@return The list of tokens.
209+
"""
210+
return self._tokens
211+
212+
def to_line(self) -> str:
213+
"""
214+
@brief Retrieves the string form of the instruction to write to the instruction file.
215+
216+
@return The string representation of the instruction.
217+
"""
218+
comment_str = ""
219+
if not GlobalConfig.suppress_comments:
220+
comment_str = f" # {self.comment}" if self.comment else ""
221+
222+
tokens_str = ", ".join(self.tokens)
223+
return f"{tokens_str}{comment_str}"

assembler_tools/hec-assembler-tools/assembler/instructions/xinst/__init__.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,24 @@ def createFromParsedObj(mem_model: MemoryModel, inst_type, parsed_op, new_id: in
121121
return inst_type(new_id, **parsed_op)
122122

123123

124+
def getParsedOpFromPISALine(line: str, line_no: int):
125+
"""
126+
@brief Parses a P-ISA line and returns the parsed operation.
127+
This function attempts to parse a line of P-ISA code and returns the corresponding parsed operation
128+
if successful.
129+
@param line The line of P-ISA code to parse.
130+
@return The parsed operation if the line is successfully parsed; otherwise, None.
131+
"""
132+
try:
133+
for inst_type in __PISA_INSTRUCTIONS:
134+
parsed_op = inst_type.parseFromPISALine(line)
135+
if parsed_op:
136+
return parsed_op
137+
except Exception as ex:
138+
raise Exception(f"line {line_no}: {line}.") from ex
139+
return None
140+
141+
124142
def createFromPISALine(mem_model: MemoryModel, line: str, line_no: int = 0) -> XInstruction:
125143
"""
126144
Parses an XInst from the specified string (in P-ISA kernel input format) and returns a

assembler_tools/hec-assembler-tools/assembler/instructions/xinst/ntt.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def parseFromPISALine(cls, line: str) -> object:
8585
dst_src = cls.parsePISASourceDestsFromTokens(instr_tokens, cls._OP_NUM_DESTS, cls._OP_NUM_SOURCES, params_start)
8686
retval.update(dst_src)
8787
retval["stage"] = int(instr_tokens[params_end])
88-
retval["res"] = int(instr_tokens[params_end + 1])
88+
retval["res"] = int(instr_tokens[params_end + 1]) if len(instr_tokens) > params_end + 1 else 0
8989

9090
retval = Namespace(**retval)
9191
assert retval.op_name == cls.op_name_pisa

0 commit comments

Comments
 (0)