Skip to content

Commit 6be9482

Browse files
committed
Merge branch 'develop' of github.com:PaddlePaddle/GraphNet into develop
2 parents b49edb4 + 6f7b3a7 commit 6be9482

File tree

6,340 files changed

+6599392
-121
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

6,340 files changed

+6599392
-121
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,11 @@ Once you have packaged these extracted computation graphs, submit them to the Gr
9898
<table>
9999
<tr>
100100
<td align="center">
101-
<img width="200" src="https://github.com/user-attachments/assets/eef90a3e-ce83-4757-94ea-b0c0757785f0" />
101+
<img width="200" src="https://github.com/user-attachments/assets/3ea4794b-1aed-4096-bd1c-3184832b98f3" />
102102
</td>
103103
<td align="center">
104104
<img width="150" src="https://cdn.prod.website-files.com/6257adef93867e50d84d30e2/67d00cf7266d2c75571aebde_Example.svg" />
105-
<p><a href="https://discord.gg/43XQ3tf7">Channel</a> is also available.</p>
105+
<p><a href="https://discord.gg/FCZQVCkC">Channel</a> is also available.</p>
106106
</td>
107107
</tr>
108108
</table>

graph_net/paddle/test_compiler.py

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,24 @@ def get_input_spec(args):
7373
inputs_params_list = utils.load_converted_list_from_text(f"{args.model_path}")
7474
input_spec = [None] * len(inputs_params_list)
7575
for i, v in enumerate(inputs_params_list):
76+
name = v["name"]
7677
dtype = v["info"]["dtype"]
7778
shape = v["info"]["shape"]
79+
# print(f"-- i: {i}, v: name={name}, shape={shape}, dtype={dtype}")
7880
input_spec[i] = paddle.static.InputSpec(shape, dtype)
7981
return input_spec
8082

8183

84+
def regular_item(item):
85+
if isinstance(item, paddle.Tensor) and (item.dtype == paddle.bfloat16):
86+
item = np.array(item.astype("float32"))
87+
else:
88+
item = np.array(item)
89+
if item.dtype == np.bool_:
90+
item = item.astype("float32")
91+
return item
92+
93+
8294
def test_single_model(args):
8395
synchronizer_func = get_synchronizer_func(args)
8496
input_dict = get_input_dict(args)
@@ -88,20 +100,18 @@ def test_single_model(args):
88100
build_strategy.build_cinn_pass = False
89101

90102
# eager
91-
model = paddle.jit.to_static(
92-
model_dy,
93-
full_graph=False,
94-
)
95-
model.eval()
103+
print("-- Run with eager mode")
104+
model_dy.eval()
96105
for _ in range(args.warmup if args.warmup > 0 else 0):
97-
model(**input_dict)
106+
model_dy(**input_dict)
98107
eager_duration_box = DurationBox(-1)
99108
with naive_timer(eager_duration_box, synchronizer_func):
100-
expected_out = model(**input_dict)
109+
expected_out = model_dy(**input_dict)
101110

