theano/compile/profiling.py
def min_memory_generator(executable_nodes, viewed_by, view_of):
                """
                Generate all valid node order from node_list and compute its
                memory peak.

                Parameters
                ----------
                executable_nodes
                    Set of executable nodes.

                """
                global mem_count, mem_bound, max_mem_count

                for node in executable_nodes:
                    new_exec_nodes = executable_nodes.copy()
                    new_exec_nodes.remove(node)

                    # Check if cut path now
                    if max_mem_count > mem_bound:
                        continue

                    viewof_change = []
                    # Use to track view_of changes

                    viewedby_add = defaultdict(lambda: [])
                    viewedby_remove = defaultdict(lambda: [])
                    # Use to track viewed_by changes

                    for var in node.outputs:
                        compute_map[var][0] = 1

                    mem_created = 0
                    mem_freed = 0
                    max_storage = max_mem_count

                    dmap = getattr(node.op, 'destroy_map', None)
                    vmap = getattr(node.op, 'view_map', None)

                    idx = 0
                    # Update the Python emulating dicts and add the
                    # memory allocated by the node
                    for out in node.outputs:
                        ins = None
                        if dmap and idx in dmap:
                            vidx = dmap[idx]
                            assert len(vidx) == 1, ("Here we only support "
                                                    "the possibility to "
                                                    "destroy one input")
                            ins = node.inputs[vidx[0]]
                        if vmap and idx in vmap:
                            assert ins is None
                            vidx = vmap[idx]
                            assert len(vidx) == 1, ("Here we only support "
                                                    "the possibility to "
                                                    "view one input")
                            ins = node.inputs[vidx[0]]
                        if ins is not None:
                            # This is needed for destroy_map in case it
                            # return a partial view that is destroyed. So
                            # the output could be different then the
                            # input.
                            assert isinstance(ins, theano.Variable)
                            # We keep track of view only again the original
                            origin = view_of.get(ins, ins)
                            view_of[out] = origin
                            viewof_change.append(out)
                            viewed_by[origin].append(out)
                            viewedby_add[origin].append(out)
                        else:
                            mem_created += var_mem[out]
                        idx += 1

                    mem_count += mem_created
                    max_mem_count = max(max_mem_count, mem_count)

                    # Mimic the combination of Theano and Python gc.
                    for ins in node.inputs:
                        assert not (ins in view_of and
                                    viewed_by[ins])
                        # We track of the original var, so this shouldn't
                        # happen
                        if (dependencies[ins] and
                                ins not in fgraph.outputs and
                                ins.owner and
                                all([compute_map[v][0]
                                     for v in dependencies[ins]])):
                            if (ins not in view_of and
                                    not viewed_by.get(ins, [])):
                                mem_freed += var_mem[ins]
                            elif ins in view_of:
                                origin = view_of[ins]
                                viewed_by[origin].remove(ins)
                                viewedby_remove[origin].append(ins)
                                if (not viewed_by[origin] and
                                        origin not in fgraph.inputs and
                                        not isinstance(origin,
                                                       theano.Constant)):
                                    mem_freed += var_mem[origin]
                        else:
                            # ins is viewed_by something else, so its
                            # memory isn't freed
                            pass

                    mem_count -= mem_freed

                    done_set.add(node)
                    frozen_set = frozenset(done_set)
                    if (done_dict.get(frozen_set, max_mem_count + 1) >
                            max_mem_count):
                        # check if frozen_set is in done_set
                        # no, add it to done_set
                        # yes, then compare the past mem and current mem
                        # bigger, update the value and continue
                        # smaller, stop this iteration, move to next node
                        done_dict[frozen_set] = max_mem_count

                        for var in node.outputs:
                            for c, _ in var.clients:
                                if c != "output":
                                    deps = c.inputs + c.destroy_dependencies
                                    if all(compute_map[v][0] for v in deps):
                                        new_exec_nodes.add(c)

                        if not new_exec_nodes:
                            # Check and Update mem_bound
                            if max_mem_count < mem_bound:
                                mem_bound = max_mem_count
                        else:
                            min_memory_generator(
                                new_exec_nodes, viewed_by, view_of)

                    # Reset track variables
                    done_set.remove(node)
                    mem_count -= mem_created
                    max_mem_count = max_storage
                    mem_count += mem_freed
                    for var in node.outputs:
                        compute_map[var][0] = 0

                    for k_remove, v_remove in iteritems(viewedby_remove):
                        for i in v_remove:
                            viewed_by[k_remove].append(i)

                    for k_add, v_add in iteritems(viewedby_add):
                        for i in v_add:
                            viewed_by[k_add].remove(i)

                    for k in viewof_change:
                        del view_of[k]

                Generate all valid node order from node_list and compute its
                memory peak.

                Parameters
                ----------
                executable_nodes
                    Set of executable nodes.

                
