Mojo的特征与参数(参数化部分)详解
许多语言都具有元编程功能:即编写生成或修改代码的代码。Python 具有动态元编程功能:装饰器、元类等功能。这些功能使 Python 非常灵活且高效,但由于它们是动态的,因此会产生运行时开销。其他语言具有静态或编译时元编程功能,如 C 预处理器宏和 C++ 模板。这些功能可能受到限制且难以使用。
为了支持 Modular 在 AI 领域的工作,Mojo 旨在提供功能强大、易于使用且运行时成本为零的元编程。这种编译时元编程使用与运行时程序相同的语言,因此您无需学习新语言 - 只需学习一些新功能即可。
主要新功能是参数。您可以将参数视为编译时变量,该变量将成为运行时常量。这种“参数”用法可能与您在其他语言中习惯的用法不同,在其他语言中,“参数”和“参数”通常可以互换使用。在 Mojo 中,“参数”和“参数表达式”指的是编译时值,而“参数”和“表达式”指的是运行时值。
在 Mojo 中,您可以向结构或函数添加参数。您还可以定义命名参数表达式(别名),将其用作运行时常量。
参数化函数
要定义参数化函数,请在参数列表前面的方括号中添加参数。每个参数的格式与参数一样:参数名称,后跟冒号和类型(必填)。在以下示例中,该函数有一个参数count类型为Int。
fn repeat[count: Int](msg: String):@parameterfor i in range(count):print(msg)
@parameter此处显示的指令导致在for编译时评估循环。仅当循环限制是编译时常量时,该指令才有效。由于count是参数, 因此range(count)可以在编译时计算。
调用参数化函数时,您可以为参数提供值,就像函数参数一样:
repeat[3]("Hello")
输出:
Hello
Hello
Hello
编译器在编译期间解析参数值,并为每个唯一参数值创建函数的具体版本repeat。解析参数值并展开循环后,该repeat3 函数大致相当于:
fn repeat_3(msg: String):print(msg)print(msg)print(msg)
这并不代表编译器生成的实际代码。在解析参数时,Mojo 代码已经转换为MLIR中的中间表示。
如果编译器无法将所有参数值解析为常量值,则编译失败。
参数和泛型
“泛型”是指可以作用于多种类型值的函数,或可以容纳多种类型值的容器。例如, List可以容纳不同类型的值,因此您可以拥有一个值列表Int,或一个String值列表。
在 Mojo 中,泛型使用参数来指定类型。例如,List 采用类型参数,因此整数向量写为List[Int]。因此,所有泛型都使用参数,但并非所有使用参数的东西都是泛型。
例如,repeat上一节中的函数包含类型为 的形参Int和类型为 的实参String。它是参数化的,但不是泛型的。泛型函数或结构体在类型上是参数化的。例如,我们可以重写repeat以采用符合以下Stringable特征的任何类型的参数:
fn repeat[MsgType: Stringable, count: Int](msg: MsgType):@parameterfor i in range(count):print(msg)# Must use keyword parameter for `count`
repeat[count=2](42)
输出:
42
42
此更新的函数接受任何Stringable类型,因此您可以向其传递Int、 String或Bool值。
如果不指定 ,则不能将count作为位置关键字传递MsgType。您可以将其放在//后面MsgType以指定它始终由参数推断。现在您可以按count位置传递以下参数:
fn repeat[MsgType: Stringable, //, count: Int](msg: MsgType):@parameterfor i in range(count):print(msg)# MsgType is always inferred, so first positional keyword `2` is passed to `count`
repeat[2](42)
Mojo 对泛型的支持还处于早期阶段。您可以使用特征和参数编写这样的泛型函数。您还可以编写像 List和这样的泛型集合。
参数化结构
您还可以向结构体添加参数。您可以使用参数化结构体来构建通用容器。例如,通用数组类型可能包含如下代码:
from memory.unsafe_pointer import UnsafePointer, initialize_pointee_copy, destroy_pointeestruct GenericArray[ElementType: CollectionElement]:var data: UnsafePointer[ElementType]var size: Intfn __init__(inout self, *elements: ElementType):self.size = len(elements)self.data = UnsafePointer[ElementType].alloc(self.size)for i in range(self.size):initialize_pointee_move(self.data.offset(i), elements[i])fn __del__(owned self):for i in range(self.size):destroy_pointee(self.data.offset(i))self.data.free()fn __getitem__(self, i: Int) raises -> ref [__lifetime_of(self)] ElementType:if (i < self.size):return self.data[i]else:raise Error("Out of bounds")
该结构体有一个参数,ElementType它是您想要存储在数组中的数据类型的占位符,有时称为类型参数。ElementType其类型为 CollectionElement,它是一种 表示可以复制和移动的任何类型的特征。
与参数化函数一样,使用参数化结构体时需要传入参数值。在这种情况下,创建的实例时 GenericArray,需要指定要存储的类型,如Int、 或 Float64。(这有点令人困惑,因为在这种情况下传递的参数值是类型。没关系:Mojo 类型是有效的编译时值。)
您将看到它ElementType在整个结构体中被使用,而您通常会看到类型名称。例如,作为elements构造函数中的正式类型,以及方法的返回类型__getitem__()。
以下是使用的示例GenericArray:
var array = GenericArray[Int](1, 2, 3, 4)
for i in range(array.size):print(array[i], end=" ")
输出:
1
2
3
4
参数化结构体可以使用类型Self来表示结构体的具体实例(即指定了所有参数)。例如,您可以添加一个静态工厂方法,GenericArray其签名如下:
struct GenericArray[ElementType: CollectionElement]:...@staticmethodfn splat(count: Int, value: ElementType) -> Self:# Create a new array with count instances of the given value
这里,Self相当于写成GenericArray[ElementType]。也就是说,你可以像splat()这样调用该方法:
GenericArray[Float64].splat(8, 0)
该方法返回 的一个实例GenericArray[Float64]。
案例研究:SIMD类型
为了得到参数化类型的真实示例,让我们看一下Mojo中的SIMD标准库中的类型。
单指令多数据 (SIMD)是许多现代 CPU、GPU 和自定义加速器内置的并行处理技术。SIMD 允许您同时对多个数据执行单个操作。例如,如果您想对数组中每个元素求平方根,则可以使用 SIMD 来并行化工作。
处理器使用硬件中的低级向量寄存器来实现 SIMD,这些寄存器可保存标量数据类型的多个实例。为了在这些处理器上使用 SIMD 指令,必须将数据调整为适当的 SIMD 宽度(数据类型)和长度(向量大小)。处理器可能支持 512 位或更长的 SIMD 向量,并支持从 8 位整数到 64 位浮点数的多种数据类型,因此定义所有可能的 SIMD 变体并不实际。
Mojo 的SIMD类型(定义为结构)通过其方法公开常见的 SIMD 操作,并使 SIMD 数据类型和大小值参数化。这允许您将数据直接映射到任何硬件上的 SIMD 向量。
以下是 Mojo 类型定义的精简版(非功能性版本)SIMD:
struct SIMD[type: DType, size: Int]:var value: … # Some low-level MLIR stuff here# Create a new SIMD from a number of scalarsfn __init__(inout self, *elems: SIMD[type, 1]): ...# Fill a SIMD with a duplicated scalar value.@staticmethodfn splat(x: SIMD[type, 1]) -> SIMD[type, size]: ...# Cast the elements of the SIMD to a different elt type.fn cast[target: DType](self) -> SIMD[target, size]: ...# Many standard operators are supported.fn __add__(self, rhs: Self) -> Self: ...
因此,您可以像这样创建和使用 SIMD 向量:
var vector = SIMD[DType.int16, 4](1, 2, 3, 4)
vector = vector * vector
for i in range(4):print(vector[i], end=" ")
输出:
1
4
9
16
如您所见,将简单的算术运算符*应用于一对 SIMD向量会对每个向量中的相应元素进行运算。
使用参数定义每个 SIMD 变体非常有利于代码重用,因为类型 SIMD可以静态地表达所有不同的向量变体,而不需要语言预先定义每个变体。
由于SIMD是参数化类型,self其函数中的参数会携带这些参数 — 完整类型名称是SIMD[type, size]。虽然将其写出是有效的(如 的返回类型所示splat()),但这可能很冗长,因此我们建议像示例中那样使用Self类型(来自 PEP673
相关文章:
Mojo的特征与参数(参数化部分)详解
许多语言都具有元编程功能:即编写生成或修改代码的代码。Python 具有动态元编程功能:装饰器、元类等功能。这些功能使 Python 非常灵活且高效,但由于它们是动态的,因此会产生运行时开销。其他语言具有静态或编译时元编程功能,如 C 预处理器宏和 C++ 模板。这些功能可能受到…...
C++数组、vector求最大值最小值及其下标
使用 <algorithm> 头文件来查找数组或向量中最大值、最小值及其索引 #include <iostream> #include <vector> #include <algorithm> // 包含 std::max_element 和 std::min_elementint main() {std::vector<int> vec {3, 1, 4, 2, 5};// 查找最…...
内网安全:多种横向移动方式
1.MMC20.Application远程执行命令 2.ShellWindows远程执行命令 3.ShellBrowserWindow远程执行命令 4.WinRM远程执行命令横向移动 5.使用系统漏洞ms17010横向移动 DCOM: DCOM(分布式组件对象模型)是微软的一系列概念和程序接口。它支持不同…...
搭建 STM32 网关服务器的全流程:集成嵌入式 C++、TCP/IP 通信、Flash 存储及 JWT 认证(含代码示例)
引言 随着物联网(IoT)技术的快速发展,基于 STM32 的服务器(类似网关)在数据采集、设备控制等方面的应用越来越广泛。本文将介绍搭建一个基于 STM32 的服务器所需的技术栈,以及详细的搭建步骤和代码示例。 …...
一款免费强大的电脑锁屏工具,中文绿色免安装
这款软件主要特点是锁屏后不显示密码输入框,直接输入密码即可解锁。 ScreenBlur是一款功能强大的电脑屏幕锁软件,主要用于保护用户的隐私和数据安全。该软件的主要功能包括自动锁屏、隐藏桌面、加密锁机等。 功能特点 自动锁屏:用户可以设…...
Python | Leetcode Python题解之第319题灯泡开关
题目: 题解: class Solution:def bulbSwitch(self, n: int) -> int:return int(sqrt(n 0.5))...
前端Web-JavaScript(上)
要想让网页具备一定的交互效果,具有一定的动作行为,还得通过JavaScript来实现, 这门语言会让我们的页面能够和用户进行交互。 什么是JavaScript JavaScript(简称:JS) 是一门跨平台、面向对象的脚本语言,是…...
【积累】Python的类
类和方法的概念及实例 类 (Class):类是对具有相同属性和方法的对象集合的抽象描述。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。 方法:类中定义的函数。 构造方法 __init__():这是一个特殊的方法,会在类实例…...
Golang | Leetcode Golang题解之第318题最大单词长度乘积
题目: 题解: func maxProduct(words []string) (ans int) {masks : map[int]int{}for _, word : range words {mask : 0for _, ch : range word {mask | 1 << (ch - a)}if len(word) > masks[mask] {masks[mask] len(word)}}for x, lenX : ra…...
【感想】支持八股文在面试的应用
八股文:程序员面试中的利与弊 在现代社会的职场竞争中,尤其是IT行业,面试环节常常成为决定一个人能否入职的重要关卡。在这其中,“八股文”作为一种被广泛应用的考核工具,已经成为面试中不可或缺的一部分。然而&#…...
B - 02-计算球的体积 51Nod - 3266
对于半径为 rr 的球,其体积的计算公式为 V4/3πr3V4/3πr3 ,这里取 π3.14π3.14 。现给定 rr ,求 VV 。 Input 输入为一个不超过 100100 的非负实数,即球半径,类型为 doubledouble 。 Output 输出一个实数&#x…...
Qt pro文件详解
概述 在Qt中,.pro 文件(也称为项目文件)是Qt项目管理系统(qmake)所使用的配置文件。这个文件定义了如何构建你的Qt应用程序或库,其使用简单的键值对语法,允许你指定源文件、头文件、库依赖、配置…...
JavaFX布局-ButtonBar
JavaFX布局-ButtonBar 常用属性buttonOrderpaddingbuttonMinWidth 实现方式Java实现fxml实现 一个特殊的容器,用于创建一组按钮,水平排列按钮太多,会被遮住,不会自动产生滚动条 常用属性 buttonOrder 预制顺序 buttonBar.setBut…...
【C++程序设计】——利用数组处理批量数据(二)
👨💻个人主页:开发者-削好皮的Pineapple! 👨💻 hello 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 削好皮的Pineapple! 原创 👨Ǵ…...
使用 1panel面板 部署 php网站
代码仓库:https://github.com/talmudmaster/RedCorpus 目录 网站介绍安装步骤1. 准备云服务器2. 准备域名(可跳过)3. 安装1panel面板4. 服务器开放端口5. 进入1panel面板6. 安装并启动软件(服务器和面板开放端口)7. 创…...
Windows调大虚拟内存来代替升级物理运行内存(RAM)真的有用吗?
前言 前段时间有个粉丝突发奇想说:电脑运行内存不足,调大虚拟内存来代替升级物理运行内存(内存条)不就可以了?剩下的大几百块钱吃香的喝辣的不好吗? 嗯。。。直到2024年的今天,估计还有很多小…...
[Unity] ShaderGraph实现DeBuff污染 溶解叠加效果
本篇是在之前的基础上,继续做的功能衍生。 [Unity] ShaderGraph实现Sprite消散及受击变色 完整连连看如下所示:...
java算法day28
java算法day28 300 最长递增子序列136 只出现一次的数字169 多数元素234 回文链表53 最大子数组和 300 最长递增子序列 这个是记忆化搜索的代码。是从递归改过来的。 这题显然是要用dp做比较合适。因为很容易看到原问题与子问题之间的关系。 还是从后往前看。 然后可以利用选…...
vue实现歌词滚动效果
1.结构 <template><div class"lyricScroll"><div class"audio"><audio id"audio" src"./common/周传雄-青花1.mp3" controls></audio></div><div class"container" id"contai…...
【算法设计题】合并两个非递减有序链表,第1题(C/C++)
目录 第1题 合并两个非递减有序链表 得分点(必背) 题解 函数声明与初始化变量: 初始化合并链表的头节点: 合并两个链表: 处理剩余节点: 返回合并后的链表: 完整测试代码 🌈…...
Vue前端工程
创建一个工程化的vue项目 npm init vuelatest 全默认回车就好了 登录注册校验 //定义数据模型 const registerDataref({username:,password:,rePassword: }) //校验密码的函数 const checkRePassword(rule,value,callback)>{if (value){callback(new Error(请再次输入密…...
什么是药物临床试验?
药物临床试验是指在人体上进行的新药试验研究,旨在确定新药的疗效、安全性、药代动力学和药效学。临床试验不仅帮助确认药物是否对特定疾病或症状有效,还帮助识别和评估药物的副作用和风险。 药物临床试验(Clinical Trial,CT&…...
编译和汇编的区别
一、编译 编译是将高级语言(如C、C、Java等)编写的源代码转换成计算机可以直接执行的低级语言(通常是机器语言或汇编语言)的过程 编译 —— 将人类可读的源代码转换为计算机可执行的指令集 编译过程 通常包括词法分析、语法分…...
C# 设计倒计时器、串口助手开发
文章目录 1. 实现一个简单的倒计时器开始、暂停2. 串口助手开发 1. 实现一个简单的倒计时器开始、暂停 namespace Timer {public partial class Form1 : Form{int count;//用于定时器计数int time;//存储设定的定时值bool parse false;//控制暂停计时public Form1(){Initiali…...
图论① dfs | Java | LeetCode 797,Kama 98 邻接表实现(未完成)
797 所有可能路径 https://leetcode.cn/problems/all-paths-from-source-to-target/description/ 输入:graph [[1,2],[3],[3],[]] 题目分析,这里 class Solution {//这个不是二维数组,而是listList<List<Integer>> res new Ar…...
Mac安装nvm以及配置环境变量
安装nvm brew install nvm安装成功后会出现这样一段话: Add the following to your shell profile e.g. ~/.profile or ~/.zshrc:export NVM_DIR"$HOME/.nvm"[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh&q…...
AUTOSAR实战教程-使用DET来发现开发错误
2年之前因为在调试AUTOSAR存储协议栈的时候使用DET并没发现有用的信息,所以就武断下结论--这玩意没有用。活到老学到老吧,bug经历的多了,发现这玩意还挺有用的。说一下这个bug的背景。 在将时间同步报文改道CanTsync之后,由于这个AUTOSAR工具本身的问题以及配置工程师本身的…...
ZeroMQ(二):请求-响应模式,C和C++。
目录 请求响应基础 基本概念 工作流程 典型应用 请求-响应模式的特点 应用实例 优点 缺点 ZEROMQ C语言 2.1 服务器端代码(Reply Server) 2.2 客户端代码(Request Client) 3. 编译代码 4. 详细说明 ZEROMQ C 1. …...
【虚拟仿真】Unity3D中实现2DUI显示在3D物体旁边
推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址QQ群:398291828大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 这篇文章来实现2DUI显示在3D物体旁边,当我们需要在3D模型旁边显示2DUI的时候,比如人物的对…...
代码随想录 day 29 贪心
第八章 贪心算法 part03 134. 加油站 本题有点难度,不太好想,推荐大家熟悉一下方法二 https://programmercarl.com/0134.%E5%8A%A0%E6%B2%B9%E7%AB%99.html 135. 分发糖果 本题涉及到一个思想,就是想处理好一边再处理另一边,不…...
网站建设 成功案例/seo咨询邵阳
Python处理图片九宫格,炫酷朋友圈前言在日常的生活中,大家偶尔会看到朋友圈发的照片由一张被切成九张的效果,有时由一张照片被切成九张照片所带来的视觉盛宴是不一样的!现在许多 P 图工具里面自带了这种功能,而微信小程…...
网站推广的方法及技巧/正规网络教育培训机构
转载于:https://www.cnblogs.com/fanweisheng/p/11250459.html...
怎么关闭自己公司网站/百度广告推广费用年费
Oracle RAC,全称是Oracle Real Application Cluster,顾名思义即为真正的应用集群,整个集群系统由Oracle Clusterware (集群就绪软件)和 Real Application Clusters(RAC)两大部分组成。RAC的主要优点为高可用…...
杭州 网站外包/推广app赚钱的平台
本文讲的是黑客全军覆没 书生安全云实战各路高手,武术之道讲究形神兼备,内外合一。然世间习武者,多钻研外功者,却少见恒练内功之人。皆因外功一事,习之便利,所费时日既短又少,而无论所习何种内功…...
聊城做移动网站服务/百度营销推广登录平台
水平对齐方式--text-align属性 left 左 默认值 right 右 center 中 justify 两端对齐垂直对齐--vertical-align属性 middle top bottom 转载于:https://www.cnblogs.com/Bhi9712/p/7057660.html...
河北 建设厅网站首页/聊城网站推广公司
以下是我自工作以来,结合对C/S项目的认知,对B/S项目的一些理解。如有不足或者错误,请各位指正。由于个人一开始入门时是ASP.NET MVC,是一个比较完善、完整的框架,下面仅对JAVA的web应用框架进行简单介绍。对于JEE Serv…...