Skip to content

transpose_3d for hls_stream missing #712

Description

@AnouarITI

I have the following model:

x_in = Input(shape=(1024,1,2))
x = Permute((3,1,2))(x_in)

x = Conv2D(8 , (7,1), padding='same', name='C1')(x)
x = ReLU(name='C1_relu')(x)
x = Conv2D(16, (7,1), padding='same', name='C2')(x)
x = ReLU(name='C2_relu')(x)
x = Conv2D(32, (7,1), padding='same', name='C3')(x)
x = ReLU(name='C3_relu')(x)
x = Conv2D(64, (7,1), padding='same', name='C4')(x)
x = ReLU(name='C4_relu')(x)

x = AveragePooling2D((1,256), (1,256), padding='same', name='AVG_pool_1')(x)
x = AveragePooling2D((1,4), (1,4), padding='same', name='AVG_pool_2')(x)

x = Flatten()(x)

x = Dense(256, name='D1')(x)
x = ReLU(name='D1_relu')(x)
x = Dense(22, name='D2')(x)
x_out = Softmax(name='D2_softmax')(x)

model = models.Model(x_in, x_out)

And I am trying to convert it to an hls_model, everything went alright until i hit an error which I think it is caused by the permute layer.
Here is the rest of the code to replicate the behavior:

LOSS        = tf.keras.losses.CategoricalCrossentropy()
OPTIMIZER   = tf.keras.optimizers.Adam(learning_rate=1E-3)

model.compile(loss=LOSS, optimizer=OPTIMIZER, metrics=["accuracy"])
import hls4ml

hls4ml.model.optimizer.get_optimizer('output_rounding_saturation_mode').configure(layers=['Activation'])
hls4ml.model.optimizer.get_optimizer('output_rounding_saturation_mode').configure(rounding_mode='AP_RND')
hls4ml.model.optimizer.get_optimizer('output_rounding_saturation_mode').configure(saturation_mode='AP_SAT')

hls_config = hls4ml.utils.config_from_keras_model(model, granularity='name')

Precision = 'ap_fixed<16,6>'
Reuse_Factor = 1

hls_config['Model']['Precision'] = Precision
hls_config['Model']['ReuseFactor'] = Reuse_Factor

for Layer in hls_config['LayerName'].keys():
    hls_config['LayerName'][Layer]['Precision'] = Precision
    hls_config['LayerName'][Layer]['Strategy'] = 'Latency'
    hls_config['LayerName'][Layer]['ReuseFactor'] = Reuse_Factor
    
hls_config['LayerName']['D2_softmax']['Strategy'] = 'Stable'

cfg = hls4ml.converters.create_config(backend='Vivado')
cfg['IOType']     = 'io_stream' # Must set this if using CNNs!
cfg['HLSConfig']  = hls_config
cfg['KerasModel'] = model
cfg['OutputDir']  = 'model_16b_rf1/'
cfg['XilinxPart'] = 'xcvu9p-flga2104-2L-e'

hls_model = hls4ml.converters.keras_to_hls(cfg)
hls_model.compile()

and this is the error:

firmware/myproject.cpp: In function ‘void myproject(hls::stream<nnet::array<ap_fixed<16, 6>, 2> >&, hls::stream<nnet::array<ap_fixed<16, 6>, 22> >&)’:
firmware/myproject.cpp:61:52: error: cannot convert ‘hls::stream<nnet::array<ap_fixed<16, 6>, 2> >’ to ‘nnet::array<ap_fixed<16, 6>, 2>*’
   61 |     nnet::transpose_3d<input_t, layer2_t, config2>(input_1, layer2_out); // permute
      |                                                    ^~~~~~~
      |                                                    |
      |                                                    hls::stream<nnet::array<ap_fixed<16, 6>, 2> >
In file included from firmware/parameters.h:12,
                 from firmware/myproject.cpp:22:
firmware/nnet_utils/nnet_array.h:31:12: note:   initializing argument 1 of ‘void nnet::transpose_3d(data_T*, res_T*) [with data_T = nnet::array<ap_fixed<16, 6>, 2>; res_T = nnet::array<ap_fixed<16, 6>, 1>; CONFIG_T = config2]’
   31 |     data_T data[CONFIG_T::depth * CONFIG_T::height * CONFIG_T::width],
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
firmware/nnet_utils/nnet_array.h: In instantiation of ‘void nnet::transpose_3d(data_T*, res_T*) [with data_T = nnet::array<ap_fixed<16, 6>, 2>; res_T = nnet::array<ap_fixed<16, 6>, 1>; CONFIG_T = config2]’:
firmware/myproject.cpp:61:71:   required from here
firmware/nnet_utils/nnet_array.h:48:92: error: no match for ‘operator=’ (operand types are ‘nnet::array<ap_fixed<16, 6>, 1>’ and ‘nnet::array<ap_fixed<16, 6>, 2>’)
   48 |                 data_t[idx_t[0] * dims_t[1] * dims_t[2] + idx_t[1] * dims_t[2] + idx_t[2]] = data[idx[0] * dims[1] * dims[2] + idx[1] * dims[2] + idx[2]];
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
In file included from firmware/defines.h:6,
                 from firmware/myproject.h:27,
                 from firmware/myproject.cpp:21:
firmware/nnet_utils/nnet_types.h:26:12: note: candidate: ‘nnet::array<T, N>& nnet::array<T, N>::operator=(const nnet::array<T, N>&) [with T = ap_fixed<16, 6>; unsigned int N = 1]’
   26 |     array& operator=(const array &other) {
      |            ^~~~~~~~
firmware/nnet_utils/nnet_types.h:26:35: note:   no known conversion for argument 1 from ‘nnet::array<ap_fixed<16, 6>, 2>’ to ‘const nnet::array<ap_fixed<16, 6>, 1>&’
   26 |     array& operator=(const array &other) {
      |                      ~~~~~~~~~~~~~^~~~~
g++: error: myproject.o: No such file or directory

I thought that the Permute layer is already supported by hls4ml, or I am wrong?? How can I fix such an error?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions