基于因特尔OneAPI实现矩阵并行乘法运算

这篇具有很好参考价值的文章主要介绍了基于因特尔OneAPI实现矩阵并行乘法运算。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于因特尔OneAPI实现矩阵并行乘法运算

OneAPI介绍

Intel oneAPI 是一个跨行业、开放、基于标准的统一的编程模型,旨在提供一个适用于各类计算架构的统一编程模型和应用程序接口。其核心思想是使开发者只需编写一次代码,便可在跨平台的异构系统上运行,支持的底层硬件架构包括 CPU、GPU、FPGA、神经网络处理器以及其他专为不同应用设计的硬件加速器等。这意味着,oneAPI不仅提高了开发效率,同时具备一定的性能可移植性。通过采用这一编程模型,开发者能够更灵活地利用不同类型的硬件,充分发挥各种计算资源的潜力,从而更好地适应不同应用场景的需求。

问题描述

编写⼀个基于oneAPI的C++/SYCL程序来执行矩阵乘法操作,需要考虑大尺寸矩阵的乘法操作以及不同线程之间的数据依赖关系。

实现思路

运行代码使用因特尔的云平台Get Started | Intel® DevCloud,进入oneapi/essential,然后进入02-SYCL-Program-Structure

编码方面利用基于SYCL的编程模型在GPU上实现矩阵乘法的计算,步骤如下:

  1. 分配内存:在主机端分配内存空间用于存储输⼊矩阵和输出矩阵,同时在GPU端分配内存空间用于存储相应 的输入和输出数据。

  2. 数据传输:将输入矩阵数据从主机端内存传输到GPU端内存中。

  3. 核函数调用:在SYCL中,矩阵乘法的计算通常会在GPU上使用核函数来实现并行计算。核函数 会分配线程块和线程来处理不同的数据块。

  4. 并行计算:在核函数中,每个线程负责计算输出矩阵的⼀个单独的元素。为了最大限度地利用 GPU的并行计算能力,通常会使用⼆维线程块和线程网格的方式来处理矩阵的乘法计算。

  5. 数据传输:计算完成后,将输出矩阵数据从GPU端内存传输回主机端内存中,以便进⼀步处理或 分析。

在并行计算矩阵乘法时,可以利用线程块和线程的层次结构来优化计算。通过合理划分矩阵数据并利用共享内 存来减少全局内存访问的次数,可以⼤幅提高计算效率。此外,还可以利用GPU上的多个计算单元并执行行矩 阵乘法,进⼀步提高计算速度

代码详解

 %%writefile lab/vector_add.cpp
 //==============================================================
 // Copyright © Intel Corporation
 //
 // SPDX-License-Identifier: MIT
 // =============================================================
 #include <sycl/sycl.hpp>
 #include <iostream>
 #include <vector>
 #include <random>
  
 using namespace sycl;
 using namespace std;
  
 class CustomDeviceSelector {
  public:
   CustomDeviceSelector(std::string vendorName) : vendorName_(vendorName){};
   int operator()(const device &dev) {
     int device_rating = 0;
     if (dev.is_gpu() & (dev.get_info<info::device::name>().find(vendorName_) !=
                         std::string::npos))
       device_rating = 3;
     else if (dev.is_gpu())
       device_rating = 2;
     else if (dev.is_cpu())
       device_rating = 1;
     return device_rating;
   };
  
  private:
   std::string vendorName_;
 };
  
 int main() {
     const int N = 1024;
     
     //二维数组
     vector<vector<float>> matrix1(N, vector<float>(N));
     vector<vector<float>> matrix2(N, vector<float>(N));
     vector<vector<float>> matrix3(N, vector<float>(N));
     //初始化
     random_device rd;
     mt19937 rng(rd());
     uniform_int_distribution<int> dist(0, 2); 
  
     for (size_t i = 0; i < N; i++) {
         for (size_t j = 0; j < N; j++) {
             matrix1[i][j] = dist(rng);
             matrix2[i][j] = dist(rng);
         }
     }
     
     cout<<"\nmatrix1:\n";
      for (size_t i=0;i<N;i++)
 {
     for (size_t j=0;j<N;j++){
         cout<<matrix1[i][j]<<" ";
     }
     cout<<"\n";
 }
     cout<<"\nmatrix2:\n";
      for (size_t i=0;i<N;i++)
 {
     for (size_t j=0;j<N;j++){
         cout<<matrix2[i][j]<<" ";
     }
     cout<<"\n";
 }
     //Create buffers
     buffer<float, 2> Matrix1_buffer(reinterpret_cast<float*>(matrix1.data()), range<2>(N, N));
     buffer<float, 2> Matrix2_buffer(reinterpret_cast<float*>(matrix2.data()), range<2>(N, N));
     buffer<float, 2> Output_buffer(reinterpret_cast<float*>(matrix3.data()), range<2>(N, N));
  
  
     //Choose device
     std::string vendor_name = "Intel";
     CustomDeviceSelector selector(vendor_name);
     
  
     //Submit task to multiply matrices
     queue q(selector);
     q.submit([&](handler &h) {
       //# Create accessors for buffers
       accessor M1 (Matrix1_buffer,h,read_only);
       accessor M2 (Matrix2_buffer,h,read_only);
       accessor M3 (Output_buffer,h,write_only);
  
       h.parallel_for(nd_range<2>({N, N}, {64, 64}), [=](nd_item<2> item) {
           //# Multiplication
           size_t row = item.get_global_id(0);
           size_t col = item.get_global_id(1);
           for (size_t k = 0; k < N; ++k) {
               M3[row][col] += M1[row][k] * M2[k][col];
           }
         });
     });
  
  
     //Create accessor
     host_accessor h_a(Output_buffer, read_write);
  
     
     cout << "\nmatrix3:\n";
     for (size_t i = 0; i < N; i++) {
         for (size_t j = 0; j < N; j++) {
             cout << matrix3[i][j] << " ";
         }
         cout << "\n";
     }
     return 0;
 }

