sqrt_vml_cpu not implemented for 'Long' - pytorch

a = torch.full([2, 2], 9)
b = a.sqrt()
print(b)
b = a.rsqrt()
print(b)
RuntimeError: sqrt_vml_cpu not implemented for 'Long'
a is torch.LongTensor, but sqrt and rsqrt do not suppor Long, what should I do?

I couldn't reproduce your code because, when I run it, I get the following error (PyTorch 1.6):
RuntimeError: Providing a bool or integral fill value without setting the
optional `dtype` or `out` arguments is currently unsupported. In PyTorch 1.7,
when `dtype` and `out` are not set a bool fill value will return a tensor of
torch.bool dtype, and an integral fill value will return a tensor of
torch.long dtype.
However, I think your problem occurs because PyTorch does not support square root operation for Long/torch.int64. You should use another data type. This should do it:
a = torch.full([2, 2], 9, dtype=torch.float32)
b = a.sqrt()
b = a.rsqrt()

Related

Slicing a tensor with a dimension varying

I'm trying to slice a PyTorch tensor my_tensor of dimensions s x b x c so that the slicing along the first dimension varies according to a tensor indices of length b, to the effect of:
my_tensor[0:indices, torch.arange(0, b, dtype=torch.long), :] = something
The code above doesn't work and receives the error TypeError: tuple indices must be integers or slices, not tuple.
What I'm aiming for is, for example, if indices = torch.tensor([3, 5, 4]) then:
my_tensor[0:3, 0, :] = something
my_tensor[0:5, 1, :] = something
my_tensor[0:4, 2, :] = something
I'm hoping for a tensorized way to do this so I don't have to resort to a for loop. Also, the method needs to be compatible with TorchScript. Thanks very much.

tf.cond() returning a tensor of shape unknown

Below is the function that I am passing to a keras Lambda layer.
I am getting a problem with the output of tf.cond(). It returns a shape of <unknown>. The input tensor (t) and the constant weight tensor have shapes of (None,6) and (6,), respectively. When I add these two outside of tf.cond() then I get a tensor of shape (None,6), which is what I need it to be. However, when the same add operation is returned from within tf.cond(), I get a tensor of shape <unknown>.
What changes when this operation goes via tf.cond().
def class_segmentation(t):
class_segments = tf.constant([0,0,1,1,2,2])
a = tf.math.segment_mean(t, class_segments, name=None)
b = tf.math.argmax(a)
left_weights = tf.constant([1.0,1.0,0.0,0.0,0.0,0.0])
middle_weights = tf.constant([0.0,0.0,1.0,1.0,0.0,0.0])
right_weights = tf.constant([0.0,0.0,0.0,0.0,1.0,1.0])
zero_weights = tf.constant([0.0,0.0,0.0,0.0,0.0,0.0])
c = tf.cond(tf.math.equal(b,0), lambda: tf.math.add(t, left_weights), lambda: zero_weights)
d = tf.cond(tf.math.equal(b,1), lambda: tf.math.add(t, middle_weights ), lambda: zero_weights)
e = tf.cond(tf.math.equal(b,2), lambda: tf.math.add(t, right_weights), lambda: zero_weights)
f = tf.math.add_n([c,d,e])
print("Tensor shape: ", f.shape) # returns "Unknown"
return f
You have a few problems in your code.
tf.math.segment_mean() expects class_segments to have the same shape as first dimension of your input t. So None must be equal 6 in order for your code to run. This is most likely cause of you getting the unknown shape - because the shape of your tensors depends on None which is determined on runtime. You could apply transformation for your code to run (not sure if that is what you are trying to achieve), eg.
a = tf.math.segment_mean(tf.transpose(t), class_segments)
In tf.cond() true_fn and false_fn must return tensors of same shape. In your case true_fn returns (None, 6) because of broadcasting and false_fn returns tensor of shape (6,).
The predicate in tf.cond() must be reduced to a rank 0. For example, if you were to apply
b = tf.math.argmax(tf.math.segment_mean(tf.transpose(t), class_segments), 0)
then the shape of b would be (None) and the predicate pred in tf.cond() will be broadcasted to the same shape (which will raise an error).
Without knowing what are you trying to achieve further help is impossible.

TypeError: can't multiply sequence by non-int of type 'list_iterator' in docplex

