Глава 8 Неоднородные вычисления. Неоднородные вычисления Содержание Глава Неоднородные вычисления Основы неоднородных вычислений
Скачать 0.62 Mb.
|
OUTPUT VECTOR RESULT A + B [70 54 76 154 182 194 141 96 77 52 100 162 126 112 151 156 111 117 152 97 161 100 60 75 98 118 75 70 28 129 37 101 133 80 95 91 130 58 74 134 177 145 115 76 84 36 44 54 91 144 68 141 53 80 156 164 121 151 74 35 107 80 92 106 106 64 59 86 81 94 170 104 80 76 92 13 61 69 171 70 87 125 121 119 76 72 55 8 69 55 144 146 124 173 18 152 93 86 158 74] Также ознакомьтесь... В данном разделе мы рассмотрели модель выполнения PyOpenCL, которая как и PyCUDA, привлекает процесор хоста, управляющий одним или более разнородных устройств. В частности, каждая команда PyOpenCL отправляется в надлежащее устройство из своего хоста в виде исходного кода, который определяется посредством необходимой функции ядра. Такой исходный код далее загружается в некий объект программы для эталонной архитектуры, эта программа компилируется для такой эталонной архитектуры, и создаётся надлежащий объект ядра, соотносимый с данной программой. Объект ядра может выполняться в произвольном числе рабочих групп, создавая некую n- мерную вычислительную матрицу, что позволяет ему действенно подразделять общую рабочую нагрузку для задачи на n- измерений (1, 2 или 3) в каждой из рабочих групп. В свою очередь, они составляются в некое число исполнительных элементов, которые работают параллельно. Балансировка общей рабочей нагрузки каждой рабочей группы, основывающаяся на имеющейся возможности параллельных вычислений некого устройства, является одним из критически важных параметров для достижения достойной производительности приложения. Ненадлежащая балансировка имеющейся рабочей нагрузки, совместно с конкретными особенностями каждого устройства (такими как задержки н обмен, пропускная способность и полоса пропускания) могут приводить к существенным потерям производительности или к компромиссам в присутствии переносимости вашего кода при выполнении без учёта сведений динамичного получения системы вычислений в плане вычислительных возможностей устройства. Однако аккуратное применение таких технологий позволяет нам достигать высоких уровней производительности в сочетании с получаемыми результатами вычислений для различных вычислительных устройств. Дополнительно С дополнительными сведениями по программированию PyOpenCL можно ознакомиться по следующей ссылке. Поэлементные выражения с применением PyOpenCL Функциональность поэлементных выражений позволяет нам вычислять ядра сложных выражений (которые составляются из большого числа операндов) за один вычислительный проход. Приготовление Для поэлементной обработки в PyOpenCL реализуется метод ElementwiseKernel (context, argument, operation, name, optional_parameters) . Его основные параметры таковы: context является устройством или группой устройств в котором должна исполняться поэлементная обработка. argument является неким C- подобным списком аргументов для всех вовлечённых в это вычисление параметров. operation это строка, представляющая то действие, которое выполняется с заданным списком аргументов. name выступает в качестве названия, которое ассоциируется с Elementwisekernel. optional_parameters не важен для данного рецепта. Как это сделать... Здесь мы снова рассмотрим задачу сложения двух векторов. Начинаем с импорта относящихся к делу библиотек: import pyopencl as cl import pyopencl.array as cl_array import numpy as np Задаём необходимые элемент контекста (context) и очередь команд (queue): context = cl.create_some_context() queue = cl.CommandQueue(context) Здесь мы устанавливаем значение размерности вектора и выделяем необходимое пространство для своих входных и выходного векторов: vector_dim = 100 vector_a=cl_array.to_device(queue,np.random.randint(100,\ size=vector_dim)) vector_b = cl_array.to_device(queue,np.random.randint(100,\ size=vector_dim)) result_vector = cl_array.empty_like(vector_a) Мы устанавливаем elementwiseSum в качестве своего приложения ElementwiseKernel, а затем настраиваем для него некий набор аргументов, которые определяют те операции, которые следует применить для наших входных векторов: elementwiseSum = cl.elementwise.ElementwiseKernel(context, "int *a,\ int *b, int *c", "c[i] = a[i] + b[i]", "sum") elementwiseSum(vector_a, vector_b, result_vector) Наконец, мы выводим на печать получаемый результат: print ("PyOpenCL ELEMENTWISE SUM OF TWO VECTORS") print ("VECTOR LENGTH = %s" %vector_dimension) print ("INPUT VECTOR A") print (vector_a) print ("INPUT VECTOR B") print (vector_b) print ("OUTPUT VECTOR RESULT A + B ") print (result_vector) Как это работает... В самых первых строках своего сценария мы импортируем все необходимые нам модули. Для инициализации своего контекста мы применяем метод cl.create_some_context(). Он запрашивает у пользователя какой именно контекст требуется применять для данного вычисления: Choose platform: [0] 'NVIDIA CUDA' at 0x1c0a25aecf0> [1] 'Intel(R) OpenCL' at 0x1c0a2608400> Вслед за этим нам требуется установить экземпляр своей очереди, которая будет получать ElementwiseKernel: queue = cl.CommandQueue(context) Создаются экземпляры входных и выходного векторов. Наши входные векторы, vector_a и vector_b, являются векторами целочисленных значений, получаемых при помощи функции NumPy random.randint. Эти векторы, за этим, копируются в вычислительное усройство при помощи соответствующего оператора PyOpenCL: cl.array_to_device(queue,array) В ElementwiseKernel создаётся некий объект: elementwiseSum = cl.elementwise.ElementwiseKernel(context,\ "int *a, int *b, int *c", "c[i] = a[i] + b[i]", "sum")
Наконец, мы вызываем свою функцию elementwiseSum с заданными ранее значениями аргументов: elementwiseSum(vector_a, vector_b, result_vector) Данный пример завершается выводом на печать значений входных векторов и получаемого результата. Наш вывод выглядит как- то так: (base) C:\>python elementwisePyopencl.py Choose platform: [0] at 0x1c0a25aecf0> [1] at 0x1c0a2608400> Choice [0]:1 Choose device(s): [0] 5500' on 'Intel(R) OpenCL' at 0x1c0a1640db0> [1] 5500U CPU @ 2.40GHz' on 'Intel(R) OpenCL' at 0x1c0a15e53f0> Choice, comma-separated [0]:0 PyOpenCL ELEMENTWISE SUM OF TWO VECTORS VECTOR LENGTH = 100 INPUT VECTOR A [24 64 73 37 40 4 41 85 19 90 32 51 6 89 98 56 97 53 34 91 82 89 97 2 54 65 90 90 91 75 30 8 62 94 63 69 31 99 8 18 28 7 81 72 14 53 91 80 76 39 8 47 25 45 26 56 23 47 41 18 89 17 82 84 10 75 56 89 71 56 66 61 58 54 27 88 16 20 9 61 68 63 74 84 18 82 67 30 15 25 25 3 93 36 24 27 70 5 78 15] |