使用统一共享内存(USM)

统一共享内存(USM)在主机和设备(GPU)之间提供了一个统一的存储模式。通过用以下代码修改程序以使用统一共享内存来实现内存分配和数据转换,从而替代缓存和存储。(主要内容不变,仅仅改变了存储方式)

     //# USM allocation using malloc_shared
     float *M1 = malloc_shared<float>(Size, q);
     float *M2 = malloc_shared<float>(Size, q);
     float *M3 = malloc_shared<float>(Size, q);
     
     //# Initialize matrices A and B with random values
     std::mt19937 rng(42);
     uniform_int_distribution<int> dist(0, 4); 
     //std::uniform_real_distribution<float> dist(0.0, 1.0);
     for (size_t i = 0; i < Size; i++) {
         M1[i] = dist(rng);
         M2[i] = dist(rng);
         M3[i]=0;
     }
     std::cout<<"\nInput Matrix1:\n";    
     for (size_t i = 0; i < N; i++) {
         for (size_t j = 0; j < N; j++) {
             std::cout << M1[i*N+j] << " ";
         }
         std::cout << "\n";
     }
     std::cout<<"\nInput Matrix2:\n";    
     for (size_t i = 0; i < N; i++) {
         for (size_t j = 0; j < N; j++) {
             std::cout << M2[i*N+j] << " ";
         }
         std::cout << "\n";
     }
 ​
     q.parallel_for(nd_range<2>({N, N}, {16, 16}), [=](nd_item<2> item) {
       //# Multiplication
       size_t row = item.get_global_id(0);
       size_t col = item.get_global_id(1);
       for (size_t k = 0; k < N; ++k) {
           M3[row*N+col] += M1[row*N+k] * M2[k*N+col];
       }
     });
 ​
     //# Print Output values 
     std::cout<<"\nOutput Values:\n";
     for (size_t i = 0; i < N; i++) {
         for (size_t j = 0; j < N; j++) {
             std::cout << M3[i*N+j] << " ";
         }
         std::cout << "\n";
     }
     free(M1, q);
     free(M2, q);
     free(M3, q);
 ​
 ​

总结

通过本次实验学会了如何运用SYCL来进行并行编程,学会了因特尔OneAPI的工具和库函数来进行矩阵乘法运算,了解了因特尔的平台的运用方法,很方便,直接在网站上就可以运行自己的并行运算代码,增深了对高性能计算和并行处理的理解。

感谢因特尔相关团队提供的技术支持和云平台的支持。文章来源地址https://www.toymoban.com/news/detail-767422.html

