关于放置稀疏矩阵的问题

参考examples中mgpcg.py放置稀疏矩阵的写法,尝试如下放置一个5 x 5的二维field,称作a:

>>> import taichi as ti
[Taichi] mode=release
[Taichi] preparing sandbox at /tmp/taichi-rrbakpha
[Taichi] version 0.6.27, llvm 10.0.0, commit a34a6128, linux, python 3.6.9
>>> a = ti.field(dtype=ti.f32)
>>> ti.root.pointer(ti.ij, (5,5)).place(a)
[Taichi] materializing...
ti.root => pointer [5, 5]
>>> for i,j in ti.ndrange(3,3):
...     a[i,j] = 1.0
...
>>> for i,j in a:
...     print(a[i,j])
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'float' object is not iterable

结果是用range-for可以遍历所有元素,但是用struct-for会报错。另外,用ti.root.pointer放置出来的就是稀疏矩阵吗?

在mgpcg的例子当中为什么要定义一个这样的多重结构?

grid = ti.root.pointer(ti.ijk, [N_tot // 4]).dense(ti.ijk, 4).place(x, p, Ap)

谢谢!

结果是用range-for可以遍历所有元素,但是用struct-for会报错。

把 struct-for 放在 taichi scope 里就好了, 如下:

import taichi as ti
ti.init(debug = True)
a = ti.field(dtype = ti.f32)
ti.root.pointer(ti.ij, (5, 5)).place(a)
for i, j in ti.ndrange(3, 3):
    a[i,j] = 1.0

@ti.kernel
def fun():
    for i, j in a:
        print(a[i,j])

fun()

在mgpcg的例子当中为什么要定义一个这样的多重结构?

可以减少遍历一些不用计算的元素,详见 GAMES201 Lecture 09。

1 个赞

感谢!我都二到忘记Taichi scope了。。。另外我发现在我的机器(16G内存)上,放置大约超过10000 x 10000的矩阵就会报错,这是正常的吗?

得看你用的是什么backend,内存是cpu做后端的,如果是cuda的话得看你显存
字节数你可以自己计算下,估计下10000x10000x16x4 = 64x10e8 byte = 6.4g
所以你的显存看看有没有6G咯?当然你电脑上其他应用程序也会有影响啦

1 个赞

我是用CPU做后端的,所以用的应该是内存。请问这个计算为什么是乘以16 x 4呢?是说一个元素要占64 byte的意思吗。。我按照64位浮点数直接换算的话,一个浮点数8个byte,一共也就是10000 x 10000 x 8 = 8 x 10e8 = 800MB的样子,不太懂为什么这样就会报错。
另外,不同的SNode好像也会占不同的空间的样子,ti.root.pointer似乎可以放置的比ti.root.bitmasked少,这两者放置时占据的空间分别应该怎么计算?

我没仔细看你代码,以为是张量里面放矩阵,骚瑞
taichi内部内存的布局,我也不是开发者不太清楚,等大佬给你解答吧

1 个赞

我不是放置矩阵的矩阵,就是ti.field

a = ti.field(dtype=ti.f64)
ti.root.pointer(ti.ij, (12000, 12000)).place(a)

直接使用var可以,不知道啥原因

import sys
import os
import taichi as ti
import time
import math
import numpy as np
ti.init(arch=ti.cpu,advanced_optimization=True)
imgSize = 512
screenRes = ti.Vector([imgSize, imgSize])
img       = ti.Vector(3, dt=ti.f64, shape=[imgSize,imgSize])
gui       = ti.GUI('test', res=(imgSize,imgSize))

#a = ti.field(dtype=ti.f64)
#ti.root.pointer(ti.ij, (12000, 12000)).place(a)
a = ti.var(dt=ti.f64, shape=[12000,12000])


@ti.kernel
def render():
    for i, j in a:
        a[i,j] = ti.random()
    for i, j in img:
        img[i,j].fill(a[i,j])

while gui.running:
    render()
    gui.set_image(img.to_numpy())
    gui.show()
1 个赞

谢谢帮助测试,我也发现了声明成稠密矩阵没有问题(一定大小之内,大约是3w x 3w)。声明稀疏本身也不会有问题,就是写访问这个稀疏矩阵的时候,当矩阵size超过一定大小就会报错。

import taichi as ti

ti.init(default_fp=ti.f64)

# 这样就会导致后面报错
a = ti.field(dtype=ti.f64)
ti.root.pointer(ti.ij, (12000, 12000)).place(a)

# 这样不会爆炸
# a = ti.field(dtype=ti.f64, shape=(12000, 12000))


@ti.kernel
def init():
    for i, j in ti.ndrange(2, 2):
        a[i, j] = 1


# 这个函数当a超过一定大小就会出错
@ti.kernel
def printa():
    for i, j in a:
        print(a[i, j])


init()
printa()