2015-08-26 4 views
4

Итак, я прочитал, что theano не может выполнять вычисления gpu с float64 и хранить int как общие переменные на gpu, они должны быть инициализированы как общие данные float32, а затем переустановлены на ints (как в «маленьком хаке» в логистике регрессия example) ... но после такого передела, можно сделать anano do gpu на ints? и является ли предварительным условием для вычисления? Другими словами, возможны ли следующие два сценария?Возможны ли операции int на GPU в Theano?

Сценарий 1. Я хочу сделать точечный продукт на двух больших векторах ints. Поэтому я делаю их разделяемыми как float32 и переписываю их в int перед точечным продуктом, является ли этот точечный продукт затем выполняться на gpu (независимо от типа int)?

Сценарий 2. Если возможен сценарий 1, возможно ли выполнить вычисления на gpu, не сохраняя их сначала как shared float32? (Я понимаю, что обменные переменные могут смягчить связь gpu-cpu, но будет ли возможно использовать точечный продукт? Является ли хранилище предварительным условием для вычисления на gpu?)

ответ

5

Нет, нет (в настоящее время) никаких способов делать какие-либо операции с GPU любого типа, кроме float32.

Это можно увидеть с этой небольшой демо-код:

import numpy 
import theano 
import theano.tensor as tt 

x = theano.shared(numpy.arange(9 * 10).reshape((9, 10)).astype(numpy.float32)) 
y = theano.shared(numpy.arange(10 * 11).reshape((10, 11)).astype(numpy.float32)) 
z = theano.dot(tt.cast(x, 'int32'), tt.cast(y, 'int32')) 
f = theano.function([], outputs=z) 
theano.printing.debugprint(f) 

При запуске на GPU будет печатать следующий вычислительный граф:

dot [@A] '' 4 
|Elemwise{Cast{int32}} [@B] '' 3 
| |HostFromGpu [@C] '' 1 
| |<CudaNdarrayType(float32, matrix)> [@D] 
|Elemwise{Cast{int32}} [@E] '' 2 
    |HostFromGpu [@F] '' 0 
    |<CudaNdarrayType(float32, matrix)> [@G] 

Здесь вы можете увидеть, что два общих переменных действительно сохраняются в памяти GPU (два CudaNdarrayType с), но они перемещаются на хост (то есть процессор/основная память) из графического процессора (операции HostFromGpu) перед тем, как быть отнесены к int и обычной операции dot.

Если слепки опущены, то вы увидели бы

HostFromGpu [@A] '' 1 
|GpuDot22 [@B] '' 0 
    |<CudaNdarrayType(float32, matrix)> [@C] 
    |<CudaNdarrayType(float32, matrix)> [@D] 

Показано, что GPU выполняет скалярное произведение (GpuDot22 операции), но на данных с плавающей точкой, а не целочисленные данные.

+0

Действительно хороший ответ, и я определенно буду его продвигать (но у меня нет необходимой репутации: S). В соответствии с этим, однако, в примере логистической регрессии [deeplearrning.net] (http://deeplearning.net/tutorial/logreg.html) кажется бесполезным, что они сначала хранят shared_y как floatX, а затем переходят в int. Согласно вашему примеру выше, это только увеличит сообщение gpu-cpu. – Frazieness

+0

Ситуация, я считаю, немного отличается, если ints используются только как индексы в других тензорах, как в этом примере. Проблема возникает, когда вы хотите выполнять математические операции над ints. –

Смежные вопросы