added tests but need to do rewrites. focus on GPU execution for now
Some checks are pending
CI / Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} (x64, ubuntu-latest, 1.10) (push) Waiting to run
CI / Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} (x64, ubuntu-latest, 1.6) (push) Waiting to run
CI / Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} (x64, ubuntu-latest, pre) (push) Waiting to run

This commit is contained in:
Daniel 2024-07-11 15:44:22 +02:00
parent 81d0158e46
commit 26741adec7
6 changed files with 119 additions and 52 deletions

View File

@ -3,6 +3,9 @@ uuid = "5b8ee377-1e19-4ba5-a85c-78c7d1694bfe"
authors = ["Daniel Wiplinger"] authors = ["Daniel Wiplinger"]
version = "1.0.0-DEV" version = "1.0.0-DEV"
[deps]
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
[compat] [compat]
julia = "1.6.7" julia = "1.6.7"

View File

@ -1,11 +1,12 @@
module ExpressionExecutorCuda module ExpressionExecutorCuda
include("Interpreter.jl") include("Interpreter.jl")
include("ExpressionProcessing.jl")
export interpret_gpu export interpret_gpu
export evaluate_gpu export evaluate_gpu
export test export test
const SymbolTable64 = Dict{Tuple{Expr, Symbol},Float64} # const SymbolTable64 = Dict{Tuple{Expr, Symbol},Float64}
# #
# Some assertions: # Some assertions:
# Variables and parameters start their naming with "1" meaning the first variable/parameter has to be "x1/p1" and not "x0/p0" # Variables and parameters start their naming with "1" meaning the first variable/parameter has to be "x1/p1" and not "x0/p0"
@ -40,60 +41,18 @@ end
- It replaces every variable with the according value stored in X and p. - It replaces every variable with the according value stored in X and p.
- It transforms the expressions into postfix form and returns them. - It transforms the expressions into postfix form and returns them.
" "
function preprocess_expressions!(exprs::Vector{Expr}, X::Matrix{Float64}, p::Vector{Vector{Float64}})::Vector{String} function preprocess_expressions!(exprs::Vector{Expr}, X::Matrix{Float64}, p::Vector{Vector{Float64}})::Array{String}
symtable = construct_symtable(exprs, X, p) symtable = ExpressionProcessing.construct_symtable(exprs, X, p)
postfixExpressions = postfixExpressions = Array{String,1}()
# Test if multi threading provides a speedup and if it does, roughly determin the size at which it is beneficial. # Test if multi threading provides a speedup and if it does, roughly determin the size at which it is beneficial.
for i in eachindex(exprs) for i in eachindex(exprs)
replace_variables!(exprs[i], symtable) expr = deepcopy(exprs[i])
ExpressionProcessing.replace_variables!(exprs[i], symtable, expr)
push!(postfixExpressions, ExpressionProcessing.expr_to_postfix(exprs[i]))
end end
return expr_to_postfix() return postfixExpressions
end
function expr_to_postfix()::Array{String}
# TODO
end
# Probaly move the below function into another module
"Replaces all the variables and parameters of the given expression with their corresponding value stored in the symtable"
function replace_variables!(ex::Expr, symtable::SymbolTable64)
for i in 1:length(ex.args)
arg = ex.args[i]
if typeof(arg) === Expr
replace_variables!(ex, symtable)
elseif haskey(symtable, (ex,arg)) # We found a variable/parameter and can replace it with the actual value
ex.args[i] = symtable[(ex,arg)]
end
end
end
function construct_symtable(expressions::Vector{Expr}, mat::Matrix{Float64}, params::Vector{Vector{Float64}})::SymbolTable64
symtable = SymbolTable64()
for i in eachindex(expressions)
expr = expressions[i]
values = mat[:,i]
parameters = params[i]
fill_symtable!(expr, symtable, values, "x")
fill_symtable!(expr, symtable, parameters, "p")
end
return symtable
end
function fill_symtable!(expr::Expr, symtable::SymbolTable64, values::Vector{Float64}, symbolPrefix::String)
varIndex = 1
for j in eachindex(values)
val = values[j]
sym = Symbol(symbolPrefix, varIndex)
symtable[expr,sym] = val
varIndex += 1
end
end end
end end
@ -102,7 +61,8 @@ end
# Flow # Flow
# input: Vector expr == expressions contains eg. 4 expressions # input: Vector expr == expressions contains eg. 4 expressions
# Matrix X == |expr| columns, n rows. n == number of variabls x1..xn; n is the same for all expressions # Matrix X == |expr| columns, n rows. n == number of variabls x1..xn; n is the same for all expressions --- WRONG
# Matrix X == k columns, n rows. k == number of variables in the expressions (every expression must have the same number of variables); n == number of different values for xk where k is the column
# VectorVector p == vector size |expr| containing vector size m. m == number of parameters per expression. p can be different for each expression # VectorVector p == vector size |expr| containing vector size m. m == number of parameters per expression. p can be different for each expression
# #
# The following can be done on the CPU # The following can be done on the CPU

