From 62d10845e99a67282fbe05ce28ee2b31279e30eb Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 8 Aug 2024 12:06:42 +0200 Subject: [PATCH] added operators to the interpreter. storing result still missing --- README.md | 4 +- images/input-explanation.png | Bin 116504 -> 155674 bytes other/input-explanation.drawio | 175 ++++++++++++++++++++++++------- package/src/Interpreter.jl | 89 +++++++++------- package/test/InterpreterTests.jl | 6 +- 5 files changed, 195 insertions(+), 79 deletions(-) diff --git a/README.md b/README.md index 87cc1a9..620758c 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ Input: - 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. +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. Parameters and variables can not have the label x0 or p0. -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. +The Matrix is being read in column-major order. This means that each column corresponds to a set of variables to use for the expressions. Row 1 through row n are then used to retrieve the values for x1 through xn. 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. diff --git a/images/input-explanation.png b/images/input-explanation.png index 9d20a0b27b0e42302562919f6553376ad07fd7af..700b32bfc1708e2063332b10493b3d94a9dc3068 100644 GIT binary patch literal 155674 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 + - + @@ -40,6 +40,24 @@ + + + + + + + + + + + + + + + + + + @@ -104,30 +122,30 @@ - + - - + + - - + + - - + + - - + + @@ -164,12 +182,12 @@ - + - - + + @@ -180,8 +198,8 @@ - - + + @@ -198,8 +216,8 @@ - - + + @@ -257,22 +275,22 @@ - + - + - + - + - + - + @@ -299,13 +317,13 @@ - + - + - + @@ -370,25 +388,25 @@ - + - + - + - + @@ -406,6 +424,14 @@ + + + + + + + + @@ -418,6 +444,14 @@ + + + + + + + + @@ -430,16 +464,24 @@ + + + + + + + + - + - + @@ -449,7 +491,7 @@ - + @@ -459,7 +501,7 @@ - + @@ -469,13 +511,13 @@ - + - + @@ -484,7 +526,7 @@ - + @@ -493,6 +535,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/package/src/Interpreter.jl b/package/src/Interpreter.jl index 648bc23..604bff8 100644 --- a/package/src/Interpreter.jl +++ b/package/src/Interpreter.jl @@ -12,80 +12,94 @@ export interpret - parameters::Vector{Vector{Float64}} : The parameters to use. Each Vector contains the values for the parameters p1..pn. The number of parameters can be different for every expression " function interpret(expressions::Vector{ExpressionProcessing.PostfixType}, variables::Matrix{Float64}, parameters::Vector{Vector{Float64}}) - # TODO: - # create CUDA array for calculation results - - variableRows = size(variables, 1) + variableCols = size(variables, 2) # number of sets of variables to use for each expression cudaVars = CuArray(variables) 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 + # put into seperate cuArray, as this is static and would be inefficient to send seperatly to every kernel + cudaStepsize = CuArray([get_max_inner_length(expressions), get_max_inner_length(parameters), size(variables, 1)]) # max num of values per expression; max nam of parameters per expression; number of variables per expression + + # each expression has nr. of variable sets (nr. of columns of the variables) results and there are n expressions + cudaResults = CuArray{Float64}(undef, length(expressions), variableCols) # 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) + kernel = @cuda launch=false interpret_expression(cudaExprs, cudaVars, cudaParams, cudaResults, cudaStepsize, i) config = launch_configuration(kernel.fun) - threads = min(variableRows, config.threads) - blocks = cld(variableRows, threads) + threads = min(variableCols, config.threads) + blocks = cld(variableCols, threads) - # TODO: Operation stack should be n-dims. nr. of Rows == length of this expression - # nr. of columns == nr. of rows in Vars - # This means every run with different variable set has its own stack - # cudaOperationStack = CuArray{Float64}(undef, get_max_inner_length(expressions), length(expressions)) - - kernel(cudaExprs, cudaVars, cudaParams, cudaStepsize, i; threads, blocks) + kernel(cudaExprs, cudaVars, cudaParams, cudaResults, cudaStepsize, i; threads, blocks) end end const MAX_STACK_SIZE = 25 # The max number of values the expression can have. so Constant values, Variables and parameters -function interpret_expression(expressions::CuDeviceArray{ExpressionElement}, variables::CuDeviceArray{Float64}, parameters::CuDeviceArray{Float64}, stepsize::CuDeviceArray{Int}, exprIndex::Int) +function interpret_expression(expressions::CuDeviceArray{ExpressionElement}, variables::CuDeviceArray{Float64}, parameters::CuDeviceArray{Float64}, results::CuDeviceArray{Float64}, stepsize::CuDeviceArray{Int}, exprIndex::Int) firstExprIndex = ((exprIndex - 1) * stepsize[1]) + 1 # Inclusive lastExprIndex = firstExprIndex + stepsize[1] - 1 # Inclusive firstParamIndex = ((exprIndex - 1) * stepsize[2]) # Exclusive # lastParamIndex = firstParamIndex + stepsize[2] - 1 # Inclusive (probably not needed) - operationStack = MVector{MAX_STACK_SIZE, Float64}(undef) # Vector{Float64}(undef, MAX_STACK_SIZE) # Try to get this to function with variable size too - operationStackTop = 1 - for i in reverse(firstExprIndex:lastExprIndex) # Calculate real "lastExprIndex" - if expressions[i].Type != EMPTY - lastExprIndex = i - break - end - end - - for i in 1:5 - @cuprintln(variables[i]) - end + variableCols = length(variables) / stepsize[3] + firstVariableIndex = ((exprIndex - 1) * stepsize[3]) # Exclusive # TODO: This is obviously not right because each expression calculates the cudaResults for each variable set and therefore needs to incorporate the block index + stride. This is only done for testing + firstResultsIndex = ((exprIndex - 1) * variableCols) + 1 # Inclusive # TODO: Same as above. to get the index of the variable set and therefore the index in the results matrix, use the block index and stride + operationStack = MVector{MAX_STACK_SIZE, Float64}(undef) # Try to get this to function with variable size too, to allow better memory usage + operationStackTop = 0 # stores index of the last defined/valid value + + # TODO: Look into Index and stride for the case that one thread handles multiple "variable sets" return - + for i in firstExprIndex:lastExprIndex if expressions[i].Type == EMPTY break elseif expressions[i].Type == INDEX - # TODO: Load value from variables/parameters matrix and store for calculation val = expressions[i].Value + operationStackTop += 1 if val > 0 - # TODO: access variables + operationStack[operationStackTop] = variables[firstVariableIndex + val] else val = abs(val) operationStack[operationStackTop] = parameters[firstParamIndex + val] end - operationStackTop += 1 elseif expressions[i].Type == FLOAT64 - operationStack[operationStackTop] = expressions[i].Value operationStackTop += 1 + operationStack[operationStackTop] = reinterpret(Float64, expressions[i].Value) elseif expressions[i].Type == OPERATOR - # TODO: Perform calculation of the stored values. Either 1 or 2, depending on the operator - continue + # TODO Maybe put this in seperate function + type = expressions[i].Type + if type == ADD + operationStackTop -= 1 + operationStack[operationStackTop] = operationStack[operationStackTop] + operationStack[operationStackTop + 1] + elseif type == SUBTRACT + operationStackTop -= 1 + operationStack[operationStackTop] = operationStack[operationStackTop] - operationStack[operationStackTop + 1] + elseif type == MULTIPLY + operationStackTop -= 1 + operationStack[operationStackTop] = operationStack[operationStackTop] * operationStack[operationStackTop + 1] + elseif type == DIVIDE + operationStackTop -= 1 + operationStack[operationStackTop] = operationStack[operationStackTop] / operationStack[operationStackTop + 1] + elseif type == POWER + operationStackTop -= 1 + operationStack[operationStackTop] = operationStack[operationStackTop] ^ operationStack[operationStackTop + 1] + elseif type == ABS + operationStack[operationStackTop] = abs(operationStack[operationStackTop]) + elseif type == LOG + operationStack[operationStackTop] = log(operationStack[operationStackTop]) + elseif type == EXP + operationStack[operationStackTop] = exp(operationStack[operationStackTop]) + elseif type == SQRT + operationStack[operationStackTop] = sqrt(operationStack[operationStackTop]) + end else - # TODO: handle this case. Should not happen but in case it does, it needs to do something - continue + operationStack[operationStackTop] = NaN + break end end - # TODO: Store computed value in output matrix + # results[] = operationStack[operationStackTop] return end @@ -131,7 +145,6 @@ end -# @deprecate InterpretExplicit!(op::Operator, x, y) interpret_expression(expression, variables, parameters, exprIndex::Int) # Kernel function InterpretExplicit!(op::Operator, x, y) index = (blockIdx().x - 1) * blockDim().x + threadIdx().x diff --git a/package/test/InterpreterTests.jl b/package/test/InterpreterTests.jl index 12914fe..0b5bcef 100644 --- a/package/test/InterpreterTests.jl +++ b/package/test/InterpreterTests.jl @@ -39,4 +39,8 @@ end result = Interpreter.convert_to_matrix(parameters, NaN64) @test isequal(result, reference) -end \ No newline at end of file +end + +# TODO: Add several tests fo the mathematical expressions +# One test for each operator. A second test if the operation order matters +# And some more complicated expressions, with some only having variables, some only having parameters and some having both \ No newline at end of file