femtocrux 3.0.0__py3-none-any.whl → 3.2.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
- 3.0.0
1
+ 3.2.0
@@ -21,7 +21,8 @@ from femtocrux.util.utils import (
21
21
  read_secret_raw,
22
22
  get_channel_options,
23
23
  serialize_sim_inputs_message,
24
- deserialize_simulation_output,
24
+ deserialize_simulation_data,
25
+ deserialize_simulation_data_list,
25
26
  )
26
27
 
27
28
  from google.protobuf.message import Message
@@ -274,9 +275,9 @@ class Simulator:
274
275
 
275
276
  def simulate(
276
277
  self,
277
- inputs: Iterable[np.array],
278
+ inputs: list[dict[str, np.ndarray]] | dict[str, np.ndarray],
278
279
  input_period: float = 0.016,
279
- ) -> List[np.array]:
280
+ ) -> tuple:
280
281
  """
281
282
  Simulates the model on the given inputs.
282
283
 
@@ -285,11 +286,28 @@ class Simulator:
285
286
  "input_name1": np.ndarray(int16 types ...),
286
287
  "input_name2": np.ndarray([int16 types ...])
287
288
  }
289
+ # Array has dimensions for sequence, features
290
+
291
+ or a list of dicts
292
+ [
293
+ {"input_name1": np.ndarray(int16 types ..),
294
+ "input_name2": np.ndarray(int16 ...)},
295
+ {"input_name1": np.ndarray(int16 types ..),
296
+ "input_name2": np.ndarray(int16 ...)},
297
+ {"input_name1": np.ndarray(int16 types ..),
298
+ "input_name2": np.ndarray(int16 ...)},
299
+ ]
300
+
301
+ The sequence dimension is captured as list elements and the
302
+ array only has a feature dimension
303
+
288
304
  :type input_period (float, optional): Duration between each input in a sequence,
289
305
  in seconds.
290
306
 
291
- :rtype: list
292
- :return: The output tensors.
307
+ :rtype: tuple
308
+ :return: The deserialzed outputs either as a
309
+ list[str, np.ndarray.shape(features)] or
310
+ dict[str, np.ndarray.shape(sequence, features))] and the sim report.
293
311
 
294
312
  """
295
313
 
@@ -299,7 +317,16 @@ class Simulator:
299
317
  self._send_request(simulation_request)
300
318
  response = self._get_response()
301
319
 
302
- return deserialize_simulation_output(response.outputs), response.report
320
+ which = response.WhichOneof("output_data")
321
+ if which == "outputs":
322
+ deserialized_outputs = deserialize_simulation_data(response.outputs)
323
+ elif which == "list_outputs":
324
+ deserialized_outputs = deserialize_simulation_data_list(
325
+ response.list_outputs
326
+ )
327
+ else:
328
+ raise (Exception("Didn't get output data as proto dict or list message."))
329
+ return deserialized_outputs, response.report
303
330
 
304
331
 
305
332
  class CompilerClientImpl:
@@ -26,17 +26,15 @@ 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\"\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')
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\"\xdb\x01\n\x0fsimulation_data\x12+\n\x06inputs\x18\x01 \x01(\x0b\x32\x19.fscompiler.str_array_mapH\x00\x12\x35\n\x0blist_inputs\x18\x02 \x01(\x0b\x32\x1e.fscompiler.list_str_array_mapH\x00\x12\x19\n\x0csim_duration\x18\x03 \x01(\x02H\x01\x88\x01\x01\x12\x19\n\x0cinput_period\x18\x04 \x01(\x02H\x02\x88\x01\x01\x42\x0c\n\ninput_dataB\x0f\n\r_sim_durationB\x0f\n\r_input_period\"\x84\x01\n\rstr_array_map\x12\x31\n\x04\x64\x61ta\x18\x01 \x03(\x0b\x32#.fscompiler.str_array_map.DataEntry\x1a@\n\tDataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.fscompiler.ndarray:\x02\x38\x01\"=\n\x12list_str_array_map\x12\'\n\x04maps\x18\x01 \x03(\x0b\x32\x19.fscompiler.str_array_map\"\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\"\xbc\x01\n\x11simulation_output\x12,\n\x07outputs\x18\x01 \x01(\x0b\x32\x19.fscompiler.str_array_mapH\x00\x12\x36\n\x0clist_outputs\x18\x02 \x01(\x0b\x32\x1e.fscompiler.list_str_array_mapH\x00\x12\x0e\n\x06report\x18\x03 \x01(\t\x12\"\n\x06status\x18\x04 \x01(\x0b\x32\x12.fscompiler.statusB\r\n\x0boutput_data\"\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)
33
33
  _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'compiler_service_pb2', _globals)
