100 lines
3.4 KiB
ObjectPascal
100 lines
3.4 KiB
ObjectPascal
uses OpenCLABC;
|
||
|
||
const
|
||
MatrW = 4; // можно поменять на любое положительное значение
|
||
|
||
VecByteSize = MatrW*8;
|
||
MatrByteSize = MatrW*MatrW*8;
|
||
|
||
begin
|
||
try
|
||
Randomize(0); // делает так, чтобы каждое выполнение давало одинаковый результат
|
||
|
||
// Чтение и компиляция .cl файла
|
||
|
||
{$resource MatrMlt.cl} // Засовывает файл MatrMlt.cl внуть .exe
|
||
// Вообще лучше прекомпилировать .cl файл (загружать в переменную ProgramCode)
|
||
// И сохранять с помощью метода ProgramCode.SerializeTo
|
||
// А полученный бинарник уже подключать через $resource
|
||
var code := new ProgramCode(Context.Default,
|
||
System.IO.StreamReader.Create(
|
||
System.Reflection.Assembly.GetExecutingAssembly.GetManifestResourceStream('MatrMlt.cl')
|
||
).ReadToEnd
|
||
);
|
||
|
||
// Подготовка параметров
|
||
|
||
'Матрица A:'.Println;
|
||
var A_Matr := MatrRandomReal(MatrW,MatrW,0,1).Println;
|
||
Writeln;
|
||
var A := new Buffer(MatrByteSize);
|
||
|
||
'Матрица B:'.Println;
|
||
var B_Mart := MatrRandomReal(MatrW,MatrW,0,1).Println;
|
||
Writeln;
|
||
var B := new Buffer(MatrByteSize);
|
||
|
||
var C := new Buffer(MatrByteSize);
|
||
|
||
'Вектор V1:'.Println;
|
||
var V1_Arr := ArrRandomReal(MatrW);
|
||
V1_Arr.Println;
|
||
Writeln;
|
||
var V1 := new Buffer(VecByteSize);
|
||
|
||
var V2 := new Buffer(VecByteSize);
|
||
|
||
var W := KernelArg.FromRecord(MatrW);
|
||
|
||
// (запись значений в параметры - позже, в очередях)
|
||
|
||
// Подготовка очередей выполнения
|
||
|
||
var Calc_C_Q :=
|
||
code['MatrMltMatr'].NewQueue.AddExec2(MatrW, MatrW, // Выделяем ядра в форме квадрата, всего MatrW*MatrW ядер
|
||
A.NewQueue.AddWriteArray2&<real>(A_Matr), // Тип в &<> надо указывать явно, потому что компилятор не может вычислить его из типа элементов массива
|
||
B.NewQueue.AddWriteArray2&<real>(B_Mart),
|
||
C,
|
||
W
|
||
);
|
||
|
||
var Otp_C_Q :=
|
||
C.NewQueue.AddReadArray2&<real>(A_Matr) +
|
||
HPQ(()->
|
||
begin
|
||
'Матрица С = A*B:'.Println;
|
||
A_Matr.Println;
|
||
Writeln;
|
||
end);
|
||
|
||
var Calc_V2_Q :=
|
||
code['MatrMltVec'].NewQueue.AddExec1(MatrW,
|
||
C,
|
||
V1.NewQueue.AddWriteArray1&<real>(V1_Arr),
|
||
V2,
|
||
W
|
||
);
|
||
|
||
var Otp_V2_Q :=
|
||
V2.NewQueue.AddReadArray1&<real>(V1_Arr) +
|
||
HPQ(()->
|
||
begin
|
||
'Вектор V2 = C*V1:'.Println;
|
||
V1_Arr.Println;
|
||
Writeln;
|
||
end);
|
||
|
||
// Выполнение всего и сразу асинхронный вывод
|
||
|
||
Context.Default.SyncInvoke(
|
||
|
||
Calc_C_Q +
|
||
Calc_V2_Q * Otp_C_Q + // Считать V2 и выводить C можно одновременно, поэтому тут *, т.е. параллельное выполнение
|
||
Otp_V2_Q
|
||
|
||
);
|
||
|
||
except
|
||
on e: Exception do Writeln(e); // Эта строчка позволяет выводить всю ошибку, если при выполнении Context.SyncInvoke возникла ошибка
|
||
end;
|
||
end. |