Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python tf.linalg.eigh在GPU上非常慢-正常?_Python_Tensorflow - Fatal编程技术网

Python tf.linalg.eigh在GPU上非常慢-正常?

Python tf.linalg.eigh在GPU上非常慢-正常?,python,tensorflow,Python,Tensorflow,所以我刚刚找到了减慢我在GPU上的代码速度的罪魁祸首:tf.linalg.eigh() 这个想法很简单:我创建——比方说——87.000个4x4厄米矩阵,并希望得到它们的特征值和特征向量。为此,我有一个形状为[87.000,4,4]的占位符matrix,我将其输入tf.linalg.eigh(matrix)。我运行会话并将这些矩阵作为输入(矩阵的数据类型为complex64),并希望将特征值作为输出 这需要8核CPU,不到0.04秒,而GPU需要19秒,而NumPy大约需要0.4秒 所以我的问题

所以我刚刚找到了减慢我在GPU上的代码速度的罪魁祸首:
tf.linalg.eigh()

这个想法很简单:我创建——比方说——87.000个4x4厄米矩阵,并希望得到它们的特征值和特征向量。为此,我有一个形状为[87.000,4,4]的占位符
matrix
,我将其输入
tf.linalg.eigh(matrix)
。我运行会话并将这些矩阵作为输入(矩阵的数据类型为complex64),并希望将特征值作为输出

这需要8核CPU,不到0.04秒,而GPU需要19秒,而NumPy大约需要0.4秒

所以我的问题是:为什么即使给出了大批量,GPU上的
tf.linalg.eigh()。即使一个矩阵的对角化不能有效地并行化,GPU在数千个矩阵的情况下仍然应该快得多

有人能解决这个问题吗?或者我必须从GPU切换到CPU来完成这个操作吗

对守则:

进口

将numpy导入为np
从matplotlib.ticker导入LinearLocator,FormatStrFormatter
导入tensorflow作为tf
config=tf.ConfigProto(设备计数={'GPU':1})
sess=tf.Session(config=config)
导入时间
tf部件的构建

matrix=tf.placeholder(tf.complex64,shape[None,87,4,4],name=“matrix”)
本征值,本征向量=tf.linalg.eigh(tf.linalg.adjunction(矩阵))
init=tf.global_variables_initializer()
sess.run(初始化)
复数矩阵=np.ones((10000,87,4,4))+1j*np.ones((批处理网络,路径长度,num轨道,num轨道))
运行操作并测量时间

t1=time.time()
run(特征向量,feed_dict={矩阵:复数矩阵,特征值}
打印(time.time()-t1)

经过一点实验,我认为在这种情况下,最好将此操作放在CPU上。关键是PCI-GPU通信在这里是一个瓶颈,所以您根本无法获得良好的GPU利用率。尽管通过在GPU上使用TF op生成随机martix,可以减小此开销

with tf.device('/device:GPU:0'):
    matrix = tf.random.uniform((87000,4,4), minval=0.1, maxval=0.99, dtype=tf.float32)
    eigenval,eigenvec=tf.linalg.eigh(matrix)
它只允许在我的系统上减少大约40%的计算时间,这仍然比CPU慢很多。 您还可以尝试将张量拆分为相等的块,执行
linalg.eigh
并连接结果,但这也几乎没有任何改进

matrix = tf.random.uniform((87000,4,4), minval=0.1, maxval=0.99, dtype=tf.float32)
result = tf.concat([tf.linalg.eigh(x)[1] for x in tf.split(matrix, 1000, axis=0)], axis=0)
我还注意到,在CPU上执行的
linalg.eigh
的缩放近似于对数,而GPU操作似乎是线性的。希望这有帮助

一点更新。看起来操作程序<代码> SelfAdJoDigigv2甚至不被XLA编译器支持,所以这个代码

matrix = tf.random.uniform((87000, 4, 4), minval=0.1, maxval=0.99, dtype=tf.float32)
def xla_test(matrix):
    eigenval, eigenvec = tf.linalg.eigh(matrix)
    return eigenvec

y = xla.compile(xla_test, inputs=[matrix])

抛出“检测到不受支持的操作”错误

能否添加您的确切代码?当然,很抱歉没有立即执行此操作。我必须提到的是,``eigenval,eigenvec=tf.linalg.eigh(tf.linalg.adjunction(matrix))´是一些较大图形的一部分,但显然是主要的瓶颈。在此之前,有一个网络,在此操作之后有几个小的后处理操作。感谢您的详细回答。我害怕听到,现在有办法让它在GPU上运行得更快。我仍然很好奇,为什么GPU-PCI通信是瓶颈。在最初的代码中,我给了一个ANN一个输入批,经过几次操作,最终得到了这个矩阵。除了开始,所有的东西都应该在GPU上。我想答案可能就在TF的内部,特别是实现中。无论如何,通过在不同的设备上放置操作来优化TF代码是一个很好的实践,只要它能提供足够的性能。当把网络放在GPU上,把上面的部分放在CPU上时,新手应该记住什么?特别是当上面的部分作为数字因素导致损失时。顺便说一句:谢谢你的帮助,非常感谢!主要建议将任何预处理放在cpu上。其他事情大多是具体情况。见和。如果我的回答是有帮助的,考虑接受它。