34
34
  if not _descriptor._USE_C_DESCRIPTORS:
35
35
  DESCRIPTOR._loaded_options = None
36
- _globals['_SIMULATION_DATA_INPUTSENTRY']._loaded_options = None
37
- _globals['_SIMULATION_DATA_INPUTSENTRY']._serialized_options = b'8\001'
38
- _globals['_SIMULATION_OUTPUT_OUTPUTSENTRY']._loaded_options = None
39
- _globals['_SIMULATION_OUTPUT_OUTPUTSENTRY']._serialized_options = b'8\001'
36
+ _globals['_STR_ARRAY_MAP_DATAENTRY']._loaded_options = None
37
+ _globals['_STR_ARRAY_MAP_DATAENTRY']._serialized_options = b'8\001'
40
38
  _globals['_FQIR']._serialized_start=97
41
39
  _globals['_FQIR']._serialized_end=200
42
40
  _globals['_TFLITE']._serialized_start=202
@@ -52,17 +50,19 @@ if not _descriptor._USE_C_DESCRIPTORS:
52
50
  _globals['_DATA']._serialized_start=900
53
51
  _globals['_DATA']._serialized_end=920
54
52
  _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
53
+ _globals['_SIMULATION_DATA']._serialized_end=1142
54
+ _globals['_STR_ARRAY_MAP']._serialized_start=1145
55
+ _globals['_STR_ARRAY_MAP']._serialized_end=1277
56
+ _globals['_STR_ARRAY_MAP_DATAENTRY']._serialized_start=1213
57
+ _globals['_STR_ARRAY_MAP_DATAENTRY']._serialized_end=1277
58
+ _globals['_LIST_STR_ARRAY_MAP']._serialized_start=1279
59
+ _globals['_LIST_STR_ARRAY_MAP']._serialized_end=1340
60
+ _globals['_SIMULATION_INPUT']._serialized_start=1343
61
+ _globals['_SIMULATION_INPUT']._serialized_end=1472
62
+ _globals['_SIMULATION_OUTPUT']._serialized_start=1475
63
+ _globals['_SIMULATION_OUTPUT']._serialized_end=1663
64
+ _globals['_VERSION_INFO']._serialized_start=1665
65
+ _globals['_VERSION_INFO']._serialized_end=1696
66
+ _globals['_COMPILE']._serialized_start=1699
67
+ _globals['_COMPILE']._serialized_end=1973
68
68
  # @@protoc_insertion_point(module_scope)
@@ -51,7 +51,7 @@ class CompilerFrontend:
51
51
  self,
52
52
  input_ir: GraphProto,
53
53
  iospec: IOSpec | None = None,
54
- opt_profile: Literal["efficient", "fast", "conservative"] | None = "efficient",
54
+ opt_profile: Literal["efficient", "fast", "conservative"] | None = None,
55
55
  user_configuration: dict | None = None,
56
56
  memory_reservations: dict | None = None,
57
57
  ) -> tuple[FASMIR, IOSpec, dict]:
@@ -100,7 +100,7 @@ class CompilerFrontend:
100
100
 
101
101
  def run_behavioral_simulator(
102
102
  self,
103
- inputs: dict[str, np.ndarray],
103
+ inputs: dict[str, np.ndarray] | list[dict[str, np.ndarray]],
104
104
  input_period: float = None,
105
105
  iospec: IOSpec | None = None,
106
106
  **kwargs
@@ -135,7 +135,7 @@ class TorchCompiler(CompilerFrontend):
135
135
  self,
136
136
  input_ir: GraphProto,
137
137
  iospec: IOSpec | None = None,
138
- opt_profile: Literal["efficient", "fast", "conservative"] | None = "efficient",
138
+ opt_profile: Literal["efficient", "fast", "conservative"] | None = None,
139
139
  user_configuration: dict | None = None,
140
140
  memory_reservations: dict | None = None,
141
141
  ) -> tuple[FASMIR, IOSpec, dict]:
