Главная страница

Глава 8 Неоднородные вычисления. Неоднородные вычисления Содержание Глава Неоднородные вычисления Основы неоднородных вычислений


Скачать 0.62 Mb.
НазваниеНеоднородные вычисления Содержание Глава Неоднородные вычисления Основы неоднородных вычислений
Дата27.12.2022
Размер0.62 Mb.
Формат файлаdocx
Имя файлаГлава 8 Неоднородные вычисления.docx
ТипГлава
#866699
страница6 из 8
1   2   3   4   5   6   7   8

INPUT VECTOR B

[49 18 69 43 51 72 37 50 79 34 97 49 51 29 89 81 33 7 47 93 70 52 63 90

99 95 58 33 41 70 84 87 20 83 74 43 78 34 94 47 89 4 30 36 34 56 32 31

56 22 50 52 68 98 52 80 14 98 43 60 20 49 15 38 74 89 99 29 96 65 89 41

72 53 89 31 34 64 0 47 87 70 98 86 41 25 34 10 44 36 54 52 54 86 33 38

25 49 75 53]
OUTPUT VECTOR RESULT A + B

[73 82 142 80 91 76 78 135 98 124 129 100 57 118 187 137 130 60 81 184

152 141 160 92 153 160 148 123 132 145 114 95 82 177 137 112 109 133

102 65 117 11 111 108 48 109 123 111 132 61 58 99 93 143 78 136 37 145

84 78 109 66 97 122 84 164 155 118 167 121 155 102 130 107 116 119 50

84 9 108 155 133 172 170 59 107 101 40 59 61 79 55 147 122 57 65

95 54 153 68]



Также ознакомьтесь...

PyCUDA также обладает поэлементной функциональностью:
cl.array_to_device(queue,array)



Эта функциональность обладает во многом совпадающими аргументами со встроенной в PyOpenCL, за исключением параметра контекста. Тот же самый пример что и в данном разделе, который реализован для PyCUDA имеет такой листинг:
import pycuda.autoinit

import numpy

from pycuda.elementwise import ElementwiseKernel

import numpy.linalg as la




vector_dimension=100

input_vector_a = np.random.randint(100,size= vector_dimension)

input_vector_b = np.random.randint(100,size= vector_dimension)

output_vector_c = gpuarray.empty_like(input_vector_a)




elementwiseSum = ElementwiseKernel(" int *a, int * b, int *c",\

"c[i] = a[i] + b[i]"," elementwiseSum ")

elementwiseSum(input_vector_a, input_vector_b,output_vector_c)




