My bad, that one gives wrong result, fixed version:

    def recursive_dot_reduce(A_, K_):
        if K_<=1: return A_
        if K&1:
            return recursive_dot_reduce(T.dot(T.batched_dot(A_[:-1:2], A_[::
2]), A_[-1]), K_//2)
        else
            return recursive_dot_reduce(T.batched_dot(A_[::2], A_[1::2]), K_
//2)


On Thursday, February 16, 2017 at 10:52:28 PM UTC+8, Adam Becker wrote:
>
> Just for the dot reduction part, using batched_dot should give a O(log(n)) 
> graph depth:
>
> # assumes K > 1
> B = A
> for i in reversed(bin(K)[3:]):
>     if not int(i):
>         B = T.batched_dot(B[::2], B[1::2])
>     else:
>         B = T.dot(T.batched_dot(B[:-1:2], B[1::2]), B[-1])
>
> This works if K is known in advance.
>
> An efficient way to construct A is still needed.
>
>  Thursday, February 16, 2017 at 10:16:09 PM UTC+8, Oussama Souihli wrote:
>
>> P.S. 
>> If it helps, yes the indices are exactly the ones I have in the code. 
>>
>> Thanks
>> Oussama
>>
>> On 16 February 2017 at 23:00, Oussama Souihli <[email protected]> wrote:
>>
>>> Hi Fred, 
>>>
>>> Thank you for the quick reply and clever suggestions, you really hit the 
>>> nail on the head ! 
>>>
>>> I tried the suggested vectorized code, but unfortunately still 
>>> experienced the max recursion limit exception. 
>>> I also tried the workaround, but still get the max recusion limit until 
>>> I set it to 20K and I get a segmentation fault: 
>>>
>>> Process finished with exit code 139 (interrupted by signal 11: SIGSEGV) 
>>>
>>>
>>> Can you think of other suggestions that I could try ? 
>>> If for-loop approach is doomed because of the max recursion issue, is 
>>> there perhaps a way I could rewrite my code such that  scan becomes 
>>> reasonably faster ?
>>>
>>>
>>>
>>> On 16 February 2017 at 22:22, Frédéric Bastien <[email protected]> 
>>> wrote:
>>>
>>>> Is the indices exatly the one you have in your code? If so, you can 
>>>> probably take advantage of this to vectorize the code and make the for 
>>>> loop 
>>>> case work.
>>>>
>>>> The size are so small then using scan will be super slow. Each 
>>>> iteration of scan have big overhead and you only work on scalar mostly at 
>>>> each iteration. So it is normal that it is slow with scan.
>>>>
>>>> For the for loop, there was a problem of indices. I fixed it. Here is a 
>>>> partial vectorization of the code that will make it faster to execute and 
>>>> make a smaller graph:
>>>>
>>>>     coss = tt.cos(theta)
>>>>     sins = tt.sin(theta)
>>>>
>>>>     for k in range(0, K):
>>>>         A = tt.set_subtensor(A[indices[k, 0], indices[k, 0]], coss[k])
>>>>         A = tt.set_subtensor(A[indices[k, 1], indices[k, 1]], coss[k])
>>>>         A = tt.set_subtensor(A[indices[k, 0], indices[k, 1]], sins[k])
>>>>         A = tt.set_subtensor(A[indices[k, 1], indices[k, 0]], -sins[k])
>>>>         B = tt.dot(A, B)
>>>>
>>>> The call to cos and sin are only done once. This make the graph smaller.
>>>>
>>>> You can also do the indexing call only once. THis make the graph still 
>>>> smaller:
>>>>
>>>>     coss = tt.cos(theta)
>>>>     sins = tt.cos(theta)
>>>>
>>>>     for k in range(0, K):
>>>>         idx0 = indices[k, 0]
>>>>         idx1 = indices[k, 1]
>>>>         A = tt.set_subtensor(A[idx0, idx0], coss[k])
>>>>         A = tt.set_subtensor(A[idx1, idx1], coss[k])
>>>>         A = tt.set_subtensor(A[idx0, idx1], sins[k])
>>>>         A = tt.set_subtensor(A[idx1, idx0], -sins[k])
>>>>         B = tt.dot(A, B)
>>>>
>>>> The if the indices is exactly what you created and don't change, it can 
>>>> become that is even smaller:
>>>>
>>>>     for k in range(0, K):
>>>>         idx0 = K//(N-1)
>>>>         idx1 = indices[k, 1]
>>>>         A = tt.set_subtensor(A[idx0, idx0], coss[k])
>>>>         A = tt.set_subtensor(A[idx1, idx1], coss[k])
>>>>         A = tt.set_subtensor(A[idx0, idx1], sins[k])
>>>>         A = tt.set_subtensor(A[idx1, idx0], -sins[k])
>>>>         B = tt.dot(A, B)
>>>>
>>>> You can do similar with j.
>>>>
>>>> If with that, you still have the max recursion limit, try the work 
>>>> around in this issue.
>>>>
>>>> https://github.com/Theano/Theano/issues/3607
>>>>
>>>> Fred
>>>>
>>>> On Thu, Feb 16, 2017 at 7:53 AM Oussama Souihli <[email protected]> 
>>>> wrote:
>>>>
>>>>> Hi Fred, Adam, Kiuhnm, all 
>>>>>
>>>>> Thank you for the detailed and quick replies and multiple suggestions. 
>>>>> I tried bacthed_dot but still experienced both issues (maximum depth 
>>>>> recursion when using a for loop and very slow epochs when using 
>>>>> theano.scan), 
>>>>> so now I'm thinking the problem is also possibly  due to the way I 
>>>>> populate the array A (using sub_tensor). 
>>>>>
>>>>> Sorry for imposing on your kindness, but would you mind taking a look 
>>>>> at the attached, *very short*, minimal examples reproducing what I'm 
>>>>> trying to achieve ? 
>>>>> The examples are self-contained and only require python with numpy and 
>>>>> theano packages, nothing else. 
>>>>>
>>>>>    - *Issue_with_for_loop.py*: 
>>>>>    - Reproduces the for-loop maximum recursion issue. 
>>>>>       - if you run it as is, it will throw the exception on B.eval()
>>>>>       
>>>>>       - *Issue_with_scan.py*: 
>>>>>    - This one shows the alternative way of implementing the logic 
>>>>>       using scan. 
>>>>>       - Unfortunately in this case it returns a result and gives the 
>>>>>       impression like it works fine, but if I run it in Keras the epoch 
>>>>> duration 
>>>>>       becomes prohibitively large (400,000 seconds per epoch !!)
>>>>>    
>>>>>
>>>>> If you can think of a way that can achieve the logic implemented in 
>>>>> either sheets with maximum efficiency theano-wise, I'd really appreciate 
>>>>> it. 
>>>>>
>>>>>
>>>>> With gratitude,
>>>>> Oussama
>>>>>
>>>>> -- 
>>>>>
>>>>> --- 
>>>>> You received this message because you are subscribed to the Google 
>>>>> Groups "theano-users" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>>> an email to [email protected].
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>> -- 
>>>>
>>>> --- 
>>>> You received this message because you are subscribed to a topic in the 
>>>> Google Groups "theano-users" group.
>>>> To unsubscribe from this topic, visit 
>>>> https://groups.google.com/d/topic/theano-users/Yz8g-cejB8c/unsubscribe.
>>>> To unsubscribe from this group and all its topics, send an email to 
>>>> [email protected].
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>
>>>
>>

-- 

--- 
You received this message because you are subscribed to the Google Groups 
"theano-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to