//*****************************************************************************************************\\ // Copyright (©) Cergey Latchenko ( github.com/SunSerega | forum.mmcs.sfedu.ru/u/sun_serega ) // This code is distributed under the Unlicense // For details see LICENSE file or this: // https://github.com/SunSerega/POCGL/blob/master/LICENSE //*****************************************************************************************************\\ // Copyright (©) Сергей Латченко ( github.com/SunSerega | forum.mmcs.sfedu.ru/u/sun_serega ) // Этот код распространяется с лицензией Unlicense // Подробнее в файле LICENSE или тут: // https://github.com/SunSerega/POCGL/blob/master/LICENSE //*****************************************************************************************************\\ /// ///Высокоуровневая оболочка модуля OpenCL /// OpenCL и OpenCLABC можно использовать одновременно /// Но контактировать они практически не будут /// ///Если не хватает типа/метода или найдена ошибка - писать сюда: /// https://github.com/SunSerega/POCGL/issues /// ///Справка данного модуля находится в папке примеров /// По-умолчанию, её можно найти в "C:\PABCWork.NET\Samples\OpenGL и OpenCL" /// unit OpenCLABC; interface uses System; uses OpenCL; uses OpenCLABCBase; {$region Re:definition's} type ///Тип устройства, поддерживающего OpenCL DeviceType = OpenCL.DeviceType; ///Уровень кэша, используемый в Device.SplitByAffinityDomain DeviceAffinityDomain = OpenCL.DeviceAffinityDomain; ///Представляет платформу OpenCL, объединяющую одно или несколько устройств Platform = OpenCLABCBase.Platform; ///Представляет устройство, поддерживающее OpenCL Device = OpenCLABCBase.Device; ///Представляет виртуальное устройство, использующее часть ядер другого устройства ///Объекты данного типа обычно создаются методами "Device.Split*" SubDevice = OpenCLABCBase.SubDevice; ///Представляет контекст для хранения данных и выполнения команд на GPU Context = OpenCLABCBase.Context; ///Представляет область памяти устройства OpenCL Buffer = OpenCLABCBase.Buffer; ///Представляет область памяти внутри другого буфера SubBuffer = OpenCLABCBase.SubBuffer; ///Представляет подпрограмму, выполняемую на GPU Kernel = OpenCLABCBase.Kernel; ///Представляет контейнер с откомпилированным кодом для GPU, содержащим подпрограммы-kernel'ы ProgramCode = OpenCLABCBase.ProgramCode; ///Представляет задачу выполнения очереди, создаваемую методом Context.BeginInvoke CLTaskBase = OpenCLABCBase.CLTaskBase; ///Представляет задачу выполнения очереди, создаваемую методом Context.BeginInvoke CLTask = OpenCLABCBase.CLTask; ///Представляет очередь, состоящую в основном из команд, выполняемых на GPU CommandQueueBase = OpenCLABCBase.CommandQueueBase; ///Представляет очередь, состоящую в основном из команд, выполняемых на GPU CommandQueue = OpenCLABCBase.CommandQueue; ///Интерфейс, который реализован только классом ConstQueue ///Позволяет получить значение, из которого была создана константая очередь, не зная его типа IConstQueue = OpenCLABCBase.IConstQueue; ///Представляет константную очередь ///Константные очереди ничего не выполняют и возвращает заданное при создании значение ConstQueue = OpenCLABCBase.ConstQueue; ///Представляет очередь-контейнер для команд GPU, применяемых к объекту типа Buffer BufferCommandQueue = OpenCLABCBase.BufferCommandQueue; ///Представляет очередь-контейнер для команд GPU, применяемых к объекту типа Kernel KernelCommandQueue = OpenCLABCBase.KernelCommandQueue; ///Представляет аргумент, передаваемый в вызов kernel-а KernelArg = OpenCLABCBase.KernelArg; {$endregion Re:definition's} {$region HFQ/HPQ} ///Создаёт очередь, выполняющую указанную функцию на CPU ///И возвращающую результат этой функци function HFQ(f: ()->T): CommandQueue; ///Создаёт очередь, выполняющую указанную функцию на CPU ///И возвращающую результат этой функци function HFQ(f: Context->T): CommandQueue; ///Создаёт очередь, выполняющую указанную процедуру на CPU ///И возвращающую object(nil) function HPQ(p: ()->()): CommandQueueBase; ///Создаёт очередь, выполняющую указанную процедуру на CPU ///И возвращающую object(nil) function HPQ(p: Context->()): CommandQueueBase; {$endregion HFQ/HPQ} {$region WaitFor} ///Создаёт очередь, ожидающую сигнала выполненности от каждой из указанных очередей function WaitForAll(params qs: array of CommandQueueBase): CommandQueueBase; ///Создаёт очередь, ожидающую сигнала выполненности от каждой из указанных очередей function WaitForAll(qs: sequence of CommandQueueBase): CommandQueueBase; ///Создаёт очередь, ожидающую первого сигнала выполненности от любой из указанных очередей function WaitForAny(params qs: array of CommandQueueBase): CommandQueueBase; ///Создаёт очередь, ожидающую первого сигнала выполненности от любой из указанных очередей function WaitForAny(qs: sequence of CommandQueueBase): CommandQueueBase; ///Создаёт очередь, ожидающую сигнала выполненности от указанной очереди function WaitFor(q: CommandQueueBase): CommandQueueBase; {$endregion WaitFor} {$region CombineQueue's} {$region Sync} {$region NonConv} ///Создаёт очередь, выполняющую указанные очереди одну за другой ///И возвращающую результат последней очереди function CombineSyncQueueBase(params qs: array of CommandQueueBase): CommandQueueBase; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///И возвращающую результат последней очереди function CombineSyncQueueBase(qs: sequence of CommandQueueBase): CommandQueueBase; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///И возвращающую результат последней очереди function CombineSyncQueue(qs: sequence of CommandQueueBase; last: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///И возвращающую результат последней очереди function CombineSyncQueue(params qs: array of CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///И возвращающую результат последней очереди function CombineSyncQueue(qs: sequence of CommandQueue): CommandQueue; {$endregion NonConv} {$region Conv} {$region NonContext} ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue(conv: Func; params qs: array of CommandQueueBase): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue(conv: Func; qs: sequence of CommandQueueBase): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue(conv: Func; params qs: array of CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue(conv: Func; qs: sequence of CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue2(conv: Func; q1: CommandQueue; q2: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue3(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue4(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue5(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue6(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue; q6: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue7(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue; q6: CommandQueue; q7: CommandQueue): CommandQueue; {$endregion NonContext} {$region Context} ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue(conv: Func; params qs: array of CommandQueueBase): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue(conv: Func; qs: sequence of CommandQueueBase): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue(conv: Func; params qs: array of CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue(conv: Func; qs: sequence of CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue2(conv: Func; q1: CommandQueue; q2: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue3(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue4(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue5(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue6(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue; q6: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одну за другой ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineSyncQueue7(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue; q6: CommandQueue; q7: CommandQueue): CommandQueue; {$endregion Context} {$endregion Conv} {$endregion Sync} {$region Async} {$region NonConv} ///Создаёт очередь, выполняющую указанные очереди одновременно ///И возвращающую результат последней очереди function CombineAsyncQueueBase(params qs: array of CommandQueueBase): CommandQueueBase; ///Создаёт очередь, выполняющую указанные очереди одновременно ///И возвращающую результат последней очереди function CombineAsyncQueueBase(qs: sequence of CommandQueueBase): CommandQueueBase; ///Создаёт очередь, выполняющую указанные очереди одновременно ///И возвращающую результат последней очереди function CombineAsyncQueue(qs: sequence of CommandQueueBase; last: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///И возвращающую результат последней очереди function CombineAsyncQueue(params qs: array of CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///И возвращающую результат последней очереди function CombineAsyncQueue(qs: sequence of CommandQueue): CommandQueue; {$endregion NonConv} {$region Conv} {$region NonContext} ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue(conv: Func; params qs: array of CommandQueueBase): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue(conv: Func; qs: sequence of CommandQueueBase): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue(conv: Func; params qs: array of CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue(conv: Func; qs: sequence of CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue2(conv: Func; q1: CommandQueue; q2: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue3(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue4(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue5(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue6(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue; q6: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue7(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue; q6: CommandQueue; q7: CommandQueue): CommandQueue; {$endregion NonContext} {$region Context} ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue(conv: Func; params qs: array of CommandQueueBase): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue(conv: Func; qs: sequence of CommandQueueBase): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue(conv: Func; params qs: array of CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue(conv: Func; qs: sequence of CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue2(conv: Func; q1: CommandQueue; q2: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue3(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue4(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue5(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue6(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue; q6: CommandQueue): CommandQueue; ///Создаёт очередь, выполняющую указанные очереди одновременно ///Затем выполняющую указанную первым параметров функцию на CPU, передавая результаты всех очередей ///И возвращающую результат этой функции function CombineAsyncQueue7(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue; q6: CommandQueue; q7: CommandQueue): CommandQueue; {$endregion Context} {$endregion Conv} {$endregion Async} {$endregion CombineQueue's} implementation {$region HFQ/HPQ} type CommandQueueHostQueueBase = abstract class(HostQueue) where TFunc: Delegate; private f: TFunc; public constructor(f: TFunc) := self.f := f; private constructor := raise new InvalidOperationException($'Был вызван не_применимый конструктор без параметров... Обратитесь к разработчику OpenCLABC'); protected function InvokeSubQs(tsk: CLTaskBase; c: Context; main_dvc: cl_device_id; var cq: cl_command_queue; prev_ev: EventList): QueueRes; override := new QueueResConst(nil, prev_ev ?? new EventList); protected procedure RegisterWaitables(tsk: CLTaskBase; prev_hubs: HashSet); override := exit; end; CommandQueueHostFunc = sealed class(CommandQueueHostQueueBaseT>) protected function ExecFunc(o: object; c: Context): T; override := f(c); end; CommandQueueHostProc = sealed class(CommandQueueHostQueueBase()>) protected function ExecFunc(o: object; c: Context): object; override; begin f(c); Result := nil; end; end; function HFQ(f: ()->T) := new CommandQueueHostFunc(c->f()); function HFQ(f: Context->T) := new CommandQueueHostFunc(f); function HPQ(p: ()->()) := new CommandQueueHostProc(c->p()); function HPQ(p: Context->()) := new CommandQueueHostProc(p); {$endregion HFQ/HPQ} {$region WaitFor} type CommandQueueWaitFor = sealed class(CommandQueue) public waiter: WCQWaiter; public constructor(waiter: WCQWaiter) := self.waiter := waiter; protected function InvokeImpl(tsk: CLTaskBase; c: Context; main_dvc: cl_device_id; need_ptr_qr: boolean; var cq: cl_command_queue; prev_ev: EventList): QueueRes; override; begin if need_ptr_qr then new System.InvalidOperationException; var wait_ev := waiter.GetWaitEv(tsk, c); Result := new QueueResConst(nil, prev_ev=nil ? wait_ev : prev_ev+wait_ev); end; protected procedure RegisterWaitables(tsk: CLTaskBase; prev_hubs: HashSet); override := waiter.RegisterWaitables(tsk); end; function WaitForAll(params qs: array of CommandQueueBase) := WaitForAll(qs.AsEnumerable); function WaitForAll(qs: sequence of CommandQueueBase) := new CommandQueueWaitFor(new WCQWaiterAll(qs.ToArray)); function WaitForAny(params qs: array of CommandQueueBase) := WaitForAny(qs.AsEnumerable); function WaitForAny(qs: sequence of CommandQueueBase) := new CommandQueueWaitFor(new WCQWaiterAny(qs.ToArray)); function WaitFor(q: CommandQueueBase) := WaitForAll(q); {$endregion WaitFor} {$region CombineQueue's} {$region Sync} {$region NonConv} function CombineSyncQueueBase(params qs: array of CommandQueueBase) := new SimpleSyncQueueArray(QueueArrayUtils.FlattenSyncQueueArray(qs)); function CombineSyncQueueBase(qs: sequence of CommandQueueBase) := new SimpleSyncQueueArray(QueueArrayUtils.FlattenSyncQueueArray(qs)); function CombineSyncQueue(qs: sequence of CommandQueueBase; last: CommandQueue) := new SimpleSyncQueueArray(QueueArrayUtils.FlattenSyncQueueArray(qs.Append(last as CommandQueueBase))); function CombineSyncQueue(params qs: array of CommandQueue) := new SimpleSyncQueueArray(QueueArrayUtils.FlattenSyncQueueArray(qs.Cast&)); function CombineSyncQueue(qs: sequence of CommandQueue) := new SimpleSyncQueueArray(QueueArrayUtils.FlattenSyncQueueArray(qs.Cast&)); {$endregion NonConv} {$region Conv} {$region NonContext} function CombineSyncQueue(conv: Func; params qs: array of CommandQueueBase) := new ConvSyncQueueArray(qs.Select(q->q.Cast&).ToArray, (a,c)->conv(a)); function CombineSyncQueue(conv: Func; qs: sequence of CommandQueueBase) := new ConvSyncQueueArray(qs.Select(q->q.Cast&).ToArray, (a,c)->conv(a)); function CombineSyncQueue(conv: Func; params qs: array of CommandQueue) := new ConvSyncQueueArray(qs.ToArray, (a,c)->conv(a)); function CombineSyncQueue(conv: Func; qs: sequence of CommandQueue) := new ConvSyncQueueArray(qs.ToArray, (a,c)->conv(a)); function CombineSyncQueue2(conv: Func; q1: CommandQueue; q2: CommandQueue) := new ConvSyncQueueArray2(q1, q2, (o1, o2, c)->conv(o1, o2)); function CombineSyncQueue3(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue) := new ConvSyncQueueArray3(q1, q2, q3, (o1, o2, o3, c)->conv(o1, o2, o3)); function CombineSyncQueue4(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue) := new ConvSyncQueueArray4(q1, q2, q3, q4, (o1, o2, o3, o4, c)->conv(o1, o2, o3, o4)); function CombineSyncQueue5(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue) := new ConvSyncQueueArray5(q1, q2, q3, q4, q5, (o1, o2, o3, o4, o5, c)->conv(o1, o2, o3, o4, o5)); function CombineSyncQueue6(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue; q6: CommandQueue) := new ConvSyncQueueArray6(q1, q2, q3, q4, q5, q6, (o1, o2, o3, o4, o5, o6, c)->conv(o1, o2, o3, o4, o5, o6)); function CombineSyncQueue7(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue; q6: CommandQueue; q7: CommandQueue) := new ConvSyncQueueArray7(q1, q2, q3, q4, q5, q6, q7, (o1, o2, o3, o4, o5, o6, o7, c)->conv(o1, o2, o3, o4, o5, o6, o7)); {$endregion NonContext} {$region Context} function CombineSyncQueue(conv: Func; params qs: array of CommandQueueBase) := new ConvSyncQueueArray(qs.Select(q->q.Cast&).ToArray, conv); function CombineSyncQueue(conv: Func; qs: sequence of CommandQueueBase) := new ConvSyncQueueArray(qs.Select(q->q.Cast&).ToArray, conv); function CombineSyncQueue(conv: Func; params qs: array of CommandQueue) := new ConvSyncQueueArray(qs.ToArray, conv); function CombineSyncQueue(conv: Func; qs: sequence of CommandQueue) := new ConvSyncQueueArray(qs.ToArray, conv); function CombineSyncQueue2(conv: Func; q1: CommandQueue; q2: CommandQueue) := new ConvSyncQueueArray2(q1, q2, conv); function CombineSyncQueue3(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue) := new ConvSyncQueueArray3(q1, q2, q3, conv); function CombineSyncQueue4(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue) := new ConvSyncQueueArray4(q1, q2, q3, q4, conv); function CombineSyncQueue5(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue) := new ConvSyncQueueArray5(q1, q2, q3, q4, q5, conv); function CombineSyncQueue6(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue; q6: CommandQueue) := new ConvSyncQueueArray6(q1, q2, q3, q4, q5, q6, conv); function CombineSyncQueue7(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue; q6: CommandQueue; q7: CommandQueue) := new ConvSyncQueueArray7(q1, q2, q3, q4, q5, q6, q7, conv); {$endregion Context} {$endregion Conv} {$endregion Sync} {$region Async} {$region NonConv} function CombineAsyncQueueBase(params qs: array of CommandQueueBase) := new SimpleAsyncQueueArray(QueueArrayUtils.FlattenAsyncQueueArray(qs)); function CombineAsyncQueueBase(qs: sequence of CommandQueueBase) := new SimpleAsyncQueueArray(QueueArrayUtils.FlattenAsyncQueueArray(qs)); function CombineAsyncQueue(qs: sequence of CommandQueueBase; last: CommandQueue) := new SimpleAsyncQueueArray(QueueArrayUtils.FlattenAsyncQueueArray(qs.Append(last as CommandQueueBase))); function CombineAsyncQueue(params qs: array of CommandQueue) := new SimpleAsyncQueueArray(QueueArrayUtils.FlattenAsyncQueueArray(qs.Cast&)); function CombineAsyncQueue(qs: sequence of CommandQueue) := new SimpleAsyncQueueArray(QueueArrayUtils.FlattenAsyncQueueArray(qs.Cast&)); {$endregion NonConv} {$region Conv} {$region NonContext} function CombineAsyncQueue(conv: Func; params qs: array of CommandQueueBase) := new ConvAsyncQueueArray(qs.Select(q->q.Cast&).ToArray, (a,c)->conv(a)); function CombineAsyncQueue(conv: Func; qs: sequence of CommandQueueBase) := new ConvAsyncQueueArray(qs.Select(q->q.Cast&).ToArray, (a,c)->conv(a)); function CombineAsyncQueue(conv: Func; params qs: array of CommandQueue) := new ConvAsyncQueueArray(qs.ToArray, (a,c)->conv(a)); function CombineAsyncQueue(conv: Func; qs: sequence of CommandQueue) := new ConvAsyncQueueArray(qs.ToArray, (a,c)->conv(a)); function CombineAsyncQueue2(conv: Func; q1: CommandQueue; q2: CommandQueue) := new ConvAsyncQueueArray2(q1, q2, (o1, o2, c)->conv(o1, o2)); function CombineAsyncQueue3(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue) := new ConvAsyncQueueArray3(q1, q2, q3, (o1, o2, o3, c)->conv(o1, o2, o3)); function CombineAsyncQueue4(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue) := new ConvAsyncQueueArray4(q1, q2, q3, q4, (o1, o2, o3, o4, c)->conv(o1, o2, o3, o4)); function CombineAsyncQueue5(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue) := new ConvAsyncQueueArray5(q1, q2, q3, q4, q5, (o1, o2, o3, o4, o5, c)->conv(o1, o2, o3, o4, o5)); function CombineAsyncQueue6(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue; q6: CommandQueue) := new ConvAsyncQueueArray6(q1, q2, q3, q4, q5, q6, (o1, o2, o3, o4, o5, o6, c)->conv(o1, o2, o3, o4, o5, o6)); function CombineAsyncQueue7(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue; q6: CommandQueue; q7: CommandQueue) := new ConvAsyncQueueArray7(q1, q2, q3, q4, q5, q6, q7, (o1, o2, o3, o4, o5, o6, o7, c)->conv(o1, o2, o3, o4, o5, o6, o7)); {$endregion NonContext} {$region Context} function CombineAsyncQueue(conv: Func; params qs: array of CommandQueueBase) := new ConvAsyncQueueArray(qs.Select(q->q.Cast&).ToArray, conv); function CombineAsyncQueue(conv: Func; qs: sequence of CommandQueueBase) := new ConvAsyncQueueArray(qs.Select(q->q.Cast&).ToArray, conv); function CombineAsyncQueue(conv: Func; params qs: array of CommandQueue) := new ConvAsyncQueueArray(qs.ToArray, conv); function CombineAsyncQueue(conv: Func; qs: sequence of CommandQueue) := new ConvAsyncQueueArray(qs.ToArray, conv); function CombineAsyncQueue2(conv: Func; q1: CommandQueue; q2: CommandQueue) := new ConvAsyncQueueArray2(q1, q2, conv); function CombineAsyncQueue3(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue) := new ConvAsyncQueueArray3(q1, q2, q3, conv); function CombineAsyncQueue4(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue) := new ConvAsyncQueueArray4(q1, q2, q3, q4, conv); function CombineAsyncQueue5(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue) := new ConvAsyncQueueArray5(q1, q2, q3, q4, q5, conv); function CombineAsyncQueue6(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue; q6: CommandQueue) := new ConvAsyncQueueArray6(q1, q2, q3, q4, q5, q6, conv); function CombineAsyncQueue7(conv: Func; q1: CommandQueue; q2: CommandQueue; q3: CommandQueue; q4: CommandQueue; q5: CommandQueue; q6: CommandQueue; q7: CommandQueue) := new ConvAsyncQueueArray7(q1, q2, q3, q4, q5, q6, q7, conv); {$endregion Context} {$endregion Conv} {$endregion Async} {$endregion CombineQueue's} end.