102111
# compiled
112+
print("-- Run with compiled mode")
103113
build_strategy = paddle.static.BuildStrategy()
104-
build_strategy.build_cinn_pass = True
114+
# build_strategy.build_cinn_pass = True
105115
compiled_model = paddle.jit.to_static(
106116
model_dy,
107117
input_spec=input_spec,
@@ -114,8 +124,26 @@ def test_single_model(args):
114124
compiled_duration_box = DurationBox(-1)
115125
with naive_timer(compiled_duration_box, synchronizer_func):
116126
compiled_out = compiled_model(**input_dict)
117-
expected_out = expected_out.numpy()
118-
compiled_out = compiled_out.numpy()
127+
128+
if isinstance(expected_out, paddle.Tensor):
129+
expected_out = [expected_out]
130+
compiled_out = [compiled_out]
131+
if isinstance(expected_out, list) or isinstance(expected_out, tuple):
132+
for a, b in zip(expected_out, compiled_out):
133+
if (a is None and b is not None) or (a is not None and b is None):
134+
raise ValueError("Both expected_out and compiled_out must be not None.")
135+
expected_out = [
136+
regular_item(item)
137+
for item in expected_out
138+
if item is not None and np.array(item).size != 0
139+
]
140+
compiled_out = [
141+
regular_item(item)
142+
for item in compiled_out
143+
if item is not None and np.array(item).size != 0
144+
]
145+
else:
146+
raise ValueError("Illegal return value.")
119147

120148
def print_cmp(key, func, **kwargs):
121149
cmp_ret = func(expected_out, compiled_out, **kwargs)

graph_net/paddle/utils.py

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import argparse
77
import importlib
88
import inspect
9+
import ast
910
import paddle
1011

1112

@@ -115,8 +116,7 @@ def load_converted_list_from_text(file_path):
115116
weight_info = [
116117
data for data in convert_meta_classes_to_tensors(f"{file_path}/weight_meta.py")
117118
]
118-
119-
return [*input_info, *weight_info]
119+
return [*weight_info, *input_info]
120120

121121

122122
def convert_meta_classes_to_tensors(file_path):
@@ -127,13 +127,14 @@ def convert_meta_classes_to_tensors(file_path):
127127
if not k.startswith("__") and not callable(v)
128128
}
129129
data_value = None
130-
data_type = getattr(paddle, attrs.get("dtype", "paddle.float").split(".")[-1])
130+
data_type = getattr(paddle, attrs.get("dtype", "float32"))
131131
if attrs.get("data") is not None:
132132
if isinstance(attrs.get("data"), str):
133133
raise ValueError("Unimplemented")
134134
else:
135-
data_value = paddle.tensor(attrs["data"], dtype=data_type).reshape(
136-
attrs.get("shape"), []
135+
data_value = paddle.reshape(
136+
paddle.to_tensor(attrs.get("data"), dtype=data_type),
137+
attrs.get("shape", []),
137138
)
138139
yield {
139140
"info": {
@@ -142,17 +143,26 @@ def convert_meta_classes_to_tensors(file_path):
142143
"device": attrs.get("device", "gpu"),
143144
"mean": attrs.get("mean", 0.0),
144145
"std": attrs.get("std", 1.0),
146+
"low": attrs.get("low", 0),
147+
"high": attrs.get("high", 2),
145148
},
146149
"data": data_value,
147150
"name": attrs.get("name"),
148151
}
149152

150153

151154
def _get_classes(file_path):
155+
with open(file_path, "r", encoding="utf-8") as f:
156+
tree = ast.parse(f.read(), filename=file_path)
157+
158+
class_names = [node.name for node in tree.body if isinstance(node, ast.ClassDef)]
159+
152160
spec = importlib.util.spec_from_file_location("unnamed", file_path)
153161
unnamed = importlib.util.module_from_spec(spec)
154162
spec.loader.exec_module(unnamed)
155-
yield from inspect.getmembers(unnamed, inspect.isclass)
163+
164+
classes = [(name, getattr(unnamed, name)) for name in class_names]
165+
return classes
156166

157167

158168
def extract_dynamic_shapes(example_inputs):
@@ -163,11 +173,28 @@ def replay_tensor(info):
163173
device = info["info"]["device"]
164174
dtype = info["info"]["dtype"]
165175
shape = info["info"]["shape"]
176+
min_value = info["info"]["low"] if "low" in info["info"] else 0
177+
max_value = info["info"]["high"] if "high" in info["info"] else 0.5
166178
if None in shape:
167179
shape = list(map(lambda i: i if i is not None else 1, shape))
168-
mean = info["info"]["mean"]
169-
std = info["info"]["std"]
170180
if "data" in info and info["data"] is not None:
171-
return info["data"].to(device)
172-
173-
return paddle.randn(shape).to(dtype).to(device) * std * 1e-3 + 1e-2
181+
return paddle.reshape(info["data"], shape).to(dtype).to(device)
182+
elif dtype == paddle.int32 or dtype == paddle.int64:
183+
return paddle.cast(
184+
paddle.randint(
185+
low=min_value, high=max_value + 1, shape=shape, dtype="int64"
186+
),
187+
dtype,
188+
).to(device)
189+
elif dtype == paddle.bool:
190+
return paddle.cast(
191+
paddle.randint(low=0, high=2, shape=shape, dtype="int32"),
192+
paddle.bool,
193+
).to(device)
194+
else:
195+
std = info["info"]["std"]
196+
return (
197+
paddle.uniform(shape, dtype="float32", min=min_value, max=max_value)
198+
.to(dtype)
199+
.to(device)
200+
)

graph_net/paddle/validate.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import graph_net
1313
import os
1414
import re
15+
import paddle
1516

1617

1718
def load_class_from_file(file_path: str, class_name: str):
@@ -65,10 +66,15 @@ def main(args):
6566
params.update(inputs)
6667
state_dict = {k: utils.replay_tensor(v) for k, v in params.items()}
6768

68-
y = model(**state_dict)[0]
69+
y = model(**state_dict)
6970

70-
print(np.argmin(y), np.argmax(y))
71-
print(y.shape)
71+
# print(np.argmin(y), np.argmax(y))
72+
if isinstance(y, paddle.Tensor):
73+
print(y.shape)
74+
elif isinstance(y, list) or isinstance(y, tuple):
75+
print(y[0].shape if isinstance(y[0], paddle.Tensor) else y[0])
76+
else:
77+
raise ValueError("Illegal return value.")
7278

7379
if not args.no_check_redundancy:
7480
print("Check redundancy ...")
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import unittest
2+
from graph_net.torch.rp_expr import Tokenize
3+
from graph_net.torch.rp_expr.rp_expr_passes import (
4+
FlattenTokenListPass,
5+
FoldTokensPass,
6+
RecursiveFoldTokensPass,
7+
FoldIfTokenIdGreatEqualPass,
8+
)
9+
from graph_net.torch.rp_expr.nested_range import Range, Tree
10+
from graph_net.torch.rp_expr.rp_expr_parser import RpExprParser
11+
from graph_net.torch.rp_expr.rp_expr_util import (
12+
MakeNestedIndexRangeFromLetsListTokenRpExpr,
13+
)
14+
15+
16+
class TestTokenize(unittest.TestCase):
17+
"""Tests tokenization of primitive ID lists into symbolic token sequences."""
18+
19+
def test_simple(self):
20+
primitive_id_lists = [list(range(10 + i)) for i in range(5)]
21+
token_list, id_allocator, _ = Tokenize(primitive_id_lists)
22+
self.assertEqual(len(token_list.tensors), len(primitive_id_lists))
23+
24+
25+
class TestFlattenTokenListPass(unittest.TestCase):
26+
"""Tests flattening of nested token structures into linear sequences."""
27+
28+
def test_simple(self):
29+
base = 10
30+
size = 5
31+
primitive_id_lists = [list(range(base + i)) for i in range(size)]
32+
token_list, id_allocator, _ = Tokenize(primitive_id_lists)
33+
rp_expr_pass = FlattenTokenListPass(id_allocator)
34+
success, flattened_rp_expr_pass = rp_expr_pass(token_list)
35+
self.assertTrue(success)
36+
self.assertEqual(id_allocator.NextTokenId(), base + 2 * size - 1)
37+
38+
39+
class TestFoldTokensPass(unittest.TestCase):
40+
"""Tests folding of the most frequent contiguous token pattern into a single symbol."""
41+
42+
def test_simple(self):
43+
base = 3
44+
size = 3
45+
primitive_id_lists = [list(range(base + i)) for i in range(size)]
46+
token_list, id_allocator, _ = Tokenize(primitive_id_lists)
47+
flatten_pass = FlattenTokenListPass(id_allocator)
48+
_, flattened_rp_expr = flatten_pass(token_list)
49+
fold_pass = FoldTokensPass(id_allocator)
50+
success, fold_rp_expr = fold_pass(flattened_rp_expr.flattened_tensor)
51+
self.assertTrue(success)
52+
input = flattened_rp_expr.flattened_tensor.tensor.numpy().tolist()
53+
pattern = fold_rp_expr.symbol_token_tensors[0].numpy().tolist()
54+
replacement = fold_rp_expr.symbol_token_ids[0]
55+
output = fold_rp_expr.body_rp_expr.tensor.numpy().tolist()
56+
self.assertEqual(input, [3, 4, 5, 1, 3, 4, 5, 6, 2, 3, 4, 5, 6, 7])
57+
self.assertEqual(pattern, [3, 4, 5])
58+
self.assertEqual(replacement, 8)
59+
self.assertEqual(output, [8, 1, 8, 6, 2, 8, 6, 7])
60+
61+
62+
class TestRecursiveFoldTokensPass(unittest.TestCase):
63+
"""Tests recursive folding of repeated patterns at multiple levels of nesting."""
64+
65+
def test_simple(self):
66+
base = 3
67+
size = 3
68+
primitive_id_lists = [list(range(base + i)) for i in range(size)]
69+
token_list, id_allocator, _ = Tokenize(primitive_id_lists)
70+
flatten_pass = FlattenTokenListPass(id_allocator)
71+
_, flattened_rp_expr = flatten_pass(token_list)
72+
fold_pass = RecursiveFoldTokensPass(id_allocator)
73+
success, fold_rp_expr = fold_pass(flattened_rp_expr.flattened_tensor)
74+
self.assertTrue(success)
75+
input = flattened_rp_expr.flattened_tensor.tensor.numpy().tolist()
76+
pattern = [x.numpy().tolist() for x in fold_rp_expr.symbol_token_tensors]
77+
replacement = fold_rp_expr.symbol_token_ids
78+
output = fold_rp_expr.body_rp_expr.tensor.numpy().tolist()
79+
self.assertEqual(input, [3, 4, 5, 1, 3, 4, 5, 6, 2, 3, 4, 5, 6, 7])
80+
self.assertEqual(pattern, [[3, 4, 5], [8, 6]])
81+
self.assertEqual(replacement, [8, 9])
82+
self.assertEqual(output, [8, 1, 9, 2, 9, 7])
83+
84+
85+
class TestFoldIfTokenIdGreatEqualPass(unittest.TestCase):
86+
"""Tests conditional folding only for tokens with ID greater than or equal to a threshold."""
87+
88+
def test_simple(self):
89+
base = 3
90+
size = 3
91+
primitive_id_lists = [list(range(base + i)) for i in range(size)]
92+
token_list, id_allocator, _ = Tokenize(primitive_id_lists)
93+
flatten_pass = FlattenTokenListPass(id_allocator)
94+
_, flattened_rp_expr = flatten_pass(token_list)
95+
fold_pass = RecursiveFoldTokensPass(id_allocator)
96+
success, fold_rp_expr = fold_pass(flattened_rp_expr.flattened_tensor)
97+
self.assertTrue(success)
98+
threshold_fold_pass = FoldIfTokenIdGreatEqualPass(
99+
id_allocator=id_allocator,
100+
threshold_start_token_id=len(primitive_id_lists),
101+
)
102+
success, threshold_fold_rp_expr = threshold_fold_pass(fold_rp_expr.body_rp_expr)
103+
self.assertTrue(success)
104+
input = fold_rp_expr.body_rp_expr.tensor.numpy().tolist()
105+
pattern = [
106+
x.numpy().tolist() for x in threshold_fold_rp_expr.symbol_token_tensors
107+
]
108+
replacement = threshold_fold_rp_expr.symbol_token_ids
109+
self.assertEqual(len(threshold_fold_rp_expr.body_rp_expr), 3)
110+
output = [x.numpy().tolist() for x in threshold_fold_rp_expr.body_rp_expr]
111+
self.assertEqual(input, [8, 1, 9, 2, 9, 7])
112+
self.assertEqual(pattern, [[9, 7]])
113+
self.assertEqual(replacement, [10])
114+
self.assertEqual(output, [[8], [9], [10]])
115+
116+
117+
if __name__ == "__main__":
118+
unittest.main()
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from .rp_expr import Tokenize
2+
from .rp_expr_parser import RpExprParser
3+
from .nested_range import Range, Tree
4+
from .rp_expr_util import MakeNestedIndexRangeFromLetsListTokenRpExpr
5+
from .rp_expr_passes import (
6+
FlattenTokenListPass,
7+
FoldTokensPass,
8+
RecursiveFoldTokensPass,
9+
FoldIfTokenIdGreatEqualPass,
10+
)
11+
12+
__all__ = [
13+
"Tokenize",
14+
"RpExprParser",
15+
"Range",
16+
"Tree",
17+
"MakeNestedIndexRangeFromLetsListTokenRpExpr",
18+
"FlattenTokenListPass",
19+
"FoldTokensPass",
20+
"RecursiveFoldTokensPass",
21+
"FoldIfTokenIdGreatEqualPass",
22+
]

0 commit comments

Comments
 (0)