Skip to content

Commit 1e976e2

Browse files
authored
[INTEL_HPU] moved UT test index copy into UT test folder and added HPU index selected (#1632)
Signed-off-by: Luo, Focus <[email protected]>
1 parent e6e31bd commit 1e976e2

File tree

2 files changed

+212
-1
lines changed

2 files changed

+212
-1
lines changed
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# Copyright (c) 2024 PaddlePaddle Authors. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import unittest
16+
17+
import numpy as np
18+
import torch
19+
import paddle
20+
import paddlenlp_ops
21+
22+
from tests.op_test import skip_check_grad_ci
23+
24+
import os
25+
26+
intel_hpus_module_id = os.environ.get("FLAGS_selected_intel_hpus", 0)
27+
28+
29+
def index_copy_torch(input, dim, index, source, dtype):
30+
dtype_map = {
31+
"float16": torch.float16,
32+
"float32": torch.float32,
33+
"float64": torch.float64,
34+
"int32": torch.int32,
35+
}
36+
torch_dtype = dtype_map[dtype]
37+
input_tensor = torch.tensor(input).clone().detach().to(dtype=torch_dtype)
38+
index_tensor = torch.tensor(index).clone().detach().to(dtype=torch.int64)
39+
source_tensor = torch.tensor(source).clone().detach().to(dtype=torch_dtype)
40+
output = torch.index_copy(
41+
input=input_tensor, dim=dim, index=index_tensor, source=source_tensor
42+
)
43+
return output
44+
45+
46+
@skip_check_grad_ci(reason="index_copy_forward ops not support gradient calculation.")
47+
class TestIndexCopyOpFP32(unittest.TestCase):
48+
def setUp(self):
49+
self.place = paddle.CustomPlace("intel_hpu", int(intel_hpus_module_id))
50+
self.init_dtype()
51+
self.batch_size = 16
52+
self.num_heads = 32
53+
self.seq_length = 256
54+
self.head_dim = 64
55+
56+
def init_dtype(self):
57+
self.dtype = "float32"
58+
59+
def check_result(self, torch_res, ops_res):
60+
if self.dtype == "float32":
61+
rtol = 1e-5
62+
atol = 1e-6
63+
elif self.dtype == "float16":
64+
rtol = 1e-3
65+
atol = 1e-4
66+
elif self.dtype == "bfloat16":
67+
rtol = 1e-2
68+
atol = 1e-3
69+
else:
70+
self.assertTrue(
71+
False,
72+
msg="index_copy input dtype only supports bfloat16, \
73+
float16 and float32, but got "
74+
+ self.dtype,
75+
)
76+
np.testing.assert_allclose(torch_res, ops_res, rtol=rtol, atol=atol)
77+
78+
def index_copy_custom(self, input, dim, index, source):
79+
input_tensor = paddle.to_tensor(input, dtype=self.dtype).clone()
80+
index_tensor = paddle.to_tensor(index, dtype="int64").clone()
81+
source_tensor = paddle.to_tensor(source, dtype=self.dtype).clone()
82+
paddlenlp_ops.index_copy_(
83+
input=input_tensor, dim=dim, index=index_tensor, source=source_tensor
84+
)
85+
return input_tensor
86+
87+
def prepare_input(
88+
self, batch_size=16, num_heads=32, seq_length=256, head_dim=64, dim=0, index=0
89+
):
90+
self.batch_size = batch_size
91+
self.num_heads = num_heads
92+
self.seq_length = seq_length
93+
self.head_dim = head_dim
94+
95+
input = np.full(
96+
(num_heads, head_dim, seq_length, batch_size), -1, dtype=self.dtype
97+
)
98+
index = [index]
99+
if dim == 0:
100+
source = np.full(
101+
(len(index), head_dim, seq_length, batch_size), 0, dtype=self.dtype
102+
)
103+
elif dim == 1:
104+
source = np.full(
105+
(num_heads, len(index), seq_length, batch_size), 0, dtype=self.dtype
106+
)
107+
elif dim == 2:
108+
source = np.full(
109+
(num_heads, head_dim, len(index), batch_size), 0, dtype=self.dtype
110+
)
111+
elif dim == 3:
112+
source = np.full(
113+
(num_heads, head_dim, seq_length, len(index)), 0, dtype=self.dtype
114+
)
115+
else:
116+
raise ValueError(
117+
"Unsupported dimension. Only dim=0, dim=1 and dim=2 are supported."
118+
)
119+
return input, index, source, dim
120+
121+
def test_index_copy_dim0_index0(self):
122+
input, index, source, dim = self.prepare_input(dim=0, index=0)
123+
custom_res = self.index_copy_custom(input, dim, index, source)
124+
torch_res = index_copy_torch(input, dim, index, source, dtype=self.dtype)
125+
self.check_result(torch_res.numpy(), custom_res)
126+
127+
def test_index_copy_dim0_index1(self):
128+
input, index, source, dim = self.prepare_input(dim=0, index=1)
129+
custom_res = self.index_copy_custom(input, dim, index, source)
130+
torch_res = index_copy_torch(input, dim, index, source, dtype=self.dtype)
131+
self.check_result(torch_res.numpy(), custom_res)
132+
133+
def test_index_copy_dim0_index_max(self):
134+
index = max(self.num_heads - 1, 0)
135+
input, index, source, dim = self.prepare_input(dim=0, index=index)
136+
custom_res = self.index_copy_custom(input, dim, index, source)
137+
torch_res = index_copy_torch(input, dim, index, source, dtype=self.dtype)
138+
self.check_result(torch_res.numpy(), custom_res)
139+
140+
def test_index_copy_dim1_index0(self):
141+
input, index, source, dim = self.prepare_input(dim=1, index=0)
142+
custom_res = self.index_copy_custom(input, dim, index, source)
143+
torch_res = index_copy_torch(input, dim, index, source, dtype=self.dtype)
144+
self.check_result(torch_res.numpy(), custom_res)
145+
146+
def test_index_copy_dim1_index1(self):
147+
input, index, source, dim = self.prepare_input(dim=1, index=1)
148+
custom_res = self.index_copy_custom(input, dim, index, source)
149+
torch_res = index_copy_torch(input, dim, index, source, dtype=self.dtype)
150+
self.check_result(torch_res.numpy(), custom_res.numpy())
151+
152+
def test_index_copy_dim1_index_max(self):
153+
index = max(self.head_dim - 1, 0)
154+
input, index, source, dim = self.prepare_input(dim=1, index=index)
155+
custom_res = self.index_copy_custom(input, dim, index, source)
156+
torch_res = index_copy_torch(input, dim, index, source, dtype=self.dtype)
157+
self.check_result(torch_res.numpy(), custom_res.numpy())
158+
159+
def test_index_copy_dim2_index0(self):
160+
input, index, source, dim = self.prepare_input(dim=2, index=0)
161+
custom_res = self.index_copy_custom(input, dim, index, source)
162+
torch_res = index_copy_torch(input, dim, index, source, dtype=self.dtype)
163+
self.check_result(torch_res.numpy(), custom_res.numpy())
164+
165+
def test_index_copy_dim2_index1(self):
166+
input, index, source, dim = self.prepare_input(dim=2, index=1)
167+
custom_res = self.index_copy_custom(input, dim, index, source)
168+
torch_res = index_copy_torch(input, dim, index, source, dtype=self.dtype)
169+
self.check_result(torch_res.numpy(), custom_res.numpy())
170+
171+
def test_index_copy_dim2_index_max(self):
172+
index = max(self.seq_length - 1, 0)
173+
input, index, source, dim = self.prepare_input(dim=2, index=index)
174+
custom_res = self.index_copy_custom(input, dim, index, source)
175+
torch_res = index_copy_torch(input, dim, index, source, dtype=self.dtype)
176+
self.check_result(torch_res.numpy(), custom_res.numpy())
177+
178+
def test_index_copy_dim3_index0(self):
179+
input, index, source, dim = self.prepare_input(dim=3, index=0)
180+
custom_res = self.index_copy_custom(input, dim, index, source)
181+
torch_res = index_copy_torch(input, dim, index, source, dtype=self.dtype)
182+
self.check_result(torch_res.numpy(), custom_res.numpy())
183+
184+
def test_index_copy_dim3_index1(self):
185+
input, index, source, dim = self.prepare_input(dim=3, index=1)
186+
custom_res = self.index_copy_custom(input, dim, index, source)
187+
torch_res = index_copy_torch(input, dim, index, source, dtype=self.dtype)
188+
self.check_result(torch_res.numpy(), custom_res.numpy())
189+
190+
def test_index_copy_dim3_index_max(self):
191+
index = max(self.batch_size - 1, 0)
192+
input, index, source, dim = self.prepare_input(dim=3, index=index)
193+
custom_res = self.index_copy_custom(input, dim, index, source)
194+
torch_res = index_copy_torch(input, dim, index, source, dtype=self.dtype)
195+
self.check_result(torch_res.numpy(), custom_res.numpy())
196+
197+
198+
@skip_check_grad_ci(reason="index_copy_forward ops not support gradient calculation.")
199+
class TestIndexCopyOpFP16(TestIndexCopyOpFP32):
200+
def init_dtype(self):
201+
self.dtype = "float16"
202+
203+
204+
if __name__ == "__main__":
205+
unittest.main()

backends/intel_hpu/tests/unittests/test_index_put_op.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
import paddle
2222
import paddle.base as base
2323

24+
import os
25+
26+
intel_hpus_module_id = os.environ.get("FLAGS_selected_intel_hpus", 0)
27+
2428

2529
class TestIndexPut(unittest.TestCase):
2630
def setUp(self):
@@ -57,7 +61,9 @@ def test_dygraph(self):
5761
index = [paddle.to_tensor([1, 1]), paddle.to_tensor([3, 4])]
5862
index_np = np.array([[1, 1], [3, 4]])
5963

60-
paddle.disable_static(paddle.CustomPlace("intel_hpu", 0))
64+
paddle.disable_static(
65+
paddle.CustomPlace("intel_hpu", int(intel_hpus_module_id))
66+
)
6167
with base.dygraph.guard():
6268
input_np = convert_float_to_uint16(
6369
np.random.random(self.shape).astype(self.dtype)

0 commit comments

Comments
 (0)