项目文件夹

文件
2026-07-13 12:40:42 +08:00

1013 行
36 KiB
Python

此文件含有不可见的 Unicode 字符
此文件含有人类无法区分的不可见的 Unicode 字符,但可以由计算机进行不同的处理。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.w
import sys
import unittest
import numpy as np
import paddle
sys.path.append("..")
from op_test import OpTest, get_device_place, get_places
from paddle import base
# 2D normal case
class TestSolveOp(OpTest):
def config(self):
self.python_api = paddle.linalg.solve
self.input_x_matrix_shape = [15, 15]
self.input_y_matrix_shape = [15, 10]
self.dtype = "float64"
def setUp(self):
paddle.enable_static()
self.config()
self.op_type = "solve"
np.random.seed(2021)
self.inputs = {
'X': np.random.random(self.input_x_matrix_shape).astype(self.dtype),
'Y': np.random.random(self.input_y_matrix_shape).astype(self.dtype),
}
self.outputs = {
'Out': np.linalg.solve(self.inputs['X'], self.inputs['Y'])
}
def test_check_output(self):
self.check_output(check_pir=True)
def test_check_grad_normal(self):
self.check_grad(['X', 'Y'], 'Out', check_pir=True)
# x broadcast + 3D batch case
class TestSolveOpBatched_case0(OpTest):
def setUp(self):
self.python_api = paddle.linalg.solve
self.op_type = "solve"
self.dtype = "float64"
np.random.seed(2021)
self.inputs = {
'X': np.random.random((11, 11)).astype(self.dtype),
'Y': np.random.random((2, 11, 7)).astype(self.dtype),
}
result = np.linalg.solve(self.inputs['X'], self.inputs['Y'])
self.outputs = {'Out': result}
def test_check_output(self):
self.check_output(check_pir=True)
def test_check_grad_normal(self):
self.check_grad(
['X', 'Y'], 'Out', max_relative_error=1e-1, check_pir=True
)
# 3D batch + y vector case
class TestSolveOpBatched_case1(OpTest):
def setUp(self):
self.python_api = paddle.linalg.solve
self.op_type = "solve"
self.dtype = "float64"
np.random.seed(2021)
self.inputs = {
'X': np.random.random((20, 6, 6)).astype(self.dtype),
'Y': np.random.random((20, 6)).astype(self.dtype),
}
result = np.empty_like(self.inputs['Y'])
for i in range(self.inputs['X'].shape[0]):
result[i] = np.linalg.solve(
self.inputs['X'][i], self.inputs['Y'][i]
)
self.outputs = {'Out': result}
def test_check_output(self):
self.check_output(check_pir=True)
def test_check_grad_normal(self):
self.check_grad(
['X', 'Y'], 'Out', max_relative_error=0.04, check_pir=True
)
# 3D batch + y broadcast case
class TestSolveOpBatched_case2(OpTest):
def setUp(self):
self.python_api = paddle.linalg.solve
self.op_type = "solve"
self.dtype = "float64"
np.random.seed(2021)
self.inputs = {
'X': np.random.random((2, 10, 10)).astype(self.dtype),
'Y': np.random.random((1, 10, 10)).astype(self.dtype),
}
result = np.linalg.solve(self.inputs['X'], self.inputs['Y'])
self.outputs = {'Out': result}
def test_check_output(self):
self.check_output(check_pir=True)
def test_check_grad_normal(self):
self.check_grad(
['X', 'Y'], 'Out', max_relative_error=0.02, check_pir=True
)
# x broadcast + 3D batch case
class TestSolveOpBatched_case3(OpTest):
def setUp(self):
self.python_api = paddle.linalg.solve
self.op_type = "solve"
self.dtype = "float64"
np.random.seed(2021)
self.inputs = {
'X': np.random.random((1, 10, 10)).astype(self.dtype),
'Y': np.random.random((2, 10, 10)).astype(self.dtype),
}
result = np.linalg.solve(self.inputs['X'], self.inputs['Y'])
self.outputs = {'Out': result}
def test_check_output(self):
self.check_output(check_pir=True)
def test_check_grad_normal(self):
self.check_grad(
['X', 'Y'], 'Out', max_relative_error=0.02, check_pir=True
)
# 3D normal batch case
class TestSolveOpBatched_case4(OpTest):
def setUp(self):
self.python_api = paddle.linalg.solve
self.op_type = "solve"
self.dtype = "float64"
np.random.seed(2021)
self.inputs = {
'X': np.random.random((3, 6, 6)).astype(self.dtype),
'Y': np.random.random((3, 6, 7)).astype(self.dtype),
}
result = np.linalg.solve(self.inputs['X'], self.inputs['Y'])
self.outputs = {'Out': result}
def test_check_output(self):
self.check_output(check_pir=True)
def test_check_grad_normal(self):
self.check_grad(['X', 'Y'], 'Out', check_pir=True)
# 4D normal batch case
class TestSolveOpBatched_case5(OpTest):
def setUp(self):
self.python_api = paddle.linalg.solve
self.op_type = "solve"
self.dtype = "float64"
np.random.seed(2021)
self.inputs = {
'X': np.random.random((2, 2, 6, 6)).astype(self.dtype),
'Y': np.random.random((2, 2, 6, 6)).astype(self.dtype),
}
result = np.linalg.solve(self.inputs['X'], self.inputs['Y'])
self.outputs = {'Out': result}
def test_check_output(self):
self.check_output(check_pir=True)
def test_check_grad_normal(self):
self.check_grad(['X', 'Y'], 'Out', check_pir=True)
# 4D batch + y broadcast case
class TestSolveOpBatched_case6(OpTest):
def setUp(self):
self.python_api = paddle.linalg.solve
self.op_type = "solve"
self.dtype = "float64"
np.random.seed(2021)
self.inputs = {
'X': np.random.random((2, 2, 6, 6)).astype(self.dtype),
'Y': np.random.random((1, 2, 6, 9)).astype(self.dtype),
}
result = np.linalg.solve(self.inputs['X'], self.inputs['Y'])
self.outputs = {'Out': result}
def test_check_output(self):
self.check_output(check_pir=True)
def test_check_grad_normal(self):
self.check_grad(['X', 'Y'], 'Out', check_pir=True)
# 5D normal batch case
class TestSolveOpBatched_case7(OpTest):
def setUp(self):
self.python_api = paddle.linalg.solve
self.op_type = "solve"
self.dtype = "float64"
np.random.seed(2021)
self.inputs = {
'X': np.random.random((2, 2, 2, 4, 4)).astype(self.dtype),
'Y': np.random.random((2, 2, 2, 4, 4)).astype(self.dtype),
}
result = np.linalg.solve(self.inputs['X'], self.inputs['Y'])
self.outputs = {'Out': result}
def test_check_output(self):
self.check_output(check_pir=True)
def test_check_grad_normal(self):
self.check_grad(
['X', 'Y'], 'Out', max_relative_error=0.04, check_pir=True
)
# 5D batch + y broadcast case
class TestSolveOpBatched_case8(OpTest):
def setUp(self):
self.python_api = paddle.linalg.solve
self.op_type = "solve"
self.dtype = "float64"
np.random.seed(2021)
self.inputs = {
'X': np.random.random((2, 2, 2, 4, 4)).astype(self.dtype),
'Y': np.random.random((1, 2, 2, 4, 7)).astype(self.dtype),
}
result = np.linalg.solve(self.inputs['X'], self.inputs['Y'])
self.outputs = {'Out': result}
def test_check_output(self):
self.check_output(check_pir=True)
def test_check_grad_normal(self):
self.check_grad(
['X', 'Y'], 'Out', max_relative_error=0.04, check_pir=True
)
class TestSolveOpError(unittest.TestCase):
def test_errors(self):
with paddle.static.program_guard(
paddle.static.Program(), paddle.static.Program()
):
# The input type of solve_op must be Variable.
x1 = base.create_lod_tensor(
np.array([[-1]]), [[1]], base.CPUPlace()
)
y1 = base.create_lod_tensor(
np.array([[-1]]), [[1]], base.CPUPlace()
)
self.assertRaises(TypeError, paddle.linalg.solve, x1, y1)
# The data type of input must be float32 or float64.
x2 = paddle.static.data(name="x2", shape=[30, 30], dtype="bool")
y2 = paddle.static.data(name="y2", shape=[30, 10], dtype="bool")
self.assertRaises(TypeError, paddle.linalg.solve, x2, y2)
x3 = paddle.static.data(name="x3", shape=[30, 30], dtype="int32")
y3 = paddle.static.data(name="y3", shape=[30, 10], dtype="int32")
self.assertRaises(TypeError, paddle.linalg.solve, x3, y3)
x4 = paddle.static.data(name="x4", shape=[30, 30], dtype="int64")
y4 = paddle.static.data(name="y4", shape=[30, 10], dtype="int64")
self.assertRaises(TypeError, paddle.linalg.solve, x4, y4)
x5 = paddle.static.data(name="x5", shape=[30, 30], dtype="float16")
y5 = paddle.static.data(name="y5", shape=[30, 10], dtype="float16")
self.assertRaises(TypeError, paddle.linalg.solve, x5, y5)
# The number of dimensions of input'X must be >= 2.
x6 = paddle.static.data(name="x6", shape=[30], dtype="float64")
y6 = paddle.static.data(name="y6", shape=[30], dtype="float64")
self.assertRaises(ValueError, paddle.linalg.solve, x6, y6)
# The inner-most 2 dimensions of input'X should be equal to each other
x7 = paddle.static.data(name="x7", shape=[2, 3, 4], dtype="float64")
y7 = paddle.static.data(name="y7", shape=[2, 4, 3], dtype="float64")
self.assertRaises(ValueError, paddle.linalg.solve, x7, y7)
# The shape of y should not be 1 when left = False. (if y is vector it should be a row vector)
x8 = paddle.static.data(name="x8", shape=[3, 3], dtype="float64")
y8 = paddle.static.data(name="y8", shape=[3], dtype="float64")
self.assertRaises(ValueError, paddle.linalg.solve, x8, y8, False)
# The height of x should equal the width of y when left = False.
x9 = paddle.static.data(name="x9", shape=[2, 5, 5], dtype="float64")
y9 = paddle.static.data(name="y9", shape=[5, 3], dtype="float64")
self.assertRaises(ValueError, paddle.linalg.solve, x9, y9, False)
# 2D + vector case, FP64
class TestSolveOpAPI_1(unittest.TestCase):
def setUp(self):
np.random.seed(2021)
self.place = get_places()
self.dtype = "float64"
def check_static_result(self, place):
paddle.enable_static()
with base.program_guard(base.Program(), base.Program()):
paddle_input_x = paddle.static.data(
name="input_x", shape=[3, 3], dtype=self.dtype
)
paddle_input_y = paddle.static.data(
name="input_y", shape=[3], dtype=self.dtype
)
paddle_result = paddle.linalg.solve(paddle_input_x, paddle_input_y)
np_input_x = np.random.random([3, 3]).astype(self.dtype)
np_input_y = np.random.random([3]).astype(self.dtype)
np_result = np.linalg.solve(np_input_x, np_input_y)
exe = base.Executor(place)
fetches = exe.run(
base.default_main_program(),
feed={"input_x": np_input_x, "input_y": np_input_y},
fetch_list=[paddle_result],
)
np.testing.assert_allclose(fetches[0], np_result, rtol=1e-05)
def test_static(self):
for place in self.place:
self.check_static_result(place=place)
def test_dygraph(self):
def run(place):
paddle.disable_static(place)
np.random.seed(2021)
input_x_np = np.random.random([3, 3]).astype(self.dtype)
input_y_np = np.random.random([3]).astype(self.dtype)
tensor_input_x = paddle.to_tensor(input_x_np)
tensor_input_y = paddle.to_tensor(input_y_np)
numpy_output = np.linalg.solve(input_x_np, input_y_np)
paddle_output = paddle.linalg.solve(tensor_input_x, tensor_input_y)
np.testing.assert_allclose(
numpy_output, paddle_output.numpy(), rtol=1e-05
)
self.assertEqual(numpy_output.shape, paddle_output.numpy().shape)
paddle.enable_static()
for place in self.place:
run(place)
# 2D normal case, FP64
class TestSolveOpAPI_2(unittest.TestCase):
def setUp(self):
np.random.seed(2021)
self.place = get_places()
self.dtype = "float64"
def check_static_result(self, place):
paddle.enable_static()
with base.program_guard(base.Program(), base.Program()):
paddle_input_x = paddle.static.data(
name="input_x", shape=[10, 10], dtype=self.dtype
)
paddle_input_y = paddle.static.data(
name="input_y", shape=[10, 4], dtype=self.dtype
)
paddle_result = paddle.linalg.solve(paddle_input_x, paddle_input_y)
np_input_x = np.random.random([10, 10]).astype(self.dtype)
np_input_y = np.random.random([10, 4]).astype(self.dtype)
np_result = np.linalg.solve(np_input_x, np_input_y)
exe = base.Executor(place)
fetches = exe.run(
base.default_main_program(),
feed={"input_x": np_input_x, "input_y": np_input_y},
fetch_list=[paddle_result],
)
np.testing.assert_allclose(fetches[0], np_result, rtol=1e-05)
def test_static(self):
for place in self.place:
self.check_static_result(place=place)
def test_dygraph(self):
def run(place):
paddle.disable_static(place)
np.random.seed(2021)
input_x_np = np.random.random([10, 10]).astype(self.dtype)
input_y_np = np.random.random([10, 4]).astype(self.dtype)
tensor_input_x = paddle.to_tensor(input_x_np)
tensor_input_y = paddle.to_tensor(input_y_np)
numpy_output = np.linalg.solve(input_x_np, input_y_np)
paddle_output = paddle.linalg.solve(tensor_input_x, tensor_input_y)
np.testing.assert_allclose(
numpy_output, paddle_output.numpy(), rtol=1e-05
)
self.assertEqual(numpy_output.shape, paddle_output.numpy().shape)
paddle.enable_static()
for place in self.place:
run(place)
# 2D normal case, FP32
class TestSolveOpAPI_3(unittest.TestCase):
def setUp(self):
np.random.seed(2021)
self.place = get_places()
self.dtype = "float32"
def check_static_result(self, place):
paddle.enable_static()
with base.program_guard(base.Program(), base.Program()):
paddle_input_x = paddle.static.data(
name="input_x", shape=[10, 10], dtype=self.dtype
)
paddle_input_y = paddle.static.data(
name="input_y", shape=[10, 4], dtype=self.dtype
)
paddle_result = paddle.linalg.solve(paddle_input_x, paddle_input_y)
np_input_x = np.random.random([10, 10]).astype(self.dtype)
np_input_y = np.random.random([10, 4]).astype(self.dtype)
np_result = np.linalg.solve(np_input_x, np_input_y)
exe = base.Executor(place)
fetches = exe.run(
base.default_main_program(),
feed={"input_x": np_input_x, "input_y": np_input_y},
fetch_list=[paddle_result],
)
np.testing.assert_allclose(fetches[0], np_result, rtol=0.0001)
def test_static(self):
for place in self.place:
self.check_static_result(place=place)
def test_dygraph(self):
def run(place):
paddle.disable_static(place)
np.random.seed(2021)
input_x_np = np.random.random([10, 10]).astype(self.dtype)
input_y_np = np.random.random([10, 4]).astype(self.dtype)
tensor_input_x = paddle.to_tensor(input_x_np)
tensor_input_y = paddle.to_tensor(input_y_np)
numpy_output = np.linalg.solve(input_x_np, input_y_np)
paddle_output = paddle.linalg.solve(tensor_input_x, tensor_input_y)
np.testing.assert_allclose(
numpy_output, paddle_output.numpy(), rtol=0.0001
)
self.assertEqual(numpy_output.shape, paddle_output.numpy().shape)
paddle.enable_static()
for place in self.place:
run(place)
# 3D + y broadcast case, FP64
class TestSolveOpAPI_4(unittest.TestCase):
def setUp(self):
np.random.seed(2021)
self.place = get_places()
self.dtype = "float64"
def check_static_result(self, place):
with base.program_guard(base.Program(), base.Program()):
paddle_input_x = paddle.static.data(
name="input_x", shape=[2, 3, 3], dtype=self.dtype
)
paddle_input_y = paddle.static.data(
name="input_y", shape=[1, 3, 3], dtype=self.dtype
)
paddle_result = paddle.linalg.solve(paddle_input_x, paddle_input_y)
np_input_x = np.random.random([2, 3, 3]).astype(self.dtype)
np_input_y = np.random.random([1, 3, 3]).astype(self.dtype)
np_result = np.linalg.solve(np_input_x, np_input_y)
exe = base.Executor(place)
fetches = exe.run(
base.default_main_program(),
feed={"input_x": np_input_x, "input_y": np_input_y},
fetch_list=[paddle_result],
)
np.testing.assert_allclose(fetches[0], np_result, rtol=1e-05)
def test_static(self):
for place in self.place:
self.check_static_result(place=place)
def test_dygraph(self):
def run(place):
paddle.disable_static(place)
np.random.seed(2021)
input_x_np = np.random.random([2, 3, 3]).astype(self.dtype)
input_y_np = np.random.random([1, 3, 3]).astype(self.dtype)
tensor_input_x = paddle.to_tensor(input_x_np)
tensor_input_y = paddle.to_tensor(input_y_np)
numpy_output = np.linalg.solve(input_x_np, input_y_np)
paddle_output = paddle.linalg.solve(tensor_input_x, tensor_input_y)
np.testing.assert_allclose(
numpy_output, paddle_output.numpy(), rtol=1e-05
)
self.assertEqual(numpy_output.shape, paddle_output.numpy().shape)
paddle.enable_static()
for place in self.place:
run(place)
def np_transpose_last_2dim(x):
x_new_dims = list(range(len(x.shape)))
x_new_dims[-1], x_new_dims[-2] = x_new_dims[-2], x_new_dims[-1]
x = np.transpose(x, x_new_dims)
return x
def np_solve_right(x, y):
x = np_transpose_last_2dim(x)
y = np_transpose_last_2dim(y)
out = np.linalg.solve(x, y)
out = np_transpose_last_2dim(out)
return out
# 2D + vector right case, FP64
class TestSolveOpAPIRight_1(unittest.TestCase):
def setUp(self):
np.random.seed(2021)
self.place = get_places()
self.dtype = "float64"
def check_static_result(self, place):
with base.program_guard(base.Program(), base.Program()):
paddle_input_x = paddle.static.data(
name="input_x", shape=[3, 3], dtype=self.dtype
)
paddle_input_y = paddle.static.data(
name="input_y", shape=[1, 3], dtype=self.dtype
)
paddle_result = paddle.linalg.solve(
paddle_input_x, paddle_input_y, left=False
)
np_input_x = np.random.random([3, 3]).astype(self.dtype)
np_input_y = np.random.random([1, 3]).astype(self.dtype)
np_result = np_solve_right(np_input_x, np_input_y)
exe = base.Executor(place)
fetches = exe.run(
base.default_main_program(),
feed={"input_x": np_input_x, "input_y": np_input_y},
fetch_list=[paddle_result],
)
np.testing.assert_allclose(fetches[0], np_result, rtol=1e-05)
def test_static(self):
for place in self.place:
self.check_static_result(place=place)
def test_dygraph(self):
def run(place):
paddle.disable_static(place)
np.random.seed(2021)
input_x_np = np.random.random([3, 3]).astype(self.dtype)
input_y_np = np.random.random([1, 3]).astype(self.dtype)
tensor_input_x = paddle.to_tensor(input_x_np)
tensor_input_y = paddle.to_tensor(input_y_np)
numpy_output = np_solve_right(input_x_np, input_y_np)
paddle_output = paddle.linalg.solve(
tensor_input_x, tensor_input_y, left=False
)
np.testing.assert_allclose(
numpy_output, paddle_output.numpy(), rtol=1e-05
)
self.assertEqual(numpy_output.shape, paddle_output.numpy().shape)
paddle.enable_static()
for place in self.place:
run(place)
# 2D normal right case, FP64
class TestSolveOpAPIRight_2(unittest.TestCase):
def setUp(self):
np.random.seed(2021)
self.place = get_places()
self.dtype = "float64"
def check_static_result(self, place):
paddle.enable_static()
with base.program_guard(base.Program(), base.Program()):
paddle_input_x = paddle.static.data(
name="input_x", shape=[10, 10], dtype=self.dtype
)
paddle_input_y = paddle.static.data(
name="input_y", shape=[4, 10], dtype=self.dtype
)
paddle_result = paddle.linalg.solve(
paddle_input_x, paddle_input_y, left=False
)
np_input_x = np.random.random([10, 10]).astype(self.dtype)
np_input_y = np.random.random([4, 10]).astype(self.dtype)
np_result = np_solve_right(np_input_x, np_input_y)
exe = base.Executor(place)
fetches = exe.run(
base.default_main_program(),
feed={"input_x": np_input_x, "input_y": np_input_y},
fetch_list=[paddle_result],
)
np.testing.assert_allclose(fetches[0], np_result, rtol=1e-05)
def test_static(self):
for place in self.place:
self.check_static_result(place=place)
def test_dygraph(self):
def run(place):
paddle.disable_static(place)
np.random.seed(2021)
input_x_np = np.random.random([10, 10]).astype(self.dtype)
input_y_np = np.random.random([4, 10]).astype(self.dtype)
tensor_input_x = paddle.to_tensor(input_x_np)
tensor_input_y = paddle.to_tensor(input_y_np)
numpy_output = np_solve_right(input_x_np, input_y_np)
paddle_output = paddle.linalg.solve(
tensor_input_x, tensor_input_y, left=False
)
np.testing.assert_allclose(
numpy_output, paddle_output.numpy(), rtol=1e-05
)
self.assertEqual(numpy_output.shape, paddle_output.numpy().shape)
paddle.enable_static()
for place in self.place:
run(place)
# 2D normal right case, FP32
class TestSolveOpAPIRight_3(unittest.TestCase):
def setUp(self):
np.random.seed(2021)
self.place = get_places()
self.dtype = "float32"
def check_static_result(self, place):
paddle.enable_static()
with base.program_guard(base.Program(), base.Program()):
paddle_input_x = paddle.static.data(
name="input_x", shape=[10, 10], dtype=self.dtype
)
paddle_input_y = paddle.static.data(
name="input_y", shape=[6, 10], dtype=self.dtype
)
paddle_result = paddle.linalg.solve(
paddle_input_x, paddle_input_y, left=False
)
np_input_x = np.random.random([10, 10]).astype(self.dtype)
np_input_y = np.random.random([6, 10]).astype(self.dtype)
np_result = np_solve_right(np_input_x, np_input_y)
exe = base.Executor(place)
fetches = exe.run(
base.default_main_program(),
feed={"input_x": np_input_x, "input_y": np_input_y},
fetch_list=[paddle_result],
)
np.testing.assert_allclose(fetches[0], np_result, rtol=0.0001)
def test_static(self):
for place in self.place:
self.check_static_result(place=place)
def test_dygraph(self):
def run(place):
paddle.disable_static(place)
np.random.seed(2021)
input_x_np = np.random.random([10, 10]).astype(self.dtype)
input_y_np = np.random.random([6, 10]).astype(self.dtype)
tensor_input_x = paddle.to_tensor(input_x_np)
tensor_input_y = paddle.to_tensor(input_y_np)
numpy_output = np_solve_right(input_x_np, input_y_np)
paddle_output = paddle.linalg.solve(
tensor_input_x, tensor_input_y, left=False
)
np.testing.assert_allclose(
numpy_output, paddle_output.numpy(), rtol=0.0001
)
self.assertEqual(numpy_output.shape, paddle_output.numpy().shape)
paddle.enable_static()
for place in self.place:
run(place)
# 3D + y broadcast right case, FP64
class TestSolveOpAPIRight_4(unittest.TestCase):
def setUp(self):
np.random.seed(2021)
self.place = get_places()
self.dtype = "float64"
def check_static_result(self, place):
with base.program_guard(base.Program(), base.Program()):
paddle_input_x = paddle.static.data(
name="input_x", shape=[2, 3, 3], dtype=self.dtype
)
paddle_input_y = paddle.static.data(
name="input_y", shape=[1, 3, 3], dtype=self.dtype
)
paddle_result = paddle.linalg.solve(
paddle_input_x, paddle_input_y, left=False
)
np_input_x = np.random.random([2, 3, 3]).astype(self.dtype)
np_input_y = np.random.random([1, 3, 3]).astype(self.dtype)
np_result = np_solve_right(np_input_x, np_input_y)
exe = base.Executor(place)
fetches = exe.run(
base.default_main_program(),
feed={"input_x": np_input_x, "input_y": np_input_y},
fetch_list=[paddle_result],
)
np.testing.assert_allclose(fetches[0], np_result, rtol=1e-05)
def test_static(self):
for place in self.place:
self.check_static_result(place=place)
def test_dygraph(self):
def run(place):
paddle.disable_static(place)
np.random.seed(2021)
input_x_np = np.random.random([2, 3, 3]).astype(self.dtype)
input_y_np = np.random.random([1, 3, 3]).astype(self.dtype)
tensor_input_x = paddle.to_tensor(input_x_np)
tensor_input_y = paddle.to_tensor(input_y_np)
numpy_output = np_solve_right(input_x_np, input_y_np)
paddle_output = paddle.linalg.solve(
tensor_input_x, tensor_input_y, left=False
)
np.testing.assert_allclose(
numpy_output, paddle_output.numpy(), rtol=1e-05
)
self.assertEqual(numpy_output.shape, paddle_output.numpy().shape)
paddle.enable_static()
for place in self.place:
run(place)
class TestSolveOpSingularAPI(unittest.TestCase):
# Singular matrix is not invertible
def setUp(self):
self.places = get_places()
self.dtype = "float64"
def check_static_result(self, place):
with base.program_guard(base.Program(), base.Program()):
x = paddle.static.data(name="x", shape=[4, 4], dtype=self.dtype)
y = paddle.static.data(name="y", shape=[4, 4], dtype=self.dtype)
result = paddle.linalg.solve(x, y)
input_x_np = np.ones([4, 4]).astype(self.dtype)
input_y_np = np.ones([4, 4]).astype(self.dtype)
exe = base.Executor(place)
try:
exe.run(
base.default_main_program(),
feed={"x": input_x_np, "y": input_y_np},
fetch_list=[result],
)
except RuntimeError:
print("The mat is singular")
except ValueError:
print("The mat is singular")
def test_static(self):
for place in self.places:
paddle.enable_static()
self.check_static_result(place=place)
def test_dygraph(self):
for place in self.places:
with base.dygraph.guard(place):
input_x_np = np.ones([4, 4]).astype(self.dtype)
input_y_np = np.ones([4, 4]).astype(self.dtype)
input_x = paddle.to_tensor(input_x_np)
input_y = paddle.to_tensor(input_y_np)
try:
paddle.linalg.solve(input_x, input_y)
except RuntimeError:
print("The mat is singular")
except ValueError:
print("The mat is singular")
class TestSolveOpAPIZeroDimCase(unittest.TestCase):
def setUp(self):
np.random.seed(2021)
self.place = get_places()
self.dtype = "float32"
def check_static_result(self, place, x_shape, y_shape, np_y_shape):
paddle.enable_static()
with base.program_guard(base.Program(), base.Program()):
paddle_input_x = paddle.static.data(
name="input_x", shape=x_shape, dtype=self.dtype
)
paddle_input_y = paddle.static.data(
name="input_y", shape=y_shape, dtype=self.dtype
)
paddle_result = paddle.linalg.solve(
paddle_input_x, paddle_input_y, left=False
)
np_input_x = np.random.random(x_shape).astype(self.dtype)
np_input_y = np.random.random(np_y_shape).astype(self.dtype)
np_result = np.linalg.solve(np_input_x, np_input_y)
exe = base.Executor(place)
fetches = exe.run(
base.default_main_program(),
feed={"input_x": np_input_x, "input_y": np_input_y},
fetch_list=[paddle_result],
)
np.testing.assert_allclose(fetches[0], np_result, rtol=0.0001)
def test_static(self):
for place in self.place:
self.check_static_result(
place=place,
x_shape=[10, 0, 0],
y_shape=[10, 0, 0],
np_y_shape=[10, 0, 0],
)
with self.assertRaises(ValueError):
self.check_static_result(
place=place,
x_shape=[10, 0, 0],
y_shape=[10],
np_y_shape=[10],
)
def test_dygraph(self):
def run(place, x_shape, y_shape):
with base.dygraph.guard(place):
input_x_np = np.random.random(x_shape).astype(self.dtype)
input_y_np = np.random.random(y_shape).astype(self.dtype)
tensor_input_x = paddle.to_tensor(
input_x_np, stop_gradient=False
)
tensor_input_y = paddle.to_tensor(
input_y_np, stop_gradient=False
)
numpy_output = np.linalg.solve(input_x_np, input_y_np)
paddle_output = paddle.linalg.solve(
tensor_input_x, tensor_input_y, left=True
)
np.testing.assert_allclose(
numpy_output, paddle_output.numpy(), rtol=0.00011
)
self.assertEqual(
numpy_output.shape, paddle_output.numpy().shape
)
loss = paddle.sum(paddle_output)
loss.backward()
np.testing.assert_allclose(
tensor_input_x.grad.shape, tensor_input_x.shape
)
np.testing.assert_allclose(
tensor_input_y.grad.shape, tensor_input_y.shape
)
for place in self.place:
run(place, x_shape=[1, 10, 10], y_shape=[1, 10, 10])
run(place, x_shape=[0, 10, 10], y_shape=[0, 10, 10])
run(place, x_shape=[0, 10, 10], y_shape=[1, 10, 10])
run(place, x_shape=[10, 0, 0], y_shape=[10, 0, 0])
run(place, x_shape=[10, 1, 1], y_shape=[10, 1, 0])
with self.assertRaises(ValueError):
run(place, x_shape=[10, 0, 0], y_shape=[10])
class TestSolveAPI_Compatibility(unittest.TestCase):
def setUp(self):
np.random.seed(2025)
self.places = ['cpu', get_device_place()]
self.n = 4
self.shape_A = [self.n, self.n]
self.shape_B = [self.n, 1]
self.dtype = "float64"
self.init_data()
def init_data(self):
A = np.random.rand(*self.shape_A).astype(self.dtype)
self.np_A = np.dot(A, A.T) + np.eye(self.n)
self.np_B = np.random.rand(*self.shape_B).astype(self.dtype)
def test_dygraph_Compatibility(self):
paddle.disable_static()
A = paddle.to_tensor(self.np_A)
B = paddle.to_tensor(self.np_B)
paddle_dygraph_out = []
# Position args (args)
out1 = paddle.linalg.solve(A, B)
paddle_dygraph_out.append(out1)
# Key words args (kwargs) for paddle
out2 = paddle.linalg.solve(x=A, y=B)
paddle_dygraph_out.append(out2)
# Key words args for torch compatibility
out3 = paddle.linalg.solve(A=A, B=B)
paddle_dygraph_out.append(out3)
# Key words args for out
out4 = paddle.zeros_like(B)
paddle.linalg.solve(A, B, out=out4)
paddle_dygraph_out.append(out4)
# Numpy reference output
ref_out = np.linalg.solve(self.np_A, self.np_B)
for out in paddle_dygraph_out:
np.testing.assert_allclose(
ref_out, out.numpy(), rtol=1e-05, atol=1e-08
)
paddle.enable_static()
def test_static_Compatibility(self):
paddle.enable_static()
main = paddle.static.Program()
startup = paddle.static.Program()
with paddle.base.program_guard(main, startup):
A = paddle.static.data(
name="A", shape=self.shape_A, dtype=self.dtype
)
B = paddle.static.data(
name="B", shape=self.shape_B, dtype=self.dtype
)
# Position args (args)
out1 = paddle.linalg.solve(A, B)
# Key words args (kwargs) for paddle
out2 = paddle.linalg.solve(x=A, y=B)
# Key words args for torch compatibility
out3 = paddle.linalg.solve(A=A, B=B)
# Numpy reference output
ref_out = np.linalg.solve(self.np_A, self.np_B)
fetch_list = [out1, out2, out3]
for place in self.places:
exe = paddle.base.Executor(place)
fetches = exe.run(
main,
feed={"A": self.np_A, "B": self.np_B},
fetch_list=fetch_list,
)
for out in fetches:
np.testing.assert_allclose(
out, ref_out, rtol=1e-05, atol=1e-08
)
if __name__ == "__main__":
unittest.main()