update
This commit is contained in:
parent
74913a1c66
commit
1b4fed44e7
|
|
@ -0,0 +1,17 @@
|
|||
uses OpenCLABC;
|
||||
|
||||
// Вывод типа и значения объекта
|
||||
// "o?.GetType" это короткая форма "o=nil ? nil : o.GetType", то есть берём или тип объекта, или nil если сам объект nil
|
||||
// _ObjectToString это функция, которую использует Writeln для форматирования значений
|
||||
procedure OtpObject(o: object) :=
|
||||
Writeln( $'{o?.GetType}[{_ObjectToString(o)}]' );
|
||||
|
||||
begin
|
||||
var b0 := new Buffer(1);
|
||||
|
||||
OtpObject( Context.Default.SyncInvoke( b0.NewQueue as CommandQueue<Buffer> ) ); // Тип - буфер, потому что очередь создали из буфера
|
||||
OtpObject( Context.Default.SyncInvoke( HFQ( ()->5 ) ) ); // Тип - Int32(integer), потому что это тип по-умолчанию для выражения "5"
|
||||
OtpObject( Context.Default.SyncInvoke( HFQ( ()->'abc' ) ) ); // Тип - string, по той же причине
|
||||
OtpObject( Context.Default.SyncInvoke( HPQ( ()->Writeln('Выполнилась HPQ') ) ) ); // Тип отсутствует, потому что HPQ возвращает nil
|
||||
|
||||
end.
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
uses OpenCLABC;
|
||||
|
||||
begin
|
||||
|
||||
var q1 := HFQ( ()->1 );
|
||||
var q2 := HFQ( ()->2 );
|
||||
|
||||
// Выводит 2, то есть только результат последней очереди
|
||||
// Так сделано из за вопросов производительности
|
||||
Context.Default.SyncInvoke( q1+q2 ).Println;
|
||||
// Однако всё же бывает так, что нужны результаты всех сложенных/умноженных очередей
|
||||
|
||||
// В таком случае надо использовать CombineSyncQueue и CombineAsyncQueue
|
||||
// А точнее их перегрузку, первый параметр которой - функция преобразования
|
||||
Context.Default.SyncInvoke(
|
||||
CombineSyncQueue(
|
||||
results->results.JoinIntoString, // функция преобразования. Если не указывать - CombineSyncQueue работает как обычное сложение (но быстрее если складывать >2 очередей)
|
||||
q1, q2
|
||||
)
|
||||
).Println;
|
||||
// Теперь выводит строку "1 2". Это то же самое что вернёт "Arr(1,2).JoinIntoString"
|
||||
|
||||
end.
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
uses OpenCLABC;
|
||||
|
||||
begin
|
||||
|
||||
var b := new Buffer( 3*sizeof(integer) );
|
||||
var A := new integer[3];
|
||||
|
||||
// Код с очередями
|
||||
|
||||
var Q_BuffWrite :=
|
||||
( b.NewQueue.AddWriteValue(1, 0*sizeof(integer) ) as CommandQueue<Buffer> ) *
|
||||
( b.NewQueue.AddWriteValue(5, 1*sizeof(integer) ) as CommandQueue<Buffer> ) *
|
||||
( b.NewQueue.AddWriteValue(7, 2*sizeof(integer) ) as CommandQueue<Buffer> )
|
||||
;
|
||||
|
||||
var Q_BuffRead := b.NewQueue.AddReadArray(A) as CommandQueue<Buffer>;
|
||||
|
||||
var Q_Otp := HPQ(()->
|
||||
begin
|
||||
A.Println;
|
||||
end);
|
||||
|
||||
Context.Default.SyncInvoke(
|
||||
Q_BuffWrite +
|
||||
Q_BuffRead +
|
||||
Q_Otp
|
||||
);
|
||||
|
||||
// Этот же код ещё раз, но без явных очередей
|
||||
// Неявно - каждый метод .Write*** и .Read*** всё равно создаёт по очереди
|
||||
// Такая запись короче, но выполняется медленнее
|
||||
|
||||
// Аналог Q_BuffWrite
|
||||
System.Threading.Tasks.Parallel.Invoke(
|
||||
()->b.WriteValue(1, 0*sizeof(integer) ),
|
||||
()->b.WriteValue(5, 1*sizeof(integer) ),
|
||||
()->b.WriteValue(7, 2*sizeof(integer) )
|
||||
);
|
||||
|
||||
// Аналог Q_BuffRead
|
||||
b.ReadArray(A);
|
||||
|
||||
// Аналог Q_Otp
|
||||
A.Println;
|
||||
|
||||
end.
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
uses OpenCLABC;
|
||||
|
||||
begin
|
||||
var q := HFQ(()->123);
|
||||
|
||||
Context.Default.SyncInvoke(
|
||||
q.ThenConvert(i -> $'"{i}"' )
|
||||
).Println;
|
||||
|
||||
end.
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
uses OpenCLABC;
|
||||
|
||||
begin
|
||||
|
||||
var q1 := HPQ(()->
|
||||
begin
|
||||
// lock надо чтоб при параллельном выполнении два потока не пытались использовать вывод одновременно. Иначе выйдет кашу
|
||||
lock output do Writeln('Очередь 1 начала выполняться');
|
||||
Sleep(500);
|
||||
lock output do Writeln('Очередь 1 закончила выполняться');
|
||||
end);
|
||||
var q2 := HPQ(()->
|
||||
begin
|
||||
lock output do Writeln('Очередь 2 начала выполняться');
|
||||
Sleep(500);
|
||||
lock output do Writeln('Очередь 2 закончила выполняться');
|
||||
end);
|
||||
|
||||
Writeln('Последовательное выполнение:');
|
||||
Context.Default.SyncInvoke( q1 + q2 );
|
||||
|
||||
Writeln;
|
||||
Writeln('Параллельное выполнение:');
|
||||
Context.Default.SyncInvoke( q1 * q2 );
|
||||
|
||||
end.
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
uses OpenCLABC;
|
||||
|
||||
begin
|
||||
var b := new Buffer( 3*sizeof(integer) ); // Буфер достаточного размера чтоб содержать 3 значения типа integer.
|
||||
|
||||
// Создаём очередь
|
||||
var q := b.NewQueue;
|
||||
|
||||
// Добавлять команды в полученную очередь можно вызывая соответствующие методы
|
||||
q.AddWriteValue(1, 0*sizeof(integer) );
|
||||
|
||||
// Методы, добавляющие команду в очередь - возвращают очередь, для которой их вызвали (не копию а ссылку на оригинал)
|
||||
// Поэтому можно добавлять по несколько команд в 1 строчке:
|
||||
q.AddWriteValue(5, 1*sizeof(integer) ).AddWriteValue(7, 2*sizeof(integer) );
|
||||
// Все команды в q будут выполнятся последовательно, что не всегда хорошо
|
||||
// Если надо выполнять параллельно - создавайте несколько "b.NewQueue" и умножайте друг на друга
|
||||
|
||||
// В данной версии надо писать "as CommandQueue<...>" при использовании [Buffer/Kernel]CommandQueue вместо CommandQueue<...>, из за бага компилятора
|
||||
Context.Default.SyncInvoke(q as CommandQueue<Buffer>);
|
||||
|
||||
// Вообще чтение тоже надо делать через очереди, но для простого примера - и неявные очереди подходят
|
||||
b.GetArray1&<integer>(3).Println;
|
||||
|
||||
end.
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
uses OpenCLABC;
|
||||
|
||||
begin
|
||||
var N := ReadInteger('Введите размер буфера:');
|
||||
var b := new Buffer( N*sizeof(integer) );
|
||||
|
||||
var Q_RNG_val := HFQ(()->
|
||||
begin
|
||||
Result := Random(1,100);
|
||||
end);
|
||||
|
||||
// .WriteValue принимает значение размерного типа
|
||||
// Но вместо него - мы передали очередь (CommandQueue это класс, то есть точно не размерный тип)
|
||||
// Так можно, потому что возвращаемое значение очереди Q_RNG_val - размерный тип (integer)
|
||||
var Q_RNG_FillBuff := b.NewQueue.AddWriteValue(Q_RNG_val, 0) as CommandQueue<Buffer>;
|
||||
|
||||
for var i := 1 to N-1 do // 0 пропускаем, потому что его уже добавили выше
|
||||
Q_RNG_FillBuff *= b.NewQueue.AddWriteValue(Q_RNG_val.Clone(), i*sizeof(integer) ) as CommandQueue<Buffer>;
|
||||
|
||||
// Вообще, это далеко не самый эффективный и красивый способ заполнить буфер
|
||||
// В идеале - это надо делать карнелом
|
||||
// То есть написать свой алгоритм Random на языке OpenCL-C (нет, это не сложно)
|
||||
|
||||
Context.Default.SyncInvoke(Q_RNG_FillBuff);
|
||||
|
||||
b.GetArray1&<integer>(N).Println;
|
||||
end.
|
||||
11
InstallerSamples/OpenCL/OpenCLABC/Из справки/6 – Кёрнел/0.cl
Normal file
11
InstallerSamples/OpenCL/OpenCLABC/Из справки/6 – Кёрнел/0.cl
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
|
||||
|
||||
__kernel void TEST(__global int* message)
|
||||
{
|
||||
int gid = get_global_id(0);
|
||||
|
||||
message[gid] += gid;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
uses OpenCLABC;
|
||||
|
||||
begin
|
||||
|
||||
// Когда код на языке OpenCL-C хранят в файле - обычно ему дают расширение .cl
|
||||
// Но этот код можно хранить и в $resource или даже в '' в программме
|
||||
var code_text := ReadAllText('0.cl');
|
||||
|
||||
// Создание объекта типа ProgramCode
|
||||
// Перед текстом программы - можно так же указать контекст
|
||||
// Если не указывать - используется Context.Default
|
||||
var code := new ProgramCode(code_text);
|
||||
|
||||
var A := new Buffer( 10 * sizeof(integer) ); // будет хранить 10 чисел типа "integer"
|
||||
|
||||
// 'TEST' - имя подпрограммы-кёрнела из .cl файла. Регистр важен!
|
||||
code['TEST'].Exec1(10, // используем 10 потоков
|
||||
|
||||
A.NewQueue.AddFillValue(1) // заполняем весь буфер единичками, прямо перед выполнением
|
||||
as CommandQueue<Buffer> //ToDo нужно только из за issue компилятора #1981, иначе получаем странную ошибку. Когда исправят - можно будет убрать
|
||||
|
||||
);
|
||||
|
||||
A.GetArray1&<integer>(10).Println; // читаем одномерный массив с элементами "integer", длинной в 10
|
||||
|
||||
end.
|
||||
|
|
@ -166,7 +166,8 @@ begin
|
|||
|
||||
var sprog := InitProgram(vertex_shader, 0 {fragment_shader});
|
||||
|
||||
var uniform_rot_k := gl.GetUniformLocation(sprog, 'rot_k');
|
||||
var uniform_rot_k := gl.GetUniformLocation(sprog, 'rot_k');
|
||||
|
||||
var attribute_position := gl.GetAttribLocation(sprog, 'position');
|
||||
var attribute_color := gl.GetAttribLocation(sprog, 'color');
|
||||
|
||||
|
|
|
|||
|
|
@ -2093,7 +2093,7 @@ type
|
|||
static function GetEventInfo(&event: cl_event; param_name: EventInfoType; param_value_size: UIntPtr; param_value: pointer; param_value_size_ret: ^UIntPtr): ErrorCode;
|
||||
external 'opencl.dll' name 'clGetEventInfo';
|
||||
|
||||
static function SetEventCallback(&event: cl_event; command_exec_callback_type: ErrorCode; pfn_notify: Event_Callback; user_data: pointer): ErrorCode;
|
||||
static function SetEventCallback(&event: cl_event; command_exec_callback_type: CommandExecutionStatus; pfn_notify: Event_Callback; user_data: pointer): ErrorCode;
|
||||
external 'opencl.dll' name 'clSetEventCallback';
|
||||
|
||||
static function RetainEvent(&event: cl_event): ErrorCode;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue