Vitis HLS 学习笔记--Stream Chain Matrix Multiplication

目录

1. 简介

2. 示例解析

2.1 示例功能说明

2.2 函数说明 

2.2.1 mmult 函数

2.2.2 mm2s 函数

2.2.3 s2mm 函数

2.2.4 总示意图

3. 总结


1. 简介

这是一个包含使用数据流的级联矩阵乘法的内核。该内核启用了 ap_ctrl_chain,以展示如何重叠多个内核调用队列以提供更高的性能。 ap_ctrl_chain 允许内核在完成当前内核操作之前开始处理下一个内核操作。

2. 示例解析

2.1 示例功能说明

这个例子展示了链式内核和简单内核之间的性能差异。

#pragma HLS INTERFACE s_axilite port = return bundle = control
#pragma HLS INTERFACE ap_ctrl_chain port = return bundle = control

示例包含两个内核:

1. krnl_simple_mmult:使用 ap_ctrl_hs 协议的内核。

#pragma HLS INTERFACE ap_ctrl_hs port = return

2. krnl_chain_mmult:使用 ap_ctrl_chain 协议的内核;

#pragma HLS INTERFACE ap_ctrl_chain port = return

ap_ctrl_chain 实现一组块级控制端口,用于启动设计操作、继续操作,并指示设计何时空闲、完成以及准备好新的输入数据。 ap_ctrl_chain 接口模式与 ap_ctrl_hs 类似,但提供额外的输入信号 ap_continue 来施加背压。 Xilinx 建议在将 Vivado HLS 块链接在一起时使用 ap_ctrl_chain 块级 I/O 协议。

#include "ap_axi_sdata.h"
#include "ap_int.h"
#include "hls_stream.h"
#include "krnl_mmult.hpp"
extern "C" {
void krnl_simple_mmult(int* a, int* b, int* c, int* d, int* output, int dim) {
#pragma HLS INTERFACE m_axi port = a offset = slave bundle = gmem0
#pragma HLS INTERFACE m_axi port = b offset = slave bundle = gmem1
#pragma HLS INTERFACE m_axi port = c offset = slave bundle = gmem2
#pragma HLS INTERFACE m_axi port = d offset = slave bundle = gmem3
#pragma HLS INTERFACE m_axi port = output offset = slave bundle = gmem3
#pragma HLS INTERFACE s_axilite port = a
#pragma HLS INTERFACE s_axilite port = b
#pragma HLS INTERFACE s_axilite port = c
#pragma HLS INTERFACE s_axilite port = d
#pragma HLS INTERFACE s_axilite port = output
#pragma HLS INTERFACE s_axilite port = dim
#pragma HLS INTERFACE s_axilite port = return
#pragma HLS INTERFACE ap_ctrl_hs port = return#pragma HLS STABLE variable = a
#pragma HLS STABLE variable = b
#pragma HLS STABLE variable = c
#pragma HLS STABLE variable = d
#pragma HLS STABLE variable = outputhls::stream<pkt> strm_a, strm_b, strm_c, strm_d;hls::stream<int> strm_ctrl_trans1, strm_ctrl_trans2, strm_ctrl_trans3, strm_ctrl_trans4, strm_ctrl_trans5;int tmp = dim;strm_ctrl_trans1.write(tmp);#pragma HLS STREAM variable = strm_ctrl_trans1 depth = 2
#pragma HLS STREAM variable = strm_ctrl_trans2 depth = 2
#pragma HLS STREAM variable = strm_ctrl_trans3 depth = 2
#pragma HLS STREAM variable = strm_ctrl_trans4 depth = 2
#pragma HLS STREAM variable = strm_ctrl_trans5 depth = 2#pragma HLS STREAM variable = strm_a depth = 64
#pragma HLS STREAM variable = strm_b depth = 64
#pragma HLS STREAM variable = strm_c depth = 64
#pragma HLS STREAM variable = strm_d depth = 64#pragma HLS DATAFLOWmm2s(a, strm_a, strm_ctrl_trans1, strm_ctrl_trans2);mmult(strm_a, b, strm_ctrl_trans2, strm_b, strm_ctrl_trans3);mmult(strm_b, c, strm_ctrl_trans3, strm_c, strm_ctrl_trans4);mmult(strm_c, d, strm_ctrl_trans4, strm_d, strm_ctrl_trans5);s2mm(strm_d, output, strm_ctrl_trans5);
}
}