@@ -15,6 +15,7 @@ from femtocrux.util.utils import (
15
15
  get_channel_options,
16
16
  serialize_simulation_output,
17
17
  deserialize_simulation_data,
18
+ deserialize_simulation_data_list,
18
19
  )
19
20
 
20
21
  # Import GRPC artifacts
@@ -165,7 +166,16 @@ class CompileServicer(cs_pb2_grpc.CompileServicer):
165
166
  try:
166
167
  if data_request.WhichOneof("model_or_data") == "data":
167
168
  ### New Path with int64 proto message holding data
168
- deserialized_inputs = deserialize_simulation_data(data.inputs)
169
+
170
+ which = data.WhichOneof("input_data")
171
+ if which == "inputs":
172
+ deserialized_inputs = deserialize_simulation_data(data.inputs)
173
+ elif which == "list_inputs":
174
+ deserialized_inputs = deserialize_simulation_data_list(
175
+ data.list_inputs
176
+ )
177
+ else:
178
+ raise (Exception("Didn't get input data as dict or list."))
169
179
  outputs, metrics = compiler.run_behavioral_simulator(
170
180
  deserialized_inputs,
171
181
  input_period=field_or_none(data, "input_period"),
femtocrux/util/utils.py CHANGED
@@ -31,47 +31,108 @@ def serialize_numpy_array(arr: np.ndarray) -> cs_pb2.ndarray:
31
31
  )
32
32
 
33
33
 
34
+ def prepare_array_for_serialization(array, type_of_input="dict"):
35
+ """
36
+ Check that the arrays that are sent for inputs have the correct types and shapes.
37
+
38
+ They have to be np.ndarrays and have the appropriate shapes:
39
+ List[Dict[str, np.ndarray]] the ndarray has to only have 1 dimension of features
40
+ Dict[str, np.ndarray] the ndarray can have 2 dimensions, one for sequence and
41
+ another for features.
42
+ """
43
+ if isinstance(array, torch.Tensor):
44
+ array_to_serialize = array.numpy()
45
+ elif isinstance(array, np.ndarray):
46
+ array_to_serialize = array
47
+ else:
48
+ raise (Exception("Input array was not of type torch.Tensor or np.ndarray"))
49
+
50
+ if not np.issubdtype(array_to_serialize.dtype, np.integer):
51
+ raise (
52
+ Exception(
53
+ "Input data is not an integer type. Please quantize your"
54
+ "data to int16 or lower."
55
+ )
56
+ )
57
+ shape_size = 2
58
+ if type_of_input == "dict":
59
+ shape_size = 2
60
+ elif type_of_input == "list":
61
+ shape_size = 1
62
+
63
+ if len(array_to_serialize.shape) > shape_size:
64
+ raise (
65
+ Exception(
66
+ f"Expected {shape_size} dimensions for input and got shape: "
67
+ f"{array_to_serialize.shape} Your input array has too many "
68
+ f"dimensions. When in inference mode, please remove any batch "
69
+ f"dimensions."
70
+ )
71
+ )
72
+ return array_to_serialize
73
+
74
+
34
75
  def serialize_sim_inputs_message(
35
- data_dict: dict, input_period: float
76
+ input_data: list | dict, input_period: float
36
77
  ) -> cs_pb2.simulation_data:
37
- """Serializes a dictionary where values are NumPy arrays."""
78
+ """
79
+ Serialize input_data which could be the list[dict[str, np.ndarray]] or
80
+ dict[str, np.ndarray] format of input into oneof.
81
+
82
+ list_str_array_map or str_array_map proto messages and create a larger
83
+ simulation_data proto message.
84
+
85
+ return simulation_data proto message
86
+ """
38
87
  message = cs_pb2.simulation_data()
39
- for key, array in data_dict.items():
40
- if isinstance(array, torch.Tensor):
41
- array_to_serialize = array.numpy()
42
- elif isinstance(array, np.ndarray):
43
- array_to_serialize = array
44
- else:
45
- raise (Exception("Input array was not of type torch.Tensor or np.ndarray"))
46
-
47
- if not np.issubdtype(array_to_serialize.dtype, np.integer):
48
- raise (
49
- Exception(
50
- "Input data is not an integer type. Please quantize your"
51
- "data to int16 or lower."
52
- )
53
- )
54
88
 
