pascalabcnet/InstallerSamples/StandardUnits/OpenGL и OpenCL/OpenCL/SimpleAddition.pas

67 lines
2.4 KiB
ObjectPascal
Raw Permalink Normal View History

2019-05-18 10:24:07 +03:00
uses OpenCL;
2019-05-17 18:02:15 +03:00
uses System;
uses System.Runtime.InteropServices;
2020-02-26 07:34:25 +03:00
const
buf_size = 10;
buf_byte_size = buf_size * 4;
2019-05-17 18:02:15 +03:00
begin
var ec: ErrorCode;
// Инициализация
var platform: cl_platform_id;
2020-02-26 07:34:25 +03:00
cl.GetPlatformIDs(1, platform, IntPtr.Zero).RaiseIfError;
2019-05-17 18:02:15 +03:00
var device: cl_device_id;
2020-08-04 02:26:50 +03:00
cl.GetDeviceIDs(platform, DeviceType.DEVICE_TYPE_ALL, 1,device,IntPtr.Zero).RaiseIfError;
// Если пишет что устройств нет - обновите драйверы
2019-07-18 03:47:28 +03:00
2020-02-26 07:34:25 +03:00
var context := cl.CreateContext(nil, 1,device, nil,IntPtr.Zero, ec);
2019-05-17 18:02:15 +03:00
ec.RaiseIfError;
2020-02-26 07:34:25 +03:00
var command_queue := cl.CreateCommandQueueWithProperties(context, device, nil, ec);
2019-05-17 18:02:15 +03:00
ec.RaiseIfError;
// Чтение и компиляция .cl файла
{$resource SimpleAddition.cl} // эта строчка засовывает SimpleAddition.cl внутрь .exe, чтоб не надо было таскать его вместе с .exe
2020-08-04 02:26:50 +03:00
var prog_str := System.IO.StreamReader.Create(
System.Reflection.Assembly.GetCallingAssembly.GetManifestResourceStream('SimpleAddition.cl')
).ReadToEnd;
2019-05-17 18:02:15 +03:00
var prog := cl.CreateProgramWithSource(
context,
1,
new string[](prog_str),
2020-03-13 05:28:53 +03:00
nil,
2019-05-17 18:02:15 +03:00
ec
);
ec.RaiseIfError;
2020-02-26 07:34:25 +03:00
cl.BuildProgram(prog, 1,device, nil, nil,IntPtr.Zero).RaiseIfError;
2019-05-17 18:02:15 +03:00
// Подготовка и запуск программы на GPU
2020-02-26 07:34:25 +03:00
var kernel := cl.CreateKernel(prog, 'TEST', ec); // То же имя что у kernel'а из .cl файла. Регистр важен!
2019-05-17 18:02:15 +03:00
ec.RaiseIfError;
2020-02-26 07:34:25 +03:00
var buf := cl.CreateBuffer(context, MemFlags.MEM_READ_WRITE, new UIntPtr(buf_byte_size), IntPtr.Zero, ec);
2019-05-17 18:02:15 +03:00
ec.RaiseIfError;
2020-02-26 07:34:25 +03:00
var buf_fill_pattern := 1;
var buf_fill_ev: cl_event;
cl.EnqueueFillBuffer(command_queue, buf, buf_fill_pattern,new UIntPtr(sizeof(integer)), UIntPtr.Zero,new UIntPtr(buf_byte_size), 0,nil,buf_fill_ev).RaiseIfError;
2019-05-17 18:02:15 +03:00
2020-02-26 07:34:25 +03:00
cl.SetKernelArg(kernel, 0, new UIntPtr(cl_mem.Size), buf).RaiseIfError;
2019-05-17 18:02:15 +03:00
2020-02-26 07:34:25 +03:00
var k_ev: cl_event;
cl.EnqueueNDRangeKernel(command_queue, kernel, 1, nil,new UIntPtr[](new UIntPtr(buf_size)),nil, 1,buf_fill_ev,k_ev).RaiseIfError;
2019-05-17 18:02:15 +03:00
// Чтение и вывод результата
2020-02-26 07:34:25 +03:00
var res := new integer[buf_size];
cl.EnqueueReadBuffer(command_queue, buf, Bool.BLOCKING, UIntPtr.Zero, new UIntPtr(buf_byte_size), res[0], 1,k_ev,IntPtr.Zero).RaiseIfError;
2019-05-17 18:02:15 +03:00
res.Println;
end.