2.2 函数说明 

  • mm2s 函数:这个函数将矩阵的行读入并写入一个流,同时发送控制信号以指示矩阵的大小。
  • mmult 函数:这个函数实现了矩阵乘法。它首先读取控制信号来确定矩阵的大小。然后,它创建了四个临时数组来存储矩阵的行、列、乘积和最终结果。接下来,它使用三个循环来计算每个结果元素的值,通过将相应行和列的元素相乘和相加得到。
  • s2mm 函数:这个函数将矩阵的结果读入并写入一个流,同时发送控制信号以指示矩阵的大小。

下面分别对三个函数展开说明:

2.2.1 mmult 函数

// Template to avoid signature conflict in sw_em
template <int DUMMY = 0>
void mmult(hls::stream<pkt>& strm_a,int* b,hls::stream<int>& strm_ctrl_trans2,hls::stream<pkt>& strm_out,hls::stream<int>& strm_ctrl_trans3) {int dim = strm_ctrl_trans2.read();strm_ctrl_trans3.write(dim);int size = dim * dim;int buf_a[MAT_DIM][MAT_DIM];int buf_b[MAT_DIM][MAT_DIM];int buf_out[MAT_DIM][MAT_DIM];int temp_sum[MAT_DIM];int i, j, itr;// Auto-pipeline is going to apply pipeline to these loops
read_strm_in1:for (itr = 0, i = 0, j = 0; itr < size; itr++, j++) {if (j == dim) {j = 0;i++;}pkt temp = strm_a.read();buf_a[i][j] = temp;}read_mm_in2:for (itr = 0, i = 0, j = 0; itr < size; itr++, j++) {if (j == dim) {j = 0;i++;}buf_b[i][j] = b[i * dim + j];}mmult_strm_1:for (int row = 0; row < dim; row++) {mmult_strm_2:for (int col = 0; col < dim; col++) {int result = 0;mmult_strm_3:for (int l = 0; l < dim; l++) {
// As the outer loop is not a perfect loop
#pragma HLS loop_flatten offresult += buf_a[row][l] * buf_b[l][col];}buf_out[row][col] = result;}}write_strm_out:for (itr = 0, i = 0, j = 0; itr < size; itr++, j++) {if (j == dim) {j = 0;i++;}pkt temp;temp = buf_out[i][j];strm_out.write(temp);}
}

2.2.2 mm2s 函数

template <int DUMMY = 0>
void mm2s(       int* a,hls::stream<pkt>& strm_a,hls::stream<int>& strm_ctrl_trans1,hls::stream<int>& strm_ctrl_trans2)
{int dim = strm_ctrl_trans1.read();strm_ctrl_trans2.write(dim);int size = dim * dim;// Auto-pipeline is going to apply pipeline to this loop
mm2s:for (int i = 0; i < size; i++) {pkt p1;p1 = a[i];strm_a.write(p1);}
}

2.2.3 s2mm 函数

template <int DUMMY = 0>
void s2mm(hls::stream<pkt>& strm_in,int* output,hls::stream<int>& strm_ctrl_trans5)
{int dim = strm_ctrl_trans5.read();int size = dim * dim;write_output:for (int i = 0; i < size; i++) {pkt temp = strm_in.read();output[i] = temp;}
}

 

2.2.4 总示意图

3. 总结

这个内核的核心功能是通过使用数据流和级联矩阵乘法来提高性能。它利用了 ap_ctrl_chain 协议,这允许内核在当前操作完成后立即开始下一个操作,从而实现了更高的并行性和效率。内核包含两个版本:简单的 krnl_simple_mmult 和链式的 krnl_chain_mmult。简单版本使用 ap_ctrl_hs 协议,而链式版本使用 ap_ctrl_chain 协议,后者提供了额外的控制信号来管理内核操作的流程。

示例代码展示了如何使用这些内核进行矩阵乘法。mm2s 函数读取矩阵的行并发送控制信号,mmult 实现了矩阵乘法操作,而 s2mm 函数将结果写入流。这些函数通过数据流和控制信号的协同工作,实现了高效的内核调用和数据处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/29418.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

防火墙规则来阻止攻击者的 IP 地址

1. iptables 要禁止服务器与特定 IP 地址的通信&#xff0c;可以使用防火墙来设置规则。在 Ubuntu 上&#xff0c;iptables 是一个常用的防火墙工具。以下是使用 iptables 设置禁止与特定 IP 通信的步骤&#xff1a; 阻止所有进出的通信 如果你想阻止服务器与特定 IP 地址的…

AES加解密工具类

文章目录 前言一、AES加解密工具类总结 前言 当涉及到数据的安全性和保密性时&#xff0c;加密是一种关键的技术手段。AES&#xff08;Advanced Encryption Standard&#xff09;是一种广泛使用的对称加密算法&#xff0c;被认为是目前最安全和最常用的加密算法之一。 一、AES…

2024年最好用的精简系统推荐!旧电脑福音!

精简版电脑系统经过精心优化&#xff0c;去除了冗余功能&#xff0c;保留了核心功能&#xff0c;让用户的操作更加便捷高效&#xff0c;同时也具备强大的兼容性和稳定性&#xff0c;整体操作体验感很好。但是&#xff0c;许多新手用户不知道在哪里才可以找到好用的精简版系统&a…

Mojo崛起:AI-first 的编程语言能否成为新流行?

眨眼之间&#xff0c;你可能会错过又一种编程语言的发明。 有个笑话说&#xff0c;程序员花费20%的时间编写代码&#xff0c;80%的时间决定使用什么语言。 事实上&#xff0c;编程语言如此之多&#xff0c;以至于我们不确定实际有多少种。据估计&#xff0c;至少有700种编程语…

【Android 11】AOSP Settings添加屏幕旋转按钮

前言 这里是客户要求添加按钮以实现屏幕旋转。屏幕旋转使用adb的命令很容易实现&#xff1a; #屏幕翻转 adb shell settings put system user_rotation 1 #屏幕正常模式 adb shell settings put system user_rotation 0这里的值可以是0&#xff0c;1&#xff0c;2&#xff0c…

中国天辰×蓝卓丨共创行业级工业操作系统,加速培育新质生产力!

6月17日&#xff0c;中国天辰工程有限公司&#xff08;以下简称“中国天辰”&#xff09;党委委员、总经理梁军湘一行莅临蓝卓&#xff0c;双方就工业互联网平台合作进行座谈交流。蓝卓总经理谭彰、副总经理蓝照斌、总经理助理俞益标&#xff0c;以及中控技术副总裁吴才宝、大客…

原生dom操作快速写入html渲染(insertAdjacentHTML)

// 旧方法 const btn document.createElement(div) btn.id material-btn-id btn.className material-btn btn.textContent 素材库 document.body.appendChild(btn) btn.addEventListener(click, () > {// 点击事件 }) // 新方法 const btn document.createElement(div…

软件开发小程序正规公司流程是什么样的?

正规软件开发的流程可以清晰地分为以下几个阶段&#xff0c;每个阶段都有其特定的目标和产出&#xff1a; 项目开发目的分析与确定&#xff1a; 此阶段主要是在软件开发商将开发项目确定下来之后&#xff0c;与需求方进行讨论&#xff0c;明确软件开发的目标及其具体需要实现…

NumPy 切片和索引

NumPy 切片和索引 NumPy 是 Python 中用于科学计算的核心库之一&#xff0c;它提供了一个强大的 N 维数组对象和许多用于操作这些数组的函数。在数据处理和数值计算中&#xff0c;切片和索引是常用的操作&#xff0c;它们允许我们有效地访问和修改数组的部分数据。本文将详细介…

调试的时候给打印加颜色

在 C 中&#xff0c;打印紫色文本通常涉及使用控制台的特定颜色输出。在大多数操作系统中&#xff0c;控制台颜色是通过特殊的转义序列来实现的。这些转义序列可以在输出文本之前插入&#xff0c;以改变文本的颜色、样式或其他属性。 使用 ANSI 转义序列 在 POSIX 兼容的系统&…

Altair 人工智能技术助力MABE预测消费者行为,实现设备性能优化

主要看点 行业&#xff1a; 家电行业 挑战&#xff1a; 企业面临的挑战是如何利用已收集的大量数据&#xff0c;深入了解消费者在产品使用过程中对某些保鲜程序的影响。 Altair 解决方案&#xff1a; Altair采用了Altair RapidMiner人工智能平台来解决问题&#xff0c;特别是…

QML Controls模块-标准对话框用法说明

文章目录 颜色对话框文件对话框字体对话框自定义对话框通知对话框在QML中,Qt提供了一个名为 QtQuick.Controls的模块,其中包含了一系列用户界面控件,可以用于创建现代化、响应式的用户界面。在QtQuick.Controls模块中,一些控件可以用来调用标准对话框,包括文件对话框、字体…

Java进阶示例

使用DataFrame和SQL查询处理数据 在Spark中&#xff0c;DataFrame是一种以结构化方式处理数据的强大工具&#xff0c;它允许用户以类似于SQL的方式操作数据&#xff0c;提供了比RDD更高的抽象层次和更好的性能。下面的示例将展示如何使用Spark SQL的DataFrame API来读取CSV数据…

docker安装消息队列mq中的rabbit服务

在现代化的分布式系统中&#xff0c;消息队列&#xff08;Message Queue, MQ&#xff09;已经成为了一种不可或缺的组件。RabbitMQ作为一款高性能、开源的消息队列软件&#xff0c;因其高可用性、可扩展性和易用性而广受欢迎。本文将详细介绍如何在Docker环境中安装RabbitMQ服务…

2024.6.18 刷题总结

2024.6.18 **每日一题** 2288.价格减免&#xff0c;这是一道纯字符串的题目&#xff0c;我们的目标是识别出字符串中的价格并将它替换为折扣后的数字。这道题利用了一些字符串的关键字&#xff1a; stringstream 是C标准库中的一个类&#xff0c;属于 <sstream> 头文件…

八股系列 Flink

Flink 和 SparkStreaming的区别 设计理念方面 SparkStreaming&#xff1a;使用微批次来模拟流计算&#xff0c;数据已时间为单位分为一个个批次&#xff0c;通过RDD进行分布式计算 Flink&#xff1a;基于事件驱动&#xff0c;是面向流的处理框架&#xff0c;是真正的流式计算…

网络学习(13)|Spring Boot中获取HTTP请求头(Header)内容的详细解析

文章目录 方法一&#xff1a;使用HttpServletRequest实现原理代码示例优点缺点适用场景 方法二&#xff1a;使用RequestContextHolder实现原理代码示例优点缺点适用场景 方法三&#xff1a;使用RequestHeader注解实现原理代码示例优点缺点适用场景 总结 在Spring Boot应用中&am…

访问学者谈CSC青年骨干教师项目出国经历及感受

CSC青年骨干教师出国研修项目实施已近20年&#xff0c;越来越多的青年教师成为该项目的受益者。知识人网小编推荐该项目资助老师谈谈在加拿大卡尔加里大学访学一年的经历及感受。 国家留学基金委&#xff08;以下简称CSC&#xff09;高等学校青年骨干教师出国研修项目&#xff…

41、商城系统(二十二):Sentinel实现熔断、降级、限流

目录 一、熔断、降级、限流 1.什么是熔断 2.什么是降级 3.什么是限流 二、整合Sentinel初体验 1.引入依赖 2.官网下载dashboard可视化页面 3.配置参数 4.启动服务 三、实时监控没数据,流控响应结果自定义 1.实时监控没有数据 2.自定义流控返回结果 四、解决rabbi…