AttributeError: Could not find IP or hierarchy fir_filter in overlay

Hi,

I am new to PYNQ environment and trying out this online example using PYNQ-Z2 board
How to accelerate a Python function with PYNQ - FPGA Developer
Except for folder and design names, I have followed the tutorial closely and below is my overlay diagram and notebook. I have placed the .tcl, .bit and .hwh files in the overlay folder.
FIR_Accel.pdf (80.3 KB)
FIR_Acceleration.ipynb (434.2 KB)

I am able to run the codes until the part where it tries to address the FIR filter and got the error below:

On trying to debug the issue, I noticed there is no “fir_filter” in the block design and I don’t understand why the tutorial is able to run this line without issue. I tried changing it to overlay.filter.fir but still getting the error.

Can someone kindly point to me where I might have done wrong?

2 Likes

Hi @VLHS,

You are missing the custom driver that is being created to handle the FIR. .fir_filter does not refer to an IP, but rather is a method of the FirDriver class. This is cell 8 in the notebook.

Mario

1 Like

Hi Mario,

Thank you for pointing out my misunderstanding bur I will like to seek further clarity. I ran cell 8 so shouldn’t the function “fir_filter” be recognized by my environment? Or am I missing some file on my PYNQ board? In the usual Python sense, I should invoke it using FirDriver.fir_filter isn’t it?

You need to run cell 8 before using the Overlay class. Have you done that?

When you call Overlay, pynq assigns defaultHierarchy by default unless there is a class that inherits from defaultHierarchy in the environment. In such case, pynq will assign the corresponding class

Yes, I ran cell 8. The call to overlay.filter.fir_filter in my original post is in cell 9. After running cell 9 with error, I did a print out of the overlay details and copped out the following:


Am I supposed to see pynq.overlay.FirDriver instead of pynq.overlay.DefaultHierarchy?

@VLHS,

The tutorial was create with an older version of pynq. In the latest version, the fir is not part of the .ip_dict, so the hierarchy class needs updating. Note, that I also update to allocate, Xlnk is deprecated.

from pynq import DefaultHierarchy
from pynq import allocate

class FirDriver(DefaultHierarchy):
    def __init__(self, description):
        super().__init__(description)
        
    def fir_filter(self, data):
         with allocate(shape=(len(data),), dtype=np.int32) as in_buffer,\
              allocate(shape=(len(data),), dtype=np.int32) as out_buffer:
             np.copyto(in_buffer,data)
             self.fir_dma.sendchannel.transfer(in_buffer)
             self.fir_dma.recvchannel.transfer(out_buffer)
             self.fir_dma.sendchannel.wait()
             self.fir_dma.recvchannel.wait()
             result = out_buffer.copy()
         return result
    
    # use @staticmethod... Can't change class state, just as a utility function
    # remove check for FIR in the desc because somehow it's not there.
    @staticmethod
    def checkhierarchy(description):
        if 'fir_dma' in description['ip']:
            return True
        else:
            return False

I checked, and it is working for me.

Hierarchies
-----------
filter               : __main__.FirDriver

Mario

2 Likes

I am able to overcome the issue with your inputs and obtain the output as you have shown. However, my issue persists with my environment complaining of ‘PynqBuffer’ object has no attribute ‘free_buffer’ on exiting the driver call when the function exit was invoked.

What pynq version are you using? If you go back to Xlnk, does this happen?

The PYNQ version I am using is Release 2019_10_03. When I reverted the two “allocate” call to “xlnk.cma_array”, I am still getting no free_buffer attribute error.

Please install download the latest sdcard (2.6.0) image and try with that version, http://www.pynq.io/board.html

Mario

image001.jpg

I refreshed my image to PYNQ 2.6.0 and now able to run the code successfully on my PYNQ-Z2. Thank you for guiding me to resolve my issue.

1 Like

Thanks much. This works in PYNQ 2.7 also.

John

1 Like

On my ZCU104, I get the following times:
Software FIR execution time: 0.0432887077331543
Hardware FIR execution time: 0.003331422805786133
Hardware FIR execution time (with driver): 0.07016849517822266

So using the the driver slows it down to much slower than just doing it in the CPU. Is this expected or does anyone have suggestions on how to optimize the driver code?

I am new to this and will update if I figure something out.

Thanks,
John

1 Like

Answering my own question - Comparing apples to oranges.

The Hardware FIR execution time doesn’t include buffer allocation or the numpy copy while the Hardware FIR execution time (with driver) does.

John

1 Like

Thank u for the insights John
Abdelghani

As alternative to upgrading to 2.6 as suggested, as a temporary workaround the notebook can be modified. The error is due to a bug in Pynq v2.5, specifically in buffer.py where PynqBuffer calls “free_buffer” at exit, but the implemented method is actually called “freebuffer”. This is triggered by the use of the with block (regardless of the status of the buffers), so a solution is to make the driver method look more like the code in the earlier cell, just with a result = out_buffer.copy() instead of plotting.

1 Like