part of update
This commit is contained in:
parent
57d2c7c650
commit
ebc3c8725e
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,20 +8,20 @@ begin
|
|||
|
||||
// Подготовка параметров
|
||||
|
||||
var A := new Buffer( 10 * sizeof(integer) ); // Буфер достаточного размера, чтобы хранить 10 элементов типа "integer"
|
||||
var A := new CLArray<integer>(10);
|
||||
|
||||
// Выполнение
|
||||
|
||||
prog['TEST'].Exec1(10, // Используем 10 ядер
|
||||
|
||||
// Заполняем весь буфер значениями (1), прямо перед выполнением
|
||||
// Тип значения integer, потому что это тип по-умолчанию для целых чисел
|
||||
A.NewQueue.AddFillValue(1)
|
||||
// Заполняем весь массив значениями (1), прямо перед выполнением
|
||||
//ToDo Разобраться почему надо KernelArg.From
|
||||
KernelArg.FromCLArrayCQ(A.NewQueue.AddFill(1))
|
||||
|
||||
);
|
||||
|
||||
// Чтение и вывод результата
|
||||
|
||||
A.GetArray1&<integer>.Println; // Читаем всё содержимое как одномерный массив с элементами типа "integer"
|
||||
A.GetArray.Println; // Читаем всё содержимое как одномерный массив
|
||||
|
||||
end.
|
||||
|
|
@ -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];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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<array[,] of byte>;
|
||||
|
||||
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<byte> когда будет
|
||||
var B := new MemorySegment(W*W*sizeof(byte));
|
||||
B.WriteArray2&<byte>(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&<byte>(W,W)
|
||||
.ThenConvert&<array[,] of byte>(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;
|
||||
|
|
@ -11,14 +11,15 @@ begin
|
|||
|
||||
// Дальше всё так же как в "0Простейшие примеры\SimpleAddition"
|
||||
|
||||
var A := new Buffer( 10 * sizeof(integer) );
|
||||
var A := new CLArray<integer>(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&<integer>.Println;
|
||||
A.GetArray.Println;
|
||||
|
||||
end.
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
<html>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
|
|
@ -14,6 +15,7 @@ body {
|
|||
|
||||
.page-base {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#splitter {
|
||||
|
|
@ -26,6 +28,7 @@ body {
|
|||
margin: 7.5px;
|
||||
background-color: white;
|
||||
overflow: auto;
|
||||
flex-grow: 1;
|
||||
}
|
||||
#page-select-container {
|
||||
white-space: nowrap;
|
||||
|
|
@ -58,11 +61,11 @@ body {
|
|||
}
|
||||
.ps-folder-name {
|
||||
cursor: pointer;
|
||||
padding: 1;
|
||||
padding: 1;
|
||||
}
|
||||
.ps-container {
|
||||
margin-left: 7;
|
||||
padding-left: 7;
|
||||
margin-left: 7px;
|
||||
padding-left: 7px;
|
||||
border-left: thin solid;
|
||||
border-color: #80808080;
|
||||
}
|
||||
|
|
@ -71,7 +74,7 @@ body {
|
|||
}
|
||||
.ps-page-name {
|
||||
cursor: pointer;
|
||||
padding: 1;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
/* ============================== *\
|
||||
|
|
@ -985,18 +988,28 @@ begin
|
|||
var dvc := Context.Default.MainDevice;
|
||||
|
||||
Writeln('Поддерживаемые типы .Spilt-ов:');
|
||||
// Пустой список, или DEVICE_PARTITION_BY_COUNTS_LIST_END, если ни 1 не поддерживается
|
||||
dvc.Properties.PartitionProperties.PrintLines;
|
||||
var partition_properties := dvc.Properties.PartitionProperties;
|
||||
if (partition_properties.Length=0) or (partition_properties[0].val = System.IntPtr.Zero) then
|
||||
begin
|
||||
Writeln('Ничего не поддерживается...');
|
||||
exit;
|
||||
end else
|
||||
partition_properties.PrintLines;
|
||||
Writeln('='*30);
|
||||
|
||||
Writeln('Виртуальные устройства, по 1 ядру каждое:');
|
||||
// Если упадёт потому что слишком много
|
||||
// устройств - пожалуйста, напишите в issue
|
||||
dvc.SplitEqually(1).PrintLines;
|
||||
if dvc.CanSplitEqually then
|
||||
// Если упадёт потому что слишком много
|
||||
// устройств - пожалуйста, напишите в issue
|
||||
dvc.SplitEqually(1).PrintLines else
|
||||
Writeln('Не поддерживается...');
|
||||
Writeln('='*30);
|
||||
|
||||
Writeln('Два устройства, 1 и 2 ядра соответственно:');
|
||||
dvc.SplitByCounts(1,2).PrintLines;
|
||||
if dvc.CanSplitByCounts then
|
||||
dvc.SplitByCounts(1,2).PrintLines else
|
||||
Writeln('Не поддерживается...');
|
||||
Writeln('='*30);
|
||||
|
||||
end.
|
||||
</code></pre>
|
||||
|
|
@ -1061,7 +1074,7 @@ begin
|
|||
end.
|
||||
</code></pre>
|
||||
</div>
|
||||
<script>on_start_folder("Buffer", document.getElementById("page-7"))</script>
|
||||
<script>on_start_folder("Виды памяти", document.getElementById("page-7"))</script>
|
||||
<script>on_end_folder()</script>
|
||||
<div id="page-8" page_name="" hidden=true>
|
||||
<p>Объект типа <code>Kernel</code> представляет одну подпрограмму в OpenCL-C коде,
|
||||
|
|
@ -1403,7 +1416,7 @@ end;
|
|||
</ol>
|
||||
</div>
|
||||
<script>on_start_folder("Создание очередей", document.getElementById("page-15"))</script>
|
||||
<div id="page-16" page_name="Из буфера или kernel'a" hidden=true>
|
||||
<div id="page-16" page_name="Из объекта с коммандами" hidden=true>
|
||||
<p>Самый просто способ создать очередь — выбрать объект типа <code>Buffer</code> или <code>Kernel</code> и вызвать для него метод <code>.NewQueue</code>.</p>
|
||||
<p>Полученная очередь будет иметь особый тип: <code>BufferCommandQueue</code>/<code>KernelCommandQueue</code> для буфера/kernel'а соответственно.<br />
|
||||
К такой очереди можно добавлять команды, вызывая её методы, имена которых начинаются с <code>.Add...</code>.</p>
|
||||
|
|
@ -1983,11 +1996,10 @@ begin
|
|||
|
||||
var Q2 := HPQ(()->lock output do Writeln('Выполнилась Q2'));
|
||||
var Q3 := HPQ(()->lock output do Writeln('Выполнилась Q3'));
|
||||
var Q4 := HPQ(()->lock output do Writeln('Выполнилась Q4'));
|
||||
|
||||
var t := Context.Default.BeginInvoke(
|
||||
( WaitFor(Q1)+Q3 ) *
|
||||
( WaitFor(Q1)+Q4 )
|
||||
( WaitFor(Q1)+Q2 ) *
|
||||
( WaitFor(Q1)+Q3 )
|
||||
);
|
||||
Q1.SendSignal;
|
||||
Context.Default.SyncInvoke(Q1);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
<html>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
|
|
@ -14,6 +15,7 @@ body {
|
|||
|
||||
.page-base {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#splitter {
|
||||
|
|
@ -26,6 +28,7 @@ body {
|
|||
margin: 7.5px;
|
||||
background-color: white;
|
||||
overflow: auto;
|
||||
flex-grow: 1;
|
||||
}
|
||||
#page-select-container {
|
||||
white-space: nowrap;
|
||||
|
|
@ -58,11 +61,11 @@ body {
|
|||
}
|
||||
.ps-folder-name {
|
||||
cursor: pointer;
|
||||
padding: 1;
|
||||
padding: 1;
|
||||
}
|
||||
.ps-container {
|
||||
margin-left: 7;
|
||||
padding-left: 7;
|
||||
margin-left: 7px;
|
||||
padding-left: 7px;
|
||||
border-left: thin solid;
|
||||
border-color: #80808080;
|
||||
}
|
||||
|
|
@ -71,7 +74,7 @@ body {
|
|||
}
|
||||
.ps-page-name {
|
||||
cursor: pointer;
|
||||
padding: 1;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
/* ============================== *\
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue