femtocrux 2.5.1__py3-none-any.whl → 3.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- femtocrux/VERSION +1 -1
- femtocrux/__init__.py +8 -1
- femtocrux/client/client.py +116 -23
- femtocrux/grpc/compiler_service_pb2.py +25 -25
- femtocrux/grpc/compiler_service_pb2_grpc.py +3 -3
- femtocrux/server/compiler_frontend.py +40 -25
- femtocrux/server/server.py +43 -20
- {femtocrux-2.5.1.dist-info → femtocrux-3.0.0.dist-info}/METADATA +1 -1
- femtocrux-3.0.0.dist-info/RECORD +22 -0
- femtocrux-2.5.1.dist-info/RECORD +0 -22
- {femtocrux-2.5.1.dist-info → femtocrux-3.0.0.dist-info}/WHEEL +0 -0
- {femtocrux-2.5.1.dist-info → femtocrux-3.0.0.dist-info}/licenses/LICENSE +0 -0
- {femtocrux-2.5.1.dist-info → femtocrux-3.0.0.dist-info}/top_level.txt +0 -0
femtocrux/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
3.0.0
|
femtocrux/__init__.py
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
from .client.client import
|
|
1
|
+
from .client.client import (
|
|
2
|
+
CompilerClient,
|
|
3
|
+
TFLiteModel,
|
|
4
|
+
FQIRModel,
|
|
5
|
+
ModelAndMetadata,
|
|
6
|
+
ManagedCompilerClient,
|
|
7
|
+
)
|
|
2
8
|
from .version import __version__
|
|
3
9
|
|
|
4
10
|
# PEP 8 definiton of public API
|
|
@@ -7,6 +13,7 @@ __all__ = [
|
|
|
7
13
|
"CompilerClient",
|
|
8
14
|
"TFLiteModel",
|
|
9
15
|
"FQIRModel",
|
|
16
|
+
"ModelAndMetadata",
|
|
10
17
|
"__version__",
|
|
11
18
|
"ManagedCompilerClient",
|
|
12
19
|
]
|
femtocrux/client/client.py
CHANGED
|
@@ -15,6 +15,7 @@ from contextlib import contextmanager
|
|
|
15
15
|
import subprocess
|
|
16
16
|
|
|
17
17
|
from fmot.fqir import GraphProto
|
|
18
|
+
from femtorun import IOSpec
|
|
18
19
|
|
|
19
20
|
from femtocrux.util.utils import (
|
|
20
21
|
read_secret_raw,
|
|
@@ -23,6 +24,8 @@ from femtocrux.util.utils import (
|
|
|
23
24
|
deserialize_simulation_output,
|
|
24
25
|
)
|
|
25
26
|
|
|
27
|
+
from google.protobuf.message import Message
|
|
28
|
+
|
|
26
29
|
# GRPC artifacts
|
|
27
30
|
import femtocrux.grpc.compiler_service_pb2 as cs_pb2
|
|
28
31
|
import femtocrux.grpc.compiler_service_pb2_grpc as cs_pb2_grpc
|
|
@@ -104,13 +107,16 @@ class Model:
|
|
|
104
107
|
:class:`~femtocrux.client.client.TFLiteModel`.
|
|
105
108
|
"""
|
|
106
109
|
|
|
107
|
-
def _get_message(self,
|
|
110
|
+
def _get_message(self, user_configuration: dict = {}) -> cs_pb2.model_and_metadata:
|
|
108
111
|
# Format the options
|
|
109
|
-
|
|
110
|
-
|
|
112
|
+
user_configuration_struct = google.protobuf.struct_pb2.Struct()
|
|
113
|
+
user_configuration_struct.update(user_configuration)
|
|
111
114
|
|
|
112
115
|
# Construct the model with IR
|
|
113
|
-
return cs_pb2.
|
|
116
|
+
return cs_pb2.model_and_metadata(
|
|
117
|
+
**{self._ir_name: self._get_ir()},
|
|
118
|
+
user_configuration=user_configuration_struct,
|
|
119
|
+
)
|
|
114
120
|
|
|
115
121
|
@property
|
|
116
122
|
def _ir_name(self) -> str:
|
|
@@ -186,14 +192,54 @@ class TFLiteModel(Model):
|
|
|
186
192
|
return cs_pb2.tflite(model=self.flatbuffer, signature_name=self.signature_name)
|
|
187
193
|
|
|
188
194
|
|
|
195
|
+
@dataclass
|
|
196
|
+
class ModelAndMetadata(Model):
|
|
197
|
+
"""
|
|
198
|
+
Wraps an FQIR model and metadata to be compiled by femtocrux.
|
|
199
|
+
|
|
200
|
+
model: FQIRModel object
|
|
201
|
+
iospec: IOSpec object
|
|
202
|
+
opt_profile: (str) simple compiler configuration setting
|
|
203
|
+
user_configuration: (dict) fine grained compiler configuration
|
|
204
|
+
memory_reservations: (dict) requested memory to be reserved for IO buffering.
|
|
205
|
+
Currently unsupported.
|
|
206
|
+
"""
|
|
207
|
+
|
|
208
|
+
model: FQIRModel = None
|
|
209
|
+
iospec: IOSpec = None
|
|
210
|
+
opt_profile: str | None = None
|
|
211
|
+
user_configuration: dict | None = None
|
|
212
|
+
memory_reservations: dict | None = None # Currently unsupported by the compiler
|
|
213
|
+
|
|
214
|
+
@property
|
|
215
|
+
def _ir_name(self) -> str:
|
|
216
|
+
return "fqir"
|
|
217
|
+
|
|
218
|
+
def _get_ir(self) -> Any:
|
|
219
|
+
# Send the serialized model
|
|
220
|
+
serialized_iospec = self.iospec.serialize_to_string()
|
|
221
|
+
return cs_pb2.model_and_metadata(
|
|
222
|
+
fqir=self.model._get_ir(),
|
|
223
|
+
iospec=serialized_iospec,
|
|
224
|
+
opt_profile=self.opt_profile,
|
|
225
|
+
user_configuration=self.user_configuration,
|
|
226
|
+
memory_reservations=self.memory_reservations,
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
|
|
189
230
|
class Simulator:
|
|
190
231
|
"""
|
|
191
232
|
Simulates a compiled model's behavior on the SPU.
|
|
192
233
|
"""
|
|
193
234
|
|
|
194
|
-
def __init__(
|
|
235
|
+
def __init__(
|
|
236
|
+
self,
|
|
237
|
+
client: "CompilerClient",
|
|
238
|
+
model_and_metadata: ModelAndMetadata,
|
|
239
|
+
options: dict = {},
|
|
240
|
+
):
|
|
195
241
|
self.client = client
|
|
196
|
-
self.
|
|
242
|
+
self.model_and_metadata = model_and_metadata
|
|
197
243
|
|
|
198
244
|
# Create an event stream fed by a queue
|
|
199
245
|
self.request_queue = queue.SimpleQueue()
|
|
@@ -201,8 +247,9 @@ class Simulator:
|
|
|
201
247
|
self.response_iterator = client._simulate(request_iterator)
|
|
202
248
|
|
|
203
249
|
# Compile the model with the first message
|
|
204
|
-
model_msg = model._get_message(options)
|
|
205
|
-
|
|
250
|
+
# model_msg = self.model._get_message(user_configuration=options)
|
|
251
|
+
message = model_and_metadata._get_ir()
|
|
252
|
+
simulation_start_msg = cs_pb2.simulation_input(model=message)
|
|
206
253
|
self._send_request(simulation_start_msg)
|
|
207
254
|
|
|
208
255
|
# Check compilation status
|
|
@@ -291,23 +338,63 @@ class CompilerClientImpl:
|
|
|
291
338
|
server_version,
|
|
292
339
|
)
|
|
293
340
|
|
|
294
|
-
def compile(
|
|
341
|
+
def compile(
|
|
342
|
+
self,
|
|
343
|
+
model: GraphProto | Model,
|
|
344
|
+
iospec: IOSpec | None = None,
|
|
345
|
+
opt_profile: str | None = None,
|
|
346
|
+
user_configuration: dict | None = None,
|
|
347
|
+
memory_reservations: dict | None = None,
|
|
348
|
+
) -> tuple[Message, IOSpec, Message]:
|
|
295
349
|
"""
|
|
296
350
|
Compile the model to a bitstream.
|
|
297
351
|
|
|
298
|
-
:
|
|
299
|
-
:
|
|
300
|
-
|
|
301
|
-
:
|
|
302
|
-
:
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
:return:
|
|
352
|
+
:model: FQIRModel or GraphProto of the model to compile
|
|
353
|
+
:iospec: IOSpec object
|
|
354
|
+
:opt_profile: (str) simple compiler configuration setting
|
|
355
|
+
:user_configuration: (dict) fine grained compiler configuration
|
|
356
|
+
:memory_reservations: (dict) requested memory to be reserved for IO buffering.
|
|
357
|
+
Currently unsupported.
|
|
358
|
+
|
|
359
|
+
:return:
|
|
360
|
+
ProtoMessage of A zip archive of compiler artifacts.
|
|
361
|
+
ProtoMessage of iospec
|
|
362
|
+
ProtoMessage of memory_reservations
|
|
306
363
|
"""
|
|
307
364
|
|
|
308
|
-
response = self.stub.compile(model._get_message(options))
|
|
365
|
+
# response = self.stub.compile(model._get_message(options))
|
|
366
|
+
|
|
367
|
+
# Send the serialized model
|
|
368
|
+
if isinstance(model, GraphProto):
|
|
369
|
+
fqir_message = FQIRModel(
|
|
370
|
+
graph_proto=model,
|
|
371
|
+
batch_dim=0,
|
|
372
|
+
sequence_dim=1,
|
|
373
|
+
)
|
|
374
|
+
elif isinstance(model, FQIRModel):
|
|
375
|
+
fqir_message = model
|
|
376
|
+
else:
|
|
377
|
+
raise Exception(
|
|
378
|
+
f"Expected fqir GraphProto or protobuf Model message. "
|
|
379
|
+
f"Model allows for specifying custom batch and sequence dimensions. "
|
|
380
|
+
f"Got {type(model)}"
|
|
381
|
+
)
|
|
382
|
+
if iospec is None:
|
|
383
|
+
raise Exception(
|
|
384
|
+
"No iospec was provided. Please provide an iospec to the compiler."
|
|
385
|
+
)
|
|
386
|
+
serialized_iospec = iospec.serialize_to_string()
|
|
387
|
+
data_to_send = cs_pb2.model_and_metadata(
|
|
388
|
+
fqir=fqir_message._get_ir(),
|
|
389
|
+
iospec=serialized_iospec,
|
|
390
|
+
opt_profile=opt_profile,
|
|
391
|
+
user_configuration=user_configuration,
|
|
392
|
+
memory_reservations=memory_reservations,
|
|
393
|
+
)
|
|
394
|
+
response = self.stub.compile(data_to_send)
|
|
395
|
+
returned_iospec = IOSpec.deserialize_from_string(response.iospec)
|
|
309
396
|
self._check_status(response.status)
|
|
310
|
-
return response.bitfile
|
|
397
|
+
return response.bitfile, returned_iospec, response.memory_reservations
|
|
311
398
|
|
|
312
399
|
def _ping(self, message: bytes) -> None:
|
|
313
400
|
"""Pings the server with a message."""
|
|
@@ -319,7 +406,9 @@ class CompilerClientImpl:
|
|
|
319
406
|
"""Calls the 'simulator' bidirectional streaming RPC."""
|
|
320
407
|
return self.stub.simulate(in_stream)
|
|
321
408
|
|
|
322
|
-
def simulate(
|
|
409
|
+
def simulate(
|
|
410
|
+
self, model_and_metadata: ModelAndMetadata, options: dict = {}
|
|
411
|
+
) -> Simulator:
|
|
323
412
|
"""
|
|
324
413
|
Get a simulator for the model.
|
|
325
414
|
|
|
@@ -332,10 +421,14 @@ class CompilerClientImpl:
|
|
|
332
421
|
:rtype: Simulator
|
|
333
422
|
:return: A simulator for the model.
|
|
334
423
|
"""
|
|
335
|
-
return Simulator(
|
|
424
|
+
return Simulator(
|
|
425
|
+
client=self, model_and_metadata=model_and_metadata, options=options
|
|
426
|
+
)
|
|
336
427
|
|
|
337
|
-
def get_simulator_object(
|
|
338
|
-
|
|
428
|
+
def get_simulator_object(
|
|
429
|
+
self, model_and_metadata: ModelAndMetadata, options: dict = {}
|
|
430
|
+
) -> Simulator:
|
|
431
|
+
return self.simulate(model_and_metadata, options)
|
|
339
432
|
|
|
340
433
|
def _server_version(self) -> str:
|
|
341
434
|
"""Queries the femtocrux version running on the server."""
|
|
@@ -26,7 +26,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
|
|
|
26
26
|
from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x63ompiler_service.proto\x12\nfscompiler\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1cgoogle/protobuf/struct.proto\"g\n\x04\x66qir\x12\r\n\x05model\x18\x01 \x01(\x0c\x12\x16\n\tbatch_dim\x18\x02 \x01(\x03H\x00\x88\x01\x01\x12\x19\n\x0csequence_dim\x18\x03 \x01(\x03H\x01\x88\x01\x01\x42\x0c\n\n_batch_dimB\x0f\n\r_sequence_dim\"G\n\x06tflite\x12\r\n\x05model\x18\x01 \x01(\x0c\x12\x1b\n\x0esignature_name\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x11\n\x0f_signature_name\"\
|
|
29
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x63ompiler_service.proto\x12\nfscompiler\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1cgoogle/protobuf/struct.proto\"g\n\x04\x66qir\x12\r\n\x05model\x18\x01 \x01(\x0c\x12\x16\n\tbatch_dim\x18\x02 \x01(\x03H\x00\x88\x01\x01\x12\x19\n\x0csequence_dim\x18\x03 \x01(\x03H\x01\x88\x01\x01\x42\x0c\n\n_batch_dimB\x0f\n\r_sequence_dim\"G\n\x06tflite\x12\r\n\x05model\x18\x01 \x01(\x0c\x12\x1b\n\x0esignature_name\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x11\n\x0f_signature_name\"\xd0\x02\n\x12model_and_metadata\x12 \n\x04\x66qir\x18\x01 \x01(\x0b\x32\x10.fscompiler.fqirH\x00\x12$\n\x06tflite\x18\x02 \x01(\x0b\x32\x12.fscompiler.tfliteH\x00\x12\x13\n\x06iospec\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0bopt_profile\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x38\n\x12user_configuration\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructH\x03\x88\x01\x01\x12\x39\n\x13memory_reservations\x18\x06 \x01(\x0b\x32\x17.google.protobuf.StructH\x04\x88\x01\x01\x42\x04\n\x02irB\t\n\x07_iospecB\x0e\n\x0c_opt_profileB\x15\n\x13_user_configurationB\x16\n\x14_memory_reservations\"&\n\x06status\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x0b\n\x03msg\x18\x02 \x01(\t\"\xbc\x01\n\x12\x63ompiled_artifacts\x12\x0f\n\x07\x62itfile\x18\x01 \x01(\x0c\x12\x13\n\x06iospec\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x39\n\x13memory_reservations\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructH\x01\x88\x01\x01\x12\"\n\x06status\x18\x04 \x01(\x0b\x32\x12.fscompiler.statusB\t\n\x07_iospecB\x16\n\x14_memory_reservations\"5\n\x07ndarray\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\x12\r\n\x05shape\x18\x02 \x03(\x03\x12\r\n\x05\x64type\x18\x03 \x01(\t\"\x14\n\x04\x64\x61ta\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\"\xe6\x01\n\x0fsimulation_data\x12\x37\n\x06inputs\x18\x01 \x03(\x0b\x32\'.fscompiler.simulation_data.InputsEntry\x12\x19\n\x0csim_duration\x18\x02 \x01(\x02H\x00\x88\x01\x01\x12\x19\n\x0cinput_period\x18\x03 \x01(\x02H\x01\x88\x01\x01\x1a\x42\n\x0bInputsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.fscompiler.ndarray:\x02\x38\x01\x42\x0f\n\r_sim_durationB\x0f\n\r_input_period\"\x81\x01\n\x10simulation_input\x12/\n\x05model\x18\x01 \x01(\x0b\x32\x1e.fscompiler.model_and_metadataH\x00\x12+\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x1b.fscompiler.simulation_dataH\x00\x42\x0f\n\rmodel_or_data\"\xc9\x01\n\x11simulation_output\x12;\n\x07outputs\x18\x01 \x03(\x0b\x32*.fscompiler.simulation_output.OutputsEntry\x12\x0e\n\x06report\x18\x02 \x01(\t\x12\"\n\x06status\x18\x03 \x01(\x0b\x32\x12.fscompiler.status\x1a\x43\n\x0cOutputsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.fscompiler.ndarray:\x02\x38\x01\"\x1f\n\x0cversion_info\x12\x0f\n\x07version\x18\x01 \x01(\t2\x92\x02\n\x07\x43ompile\x12K\n\x07\x63ompile\x12\x1e.fscompiler.model_and_metadata\x1a\x1e.fscompiler.compiled_artifacts\"\x00\x12,\n\x04ping\x12\x10.fscompiler.data\x1a\x10.fscompiler.data\"\x00\x12M\n\x08simulate\x12\x1c.fscompiler.simulation_input\x1a\x1d.fscompiler.simulation_output\"\x00(\x01\x30\x01\x12=\n\x07version\x12\x16.google.protobuf.Empty\x1a\x18.fscompiler.version_info\"\x00\x62\x06proto3')
|
|
30
30
|
|
|
31
31
|
_globals = globals()
|
|
32
32
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
@@ -41,28 +41,28 @@ if not _descriptor._USE_C_DESCRIPTORS:
|
|
|
41
41
|
_globals['_FQIR']._serialized_end=200
|
|
42
42
|
_globals['_TFLITE']._serialized_start=202
|
|
43
43
|
_globals['_TFLITE']._serialized_end=273
|
|
44
|
-
_globals['
|
|
45
|
-
_globals['
|
|
46
|
-
_globals['_STATUS']._serialized_start=
|
|
47
|
-
_globals['_STATUS']._serialized_end=
|
|
48
|
-
_globals['_COMPILED_ARTIFACTS']._serialized_start=
|
|
49
|
-
_globals['_COMPILED_ARTIFACTS']._serialized_end=
|
|
50
|
-
_globals['_NDARRAY']._serialized_start=
|
|
51
|
-
_globals['_NDARRAY']._serialized_end=
|
|
52
|
-
_globals['_DATA']._serialized_start=
|
|
53
|
-
_globals['_DATA']._serialized_end=
|
|
54
|
-
_globals['_SIMULATION_DATA']._serialized_start=
|
|
55
|
-
_globals['_SIMULATION_DATA']._serialized_end=
|
|
56
|
-
_globals['_SIMULATION_DATA_INPUTSENTRY']._serialized_start=
|
|
57
|
-
_globals['_SIMULATION_DATA_INPUTSENTRY']._serialized_end=
|
|
58
|
-
_globals['_SIMULATION_INPUT']._serialized_start=
|
|
59
|
-
_globals['_SIMULATION_INPUT']._serialized_end=
|
|
60
|
-
_globals['_SIMULATION_OUTPUT']._serialized_start=
|
|
61
|
-
_globals['_SIMULATION_OUTPUT']._serialized_end=
|
|
62
|
-
_globals['_SIMULATION_OUTPUT_OUTPUTSENTRY']._serialized_start=
|
|
63
|
-
_globals['_SIMULATION_OUTPUT_OUTPUTSENTRY']._serialized_end=
|
|
64
|
-
_globals['_VERSION_INFO']._serialized_start=
|
|
65
|
-
_globals['_VERSION_INFO']._serialized_end=
|
|
66
|
-
_globals['_COMPILE']._serialized_start=
|
|
67
|
-
_globals['_COMPILE']._serialized_end=
|
|
44
|
+
_globals['_MODEL_AND_METADATA']._serialized_start=276
|
|
45
|
+
_globals['_MODEL_AND_METADATA']._serialized_end=612
|
|
46
|
+
_globals['_STATUS']._serialized_start=614
|
|
47
|
+
_globals['_STATUS']._serialized_end=652
|
|
48
|
+
_globals['_COMPILED_ARTIFACTS']._serialized_start=655
|
|
49
|
+
_globals['_COMPILED_ARTIFACTS']._serialized_end=843
|
|
50
|
+
_globals['_NDARRAY']._serialized_start=845
|
|
51
|
+
_globals['_NDARRAY']._serialized_end=898
|
|
52
|
+
_globals['_DATA']._serialized_start=900
|
|
53
|
+
_globals['_DATA']._serialized_end=920
|
|
54
|
+
_globals['_SIMULATION_DATA']._serialized_start=923
|
|
55
|
+
_globals['_SIMULATION_DATA']._serialized_end=1153
|
|
56
|
+
_globals['_SIMULATION_DATA_INPUTSENTRY']._serialized_start=1053
|
|
57
|
+
_globals['_SIMULATION_DATA_INPUTSENTRY']._serialized_end=1119
|
|
58
|
+
_globals['_SIMULATION_INPUT']._serialized_start=1156
|
|
59
|
+
_globals['_SIMULATION_INPUT']._serialized_end=1285
|
|
60
|
+
_globals['_SIMULATION_OUTPUT']._serialized_start=1288
|
|
61
|
+
_globals['_SIMULATION_OUTPUT']._serialized_end=1489
|
|
62
|
+
_globals['_SIMULATION_OUTPUT_OUTPUTSENTRY']._serialized_start=1422
|
|
63
|
+
_globals['_SIMULATION_OUTPUT_OUTPUTSENTRY']._serialized_end=1489
|
|
64
|
+
_globals['_VERSION_INFO']._serialized_start=1491
|
|
65
|
+
_globals['_VERSION_INFO']._serialized_end=1522
|
|
66
|
+
_globals['_COMPILE']._serialized_start=1525
|
|
67
|
+
_globals['_COMPILE']._serialized_end=1799
|
|
68
68
|
# @@protoc_insertion_point(module_scope)
|
|
@@ -38,7 +38,7 @@ class CompileStub(object):
|
|
|
38
38
|
"""
|
|
39
39
|
self.compile = channel.unary_unary(
|
|
40
40
|
'/fscompiler.Compile/compile',
|
|
41
|
-
request_serializer=compiler__service__pb2.
|
|
41
|
+
request_serializer=compiler__service__pb2.model_and_metadata.SerializeToString,
|
|
42
42
|
response_deserializer=compiler__service__pb2.compiled_artifacts.FromString,
|
|
43
43
|
_registered_method=True)
|
|
44
44
|
self.ping = channel.unary_unary(
|
|
@@ -91,7 +91,7 @@ def add_CompileServicer_to_server(servicer, server):
|
|
|
91
91
|
rpc_method_handlers = {
|
|
92
92
|
'compile': grpc.unary_unary_rpc_method_handler(
|
|
93
93
|
servicer.compile,
|
|
94
|
-
request_deserializer=compiler__service__pb2.
|
|
94
|
+
request_deserializer=compiler__service__pb2.model_and_metadata.FromString,
|
|
95
95
|
response_serializer=compiler__service__pb2.compiled_artifacts.SerializeToString,
|
|
96
96
|
),
|
|
97
97
|
'ping': grpc.unary_unary_rpc_method_handler(
|
|
@@ -136,7 +136,7 @@ class Compile(object):
|
|
|
136
136
|
request,
|
|
137
137
|
target,
|
|
138
138
|
'/fscompiler.Compile/compile',
|
|
139
|
-
compiler__service__pb2.
|
|
139
|
+
compiler__service__pb2.model_and_metadata.SerializeToString,
|
|
140
140
|
compiler__service__pb2.compiled_artifacts.FromString,
|
|
141
141
|
options,
|
|
142
142
|
channel_credentials,
|
|
@@ -13,10 +13,11 @@ import zipfile
|
|
|
13
13
|
|
|
14
14
|
from fmot import ConvertedModel
|
|
15
15
|
from fmot.fqir import GraphProto
|
|
16
|
-
from femtomapper import
|
|
16
|
+
from femtomapper import compile as femtomapper_compile
|
|
17
17
|
from femtobehav.fasmir import FASMIR
|
|
18
18
|
from femtobehav.sim import SimRunner
|
|
19
|
-
from
|
|
19
|
+
from femtorun import IOSpec
|
|
20
|
+
from typing import Any, Literal
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
class CompilerFrontend:
|
|
@@ -25,13 +26,15 @@ class CompilerFrontend:
|
|
|
25
26
|
def __init__(self, input_ir: Any, fasmir: FASMIR = None):
|
|
26
27
|
self.input_ir = input_ir
|
|
27
28
|
self.fasmir = fasmir
|
|
29
|
+
self.iospec = None
|
|
30
|
+
self.memory_reservations = None
|
|
28
31
|
# self.io_wrapper = io_wrapper
|
|
29
32
|
|
|
30
33
|
@property
|
|
31
34
|
def is_compiled(self):
|
|
32
35
|
return self.fasmir is not None
|
|
33
36
|
|
|
34
|
-
def _compile(self, input_ir: Any
|
|
37
|
+
def _compile(self, input_ir: Any) -> FASMIR:
|
|
35
38
|
"""
|
|
36
39
|
Runs FM compiler to generate FASMIR, and encode io information in a
|
|
37
40
|
SimIOWrapper object.
|
|
@@ -44,9 +47,19 @@ class CompilerFrontend:
|
|
|
44
47
|
"Subclasses need to implement this based on their input ir"
|
|
45
48
|
)
|
|
46
49
|
|
|
47
|
-
def compile(
|
|
50
|
+
def compile(
|
|
51
|
+
self,
|
|
52
|
+
input_ir: GraphProto,
|
|
53
|
+
iospec: IOSpec | None = None,
|
|
54
|
+
opt_profile: Literal["efficient", "fast", "conservative"] | None = "efficient",
|
|
55
|
+
user_configuration: dict | None = None,
|
|
56
|
+
memory_reservations: dict | None = None,
|
|
57
|
+
) -> tuple[FASMIR, IOSpec, dict]:
|
|
48
58
|
if not self.is_compiled:
|
|
49
|
-
self.fasmir = self._compile(
|
|
59
|
+
self.fasmir, self.iospec, self.memory_reservations = self._compile(
|
|
60
|
+
input_ir, iospec, opt_profile, user_configuration, memory_reservations
|
|
61
|
+
)
|
|
62
|
+
return self.fasmir, self.iospec, self.memory_reservations
|
|
50
63
|
|
|
51
64
|
def dump_bitfile(self, encrypt: bool = True) -> bytes:
|
|
52
65
|
"""Dumps a bitfile used to program the SPU."""
|
|
@@ -56,7 +69,9 @@ class CompilerFrontend:
|
|
|
56
69
|
with tempfile.TemporaryFile() as tmpfile:
|
|
57
70
|
with tempfile.TemporaryDirectory() as dirname:
|
|
58
71
|
# Dump memory files to a directory
|
|
59
|
-
runner = SimRunner(
|
|
72
|
+
runner = SimRunner(
|
|
73
|
+
self.fasmir, io_spec=self.iospec, data_dir=dirname, encrypt=encrypt
|
|
74
|
+
)
|
|
60
75
|
runner.reset()
|
|
61
76
|
runner.finish()
|
|
62
77
|
|
|
@@ -84,7 +99,11 @@ class CompilerFrontend:
|
|
|
84
99
|
return fasmir_var.numpy.shape[0]
|
|
85
100
|
|
|
86
101
|
def run_behavioral_simulator(
|
|
87
|
-
self,
|
|
102
|
+
self,
|
|
103
|
+
inputs: dict[str, np.ndarray],
|
|
104
|
+
input_period: float = None,
|
|
105
|
+
iospec: IOSpec | None = None,
|
|
106
|
+
**kwargs
|
|
88
107
|
):
|
|
89
108
|
"""
|
|
90
109
|
Runs the behavioral simulator and returns outputs and metrics.
|
|
@@ -96,7 +115,7 @@ class CompilerFrontend:
|
|
|
96
115
|
input_period (float, optional): total simulation time.
|
|
97
116
|
|
|
98
117
|
"""
|
|
99
|
-
runner = SimRunner(self.fasmir, **kwargs)
|
|
118
|
+
runner = SimRunner(self.fasmir, io_spec=iospec, **kwargs)
|
|
100
119
|
runner.reset()
|
|
101
120
|
outputs, __, __ = runner.run(inputs)
|
|
102
121
|
metrics = runner.get_metrics(input_period, concise=True, as_yamlable=True)
|
|
@@ -104,19 +123,6 @@ class CompilerFrontend:
|
|
|
104
123
|
return outputs, metrics
|
|
105
124
|
|
|
106
125
|
|
|
107
|
-
def _compile_fqir(graph: GraphProto, options: dict) -> FASMIR:
|
|
108
|
-
mapper_conf = MapperConf(**options)
|
|
109
|
-
mapper = Mapper(mapper_conf)
|
|
110
|
-
mapper_state = MapperState(fqir=graph)
|
|
111
|
-
|
|
112
|
-
# compile:
|
|
113
|
-
mapper_state = mapper.do(mapper_state)
|
|
114
|
-
|
|
115
|
-
# extract fasmir
|
|
116
|
-
fasmir = mapper_state.fasmir
|
|
117
|
-
return fasmir
|
|
118
|
-
|
|
119
|
-
|
|
120
126
|
class TorchCompiler(CompilerFrontend):
|
|
121
127
|
def __init__(self, graph: GraphProto, batch_dim: int = None, seq_dim: int = None):
|
|
122
128
|
assert isinstance(graph, GraphProto)
|
|
@@ -125,10 +131,19 @@ class TorchCompiler(CompilerFrontend):
|
|
|
125
131
|
self.batch_dim = batch_dim
|
|
126
132
|
self.seq_dim = seq_dim
|
|
127
133
|
|
|
128
|
-
def _compile(
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
134
|
+
def _compile(
|
|
135
|
+
self,
|
|
136
|
+
input_ir: GraphProto,
|
|
137
|
+
iospec: IOSpec | None = None,
|
|
138
|
+
opt_profile: Literal["efficient", "fast", "conservative"] | None = "efficient",
|
|
139
|
+
user_configuration: dict | None = None,
|
|
140
|
+
memory_reservations: dict | None = None,
|
|
141
|
+
) -> tuple[FASMIR, IOSpec, dict]:
|
|
142
|
+
mapper_state, iospec, memory_reservations = femtomapper_compile(
|
|
143
|
+
input_ir, iospec, opt_profile, user_configuration, memory_reservations
|
|
144
|
+
)
|
|
145
|
+
fasmir = mapper_state.fasmir
|
|
146
|
+
return fasmir, iospec, memory_reservations
|
|
132
147
|
|
|
133
148
|
@classmethod
|
|
134
149
|
def from_fqir(cls, graph: GraphProto, batch_dim: int = None, seq_dim: int = None):
|
femtocrux/server/server.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
from collections.abc import Iterable
|
|
3
3
|
import concurrent
|
|
4
|
-
from google.protobuf.json_format import MessageToDict
|
|
5
4
|
import grpc
|
|
6
5
|
import logging
|
|
7
6
|
import pickle
|
|
8
7
|
import sys
|
|
9
8
|
|
|
9
|
+
from femtorun import IOSpec
|
|
10
10
|
from femtocrux.server import CompilerFrontend, TorchCompiler
|
|
11
11
|
|
|
12
12
|
from femtocrux.server.exceptions import format_exception, format_exception_from_exc
|
|
@@ -36,8 +36,9 @@ class CompileServicer(cs_pb2_grpc.CompileServicer):
|
|
|
36
36
|
self.logger = logging.getLogger("CompileServicer")
|
|
37
37
|
self.logger.setLevel(logging.DEBUG)
|
|
38
38
|
self.logger.info("Starting compile server.")
|
|
39
|
+
self.iospec = None
|
|
39
40
|
|
|
40
|
-
def _get_fqir_compiler(self, model: cs_pb2.
|
|
41
|
+
def _get_fqir_compiler(self, model: cs_pb2.model_and_metadata) -> CompilerFrontend:
|
|
41
42
|
"""Get a Torch compiler from an FQIR a model message"""
|
|
42
43
|
# Deserialize FQIR
|
|
43
44
|
fqir = model.fqir
|
|
@@ -50,24 +51,36 @@ class CompileServicer(cs_pb2_grpc.CompileServicer):
|
|
|
50
51
|
seq_dim=field_or_none(fqir, "sequence_dim"),
|
|
51
52
|
)
|
|
52
53
|
|
|
53
|
-
def _compile_model(
|
|
54
|
+
def _compile_model(
|
|
55
|
+
self, model_and_metadata: cs_pb2.model_and_metadata, context
|
|
56
|
+
) -> CompilerFrontend:
|
|
54
57
|
"""Compile a model, for simulation or bitfile generation."""
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
58
|
+
|
|
59
|
+
# Deserialize FQIR
|
|
60
|
+
fqir = model_and_metadata.fqir
|
|
61
|
+
graph_proto = pickle.loads(fqir.model)
|
|
62
|
+
|
|
63
|
+
# Compile the FQIR
|
|
64
|
+
compiler = TorchCompiler(
|
|
65
|
+
graph_proto,
|
|
66
|
+
batch_dim=field_or_none(fqir, "batch_dim"),
|
|
67
|
+
seq_dim=field_or_none(fqir, "sequence_dim"),
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
# Get the iospec
|
|
71
|
+
iospec = field_or_none(model_and_metadata, "iospec")
|
|
72
|
+
iospec = IOSpec.deserialize_from_string(iospec)
|
|
73
|
+
self.iospec = iospec
|
|
74
|
+
# Get the opt_profile
|
|
75
|
+
opt_profile = field_or_none(model_and_metadata, "opt_profile")
|
|
76
|
+
# Get the user_configuration
|
|
77
|
+
user_configuration = field_or_none(model_and_metadata, "user_configuration")
|
|
78
|
+
memory_reservations = field_or_none(model_and_metadata, "memory_reservations")
|
|
68
79
|
|
|
69
80
|
# Compile the model
|
|
70
|
-
compiler.compile(
|
|
81
|
+
compiler.compile(
|
|
82
|
+
graph_proto, iospec, opt_profile, user_configuration, memory_reservations
|
|
83
|
+
)
|
|
71
84
|
assert compiler.is_compiled, "Expected compilation completed"
|
|
72
85
|
return compiler
|
|
73
86
|
|
|
@@ -88,10 +101,15 @@ class CompileServicer(cs_pb2_grpc.CompileServicer):
|
|
|
88
101
|
)
|
|
89
102
|
|
|
90
103
|
# Return the bitfile
|
|
91
|
-
|
|
92
|
-
bitfile=bitfile,
|
|
104
|
+
ret_message = cs_pb2.compiled_artifacts(
|
|
105
|
+
bitfile=bitfile,
|
|
106
|
+
iospec=compiler.iospec.serialize_to_string(),
|
|
107
|
+
memory_reservations=compiler.memory_reservations,
|
|
108
|
+
status=cs_pb2.status(success=True),
|
|
93
109
|
)
|
|
94
110
|
|
|
111
|
+
return ret_message
|
|
112
|
+
|
|
95
113
|
def ping(self, data: cs_pb2.data, context) -> cs_pb2.data:
|
|
96
114
|
"""Round-trip a message."""
|
|
97
115
|
return data
|
|
@@ -107,7 +125,11 @@ class CompileServicer(cs_pb2_grpc.CompileServicer):
|
|
|
107
125
|
# Check that this is a model request
|
|
108
126
|
if not model_request.WhichOneof("model_or_data") == "model":
|
|
109
127
|
yield cs_pb2.simulation_output(
|
|
110
|
-
status=cs_pb2.status(
|
|
128
|
+
status=cs_pb2.status(
|
|
129
|
+
success=False,
|
|
130
|
+
msg=f"Expected model message, got "
|
|
131
|
+
f"{model_request.WhichOneof('model_or_data')}",
|
|
132
|
+
)
|
|
111
133
|
)
|
|
112
134
|
continue
|
|
113
135
|
|
|
@@ -147,6 +169,7 @@ class CompileServicer(cs_pb2_grpc.CompileServicer):
|
|
|
147
169
|
outputs, metrics = compiler.run_behavioral_simulator(
|
|
148
170
|
deserialized_inputs,
|
|
149
171
|
input_period=field_or_none(data, "input_period"),
|
|
172
|
+
iospec=self.iospec,
|
|
150
173
|
)
|
|
151
174
|
else:
|
|
152
175
|
raise (Exception("Didn't get a model or data"))
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
femtocrux/ENV_REQUIREMENTS.sh,sha256=t_O1B4hJAMgxvH9gwp1qls6eVFmhSYBJe64KmuK_H-4,1389
|
|
2
|
+
femtocrux/PY_REQUIREMENTS,sha256=UwXV0o3gieruZUYdN9r2bqQ0Wcf_vosjeP6LJVx6oF0,275
|
|
3
|
+
femtocrux/VERSION,sha256=KYW-iyjTrehY6Nj7S8IvVlsb9gIN_5gtzhQfdyG5mZw,6
|
|
4
|
+
femtocrux/__init__.py,sha256=VeuEHuCvQmqHgzj_ogjIbwGE_E8UFLYSJN6GTpXBfe0,409
|
|
5
|
+
femtocrux/version.py,sha256=uNg2kHxQo6oUN1ah7s9_85rCZVRoTHGPD1GAQPZW4lw,164
|
|
6
|
+
femtocrux/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
femtocrux/client/client.py,sha256=UrO8OYhw6KTbI_tHz_DpRwBx93MwO1MvrkMUnAQaR94,29797
|
|
8
|
+
femtocrux/grpc/__init__.py,sha256=uiMHQt5I2eAKJqI3Zh0h1Gm7cmPR4PbaGS71nCJQCGw,169
|
|
9
|
+
femtocrux/grpc/compiler_service_pb2.py,sha256=ChHlC3TvWNFR-umRg2l7j3FAiybe1EGBEJfYB0Z78zM,6084
|
|
10
|
+
femtocrux/grpc/compiler_service_pb2_grpc.py,sha256=b_fyld4rpKE4n5MimKOoyNZ5VU4UqUS_R3EM3_daqxM,8539
|
|
11
|
+
femtocrux/server/__init__.py,sha256=kpm2AGLxo3AA9zo-G8N0Dm0gmWbvAd6jfhMbtkeHcxo,77
|
|
12
|
+
femtocrux/server/compiler_frontend.py,sha256=kXVg_JIQyLY9zdwT1s5xusWaBd-9t4gDwXrU6FX6UqI,6217
|
|
13
|
+
femtocrux/server/exceptions.py,sha256=lI6n471n5QKf5G3aL_1kuBVEItD-jBgithVVpPDwNYc,609
|
|
14
|
+
femtocrux/server/healthcheck.py,sha256=ehqAwnv0D0zpy-AUZAPwv8rp874DZCwUmP8nzdXzZvI,1565
|
|
15
|
+
femtocrux/server/server.py,sha256=k7GiLHxtzo5UH1O0edav4yEPgYD682DmB1aTZodtBuQ,8268
|
|
16
|
+
femtocrux/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
+
femtocrux/util/utils.py,sha256=v8v09aDaOtfejpSIB-LgaA--JJj9o2_BWvNwjd8wfww,4134
|
|
18
|
+
femtocrux-3.0.0.dist-info/licenses/LICENSE,sha256=eN9ZI1xHjUmFvN3TEeop5kBGXRUBfbsl55KBNBYYFqI,36
|
|
19
|
+
femtocrux-3.0.0.dist-info/METADATA,sha256=TZkC3EUSy5ZqBYmeGccdq4HAYx3NL_wQoYWipcKccDk,2763
|
|
20
|
+
femtocrux-3.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
21
|
+
femtocrux-3.0.0.dist-info/top_level.txt,sha256=BkTttlioC3je__8577wxRieZqY3Abu7FOOdMnmYbcNI,10
|
|
22
|
+
femtocrux-3.0.0.dist-info/RECORD,,
|
femtocrux-2.5.1.dist-info/RECORD
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
femtocrux/ENV_REQUIREMENTS.sh,sha256=t_O1B4hJAMgxvH9gwp1qls6eVFmhSYBJe64KmuK_H-4,1389
|
|
2
|
-
femtocrux/PY_REQUIREMENTS,sha256=UwXV0o3gieruZUYdN9r2bqQ0Wcf_vosjeP6LJVx6oF0,275
|
|
3
|
-
femtocrux/VERSION,sha256=mWAPanv-bDPr0aJRj0SoYaZ6_EDCXaQrxiJZVxZSlYQ,6
|
|
4
|
-
femtocrux/__init__.py,sha256=yIWd9I2PEXCn_PKIILAN3mkWeTf0tgtVualeTIHNxfQ,342
|
|
5
|
-
femtocrux/version.py,sha256=uNg2kHxQo6oUN1ah7s9_85rCZVRoTHGPD1GAQPZW4lw,164
|
|
6
|
-
femtocrux/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
femtocrux/client/client.py,sha256=eJH-CM_Pob1V-M9EuwhFyyWd1NsdLBIUiF99Psz46-8,26428
|
|
8
|
-
femtocrux/grpc/__init__.py,sha256=uiMHQt5I2eAKJqI3Zh0h1Gm7cmPR4PbaGS71nCJQCGw,169
|
|
9
|
-
femtocrux/grpc/compiler_service_pb2.py,sha256=grQNjlnoUg8KKcykK7JcT7Pmv_7R7sjLpsoG_EHGyoY,5494
|
|
10
|
-
femtocrux/grpc/compiler_service_pb2_grpc.py,sha256=Hl1bGJEYA7CvdIj38FUvlEolPGCoWyK8WazqOhx4v8s,8500
|
|
11
|
-
femtocrux/server/__init__.py,sha256=kpm2AGLxo3AA9zo-G8N0Dm0gmWbvAd6jfhMbtkeHcxo,77
|
|
12
|
-
femtocrux/server/compiler_frontend.py,sha256=-pfhOHDkXWReoB273Bc9s2s7BVTMZoCSyGM7pudmMhY,5472
|
|
13
|
-
femtocrux/server/exceptions.py,sha256=lI6n471n5QKf5G3aL_1kuBVEItD-jBgithVVpPDwNYc,609
|
|
14
|
-
femtocrux/server/healthcheck.py,sha256=ehqAwnv0D0zpy-AUZAPwv8rp874DZCwUmP8nzdXzZvI,1565
|
|
15
|
-
femtocrux/server/server.py,sha256=sumnTj63uOGkzwj4-xwTuN4wVB7CDopy8e7PLOpW64Q,7405
|
|
16
|
-
femtocrux/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
-
femtocrux/util/utils.py,sha256=v8v09aDaOtfejpSIB-LgaA--JJj9o2_BWvNwjd8wfww,4134
|
|
18
|
-
femtocrux-2.5.1.dist-info/licenses/LICENSE,sha256=eN9ZI1xHjUmFvN3TEeop5kBGXRUBfbsl55KBNBYYFqI,36
|
|
19
|
-
femtocrux-2.5.1.dist-info/METADATA,sha256=8hmP0A4KIm8CLNlJA0X4GuW2MjuthJYg2NOpEg2ruZA,2763
|
|
20
|
-
femtocrux-2.5.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
21
|
-
femtocrux-2.5.1.dist-info/top_level.txt,sha256=BkTttlioC3je__8577wxRieZqY3Abu7FOOdMnmYbcNI,10
|
|
22
|
-
femtocrux-2.5.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|