Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failure at converters.convert_from_pytorch_model . compile/build() #954

Open
fgias opened this issue Jan 10, 2024 · 0 comments
Open

Failure at converters.convert_from_pytorch_model . compile/build() #954

fgias opened this issue Jan 10, 2024 · 0 comments
Labels

Comments

@fgias
Copy link

fgias commented Jan 10, 2024

Quick summary

After creating the HLS model successfully, from the PyTorch model, with the command

hls_model = hls4ml.converters.convert_from_pytorch_model( ... )

the command hls_model.compile() or hls_model.build(csim=False, export=True) fails.

Details

The error output.

Writing HLS project
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[7], line 1
----> 1 hls_model.build(csim=False, export=True)

File ~/hls4ml-etx4velo/hls4ml/hls4ml/model/graph.py:869, in ModelGraph.build(self, **kwargs)
    863 """Builds the generated project using HLS compiler.
    864 
    865 Please see the `build()` function of backends for a list of possible arguments.
    866 """
    867 if not os.path.exists(self.config.get_output_dir()):
    868     # Assume the project wasn't written before
--> 869     self.write()
    871 return self.config.backend.build(self, **kwargs)

File ~/hls4ml-etx4velo/hls4ml/hls4ml/model/graph.py:654, in ModelGraph.write(self)
    647 def write(self):
    648     """Write the generated project to disk.
    649 
    650     This function converts the model to C++ and writes the generated files in the output
    651     directory specified in the `config`.
    652     """
--> 654     self.config.backend.write(self)

File ~/hls4ml-etx4velo/hls4ml/hls4ml/backends/fpga/fpga_backend.py:150, in FPGABackend.write(self, model)
    140 def write(self, model):
    141     """Write the generated project to disk.
    142 
    143     This function converts the model to C++ and writes the generated files in the output
   (...)
    147         model (ModelGraph): Model to write.
    148     """
--> 150     model.apply_flow(self.get_writer_flow())

File ~/hls4ml-etx4velo/hls4ml/hls4ml/model/graph.py:424, in ModelGraph.apply_flow(self, flow, reapply)
    421         return
    423 self._applied_flows.append(applied_flows)
--> 424 self._apply_sub_flow(flow, applied_flows)

File ~/hls4ml-etx4velo/hls4ml/hls4ml/model/graph.py:436, in ModelGraph._apply_sub_flow(self, flow_name, applied_flows)
    433         self._apply_sub_flow(sub_flow, applied_flows)
    435 if len(flow.optimizers) > 0:
--> 436     applied_passes = optimize_model(self, flow.optimizers)
    437 else:
    438     applied_passes = set()

File ~/hls4ml-etx4velo/hls4ml/hls4ml/model/optimizer/optimizer.py:312, in optimize_model(model, passes)
    310 for opt_name, opt in optimizers.items():
    311     if isinstance(opt, ModelOptimizerPass) and opt_name not in applied_passes:
--> 312         res = opt.transform(model)
    313         if res:
    314             applied_passes.add(opt_name)

File ~/hls4ml-etx4velo/hls4ml/hls4ml/model/optimizer/optimizer.py:94, in ModelOptimizerPass.transform(self, model)
     93 def transform(self, model):
---> 94     retval = self.transform_func(model)
     95     return retval if retval is not None else False

File ~/hls4ml-etx4velo/hls4ml/hls4ml/backends/fpga/fpga_backend.py:865, in FPGABackend.write_hls(self, model)
    863 @model_optimizer()
    864 def write_hls(self, model):
--> 865     self.writer.write_hls(model)
    866     return True

File ~/hls4ml-etx4velo/hls4ml/hls4ml/writer/vivado_writer.py:726, in VivadoWriter.write_hls(self, model)
    724 self.write_nnet_utils(model)
    725 self.write_generated_code(model)
--> 726 self.write_yml(model)
    727 self.write_tar(model)
    728 print('Done')

File ~/hls4ml-etx4velo/hls4ml/hls4ml/writer/vivado_writer.py:701, in VivadoWriter.write_yml(self, model)
    698     pass
    700 with open(model.config.get_output_dir() + '/' + config_filename, 'w') as file:
--> 701     yaml.dump(model.config.config, file)

File /dsk/l1/misc/fgias/miniforge3/envs/hls4ml-etx4velo-deps-tf/lib/python3.11/site-packages/yaml/__init__.py:253, in dump(data, stream, Dumper, **kwds)
    248 def dump(data, stream=None, Dumper=Dumper, **kwds):
    249     """
    250     Serialize a Python object into a YAML stream.
    251     If stream is None, return the produced string instead.
    252     """
--> 253     return dump_all([data], stream, Dumper=Dumper, **kwds)

File /dsk/l1/misc/fgias/miniforge3/envs/hls4ml-etx4velo-deps-tf/lib/python3.11/site-packages/yaml/__init__.py:241, in dump_all(documents, stream, Dumper, default_style, default_flow_style, canonical, indent, width, allow_unicode, line_break, encoding, explicit_start, explicit_end, version, tags, sort_keys)
    239     dumper.open()
    240     for data in documents:
