From 1f6ad3d3c3017393eef1eaa30a57ca39a40a9a91 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Wed, 26 Jul 2023 22:14:30 +0200 Subject: [PATCH] Added examples --- .github/workflows/build-sphinx.yml | 2 +- doc/index.rst | 1 - doc/quick_start_guide.rst | 21 ++++++++++++- examples/example1.py | 28 ++++++++--------- examples/example10.py | 27 +++++++++-------- examples/example2.py | 37 +++++++---------------- examples/example6.py | 12 +------- examples/example7.py | 31 ++++++++++--------- examples/example_bs.py | 14 ++------- examples/example_cfd.py | 48 ++++++++++++++++++++++++++++++ examples/example_sum.py | 44 +++++++++++++++++++++++++++ 11 files changed, 169 insertions(+), 96 deletions(-) create mode 100644 examples/example_cfd.py create mode 100644 examples/example_sum.py diff --git a/.github/workflows/build-sphinx.yml b/.github/workflows/build-sphinx.yml index ceaef45f8af..5b1fe9caf58 100644 --- a/.github/workflows/build-sphinx.yml +++ b/.github/workflows/build-sphinx.yml @@ -144,7 +144,7 @@ jobs: uses: mshick/add-pr-comment@v2.8.1 with: message: | - View rendered docs @ https://intelpython.github.io/dpnp/pulls/${{ env.PR_NUM }}/index.html + View rendered docs @ https://intelpython.github.io/dpnp/pull/${{ env.PR_NUM }}/index.html allow-repeats: false clean: diff --git a/doc/index.rst b/doc/index.rst index fcf07d2aa17..b34e2d15ab3 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -18,4 +18,3 @@ Data Parallel Extension for NumPy* :caption: Development information dpnp_backend_api - dpctl diff --git a/doc/quick_start_guide.rst b/doc/quick_start_guide.rst index a2e7df79746..71cc5b2f32d 100644 --- a/doc/quick_start_guide.rst +++ b/doc/quick_start_guide.rst @@ -75,7 +75,7 @@ Finanly, to install the result package: .. code-block:: bash - conda install dpnp + conda install dpnp -c local Build and Install with scikit-build @@ -127,3 +127,22 @@ by the source, you will need to run a command as below: .. code-block:: bash pytest -s tests + +Examples +======== + +The examples below demonstrates a simple usage of the Data Parallel Extension for NumPy* + +.. literalinclude:: ../examples/example_sum.py + :linenos: + :language: python + :lines: 35- + :caption: How to create an array and to sum the elements + +.. literalinclude:: ../examples/example_cfd.py + :linenos: + :language: python + :lines: 34- + :caption: How to create an array on the specific device type and the next computation follows it + +More examples on how to use ``dpnp`` can be found in ``dpnp/examples``. diff --git a/examples/example1.py b/examples/example1.py index 7d86c0a15e9..e078a02090d 100644 --- a/examples/example1.py +++ b/examples/example1.py @@ -36,21 +36,13 @@ """ -try: - import dpnp -except ImportError: - import os - import sys - - root_dir = os.path.join(os.path.dirname(__file__), os.pardir) - sys.path.append(root_dir) - - import dpnp - import time +import dpctl import numpy +import dpnp + def run_dgemm(executor, name, size, test_type, repetition): x1 = executor.reshape( @@ -75,15 +67,23 @@ def run_dgemm(executor, name, size, test_type, repetition): return (min_time, med_time, max_time), result.item(5) +def get_dtypes(): + _dtypes_list = [numpy.int32, numpy.int64, numpy.float32] + device = dpctl.select_default_device() + if device.has_aspect_fp64: + _dtypes_list.append(numpy.float64) + return _dtypes_list + + if __name__ == "__main__": test_repetition = 5 - for test_type in [numpy.float64, numpy.float32, numpy.int64, numpy.int32]: + for test_type in get_dtypes(): type_name = numpy.dtype(test_type).name print( f"...Test data type is {test_type}, each test repetitions {test_repetition}" ) - for size in [16, 32, 64, 128]: # , 256, 512, 1024, 2048, 4096]: + for size in [16, 32, 64, 128, 256, 512, 1024]: times_python, result_python = run_dgemm( numpy, "", size, test_type, test_repetition ) @@ -97,6 +97,6 @@ def run_dgemm(executor, name, size, test_type, repetition): msg = f"type:{type_name}:N:{size:4}" msg += f":__NumPy__:{times_python[1]:.3e}:(min:{times_python[0]:.3e}:max:{times_python[2]:.3e})" - msg += f":__SYCL__:{times_sycl[1]:.3e}:(min:{times_sycl[0]:.3e}:max:{times_sycl[2]:.3e})" + msg += f":__DPNP__:{times_sycl[1]:.3e}:(min:{times_sycl[0]:.3e}:max:{times_sycl[2]:.3e})" msg += f":ratio:{times_python[1]/times_sycl[1]:6.2f}:verification:{verification}" print(msg) diff --git a/examples/example10.py b/examples/example10.py index a11c4610f48..e2518423678 100644 --- a/examples/example10.py +++ b/examples/example10.py @@ -28,23 +28,16 @@ """Example 10. This example shows simple usage of the DPNP -in combination with dpCtl. +in combination with dpctl. """ import time -try: - import dpnp -except ImportError: - import os - import sys - - sys.path.insert(0, os.path.abspath(".")) - import dpnp - import numpy +import dpnp + def run(executor, size, test_type, repetition): x = executor.reshape( @@ -61,9 +54,17 @@ def run(executor, size, test_type, repetition): return numpy.median(times), result +def get_dtypes(): + _dtypes_list = [numpy.int32, numpy.int64, numpy.float32] + device = dpctl.select_default_device() + if device.has_aspect_fp64: + _dtypes_list.append(numpy.float64) + return _dtypes_list + + def example(): test_repetition = 5 - for test_type in [numpy.float64, numpy.float32, numpy.int64, numpy.int32]: + for test_type in get_dtypes(): type_name = numpy.dtype(test_type).name print( f"...Test data type is {type_name}, each test repetitions {test_repetition}" @@ -80,7 +81,7 @@ def example(): else: verification = f"({result_dpnp} != {result_numpy})" - msg = f"type:{type_name}:N:{size:4}:NumPy:{time_numpy:.3e}:SYCL:{time_dpnp:.3e}" + msg = f"type:{type_name}:N:{size:4}:NumPy:{time_numpy:.3e}:DPNP:{time_dpnp:.3e}" msg += f":ratio:{time_numpy/time_dpnp:6.2f}:verification:{verification}" print(msg) @@ -90,7 +91,7 @@ def example(): import dpctl with dpctl.device_context("opencl:gpu") as gpu_queue: - gpu_queue.get_sycl_device().dump_device_info() + gpu_queue.get_sycl_device().print_device_info() example() except ImportError: diff --git a/examples/example2.py b/examples/example2.py index f2a4d06a4dc..55408d3df49 100644 --- a/examples/example2.py +++ b/examples/example2.py @@ -36,36 +36,18 @@ """ -try: - import dpnp -except ImportError: - import os - import sys - - root_dir = os.path.join(os.path.dirname(__file__), os.pardir) - sys.path.append(root_dir) - - import dpnp - import time import numpy -common_function_one_input = numpy.sin -""" -Fixed third party function -""" - - -def get_package_specific_input_data_type(input_type, size): - return input_type.arange(size) +import dpnp -def run_third_party_function(input, repetition): +def run_third_party_function(xp, input, repetition): times = [] for _ in range(repetition): start_time = time.time() - result = common_function_one_input(input) + result = xp.sin(input) end_time = time.time() times.append(end_time - start_time) @@ -75,18 +57,19 @@ def run_third_party_function(input, repetition): if __name__ == "__main__": test_repetition = 5 - for input_type in [numpy, dpnp]: - type_name = input_type.__name__ + for xp in [numpy, dpnp]: + type_name = xp.__name__ print( f"...Test data type is {type_name}, each test repetitions {test_repetition}" ) - for size in [2048, 4096, 8192, 16384, 32768, 65536]: - input_data = get_package_specific_input_data_type(input_type, size) + for size in range(20, 25): + size = 2**size + input_data = xp.arange(size) result_time, result = run_third_party_function( - input_data, test_repetition + xp, input_data, test_repetition ) print( - f"type:{type_name}:N:{size:6}:Time:{result_time:.3e}:result:{result:.3e}" + f"type:{type_name}:N:{size:6}:Time:{result_time:.3e}:result:{result}" ) diff --git a/examples/example6.py b/examples/example6.py index 96a494bc437..5cd19651046 100644 --- a/examples/example6.py +++ b/examples/example6.py @@ -32,17 +32,7 @@ dpnp.random.randn """ - -try: - import dpnp -except ImportError: - import os - import sys - - root_dir = os.path.join(os.path.dirname(__file__), os.pardir) - sys.path.append(root_dir) - - import dpnp +import dpnp if __name__ == "__main__": # TODO diff --git a/examples/example7.py b/examples/example7.py index 1e5ee8ce596..a0df2e1eef3 100644 --- a/examples/example7.py +++ b/examples/example7.py @@ -25,7 +25,7 @@ # THE POSSIBILITY OF SUCH DAMAGE. # ***************************************************************************** -"""Example 1. +"""Example 7. This example shows simple usage of the DPNP to calculate square matrix multiplication @@ -35,22 +35,13 @@ """ - -try: - import dpnp -except ImportError: - import os - import sys - - root_dir = os.path.join(os.path.dirname(__file__), os.pardir) - sys.path.append(root_dir) - - import dpnp - import time +import dpctl import numpy +import dpnp + def run_function(executor, name, size, test_type, repetition): x = executor.reshape( @@ -69,15 +60,23 @@ def run_function(executor, name, size, test_type, repetition): return execution_time, result +def get_dtypes(): + _dtypes_list = [numpy.int32, numpy.int64, numpy.float32] + device = dpctl.select_default_device() + if device.has_aspect_fp64: + _dtypes_list.append(numpy.float64) + return _dtypes_list + + if __name__ == "__main__": test_repetition = 5 - for test_type in [numpy.float64, numpy.float32, numpy.int64, numpy.int32]: + for test_type in get_dtypes(): type_name = numpy.dtype(test_type).name print( f"...Test data type is {test_type}, each test repetitions {test_repetition}" ) - for size in [16, 32, 64, 128, 256, 512, 1024, 2048, 4096]: + for size in [256, 512, 1024, 2048, 4096, 8192]: time_python, result_python = run_function( numpy, "", size, test_type, test_repetition ) @@ -90,6 +89,6 @@ def run_function(executor, name, size, test_type, repetition): else: verification = f"({result_mkl} != {result_python})" - msg = f"type:{type_name}:N:{size:4}:NumPy:{time_python:.3e}:SYCL:{time_mkl:.3e}" + msg = f"type:{type_name}:N:{size:4}:NumPy:{time_python:.3e}:DPNP:{time_mkl:.3e}" msg += f":ratio:{time_python/time_mkl:6.2f}:verification:{verification}" print(msg) diff --git a/examples/example_bs.py b/examples/example_bs.py index db920c07ab3..488f495303f 100644 --- a/examples/example_bs.py +++ b/examples/example_bs.py @@ -32,20 +32,10 @@ """ -try: - import dpnp as np -except ImportError: - import os - import sys - - root_dir = os.path.join(os.path.dirname(__file__), os.pardir) - sys.path.append(root_dir) - - import dpnp as np - +import dpnp as np SIZE = 2**8 -DTYPE = np.float64 +DTYPE = np.default_float_type() SEED = 7777777 PL, PH = 10.0, 50.0 diff --git a/examples/example_cfd.py b/examples/example_cfd.py new file mode 100644 index 00000000000..db309065759 --- /dev/null +++ b/examples/example_cfd.py @@ -0,0 +1,48 @@ +# cython: language_level=3 +# -*- coding: utf-8 -*- +# ***************************************************************************** +# Copyright (c) 2023, Intel Corporation +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# - Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# - Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# ***************************************************************************** + +"""Example CFD. + +This example shows how DPNP follows compute follows data paradigm + +""" + +import dpnp as np + +x = np.empty(3) +try: + x = np.asarray([1, 2, 3], device="gpu") +except Exception: + print("GPU device is not available") + +print("Array x allocated on the device:", x.device) + +y = np.sum(x) + +print("Result y is located on the device:", y.device) # The same device as x +print("Shape of y is:", y.shape) # 0-dimensional array +print("y=", y) # Expect 6 diff --git a/examples/example_sum.py b/examples/example_sum.py new file mode 100644 index 00000000000..478194ccbe3 --- /dev/null +++ b/examples/example_sum.py @@ -0,0 +1,44 @@ +# cython: language_level=3 +# -*- coding: utf-8 -*- +# ***************************************************************************** +# Copyright (c) 2023, Intel Corporation +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# - Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# - Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# ***************************************************************************** + +"""Example sum. + +This example shows simple usage of the DPNP +to calculate sum of an array + +""" + +import dpnp as np + +x = np.asarray([1, 2, 3]) +print("Array x allocated on the device:", x.device) + +y = np.sum(x) + +print("Result y is located on the device:", y.device) # The same device as x +print("Shape of y is:", y.shape) # 0-dimensional array +print("y =", y) # Expect 6