То, что вы пытаетесь сделать, может быть достигнуто с помощью пакета matmul. Рассмотрим следующие изменения:
import tensorflow as tf
import numpy
import time
import numpy as np
rc = 1000
sess = tf.Session()
#compute on cpu for comparison later
vals = np.random.uniform(size=[rc,rc,4]).astype(np.float32)
mat1 = tf.identity(vals)
mat2 = tf.transpose(vals, [2, 0, 1])
#store mul in array so all are fetched in run call
muls = []
#I only have one GPU.
for deviceName in ['/cpu:0', '/device:GPU:0']:
with tf.device(deviceName):
def mult(i):
product = tf.matmul(mat1[:,:,i],mat1[:,:,i+1])
return product
mul = tf.zeros([rc,rc,3], dtype = tf.float32)
mul = tf.map_fn(mult, numpy.array([0,1,2]), dtype = tf.float32, parallel_iterations = 10)
muls.append(mul)
#use transposed mat with a shift to matmul in one go
mul = tf.matmul(mat2[:-1], mat2[1:])
print(muls)
print(mul)
start = time.time()
m1 = sess.run(muls)
end = time.time()
print("muls:", end - start)
start = time.time()
m2 = sess.run(mul)
end = time.time()
print("mul:", end - start)
print(np.allclose(m1[0],m1[1]))
print(np.allclose(m1[0],m2))
print(np.allclose(m1[1],m2))
Результаты на моем ПК:
[<tf.Tensor 'map/TensorArrayStack/TensorArrayGatherV3:0' shape=(3, 1000, 1000) dtype=float32>, <tf.Tensor 'map_1/TensorArrayStack/TensorArrayGatherV3:0' shape=(3, 1000, 1000) dtype=float32>]
Tensor("MatMul:0", shape=(3, 1000, 1000), dtype=float32)
muls: 0.4262731075286865
mul: 0.3794088363647461
True
True
True
Вы редко хотите использовать процессор синхронно с графическим процессором, поскольку это будет узким местом. Графические процессоры будут ожидать завершения работы процессора. Если вы что-то делаете с процессором, то он должен быть асинхронным с графическим процессором, чтобы он мог работать в режиме полного наклона.