#NEWLINE# def _build_tree( type_args ) : #NEWLINE# #INDENT# '\n    rebuild a mutable tree from the stack\n    flag each op node with whether it is scalar or not\n    also include a count of reductions under this node:\n    node: [ arg(op, tensor or const), is_scalar, red_count, left_child, right_child ]\n    ' #NEWLINE# stack = list ( ) #NEWLINE# for arg in type_args : #NEWLINE# #INDENT# arg_type = arg [ 0 ] #NEWLINE# if ( arg_type in _float_ops ) : #NEWLINE# #INDENT# numops = _float_ops [ arg_type ] [ 0 ] #NEWLINE# node = [ arg , ( numops > 0 ) , 0 ] #NEWLINE# for i in range ( numops ) : #NEWLINE# #INDENT# operand = stack . pop ( ) #NEWLINE# if ( type ( operand ) is list ) : #NEWLINE# #INDENT# node [ 2 ] += operand [ 2 ] #NEWLINE# if ( operand [ 1 ] == 0 ) : #NEWLINE# #INDENT# node [ 1 ] = False #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( ( operand [ 0 ] is ng . GPUTensor ) and ( ( operand [ 1 ] > 0 ) or ( not operand [ 4 ] ) ) ) : #NEWLINE# #INDENT# node [ 1 ] = False #NEWLINE# #UNINDENT# #UNINDENT# node . insert ( 3 , operand ) #NEWLINE# #UNINDENT# stack . append ( node ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( arg_type in _reduction_ops ) : #NEWLINE# #INDENT# operand = stack . pop ( ) #NEWLINE# reds = 1 #NEWLINE# if ( type ( operand ) is list ) : #NEWLINE# #INDENT# reds += operand [ 2 ] #NEWLINE# #UNINDENT# stack . append ( [ arg , True , reds , operand ] ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# stack . append ( arg ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# return stack [ 0 ]