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 CHANGED
@@ -1 +1 @@
1
- 2.5.1
1
+ 3.0.0
femtocrux/__init__.py CHANGED
@@ -1,4 +1,10 @@
1
- from .client.client import CompilerClient, TFLiteModel, FQIRModel, ManagedCompilerClient
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
  ]
@@ -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, options: dict = {}) -> cs_pb2.model:
110
+ def _get_message(self, user_configuration: dict = {}) -> cs_pb2.model_and_metadata:
108
111
  # Format the options
109
- options_struct = google.protobuf.struct_pb2.Struct()
110
- options_struct.update(options)
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.model(**{self._ir_name: self._get_ir()}, options=options_struct)
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__(self, client: "CompilerClient", model: Model, options: dict = {}):
235
+ def __init__(
236
+ self,
237
+ client: "CompilerClient",
238
+ model_and_metadata: ModelAndMetadata,
239
+ options: dict = {},
240
+ ):
195
241
  self.client = client
196
- self.model = model
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
- simulation_start_msg = cs_pb2.simulation_input(model=model_msg)
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(self, model: Model, options: dict = {}) -> bytes:
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
- :type model: Model, required
299
- :param model: The model to be compiled.
300
-
301
- :type options: dict, optional
302
- :param options: Complier options.
303
-
304
- :rtype: bytes
305
- :return: A zip archive of compiler artifacts.
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(self, model: Model, options: dict = {}) -> Simulator:
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(client=self, model=model, options=options)
424
+ return Simulator(
425
+ client=self, model_and_metadata=model_and_metadata, options=options
426
+ )
336
427
 
337
- def get_simulator_object(self, model: Model, options: dict = {}) -> Simulator:
338
- return self.simulate(model, options)
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\"\x90\x01\n\x05model\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-\n\x07options\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructH\x01\x88\x01\x01\x42\x04\n\x02irB\n\n\x08_options\"&\n\x06status\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x0b\n\x03msg\x18\x02 \x01(\t\"I\n\x12\x63ompiled_artifacts\x12\x0f\n\x07\x62itfile\x18\x01 \x01(\x0c\x12\"\n\x06status\x18\x02 \x01(\x0b\x32\x12.fscompiler.status\"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\"t\n\x10simulation_input\x12\"\n\x05model\x18\x01 \x01(\x0b\x32\x11.fscompiler.modelH\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\x85\x02\n\x07\x43ompile\x12>\n\x07\x63ompile\x12\x11.fscompiler.model\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')
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['_MODEL']._serialized_start=276
45
- _globals['_MODEL']._serialized_end=420
46
- _globals['_STATUS']._serialized_start=422
47
- _globals['_STATUS']._serialized_end=460
48
- _globals['_COMPILED_ARTIFACTS']._serialized_start=462
49
- _globals['_COMPILED_ARTIFACTS']._serialized_end=535
50
- _globals['_NDARRAY']._serialized_start=537
51
- _globals['_NDARRAY']._serialized_end=590
52
- _globals['_DATA']._serialized_start=592
53
- _globals['_DATA']._serialized_end=612
54
- _globals['_SIMULATION_DATA']._serialized_start=615
55
- _globals['_SIMULATION_DATA']._serialized_end=845
56
- _globals['_SIMULATION_DATA_INPUTSENTRY']._serialized_start=745
57
- _globals['_SIMULATION_DATA_INPUTSENTRY']._serialized_end=811
58
- _globals['_SIMULATION_INPUT']._serialized_start=847
59
- _globals['_SIMULATION_INPUT']._serialized_end=963
60
- _globals['_SIMULATION_OUTPUT']._serialized_start=966
61
- _globals['_SIMULATION_OUTPUT']._serialized_end=1167
62
- _globals['_SIMULATION_OUTPUT_OUTPUTSENTRY']._serialized_start=1100
63
- _globals['_SIMULATION_OUTPUT_OUTPUTSENTRY']._serialized_end=1167
64
- _globals['_VERSION_INFO']._serialized_start=1169
65
- _globals['_VERSION_INFO']._serialized_end=1200
66
- _globals['_COMPILE']._serialized_start=1203
67
- _globals['_COMPILE']._serialized_end=1464
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.model.SerializeToString,
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.model.FromString,
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.model.SerializeToString,
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 MapperConf, Mapper, MapperState
16
+ from femtomapper import compile as femtomapper_compile
17
17
  from femtobehav.fasmir import FASMIR
18
18
  from femtobehav.sim import SimRunner
19
- from typing import Any
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, options: dict) -> FASMIR:
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(self, options: dict = {}):
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(self.input_ir, options)
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(self.fasmir, data_dir=dirname, encrypt=encrypt)
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, inputs: dict[str, np.ndarray], input_period: float = None, **kwargs
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(self, input_ir: GraphProto, options: dict) -> FASMIR:
129
- fasmir = _compile_fqir(input_ir, options)
130
- # wrapper = self._get_fqir_iowrapper(input_ir, fasmir)
131
- return fasmir
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):
@@ -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.model) -> CompilerFrontend:
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(self, model: cs_pb2.model, context) -> CompilerFrontend:
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
- # Get a compiler for the model
56
- model_type_map = {
57
- "fqir": self._get_fqir_compiler,
58
- }
59
- model_type = model.WhichOneof("ir")
60
- compiler = model_type_map[model_type](model)
61
-
62
- # Get the compiler options
63
- options_struct = field_or_none(model, "options")
64
- if options_struct is None:
65
- options = {}
66
- else:
67
- options = MessageToDict(options_struct)
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(options=options)
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
- return cs_pb2.compiled_artifacts(
92
- bitfile=bitfile, status=cs_pb2.status(success=True)
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(success=False, msg="Expected model message.")
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"))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: femtocrux
3
- Version: 2.5.1
3
+ Version: 3.0.0
4
4
  Summary: Femtosense Compiler
5
5
  Home-page: https://github.com/femtosense/femtocrux
6
6
  Author: Femtosense
@@ -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,,
@@ -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,,