diff --git a/src/backend/compiler_python.jl b/src/backend/compiler_python.jl index 66ed79b2..1fbea267 100644 --- a/src/backend/compiler_python.jl +++ b/src/backend/compiler_python.jl @@ -1,132 +1,195 @@ -# ms = pyimport("mindspore") - -""" - function to_pystatic(operator::Type, subgraphs::AbstractVector{<:AbstractGraph}, subgraph_factors::AbstractVector) - -Returns the static representation of a computational graph node `g` with operator `operator`, subgraphs `subgraphs`, and subgraph factors `subgraph_factors` in python. -""" -function to_pystatic(operator::Type, subgraphs::AbstractVector{<:AbstractGraph}, subgraph_factors::AbstractVector) - error( - "Static representation for computational graph nodes with operator $(operator) not yet implemented! " * - "Please define a method `to_static(::Type{$(operator)}, subgraphs::$(typeof(subgraphs)), subgraph_factors::$(typeof(subgraph_factors)))`." - ) -end - -function to_pystatic(::Type{ComputationalGraphs.Sum}, subgraphs::Vector{Graph{F,W}}, subgraph_factors::Vector{F}) where {F,W} - if length(subgraphs) == 1 - factor_str = subgraph_factors[1] == 1 ? "" : " * $(subgraph_factors[1])" - return "(g$(subgraphs[1].id)$factor_str)" - else - terms = ["g$(g.id)" * (gfactor == 1 ? "" : " * $gfactor") for (g, gfactor) in zip(subgraphs, subgraph_factors)] - return "(" * join(terms, " + ") * ")" - end -end - -function to_pystatic(::Type{ComputationalGraphs.Prod}, subgraphs::Vector{Graph{F,W}}, subgraph_factors::Vector{F}) where {F,W} - if length(subgraphs) == 1 - factor_str = subgraph_factors[1] == 1 ? "" : " * $(subgraph_factors[1])" - return "(g$(subgraphs[1].id)$factor_str)" - else - terms = ["g$(g.id)" * (gfactor == 1 ? "" : " * $gfactor") for (g, gfactor) in zip(subgraphs, subgraph_factors)] - return "(" * join(terms, " * ") * ")" - # return "(" * join(["g$(g.id)" for g in subgraphs], " * ") * ")" - end -end - -function to_pystatic(::Type{ComputationalGraphs.Power{N}}, subgraphs::Vector{Graph{F,W}}, subgraph_factors::Vector{F}) where {N,F,W} - factor_str = subgraph_factors[1] == 1 ? "" : " * $(subgraph_factors[1])" - return "((g$(subgraphs[1].id))**$N$factor_str)" -end - -function to_pystatic(::Type{ComputationalGraphs.Sum}, subgraphs::Vector{FeynmanGraph{F,W}}, subgraph_factors::Vector{F}) where {F,W} - if length(subgraphs) == 1 - factor_str = subgraph_factors[1] == 1 ? "" : " * $(subgraph_factors[1])" - return "(g$(subgraphs[1].id)$factor_str)" - else - terms = ["g$(g.id)" * (gfactor == 1 ? "" : " * $gfactor") for (g, gfactor) in zip(subgraphs, subgraph_factors)] - return "(" * join(terms, " + ") * ")" - end -end - -function to_pystatic(::Type{ComputationalGraphs.Prod}, subgraphs::Vector{FeynmanGraph{F,W}}, subgraph_factors::Vector{F}) where {F,W} - if length(subgraphs) == 1 - factor_str = subgraph_factors[1] == 1 ? "" : " * $(subgraph_factors[1])" - return "(g$(subgraphs[1].id)$factor_str)" - else - terms = ["g$(g.id)" * (gfactor == 1 ? "" : " * $gfactor") for (g, gfactor) in zip(subgraphs, subgraph_factors)] - return "(" * join(terms, " * ") * ")" - end -end - -function to_pystatic(::Type{ComputationalGraphs.Power{N}}, subgraphs::Vector{FeynmanGraph{F,W}}, subgraph_factors::Vector{F}) where {N,F,W} - factor_str = subgraph_factors[1] == 1 ? "" : " * $(subgraph_factors[1])" - return "((g$(subgraphs[1].id))**$N$factor_str)" -end - -""" - function to_python_str(graphs::AbstractVector{<:AbstractGraph}) - Compile a list of graphs into a string for a python static function and output a python script which support the mindspore and jax framework. - - # Arguments: - - `graphs` vector of computational graphs - - `framework` the type of the python frameworks, including `:jax` and `mindspore`. -""" -function to_python_str(graphs::AbstractVector{<:AbstractGraph}, framework::Symbol=:jax) - if framework == :jax - head = "" - elseif framework == :mindspore - head = "import mindspore as ms\n@ms.jit\n" - else - error("no support for $type framework") - end - body = "" - leafidx = 1 - root = [id(g) for g in graphs] - inds_visitedleaf = Int[] - inds_visitednode = Int[] - gid_to_leafid = Dict{String, Int64}() - rootidx = 1 - for graph in graphs - for g in PostOrderDFS(graph) #leaf first search - g_id = id(g) - target = "g$(g_id)" - isroot = false - if g_id in root - isroot = true - end - if isempty(subgraphs(g)) #leaf - g_id in inds_visitedleaf && continue - factor_str = factor(g) == 1 ? "" : " * $(factor(g))" - body *= " $target = l$(leafidx)$factor_str\n" - gid_to_leafid[target] = leafidx - leafidx += 1 - push!(inds_visitedleaf, g_id) - else - g_id in inds_visitednode && continue - factor_str = factor(g) == 1 ? "" : " * $(factor(g))" - body *= " $target = $(to_pystatic(operator(g), subgraphs(g), subgraph_factors(g)))$factor_str\n" - push!(inds_visitednode, g_id) - end - if isroot - body *= " out$(rootidx)=$target\n" - rootidx +=1 - end - end - end - input = ["l$(i)" for i in 1:leafidx-1] - input = join(input,",") - output = ["out$(i)" for i in 1:rootidx-1] - output = join(output,",") - head *="def graphfunc($input):\n" - tail = " return $output\n" - # tail*= "def to_StaticGraph(leaf):\n" - # tail*= " output = graphfunc(leaf)\n" - # tail*= " return output" - expr = head * body * tail - println(expr) - # return head * body * tail - f = open("GraphFunc.py", "w") - write(f, expr) - return expr, leafidx-1, gid_to_leafid -end - +# ms = pyimport("mindspore") + +""" + function to_pystatic(operator::Type, subgraphs::AbstractVector{<:AbstractGraph}, subgraph_factors::AbstractVector) + +Returns the static representation of a computational graph node `g` with operator `operator`, subgraphs `subgraphs`, and subgraph factors `subgraph_factors` in python. +""" +function to_pystatic(operator::Type, subgraphs::AbstractVector{<:AbstractGraph}, subgraph_factors::AbstractVector) + error( + "Static representation for computational graph nodes with operator $(operator) not yet implemented! " * + "Please define a method `to_static(::Type{$(operator)}, subgraphs::$(typeof(subgraphs)), subgraph_factors::$(typeof(subgraph_factors)))`." + ) +end + +function to_pystatic(::Type{ComputationalGraphs.Sum}, subgraphs::Vector{Graph{F,W}}, subgraph_factors::Vector{F}) where {F,W} + if length(subgraphs) == 1 + factor_str = subgraph_factors[1] == 1 ? "" : " * $(subgraph_factors[1])" + return "(g$(subgraphs[1].id)$factor_str)" + else + terms = ["g$(g.id)" * (gfactor == 1 ? "" : " * $gfactor") for (g, gfactor) in zip(subgraphs, subgraph_factors)] + return "(" * join(terms, " + ") * ")" + end +end + +function to_pystatic(::Type{ComputationalGraphs.Prod}, subgraphs::Vector{Graph{F,W}}, subgraph_factors::Vector{F}) where {F,W} + if length(subgraphs) == 1 + factor_str = subgraph_factors[1] == 1 ? "" : " * $(subgraph_factors[1])" + return "(g$(subgraphs[1].id)$factor_str)" + else + terms = ["g$(g.id)" * (gfactor == 1 ? "" : " * $gfactor") for (g, gfactor) in zip(subgraphs, subgraph_factors)] + return "(" * join(terms, " * ") * ")" + # return "(" * join(["g$(g.id)" for g in subgraphs], " * ") * ")" + end +end + +function to_pystatic(::Type{ComputationalGraphs.Power{N}}, subgraphs::Vector{Graph{F,W}}, subgraph_factors::Vector{F}) where {N,F,W} + factor_str = subgraph_factors[1] == 1 ? "" : " * $(subgraph_factors[1])" + return "((g$(subgraphs[1].id))**$N$factor_str)" +end + +function to_pystatic(::Type{ComputationalGraphs.Sum}, subgraphs::Vector{FeynmanGraph{F,W}}, subgraph_factors::Vector{F}) where {F,W} + if length(subgraphs) == 1 + factor_str = subgraph_factors[1] == 1 ? "" : " * $(subgraph_factors[1])" + return "(g$(subgraphs[1].id)$factor_str)" + else + terms = ["g$(g.id)" * (gfactor == 1 ? "" : " * $gfactor") for (g, gfactor) in zip(subgraphs, subgraph_factors)] + return "(" * join(terms, " + ") * ")" + end +end + +function to_pystatic(::Type{ComputationalGraphs.Prod}, subgraphs::Vector{FeynmanGraph{F,W}}, subgraph_factors::Vector{F}) where {F,W} + if length(subgraphs) == 1 + factor_str = subgraph_factors[1] == 1 ? "" : " * $(subgraph_factors[1])" + return "(g$(subgraphs[1].id)$factor_str)" + else + terms = ["g$(g.id)" * (gfactor == 1 ? "" : " * $gfactor") for (g, gfactor) in zip(subgraphs, subgraph_factors)] + return "(" * join(terms, " * ") * ")" + end +end + +function to_pystatic(::Type{ComputationalGraphs.Power{N}}, subgraphs::Vector{FeynmanGraph{F,W}}, subgraph_factors::Vector{F}) where {N,F,W} + factor_str = subgraph_factors[1] == 1 ? "" : " * $(subgraph_factors[1])" + return "((g$(subgraphs[1].id))**$N$factor_str)" +end + +""" + function to_python_str(graphs::AbstractVector{<:AbstractGraph}) + Compile a list of graphs into a string for a python static function and output a python script which support the mindspore and jax framework. + + # Arguments: + - `graphs` vector of computational graphs + - `framework` the type of the python frameworks, including `:jax` and `mindspore`. +""" +function to_python_str(graphs::AbstractVector{<:AbstractGraph}, framework::Symbol=:jax) + if framework == :jax + head = "from jax import jit\n" + elseif framework == :mindspore + head = "import mindspore as ms\n@ms.jit\n" + else + error("no support for $type framework") + end + body = "" + leafidx = 0 + root = [id(g) for g in graphs] + inds_visitedleaf = Int[] + inds_visitednode = Int[] + gid_to_leafid = Dict{String,Int64}() + rootidx = 0 + for graph in graphs + for g in PostOrderDFS(graph) #leaf first search + g_id = id(g) + target = "g$(g_id)" + isroot = false + if g_id in root + isroot = true + end + if isempty(subgraphs(g)) #leaf + g_id in inds_visitedleaf && continue + factor_str = factor(g) == 1 ? "" : " * $(factor(g))" + body *= " $target = leaf[$(leafidx)]$factor_str\n" + gid_to_leafid[target] = leafidx + leafidx += 1 + push!(inds_visitedleaf, g_id) + else + g_id in inds_visitednode && continue + factor_str = factor(g) == 1 ? "" : " * $(factor(g))" + body *= " $target = $(to_pystatic(operator(g), subgraphs(g), subgraph_factors(g)))$factor_str\n" + push!(inds_visitednode, g_id) + end + if isroot + body *= " root$(rootidx) = $target\n" + rootidx += 1 + end + end + end + head *= "def graphfunc(leaf):\n" + output = ["root$(i)" for i in 0:rootidx-1] + output = join(output,",") + tail = " return $output\n\n" + + if framework == :jax + tail *="graphfunc_jit = jit(graphfunc)" + end + expr = head * body * tail + + return expr, leafidx , gid_to_leafid +end +function compile_python(graphs::AbstractVector{<:AbstractGraph}, framework::Symbol=:jax, filename::String="GraphFunc.py") + py_string, leafnum, leafmap = to_python_str(graphs,framework) + println("The number of leaves: $leafnum") + open(filename, "w") do f + write(f, py_string) + end + return leafnum, leafmap +end + +# function to_python_str(graphs::AbstractVector{<:AbstractGraph}, framework::Symbol=:jax) +# if framework == :jax +# head = "" +# elseif framework == :mindspore +# head = "import mindspore as ms\n@ms.jit\n" +# else +# error("no support for $type framework") +# end +# body = "" +# leafidx = 1 +# root = [id(g) for g in graphs] +# inds_visitedleaf = Int[] +# inds_visitednode = Int[] +# gid_to_leafid = Dict{String, Int64}() +# rootidx = 1 +# for graph in graphs +# for g in PostOrderDFS(graph) #leaf first search +# g_id = id(g) +# target = "g$(g_id)" +# isroot = false +# if g_id in root +# isroot = true +# end +# if isempty(subgraphs(g)) #leaf +# g_id in inds_visitedleaf && continue +# factor_str = factor(g) == 1 ? "" : " * $(factor(g))" +# body *= " $target = l$(leafidx)$factor_str\n" +# gid_to_leafid[target] = leafidx +# leafidx += 1 +# push!(inds_visitedleaf, g_id) +# else +# g_id in inds_visitednode && continue +# factor_str = factor(g) == 1 ? "" : " * $(factor(g))" +# body *= " $target = $(to_pystatic(operator(g), subgraphs(g), subgraph_factors(g)))$factor_str\n" +# push!(inds_visitednode, g_id) +# end +# if isroot +# body *= " out$(rootidx)=$target\n" +# rootidx +=1 +# end +# end +# end +# input = ["l$(i)" for i in 1:leafidx-1] +# input = join(input,",") +# output = ["out$(i)" for i in 1:rootidx-1] +# output = join(output,",") +# head *="def graphfunc($input):\n" +# tail = " return $output\n" +# # tail*= "def to_StaticGraph(leaf):\n" +# # tail*= " output = graphfunc(leaf)\n" +# # tail*= " return output" +# expr = head * body * tail +# println(expr) +# # return head * body * tail +# f = open("GraphFunc.py", "w") +# write(f, expr) +# return expr, leafidx-1, gid_to_leafid +# end + diff --git a/src/backend/to_dot.jl b/src/backend/to_dot.jl index 69e64f2f..6fc944dd 100644 --- a/src/backend/to_dot.jl +++ b/src/backend/to_dot.jl @@ -8,25 +8,29 @@ function to_dotstatic(::Type{ComputationalGraphs.Sum}, id::Int, factor::F, subgr node_temp = "" arrow_temp = "" if factor != 1 - opr_fac = "factor$(id)[label=$(factor), style=filled, fillcolor=lavender]\n" - opr_name = "g$(id)_t" - node_str = "g$(id)[shape=box, label = \"Mul\", style=filled, fillcolor=cornsilk,]\n" - arrow_temp *= "factor$(id)->g$(id)[arrowhead=vee,]\ng$(id)_t->g$(id)[arrowhead=vee,]\n" - node_temp *= opr_fac * node_str + # opr_fac = "factor$(id)[label=$(factor), style=filled, fillcolor=lavender]\n" + # opr_name = "g$(id)_t" + # node_str = "g$(id)[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,]\n" + # arrow_temp *= "factor$(id)->g$(id)[arrowhead=vee,]\ng$(id)_t->g$(id)[arrowhead=vee,]\n" + # node_temp *= opr_fac * node_str + opr_node = "g$(id)[shape=box, label = <($factor)*⊕>, style=filled, fillcolor=cyan,fontsize=18]" else - opr_name = "g$id" + opr_node = "g$(id)[shape=box, label = <⊕>, style=filled, fillcolor=cyan,fontsize=18]" + # opr_name = "g$id" end - opr_node = opr_name * "[shape=box, label = \"Add\", style=filled, fillcolor=cyan,]\n" + opr_name = "g$id" + # opr_node = opr_name * "[shape=box, label = <⊕>, style=filled, fillcolor=cyan,]\n" node_temp *= opr_node for (gix, (g, gfactor)) in enumerate(zip(subgraphs, subgraph_factors)) if gfactor != 1 - factor_str = "factor$(g.id)_$(id)_$gix[label=$(gfactor), style=filled, fillcolor=lavender]\n" - subg_str = "g$(g.id)_$(id)_$gix[shape=box, label = \"Mul\", style=filled, fillcolor=cornsilk,]\n" - node_temp *= factor_str * subg_str - arrow_temp *= "factor$(g.id)_$(id)_$gix->g$(g.id)_$(id)_$gix[arrowhead=vee,]\ng$(g.id)->g$(g.id)_$(id)_$gix[arrowhead=vee,]\n" - arrow_temp *= "g$(g.id)_$(id)_$gix->$opr_name[arrowhead=vee,]\n" + # factor_str = "factor$(g.id)_$(id)_$gix[label=$(gfactor), style=filled, fillcolor=lavender]\n" + # subg_str = "g$(g.id)_$(id)_$gix[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,]\n" + # node_temp *= factor_str * subg_str + # arrow_temp *= "factor$(g.id)_$(id)_$gix->g$(g.id)_$(id)_$gix[arrowhead=vee,]\ng$(g.id)->g$(g.id)_$(id)_$gix[arrowhead=vee,]\n" + # arrow_temp *= "g$(g.id)_$(id)_$gix->$opr_name[arrowhead=vee,]\n" + arrow_temp *= "g$(g.id)->g$(id)[arrowhead=vee,label=$gfactor,fontsize=16]\n" else - arrow_temp *= "g$(g.id)->$opr_name[arrowhead=vee,]\n" + arrow_temp *= "g$(g.id)->g$(id)[arrowhead=vee,]\n" end end return node_temp, arrow_temp @@ -36,37 +40,39 @@ function to_dotstatic(::Type{ComputationalGraphs.Prod}, id::Int, factor::F, subg node_temp = "" arrow_temp = "" if factor != 1 - opr_fac = "factor$(id)[label=$(factor), style=filled, fillcolor=lavender]\n" - opr_name = "g$(id)_t" - node_str = "g$(id)[shape=box, label = \"Mul\", style=filled, fillcolor=cornsilk,]\n" - arrow_temp *= "factor$(id)->g$(id)[arrowhead=vee,]\ng$(id)_t->g$(id)[arrowhead=vee,]\n" - node_temp *= opr_fac * node_str + # opr_fac = "factor$(id)[label=$(factor), style=filled, fillcolor=lavender]\n" + # opr_name = "g$(id)_t" + # node_str = "g$(id)[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,]\n" + # arrow_temp *= "factor$(id)->g$(id)[arrowhead=vee,]\ng$(id)_t->g$(id)[arrowhead=vee,]\n" + # node_temp *= opr_fac * node_str + opr_node = "g$id[shape=box, label = <($factor)⊗>, style=filled, fillcolor=cornsilk,fontsize=18]\n" else - opr_name = "g$id" + opr_node = "g$id[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,fontsize=18]\n" end - opr_node = opr_name * "[shape=box, label = \"Mul\", style=filled, fillcolor=cornsilk,]\n" + # opr_node = opr_name * "[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,]\n" node_temp *= opr_node - if length(subgraphs) == 1 - if subgraph_factors[1] == 1 - arrow_temp *= "g$(subgraphs[1].id)->$opr_name[arrowhead=vee,]\n" + # if length(subgraphs) == 1 + # if subgraph_factors[1] == 1 + # arrow_temp *= "g$(subgraphs[1].id)->$opr_name[arrowhead=vee,]\n" + # else + # factor_str = "factor$(subgraphs[1].id)_$(id)[label=$(subgraph_factors[1]), style=filled, fillcolor=lavender]\n" + # node_temp *= factor_str + # arrow_temp *= "factor$(subgraphs[1].id)_$(id)->$opr_name[arrowhead=vee,]\ng$(subgraphs[1].id)->$opr_name[arrowhead=vee,]\n" + # end + # else + for (gix, (g, gfactor)) in enumerate(zip(subgraphs, subgraph_factors)) + if gfactor != 1 + # factor_str = "factor$(g.id)_$(id)_$gix[label=$(gfactor), style=filled, fillcolor=lavender]\n" + # subg_str = "g$(g.id)_$(id)_$gix[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,]\n" + # node_temp *= factor_str * subg_str + # arrow_temp *= "factor$(g.id)_$(id)_$gix->g$(g.id)_$(id)_$gix[arrowhead=vee,]\ng$(g.id)->g$(g.id)_$(id)_$gix[arrowhead=vee,]\n" + # arrow_temp *= "g$(g.id)_$(id)_$gix->$opr_name[arrowhead=vee,]\n" + arrow_temp *= "g$(g.id)->g$(id)[arrowhead=vee,label=$gfactor,fontsize=16]\n" else - factor_str = "factor$(subgraphs[1].id)_$(id)[label=$(subgraph_factors[1]), style=filled, fillcolor=lavender]\n" - node_temp *= factor_str - arrow_temp *= "factor$(subgraphs[1].id)_$(id)->$opr_name[arrowhead=vee,]\ng$(subgraphs[1].id)->$opr_name[arrowhead=vee,]\n" - end - else - for (gix, (g, gfactor)) in enumerate(zip(subgraphs, subgraph_factors)) - if gfactor != 1 - factor_str = "factor$(g.id)_$(id)_$gix[label=$(gfactor), style=filled, fillcolor=lavender]\n" - subg_str = "g$(g.id)_$(id)_$gix[shape=box, label = \"Mul\", style=filled, fillcolor=cornsilk,]\n" - node_temp *= factor_str * subg_str - arrow_temp *= "factor$(g.id)_$(id)_$gix->g$(g.id)_$(id)_$gix[arrowhead=vee,]\ng$(g.id)->g$(g.id)_$(id)_$gix[arrowhead=vee,]\n" - arrow_temp *= "g$(g.id)_$(id)_$gix->$opr_name[arrowhead=vee,]\n" - else - arrow_temp *= "g$(g.id)->$opr_name[arrowhead=vee,]\n" - end + arrow_temp *= "g$(g.id)->g$(id)[arrowhead=vee,]\n" end end + # end return node_temp, arrow_temp end @@ -74,24 +80,26 @@ function to_dotstatic(::Type{ComputationalGraphs.Power{N}}, id::Int, factor::F, node_temp = "" arrow_temp = "" if factor != 1 - opr_fac = "factor$(id)[label=$(factor), style=filled, fillcolor=lavender]\n" - opr_name = "g$(id)_t" - node_str = "g$(id)[shape=box, label = \"Mul\", style=filled, fillcolor=cornsilk,]\n" - arrow_temp *= "factor$(id)->g$(id)[arrowhead=vee,]\ng$(id)_t->g$(id)[arrowhead=vee,]\n" - node_temp *= opr_fac * node_str + # opr_fac = "factor$(id)[label=$(factor), style=filled, fillcolor=lavender]\n" + # opr_name = "g$(id)_t" + # node_str = "g$(id)[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,]\n" + # arrow_temp *= "factor$(id)->g$(id)[arrowhead=vee,]\ng$(id)_t->g$(id)[arrowhead=vee,]\n" + # node_temp *= opr_fac * node_str + opr_node = "g$id[shape=box, label = <($factor)*Pow($N)>, style=filled, fillcolor=darkolivegreen,fontsize=18]\n" else - opr_name = "g$id" + opr_node = "g$id[shape=box, label = , style=filled, fillcolor=darkolivegreen,fontsize=18]\n" end - opr_node = opr_name * "[shape=box, label = \"Pow\", style=filled, fillcolor=darkolivegreen,]\n" - order_node = "order$(id)[label=$N, style=filled, fillcolor=lavender]\n" - node_temp *= opr_node * order_node - arrow_temp *= "order$(id)->$opr_name[arrowhead=vee,]\n" + # opr_node = "g$id[shape=box, label = , style=filled, fillcolor=darkolivegreen,]\n" + # order_node = "order$(id)[label=$N, style=filled, fillcolor=lavender]\n" + # node_temp *= opr_node * order_node + node_temp *= opr_node + # arrow_temp *= "order$(id)->$opr_name[arrowhead=vee,]\n" if subgraph_factors[1] != 1 - factor_str = "factor$(subgraphs[1].id)_$(id)[label=$(subgraph_factors[1]), style=filled, fillcolor=lavender]\n" - subg_str = "g$(subgraphs[1].id)_$(id)[shape=box, label = \"Mul\", style=filled, fillcolor=cornsilk,]\n" - node_temp *= factor_str * subg_str - arrow_temp *= "factor$(subgraphs[1].id)_$(id)->g$(subgraphs[1].id)_$(id)[arrowhead=vee,]\ng$(subgraphs[1].id)->g$(subgraphs[1].id)_$(id)[arrowhead=vee,]\n" - arrow_temp *= "g$(subgraphs[1].id)_$(id)->$opr_name[arrowhead=vee,]\n" + # factor_str = "factor$(subgraphs[1].id)_$(id)[label=$(subgraph_factors[1]), style=filled, fillcolor=lavender]\n" + # subg_str = "g$(subgraphs[1].id)_$(id)[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,]\n" + # node_temp *= factor_str * subg_str + # arrow_temp *= "factor$(subgraphs[1].id)_$(id)->g$(subgraphs[1].id)_$(id)[arrowhead=vee,]\ng$(subgraphs[1].id)->g$(subgraphs[1].id)_$(id)[arrowhead=vee,]\n" + arrow_temp *= "g$(subgraphs[1].id)->$opr_name[arrowhead=vee,label=$gfactor,fontsize=16]\n" else arrow_temp *= "g$(subgraphs[1].id)->$opr_name[arrowhead=vee,]\n" end @@ -102,23 +110,27 @@ function to_dotstatic(::Type{ComputationalGraphs.Sum}, id::Int, factor::F, subgr node_temp = "" arrow_temp = "" if factor != 1 - opr_fac = "factor$(id)[label=$(factor), style=filled, fillcolor=lavender]\n" - opr_name = "g$(id)_t" - node_str = "g$(id)[shape=box, label = \"Mul\", style=filled, fillcolor=cornsilk,]\n" - arrow_temp *= "factor$(id)->g$(id)[arrowhead=vee,]\ng$(id)_t->g$(id)[arrowhead=vee,]\n" - node_temp *= opr_fac * node_str + # opr_fac = "factor$(id)[label=$(factor), style=filled, fillcolor=lavender]\n" + # opr_name = "g$(id)_t" + # node_str = "g$(id)[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,]\n" + # arrow_temp *= "factor$(id)->g$(id)[arrowhead=vee,]\ng$(id)_t->g$(id)[arrowhead=vee,]\n" + # node_temp *= opr_fac * node_str + opr_node = "g$(id)[shape=box, label = <($factor)*⊕>, style=filled, fillcolor=cyan,fontsize=18]" else - opr_name = "g$id" + opr_node = "g$(id)[shape=box, label = <⊕>, style=filled, fillcolor=cyan,fontsize=18]" + # opr_name = "g$id" end - opr_node = opr_name * "[shape=box, label = \"Add\", style=filled, fillcolor=cyan,]\n" + opr_name = "g$id" + # opr_node = opr_name * "[shape=box, label = <⊕>, style=filled, fillcolor=cyan,]\n" node_temp *= opr_node for (gix, (g, gfactor)) in enumerate(zip(subgraphs, subgraph_factors)) if gfactor != 1 - factor_str = "factor$(g.id)_$(id)_$gix[label=$(gfactor), style=filled, fillcolor=lavender]\n" - subg_str = "g$(g.id)_$(id)_$gix[shape=box, label = \"Mul\", style=filled, fillcolor=cornsilk,]\n" - node_temp *= factor_str * subg_str - arrow_temp *= "factor$(g.id)_$(id)_$gix->g$(g.id)_$(id)_$gix[arrowhead=vee,]\ng$(g.id)->g$(g.id)_$(id)_$gix[arrowhead=vee,]\n" - arrow_temp *= "g$(g.id)_$(id)_$gix->$opr_name[arrowhead=vee,]\n" + # factor_str = "factor$(g.id)_$(id)_$gix[label=$(gfactor), style=filled, fillcolor=lavender]\n" + # subg_str = "g$(g.id)_$(id)_$gix[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,]\n" + # node_temp *= factor_str * subg_str + # arrow_temp *= "factor$(g.id)_$(id)_$gix->g$(g.id)_$(id)_$gix[arrowhead=vee,]\ng$(g.id)->g$(g.id)_$(id)_$gix[arrowhead=vee,]\n" + # arrow_temp *= "g$(g.id)_$(id)_$gix->$opr_name[arrowhead=vee,]\n" + arrow_temp *= "g$(g.id)->$opr_name[arrowhead=vee,label=$gfactor,fontsize=16]\n" else arrow_temp *= "g$(g.id)->$opr_name[arrowhead=vee,]\n" end @@ -130,37 +142,39 @@ function to_dotstatic(::Type{ComputationalGraphs.Prod}, id::Int, factor::F, subg node_temp = "" arrow_temp = "" if factor != 1 - opr_fac = "factor$(id)[label=$(factor), style=filled, fillcolor=lavender]\n" - opr_name = "g$(id)_t" - node_str = "g$(id)[shape=box, label = \"Mul\", style=filled, fillcolor=cornsilk,]\n" - arrow_temp *= "factor$(id)->g$(id)[arrowhead=vee,]\ng$(id)_t->g$(id)[arrowhead=vee,]\n" - node_temp *= opr_fac * node_str + # opr_fac = "factor$(id)[label=$(factor), style=filled, fillcolor=lavender]\n" + # opr_name = "g$(id)_t" + # node_str = "g$(id)[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,]\n" + # arrow_temp *= "factor$(id)->g$(id)[arrowhead=vee,]\ng$(id)_t->g$(id)[arrowhead=vee,]\n" + # node_temp *= opr_fac * node_str + opr_node = "g$id[shape=box, label = <($factor)⊗>, style=filled, fillcolor=cornsilk,fontsize=18]\n" else - opr_name = "g$id" + opr_node = "g$id[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,fontsize=18]\n" end - opr_node = opr_name * "[shape=box, label = \"Mul\", style=filled, fillcolor=cornsilk,]\n" + # opr_node = opr_name * "[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,]\n" node_temp *= opr_node - if length(subgraphs) == 1 - if subgraph_factors[1] == 1 - arrow_temp *= "g$(subgraphs[1].id)->$opr_name[arrowhead=vee,]\n" + # if length(subgraphs) == 1 + # if subgraph_factors[1] == 1 + # arrow_temp *= "g$(subgraphs[1].id)->$opr_name[arrowhead=vee,]\n" + # else + # factor_str = "factor$(subgraphs[1].id)_$(id)[label=$(subgraph_factors[1]), style=filled, fillcolor=lavender]\n" + # node_temp *= factor_str + # arrow_temp *= "factor$(subgraphs[1].id)_$(id)->$opr_name[arrowhead=vee,]\ng$(subgraphs[1].id)->$opr_name[arrowhead=vee,]\n" + # end + # else + for (gix, (g, gfactor)) in enumerate(zip(subgraphs, subgraph_factors)) + if gfactor != 1 + # factor_str = "factor$(g.id)_$(id)_$gix[label=$(gfactor), style=filled, fillcolor=lavender]\n" + # subg_str = "g$(g.id)_$(id)_$gix[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,]\n" + # node_temp *= factor_str * subg_str + # arrow_temp *= "factor$(g.id)_$(id)_$gix->g$(g.id)_$(id)_$gix[arrowhead=vee,]\ng$(g.id)->g$(g.id)_$(id)_$gix[arrowhead=vee,]\n" + # arrow_temp *= "g$(g.id)_$(id)_$gix->$opr_name[arrowhead=vee,]\n" + arrow_temp *= "g$(g.id)->g$(id)[arrowhead=vee,label=$gfactor,fontsize=16]\n" else - factor_str = "factor$(subgraphs[1].id)_$(id)[label=$(subgraph_factors[1]), style=filled, fillcolor=lavender]\n" - node_temp *= factor_str - arrow_temp *= "factor$(subgraphs[1].id)_$(id)->$opr_name[arrowhead=vee,]\ng$(subgraphs[1].id)->$opr_name[arrowhead=vee,]\n" - end - else - for (gix, (g, gfactor)) in enumerate(zip(subgraphs, subgraph_factors)) - if gfactor != 1 - factor_str = "factor$(g.id)_$(id)_$gix[label=$(gfactor), style=filled, fillcolor=lavender]\n" - subg_str = "g$(g.id)_$(id)_$gix[shape=box, label = \"Mul\", style=filled, fillcolor=cornsilk,]\n" - node_temp *= factor_str * subg_str - arrow_temp *= "factor$(g.id)_$(id)_$gix->g$(g.id)_$(id)_$gix[arrowhead=vee,]\ng$(g.id)->g$(g.id)_$(id)_$gix[arrowhead=vee,]\n" - arrow_temp *= "g$(g.id)_$(id)_$gix->$opr_name[arrowhead=vee,]\n" - else - arrow_temp *= "g$(g.id)->$opr_name[arrowhead=vee,]\n" - end + arrow_temp *= "g$(g.id)->g$(id)[arrowhead=vee,]\n" end end + # end return node_temp, arrow_temp end @@ -168,24 +182,26 @@ function to_dotstatic(::Type{ComputationalGraphs.Power{N}}, id::Int, factor::F, node_temp = "" arrow_temp = "" if factor != 1 - opr_fac = "factor$(id)[label=$(factor), style=filled, fillcolor=lavender]\n" - opr_name = "g$(id)_t" - node_str = "g$(id)[shape=box, label = \"Mul\", style=filled, fillcolor=cornsilk,]\n" - arrow_temp *= "factor$(id)->g$(id)[arrowhead=vee,]\ng$(id)_t->g$(id)[arrowhead=vee,]\n" - node_temp *= opr_fac * node_str + # opr_fac = "factor$(id)[label=$(factor), style=filled, fillcolor=lavender]\n" + # opr_name = "g$(id)_t" + # node_str = "g$(id)[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,]\n" + # arrow_temp *= "factor$(id)->g$(id)[arrowhead=vee,]\ng$(id)_t->g$(id)[arrowhead=vee,]\n" + # node_temp *= opr_fac * node_str + opr_node = "g$id[shape=box, label = <($factor)*Pow($N)>, style=filled, fillcolor=darkolivegreen,fontsize=18]\n" else - opr_name = "g$id" + opr_node = "g$id[shape=box, label = , style=filled, fillcolor=darkolivegreen,fontsize=18]\n" end - opr_node = opr_name * "[shape=box, label = \"Pow\", style=filled, fillcolor=darkolivegreen,]\n" - order_node = "order$(id)[label=$N, style=filled, fillcolor=lavender]\n" - node_temp *= opr_node * order_node - arrow_temp *= "order$(id)->$opr_name[arrowhead=vee,]\n" + # opr_node = "g$id[shape=box, label = , style=filled, fillcolor=darkolivegreen,]\n" + # order_node = "order$(id)[label=$N, style=filled, fillcolor=lavender]\n" + # node_temp *= opr_node * order_node + node_temp *= opr_node + # arrow_temp *= "order$(id)->$opr_name[arrowhead=vee,]\n" if subgraph_factors[1] != 1 - factor_str = "factor$(subgraphs[1].id)_$(id)[label=$(subgraph_factors[1]), style=filled, fillcolor=lavender]\n" - subg_str = "g$(subgraphs[1].id)_$(id)[shape=box, label = \"Mul\", style=filled, fillcolor=cornsilk,]\n" - node_temp *= factor_str * subg_str - arrow_temp *= "factor$(subgraphs[1].id)_$(id)->g$(subgraphs[1].id)_$(id)[arrowhead=vee,]\ng$(subgraphs[1].id)->g$(subgraphs[1].id)_$(id)[arrowhead=vee,]\n" - arrow_temp *= "g$(subgraphs[1].id)_$(id)->$opr_name[arrowhead=vee,]\n" + # factor_str = "factor$(subgraphs[1].id)_$(id)[label=$(subgraph_factors[1]), style=filled, fillcolor=lavender]\n" + # subg_str = "g$(subgraphs[1].id)_$(id)[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,]\n" + # node_temp *= factor_str * subg_str + # arrow_temp *= "factor$(subgraphs[1].id)_$(id)->g$(subgraphs[1].id)_$(id)[arrowhead=vee,]\ng$(subgraphs[1].id)->g$(subgraphs[1].id)_$(id)[arrowhead=vee,]\n" + arrow_temp *= "g$(subgraphs[1].id)->$opr_name[arrowhead=vee,label=$gfactor,fontsize=16]\n" else arrow_temp *= "g$(subgraphs[1].id)->$opr_name[arrowhead=vee,]\n" end @@ -203,7 +219,7 @@ end """ function to_dot_str(graphs::AbstractVector{<:AbstractGraph}, name::String="", diagram_id_map=nothing) head = "digraph ComputationalGraph { \nlabel=\"$name\"\n" - head *= "ReturnNode[shape=box, label = \"Return\", style=filled, fillcolor=darkorange,]\n" + head *= "ReturnNode[shape=box, label = \"Return\", style=filled, fillcolor=darkorange,fontsize=18]\n" body_node = "" body_arrow = "" leafidx = 1 @@ -222,14 +238,19 @@ function to_dot_str(graphs::AbstractVector{<:AbstractGraph}, name::String="", di g_id in inds_visitedleaf && continue leafname = get_leafname(g, leafidx, diagram_id_map) if factor(g) == 1 - gnode_str = "g$g_id[label=$leafname, style=filled, fillcolor=paleturquoise]\n" + gnode_str = "g$g_id[label=<$leafname>, style=filled, fillcolor=paleturquoise,fontsize=18]\n" + body_node *= gnode_str + elseif factor(g) == -1 + gnode_str = "g$g_id[label=<-$leafname>, style=filled, fillcolor=paleturquoise,fontsize=18]\n" body_node *= gnode_str else - factor_str = "factor$(leafidx)_inp[label=$(factor(g)), style=filled, fillcolor=lavender]\n" - leaf_node = "l$(leafidx)[label=$leafname, style=filled, fillcolor=paleturquoise]\n" - gnode_str = "g$g_id[shape=box, label = \"Mul\", style=filled, fillcolor=cornsilk,]\n" - body_node *= factor_str * leaf_node * gnode_str - body_arrow *= "factor$(leafidx)_inp->g$g_id[arrowhead=vee,]\nl$(leafidx)->g$g_id[arrowhead=vee,]\n" + # factor_str = "factor$(leafidx)_inp[label=$(factor(g)), style=filled, fillcolor=lavender]\n" + # leaf_node = "l$(leafidx)[label=$leafname, style=filled, fillcolor=paleturquoise]\n" + # gnode_str = "g$g_id[shape=box, label = <⊗>, style=filled, fillcolor=cornsilk,]\n" + gnode_str = "l$(leafidx)[label=<$(factor(g))$leafname>, style=filled, fillcolor=paleturquoise,fontsize=18]\n" + # body_node *= factor_str * leaf_node * gnode_str + body_node *= gnode_str + # body_arrow *= "factor$(leafidx)_inp->g$g_id[arrowhead=vee,]\nl$(leafidx)->g$g_id[arrowhead=vee,]\n" end leafidx += 1 push!(inds_visitedleaf, g_id) @@ -260,34 +281,36 @@ function compile_dot(graphs::AbstractVector{<:AbstractGraph}, filename::String; end function get_leafname(g, leafidx, diagram_id_map=nothing) - println(typeof(g)) + # println(typeof(g)) leaftype = Nothing if g isa FeynmanGraph leaftype = g.properties.diagtype elseif g isa Graph if isnothing(diagram_id_map) == false leaftype = typeof(diagram_id_map[g.id]) + else + leaftype = typeof(g.properties) end else error("Unknown graph type: $(typeof(g))") end if leaftype in [BareGreenId, ComputationalGraphs.Propagator] - leafname = "<G$leafidx>" + leafname = "G$leafidx" elseif leaftype in [BareInteractionId, ComputationalGraphs.Interaction] - leafname = "<V$leafidx>" + leafname = "V$leafidx" elseif leaftype == PolarId - leafname = "<Π$leafidx>" + leafname = "Π$leafidx" elseif leaftype == Ver3Id - leafname = "<Γ(3)$leafidx>" + leafname = "Γ(3)$leafidx" elseif leaftype == Ver4Id - leafname = "<Γ(4)$leafidx>" + leafname = "Γ(4)$leafidx" else - leafname = "$leafidx>" + leafname = "L$leafidx" end - println() - println(g) - println(leaftype) - println(leafname) - println() + # println() + # println(g) + # println(leaftype) + # println(leafname) + # println() return leafname end