到了这里,关于基于因特尔OneAPI实现矩阵并行乘法运算的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [oneAPI] 基于BERT预训练模型的SWAG问答任务

    比赛:https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Intel® DevCloud for oneAPI:https://devcloud.intel.com/oneapi/get_started/aiAnalyticsToolkitSamples/ 在Intel® DevCloud for oneAPI平台上,我们搭建了实验环境,充分发挥其完全虚拟化的优势,使我们能够专注于模型开发和优化,无需过多关心底层配

    2024年02月11日
    浏览(27)
  • [oneAPI] 基于BERT预训练模型的命名体识别任务

    比赛:https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Intel® DevCloud for oneAPI:https://devcloud.intel.com/oneapi/get_started/aiAnalyticsToolkitSamples/ 在本次实验中,我们在Intel® DevCloud for oneAPI上搭建实验,借助完全虚拟化的环境,专注于模型开发与优化,无需关心底层配置。使用Intel® Opti

    2024年02月12日
    浏览(25)
  • oneAPI人工智能分析工具包实现图像处理

    oneAPI是一个由英特尔(Intel)主导的、面向异构计算的开放标准和平台。它旨在简化和加速跨多种硬件架构的应用程序开发,包括CPU、GPU、FPGA和其他加速器。 以下是关于oneAPI发展的一些要点: 1.创立背景和目标: oneAPI的发展始于英特尔意识到在异构计算时代,开发者面临的

    2024年02月11日
    浏览(36)
  • Intel oneAPI笔记--oneAPI简介、SYCL编程简介

    Intel oneAPI是Intel提供的统一编程模型和软件开发框架。 它旨在简化可充分利用英特尔各种硬件架构(包括 CPU、GPU 和 FPGA)的应用程序的开发 oneAPI一个重要的特性是开放性,支持多种类型的架构和不同的硬件供应商,是一种统一的编程模型。使得开发人员拥有可以选择最佳硬

    2024年02月06日
    浏览(24)
  • 矩阵乘法实现卷积运算

            矩阵根据卷积核的大小进行,从左到右、从上到i 下 的移动,对应数据相乘再相加得到的数据为该区域的值。 ​​​​​​​ ​​​​​​​         原理:根据对于相乘相加的机制,发现通过对卷积核填零构成和输入矩阵大小一致的矩阵,然后展平拼接起来,

    2024年02月12日
    浏览(34)
  • [oneAPI] 手写数字识别-BiLSTM

    比赛:https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Intel® DevCloud for oneAPI:https://devcloud.intel.com/oneapi/get_started/aiAnalyticsToolkitSamples/ 使用了pytorch以及Intel® Optimization for PyTorch,通过优化扩展了 PyTorch,使英特尔硬件的性能进一步提升,让手写数字识别问题更加的快速高效 使用

    2024年02月12日
    浏览(27)
  • [oneAPI] Neural Style Transfer

    比赛:https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Intel® DevCloud for oneAPI:https://devcloud.intel.com/oneapi/get_started/aiAnalyticsToolkitSamples/ Neural Style Transfer是一种使用 CNN 将一幅图像的内容与另一幅图像的风格相结合的算法。给定内容图像和风格图像,目标是生成最小化与内容图像

    2024年02月12日
    浏览(22)
  • FastGPT配置文件及OneAPI程序:

    FastGPT配置文件及OneAPI程序: 百度网盘 请输入提取码 提取码:wuhe 创建fastgpt目录:mkdir fastgpt 切换到fastgpt目录:cd fastgpt 下载docker-compose文件:curl -O https://raw.githubusercontent.com/labring/FastGPT/main/files/deploy/fastgpt/docker-compose.yml 下载config文件:curl -O https://raw.githubusercontent.com/labr

    2024年02月21日
    浏览(20)
  • [oneAPI] 使用Bert进行中文文本分类

    比赛:https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Intel® DevCloud for oneAPI:https://devcloud.intel.com/oneapi/get_started/aiAnalyticsToolkitSamples/ 在本次实验中,我们利用PyTorch和Intel® Optimization for PyTorch的强大功能,对PyTorch进行了精心的优化和扩展。这些优化举措极大地增强了PyTorch在各

    2024年02月12日
    浏览(32)
  • [oneAPI] 使用字符级 RNN 生成名称

    比赛:https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Intel® DevCloud for oneAPI:https://devcloud.intel.com/oneapi/get_started/aiAnalyticsToolkitSamples/ 为了深入探索语言模型在分类和生成方面的卓越能力,我们特意设计了一个独特的任务。此任务的独特之处在于,它旨在综合学习多种语言的词

    2024年02月11日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包