diff --git a/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/IntelPython_GPU_numba-dpex_Genetic_Algorithm.ipynb b/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/IntelPython_GPU_dpnp_Genetic_Algorithm.ipynb similarity index 88% rename from AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/IntelPython_GPU_numba-dpex_Genetic_Algorithm.ipynb rename to AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/IntelPython_GPU_dpnp_Genetic_Algorithm.ipynb index adc897a9ba..016f076fee 100644 --- a/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/IntelPython_GPU_numba-dpex_Genetic_Algorithm.ipynb +++ b/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/IntelPython_GPU_dpnp_Genetic_Algorithm.ipynb @@ -17,9 +17,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Genetic Algorithms on GPU using Intel Distribution of Python numba-dpex\n", + "# Genetic Algorithms on GPU using Intel Distribution of Python \n", "\n", - "This code sample shows how to implement a basic genetic algorithm with Data Parallel Python using numba-dpex.\n", + "This code sample shows how to implement a basic genetic algorithm with Data Parallel Python using Data Parallel Extension of NumPy.\n", "\n", "## Genetic algorithms\n", "\n", @@ -98,7 +98,7 @@ "\n", "### Simple evaluation method\n", "\n", - "We are starting with a simple genome evaluation function. This will be our baseline and comparison for numba-dpex.\n", + "We are starting with a simple genome evaluation function. This will be our baseline and comparison for dpnp.\n", "In this example, the fitness of an individual is computed by an arbitrary set of algebraic operations on the chromosome." ] }, @@ -317,9 +317,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## GPU execution using numba-dpex\n", + "## GPU execution using dpnp\n", "\n", - "We need to start with new population initialization, as we want to perform the same operations but now on GPU using numba-dpex implementation.\n", + "We need to start with new population initialization, as we want to perform the same operations but now on GPU using dpnpx implementation.\n", "\n", "We are setting random seed the same as before to reproduce the results. " ] @@ -344,11 +344,11 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Evaluation function using numba-dpex\n", + "### Evaluation function using Data Parallel Extension for NumPy\n", "\n", - "The only par that differs form the standard implementation is the evaluation function.\n", + "The only part that differs form the standard implementation is the evaluation function.\n", "\n", - "The most important part is to specify the index of the computation. This is the current index of the computed chromosomes. This serves as a loop function across all chromosomes." + "In this implementation we are taking benefit from vectorized operations. DPNP will automatically vectorize addition, substraction, multiplication operations, making them efficient and suitable for GPU acceleration." ] }, { @@ -364,31 +364,28 @@ }, "outputs": [], "source": [ - "import numba_dpex\n", - "from numba_dpex import kernel_api\n", + "import dpnp as dpnp\n", "\n", - "@numba_dpex.kernel\n", - "def eval_genomes_sycl_kernel(item: kernel_api.Item, chromosomes, fitnesses, chrom_length):\n", - " pos = item.get_id(0)\n", + "def eval_genomes_dpnp(chromosomes_list, fitnesses):\n", " num_loops = 3000\n", - " for i in range(num_loops):\n", - " fitnesses[pos] += chromosomes[pos*chrom_length + 1]\n", - " for i in range(num_loops):\n", - " fitnesses[pos] -= chromosomes[pos*chrom_length + 2]\n", - " for i in range(num_loops):\n", - " fitnesses[pos] += chromosomes[pos*chrom_length + 3]\n", "\n", - " if (fitnesses[pos] < 0):\n", - " fitnesses[pos] = 0" + " # Calculate fitnesses using vectorized operations\n", + " fitnesses += chromosomes_list[:, 1] * num_loops\n", + " fitnesses -= chromosomes_list[:, 2] * num_loops\n", + " fitnesses += chromosomes_list[:, 3] * num_loops\n", + "\n", + " # Clip negative fitness values to zero\n", + " fitnesses = np.where(fitnesses < 0, 0, fitnesses)\n", + " return fitnesses" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Now, we can measure the time to perform some generations of the Genetic Algorithm with Data Parallel Python Numba dpex. \n", + "Now, we can measure the time to perform some generations of the Genetic Algorithm with Data Parallel Python Extension for NumPy. \n", "\n", - "Similarly like before, the time of the evaluation, creation of new generation and fitness wipe are measured for GPU execution. But first, we need to send all the chromosomes and fitnesses container to the chosen device. " + "Similarly like before, the time of the evaluation, creation of new generation and fitness wipe are measured for GPU execution. But first, we need to send all the chromosomes and fitnesses container to the chosen device - GPU. " ] }, { @@ -399,25 +396,26 @@ }, "outputs": [], "source": [ - "import dpnp\n", - "\n", "print(\"SYCL:\")\n", "start = time.time()\n", "\n", "# Genetic Algorithm on GPU\n", "for i in range(num_generations):\n", " print(\"Gen \" + str(i+1) + \"/\" + str(num_generations))\n", - " chromosomes_flat = chromosomes.flatten()\n", - " chromosomes_flat_dpctl = dpnp.asarray(chromosomes_flat, device=\"gpu\")\n", - " fitnesses_dpctl = dpnp.asarray(fitnesses, device=\"gpu\")\n", + " chromosomes_dpctl = chromosomes\n", + " fitnesses_dpctl = fitnesses\n", + " try:\n", + " chromosomes_dpctl = dpnp.asarray(chromosomes, device=\"gpu\")\n", + " fitnesses_dpctl = dpnp.asarray(fitnesses, device=\"gpu\")\n", + " except Exception:\n", + " print(\"GPU device is not available\")\n", + " \n", + " fitnesses = eval_genomes_dpnp(chromosomes, fitnesses)\n", " \n", - " exec_range = kernel_api.Range(pop_size)\n", - " numba_dpex.call_kernel(eval_genomes_sycl_kernel, exec_range, chromosomes_flat_dpctl, fitnesses_dpctl, chrom_size)\n", " fitnesses = dpnp.asnumpy(fitnesses_dpctl)\n", " chromosomes = next_generation(chromosomes, fitnesses)\n", " fitnesses = np.zeros(pop_size, dtype=np.float32)\n", "\n", - "\n", "end = time.time()\n", "time_sycl = end-start\n", "print(\"time elapsed: \" + str((time_sycl)))\n", @@ -457,7 +455,7 @@ "\n", "plt.figure()\n", "plt.title(\"Time comparison\")\n", - "plt.bar([\"Numba_dpex\", \"without optimization\"], [time_sycl, time_cpu])\n", + "plt.bar([\"DPNP\", \"without optimization\"], [time_sycl, time_cpu])\n", "\n", "plt.show()" ] @@ -546,7 +544,7 @@ "\n", "The evaluate created generation we are calculating the full distance of the given path (chromosome). In this example, the lower the fitness value is, the better the chromosome. That's different from the general GA that we implemented.\n", "\n", - "As in this example we are also using numba-dpex, we are using an index like before." + "As in the previous example dpnp will vectorize basic mathematical operations to take benefit from optimizations." ] }, { @@ -555,11 +553,11 @@ "metadata": {}, "outputs": [], "source": [ - "@numba_dpex.kernel\n", - "def eval_genomes_plain_TSP_SYCL(item: kernel_api.Item, chromosomes, fitnesses, distances, pop_length):\n", - " pos = item.get_id(1)\n", - " for j in range(pop_length-1):\n", - " fitnesses[pos] += distances[int(chromosomes[pos, j]), int(chromosomes[pos, j+1])]\n" + "def eval_genomes_plain_TSP_SYCL(chromosomes, fitnesses, distances, pop_length):\n", + " for pos in range(pop_length):\n", + " for j in range(chromosomes.shape[1]-1):\n", + " fitnesses[pos] += distances[int(chromosomes[pos, j]), int(chromosomes[pos, j+1])]\n", + " return fitnesses\n" ] }, { @@ -703,22 +701,26 @@ "source": [ "print(\"Traveling Salesman Problem:\")\n", "\n", - "distances_dpctl = dpnp.asarray(distances, device=\"gpu\")\n", + "distances_dpnp = distances\n", + "try:\n", + " distances_dpnp = dpnp.asarray(distances, device=\"gpu\")\n", + "except Exception:\n", + " print(\"GPU device is not available\")\n", + "\n", "# Genetic Algorithm on GPU\n", "for i in range(num_generations):\n", " print(\"Gen \" + str(i+1) + \"/\" + str(num_generations))\n", - " chromosomes_flat_dpctl = dpnp.asarray(chromosomes, device=\"gpu\")\n", - " fitnesses_dpctl = dpnp.asarray(fitnesses.copy(), device=\"gpu\")\n", "\n", - " exec_range = kernel_api.Range(pop_size)\n", - " numba_dpex.call_kernel(eval_genomes_plain_TSP_SYCL, exec_range, chromosomes_flat_dpctl, fitnesses_dpctl, distances_dpctl, pop_size)\n", - " fitnesses = dpnp.asnumpy(fitnesses_dpctl)\n", - " chromosomes = next_generation_TSP(chromosomes, fitnesses)\n", + " chromosomes_dpnp = chromosomes\n", + " try:\n", + " chromosomes_dpnp = dpnp.asarray(chromosomes, device=\"gpu\")\n", + " except Exception:\n", + " print(\"GPU device is not available\")\n", + "\n", " fitnesses = np.zeros(pop_size, dtype=np.float32)\n", "\n", - "for i in range(len(chromosomes)):\n", - " for j in range(11):\n", - " fitnesses[i] += distances[int(chromosomes[i][j])][int(chromosomes[i][j+1])]\n", + " fitnesses = eval_genomes_plain_TSP_SYCL(chromosomes_dpnp, fitnesses, distances_dpnp, pop_size)\n", + " chromosomes = next_generation_TSP(chromosomes, fitnesses)\n", "\n", "fitness_pairs = []\n", "\n", @@ -736,7 +738,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "In this code sample, there was a general purpose Genetic Algorithm created and optimized using numba-dpex to run on GPU. Then the same approach was applied to the Traveling Salesman Problem." + "In this code sample, there was a general purpose Genetic Algorithm created and optimized using dpnp to run on GPU. Then the same approach was applied to the Traveling Salesman Problem." ] }, { @@ -756,7 +758,7 @@ "provenance": [] }, "kernelspec": { - "display_name": "base", + "display_name": "Base", "language": "python", "name": "base" }, @@ -770,7 +772,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.18" + "version": "3.9.19" } }, "nbformat": 4, diff --git a/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/IntelPython_GPU_numba-dpex_Genetic_Algorithm.py b/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/IntelPython_GPU_dpnp_Genetic_Algorithm.py similarity index 86% rename from AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/IntelPython_GPU_numba-dpex_Genetic_Algorithm.py rename to AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/IntelPython_GPU_dpnp_Genetic_Algorithm.py index c33bb2e1c1..6cde827960 100644 --- a/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/IntelPython_GPU_numba-dpex_Genetic_Algorithm.py +++ b/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/IntelPython_GPU_dpnp_Genetic_Algorithm.py @@ -11,9 +11,9 @@ # ============================================================= -# # Genetic Algorithms on GPU using Intel Distribution of Python numba-dpex +# # Genetic Algorithms on GPU using Intel Distribution of Python # -# This code sample shows how to implement a basic genetic algorithm with Data Parallel Python using numba-dpex. +# This code sample shows how to implement a basic genetic algorithm with Data Parallel Python using Data Parallel Extension of NumPy. # # ## Genetic algorithms # @@ -67,7 +67,7 @@ # # ### Simple evaluation method # -# We are starting with a simple genome evaluation function. This will be our baseline and comparison for numba-dpex. +# We are starting with a simple genome evaluation function. This will be our baseline and comparison for dpnp. # In this example, the fitness of an individual is computed by an arbitrary set of algebraic operations on the chromosome. # In[ ]: @@ -150,7 +150,6 @@ def mutation(child_sequence, chance=0.01): # It allows fitness proportional selection - the bigger the fitness value, the bigger the chance that a given chromosome will be selected. # # The result of all the operations is returned as chromosomes. -# # In[ ]: @@ -239,9 +238,9 @@ def next_generation(chromosomes, fitnesses): print("First chromosome: " + str(chromosomes[0])) -# ## GPU execution using numba-dpex +# ## GPU execution using dpnp # -# We need to start with new population initialization, as we want to perform the same operations but now on GPU using numba-dpex implementation. +# We need to start with new population initialization, as we want to perform the same operations but now on GPU using dpnpx implementation. # # We are setting random seed the same as before to reproduce the results. @@ -256,58 +255,57 @@ def next_generation(chromosomes, fitnesses): chromosomes[i][j] = random.uniform(0,1) -# ### Evaluation function using numba-dpex +# ### Evaluation function using Data Parallel Extension for NumPy # -# The only par that differs form the standard implementation is the evaluation function. +# The only part that differs form the standard implementation is the evaluation function. # -# The most important part is to specify the index of the computation. This is the current index of the computed chromosomes. This serves as a loop function across all chromosomes. +# In this implementation we are taking benefit from vectorized operations. DPNP will automatically vectorize addition, substraction, multiplication operations, making them efficient and suitable for GPU acceleration. # In[ ]: -import numba_dpex -from numba_dpex import kernel_api +import dpnp as dpnp -@numba_dpex.kernel -def eval_genomes_sycl_kernel(item: kernel_api.Item, chromosomes, fitnesses, chrom_length): - pos = item.get_id(0) +def eval_genomes_dpnp(chromosomes_list, fitnesses): num_loops = 3000 - for i in range(num_loops): - fitnesses[pos] += chromosomes[pos*chrom_length + 1] - for i in range(num_loops): - fitnesses[pos] -= chromosomes[pos*chrom_length + 2] - for i in range(num_loops): - fitnesses[pos] += chromosomes[pos*chrom_length + 3] - if (fitnesses[pos] < 0): - fitnesses[pos] = 0 + # Calculate fitnesses using vectorized operations + fitnesses += chromosomes_list[:, 1] * num_loops + fitnesses -= chromosomes_list[:, 2] * num_loops + fitnesses += chromosomes_list[:, 3] * num_loops + + # Clip negative fitness values to zero + fitnesses = np.where(fitnesses < 0, 0, fitnesses) + return fitnesses -# Now, we can measure the time to perform some generations of the Genetic Algorithm with Data Parallel Python Numba dpex. + +# Now, we can measure the time to perform some generations of the Genetic Algorithm with Data Parallel Python Extension for NumPy. # -# Similarly like before, the time of the evaluation, creation of new generation and fitness wipe are measured for GPU execution. But first, we need to send all the chromosomes and fitnesses container to the chosen device. +# Similarly like before, the time of the evaluation, creation of new generation and fitness wipe are measured for GPU execution. But first, we need to send all the chromosomes and fitnesses container to the chosen device - GPU. # In[ ]: -import dpnp - print("SYCL:") start = time.time() # Genetic Algorithm on GPU for i in range(num_generations): print("Gen " + str(i+1) + "/" + str(num_generations)) - chromosomes_flat = chromosomes.flatten() - chromosomes_flat_dpctl = dpnp.asarray(chromosomes_flat, device="gpu") - fitnesses_dpctl = dpnp.asarray(fitnesses, device="gpu") - - exec_range = kernel_api.Range(pop_size) - numba_dpex.call_kernel(eval_genomes_sycl_kernel, exec_range, chromosomes_flat_dpctl, fitnesses_dpctl, chrom_size) + chromosomes_dpctl = chromosomes + fitnesses_dpctl = fitnesses + try: + chromosomes_dpctl = dpnp.asarray(chromosomes, device="gpu") + fitnesses_dpctl = dpnp.asarray(fitnesses, device="gpu") + except Exception: + print("GPU device is not available") + + fitnesses = eval_genomes_dpnp(chromosomes, fitnesses) + fitnesses = dpnp.asnumpy(fitnesses_dpctl) chromosomes = next_generation(chromosomes, fitnesses) fitnesses = np.zeros(pop_size, dtype=np.float32) - end = time.time() time_sycl = end-start print("time elapsed: " + str((time_sycl))) @@ -331,7 +329,7 @@ def eval_genomes_sycl_kernel(item: kernel_api.Item, chromosomes, fitnesses, chro plt.figure() plt.title("Time comparison") -plt.bar(["Numba_dpex", "without optimization"], [time_sycl, time_cpu]) +plt.bar(["DPNP", "without optimization"], [time_sycl, time_cpu]) plt.show() @@ -400,16 +398,16 @@ def eval_genomes_sycl_kernel(item: kernel_api.Item, chromosomes, fitnesses, chro # # The evaluate created generation we are calculating the full distance of the given path (chromosome). In this example, the lower the fitness value is, the better the chromosome. That's different from the general GA that we implemented. # -# As in this example we are also using numba-dpex, we are using an index like before. +# As in the previous example dpnp will vectorize basic mathematical operations to take benefit from optimizations. # In[ ]: -@numba_dpex.kernel -def eval_genomes_plain_TSP_SYCL(item: kernel_api.Item, chromosomes, fitnesses, distances, pop_length): - pos = item.get_id(1) - for j in range(pop_length-1): - fitnesses[pos] += distances[int(chromosomes[pos, j]), int(chromosomes[pos, j+1])] +def eval_genomes_plain_TSP_SYCL(chromosomes, fitnesses, distances, pop_length): + for pos in range(pop_length): + for j in range(chromosomes.shape[1]-1): + fitnesses[pos] += distances[int(chromosomes[pos, j]), int(chromosomes[pos, j+1])] + return fitnesses # ### Crossover @@ -521,22 +519,26 @@ def next_generation_TSP(chromosomes, fitnesses): print("Traveling Salesman Problem:") -distances_dpctl = dpnp.asarray(distances, device="gpu") +distances_dpnp = distances +try: + distances_dpnp = dpnp.asarray(distances, device="gpu") +except Exception: + print("GPU device is not available") + # Genetic Algorithm on GPU for i in range(num_generations): print("Gen " + str(i+1) + "/" + str(num_generations)) - chromosomes_flat_dpctl = dpnp.asarray(chromosomes, device="gpu") - fitnesses_dpctl = dpnp.asarray(fitnesses.copy(), device="gpu") - exec_range = kernel_api.Range(pop_size) - numba_dpex.call_kernel(eval_genomes_plain_TSP_SYCL, exec_range, chromosomes_flat_dpctl, fitnesses_dpctl, distances_dpctl, pop_size) - fitnesses = dpnp.asnumpy(fitnesses_dpctl) - chromosomes = next_generation_TSP(chromosomes, fitnesses) + chromosomes_dpnp = chromosomes + try: + chromosomes_dpnp = dpnp.asarray(chromosomes, device="gpu") + except Exception: + print("GPU device is not available") + fitnesses = np.zeros(pop_size, dtype=np.float32) -for i in range(len(chromosomes)): - for j in range(11): - fitnesses[i] += distances[int(chromosomes[i][j])][int(chromosomes[i][j+1])] + fitnesses = eval_genomes_plain_TSP_SYCL(chromosomes_dpnp, fitnesses, distances_dpnp, pop_size) + chromosomes = next_generation_TSP(chromosomes, fitnesses) fitness_pairs = [] @@ -550,9 +552,10 @@ def next_generation_TSP(chromosomes, fitnesses): print("Worst path: ", sorted_pairs[-1][0], " distance: ", sorted_pairs[-1][1]) -# In this code sample, there was a general purpose Genetic Algorithm created and optimized using numba-dpex to run on GPU. Then the same approach was applied to the Traveling Salesman Problem. +# In this code sample, there was a general purpose Genetic Algorithm created and optimized using dpnp to run on GPU. Then the same approach was applied to the Traveling Salesman Problem. # In[ ]: print("[CODE_SAMPLE_COMPLETED_SUCCESFULLY]") + diff --git a/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/License.txt b/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/License.txt similarity index 100% rename from AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/License.txt rename to AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/License.txt diff --git a/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/README.md b/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/README.md similarity index 82% rename from AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/README.md rename to AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/README.md index 3c7c97d4ee..55fb54864e 100644 --- a/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/README.md +++ b/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/README.md @@ -1,18 +1,18 @@ -# `Genetic Algorithms on GPU using Intel® Distribution for Python* numba-dpex` Sample +# `Genetic Algorithms on GPU using Intel® Distribution for Python* dpnp` Sample -The `Genetic Algorithms on GPU using Intel® Distribution for Python* numba-dpex` sample shows how to implement a general genetic algorithm (GA) and offload computation to a GPU using numba-dpex. +The `Genetic Algorithms on GPU using Intel® Distribution for Python* dpnp` sample shows how to implement a general genetic algorithm (GA) and offload computation to a GPU using dpnp. | Property | Description | :--- | :--- | Category | Code Optimization -| What you will learn | How to implement the genetic algorithm using the Data-parallel Extension for Numba* (numba-dpex)? +| What you will learn | How to implement the genetic algorithm using the Data-parallel Extension for NumPy* (dpnp)? | Time to complete | 8 minutes >**Note**: This sample is validated on Intel® Distribution for Python* Offline Installer and AI Tools Offline Installer. For the full list of validated platforms refer to [Platform Validation](https://github.com/oneapi-src/oneAPI-samples/tree/master?tab=readme-ov-file#platform-validation). ## Purpose -In this sample, you will create and run the general genetic algorithm and optimize it to run on GPU using the Intel® Distribution for Python* numba-dpex. You will learn what are selection, crossover, and mutation, and how to adjust those methods from general genetic algorithm to a specific optimization problem which is the Traveling Salesman Problem. +In this sample, you will create and run the general genetic algorithm and optimize it to run on GPU using the Intel® Distribution for Python* dpnp. You will learn what are selection, crossover, and mutation, and how to adjust those methods from general genetic algorithm to a specific optimization problem which is the Traveling Salesman Problem. ## Prerequisites @@ -24,7 +24,7 @@ In this sample, you will create and run the general genetic algorithm and optimi ## Key Implementation Details -This sample code is implemented for GPUs using Python. The sample assumes you have numba-dpex installed inside a Conda environment, similar to what is installed with the Intel® Distribution for Python*. +This sample code is implemented for GPUs using Python. The sample assumes you have dpnp installed inside a Conda environment, similar to what is installed with the Intel® Distribution for Python*. The sample tutorial contains one Jupyter Notebook and one Python script. You can use either. @@ -53,7 +53,7 @@ cd oneAPI-samples/AI-and-Analytics// - ``` git clone https://github.com/oneapi-src/oneAPI-samples.git -cd oneAPI-samples/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm +cd oneAPI-samples/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm ``` **4. Install dependencies** @@ -67,7 +67,7 @@ pip install notebook For Jupyter Notebook, refer to [Installing Jupyter](https://jupyter.org/install) for detailed installation instructions. ## Run the Sample ->**Note**: Before running the sample, make sure [Environment Setup](https://github.com/oneapi-src/oneAPI-samples/tree/master/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm#environment-setup) is completed. +>**Note**: Before running the sample, make sure [Environment Setup](https://github.com/oneapi-src/oneAPI-samples/tree/master/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm#environment-setup) is completed. ### Intel® Distribution for Python* Offline Installer (Validated) @@ -91,7 +91,7 @@ jupyter notebook --ip=0.0.0.0 **4. Select the Notebook** ``` -IntelPython_GPU_numba-dpex_Genetic_Algorithm.ipynb +IntelPython_GPU_dpnp_Genetic_Algorithm.ipynb ``` **5. Change the kernel to `base`** @@ -99,7 +99,7 @@ IntelPython_GPU_numba-dpex_Genetic_Algorithm.ipynb ## Example Output -If successful, the sample displays `[CODE_SAMPLE_COMPLETED_SUCCESSFULLY]` at the end of execution. The sample will print out the runtimes and charts of relative performance with numba-dpex and without any optimizations as the baseline. Additionally, sample will print the best and worst path found in the Traveling Salesman Problem. +If successful, the sample displays `[CODE_SAMPLE_COMPLETED_SUCCESSFULLY]` at the end of execution. The sample will print out the runtimes and charts of relative performance with dpnp and without any optimizations as the baseline. Additionally, sample will print the best and worst path found in the Traveling Salesman Problem. ## Related Samples diff --git a/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/assets/crossover.png b/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/assets/crossover.png similarity index 100% rename from AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/assets/crossover.png rename to AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/assets/crossover.png diff --git a/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/assets/mutation.png b/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/assets/mutation.png similarity index 100% rename from AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/assets/mutation.png rename to AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/assets/mutation.png diff --git a/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/assets/selection.png b/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/assets/selection.png similarity index 100% rename from AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/assets/selection.png rename to AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/assets/selection.png diff --git a/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/requirements.txt b/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/requirements.txt similarity index 100% rename from AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/requirements.txt rename to AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/requirements.txt diff --git a/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/sample.json b/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/sample.json similarity index 76% rename from AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/sample.json rename to AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/sample.json index 4ad8027821..4d2dead081 100644 --- a/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/sample.json +++ b/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/sample.json @@ -1,8 +1,8 @@ { "guid": "DB33884A-2DDE-4657-9F95-E6E573403F61", - "name": "Genetic Algorithms on GPU using Intel® Distribution of Python numba-dpex", + "name": "Genetic Algorithms on GPU using Intel® Distribution of Python dpnp", "categories": ["Toolkit/oneAPI AI And Analytics/Getting Started"], - "description": "This sample shows how to implement general genetic algorithm (GA) and offload computation to GPU using numba-dpex.", + "description": "This sample shows how to implement general genetic algorithm (GA) and offload computation to GPU using dpnp.", "builder": ["cli"], "languages": [{"python":{}}], "dependencies": ["intelpython"], @@ -16,9 +16,9 @@ "conda activate base", "pip install -r requirements.txt" ], - "id": "idp_ga_numba_dpex_py", + "id": "idp_ga_dpnp_py", "steps": [ - "python IntelPython_GPU_numba-dpex_Genetic_Algorithm.py" + "python IntelPython_GPU_dpnp_Genetic_Algorithm.py" ] } ] diff --git a/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/third-party-programs.txt b/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/third-party-programs.txt similarity index 100% rename from AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/third-party-programs.txt rename to AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/third-party-programs.txt diff --git a/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpex_kNN/IntelPython_Numpy_Numba_dpex_kNN.ipynb b/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpnp_kNN/IntelPython_Numpy_Numba_dpnp_kNN.ipynb similarity index 71% rename from AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpex_kNN/IntelPython_Numpy_Numba_dpex_kNN.ipynb rename to AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpnp_kNN/IntelPython_Numpy_Numba_dpnp_kNN.ipynb index 47a10db05b..37fb4c58c8 100644 --- a/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpex_kNN/IntelPython_Numpy_Numba_dpex_kNN.ipynb +++ b/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpnp_kNN/IntelPython_Numpy_Numba_dpnp_kNN.ipynb @@ -17,7 +17,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Simple k-NN classification with numba_dpex IDP optimization\n", + "# Simple k-NN classification with Data Parallel Extension for NumPy IDP optimization\n", "\n", "This sample shows how to receive the same accuracy of the k-NN model classification by using numpy, numba and numba_dpex. The computation are performed using wine dataset.\n", "\n", @@ -276,7 +276,7 @@ " counter = {}\n", " for item in neighbor_classes:\n", " if item in counter:\n", - " counter[item] = counter.get(item) + 1\n", + " counter[item] += 1\n", " else:\n", " counter[item] = 1\n", " counter_sorted = sorted(counter)\n", @@ -312,13 +312,11 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Numba_dpex k-NN\n", + "## Data Parallel Extension for NumPy k-NN\n", "\n", - "Numba_dpex implementation use `numba_dpex.kernel()` decorator. For more information about programming, SYCL kernels go to: https://intelpython.github.io/numba-dpex/latest/user_guides/kernel_programming_guide/index.html.\n", + "To take benefit of DPNP, we can leverage its vectorized operations and efficient algorithms to implement a k-NN algorithm. We will use optimized operations like `sum`, `sqrt` or `argsort`.\n", "\n", - "Calculating distance is like in the NumPy example. We are using Euclidean distance. Later, we create the queue of the neighbors by the calculated distance and count in provided *k* votes for dedicated classes of neighbors.\n", - "\n", - "In the end, we are taking a class that achieves the maximum value of votes and setting it for the current global iteration." + "Calculating distance is like in the NumPy example. We are using Euclidean distance. The next step is to find the indexes of k-nearest neighbours for each test poin, and get tehir labels. At the end, we neet to determine the most frequent label among k-nearest." ] }, { @@ -327,87 +325,23 @@ "metadata": {}, "outputs": [], "source": [ - "import numba_dpex\n", - "\n", - "@numba_dpex.kernel\n", - "def knn_numba_dpex(\n", - " item: numba_dpex.kernel_api.Item,\n", - " train,\n", - " train_labels,\n", - " test,\n", - " k,\n", - " predictions,\n", - " votes_to_classes_lst,\n", - "):\n", - " dtype = train.dtype\n", - " i = item.get_id(0)\n", - " queue_neighbors = numba_dpex.kernel_api.PrivateArray(shape=(3, 2), dtype=dtype)\n", - "\n", - " for j in range(k):\n", - " x1 = train[j, 0]\n", - " x2 = test[i, 0]\n", - "\n", - " distance = dtype.type(0.0)\n", - " diff = x1 - x2\n", - " distance += diff * diff\n", - " dist = math.sqrt(distance)\n", - "\n", - " queue_neighbors[j, 0] = dist\n", - " queue_neighbors[j, 1] = train_labels[j]\n", - "\n", - " for j in range(k):\n", - " new_distance = queue_neighbors[j, 0]\n", - " new_neighbor_label = queue_neighbors[j, 1]\n", - " index = j\n", - "\n", - " while index > 0 and new_distance < queue_neighbors[index - 1, 0]:\n", - " queue_neighbors[index, 0] = queue_neighbors[index - 1, 0]\n", - " queue_neighbors[index, 1] = queue_neighbors[index - 1, 1]\n", - "\n", - " index = index - 1\n", - "\n", - " queue_neighbors[index, 0] = new_distance\n", - " queue_neighbors[index, 1] = new_neighbor_label\n", - "\n", - " for j in range(k, len(train)):\n", - " x1 = train[j, 0]\n", - " x2 = test[i, 0]\n", - "\n", - " distance = dtype.type(0.0)\n", - " diff = x1 - x2\n", - " distance += diff * diff\n", - " dist = math.sqrt(distance)\n", - "\n", - " if dist < queue_neighbors[k - 1, 0]:\n", - " queue_neighbors[k - 1, 0] = dist\n", - " queue_neighbors[k - 1, 1] = train_labels[j]\n", - " new_distance = queue_neighbors[k - 1, 0]\n", - " new_neighbor_label = queue_neighbors[k - 1, 1]\n", - " index = k - 1\n", - "\n", - " while index > 0 and new_distance < queue_neighbors[index - 1, 0]:\n", - " queue_neighbors[index, 0] = queue_neighbors[index - 1, 0]\n", - " queue_neighbors[index, 1] = queue_neighbors[index - 1, 1]\n", - "\n", - " index = index - 1\n", - "\n", - " queue_neighbors[index, 0] = new_distance\n", - " queue_neighbors[index, 1] = new_neighbor_label\n", - "\n", - " votes_to_classes = votes_to_classes_lst[i]\n", - "\n", - " for j in range(len(queue_neighbors)):\n", - " votes_to_classes[int(queue_neighbors[j, 1])] += 1\n", - "\n", - " max_ind = 0\n", - " max_value = dtype.type(0)\n", - "\n", - " for j in range(3):\n", - " if votes_to_classes[j] > max_value:\n", - " max_value = votes_to_classes[j]\n", - " max_ind = j\n", - "\n", - " predictions[i] = max_ind" + "import dpnp as dpnp\n", + "\n", + "def knn_dpnp(train, train_labels, test, k):\n", + " # 1. Calculate pairwise distances between test and train points\n", + " distances = dpnp.sqrt(dpnp.sum((test[:, None, :] - train[None, :, :])**2, axis=-1))\n", + "\n", + " # 2. Find the indices of the k nearest neighbors for each test point\n", + " nearest_neighbors = dpnp.argsort(distances, axis=1)[:, :k]\n", + "\n", + " # 3. Get the labels of the nearest neighbors\n", + " nearest_labels = train_labels[nearest_neighbors]\n", + "\n", + " # 4. Determine the most frequent label among the k nearest neighbors\n", + " unique_labels, counts = np.unique(nearest_labels, return_counts=True)\n", + " predicted_labels = nearest_labels[np.argmax(counts)]\n", + "\n", + " return predicted_labels" ] }, { @@ -416,9 +350,7 @@ "source": [ "Next, like before, let's test the prepared k-NN function.\n", "\n", - "In this case, we will need to provide the container for predictions: `predictions` and the container for votes per class: `votes_to_classes_lst` (the container size is 3, as we have 3 classes in our dataset).\n", - "\n", - "We are running a prepared k-NN function on a CPU device as the input data was allocated on the CPU. Numba-dpex will infer the execution queue based on where the input arguments to the kernel were allocated. Refer: https://intelpython.github.io/oneAPI-for-SciPy/details/programming_model/#compute-follows-data" + "We are running a prepared k-NN function on a CPU device as the input data was allocated on the CPU using DPNP." ] }, { @@ -427,26 +359,11 @@ "metadata": {}, "outputs": [], "source": [ - "import dpnp\n", - "\n", - "predictions = dpnp.empty(len(X_test.values), device=\"cpu\")\n", - "# we have 3 classes\n", - "votes_to_classes_lst = dpnp.zeros((len(X_test.values), 3), device=\"cpu\")\n", - "\n", "X_train_dpt = dpnp.asarray(X_train.values, device=\"cpu\")\n", "y_train_dpt = dpnp.asarray(y_train.values, device=\"cpu\")\n", "X_test_dpt = dpnp.asarray(X_test.values, device=\"cpu\")\n", "\n", - "numba_dpex.call_kernel(\n", - " knn_numba_dpex,\n", - " numba_dpex.Range(len(X_test.values)),\n", - " X_train_dpt,\n", - " y_train_dpt,\n", - " X_test_dpt,\n", - " 3,\n", - " predictions,\n", - " votes_to_classes_lst,\n", - ")" + "pred = knn_dpnp(X_train_dpt, y_train_dpt, X_test_dpt, 3)" ] }, { @@ -465,7 +382,7 @@ "predictions_numba = dpnp.asnumpy(predictions)\n", "true_values = y_test.to_numpy()\n", "accuracy = np.mean(predictions_numba == true_values)\n", - "print(\"Numba_dpex accuracy:\", accuracy)" + "print(\"Data Parallel Extension for NumPy accuracy:\", accuracy)" ] }, { @@ -480,9 +397,9 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (Intel® oneAPI 2022.3)", + "display_name": "Base", "language": "python", - "name": "c009-intel_distribution_of_python_3_oneapi-beta05-python" + "name": "base" }, "language_info": { "codemirror_mode": { @@ -494,7 +411,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.13" + "version": "3.9.19" }, "vscode": { "interpreter": { diff --git a/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpex_kNN/IntelPython_Numpy_Numba_dpex_kNN.py b/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpnp_kNN/IntelPython_Numpy_Numba_dpnp_kNN.py similarity index 100% rename from AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpex_kNN/IntelPython_Numpy_Numba_dpex_kNN.py rename to AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpnp_kNN/IntelPython_Numpy_Numba_dpnp_kNN.py diff --git a/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpex_kNN/License.txt b/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpnp_kNN/License.txt similarity index 100% rename from AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpex_kNN/License.txt rename to AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpnp_kNN/License.txt diff --git a/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpex_kNN/README.md b/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpnp_kNN/README.md similarity index 86% rename from AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpex_kNN/README.md rename to AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpnp_kNN/README.md index 1e95a29ff0..dfe5b88d3d 100644 --- a/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpex_kNN/README.md +++ b/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpnp_kNN/README.md @@ -1,18 +1,18 @@ -# `Intel® Python: NumPy vs numba-dpex` Sample +# `Intel® Python: NumPy vs Numba vs DPNP` Sample -The `Intel® Python: NumPy vs numba-dpex` sample shows how to achieve the same accuracy of the k-NN model classification while using NumPy*, Numba*, and Data Parallel Extension for Numba* (numba-dpex). +The `Intel® Python: NumPy vs Numba vs DPNP` sample shows how to achieve the same accuracy of the k-NN model classification while using NumPy*, Numba*, and Data Parallel Extension for NumPy* (dpnp). | Property | Description | :--- | :--- | Category | Code Optimization -| What you will learn | How to program using the Data Parallel Extension for Numba* (numba-dpex) +| What you will learn | How to program using the Data Parallel Extension for NumPy* (dpnp) | Time to complete | 5 minutes >**Note**: This sample is validated on Intel® Distribution for Python* Offline Installer and AI Tools Offline Installer. For the full list of validated platforms refer to [Platform Validation](https://github.com/oneapi-src/oneAPI-samples/tree/master?tab=readme-ov-file#platform-validation). ## Purpose -In this sample, you will run a k-nearest neighbors algorithm using 3 different Intel® Distribution for Python* libraries: NumPy, Numba, and numba-dpex. You will learn how to use k-NN model and how to optimize it by numba-dpex operations without sacrificing accuracy. +In this sample, you will run a k-nearest neighbors algorithm using 3 different Intel® Distribution for Python* libraries: NumPy, Numba, and dpnp. You will learn how to use k-NN model and how to optimize it by dpnp operations without sacrificing accuracy. ## Prerequisites @@ -24,7 +24,7 @@ In this sample, you will run a k-nearest neighbors algorithm using 3 different I ## Key Implementation Details -This sample code is implemented for the CPU using Python. The sample assumes you have numba-dpex installed inside a Conda environment, similar to what is installed with the Intel® Distribution for Python*. +This sample code is implemented for the CPU using Python. The sample assumes you have dpnp installed inside a Conda environment, similar to what is installed with the Intel® Distribution for Python*. The sample tutorial contains one Jupyter Notebook and one Python script. You can use either. @@ -112,7 +112,7 @@ Numba_dpex accuracy 0.7222222222222222 ## Related Samples * [Get Started with the Intel® Distribution for Python*](https://www.intel.com/content/www/us/en/developer/articles/technical/get-started-with-intel-distribution-for-python.html) -* [`Genetic Algorithms on GPU using Intel® Distribution for Python* numba-dpex` Sample](https://github.com/oneapi-src/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_numba-dpex_Genetic_Algorithm/README.md) +* [`Genetic Algorithms on GPU using Intel® Distribution for Python* dpnp` Sample](https://github.com/oneapi-src/AI-and-Analytics/Features-and-Functionality/IntelPython_GPU_dpnp_Genetic_Algorithm/README.md) ## License Code samples are licensed under the MIT license. See diff --git a/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpex_kNN/sample.json b/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpnp_kNN/sample.json similarity index 76% rename from AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpex_kNN/sample.json rename to AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpnp_kNN/sample.json index 65ec27b5d8..b663ead410 100644 --- a/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpex_kNN/sample.json +++ b/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpnp_kNN/sample.json @@ -1,8 +1,8 @@ { "guid": "20ED32F3-671E-4710-A857-2821DB56CC22", - "name": "Intel® Python NumPy vs Numba_dpex", + "name": "Intel® Python NumPy vs Numba vs DPNP", "categories": ["Toolkit/oneAPI AI And Analytics/Getting Started"], - "description": "This sample shows how to achieve the same accuracy of the k-NN model classification while using numpy, numba and numba_dpex.", + "description": "This sample shows how to achieve the same accuracy of the k-NN model classification while using numpy, numba and dpnp.", "builder": ["cli"], "languages": [{"python":{}}], "dependencies": ["intelpython"], @@ -14,11 +14,11 @@ "env": [ "source /intel/oneapi/intelpython/bin/activate", "conda activate base", - "pip install pandas" + "pip install numba" ], - "id": "idp_numpy_numba_dpex_gs_py", + "id": "idp_numpy_numba_dpnp_gs_py", "steps": [ - "python IntelPython_Numpy_Numba_dpex_kNN.py" + "python IntelPython_Numpy_Numba_dpnp_kNN.py" ] } ] diff --git a/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpex_kNN/third-party-programs.txt b/AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpnp_kNN/third-party-programs.txt similarity index 100% rename from AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpex_kNN/third-party-programs.txt rename to AI-and-Analytics/Features-and-Functionality/IntelPython_Numpy_Numba_dpnp_kNN/third-party-programs.txt