Solving 0-1 integer programming problem using docplex solver in python.
T_1_d = int((180+8*15-lon-math.acos(math.tan(10547*(math.pi)/81000*math.cos(2*(math.pi)*(date+9)/365))*math.tan(lat*(math.pi)/180))*180/(math.pi))/15)
T_1_d1 = int((180+8*15-lon-math.acos(math.tan(10547*(math.pi)/81000*math.cos(2*(math.pi)*(date+10)/365))*math.tan(lat*(math.pi)/180))*180/(math.pi))/15)
model = Model()
var_list = [i for i in range(T_1_d, T_1_d1+24)]
B = model.binary_var_list(var_list, lb=0, name='B')
model.maximize(A*O*C_0*3600*sum(B[i])/1e9 - Q_0*A/(1000*E)*sum(B[i]*F[i]) - H*D_O*A*P_0/1e4)
When I run the code it reports the following error:
TypeError: 'Var' object is not iterable.
Then I wrote B = iter(B), it reports the following error:
TypeError: 'list_iterator' object is not subscriptable.
Then I remove the index, turn B[i] to B, it reports the following error:
TypeError: can't multiply sequence by non-int of type 'list_iterator'
The type of B is list, the type of B[i] is docplex.mp.linear.Var. I've tried to int(B[i]) to change its type, but I failed.
I don't know how to correct. Hoping for your help, thanks!
You did not specify your for loop, rather than sum(B[i]), it should be something like model.sum(B[i] for i in range(len(B))).
Similarly for the other summation terms.
Example of code:
from docplex.mp.model import Model
model = Model()
var_list = [i for i in range(3, 6)]
B = model.binary_var_list(var_list, lb=0, name='B')
F = [ 5, 6, 7]
print(B)
model.maximize(3600*model.sum(B[i] for i in range(len(B))) - model.sum(B[i]*F[i] for i in range(len(B))))

tensorflow map_fn on signle value Tensor

Is it possible to run map_fn on a tensor with a single value?
The following works:
import tensorflow as tf
a = tf.constant(1.0, shape=[3])
tf.map_fn(lambda x: x+1, a)
#output: [2.0, 2.0, 2.0]
However this does not:
import tensorflow as tf
b = tf.constant(1.0)
tf.map_fn(lambda x: x+1, b)
#expected output: 2.0
Is it possible at all?
What am I doing wrong?
Any hints will be greatly appreciated!
Well, I see you accepted an answer, which correctly states that tf.map_fn() is applying a function to elements of a tensor, and a scalar tensor has no elements. But it's not impossible to do this for a scalar tensor, you just have to tf.reshape() it before and after, like this code (tested):
import tensorflow as tf
b = tf.constant(1.0)
if () == b.get_shape():
c = tf.reshape( tf.map_fn(lambda x: x+1, tf.reshape( b, ( 1, ) ) ), () )
else:
c = tf.map_fn(lambda x: x+1, b)
#expected output: 2.0
with tf.Session() as sess:
print( sess.run( c ) )
will output:
2.0
as desired.
This way you can factor this into an agnostic function that can take both scalar and non-scalar tensors as argument.
No, this is not possible. As you probably saw it throws an error:
ValueError: elems must be a 1+ dimensional Tensor, not a scalar
The point of map_fn is to apply a function to each element of a tensor, so it makes no sense to use this for a scalar (single-element) tensor.
As to "what you are doing wrong": This is difficult to say without knowing what you're trying to achieve.

Why do we need Theano reshape?

I don't understand why do we need tensor.reshape() function in Theano. It is said in the documentation:
Returns a view of this tensor that has been reshaped as in
numpy.reshape.
As far as I understood, theano.tensor.var.TensorVariable is some entity that is used for computation graphs creation. And it is absolutely independent of shapes. For instance when you create your function you can pass there matrix 2x2 or matrix 100x200. As I thought reshape somehow restricts this variety. But it is not. Suppose the following example:
X = tensor.matrix('X')
X_resh = X.reshape((3, 3))
Y = X_resh ** 2
f = theano.function([X_resh], Y)
print(f(numpy.array([[1, 2], [3, 4]])))
As I understood, it should give an error since I passed matrix 2x2 not 3x3, but it computes element-wise squares perfectly.
So what is the shape of the theano tensor variable and where should we use it?
There is an error in the provided code though Theano fails to point this out.
Instead of
f = theano.function([X_resh], Y)
you should really use
f = theano.function([X], Y)
Using the original code you are actually providing the tensor after the reshape so the reshape command never gets executed. This can be seen by adding
theano.printing.debugprint(f)
which prints
Elemwise{sqr,no_inplace} [id A] '' 0
|<TensorType(float64, matrix)> [id B]
Note that there is no reshape operation in this compiled execution graph.
If one changes the code so that X is used as the input instead of X_resh then Theano throws an error including the message
ValueError: total size of new array must be unchanged Apply node that
caused the error: Reshape{2}(X, TensorConstant{(2L,) of 3})
This is expected because one cannot reshape a tensor with shape (2, 2) (i.e. 4 elements) into a tensor with shape (3, 3) (i.e. 9 elements).
To address the broader question, we can use symbolic expressions in the target shape and those expressions can be functions of the input tensor's symbolic shape. Here's some examples:
import numpy
import theano
import theano.tensor
X = theano.tensor.matrix('X')
X_vector = X.reshape((X.shape[0] * X.shape[1],))
X_row = X.reshape((1, X.shape[0] * X.shape[1]))
X_column = X.reshape((X.shape[0] * X.shape[1], 1))
X_3d = X.reshape((-1, X.shape[0], X.shape[1]))
f = theano.function([X], [X_vector, X_row, X_column, X_3d])
for output in f(numpy.array([[1, 2], [3, 4]])):
print output.shape, output

Resources