|
24 | 24 | "## Genetic algorithms\n",
|
25 | 25 | "\n",
|
26 | 26 | "Let's start with the question **What is a genetic algorithm?**. It is an algorithm, search heuristic inspired by the process of natural selection. It is usually applied to various optimization problems, NP-hard problems for which finding a solution by standard methods is very time and resource consuming. This algorithm makes it possible to obtain a satisfying high quality result based on biology-inspired operations, such as:\n",
|
27 |
| - " \n", |
| 27 | + " \n", |
28 | 28 | "* selection - is the process of selecting parents who mate and recombine to create offspring for the next generation. Parent selection is very crucial to the convergence rate of the GA as good parents drive individuals to better and fitter solutions.\n",
|
29 | 29 | "* crossover - is a process similar to biological crossover. In this, more than one parent is selected and one or more offspring are produced using the genetic material of the parents.\n",
|
30 | 30 | "* mutation - small random tweak in the chromosome, to get a new solution. It is used to maintain and introduce diversity in the genetic population and is usually applied with a low probability. \n",
|
|
348 | 348 | "\n",
|
349 | 349 | "The only par that differs form the standard implementation is the evaluation function.\n",
|
350 | 350 | "\n",
|
351 |
| - "The most important part is to specify the global index of the computation. This is the current index of the computed chromosomes. This serves as a loop function across all chromosomes." |
| 351 | + "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." |
352 | 352 | ]
|
353 | 353 | },
|
354 | 354 | {
|
|
365 | 365 | "outputs": [],
|
366 | 366 | "source": [
|
367 | 367 | "import numba_dpex\n",
|
| 368 | + "from numba_dpex import kernel_api\n", |
368 | 369 | "\n",
|
369 | 370 | "@numba_dpex.kernel\n",
|
370 |
| - "def eval_genomes_sycl_kernel(chromosomes, fitnesses, chrom_length):\n", |
371 |
| - " pos = numba_dpex.get_global_id(0)\n", |
| 371 | + "def eval_genomes_sycl_kernel(item: kernel_api.Item, chromosomes, fitnesses, chrom_length):\n", |
| 372 | + " pos = item.get_id(0)\n", |
372 | 373 | " num_loops = 3000\n",
|
373 | 374 | " for i in range(num_loops):\n",
|
374 | 375 | " fitnesses[pos] += chromosomes[pos*chrom_length + 1]\n",
|
|
409 | 410 | " chromosomes_flat = chromosomes.flatten()\n",
|
410 | 411 | " chromosomes_flat_dpctl = dpnp.asarray(chromosomes_flat, device=\"gpu\")\n",
|
411 | 412 | " fitnesses_dpctl = dpnp.asarray(fitnesses, device=\"gpu\")\n",
|
412 |
| - "\n", |
413 |
| - " eval_genomes_sycl_kernel[numba_dpex.Range(pop_size)](chromosomes_flat_dpctl, fitnesses_dpctl, chrom_size)\n", |
| 413 | + " \n", |
| 414 | + " exec_range = kernel_api.Range(pop_size)\n", |
| 415 | + " numba_dpex.call_kernel(eval_genomes_sycl_kernel, exec_range, chromosomes_flat_dpctl, fitnesses_dpctl, chrom_size)\n", |
414 | 416 | " fitnesses = dpnp.asnumpy(fitnesses_dpctl)\n",
|
415 | 417 | " chromosomes = next_generation(chromosomes, fitnesses)\n",
|
416 | 418 | " fitnesses = np.zeros(pop_size, dtype=np.float32)\n",
|
|
544 | 546 | "\n",
|
545 | 547 | "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",
|
546 | 548 | "\n",
|
547 |
| - "As in this example we are also using numba-dpex, we are using a global index like before." |
| 549 | + "As in this example we are also using numba-dpex, we are using an index like before." |
548 | 550 | ]
|
549 | 551 | },
|
550 | 552 | {
|
|
554 | 556 | "outputs": [],
|
555 | 557 | "source": [
|
556 | 558 | "@numba_dpex.kernel\n",
|
557 |
| - "def eval_genomes_plain_TSP_SYCL(chromosomes, fitnesses, distances, pop_length):\n", |
558 |
| - " pos = numba_dpex.get_global_id(0)\n", |
| 559 | + "def eval_genomes_plain_TSP_SYCL(item: kernel_api.Item, chromosomes, fitnesses, distances, pop_length):\n", |
| 560 | + " pos = item.get_id(1)\n", |
559 | 561 | " for j in range(pop_length-1):\n",
|
560 | 562 | " fitnesses[pos] += distances[int(chromosomes[pos, j]), int(chromosomes[pos, j+1])]\n"
|
561 | 563 | ]
|
|
708 | 710 | " chromosomes_flat_dpctl = dpnp.asarray(chromosomes, device=\"gpu\")\n",
|
709 | 711 | " fitnesses_dpctl = dpnp.asarray(fitnesses.copy(), device=\"gpu\")\n",
|
710 | 712 | "\n",
|
711 |
| - " eval_genomes_plain_TSP_SYCL[numba_dpex.Range(pop_size)](chromosomes_flat_dpctl, fitnesses_dpctl, distances_dpctl, pop_size)\n", |
| 713 | + " exec_range = kernel_api.Range(pop_size)\n", |
| 714 | + " numba_dpex.call_kernel(eval_genomes_plain_TSP_SYCL, exec_range, chromosomes_flat_dpctl, fitnesses_dpctl, distances_dpctl, pop_size)\n", |
712 | 715 | " fitnesses = dpnp.asnumpy(fitnesses_dpctl)\n",
|
713 | 716 | " chromosomes = next_generation_TSP(chromosomes, fitnesses)\n",
|
714 | 717 | " fitnesses = np.zeros(pop_size, dtype=np.float32)\n",
|
|
0 commit comments