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

NNgen log ignores lazy_reshape, which is the output layer, and shows the previous operator as the output layer. #39

Open
RyusukeYamano opened this issue Jul 7, 2021 · 1 comment
Labels
wontfix This will not be worked on

Comments

@RyusukeYamano
Copy link
Contributor

RyusukeYamano commented Jul 7, 2021

NNgen log ignores lazy_reshape, which is the output layer, and shows the previous operator as the output layer.

the test case

  • /nngen/tests/matrix_reshape/test_matrix_reshape_int16.py
from __future__ import absolute_import
from __future__ import print_function

import os
import sys

# the next line can be removed after installation
sys.path.insert(0, os.path.dirname(os.path.dirname(
    os.path.dirname(os.path.abspath(__file__)))))

import nngen as ng
import veriloggen

import matrix_reshape


a_shape = (4, 16)
b_shape = (16, 4)
a_dtype = ng.int16
b_dtype = ng.int16
axi_datawidth = 32


def test(request, silent=True):
    veriloggen.reset()

    simtype = request.config.getoption('--sim')

    rslt = matrix_reshape.run(a_shape, b_shape,
                              a_dtype, b_dtype,
                              axi_datawidth, silent,
                              filename=None, simtype=simtype,
                              outputfile=os.path.splitext(os.path.basename(__file__))[0] + '.out')

    verify_rslt = rslt.splitlines()[-1]
    assert(verify_rslt == '# verify: PASSED')


if __name__ == '__main__':
    rslt = matrix_reshape.run(a_shape, b_shape,
                              a_dtype, b_dtype,
                              axi_datawidth, silent=False,
                              filename='tmp.v',
                              outputfile=os.path.splitext(os.path.basename(__file__))[0] + '.out')
    print(rslt)

It log is below

[Schedule Table]
(Stage 0)
(Stage 1)
  <_lazy_reshape None dtype:int16 shape:(16, 4) alias_of:a default_addr:128 g_index:2 word_alignment:2 aligned_shape:(16, 4) scale_factor:1.000000>
  | <placeholder a dtype:int16 shape:(4, 16) default_addr:128 g_index:2 word_alignment:2 aligned_shape:(4, 16) scale_factor:1.000000>
(Stage 2)
  <sub output_sub_0 dtype:int16 shape:(16, 4) default_addr:0 g_index:1 word_alignment:2 aligned_shape:(16, 4) scale_factor:1.000000>
  | <add None dtype:int16 shape:(16, 4) chained default_addr:0 word_alignment:2 aligned_shape:(16, 4) scale_factor:1.000000>
  | | <_lazy_reshape None dtype:int16 shape:(16, 4) alias_of:a default_addr:128 g_index:2 word_alignment:2 aligned_shape:(16, 4) scale_factor:1.000000>
  | | <_lazy_reshape None dtype:int16 shape:(16, 4) alias_of:a default_addr:128 g_index:2 word_alignment:2 aligned_shape:(16, 4) scale_factor:1.000000>
  | <_lazy_reshape None dtype:int16 shape:(16, 4) alias_of:a default_addr:128 g_index:2 word_alignment:2 aligned_shape:(16, 4) scale_factor:1.000000>
(Stage 3)
  <_lazy_reshape None dtype:int16 shape:(4, 16) alias_of:output_sub_0 default_addr:0 g_index:1 word_alignment:2 aligned_shape:(4, 16) scale_factor:1.000000>
  | <sub output_sub_0 dtype:int16 shape:(16, 4) default_addr:0 g_index:1 word_alignment:2 aligned_shape:(16, 4) scale_factor:1.000000>
[RAM (spec: num)]
  16-bit 512-entry 2-port 2-bank RAM: 4
[Substream (spec: num)]
[Stream (spec: num)]
  (((<class 'nngen.operator.basic._lazy_reshape'>, <dtype int16>), <dtype int16>, 1), True): 1
  ((<class 'nngen.operator.basic.sub'>, ((<class 'nngen.operator.basic.add'>, <dtype int16>, <dtype int16>), <dtype int16>, 1), <dtype int16>), <dtype int16>, 1): 1
[State IDs in main_fsm]
  (3, 4, 'a', 'None')
  (5, 6, None, 'None')
  (12, 14, 'output_sub_0', 'control_sub_3')
  (15, 16, None, 'None')