--> 241         dumper.represent(data)
    242     dumper.close()
    243 finally:

File /dsk/l1/misc/fgias/miniforge3/envs/hls4ml-etx4velo-deps-tf/lib/python3.11/site-packages/yaml/representer.py:27, in BaseRepresenter.represent(self, data)
     26 def represent(self, data):
---> 27     node = self.represent_data(data)
     28     self.serialize(node)
     29     self.represented_objects = {}

File /dsk/l1/misc/fgias/miniforge3/envs/hls4ml-etx4velo-deps-tf/lib/python3.11/site-packages/yaml/representer.py:48, in BaseRepresenter.represent_data(self, data)
     46 data_types = type(data).__mro__
     47 if data_types[0] in self.yaml_representers:
---> 48     node = self.yaml_representers[data_types[0]](self, data)
     49 else:
     50     for data_type in data_types:

File /dsk/l1/misc/fgias/miniforge3/envs/hls4ml-etx4velo-deps-tf/lib/python3.11/site-packages/yaml/representer.py:207, in SafeRepresenter.represent_dict(self, data)
    206 def represent_dict(self, data):
--> 207     return self.represent_mapping('tag:yaml.org,2002:map', data)

File /dsk/l1/misc/fgias/miniforge3/envs/hls4ml-etx4velo-deps-tf/lib/python3.11/site-packages/yaml/representer.py:118, in BaseRepresenter.represent_mapping(self, tag, mapping, flow_style)
    116 for item_key, item_value in mapping:
    117     node_key = self.represent_data(item_key)
--> 118     node_value = self.represent_data(item_value)
    119     if not (isinstance(node_key, ScalarNode) and not node_key.style):
    120         best_style = False

File /dsk/l1/misc/fgias/miniforge3/envs/hls4ml-etx4velo-deps-tf/lib/python3.11/site-packages/yaml/representer.py:52, in BaseRepresenter.represent_data(self, data)
     50 for data_type in data_types:
     51     if data_type in self.yaml_multi_representers:
---> 52         node = self.yaml_multi_representers[data_type](self, data)
     53         break
     54 else:

File /dsk/l1/misc/fgias/miniforge3/envs/hls4ml-etx4velo-deps-tf/lib/python3.11/site-packages/yaml/representer.py:342, in Representer.represent_object(self, data)
    339 function_name = '%s.%s' % (function.__module__, function.__name__)
    340 if not args and not listitems and not dictitems \
    341         and isinstance(state, dict) and newobj:
--> 342     return self.represent_mapping(
    343             'tag:yaml.org,2002:python/object:'+function_name, state)
    344 if not listitems and not dictitems  \
    345         and isinstance(state, dict) and not state:
    346     return self.represent_sequence(tag+function_name, args)

File /dsk/l1/misc/fgias/miniforge3/envs/hls4ml-etx4velo-deps-tf/lib/python3.11/site-packages/yaml/representer.py:118, in BaseRepresenter.represent_mapping(self, tag, mapping, flow_style)
    116 for item_key, item_value in mapping:
    117     node_key = self.represent_data(item_key)
--> 118     node_value = self.represent_data(item_value)
    119     if not (isinstance(node_key, ScalarNode) and not node_key.style):
    120         best_style = False

File /dsk/l1/misc/fgias/miniforge3/envs/hls4ml-etx4velo-deps-tf/lib/python3.11/site-packages/yaml/representer.py:52, in BaseRepresenter.represent_data(self, data)
     50 for data_type in data_types:
     51     if data_type in self.yaml_multi_representers:
---> 52         node = self.yaml_multi_representers[data_type](self, data)
     53         break
     54 else:

File /dsk/l1/misc/fgias/miniforge3/envs/hls4ml-etx4velo-deps-tf/lib/python3.11/site-packages/yaml/representer.py:330, in Representer.represent_object(self, data)
    328     listitems = list(listitems)
    329 if dictitems is not None:
--> 330     dictitems = dict(dictitems)
    331 if function.__name__ == '__newobj__':
    332     function = args[0]

ValueError: dictionary update sequence element #0 has length 1; 2 is required

Steps to Reproduce

  1. Clone hls4ml-etx4velo.
git clone https://gitlab.cern.ch/gdl4hep/hls4ml-etx4velo --recurse-submodules
  1. Follow the instructions in the README.md to set up Vivado and the environment. Use the hls4ml-etx4velo-deps.yaml file to create the environment.

  2. Run the notebook hls4ml-etx4velo.ipynb.

Expected behavior

This should in principle write the HLS project.

Actual behavior

Instead it crashes.

Optional

Possible fix

According to the error output, it seems to be that the problem is in the hls4ml writer vivado_writer.py.

@fgias fgias added the bug label Jan 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant