Skip to content

Commit

Permalink
Faster alist file creation
Browse files Browse the repository at this point in the history
Use sparse structure for computing node degrees when input parity check matrix is sparse. Also clean up type annotations and update some comments
  • Loading branch information
Adomas Baliuka authored and Adomas Baliuka committed Oct 4, 2023
1 parent c413125 commit e7f7708
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 21 deletions.
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "LDPCStorage"
uuid = "d46d874d-5773-4ce9-8adb-568101dc8882"
authors = ["Adomas Baliuka <[email protected]>"]
version = "0.3.6"
version = "0.4.0"

[deps]
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
Expand All @@ -10,10 +10,12 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"

[compat]
DocStringExtensions = "0.9"
JSON = "0.21"
StatsBase = "0.34"
julia = "1.6"

[extras]
Expand Down
49 changes: 30 additions & 19 deletions src/alist.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using SparseArrays
using LinearAlgebra
using StatsBase: countmap

struct InconsistentAlistFileError <: Exception
msg::Any
Expand Down Expand Up @@ -108,13 +109,16 @@ end
"""
$(SIGNATURES)
Save LDPC matrix to file in alist format. For details about the format, see:
Save LDPC matrix to file in alist format.
It is assumed that the matrix only contains zeros and ones. Otherwise, behavior is undefined.
For details about the Alist format, see:
https://aff3ct.readthedocs.io/en/latest/user/simulation/parameters/codec/ldpc/decoder.html#dec-h-path-image-required-argument
http://www.inference.org.uk/mackay/codes/alist.html
"""
function save_to_alist(out_file_path::String, matrix::AbstractArray{Int8,2})
function save_to_alist(out_file_path::String, matrix::AbstractMatrix{Int8})
open(out_file_path, "w+") do file
print_alist(file, matrix)
end
Expand All @@ -125,18 +129,19 @@ end
"""
$(SIGNATURES)
Save LDPC matrix to file in alist format. For details about the format, see:
Save LDPC matrix to file in alist format.
It is assumed that the matrix only contains zeros and ones. Otherwise, behavior is undefined.
For details about the Alist format, see:
https://aff3ct.readthedocs.io/en/latest/user/simulation/parameters/codec/ldpc/decoder.html#dec-h-path-image-required-argument
http://www.inference.org.uk/mackay/codes/alist.html
"""
function print_alist(io::IO, matrix::AbstractArray{Int8,2})
# TODO more careful testing
function print_alist(io::IO, matrix::AbstractMatrix{Int8})
(the_M, the_N) = size(matrix)

variable_node_degrees = get_variable_node_degrees(matrix)
check_node_degrees = get_check_node_degrees(matrix)
check_node_degrees, variable_node_degrees = get_node_degrees(matrix)

# write data as specified by the alist format
lines = String[]
Expand All @@ -159,11 +164,9 @@ function print_alist(io::IO, matrix::AbstractArray{Int8,2})
# variable node '1'
"""
Get indices of elements equal to one in a matrix.
:param matrix: 2d numpy array
:return: Array of strings, one string with indices for each line in the matrix.
Returns `Vector{String}`, one string with indices for each row of the matrix.
"""
function get_node_indices(matrix::AbstractArray{Int8,2})
# the first check node index is '1' (and not '0')
degrees = [findall(row .== 1) for row in eachrow(matrix)]
return [join(string.(index_list), " ") for index_list in degrees]
end
Expand All @@ -182,16 +185,24 @@ function print_alist(io::IO, matrix::AbstractArray{Int8,2})
return nothing
end



# helper methods for testing the parity check matrix
function get_variable_node_degrees(matrix::AbstractArray{Int8,2})
@assert(length(size(matrix)) == 2, "Matrix required. Wrong number of dimensions")
return [sum(row) for row in eachcol(matrix)]
function get_node_degrees(matrix::AbstractMatrix{Int8})
check_node_degrees = [sum(row) for row in eachrow(matrix)]
variable_node_degrees = [sum(row) for row in eachcol(matrix)]
return check_node_degrees, variable_node_degrees
end

"""Faster version operating on sparse arrays. Assumes all non-zero values are 1!!"""
function get_node_degrees(H_::AbstractSparseMatrix{Int8})
H = dropzeros(H_)

I, J, _ = findnz(H) # assumes all non-zero values are 1!
row_counts = countmap(I)
col_counts = countmap(J)

check_node_degrees = zeros(Int, size(H, 1))
var_node_degrees = zeros(Int, size(H, 2))
check_node_degrees[collect(keys(row_counts))] .= values(row_counts)
var_node_degrees[collect(keys(col_counts))] .= values(col_counts)

function get_check_node_degrees(matrix::AbstractArray{Int8,2})
@assert(length(size(matrix)) == 2, "Matrix required. Wrong number of dimensions")
return [sum(row) for row in eachrow(matrix)]
return check_node_degrees, var_node_degrees
end
3 changes: 2 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ using Test, Aqua
using LDPCStorage

@testset "Aqua (Code quality)" begin
Aqua.test_all(LDPCStorage)
Aqua.test_all(LDPCStorage; ambiguities = false)
Aqua.test_ambiguities([LDPCStorage, Core]) # exclude `Base` in order to not hit unrelated ambiguities from StatsBase.
end

@testset "LDPCStorage" begin
Expand Down

4 comments on commit e7f7708

@adomasbaliuka
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error while trying to register: Register Failed
@adomasbaliuka, it looks like you don't have collaborator status on this repository.

@XQP-Munich
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/92759

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.4.0 -m "<description of version>" e7f7708fa97ab3a1c626b9d747c8e16b8bf50ba3
git push origin v0.4.0

Please sign in to comment.