NVIDIA Warp:高性能GPU模拟与图形计算的Python框架
NVIDIA Warp是一个用于编写高性能模拟和图形代码的Python框架。它能够将普通的Python函数即时编译(JIT)成高效的内核代码,这些代码可以在CPU或GPU上运行。Warp专为空间计算设计,提供了丰富的原语,使物理模拟、感知、机器人和几何处理等程序的编写变得简单。此外,Warp内核是可微分的,可以作为机器学习管道的一部分与PyTorch、JAX和Paddle等框架一起使用。
本文将详细介绍NVIDIA Warp的安装部署方法、核心功能以及通过实例展示其在各种模拟场景中的应用。
文章目录
GTC 2025 中文在线解读| CUDA最新特性与未来 [WP72383]
NVIDIA GTC大会火热进行中,一波波重磅科技演讲让人应接不暇,3月24日,NVIDIA 企业开发者社区邀请Ken He、Yipeng Li两位技术专家,面向开发者,以中文深度拆解GTC2025四场重磅开发技术相关会议,直击AI行业应用痛点,破解前沿技术难题!
作为GPU计算领域的基石,CUDA通过其编程语言、编译器、运行时环境及核心库构建了完整的计算生态,驱动着人工智能、科学计算等前沿领域的创新发展。在本次在线解读活动中,将由CUDA架构师深度解析GPU计算生态的核心技术演进。带您了解今年CUDA平台即将推出的众多新功能,洞悉CUDA及GPU计算技术的未来发展方向。
时间:3月24日18:00-19:00
中文解读:Ken He / Developer community
链接:link: https://www.nvidia.cn/gtc-global/session-catalog/?tab.catalogallsessionstab=16566177511100015Kus&search=WP72383%3B%20WP72450%3B%20WP73739b%3B%20WP72784a%20#/session/1739861154177001cMJd=
目录
安装与部署
系统要求
- Python版本:推荐Python 3.9或更新版本
- 支持的CPU:x86-64和ARMv8 CPU(Windows、Linux和macOS)
- GPU支持:需要支持CUDA的NVIDIA GPU和驱动程序(最低要求GeForce GTX 9xx)
基本安装
最简单的安装方法是通过PyPI:
pip install warp-lang
如果需要运行示例和USD相关功能,可以安装附加依赖:
pip install warp-lang[extras]
这相当于手动安装以下依赖:
pip install usd-core matplotlib pyglet
CUDA要求
PyPI上托管的二进制文件目前是使用CUDA 12运行时构建的,因此需要最低版本的CUDA驱动程序:
- Linux x86-64:525.60.13
- Windows x86-64:528.33
旧版CUDA驱动支持
如果您的系统有较旧的CUDA驱动程序,但仍需要GPU支持,可以从GitHub Releases页面安装使用CUDA 11.8运行时构建的wheel文件:
平台 | 安装命令 |
---|---|
Linux aarch64 | pip install https://github.com/NVIDIA/warp/releases/download/v1.6.2/warp_lang-1.6.2+cu11-py3-none-manylinux2014_aarch64.whl |
Linux x86-64 | pip install https://github.com/NVIDIA/warp/releases/download/v1.6.2/warp_lang-1.6.2+cu11-py3-none-manylinux2014_x86_64.whl |
Windows x86-64 | pip install https://github.com/NVIDIA/warp/releases/download/v1.6.2/warp_lang-1.6.2+cu11-py3-none-win_amd64.whl |
可能需要使用--force-reinstall
选项来覆盖之前的安装。
夜间构建版本
Warp的main
分支夜间构建版本可在NVIDIA Package Index上获取:
pip install -U --pre warp-lang --extra-index-url=https://pypi.nvidia.com/
注意,夜间构建版本使用CUDA 12运行时构建,且不为macOS发布。
如果您计划定期安装夜间构建版本,可以通过设置PIP_EXTRA_INDEX_URL
环境变量来简化未来的安装:
export PIP_EXTRA_INDEX_URL="https://pypi.nvidia.com"
CUDA驱动要求总结
- 使用CUDA Toolkit 11.x构建的Warp包需要NVIDIA驱动470或更新版本
- 使用CUDA Toolkit 12.x构建的Warp包需要NVIDIA驱动525或更新版本
驱动兼容性检查
Warp在初始化期间会检查已安装的驱动程序,如果驱动程序不合适,将报告警告,例如:
Warp UserWarning:
Insufficient CUDA driver version.
The minimum required CUDA driver version is 12.0, but the installed CUDA driver version is 11.8.
Visit https://github.com/NVIDIA/warp/blob/main/README.md#installing for guidance.
这将使CUDA设备不可用,但仍然可以使用CPU。
解决驱动兼容性问题
如果遇到驱动兼容性问题,有几个选项:
- 更新驱动程序
- 安装兼容的预构建Warp包
- 使用与已安装驱动程序兼容的CUDA Toolkit从源代码构建Warp
Warp核心概念
Warp的核心是一个即时编译(JIT)系统,它将Python函数转换为可以在CPU或GPU上高效运行的内核代码。以下是Warp的一些核心概念:
内核函数
在Warp中,使用@wp.kernel
装饰器定义的函数会被编译为可在GPU上并行执行的内核。例如:
import warp as wp
import numpy as np
@wp.kernel
def length(points: wp.array(dtype=wp.vec3),
lengths: wp.array(dtype=float)):
# 线程索引
tid = wp.tid()
# 计算每个点到原点的距离
lengths[tid] = wp.length(points[tid])
数据类型
Warp提供了丰富的内置数据类型,包括:
- 标量类型:
float
,int
,bool
等 - 向量类型:
vec2
,vec3
,vec4
等 - 矩阵类型:
mat22
,mat33
,mat44
等 - 四元数类型:
quat
数组和内存管理
Warp提供了高效的数组类型,可以在CPU和GPU之间无缝传输数据:
# 创建Warp数组
points = wp.array(np.random.rand(1024, 3), dtype=wp.vec3)
lengths = wp.zeros(1024, dtype=float)
启动内核
使用wp.launch
函数来执行内核:
# 启动内核
wp.launch(
kernel=length,
dim=len(points),
inputs=[points, lengths]
)
案例分析
下面我们将通过三个具体案例来展示Warp的强大功能:离散元法(DEM)粒子模拟、流体模拟和移动立方体算法。
离散元法(DEM)粒子模拟
离散元法是一种用于模拟颗粒材料行为的数值方法。在这个示例中,我们将展示如何使用Warp实现带有粒子间凝聚力的DEM模拟。上图展示了使用Warp模拟的颗粒材料堆积效果,可以看到粒子之间的相互作用和堆积形态。
核心代码
首先,我们定义一个计算接触力的函数:
@wp.func
def contact_force(n: wp.vec3, v: wp.vec3, c: float, k_n: float, k_d: float, k_f: float, k_mu: float):
"""
计算接触力函数
参数:
n: 法线向量
v: 相对速度
c: 接触深度
k_n: 法向刚度系数
k_d: 阻尼系数
k_f: 摩擦系数
k_mu: 库仑摩擦系数
返回:
接触力向量
"""
# 计算法向速度分量
vn = wp.dot(n, v)
# 计算法向弹性力
jn = c * k_n
# 计算法向阻尼力(只在接触压缩时生效)
jd = min(vn, 0.0) * k_d
# 总法向接触力
fn = jn + jd
# 计算切向速度分量
vt = v - n * vn
vs = wp.length(vt)
# 归一化切向速度方向
if vs > 0.0:
vt = vt / vs
# 库仑条件:切向力不能超过法向力乘以摩擦系数
ft = wp.min(vs * k_f, k_mu * wp.abs(fn))
# 返回总力(法向力+切向力)
return -n * fn - vt * ft
然后,我们定义应用力的内核函数:
@wp.kernel
def apply_forces(
grid: wp.uint64,
particle_x: wp.array(dtype=wp.vec3),
particle_v: wp.array(dtype=wp.vec3),
particle_f: wp.array(dtype=wp.vec3),
radius: float,
k_contact: float,
k_damp: float,
k_friction: float,
k_mu: float,
):
"""
应用力的内核函数
计算每个粒子受到的力,包括地面接触力和粒子间接触力
"""
# 获取线程ID
tid = wp.tid()
# 按网格单元排序线程
i = wp.hash_grid_point_id(grid, tid)
# 获取当前粒子的位置和速度
x = particle_x[i]
v = particle_v[i]
# 初始化力向量
f = wp.vec3()
# 计算地面接触
n = wp.vec3(0.0, 1.0, 0.0) # 地面法线向上
c = wp.dot(n, x) # 计算到地面的距离
# 凝聚力参数
cohesion_ground = 0.02 # 与地面的凝聚距离
cohesion_particle = 0.0075 # 粒子间的凝聚距离
# 如果粒子在凝聚距离内,计算与地面的接触力
if c < cohesion_ground:
f = f + contact_force(n, v, c, k_contact, k_damp, 100.0, 0.5)
# 计算粒子间接触
# 查询在指定半径内的所有邻近粒子
neighbors = wp.hash_grid_query(grid, x, radius * 5.0)
# 遍历所有邻近粒子
for index in neighbors:
if index != i: # 排除自身
# 计算到邻近粒子的距离
n = x - particle_x[index]
d = wp.length(n)
err = d - radius * 2.0 # 计算实际距离与理想距离(两倍半径)的差
# 如果在凝聚距离内,计算接触力
if err <= cohesion_particle:
n = n / d # 归一化方向向量
vrel = v - particle_v[index] # 相对速度
# 计算并累加接触力
f = f + contact_force(n, vrel, err, k_contact, k_damp, k_friction, k_mu)
# 存储计算得到的力
particle_f[i] = f
最后,我们定义积分更新内核函数:
@wp.kernel
def integrate(
x: wp.array(dtype=wp.vec3),
v: wp.array(dtype=wp.vec3),
f: wp.array(dtype=wp.vec3),
gravity: wp.vec3,
dt: float,
inv_mass: float,
):
"""
积分更新内核函数
根据力和重力更新粒子的速度和位置
"""
tid = wp.tid()
# 使用半隐式欧拉积分更新速度和位置
v_new = v[tid] + f[tid] * inv_mass * dt + gravity * dt
x_new = x[tid] + v_new * dt
# 更新粒子状态
v[tid] = v_new
x[tid] = x_new
模拟结果
DEM模拟可以用于模拟各种颗粒材料的行为,如沙子、土壤和岩石。通过调整参数,我们可以模拟不同材料的特性,如摩擦、弹性和凝聚力。上图展示的模拟结果显示了颗粒材料的自然堆积行为,这在地质工程、采矿和材料处理等领域有广泛应用。
流体模拟
流体模拟是计算机图形学和物理模拟中的一个重要领域。在这个示例中,我们将展示如何使用Warp实现一个简单的2D稳定流体求解器。上图展示了使用Warp模拟的流体动态效果,可以看到流体的流动和涡旋形成的过程。
核心代码
首先,我们定义一些辅助函数来处理流体场的采样:
@wp.func
def sample_float(f: wp.array2d(dtype=float), x: float, y: float):
"""
对二维浮点数组进行双线性插值采样
参数:
f: 二维浮点数组
x, y: 采样坐标(可以是非整数)
返回:
插值后的值
"""
# 计算左下角整数坐标
lx = int(wp.floor(x))
ly = int(wp.floor(y))
# 计算插值系数
tx = x - float(lx)
ty = y - float(ly)
# 在x方向上进行线性插值
s0 = wp.lerp(lookup_float(f, lx, ly), lookup_float(f, lx + 1, ly), tx)
s1 = wp.lerp(lookup_float(f, lx, ly + 1), lookup_float(f, lx + 1, ly + 1), tx)
# 在y方向上进行线性插值
s = wp.lerp(s0, s1, ty)
return s
然后,我们定义平流内核函数:
@wp.kernel
def advect(
u0: wp.array2d(dtype=wp.vec2),
u1: wp.array2d(dtype=wp.vec2),
rho0: wp.array2d(dtype=float),
rho1: wp.array2d(dtype=float),
dt: float,
):
"""
半拉格朗日平流内核
使用当前速度场回溯粒子位置,并从源位置采样速度和密度
"""
i, j = wp.tid() # 获取当前线程的二维索引
# 获取当前位置的速度
u = u0[i, j]
# 回溯粒子路径
p = wp.vec2(float(i), float(j))
p = p - u * dt # 向后追踪粒子
# 从回溯位置采样速度和密度
u1[i, j] = sample_vel(u0, p[0], p[1])
rho1[i, j] = sample_float(rho0, p[0], p[1])
接下来,我们定义散度计算和压力求解内核:
@wp.kernel
def divergence(u: wp.array2d(dtype=wp.vec2), div: wp.array2d(dtype=float)):
"""
计算速度场的散度
散度表示流体的压缩或膨胀率
"""
i, j = wp.tid()
# 边界检查
if i == grid_width - 1:
return
if j == grid_height - 1:
return
# 计算x和y方向的速度差分
dx = (u[i + 1, j][0] - u[i, j][0]) * 0.5
dy = (u[i, j + 1][1] - u[i, j][1]) * 0.5
# 计算散度
div[i, j] = dx + dy
模拟结果
流体模拟可以用于各种应用,如游戏、电影特效、工程分析等。通过Warp,我们可以高效地实现复杂的流体动力学模型,并在GPU上并行计算,大大提高模拟性能。上图展示的模拟结果显示了流体的自然流动和涡旋形成,这种模拟在气象学、海洋学和航空航天等领域有重要应用。
移动立方体算法
移动立方体算法(Marching Cubes)是一种从体素数据中提取等值面的经典算法,广泛应用于医学成像、科学可视化和计算机图形学。上图展示了使用Warp实现的移动立方体算法生成的3D模型,可以看到从体素数据中提取出的平滑曲面。
核心代码
首先,我们定义一个函数来生成体素场:
@wp.func
def implicit_sphere(x: float, y: float, z: float, cx: float, cy: float, cz: float, r: float):
"""
计算点到球体的有符号距离场
参数:
x, y, z: 查询点坐标
cx, cy, cz: 球体中心坐标
r: 球体半径
返回:
有符号距离(负值表示在球体内部)
"""
dx = x - cx
dy = y - cy
dz = z - cz
return wp.sqrt(dx*dx + dy*dy + dz*dz) - r
然后,我们定义一个内核来计算体素场:
@wp.kernel
def compute_field(
field: wp.array3d(dtype=float),
dx: float,
time: float
):
"""
计算3D体素场
使用隐式函数定义的几何体生成有符号距离场
"""
i, j, k = wp.tid()
# 计算体素中心的世界坐标
x = float(i) * dx
y = float(j) * dx
z = float(k) * dx
# 使用多个球体的混合创建动态场
# 第一个球体
d1 = implicit_sphere(
x, y, z,
0.5 + 0.1 * wp.sin(time * 1.5),
0.5 + 0.1 * wp.cos(time),
0.5,
0.2
)
# 第二个球体
d2 = implicit_sphere(
x, y, z,
0.7,
0.5,
0.5 + 0.1 * wp.sin(time * 2.0),
0.15
)
# 使用平滑最小函数混合两个球体
field[i, j, k] = wp.min(d1, d2)
最后,我们使用Warp的内置函数来执行移动立方体算法:
# 使用Warp的marching_cubes函数从体素场中提取等值面
verts, tris = wp.marching_cubes(field, 0.0)
应用场景
移动立方体算法在许多领域有广泛应用:
- 医学成像:从CT或MRI扫描数据中重建3D模型
- 科学可视化:显示流体密度、温度场等物理量的等值面
- 计算机图形学:生成程序化地形、流体表面和其他复杂几何形状
- 3D打印:从体素数据生成可打印的网格模型
通过Warp的高性能实现,我们可以实时处理大规模体素数据,并生成高质量的三角形网格。上图展示的结果显示了从动态变化的体素场中提取的平滑曲面,这种技术在交互式应用和实时可视化中特别有用。
总结与展望
NVIDIA Warp为高性能模拟和图形计算提供了一个强大而灵活的Python框架。通过将Python函数即时编译为高效的内核代码,Warp使开发者能够轻松编写在CPU和GPU上高效运行的并行代码。
本文介绍了Warp的安装部署方法、核心概念,并通过三个具体案例展示了其在不同模拟场景中的应用:离散元法(DEM)粒子模拟、流体模拟和移动立方体算法。这些案例展示了Warp在物理模拟、计算流体动力学和几何处理等领域的强大能力。
Warp的可微分性使其能够与现代机器学习框架无缝集成,为物理模拟与机器学习的结合提供了新的可能性。随着NVIDIA继续改进和扩展Warp的功能,我们可以期待看到更多创新的应用在游戏开发、电影特效、科学研究和工程分析等领域涌现。
如果您对高性能模拟和图形计算感兴趣,NVIDIA Warp无疑是一个值得探索的强大工具。通过其简洁的Python接口和强大的GPU加速能力,Warp使复杂的模拟和计算变得更加简单和高效。