From 95e75d2201de1e750b26cde6da6175bac19bea44 Mon Sep 17 00:00:00 2001 From: Kaushik Kulkarni Date: Sat, 8 Jan 2022 02:13:43 +0000 Subject: [PATCH 01/10] Rpow scalar --- pycuda/elementwise.py | 39 +++++++++++++++++++++++++++++++++++++++ pycuda/gpuarray.py | 21 +++++++++++++++++++++ test/test_gpuarray.py | 15 +++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/pycuda/elementwise.py b/pycuda/elementwise.py index 258bae5c..607e9f9c 100644 --- a/pycuda/elementwise.py +++ b/pycuda/elementwise.py @@ -666,6 +666,45 @@ def get_pow_array_kernel(dtype_x, dtype_y, dtype_z): ) +@context_dependent_memoize +def get_rpow_kernel(dtype_x, dtype_y, dtype_z, is_base_array, is_exp_array): + """ + Returns the kernel for the operation: ``z = x ** y`` + """ + if np.float64 in [dtype_x, dtype_y]: + func = "pow" + else: + func = "powf" + + if not is_base_array and is_exp_array: + x_ctype = "%(tp_x)s x" + y_ctype = "%(tp_y)s *y" + func = "%s(x,y[i])" % func + + elif is_base_array and is_exp_array: + x_ctype = "%(tp_x)s *x" + y_ctype = "%(tp_y)s *y" + func = "%s(x[i],y[i])" % func + + elif is_base_array and not is_exp_array: + x_ctype = "%(tp_x)s *x" + y_ctype = "%(tp_y)s y" + func = "%s(x[i],y)" % func + + else: + raise AssertionError + + return get_elwise_kernel( + ("%(tp_z)s *z, " + x_ctype + ", "+y_ctype) + % { + "tp_x": dtype_to_ctype(dtype_x), + "tp_y": dtype_to_ctype(dtype_y), + "tp_z": dtype_to_ctype(dtype_z), + }, + "z[i] = %s" % func, + name="pow_method") + + @context_dependent_memoize def get_fmod_kernel(): return get_elwise_kernel( diff --git a/pycuda/gpuarray.py b/pycuda/gpuarray.py index a0bf84c4..5e7a5607 100644 --- a/pycuda/gpuarray.py +++ b/pycuda/gpuarray.py @@ -839,6 +839,27 @@ class GPUArray: """ return self._pow(other, new=False) + def __rpow__(self, other): + common_dtype = _get_common_dtype(self, other) + result = self._new_like_me(common_dtype) + + if not np.isscalar(other): + # Base is a gpuarray => do not cast. + base = other + else: + base = common_dtype.type(other) + + func = elementwise.get_rpow_kernel( + base.dtype, self.dtype, result.dtype, + is_base_array=not np.isscalar(other), is_exp_array=not np.isscalar(self)) + # Evaluates z = x ** y + func.prepared_async_call(self._grid, self._block, None, + result.gpudata, # z + base if np.isscalar(base) else base.gpudata, # x + self.gpudata, # y + self.mem_size) + return result + def reverse(self, stream=None): """Return this array in reversed order. The array is treated as one-dimensional. diff --git a/test/test_gpuarray.py b/test/test_gpuarray.py index dbf4b2f7..5234d8a2 100644 --- a/test/test_gpuarray.py +++ b/test/test_gpuarray.py @@ -40,6 +40,21 @@ class TestGPUArray: a_gpu = a_gpu.get() assert (np.abs(a ** 2 - a_gpu) < 1e-3).all() + @mark_cuda_test + def test_rpow_array(self): + scalar = np.random.rand() + a = abs(np.random.rand(10)) + a_gpu = gpuarray.to_gpu(a) + + result = (scalar ** a_gpu).get() + np.testing.assert_allclose(scalar ** a, result) + + result = (a_gpu ** a_gpu).get() + np.testing.assert_allclose(a ** a, result) + + result = (a_gpu ** scalar).get() + np.testing.assert_allclose(a ** scalar, result) + @mark_cuda_test def test_numpy_integer_shape(self): gpuarray.empty(np.int32(17), np.float32) -- GitLab From 5461fa5f7ce665a1367ddca9b95fb792bbfe5a97 Mon Sep 17 00:00:00 2001 From: Mit Kotak Date: Sat, 15 Jan 2022 22:30:03 +0000 Subject: [PATCH 02/10] Merged get_rpow_kernel into get_pow_kernel --- pycuda/elementwise.py | 29 ++++++----------------------- pycuda/gpuarray.py | 4 ++-- 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/pycuda/elementwise.py b/pycuda/elementwise.py index 607e9f9c..b1fdbc46 100644 --- a/pycuda/elementwise.py +++ b/pycuda/elementwise.py @@ -648,26 +648,8 @@ def get_pow_kernel(dtype): @context_dependent_memoize -def get_pow_array_kernel(dtype_x, dtype_y, dtype_z): - if np.float64 in [dtype_x, dtype_y]: - func = "pow" - else: - func = "powf" - - return get_elwise_kernel( - "%(tp_x)s *x, %(tp_y)s *y, %(tp_z)s *z" - % { - "tp_x": dtype_to_ctype(dtype_x), - "tp_y": dtype_to_ctype(dtype_y), - "tp_z": dtype_to_ctype(dtype_z), - }, - "z[i] = %s(x[i], y[i])" % func, - "pow_method", - ) - - -@context_dependent_memoize -def get_rpow_kernel(dtype_x, dtype_y, dtype_z, is_base_array, is_exp_array): +def get_pow_array_kernel(dtype_x, dtype_y, dtype_z, +is_base_array, is_exp_array): """ Returns the kernel for the operation: ``z = x ** y`` """ @@ -692,9 +674,9 @@ def get_rpow_kernel(dtype_x, dtype_y, dtype_z, is_base_array, is_exp_array): func = "%s(x[i],y)" % func else: - raise AssertionError + raise Assertion Error - return get_elwise_kernel( + return get_elwise_kernel( ("%(tp_z)s *z, " + x_ctype + ", "+y_ctype) % { "tp_x": dtype_to_ctype(dtype_x), @@ -702,7 +684,8 @@ def get_rpow_kernel(dtype_x, dtype_y, dtype_z, is_base_array, is_exp_array): "tp_z": dtype_to_ctype(dtype_z), }, "z[i] = %s" % func, - name="pow_method") + name="pow_method" + ) @context_dependent_memoize diff --git a/pycuda/gpuarray.py b/pycuda/gpuarray.py index 5e7a5607..30cd59c8 100644 --- a/pycuda/gpuarray.py +++ b/pycuda/gpuarray.py @@ -780,16 +780,16 @@ class GPUArray: result = self func = elementwise.get_pow_array_kernel( - self.dtype, other.dtype, result.dtype + result.dtype, self.dtype, other.dtype ) func.prepared_async_call( self._grid, self._block, None, + result.gpudata, self.gpudata, other.gpudata, - result.gpudata, self.mem_size, ) -- GitLab From 28d963c42aa9eaac87e046394b9d39754c6d7753 Mon Sep 17 00:00:00 2001 From: Mit Kotak Date: Sat, 15 Jan 2022 22:36:42 +0000 Subject: [PATCH 03/10] Resolved Assertion Error typo --- pycuda/elementwise.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pycuda/elementwise.py b/pycuda/elementwise.py index b1fdbc46..0c70dcbf 100644 --- a/pycuda/elementwise.py +++ b/pycuda/elementwise.py @@ -674,9 +674,9 @@ is_base_array, is_exp_array): func = "%s(x[i],y)" % func else: - raise Assertion Error + raise AssertionError - return get_elwise_kernel( + return get_elwise_kernel( ("%(tp_z)s *z, " + x_ctype + ", "+y_ctype) % { "tp_x": dtype_to_ctype(dtype_x), -- GitLab From e82835b5b5af28a7941520cafa53780fe7e9598b Mon Sep 17 00:00:00 2001 From: Mit Kotak Date: Sat, 15 Jan 2022 22:48:05 +0000 Subject: [PATCH 04/10] Added flags to get_pow_array_kernel --- pycuda/gpuarray.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pycuda/gpuarray.py b/pycuda/gpuarray.py index 30cd59c8..b4d87e6f 100644 --- a/pycuda/gpuarray.py +++ b/pycuda/gpuarray.py @@ -780,7 +780,9 @@ class GPUArray: result = self func = elementwise.get_pow_array_kernel( - result.dtype, self.dtype, other.dtype + result.dtype, self.dtype, other.dtype, + is_base_array=True, + is_exp_array=True ) func.prepared_async_call( -- GitLab From 1cae937225c9eb7b8186ff365f99e9bf3b03c951 Mon Sep 17 00:00:00 2001 From: Mit Kotak Date: Sat, 15 Jan 2022 22:56:26 +0000 Subject: [PATCH 05/10] Had to remove all declaratoins of get_rpow_kernel --- pycuda/gpuarray.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pycuda/gpuarray.py b/pycuda/gpuarray.py index b4d87e6f..adb0ea53 100644 --- a/pycuda/gpuarray.py +++ b/pycuda/gpuarray.py @@ -851,7 +851,7 @@ class GPUArray: else: base = common_dtype.type(other) - func = elementwise.get_rpow_kernel( + func = elementwise.get_pow_array_kernel( base.dtype, self.dtype, result.dtype, is_base_array=not np.isscalar(other), is_exp_array=not np.isscalar(self)) # Evaluates z = x ** y -- GitLab From ece3d97ada21169880d47e2c4cd3533eb8eeb8f4 Mon Sep 17 00:00:00 2001 From: Mit Kotak Date: Sun, 16 Jan 2022 17:35:15 +0000 Subject: [PATCH 06/10] Updated test_pow_array --- pycuda/elementwise.py | 3 +-- test/test_gpuarray.py | 10 ++++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/pycuda/elementwise.py b/pycuda/elementwise.py index 0c70dcbf..cbe92953 100644 --- a/pycuda/elementwise.py +++ b/pycuda/elementwise.py @@ -648,8 +648,7 @@ def get_pow_kernel(dtype): @context_dependent_memoize -def get_pow_array_kernel(dtype_x, dtype_y, dtype_z, -is_base_array, is_exp_array): +def get_pow_array_kernel(dtype_x, dtype_y, dtype_z, is_base_array, is_exp_array): """ Returns the kernel for the operation: ``z = x ** y`` """ diff --git a/test/test_gpuarray.py b/test/test_gpuarray.py index 5234d8a2..32ae5158 100644 --- a/test/test_gpuarray.py +++ b/test/test_gpuarray.py @@ -17,12 +17,14 @@ class TestGPUArray: def test_pow_array(self): a = np.array([1, 2, 3, 4, 5]).astype(np.float32) a_gpu = gpuarray.to_gpu(a) + b = np.array([6, 7, 8, 9, 10]).astype(np.float32) + b_gpu = gpuarray.to_gpu(b) - result = pow(a_gpu, a_gpu).get() - assert (np.abs(a ** a - result) < 1e-3).all() + result = pow(a_gpu, b_gpu).get() + assert (np.abs(a ** b - result) < 1e-3).all() - result = (a_gpu ** a_gpu).get() - assert (np.abs(pow(a, a) - result) < 1e-3).all() + result = (a_gpu ** b_gpu).get() + assert (np.abs(pow(a, b) - result) < 1e-3).all() a_gpu **= a_gpu a_gpu = a_gpu.get() -- GitLab From 8b329a30020d5001134d3066d2270167ad488840 Mon Sep 17 00:00:00 2001 From: Mit Kotak Date: Sun, 16 Jan 2022 17:49:33 +0000 Subject: [PATCH 07/10] Updating functions to work for new test cases --- pycuda/gpuarray.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pycuda/gpuarray.py b/pycuda/gpuarray.py index adb0ea53..dbbf4eac 100644 --- a/pycuda/gpuarray.py +++ b/pycuda/gpuarray.py @@ -780,7 +780,7 @@ class GPUArray: result = self func = elementwise.get_pow_array_kernel( - result.dtype, self.dtype, other.dtype, + self.dtype, other.dtype, result.dtype, is_base_array=True, is_exp_array=True ) -- GitLab From 0f9e45434f7303b467ad99cbedf958099c99a3fa Mon Sep 17 00:00:00 2001 From: Mit Kotak Date: Sun, 16 Jan 2022 17:57:57 +0000 Subject: [PATCH 08/10] Reverting back to original test case --- test/test_gpuarray.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/test_gpuarray.py b/test/test_gpuarray.py index 32ae5158..5234d8a2 100644 --- a/test/test_gpuarray.py +++ b/test/test_gpuarray.py @@ -17,14 +17,12 @@ class TestGPUArray: def test_pow_array(self): a = np.array([1, 2, 3, 4, 5]).astype(np.float32) a_gpu = gpuarray.to_gpu(a) - b = np.array([6, 7, 8, 9, 10]).astype(np.float32) - b_gpu = gpuarray.to_gpu(b) - result = pow(a_gpu, b_gpu).get() - assert (np.abs(a ** b - result) < 1e-3).all() + result = pow(a_gpu, a_gpu).get() + assert (np.abs(a ** a - result) < 1e-3).all() - result = (a_gpu ** b_gpu).get() - assert (np.abs(pow(a, b) - result) < 1e-3).all() + result = (a_gpu ** a_gpu).get() + assert (np.abs(pow(a, a) - result) < 1e-3).all() a_gpu **= a_gpu a_gpu = a_gpu.get() -- GitLab From 9ac385b17c57e934bcba05a2cb9bb0b85d6fee0e Mon Sep 17 00:00:00 2001 From: Mit Kotak Date: Sun, 16 Jan 2022 18:29:00 +0000 Subject: [PATCH 09/10] Changed assert -> np.testing.assert_allclose --- test/test_gpuarray.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/test/test_gpuarray.py b/test/test_gpuarray.py index 5234d8a2..12e7704e 100644 --- a/test/test_gpuarray.py +++ b/test/test_gpuarray.py @@ -16,17 +16,19 @@ class TestGPUArray: @mark_cuda_test def test_pow_array(self): a = np.array([1, 2, 3, 4, 5]).astype(np.float32) + b = np.array([6, 7, 8, 9, 10]).astype(np.float32) a_gpu = gpuarray.to_gpu(a) + b_gpu = gpuarray.to_gpu(b) - result = pow(a_gpu, a_gpu).get() - assert (np.abs(a ** a - result) < 1e-3).all() + result = pow(a_gpu, b_gpu).get() + np.testing.assert_allclose(a ** b, result) - result = (a_gpu ** a_gpu).get() - assert (np.abs(pow(a, a) - result) < 1e-3).all() + result = (a_gpu ** b_gpu).get() + np.testing.assert_allclose(pow(a, b), result) - a_gpu **= a_gpu + a_gpu **= b_gpu a_gpu = a_gpu.get() - assert (np.abs(pow(a, a) - a_gpu) < 1e-3).all() + np.testing.assert_allclose(pow(a, b), result) @mark_cuda_test def test_pow_number(self): -- GitLab From 43dc9f532ea4a33822fd2c0dc61591568e3b8a6e Mon Sep 17 00:00:00 2001 From: Mit Kotak Date: Sun, 16 Jan 2022 18:34:37 +0000 Subject: [PATCH 10/10] Making sure that test fails for irrelevant cases --- pycuda/gpuarray.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pycuda/gpuarray.py b/pycuda/gpuarray.py index dbbf4eac..adb0ea53 100644 --- a/pycuda/gpuarray.py +++ b/pycuda/gpuarray.py @@ -780,7 +780,7 @@ class GPUArray: result = self func = elementwise.get_pow_array_kernel( - self.dtype, other.dtype, result.dtype, + result.dtype, self.dtype, other.dtype, is_base_array=True, is_exp_array=True ) -- GitLab