class TensorStream::Graphml
Public Class Methods
new()
click to toggle source
# File lib/tensor_stream/graph_serializers/graphml.rb, line 3 def initialize end
Public Instance Methods
get_string(tensor, session = nil)
click to toggle source
# File lib/tensor_stream/graph_serializers/graphml.rb, line 6 def get_string(tensor, session = nil) tensor = TensorStream.convert_to_tensor(tensor) unless tensor.is_a?(Tensor) @session = session @name = tensor.name @last_session_context = session ? session.last_session_context : {} groups = {} arr_buf = [] arr_buf << '<?xml version="1.0" encoding="UTF-8"?>' arr_buf << '<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">' arr_buf << '<key id="d0" for="node" attr.name="label" attr.type="string"/>' arr_buf << '<key id="d1" for="node" attr.name="formula" attr.type="string"/>' arr_buf << '<key id="d2" for="node" attr.name="color" attr.type="string"/>' arr_buf << '<key id="d3" for="node" attr.name="value" attr.type="string"/>' arr_buf << '<key attr.name="description" attr.type="string" for="edge" id="d12"/>' arr_buf << '<key for="edge" id="d13" yfiles.type="edgegraphics"/>' arr_buf << '<key for="node" id="d9" yfiles.type="nodegraphics"/>' arr_buf << "<graph id=\"g_#{_gml_string(tensor.name)}\" edgedefault=\"directed\">" arr_buf << "<node id=\"out\">" arr_buf << "<data key=\"d0\">out</data>" arr_buf << "<data key=\"d2\">red</data>" arr_buf << "<data key=\"d9\">" arr_buf << "<y:ShapeNode>" arr_buf << " <y:Fill color=\"#FF0000\" transparent=\"false\"/>" arr_buf << " <y:NodeLabel alignment=\"center\">out</y:NodeLabel>" arr_buf << "</y:ShapeNode>" arr_buf << "</data>" arr_buf << "</node>" to_graph_ml(tensor, arr_buf, {}, groups) # dump groups groups.each do |k, g| arr_buf << create_group(k, k, g) end output_edge(tensor, "out", arr_buf) arr_buf << "</graph>" arr_buf << "</graphml>" arr_buf.flatten.join("\n") end
Private Instance Methods
_gml_string(str)
click to toggle source
# File lib/tensor_stream/graph_serializers/graphml.rb, line 206 def _gml_string(str) str.tr("/", "-") end
_val(tensor)
click to toggle source
# File lib/tensor_stream/graph_serializers/graphml.rb, line 102 def _val(tensor) # JSON.pretty_generate(@last_session_context[tensor.name]) @last_session_context[tensor.name] || @last_session_context[:_cache][tensor.name] end
add_to_group(groups, name, arr_buf)
click to toggle source
# File lib/tensor_stream/graph_serializers/graphml.rb, line 50 def add_to_group(groups, name, arr_buf) name_parts = name.split("/") return false if name_parts.size < 2 prefix = name_parts.shift ptr = find_or_create_group(prefix, groups) Kernel.loop do next_group = ptr[:group] ptr = find_or_create_group(prefix, next_group) break if name_parts.size < 2 prefix = name_parts.shift end ptr[:buf] << arr_buf true end
create_group(id, title, group)
click to toggle source
# File lib/tensor_stream/graph_serializers/graphml.rb, line 77 def create_group(id, title, group) arr_buf = [] arr_buf << "<node id=\"#{id}\" yfiles.foldertype=\"group\">" arr_buf << '<data key="d9">' arr_buf << "<y:ProxyAutoBoundsNode>" arr_buf << '<y:Realizers active="0">' arr_buf << "<y:GroupNode>" arr_buf << '<y:Fill color="#CAECFF84" transparent="false"/>' arr_buf << '<y:BorderStyle color="#666699" type="dotted" width="1.0"/>' arr_buf << '<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#99CCFF" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="67.18603515625" x="-8.593017578125" y="0.0">' + title + "</y:NodeLabel>" arr_buf << '<y:Shape type="roundrectangle"/>' arr_buf << "</y:GroupNode>" arr_buf << "</y:Realizers>" arr_buf << "</y:ProxyAutoBoundsNode>" arr_buf << "</data>" arr_buf << '<graph edgedefault="directed" id="n105:">' arr_buf << group[:buf] group[:group].each do |k, g| arr_buf << create_group(k, k, g) end arr_buf << "</graph>" arr_buf << "</node>" arr_buf end
find_or_create_group(prefix, groups)
click to toggle source
# File lib/tensor_stream/graph_serializers/graphml.rb, line 69 def find_or_create_group(prefix, groups) unless groups[prefix] groups[prefix] = {buf: [], group: {}} end groups[prefix] end
output_edge(input, tensor, arr_buf, index = 0)
click to toggle source
# File lib/tensor_stream/graph_serializers/graphml.rb, line 210 def output_edge(input, tensor, arr_buf, index = 0) target_name = tensor.is_a?(Tensor) ? tensor.name : tensor arr_buf << "<edge source=\"#{_gml_string(input.name)}\" target=\"#{_gml_string(target_name)}\">" arr_buf << "<data key=\"d13\">" arr_buf << "<y:PolyLineEdge>" arr_buf << "<y:EdgeLabel >" arr_buf << if !@last_session_context.empty? "<![CDATA[ #{_val(input)} ]]>" elsif input.shape.shape.nil? "<![CDATA[ #{input.data_type} ? ]]>" else "<![CDATA[ #{input.data_type} #{input.shape.shape.empty? ? "scalar" : input.shape.shape.to_json} ]]>" end arr_buf << "</y:EdgeLabel >" arr_buf << "<y:Arrows source=\"none\" target=\"standard\"/>" arr_buf << if index.zero? "<y:LineStyle color=\"#FF0000\" type=\"line\" width=\"1.0\"/>" else "<y:LineStyle color=\"#0000FF\" type=\"line\" width=\"1.0\"/>" end arr_buf << "</y:PolyLineEdge>" arr_buf << "</data>" arr_buf << "</edge>" end
to_graph_ml(tensor, arr_buf = [], added = {}, groups = {}, _id = 0)
click to toggle source
# File lib/tensor_stream/graph_serializers/graphml.rb, line 107 def to_graph_ml(tensor, arr_buf = [], added = {}, groups = {}, _id = 0) puts tensor.name return unless tensor.is_a?(Operation) added[tensor.name] = true node_buf = [] node_buf << "<node id=\"#{_gml_string(tensor.name)}\">" node_buf << "<data key=\"d0\">#{tensor.operation}</data>" node_buf << "<data key=\"d1\">#{tensor.to_math(true, 1)}</data>" node_buf << "<data key=\"d2\">blue</data>" if @last_session_context[tensor.name] arr_buf << "<data key=\"d3\">#{_val(tensor)}</data>" end node_buf << "<data key=\"d9\">" node_buf << "<y:ShapeNode>" node_buf << if tensor.internal? " <y:Fill color=\"#FFFF99\" transparent=\"false\"/>" else " <y:Fill color=\"#99CC00\" transparent=\"false\"/>" end node_buf << " <y:NodeLabel alignment=\"center\">#{tensor.operation}</y:NodeLabel>" node_buf << "</y:ShapeNode>" node_buf << "</data>" node_buf << "</node>" unless add_to_group(groups, tensor.name, node_buf) add_to_group(groups, "program/#{tensor.name}", node_buf) end tensor.inputs.each do |input| next unless input next if added[input.name] next to_graph_ml(input, arr_buf, added, groups) if input.is_a?(Operation) added[input.name] = true input_buf = [] if input.is_a?(Variable) input_buf << "<node id=\"#{_gml_string(input.name)}\">" input_buf << "<data key=\"d0\">#{input.name}</data>" input_buf << "<data key=\"d2\">green</data>" input_buf << "<data key=\"d3\">#{_val(tensor)}</data>" if @last_session_context[input.name] input_buf << "<data key=\"d9\">" input_buf << "<y:ShapeNode>" input_buf << " <y:Fill color=\"#33CCCC\" transparent=\"false\"/>" input_buf << " <y:NodeLabel alignment=\"center\">#{input.name}</y:NodeLabel>" input_buf << "</y:ShapeNode>" input_buf << "</data>" input_buf << "</node>" elsif input.is_a?(Placeholder) input_buf << "<node id=\"#{_gml_string(input.name)}\">" input_buf << "<data key=\"d9\">" input_buf << "<y:ShapeNode>" input_buf << " <y:Fill color=\"#FFCC00\" transparent=\"false\"/>" input_buf << " <y:NodeLabel alignment=\"center\">#{input.name}</y:NodeLabel>" input_buf << "</y:ShapeNode>" input_buf << "</data>" input_buf << "<data key=\"d3\">#{_val(tensor)}</data>" if @last_session_context[input.name] \ input_buf << "</node>" elsif input.is_a?(Tensor) input_buf << "<node id=\"#{_gml_string(input.name)}\">" input_buf << "<data key=\"d0\">#{input.name}</data>" input_buf << "<data key=\"d2\">black</data>" input_buf << "<data key=\"d9\">" input_buf << "<y:ShapeNode>" input_buf << if input.internal? " <y:Fill color=\"#C0C0C0\" transparent=\"false\"/>" else " <y:Fill color=\"#FFFFFF\" transparent=\"false\"/>" end input_buf << " <y:NodeLabel alignment=\"center\">#{input.name}</y:NodeLabel>" input_buf << "</y:ShapeNode>" input_buf << "</data>" input_buf << "</node>" end unless add_to_group(groups, input.name, input_buf) if input.is_a?(Variable) add_to_group(groups, "variable/#{input.name}", input_buf) else add_to_group(groups, "program/#{input.name}", input_buf) end end end tensor.inputs.each_with_index do |input, index| next unless input output_edge(input, tensor, arr_buf, index) end end