Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allocation at nonexisting line #87

Open
ForceBru opened this issue Oct 20, 2024 · 0 comments
Open

Allocation at nonexisting line #87

ForceBru opened this issue Oct 20, 2024 · 0 comments

Comments

@ForceBru
Copy link

I've just wasted like 2 hours trying to debug some code, only to find that the allocation happens at a line that doesn't exist. Also seems to always be line 139, irrespective of the number of line in my code.

This code has 83 lines:

import Pkg
Pkg.activate(temp=true)
Pkg.add(name="AllocCheck", version="0.2.0")

import Random
using AllocCheck

const AV{T} = AbstractVector{T}

struct Prealloc{T<:Real}
	As::Vector{T}
	Bs::Vector{T}
	Cs::Vector{T}
	qs::Vector{T}
	function Prealloc(As::AV{T}, Bs::AV{T}, Cs::AV{T}, qs::AV{T}) where T<:Real
		@warn "Preallocating" length(As)
		@assert length(As) == length(Bs) == length(Cs) == length(qs)
		new{T}(As, Bs, Cs, qs)
	end
end

Prealloc{T}(K::Integer) where T<:Real =
	Prealloc(zeros(T, K), zeros(T, K), zeros(T, K), zeros(T, K))

Prealloc(K::Integer) = Prealloc{Float64}(K)

@check_allocs function step_mle!(
	ps::AV{T}, ms::AV{T}, ts::AV{T}, data::AV{<:Real},
	l2norm::Bool, lmb::Real, aux::Prealloc{T}
) where T<:Real
	As, Bs, Cs, qs = aux.As, aux.Bs, aux.Cs, aux.qs
	As .= zero(T); Bs .= zero(T); Cs .= zero(T)
	nothing
end

struct Mixture{T<:Real}
	ps::Vector{T}
	ms::Vector{T}
	ts::Vector{T}
	function Mixture(ps::AV{T}, ms::AV{T}, ts::AV{T}) where T<:Real
		@assert length(ps) == length(ms) == length(ts)	
		new{T}(ps, ms, ts)
	end
end

rand_categorical(rng::Random.AbstractRNG, weights::AV)::Integer =
	findfirst(cumsum(weights) .> rand(rng))

Random.rand(
	rng::Random.AbstractRNG, d::Mixture{T}
) where T<:Real = begin
	k = rand_categorical(rng, d.ps);
	randn(rng, T) / d.ts[k] + d.ms[k]
end

function Random.rand(d::Mixture, n::Integer)
	rng = Random.default_rng()
	[rand(rng, d) for _ in 1:n]
end

@check_allocs function fit_basic!(
	mix::Mixture{T}, data::AV{<:Real};
	niter::Integer=300,
	aux::Prealloc{T}
) where T<:Real
	ps, ms, ts = mix.ps, mix.ms, mix.ts
	for ep in 1:niter
		step_mle!(ps, ms, ts, data, true, 0.0, aux) # LINE 68
	end
end

let
	K = 50
	mix0 = Mixture(ones(K) ./ K, randn(K), rand(K))
	data = rand(mix0, 200);
	aux = Prealloc(K)

	try
		fit_basic!(mix0, data; aux, niter=2000)
	catch err
		@show err.errors[1]
	end
end

Running this:

> julia --version
julia version 1.11.1
> julia test.jl
  Activating new project at `/var/folders/61/p7f15sln0gxd7lwbr58cy6f00000gn/T/jl_oQS2Dn`
   Resolving package versions...
    Updating `/private/var/folders/61/p7f15sln0gxd7lwbr58cy6f00000gn/T/jl_oQS2Dn/Project.toml`
  [9b6a8646] + AllocCheck v0.2.0
    Updating `/private/var/folders/61/p7f15sln0gxd7lwbr58cy6f00000gn/T/jl_oQS2Dn/Manifest.toml`
  [9b6a8646] + AllocCheck v0.2.0
...
  [3f19e933] + p7zip_jll v17.4.0+2
        Info Packages marked with ⌅ have new versions available but compatibility constraints restrict them from upgrading. To see why use `status --outdated -m`
┌ Warning: Preallocating
│   length(As) = 50
└ @ Main ~/Desktop/dev/test.jl:16
err.errors[1] = Allocating runtime call to "jl_f_getfield" in ./Base.jl:49
  | getproperty(x, f::Symbol) = (@inline; getfield(x, f))

Stacktrace:
 [1] getproperty
   @ ./Base.jl:49 [inlined]
 [2] step_mle!(ps::Vector{Float64}, ms::Vector{Float64}, ts::Vector{Float64}, data::Vector{Float64}, l2norm::Bool, lmb::Float64, aux::Prealloc{Float64})
   @ Main ~/Desktop/dev/test.jl:139
 [3] var"##fit_basic!#239"(mix::Mixture{Float64}, data::Vector{Float64}, niter::Int64, aux::Prealloc{Float64})
   @ Main ~/Desktop/dev/test.jl:68

> 

It says @ Main ~/Desktop/dev/test.jl:139, but there's no line 139! Same error happens in a longer file that I can't post here, also at line 139, no matter how I reorganize the code, no matter what code happens to be at line 139.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant