本次实验编写了一个基于oneAPI的C++/SYCL程序来执行矩阵乘法操作。考虑了大尺寸矩阵的乘法操作和不同线程之间的数据依赖关系,实现了并行矩阵乘法。本文基于intel DevCloud平台完成。
一、熟悉Intel DevCloud开发环境
Intel DevCloud 专门为边缘计算设计的云开发平台,开发者可基于平台开发应用程序,构建容器,部署应用,监测设备运行,最终完成产品上市前的性能评估和硬件选型。在官方网站初次注册后,就可以获得120天的免费云计算资源。
本次实验使用JupyterLab 环境开发。
Intel提供了如下计算资源:
二、编写调试代码,得出结果
此次实验的任务是将五个矩阵依次并行乘法计算后得出计算结果,五个矩阵文件分别是matrix0.txt,matrix1.txt,matrix2.txt,matrix3.txt,matrix4.txt。这五个矩阵的行列都小于128x128,故使用128x128的矩阵即可解决五个矩阵行列不整齐的问题。
#include <CL/sycl.hpp>
#include <iostream>
constexpr size_t N = 128;
int main() {
std::vector<double> matrixA(N * N, 0.0f);
std::vector<double> matrixB(N * N, 0.0f);
std::vector<double> matrixC(N * N, 0.0f);
for (int i = 0; i < 4; i++) { //进行四次矩阵乘法
if (i == 0) {
std::ifstream in1("matrix0.txt"); //读入矩阵
if(!in1) {
std::cerr<<"Failed to open file."<<"\n";
exit(1);
}
std::string line;
int ff = 0;
while(std::getline(in1, line)) {
std::stringstream ss(line);
int temp = ff;
while(ss) {
ss >> matrixA[temp];
temp++;
}
ff += N;
}
}
std::string file = "matrix" + std::to_string(i+1) + ".txt"; //读入矩阵
std::ifstream in2(file);
if(!in2) {
std::cerr<<"Failed to open file."<<"\n";
exit(1);
}
std::string line;
int ff = 0;
while(std::getline(in2, line)) {
std::stringstream ss(line);
int temp = ff;
while(ss) {
ss >> matrixB[temp];
temp++;
}
ff += N;
}
try {
sycl::queue myQueue;
sycl::range<2> size(N, N);
sycl::buffer<double, 2> bufferA(matrixA.data(), size);
sycl::buffer<double, 2> bufferB(matrixB.data(), size);
sycl::buffer<double, 2> bufferC(matrixC.data(), size);
myQueue.submit([&](sycl::handler& cgh) {
auto accessorA = bufferA.get_access<sycl::access::mode::read>(cgh);
auto accessorB = bufferB.get_access<sycl::access::mode::read>(cgh);
auto accessorC = bufferC.get_access<sycl::access::mode::write>(cgh);
cgh.parallel_for<class MatrixMultiply>(size, [=](sycl::id<2> idx) {
double sum = 0.0f;
for (int k = 0; k < N; ++k) {
sum += accessorA[idx[0]][k] * accessorB[k][idx[1]];
}
accessorC[idx] = sum;
});
});
myQueue.wait();
} catch (sycl::exception const& e) {
std::cerr << "An exception occurred: " << e.what() << std::endl;
return 1;
}
matrixB = matrixC;
}
// 打印结果
for (size_t i = 0; i < 66; ++i) {
for (size_t j = 0; j < 54; ++j) {
std::cout << matrixC[i * N + j] << " ";
}
std::cout << std::endl;
}
return 0;
}
打开Terminal终端
切换到相应文件夹后,使用icpx -fsycl dpc.cpp -o dpc编译dpc.cpp文件,得到dpc后执行得到结果矩阵,共66行54列。
三、总结
本次实验使用oneAPI的sycl库实现了并行矩阵乘法,同时Intel DevCloud提供了裸机开发环境和容器化开发环境。登录平台后不需要对环境做任何配置,即可使用浏览器随时访问Intel DevCloud上的教程和参考实例,无需考虑软硬件兼容问题,可以把更多精力用于自己应用程序的开发,提供了高效便捷的开发环境。