55
- if len(array_to_serialize.shape) > 2:
56
- raise (
57
- Exception(
58
- "Expected 2 dimensions for input and got shape: "
59
- "{array_to_serialize.shape} Your input array has too many "
60
- "dimensions. When in inference mode, please remove any batch "
61
- "dimensions."
89
+ if isinstance(input_data, list):
90
+ for single_entry in input_data:
91
+ input_map = message.list_inputs.maps.add()
92
+ for key, array in single_entry.items():
93
+ array_to_serialize = prepare_array_for_serialization(
94
+ array, type_of_input="list"
62
95
  )
63
- )
96
+ input_map.data[key].CopyFrom(serialize_numpy_array(array_to_serialize))
64
97
 
65
- message.inputs[key].CopyFrom(serialize_numpy_array(array_to_serialize))
98
+ elif isinstance(input_data, dict):
99
+ for key, array in input_data.items():
100
+ array_to_serialize = prepare_array_for_serialization(
101
+ array, type_of_input="dict"
102
+ )
103
+ message.inputs.data[key].CopyFrom(serialize_numpy_array(array_to_serialize))
104
+ else:
105
+ raise (
106
+ Exception(f"input_data was of type {type(input_data)}, not dict or list.")
107
+ )
66
108
  message.input_period = input_period
67
109
  return message
68
110
 
69
111
 
70
- def serialize_simulation_output(data_dict: dict, report) -> cs_pb2.simulation_output:
71
- """Serializes a dictionary where values are NumPy arrays."""
112
+ def serialize_simulation_output(
113
+ output_data: dict | list, report
114
+ ) -> cs_pb2.simulation_output:
115
+ """
116
+ Serialize the output_data and report into a proto message simulation_output.
117
+
118
+ We have both the list[dict[str, np.ndarray]] and the dict[str, np.ndarray]
119
+ as possible output formats.
120
+
121
+ We serialize whichever one we get as message.list_outputs or message.outputs
122
+
123
+ return the proto message
124
+ """
72
125
  message = cs_pb2.simulation_output()
73
- for key, array in data_dict.items():
74
- message.outputs[key].CopyFrom(serialize_numpy_array(array))
126
+
127
+ if isinstance(output_data, list):
128
+ for single_entry in output_data:
129
+ output_map = message.list_outputs.maps.add()
130
+ for key, array in single_entry.items():
131
+ output_map.data[key].CopyFrom(serialize_numpy_array(array))
132
+ elif isinstance(output_data, dict):
133
+ for key, array in output_data.items():
134
+ message.outputs.data[key].CopyFrom(serialize_numpy_array(array))
135
+
75
136
  message.report = json.dumps(report)
76
137
  message.status.CopyFrom(cs_pb2.status(success=True))
77
138
 
@@ -83,14 +144,23 @@ def deserialize_numpy_array(proto: cs_pb2.ndarray) -> np.ndarray:
83
144
  return np.frombuffer(proto.data, dtype=np.dtype(proto.dtype)).reshape(proto.shape)
84
145
 
85
146
 
86
- def deserialize_simulation_data(proto: cs_pb2.simulation_data) -> dict:
87
- """Deserializes a LargerMessage back into a dictionary of NumPy arrays."""
88
- return {key: deserialize_numpy_array(value) for key, value in proto.items()}
89
-
90
-
91
- def deserialize_simulation_output(proto: cs_pb2.simulation_output) -> dict:
147
+ def deserialize_simulation_data(proto: cs_pb2.str_array_map) -> dict:
92
148
  """Deserializes a LargerMessage back into a dictionary of NumPy arrays."""
93
- return {key: deserialize_numpy_array(value) for key, value in proto.items()}
149
+ return {key: deserialize_numpy_array(value) for key, value in proto.data.items()}
150
+
151
+
152
+ def deserialize_simulation_data_list(list_input: cs_pb2.list_str_array_map) -> list:
153
+ """
154
+ Convert proto list_str_array_map into a python list[dict[str, np.ndarray]]
155
+ """
156
+ list_of_dicts = []
157
+ for input_map in list_input.maps:
158
+ dict_entry = {}
159
+ for key, ndarray_proto in input_map.data.items():
160
+ # Convert ndarray proto to whatever format you need
161
+ dict_entry[key] = deserialize_numpy_array(ndarray_proto)
162
+ list_of_dicts.append(dict_entry)
163
+ return list_of_dicts
94
164
 
95
165
 
96
166
  def read_secret_raw(prompt="Secret: "):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: femtocrux
3
- Version: 3.0.0
3
+ Version: 3.2.0
4
4
  Summary: Femtosense Compiler
5
5
  Home-page: https://github.com/femtosense/femtocrux
6
6
  Author: Femtosense
@@ -1,22 +1,22 @@
1
1
  femtocrux/ENV_REQUIREMENTS.sh,sha256=t_O1B4hJAMgxvH9gwp1qls6eVFmhSYBJe64KmuK_H-4,1389
2
2
  femtocrux/PY_REQUIREMENTS,sha256=UwXV0o3gieruZUYdN9r2bqQ0Wcf_vosjeP6LJVx6oF0,275
3
- femtocrux/VERSION,sha256=KYW-iyjTrehY6Nj7S8IvVlsb9gIN_5gtzhQfdyG5mZw,6
3
+ femtocrux/VERSION,sha256=M72vni1ry94uTmE-hl5AP4_iH8YhB400wwsL3H9o2QM,6
4
4
  femtocrux/__init__.py,sha256=VeuEHuCvQmqHgzj_ogjIbwGE_E8UFLYSJN6GTpXBfe0,409
5
5
  femtocrux/version.py,sha256=uNg2kHxQo6oUN1ah7s9_85rCZVRoTHGPD1GAQPZW4lw,164
6
6
  femtocrux/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- femtocrux/client/client.py,sha256=UrO8OYhw6KTbI_tHz_DpRwBx93MwO1MvrkMUnAQaR94,29797
7
+ femtocrux/client/client.py,sha256=QgyNoLdbjWbGyznWqQQyjJOgGGfGVdgiWxz-297H5Pw,31005
8
8
  femtocrux/grpc/__init__.py,sha256=uiMHQt5I2eAKJqI3Zh0h1Gm7cmPR4PbaGS71nCJQCGw,169
9
- femtocrux/grpc/compiler_service_pb2.py,sha256=ChHlC3TvWNFR-umRg2l7j3FAiybe1EGBEJfYB0Z78zM,6084
9
+ femtocrux/grpc/compiler_service_pb2.py,sha256=a95hVO0IOLTuDmmag-acQaW6v8FFVAsoOkB6_8hw6vo,6255
10
10
  femtocrux/grpc/compiler_service_pb2_grpc.py,sha256=b_fyld4rpKE4n5MimKOoyNZ5VU4UqUS_R3EM3_daqxM,8539
11
11
  femtocrux/server/__init__.py,sha256=kpm2AGLxo3AA9zo-G8N0Dm0gmWbvAd6jfhMbtkeHcxo,77
12
- femtocrux/server/compiler_frontend.py,sha256=kXVg_JIQyLY9zdwT1s5xusWaBd-9t4gDwXrU6FX6UqI,6217
12
+ femtocrux/server/compiler_frontend.py,sha256=4m7Sk8eVdFMvpS4U3fqdDd_QpNv-n1lnoxuqH2_LdHE,6233
13
13
  femtocrux/server/exceptions.py,sha256=lI6n471n5QKf5G3aL_1kuBVEItD-jBgithVVpPDwNYc,609
14
14
  femtocrux/server/healthcheck.py,sha256=ehqAwnv0D0zpy-AUZAPwv8rp874DZCwUmP8nzdXzZvI,1565
15
- femtocrux/server/server.py,sha256=k7GiLHxtzo5UH1O0edav4yEPgYD682DmB1aTZodtBuQ,8268
15
+ femtocrux/server/server.py,sha256=102uwMQQHGdNm9GXDqAHaKjDlpYRFkWxDl-7NOwcwP4,8721
16
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,,
17
+ femtocrux/util/utils.py,sha256=esE9DIT1__9smSmehhBGCY0dxLvequ2RXGXqfH4R24s,6491
18
+ femtocrux-3.2.0.dist-info/licenses/LICENSE,sha256=eN9ZI1xHjUmFvN3TEeop5kBGXRUBfbsl55KBNBYYFqI,36
19
+ femtocrux-3.2.0.dist-info/METADATA,sha256=8dsm6SO9xFvURsKigS93XpRRho37noQoGY-iQqr_Jkg,2763
20
+ femtocrux-3.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
21
+ femtocrux-3.2.0.dist-info/top_level.txt,sha256=BkTttlioC3je__8577wxRieZqY3Abu7FOOdMnmYbcNI,10
22
+ femtocrux-3.2.0.dist-info/RECORD,,