Generate all valid node order from node_list and compute its
memory peak.

Parameters

executable_nodes
Set of executable nodes.
Generate all valid node order from node_list and compute its memory peak . Parameters executable_nodes Set of executable nodes .
def min_memory_generator(executable_nodes, viewed_by, view_of):
                global mem_count, mem_bound, max_mem_count
                for node in executable_nodes:
                    new_exec_nodes = executable_nodes.copy()
                    new_exec_nodes.remove(node)
                    if max_mem_count > mem_bound:
                        continue
                    viewof_change = []
                    viewedby_add = defaultdict(lambda: [])
                    viewedby_remove = defaultdict(lambda: [])
                    for var in node.outputs:
                        compute_map[var][0] = 1
                    mem_created = 0
                    mem_freed = 0
                    max_storage = max_mem_count
                    dmap = getattr(node.op, 'destroy_map', None)
                    vmap = getattr(node.op, 'view_map', None)
                    idx = 0
                    for out in node.outputs:
                        ins = None
                        if dmap and idx in dmap:
                            vidx = dmap[idx]
                            assert len(vidx) == 1, ("Here we only support "
                                                    "the possibility to "
                                                    "destroy one input")
                            ins = node.inputs[vidx[0]]
                        if vmap and idx in vmap:
                            assert ins is None
                            vidx = vmap[idx]
                            assert len(vidx) == 1, ("Here we only support "
                                                    "the possibility to "
                                                    "view one input")
                            ins = node.inputs[vidx[0]]
                        if ins is not None:
                            assert isinstance(ins, theano.Variable)
                            origin = view_of.get(ins, ins)
                            view_of[out] = origin
                            viewof_change.append(out)
                            viewed_by[origin].append(out)
                            viewedby_add[origin].append(out)
                        else:
                            mem_created += var_mem[out]
                        idx += 1
                    mem_count += mem_created
                    max_mem_count = max(max_mem_count, mem_count)
                    for ins in node.inputs:
                        assert not (ins in view_of and
                                    viewed_by[ins])
                        if (dependencies[ins] and
                                ins not in fgraph.outputs and
                                ins.owner and
                                all([compute_map[v][0]
                                     for v in dependencies[ins]])):
                            if (ins not in view_of and
                                    not viewed_by.get(ins, [])):
                                mem_freed += var_mem[ins]
                            elif ins in view_of:
                                origin = view_of[ins]
                                viewed_by[origin].remove(ins)
                                viewedby_remove[origin].append(ins)
                                if (not viewed_by[origin] and
                                        origin not in fgraph.inputs and
                                        not isinstance(origin,
                                                       theano.Constant)):
                                    mem_freed += var_mem[origin]
                        else:
                            pass
                    mem_count -= mem_freed
                    done_set.add(node)
                    frozen_set = frozenset(done_set)
                    if (done_dict.get(frozen_set, max_mem_count + 1) >
                            max_mem_count):
                        done_dict[frozen_set] = max_mem_count
                        for var in node.outputs:
                            for c, _ in var.clients:
                                if c != "output":
                                    deps = c.inputs + c.destroy_dependencies
                                    if all(compute_map[v][0] for v in deps):
                                        new_exec_nodes.add(c)
                        if not new_exec_nodes:
                            if max_mem_count < mem_bound:
                                mem_bound = max_mem_count
                        else:
                            min_memory_generator(
                                new_exec_nodes, viewed_by, view_of)
                    done_set.remove(node)
                    mem_count -= mem_created
                    max_mem_count = max_storage
                    mem_count += mem_freed
                    for var in node.outputs:
                        compute_map[var][0] = 0
                    for k_remove, v_remove in iteritems(viewedby_remove):
                        for i in v_remove:
                            viewed_by[k_remove].append(i)
                    for k_add, v_add in iteritems(viewedby_add):
                        for i in v_add:
                            viewed_by[k_add].remove(i)
                    for k in viewof_change:
                        del view_of[k]
