1+ from opto import trace
2+ from copy import deepcopy , copy
3+
4+ @trace .model
5+ class Model :
6+
7+ @trace .bundle (trainable = True )
8+ def forward (self , x ):
9+ return x + 1
10+
11+
12+ def test_case_two_models ():
13+ m1 = Model ()
14+ m2 = Model ()
15+
16+ # Make sure the parameters are different
17+ try :
18+ assert m1 .__TRACE_RESERVED_self_node is not m2 .__TRACE_RESERVED_self_node
19+ except AttributeError :
20+ # These secrets attributes are not defined yet. They will only be defined after the bundled method is accessed.
21+ pass
22+
23+ # The hidden nodes are defined now
24+ assert len (m1 .parameters ()) == 1
25+ assert len (m2 .parameters ()) == 1
26+
27+ # Make sure the parameters are different
28+ assert m1 .__TRACE_RESERVED_self_node is not m2 .__TRACE_RESERVED_self_node # they are defined now
29+ assert m1 .parameters ()[0 ] is not m2 .parameters ()[0 ]
30+
31+ # check that the reserved node is the returned parameter
32+ assert getattr (m1 , '__TRACE_RESERVED_bundle_Model.forward' ).parameter is m1 .parameters ()[0 ]
33+ assert getattr (m2 , '__TRACE_RESERVED_bundle_Model.forward' ).parameter is m2 .parameters ()[0 ]
34+
35+ # each instance has a version different from the class' version
36+ assert m1 .forward != m2 .forward
37+ assert m1 .forward != Model .forward
38+ assert m2 .forward .parameter == Model .forward .parameter == m1 .forward .parameter
39+
40+ y1 = m1 .forward (1 )
41+ y2 = m1 .forward (2 )
42+
43+ from opto .trace .utils import contain
44+ # self is not duplicated
45+ assert contain (y1 .parents , m1 .__TRACE_RESERVED_self_node )
46+ assert contain (y2 .parents , m1 .__TRACE_RESERVED_self_node )
47+ # assert m1.__TRACE_RESERVED_self_node in y1.parents
48+ # assert m1.__TRACE_RESERVED_self_node in y2.parents
49+ assert contain (y1 .parents , m1 .forward .parameter )
50+ assert contain (y2 .parents , m1 .forward .parameter )
51+ # assert m1.forward.parameter in y1.parents
52+ # assert m1.forward.parameter in y2.parents
53+ assert len (y1 .parents ) == 3 # since it's trainable
54+ assert len (y2 .parents ) == 3
55+
56+ def test_case_model_copy ():
57+ m1 = Model ()
58+ m2 = deepcopy (m1 )
59+
60+ # Make sure the parameters are different
61+ try :
62+ assert m1 .__TRACE_RESERVED_self_node is not m2 .__TRACE_RESERVED_self_node
63+ except AttributeError :
64+ # These secrets attributes are not defined yet. They will only be defined after the bundled method is accessed.
65+ pass
66+
67+ # The hidden nodes are defined now
68+ assert len (m1 .parameters ()) == 1
69+ assert len (m2 .parameters ()) == 1
70+
71+ # Make sure the parameters are different
72+ assert m1 .__TRACE_RESERVED_self_node is not m2 .__TRACE_RESERVED_self_node # they are defined now
73+ assert m1 .parameters ()[0 ] is not m2 .parameters ()[0 ]
74+
75+ # check that the reserved node is the returned parameter
76+ assert getattr (m1 , '__TRACE_RESERVED_bundle_Model.forward' ).parameter is m1 .parameters ()[0 ]
77+ assert getattr (m2 , '__TRACE_RESERVED_bundle_Model.forward' ).parameter is m2 .parameters ()[0 ]
78+
79+ # each instance has a version different from the class' version
80+ assert m1 .forward is not m2 .forward
81+ assert m1 .forward is not Model .forward
82+ assert m2 .forward .parameter == Model .forward .parameter == m1 .forward .parameter
83+
84+ y1 = m1 .forward (1 )
85+ y2 = m2 .forward (2 )
86+
87+ from opto .trace .utils import contain
88+ # self is not duplicated
89+ assert contain (y1 .parents , m1 .__TRACE_RESERVED_self_node )
90+ assert contain (y2 .parents , m2 .__TRACE_RESERVED_self_node )
91+ # assert m1.__TRACE_RESERVED_self_node in y1.parents
92+ # assert m1.__TRACE_RESERVED_self_node in y2.parents
93+ assert contain (y1 .parents , m1 .forward .parameter )
94+ assert contain (y2 .parents , m2 .forward .parameter )
95+
96+ # assert m1.forward.parameter in y1.parents
97+ # assert m1.forward.parameter in y2.parents
98+ assert len (y1 .parents ) == 3 # since it's trainable
99+ assert len (y2 .parents ) == 3
100+
101+ def test_case_model_nested_copy ():
102+ m1 = Model ()
103+ m3 = deepcopy (m1 )
104+ m2 = deepcopy (m3 )
105+
106+ # Make sure the parameters are different
107+ try :
108+ assert m1 .__TRACE_RESERVED_self_node is not m2 .__TRACE_RESERVED_self_node
109+ except AttributeError :
110+ # These secrets attributes are not defined yet. They will only be defined after the bundled method is accessed.
111+ pass
112+
113+ # The hidden nodes are defined now
114+ assert len (m1 .parameters ()) == 1
115+ assert len (m2 .parameters ()) == 1
116+
117+ # Make sure the parameters are different
118+ assert m1 .__TRACE_RESERVED_self_node is not m2 .__TRACE_RESERVED_self_node # they are defined now
119+ assert m1 .parameters ()[0 ] is not m2 .parameters ()[0 ]
120+
121+ # check that the reserved node is the returned parameter
122+ assert getattr (m1 , '__TRACE_RESERVED_bundle_Model.forward' ).parameter is m1 .parameters ()[0 ]
123+ assert getattr (m2 , '__TRACE_RESERVED_bundle_Model.forward' ).parameter is m2 .parameters ()[0 ]
124+
125+ # each instance has a version different from the class' version
126+ assert m1 .forward is not m2 .forward
127+ assert m1 .forward is not Model .forward
128+ assert m2 .forward .parameter == Model .forward .parameter == m1 .forward .parameter
129+
130+ y1 = m1 .forward (1 )
131+ y2 = m2 .forward (2 )
132+
133+ from opto .trace .utils import contain
134+ # self is not duplicated
135+ assert contain (y1 .parents , m1 .__TRACE_RESERVED_self_node )
136+ assert contain (y2 .parents , m2 .__TRACE_RESERVED_self_node )
137+ # assert m1.__TRACE_RESERVED_self_node in y1.parents
138+ # assert m1.__TRACE_RESERVED_self_node in y2.parents
139+ assert contain (y1 .parents , m1 .forward .parameter )
140+ assert contain (y2 .parents , m2 .forward .parameter )
141+
142+ # assert m1.forward.parameter in y1.parents
143+ # assert m1.forward.parameter in y2.parents
144+ assert len (y1 .parents ) == 3 # since it's trainable
145+ assert len (y2 .parents ) == 3
146+
147+ test_case_two_models ()
148+ test_case_model_copy ()
149+ test_case_model_nested_copy ()
0 commit comments