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 файла
|
|
|
|
|
|
|
2019-06-06 18:18:55 +03:00
|
|
|
|
{$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.
|