def min_memory_generator ( executable_nodes , viewed_by , view_of ) : global mem_count , mem_bound , max_mem_count for node in executable_nodes : new_exec_nodes = executable_nodes . copy ( ) new_exec_nodes . remove ( node ) if max_mem_count > mem_bound : continue viewof_change = [ ] viewedby_add = defaultdict ( lambda : [ ] ) viewedby_remove = defaultdict ( lambda : [ ] ) for var in node . outputs : compute_map [ var ] [ 0 ] = 1 mem_created = 0 mem_freed = 0 max_storage = max_mem_count dmap = getattr ( node . op , 'destroy_map' , None ) vmap = getattr ( node . op , 'view_map' , None ) idx = 0 for out in node . outputs : ins = None if dmap and idx in dmap : vidx = dmap [ idx ] assert len ( vidx ) == 1 , ( "Here we only support " "the possibility to " "destroy one input" ) ins = node . inputs [ vidx [ 0 ] ] if vmap and idx in vmap : assert ins is None vidx = vmap [ idx ] assert len ( vidx ) == 1 , ( "Here we only support " "the possibility to " "view one input" ) ins = node . inputs [ vidx [ 0 ] ] if ins is not None : assert isinstance ( ins , theano . Variable ) origin = view_of . get ( ins , ins ) view_of [ out ] = origin viewof_change . append ( out ) viewed_by [ origin ] . append ( out ) viewedby_add [ origin ] . append ( out ) else : mem_created += var_mem [ out ] idx += 1 mem_count += mem_created max_mem_count = max ( max_mem_count , mem_count ) for ins in node . inputs : assert not ( ins in view_of and viewed_by [ ins ] ) if ( dependencies [ ins ] and ins not in fgraph . outputs and ins . owner and all ( [ compute_map [ v ] [ 0 ] for v in dependencies [ ins ] ] ) ) : if ( ins not in view_of and not viewed_by . get ( ins , [ ] ) ) : mem_freed += var_mem [ ins ] elif ins in view_of : origin = view_of [ ins ] viewed_by [ origin ] . remove ( ins ) viewedby_remove [ origin ] . append ( ins ) if ( not viewed_by [ origin ] and origin not in fgraph . inputs and not isinstance ( origin , theano . Constant ) ) : mem_freed += var_mem [ origin ] else : pass mem_count -= mem_freed done_set . add ( node ) frozen_set = frozenset ( done_set ) if ( done_dict . get ( frozen_set , max_mem_count + 1 ) > max_mem_count ) : done_dict [ frozen_set ] = max_mem_count for var in node . outputs : for c , _ in var . clients : if c != "output" : deps = c . inputs + c . destroy_dependencies if all ( compute_map [ v ] [ 0 ] for v in deps ) : new_exec_nodes . add ( c ) if not new_exec_nodes : if max_mem_count < mem_bound : mem_bound = max_mem_count else : min_memory_generator ( new_exec_nodes , viewed_by , view_of ) done_set . remove ( node ) mem_count -= mem_created max_mem_count = max_storage mem_count += mem_freed for var in node . outputs : compute_map [ var ] [ 0 ] = 0 for k_remove , v_remove in iteritems ( viewedby_remove ) : for i in v_remove : viewed_by [ k_remove ] . append ( i ) for k_add , v_add in iteritems ( viewedby_add ) : for i in v_add : viewed_by [ k_add ] . remove ( i ) for k in viewof_change : del view_of [ k ]
Generate all valid node order from node_list and compute its
memory peak.
Generate all valid node order from node_list and compute its memory peak .
"""
                Generate all valid node order from node_list and compute its
                memory peak.

                Parameters
                ----------
                executable_nodes
                    Set of executable nodes.

                """ # Check if cut path now # Use to track view_of changes # Use to track viewed_by changes # Update the Python emulating dicts and add the # memory allocated by the node # This is needed for destroy_map in case it # return a partial view that is destroyed. So # the output could be different then the # input. # We keep track of view only again the original # Mimic the combination of Theano and Python gc. # We track of the original var, so this shouldn't # happen # ins is viewed_by something else, so its # memory isn't freed # check if frozen_set is in done_set # no, add it to done_set # yes, then compare the past mem and current mem # bigger, update the value and continue # smaller, stop this iteration, move to next node # Check and Update mem_bound # Reset track variables
executable_nodes
viewed_by
view_of