View File

@ -0,0 +1,71 @@
module ExpressionProcessing
export construct_symtable
export replace_variables!
export expr_to_postfix
export SymbolTable64
const SymbolTable64 = Dict{Tuple{Expr, Symbol},Float64}
# Maybe switch from Array{String} to Array{Union{Float64, String}}?
function expr_to_postfix(expr::Expr)::Array{String}
postfix = Array{String,1}()
operator = String(expr.args[1])
push!(postfix, expr.args[2], expr.args[3], operator)
for i in 4:length(expr.args)
arg = expr.args[i]
if typeof(arg) === Expr
push!(postfix, expr_to_postfix(ex))
else
push!(postfix, string(arg), operator)
end
end
end
"Replaces all the variables and parameters of the given expression with their corresponding value stored in the symtable
# Arguments
- `symtable::SymbolTable64`: Contains the values of all variables for each expression
- `originalExpr::Expr`: Contains a deep copy of the original expression. It is used to link the expression and variables to their according value stored in the symtable
"
function replace_variables!(ex::Expr, symtable::SymbolTable64, originalExpr::Expr)
for i in 1:length(ex.args)
arg = ex.args[i]
if typeof(arg) === Expr
replace_variables!(arg, symtable, originalExpr)
elseif haskey(symtable, (originalExpr,arg)) # We found a variable/parameter and can replace it with the actual value
println("Replacing")
ex.args[i] = symtable[(originalExpr,arg)]
end
end
end
# TODO: Completly rewrite this function because I misunderstood it. Not every column is linked to an expression. therefore all other functions need to be reworked as well. Probably can't replace the variables in julia anymore, look into this. (see ExpressionExecutorCuda.jl for more info)
# Before rewriting, proceed with just creating a postfix notation and sending the variable matrix as well as the parameter "matrix" to the GPU to perform first calculations
function construct_symtable(expressions::Vector{Expr}, mat::Matrix{Float64}, params::Vector{Vector{Float64}})::SymbolTable64
symtable = SymbolTable64()
for i in eachindex(expressions)
expr = expressions[i]
values = mat[i,:]
parameters = params[i]
fill_symtable!(expr, symtable, values, "x")
fill_symtable!(expr, symtable, parameters, "p")
end
return symtable
end
function fill_symtable!(expr::Expr, symtable::SymbolTable64, values::Vector{Float64}, symbolPrefix::String)
varIndex = 1
for j in eachindex(values)
val = values[j]
sym = Symbol(symbolPrefix, varIndex)
symtable[expr,sym] = val
varIndex += 1
end
end
end

View File

@ -0,0 +1,31 @@
expressions = Vector{Expr}(undef, 1)
variables = Matrix{Float64}(undef, 1,2)
parameters = Vector{Vector{Float64}}(undef, 1)
# Resulting value should be 10
expressions[1] = :(x1 + 1 * x2 + p1)
variables[1,1] = 2
variables[1,2] = 3
parameters[1] = Vector{Float64}(undef, 1)
parameters[1][1] = 5
@testset "Test symtable construction" begin
symtable = ExpressionExecutorCuda.ExpressionProcessing.construct_symtable(expressions, variables, parameters)
@test haskey(symtable, (expressions[1], :x1))
@test haskey(symtable, (expressions[1], :x2))
@test haskey(symtable, (expressions[1], :p1))
@test symtable[(expressions[1], :x1)] 2.0 atol=0.01
@test symtable[(expressions[1], :x2)] 3.0 atol=0.01
@test symtable[(expressions[1], :p1)] 5.0 atol=0.01
end
@testset "Test variable replacement in expression" begin
symtable = ExpressionExecutorCuda.ExpressionProcessing.construct_symtable(expressions, variables, parameters)
println(keys(symtable))
exprCopy = deepcopy(expressions[1])
ExpressionExecutorCuda.ExpressionProcessing.replace_variables!(exprCopy, symtable, expressions[1])
dump(exprCopy)
@test eval(exprCopy) == 10 # If it can be evaluated, it means all variables have been replaced, as there are no globally defined variables
end

View File

@ -0,0 +1,2 @@
[deps]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

View File

@ -2,5 +2,5 @@ using ExpressionExecutorCuda
using Test using Test
@testset "ExpressionExecutorCuda.jl" begin @testset "ExpressionExecutorCuda.jl" begin
# Write your tests here. include("ExpressionProcessing.jl")
end end