From 6b7a4b4bca845e973f851db8e08b5bd443aac90e Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 24 Jul 2024 14:42:26 +0200 Subject: [PATCH] added first (wrong) attempt at implementing the interpretation. Added input explanation to the readme for a better understanding --- README.md | 13 + images/input-explanation.png | Bin 0 -> 116075 bytes other/input-explanation.drawio | 504 +++++++++++++++++++++++++++++++ package/src/Interpreter.jl | 45 ++- package/test/InterpreterTests.jl | 6 +- 5 files changed, 558 insertions(+), 10 deletions(-) create mode 100644 images/input-explanation.png create mode 100644 other/input-explanation.drawio diff --git a/README.md b/README.md index 83e01ed..87cc1a9 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ # master-thesis +Input: + - Vector of Expressions ```expressions::Vector{Expr}``` + - Matrix for the variables of the expression (x1..xn) ```variables::Matrix{Float64}``` + - Vector of Vectors for the parameters of the expression (p1..pn) ```parameters::Vector{Vector{Float64}}``` + +All expressions have to have the same number of variables. They do not need to appear in the same spot, they only need to be labled x1 through xn. However, they can have a different number of parameters. These can also appear at any given point and must be labled p1 through pn. + +The Matrix has to be in a form, where each column corresponds to a variable. So the i-th column corresponds to the variable xi. Each row is another set of variables to use for an expression. For each expression, every row is used to calculate a result. + +Every inner vector of the parameters corresponds to an expression. So the i-th inner vector stores the parameter values for the i-th expression. Parameter pi corresponds to the value stored at index i of the inner vector. + +The figure below demonstrates how the input data is structured and how they work together. Note that all x1..xn and p1..pn are the markers for the variables and parameters used in the expressions and can have an arbitrary value. Not every p1 needs to have the same value and not every x1 needs to have the ame value. +![Explanation of the input data](images/input-explanation.png) \ No newline at end of file diff --git a/images/input-explanation.png b/images/input-explanation.png new file mode 100644 index 0000000000000000000000000000000000000000..598fcebea36dd2f01d4ee1fad688a904ac3e3791 GIT binary patch literal 116075 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
UurXo9SAC*|k=@r3Ma; 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/package/src/Interpreter.jl b/package/src/Interpreter.jl index e159c8a..331cfda 100644 --- a/package/src/Interpreter.jl +++ b/package/src/Interpreter.jl @@ -13,12 +13,14 @@ export interpret function interpret(expressions::Vector{ExpressionProcessing.PostfixType}, variables::Matrix{Float64}, parameters::Vector{Vector{Float64}}) # TODO: # create CUDA array for calculation results + variableRows = size(variables, 1) cudaVars = CuArray(variables) - cudaParams = create_cuda_array(parameters, NaN64) - cudaExprs = create_cuda_array(expressions, ExpressionElement(EMPTY, 0)) + cudaParams = create_cuda_array(parameters, NaN64) # column corresponds to data for one expression + cudaExprs = create_cuda_array(expressions, ExpressionElement(EMPTY, 0)) # column corresponds to data for one expression cudaStepsize = CuArray([get_max_inner_length(expressions), get_max_inner_length(parameters)]) # put into seperate cuArray, as this is static and would be inefficient to send seperatly to every kernel + println(cudaVars) # Start kernel for each expression to ensure that no warp is working on different expressions for i in eachindex(expressions) kernel = @cuda launch=false interpret_expression(cudaExprs, cudaVars, cudaParams, cudaStepsize, i) @@ -31,16 +33,45 @@ function interpret(expressions::Vector{ExpressionProcessing.PostfixType}, variab end function interpret_expression(expressions::CuDeviceArray{ExpressionElement}, variables::CuDeviceArray{Float64}, parameters::CuDeviceArray{Float64}, stepsize::CuDeviceArray{Int}, exprIndex::Int) - firstExprIndex = (exprIndex - 1 * stepsize[1]) + 1 # Inclusive - lastExprIndex = firstExprIndex + stepsize[1] # Exclusive - firstParamIndex = (exprIndex - 1 * stepsize[2]) + 1 # Inclusive - # lastParamIndex = firstParamIndex + stepsize[2] # Exclusive (probably not needed) - + firstExprIndex = ((exprIndex - 1) * stepsize[1]) + 1 # Inclusive + lastExprIndex = firstExprIndex + stepsize[1] - 1 # Inclusive + firstParamIndex = ((exprIndex - 1) * stepsize[2]) + 1 # Inclusive + # lastParamIndex = firstParamIndex + stepsize[2] - 1 # Inclusive (probably not needed) + + for i in 1:5 + @cuprintln(variables[i]) + end + + # Not the correct approach. Redo this to be more stack based. for i in firstExprIndex:lastExprIndex # TODO Implement interpreter # - start at firstExprIndex and interpret until the first ExpressionElement is "Empty" or we reached lastExprIndex + if expressions[i].Type == EMPTY + break + elseif expressions[i].Type == INT64 + # TODO: Load value from variables/parameters matrix and store for calculation + val = expressions[i].Value + + if val > 0 + # TODO: access variables + else + val = abs(val) + # TODO: access parameters + end + continue + elseif expressions[i].Type == FLOAT64 + # TODO: store value as is for calculation + continue + elseif expressions[i].Type == OPERATOR + # TODO: Perform calculation of the two stored values according to the operator + continue + else + # TODO: handle this case. Should not happen but in case it does, it needs to do something + continue + end end + # TODO: Store computed value in output matrix return end diff --git a/package/test/InterpreterTests.jl b/package/test/InterpreterTests.jl index bf30c99..0eae21a 100644 --- a/package/test/InterpreterTests.jl +++ b/package/test/InterpreterTests.jl @@ -6,13 +6,13 @@ expressions = Vector{Expr}(undef, 2) variables = Matrix{Float64}(undef, 2,2) parameters = Vector{Vector{Float64}}(undef, 2) -# Resulting value should be 10 +# Resulting value should be 10 for the first expression expressions[1] = :(x1 + 1 * x2 + p1) expressions[2] = :(5 + x1 + 1 * x2 + p1 + p2) variables[1,1] = 2.0 variables[1,2] = 3.0 -variables[2,1] = 2.0 -variables[2,2] = 3.0 +variables[2,1] = 0.0 +variables[2,2] = 5.0 parameters[1] = Vector{Float64}(undef, 1) parameters[2] = Vector{Float64}(undef, 2) parameters[1][1] = 5.0