master-thesis/package/src/Utils.jl
Daniel effd477558
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
transpiler: generates valid PTX and evaluates expressions correctly
2025-03-28 19:32:48 +01:00

88 lines
2.5 KiB
Julia

module Utils
using CUDA
"Converts a vector of vectors into a matrix. The inner vectors do not need to have the same length.
All entries that cannot be filled have ```invalidElement``` as their value
"
function convert_to_matrix(vecs::Vector{Vector{T}}, invalidElement::T)::Matrix{T} where T
maxLength = get_max_inner_length(vecs)
# Pad the shorter vectors with the invalidElement
paddedVecs = [vcat(vec, fill(invalidElement, maxLength - length(vec))) for vec in vecs]
vecMat = hcat(paddedVecs...)
return vecMat
end
"Retrieves the number of entries for the largest inner vector"
function get_max_inner_length(vecs::Vector{Vector{T}})::Int where T
return maximum(length.(vecs))
end
"Returns a CuArray filed with the data provided. The inner vectors do not have to have the same length. All missing elements will be the value ```invalidElement```"
function create_cuda_array(data::Vector{Vector{T}}, invalidElement::T)::CuArray{T} where T
dataMat = convert_to_matrix(data, invalidElement)
cudaArr = CuArray(dataMat)
return cudaArr
end
struct RegisterManager
registers::Dict
symtable::Dict
end
function get_next_free_register(manager::RegisterManager, name::String)::String
if haskey(manager.registers, name)
manager.registers[name] += 1
else
manager.registers[name] = 1
end
return string("%", name, manager.registers[name] - 1)
end
function get_register_definitions(manager::RegisterManager)::String
registersBuffer = IOBuffer()
for definition in manager.registers
regType = ""
if definition.first == "p"
regType = ".pred"
elseif definition.first == "f"
regType = ".f32"
elseif definition.first == "var"
regType = ".f32"
elseif definition.first == "param"
regType = ".f32"
elseif definition.first == "r"
regType = ".b32"
elseif definition.first == "rd"
regType = ".b64"
elseif definition.first == "parameter"
regType = ".b64"
elseif definition.first == "i"
regType = ".b64"
else
throw(ArgumentError("Unknown register name used. Name '$(definition.first)' cannot be mapped to a PTX type."))
end
println(registersBuffer, ".reg $regType %$(definition.first)<$(definition.second)>;")
end
return String(take!(registersBuffer))
end
"Returns the register for this variable/parameter and true if it is used for the first time and false otherwise."
function get_register_for_name(manager::RegisterManager, varName::String)
if haskey(manager.symtable, varName)
return (manager.symtable[varName], false)
else
reg = get_next_free_register(manager, "var")
manager.symtable[varName] = reg
return (reg, true)
end
end
end