print ("PyCUDA 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)



Дополнительно

По данной ссылке вы обнаружите занимательные примеры приложений PyOpenCL.

Оценка приложений PyOpenCL

В данном разделе мы выполняем сопоставительное тестирование производительности между ЦПУ и GPU с применением библиотеки PyOpenCL.

Действительно, прежде чем изучать получаемую производительность подлежащего реализации алгоритма, также важно понимать те вычислительные преимущества, которые предлагает имеющаяся у вас вычислительная платформа.

Приготовление

Конкретные вычислительные характеристики вычислительной системы влияют на время вычисления, а следовательно они являют собой сторону первостепенной важности.

В своём следующем примере мы выполним некую проверку для наблюдения производительности в такой системе:

  • GPU: GeForce 840 M

  • ЦПУ: Intel Core i7 – 2.40 ГГц

  • ОЗУ: 8 ГБ

Как это сделать...

В нашем последующем тесте будет оцениваться и сравниваться время вычисления некой математической операции, а именно сложения двух векторов из элементов с плавающей точкой. Для выполнения такого сопоставления, одна и та же операция будет выполнена в двух раздельных функциях.

Наша первая функция выполняется только в имеющемся ЦПУ, в то время как вторая функция написана с применением PyOpenCL для использования установленной карты GPU. Данный тест выполняется для вектора с размером в 10 000 элементов.

Вот наш код:

  1. Импортируем относящиеся к делу библиотеки. Обратите внимание на импорт библиотеки time для вычисления значения времени вычисления, а также библиотеки linalg, которая является неким инструментом инструментария линейной алгебры из библиотеки numpy:



  2. from time import time

  3. import pyopencl as cl

  4. import numpy as np

  5. import deviceInfoPyopencl as device_info

  6. import numpy.linalg as la



  1. Затем мы определяем значения входных векторов. Они оба содержат 10000 случайных элементов чисел с плавающей точкой:



  2. a = np.random.rand(10000).astype(np.float32)

  3. b = np.random.rand(10000).astype(np.float32)



  1. Наша следующая функция вычисляет значение суммы двух векторов обработанное самим ЦПУ (хостом):



  2. def test_cpu_vector_sum(a, b):

  3. c_cpu = np.empty_like(a)

  4. cpu_start_time = time()

  5. for i in range(10000):

  6. for j in range(10000):

  7. c_cpu[i] = a[i] + b[i]

  8. cpu_end_time = time()

  9. print("CPU Time: {0} s".format(cpu_end_time - cpu_start_time))

  10. return c_cpu



  1. Ещё одна функция вычисляет значение суммы двух векторов как результат работы GPU (устройства):



  2. def test_gpu_vector_sum(a, b):

  3. platform = cl.get_platforms()[0]

  4. device = platform.get_devices()[0]

  5. context = cl.Context([device])

  6. queue = cl.CommandQueue(context,properties=\

  7. cl.command_queue_properties.PROFILING_ENABLE)



  1. Внутри своей функции test_gpu_vector_sum мы подготавливаем буферы в памяти для помещения в них значений входных и выходного векторов:



  2. a_buffer = cl.Buffer(context,cl.mem_flags.READ_ONLY \

  3. | cl.mem_flags.COPY_HOST_PTR, hostbuf=a)

  4. b_buffer = cl.Buffer(context,cl.mem_flags.READ_ONLY \

  5. | cl.mem_flags.COPY_HOST_PTR, hostbuf=b)

  6. c_buffer = cl.Buffer(context,cl.mem_flags.WRITE_ONLY, b.nbytes)



  1. Всё ещё внутри своей функции test_gpu_vector_sum мы определяем необходимое ядро, которое будет вычислять значение суммы двух векторов в вычислительном устройстве:



  2. program = cl.Program(context, """

  3. __kernel void sum(__global const float *a,\

  4. __global const float *b,\

  5. __global float *c){

  6. int i = get_global_id(0);

  7. int j;

  8. for(j = 0; j < 10000; j++){

  9. c[i] = a[i] + b[i];}

  10. }""").build()



  1. Далее мы сбрасываем значение переменной gpu_start_time перед началом вычислений. После этого мы вычисляем значение суммы двух векторов, а потом делаем оценку времени вычисления:



  2. gpu_start_time = time()

  3. event = program.sum(queue, a.shape, None,a_buffer, b_buffer,\

  4. c_buffer)

  5. event.wait()

  6. elapsed = 1e-9*(event.profile.end - event.profile.start)

  7. print("GPU Kernel evaluation Time: {0} s".format(elapsed))

  8. c_gpu = np.empty_like(a)

  9. cl._enqueue_read_buffer(queue, c_buffer, c_gpu).wait()

  10. gpu_end_time = time()

  11. print("GPU Time: {0} s".format(gpu_end_time - gpu_start_time))

  12. return c_gpu



  1. И окончательно мы выполняем проверку, вызывая те две функции, которве были определены ранее:



  2. if __name__ == "__main__":

  3. device_info.print_device_info()

  4. cpu_result = test_cpu_vector_sum(a, b)

  5. gpu_result = test_gpu_vector_sum(a, b)

  6. assert (la.norm(cpu_result - gpu_result)) < 1e-5


1   2   3   4   5   6   7   8


написать администратору сайта