[Control (name (# states: num))]
  main_fsm (# states: 22)
  control_sub_3 (# states: 59)
[Register Map]
    0 (R ): header0 (default: 0x00000000)
    4 (R ): header1 (default: 0x00000000)
    8 (R ): header2 (default: 0x00000000)
   12 (R ): header3 (default: 0x00000000)
   16 ( W): Start (set '1' to run)
   20 (R ): Busy (returns '1' when running)
   24 ( W): Reset (set '1' to initialize internal logic)
   28 (R ): Opcode from extern objects to SW (returns '0' when idle)
   32 ( W): Resume extern objects (set '1' to resume)
   36 (R ): Interrupt Status Register
   40 ( W): Interrupt Enable Register
   44 ( W): Interrupt Acknowledge Register
   48 (R ): State Counter
   52 ( W): Count Target
   56 ( W): Count Divider
   60 (  ): Reserved ...
  120 (  ): ... Reserved
  124 (R ): Address space amount
  128 (RW): Global address offset (default: 0)
  132 (RW): Address of temporal storages (size: 0B)
  136 (RW): Address of output (sub) 'output_sub_0' (size: 128B, dtype: int16, shape: (16, 4), alignment: 2 words (4 bytes)), aligned shape: (16, 4)
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ we expect the log that "(_lazy_reshape) 'output__lazy_reshape_0' (size: 128B, dtype: int16, shape: (4, 16), alignment: 2 words (4 bytes)), aligned shape: (4, 16)". 
  140 (RW): Address of placeholder 'a' (size: 128B, dtype: int16, shape: (4, 16), alignment: 2 words (4 bytes)), aligned shape: (4, 16)
[Default Memory Map (start - end)] (entire range: [0 - 255], size: 256B)
  [  0 - 127]: output (sub) 'output_sub_0' (size: 128B, dtype: int16, shape: (16, 4), alignment: 2 words (4 bytes)), aligned shape: (16, 4)
  [128 - 255]: placeholder 'a' (size: 128B, dtype: int16, shape: (4, 16), alignment: 2 words (4 bytes)), aligned shape: (4, 16)
# start
# end
# execution cycles:        1721
# verify: PASSED

This seems to work well.

diff --git a/nngen/verilog.py b/nngen/verilog.py
index 034a68e..390149a 100644
--- a/nngen/verilog.py
+++ b/nngen/verilog.py
@@ -500,8 +500,8 @@ def set_storage_name(objs):
             obj.name = 'input_%d' % tmp_input
             tmp_input += 1
         elif obj.is_output and obj.name is None:
-            while bt.is_view(obj) or bt.is_removable_reshape(obj):
-                obj = obj.args[0]
+            #while bt.is_view(obj) or bt.is_removable_reshape(obj):
+            #    obj = obj.args[0]
 
             obj.name = 'output_%s_%d' % (obj.__class__.__name__, tmp_output)
             tmp_output += 1
@@ -1148,6 +1154,7 @@ def make_addr_map(config, objs, saxi):
     for obj in sorted(objs, key=lambda x: x.object_id):
         if obj.is_output and obj.global_index is None:
 
+            org_obj = obj
             while bt.is_view(obj) or bt.is_removable_reshape(obj):
                 obj = obj.args[0]
 
@@ -1165,16 +1172,16 @@ def make_addr_map(config, objs, saxi):
                   "(size: %s, dtype: %s, shape: %s, "
                   "alignment: %d words (%d bytes)), "
                   "aligned shape: %s") %
-                 (obj.__class__.__name__,
-                  "'%s'" % obj.name if obj.name is not None else 'None',
+                 (org_obj.__class__.__name__,
+                  "'%s'" % org_obj.name if org_obj.name is not None else 'None',
                   size_str(space_size),
-                  obj.dtype.to_str() if obj.dtype is not None else 'None',
-                  (str(obj.shape)
-                   if isinstance(obj.shape, (tuple, list)) else '()'),
-                  obj.get_word_alignment(),
-                  bt.to_byte(obj.get_word_alignment() * obj.get_ram_width()),
-                  (str(tuple(obj.get_aligned_shape()))
-                   if isinstance(obj.shape, (tuple, list)) else '()')))
+                  org_obj.dtype.to_str() if org_obj.dtype is not None else 'None',
+                  (str(org_obj.shape)
+                   if isinstance(org_obj.shape, (tuple, list)) else '()'),
+                  org_obj.get_word_alignment(),
+                  bt.to_byte(org_obj.get_word_alignment() * org_obj.get_ram_width()),
+                  (str(tuple(org_obj.get_aligned_shape()))
+                   if isinstance(org_obj.shape, (tuple, list)) else '()')))

then the log is follow

[Schedule Table]
(Stage 0)
(Stage 1)
  <_lazy_reshape None dtype:int16 shape:(16, 4) alias_of:a default_addr:128 g_index:2 word_alignment:2 aligned_shape:(16, 4) scale_factor:1.000000>
  | <placeholder a dtype:int16 shape:(4, 16) default_addr:128 g_index:2 word_alignment:2 aligned_shape:(4, 16) scale_factor:1.000000>
(Stage 2)
  <sub None dtype:int16 shape:(16, 4) default_addr:0 g_index:1 word_alignment:2 aligned_shape:(16, 4) scale_factor:1.000000>
  | <add None dtype:int16 shape:(16, 4) chained default_addr:0 word_alignment:2 aligned_shape:(16, 4) scale_factor:1.000000>
  | | <_lazy_reshape None dtype:int16 shape:(16, 4) alias_of:a default_addr:128 g_index:2 word_alignment:2 aligned_shape:(16, 4) scale_factor:1.000000>
  | | <_lazy_reshape None dtype:int16 shape:(16, 4) alias_of:a default_addr:128 g_index:2 word_alignment:2 aligned_shape:(16, 4) scale_factor:1.000000>
  | <_lazy_reshape None dtype:int16 shape:(16, 4) alias_of:a default_addr:128 g_index:2 word_alignment:2 aligned_shape:(16, 4) scale_factor:1.000000>
(Stage 3)
  <_lazy_reshape output__lazy_reshape_0 dtype:int16 shape:(4, 16) alias_of:<sub> default_addr:0 g_index:1 word_alignment:2 aligned_shape:(4, 16) scale_factor:1.000000>
  | <sub None dtype:int16 shape:(16, 4) default_addr:0 g_index:1 word_alignment:2 aligned_shape:(16, 4) scale_factor:1.000000>
[RAM (spec: num)]
  16-bit 512-entry 2-port 2-bank RAM: 4
[Substream (spec: num)]
[Stream (spec: num)]
  (((<class 'nngen.operator.basic._lazy_reshape'>, <dtype int16>), <dtype int16>, 1), True): 1
  ((<class 'nngen.operator.basic.sub'>, ((<class 'nngen.operator.basic.add'>, <dtype int16>, <dtype int16>), <dtype int16>, 1), <dtype int16>), <dtype int16>, 1): 1
[State IDs in main_fsm]
  (3, 4, 'a', 'None')
  (5, 6, None, 'None')
  (12, 14, None, 'control_sub_3')
  (15, 16, 'output__lazy_reshape_0', 'None')
[Control (name (# states: num))]
  main_fsm (# states: 22)
  control_sub_3 (# states: 59)
[Register Map]
    0 (R ): header0 (default: 0x00000000)
    4 (R ): header1 (default: 0x00000000)
    8 (R ): header2 (default: 0x00000000)
   12 (R ): header3 (default: 0x00000000)
   16 ( W): Start (set '1' to run)
   20 (R ): Busy (returns '1' when running)
   24 ( W): Reset (set '1' to initialize internal logic)
   28 (R ): Opcode from extern objects to SW (returns '0' when idle)
   32 ( W): Resume extern objects (set '1' to resume)
   36 (R ): Interrupt Status Register
   40 ( W): Interrupt Enable Register
   44 ( W): Interrupt Acknowledge Register
   48 (R ): State Counter
   52 ( W): Count Target
   56 ( W): Count Divider
   60 (  ): Reserved ...
  120 (  ): ... Reserved
  124 (R ): Address space amount
  128 (RW): Global address offset (default: 0)
  132 (RW): Address of temporal storages (size: 0B)
  136 (RW): Address of output (_lazy_reshape) 'output__lazy_reshape_0' (size: 128B, dtype: int16, shape: (4, 16), alignment: 2 words (4 bytes)), aligned shape: (4, 16)
  140 (RW): Address of placeholder 'a' (size: 128B, dtype: int16, shape: (4, 16), alignment: 2 words (4 bytes)), aligned shape: (4, 16)
[Default Memory Map (start - end)] (entire range: [0 - 255], size: 256B)
  [  0 - 127]: output (_lazy_reshape) 'output__lazy_reshape_0' (size: 128B, dtype: int16, shape: (4, 16), alignment: 2 words (4 bytes)), aligned shape: (4, 16)
  [128 - 255]: placeholder 'a' (size: 128B, dtype: int16, shape: (4, 16), alignment: 2 words (4 bytes)), aligned shape: (4, 16)
# start
# end
# execution cycles:        1721
# verify: PASSED
@RyusukeYamano RyusukeYamano added the wontfix This will not be worked on label Jul 7, 2021
shtaxxx added a commit that referenced this issue Dec 8, 2022
@shtaxxx
Copy link
Contributor

shtaxxx commented Dec 8, 2022

This issue has been resolved in 32e8d50 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

2 participants