diff --git a/InstallerSamples/OpenGL и OpenCL/OpenCLABC/0Простейшие примеры/MatrMlt.pas b/InstallerSamples/OpenGL и OpenCL/OpenCLABC/0Простейшие примеры/MatrMlt.pas index 7f0f389d1..5d4a7b47a 100644 --- a/InstallerSamples/OpenGL и OpenCL/OpenCLABC/0Простейшие примеры/MatrMlt.pas +++ b/InstallerSamples/OpenGL и OpenCL/OpenCLABC/0Простейшие примеры/MatrMlt.pas @@ -1,14 +1,14 @@ uses OpenCLABC; const - MatrW = 4; // можно поменять на любое положительное значение + MatrW = 4; // Можно поменять на любое положительное значение VecByteSize = MatrW*8; MatrByteSize = MatrW*MatrW*8; begin try - Randomize(0); // делает так, чтобы каждое выполнение давало одинаковый результат + Randomize(0); // Делает так, чтобы каждое выполнение давало одинаковый результат // Чтение и компиляция .cl файла @@ -27,22 +27,22 @@ begin 'Матрица A:'.Println; var A_Matr := MatrRandomReal(MatrW,MatrW,0,1).Println; Writeln; - var A := new Buffer(MatrByteSize); + var A := new MemorySegment(MatrByteSize); 'Матрица B:'.Println; var B_Mart := MatrRandomReal(MatrW,MatrW,0,1).Println; Writeln; - var B := new Buffer(MatrByteSize); + var B := new MemorySegment(MatrByteSize); - var C := new Buffer(MatrByteSize); + var C := new MemorySegment(MatrByteSize); 'Вектор V1:'.Println; var V1_Arr := ArrRandomReal(MatrW); V1_Arr.Println; Writeln; - var V1 := new Buffer(VecByteSize); + var V1 := new MemorySegment(VecByteSize); - var V2 := new Buffer(VecByteSize); + var V2 := new MemorySegment(VecByteSize); var W := KernelArg.FromRecord(MatrW); diff --git a/InstallerSamples/OpenGL и OpenCL/OpenCLABC/0Простейшие примеры/SimpleAddition.pas b/InstallerSamples/OpenGL и OpenCL/OpenCLABC/0Простейшие примеры/SimpleAddition.pas index 2d50ff7fd..af6a92929 100644 --- a/InstallerSamples/OpenGL и OpenCL/OpenCLABC/0Простейшие примеры/SimpleAddition.pas +++ b/InstallerSamples/OpenGL и OpenCL/OpenCLABC/0Простейшие примеры/SimpleAddition.pas @@ -8,20 +8,20 @@ begin // Подготовка параметров - var A := new Buffer( 10 * sizeof(integer) ); // Буфер достаточного размера, чтобы хранить 10 элементов типа "integer" + var A := new CLArray(10); // Выполнение prog['TEST'].Exec1(10, // Используем 10 ядер - // Заполняем весь буфер значениями (1), прямо перед выполнением - // Тип значения integer, потому что это тип по-умолчанию для целых чисел - A.NewQueue.AddFillValue(1) + // Заполняем весь массив значениями (1), прямо перед выполнением + //ToDo Разобраться почему надо KernelArg.From + KernelArg.FromCLArrayCQ(A.NewQueue.AddFill(1)) ); // Чтение и вывод результата - A.GetArray1&.Println; // Читаем всё содержимое как одномерный массив с элементами типа "integer" + A.GetArray.Println; // Читаем всё содержимое как одномерный массив end. \ No newline at end of file diff --git a/InstallerSamples/OpenGL и OpenCL/OpenCLABC/Игра жизнь/Игра жизнь.cl b/InstallerSamples/OpenGL и OpenCL/OpenCLABC/Игра жизнь/Игра жизнь.cl new file mode 100644 index 000000000..175bc2e58 --- /dev/null +++ b/InstallerSamples/OpenGL и OpenCL/OpenCLABC/Игра жизнь/Игра жизнь.cl @@ -0,0 +1,29 @@ + + + +#define ValAt(B,X,Y) (B)[((X)+W)%W + ((Y)+W)%W * W] + +__constant int min_max_neighbours[2][2] = { + { 3, 3 }, + { 3, 4 }, +}; + +__kernel void CalcStep(__global uchar* B, __global uchar* B_temp, int W) +{ + int X = get_global_id(0); + int Y = get_global_id(1); + + int c = 0; + for (int dx = -1; dx<2; ++dx) + for (int dy = -1; dy<2; ++dy) + c += ValAt(B, X+dx, Y+dy); + uchar prev_alive = ValAt(B, X, Y); + + // Пока не смог заставить работать, поэтому нужен отдельный буфер B_temp... + //work_group_barrier(CLK_LOCAL_MEM_FENCE); + + ValAt(B_temp, X, Y) = min_max_neighbours[prev_alive][0]<=c && c<=min_max_neighbours[prev_alive][1]; + +} + + diff --git a/InstallerSamples/OpenGL и OpenCL/OpenCLABC/Игра жизнь/Игра жизнь.pas b/InstallerSamples/OpenGL и OpenCL/OpenCLABC/Игра жизнь/Игра жизнь.pas new file mode 100644 index 000000000..f43704b8e --- /dev/null +++ b/InstallerSamples/OpenGL и OpenCL/OpenCLABC/Игра жизнь/Игра жизнь.pas @@ -0,0 +1,77 @@ +## uses OpenCLABC, GraphWPF; + +try + var W := 200; + var fps := 20; + Window.Maximize; + + // Очередь состояний поля, ожидающих отрисовки + // Не путать с очередями команд OpenCLABC + var field_states_q := new System.Collections.Concurrent.ConcurrentQueue; + + BeginFrameBasedAnimation(frame-> + begin + var field: array[,] of byte; + while not field_states_q.TryDequeue(field) do Sleep(1); + Window.Title := $'Шаг №{frame}'; + + var min_window_size := Min(Window.Width, Window.Height); + var cell_w := min_window_size / W; + var dx := (Window.Width -min_window_size)/2; + var dy := (Window.Height-min_window_size)/2; + GraphWPF.FastDraw(dc-> + begin + for var x := 0 to W-1 do + for var y := 0 to W-1 do + GraphWPF.DrawRectangleDC(dc, + dx + cell_w*x, dy + cell_w*y, + cell_w, cell_w, + if field[x,y]<>0 then Colors.DarkRed else Colors.Green, + Colors.Transparent,0 + ); + end); + + end, fps); + + //ToDo Использовать CLArray2 когда будет + var B := new MemorySegment(W*W*sizeof(byte)); + B.WriteArray2&(MatrGen(W,W, (x,y)->byte(Random(2)))); + var B_temp := new MemorySegment(B.Size); + + var code := new ProgramCode(ReadAllText('Игра жизнь.cl')); + + var Q_1Step := + code['CalcStep'] + .NewQueue + .AddExec2(W,W, + B, B_temp, W + ) + + B.NewQueue.AddCopyForm(B_temp) + ; + var Q_Otp := + B.NewQueue + .AddGetArray2&(W,W) + .ThenConvert&(field-> + begin + // Если уже слишком далеко вперёд насчитали - можно немного отдохнуть + while field_states_q.Count=16 do Sleep(1000 div fps); + field_states_q.Enqueue(field); + Result := field; + end) + ; + + while true do + begin + Context.Default.SyncInvoke( + Q_1Step + + Q_Otp + ); + end; + +except + on e: Exception do + begin + Writeln(e); + Halt; + end; +end; \ No newline at end of file diff --git a/InstallerSamples/OpenGL и OpenCL/OpenCLABC/Прекомпиляция ProgramCode/Использовать.pas b/InstallerSamples/OpenGL и OpenCL/OpenCLABC/Прекомпиляция ProgramCode/Использовать.pas index 006c47b33..d42233d4b 100644 --- a/InstallerSamples/OpenGL и OpenCL/OpenCLABC/Прекомпиляция ProgramCode/Использовать.pas +++ b/InstallerSamples/OpenGL и OpenCL/OpenCLABC/Прекомпиляция ProgramCode/Использовать.pas @@ -11,14 +11,15 @@ begin // Дальше всё так же как в "0Простейшие примеры\SimpleAddition" - var A := new Buffer( 10 * sizeof(integer) ); + var A := new CLArray(10); - prog['TEST'].Exec1(10, + prog['TEST'].Exec1(10, // Используем 10 ядер - A.NewQueue.AddFillValue(1) + //ToDo Разобраться почему надо KernelArg.From + KernelArg.FromCLArrayCQ(A.NewQueue.AddFill(1)) ); - A.GetArray1&.Println; + A.GetArray.Println; end. \ No newline at end of file diff --git a/InstallerSamples/OpenGL и OpenCL/Справка OpenCLABC.html b/InstallerSamples/OpenGL и OpenCL/Справка OpenCLABC.html index cfa49fa39..706c18621 100644 --- a/InstallerSamples/OpenGL и OpenCL/Справка OpenCLABC.html +++ b/InstallerSamples/OpenGL и OpenCL/Справка OpenCLABC.html @@ -1,4 +1,5 @@ - + +