As mentioned, I want to get GPU support for a custom layer. Here is the build-net part of my code:
# MyDense
struct MyDense
d1
d2
end
MyDense(p::Pair) = MyDense(Dense(p), Dense(p))
(m::MyDense)(x) = m.d1(x) + m.d2(x)
# multiple-dispatch for gpu function on the custom layer
Flux.gpu(layer::MyDense) = MyDense(Flux.gpu(layer.d1), Flux.gpu(layer.d2))
# Define our model, a multi-layer perceptron with one hidden layer of size 3:
model = Chain(
Dense(2 => 3, tanh), # activation function inside layer
BatchNorm(3),
MyDense(3 => 2),
softmax) |> gpu # move model to GPU, if available
Reminded by #eliassno's answer in this question, I wrote a new dispatch of Flux.gpu function for my custom layer. However, it still didn't work and gave me the error:
ERROR: ArgumentError: cannot take the CPU address of a CUDA.CuArray{Float32, 2, CUDA.Mem.DeviceBuffer}
Stacktrace:
[1] unsafe_convert(#unused#::Type{Ptr{Float32}}, x::CUDA.CuArray{Float32, 2, CUDA.Mem.DeviceBuffer})
# CUDA C:\Users\Herr LU\.julia\packages\CUDA\DfvRa\src\array.jl:319
[2] gemm!(transA::Char, transB::Char, alpha::Float32, A::Matrix{Float32}, B::CUDA.CuArray{Float32, 2, CUDA.Mem.DeviceBuffer}, beta::Float32, C::CUDA.CuArray{Float32, 2, CUDA.Mem.DeviceBuffer})
# LinearAlgebra.BLAS C:\Users\Herr LU\AppData\Local\Programs\Julia-1.8.2\share\julia\stdlib\v1.8\LinearAlgebra\src\blas.jl:1514
[3] gemm_wrapper!(C::CUDA.CuArray{Float32, 2, CUDA.Mem.DeviceBuffer}, tA::Char, tB::Char, A::Matrix{Float32}, B::CUDA.CuArray{Float32, 2, CUDA.Mem.DeviceBuffer}, _add::LinearAlgebra.MulAddMul{true, true, Bool, Bool})
# LinearAlgebra C:\Users\Herr LU\AppData\Local\Programs\Julia-1.8.2\share\julia\stdlib\v1.8\LinearAlgebra\src\matmul.jl:674
[4] mul!
# C:\Users\Herr LU\AppData\Local\Programs\Julia-1.8.2\share\julia\stdlib\v1.8\LinearAlgebra\src\matmul.jl:161 [inlined]
[5] mul!
# C:\Users\Herr LU\AppData\Local\Programs\Julia-1.8.2\share\julia\stdlib\v1.8\LinearAlgebra\src\matmul.jl:276 [inlined]
[6] *
# C:\Users\Herr LU\AppData\Local\Programs\Julia-1.8.2\share\julia\stdlib\v1.8\LinearAlgebra\src\matmul.jl:148 [inlined]
[7] (::Dense{typeof(identity), Matrix{Float32}, Vector{Float32}})(x::CUDA.CuArray{Float32, 2, CUDA.Mem.DeviceBuffer})
# Flux C:\Users\Herr LU\.julia\packages\Flux\ZdbJr\src\layers\basic.jl:172
[8] (::MyDense)(x::CUDA.CuArray{Float32, 2, CUDA.Mem.DeviceBuffer})
# Main e:\Master Thesis\lu_jizhou\Learning\FluxTrial.jl:14
[9] macro expansion
# C:\Users\Herr LU\.julia\packages\Flux\ZdbJr\src\layers\basic.jl:53 [inlined]
[10] _applychain(layers::Tuple{Dense{typeof(tanh), CUDA.CuArray{Float32, 2, CUDA.Mem.DeviceBuffer}, CUDA.CuArray{Float32, 1, CUDA.Mem.DeviceBuffer}}, BatchNorm{typeof(identity), CUDA.CuArray{Float32, 1, CUDA.Mem.DeviceBuffer}, Float32, CUDA.CuArray{Float32, 1, CUDA.Mem.DeviceBuffer}}, MyDense, typeof(softmax)}, x::CUDA.CuArray{Float32, 2, CUDA.Mem.DeviceBuffer})
# Flux C:\Users\Herr LU\.julia\packages\Flux\ZdbJr\src\layers\basic.jl:53
[11] (::Chain{Tuple{Dense{typeof(tanh), CUDA.CuArray{Float32, 2, CUDA.Mem.DeviceBuffer}, CUDA.CuArray{Float32, 1, CUDA.Mem.DeviceBuffer}}, BatchNorm{typeof(identity), CUDA.CuArray{Float32, 1, CUDA.Mem.DeviceBuffer}, Float32, CUDA.CuArray{Float32, 1, CUDA.Mem.DeviceBuffer}}, MyDense, typeof(softmax)}})(x::CUDA.CuArray{Float32, 2, CUDA.Mem.DeviceBuffer})
# Flux C:\Users\Herr LU\.julia\packages\Flux\ZdbJr\src\layers\basic.jl:51
[12] top-level scope
# e:\Master Thesis\lu_jizhou\Learning\FluxTrial.jl:25
How can I solve the issue?
Related
After I excute Pkg.precompile(), the REPL return the information like following:
julia> using Pkg
julia> Pkg.precompile()
Precompiling project...
✗ GR
✗ Plots
0 dependencies successfully precompiled in 40 seconds (130 already precompiled)
ERROR: The following 1 direct dependency failed to precompile:
Plots [91a5bcdd-55d7-5caf-9e0b-520d859cae80]
Failed to precompile Plots [91a5bcdd-55d7-5caf-9e0b-520d859cae80] to C:\Users\Administrator\.julia\compiled\v1.6\Plots\jl_DB20.tmp.
ERROR: LoadError: ArgumentError: not a path: \`C:\Users\Administrator\.julia\packages\GR\xhzFJ\deps\deps.jl\`
ERROR: LoadError: ArgumentError: not a path: `C:\Users\Administrator\.julia\packages\GR\xhzFJ\deps\deps.jl`
Stacktrace:
[1] RelocatableFolders.Path(mod::Module, dir::String, path::String)
# RelocatableFolders C:\Users\Administrator\.julia\packages\RelocatableFolders\PYUl8\src\RelocatableFolders.jl:51
[2] top-level scope
# C:\Users\Administrator\.julia\packages\GR\xhzFJ\src\GR.jl:36
[3] include
# .\Base.jl:384 [inlined]
[4] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt64}}, source::String)
# Base .\loading.jl:1235
[5] top-level scope
# none:1
[6] eval
# .\boot.jl:360 [inlined]
[7] eval(x::Expr)
# Base.MainInclude .\client.jl:446
[8] top-level scope
# none:1
in expression starting at C:\Users\Administrator\.julia\packages\GR\xhzFJ\src\GR.jl:2
ERROR: LoadError: LoadError: Failed to precompile GR [28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71] to C:\Users\Administrator\.julia\compiled\v1.6\GR\jl_B11E.tmp.
Stacktrace:
[1] error(s::String)
# Base .\error.jl:33
[2] compilecache(pkg::Base.PkgId, path::String, internal_stderr::IOContext{Base.PipeEndpoint}, internal_stdout::IOContext{IOStream}, ignore_loaded_modules::Bool)
# Base .\loading.jl:1385
[3] compilecache(pkg::Base.PkgId, path::String)
# Base .\loading.jl:1329
[4] _require(pkg::Base.PkgId)
# Base .\loading.jl:1043
[5] require(uuidkey::Base.PkgId)
# Base .\loading.jl:936
[6] require(into::Module, mod::Symbol)
# Base .\loading.jl:923
[7] include(mod::Module, _path::String)
# Base .\Base.jl:384
[8] include(x::String)
# Plots C:\Users\Administrator\.julia\packages\Plots\E2187\src\Plots.jl:1
[9] top-level scope
# C:\Users\Administrator\.julia\packages\Plots\E2187\src\Plots.jl:227
[10] include
# .\Base.jl:384 [inlined]
[11] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt64}}, source::Nothing)
# Base .\loading.jl:1235
[12] top-level scope
# none:1
[13] eval
# .\boot.jl:360 [inlined]
[14] eval(x::Expr)
# Base.MainInclude .\client.jl:446
[15] top-level scope
# none:1
in expression starting at C:\Users\Administrator\.julia\packages\Plots\E2187\src\backends\gr.jl:6
in expression starting at C:\Users\Administrator\.julia\packages\Plots\E2187\src\Plots.jl:1
Stacktrace:
[1] pkgerror(msg::String)
# Pkg.Types C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\Pkg\src\Types.jl:55
[2] precompile(ctx::Pkg.Types.Context; internal_call::Bool, strict::Bool, warn_loaded::Bool, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
# Pkg.API C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\Pkg\src\API.jl:1265
[3] precompile
# C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\Pkg\src\API.jl:921 [inlined]
[4] #precompile#196
# C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\Pkg\src\API.jl:919 [inlined]
[5] precompile()
# Pkg.API C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\Pkg\src\API.jl:919
[6] top-level scope
# REPL[2]:1
Please help me!
More details:
Microsoft Windows [10.0.17763.2803]
Julia Version 1.6.6 (2022-03-28). Julia is installed by the installer downloaded from https://julialang.org/downloads/
I am a postgraduate majoring in physics. I am interested in computing and programming. From my classmates the julia lang is a programming language facing futrue because of its advanced programming philosophy. However, what I did not expect is that I meet the problem I can not resolve so soon. (This paragraph is for the prompt "Most is code, please add more details")
I do not even know what have happened till now. However I find the solution for my question and I have succeed in resolving it. Having excute Pkg.add("Plots"), just excute the following codes:
using Pkg
Pkg.add("GR")
Pkg.build("GR")
Pkg.precompile()
The answer is from here
I am encountering an error on Julia while trying to install and use Distributions module. I am not facing any errors while installing the module but it displays this error when I try to use the Distributions module. I have no idea what this PDMats or Manifest files are. I'd love to have some advice. Thanks!
This is the entire error:
julia> using Distributions
│ Package Distributions not found, but a package named Distributions is available from a registry.
│ Install package?
│ (#v1.7) pkg> add Distributions
└ (y/n) [y]: y
Updating registry at `C:\Users\rajaissacsamuel.k\.julia\registries\General.toml`
Resolving package versions...
Updating `C:\Users\rajaissacsamuel.k\.julia\environments\v1.7\Project.toml`
[31c24e10] + Distributions v0.21.12
No Changes to `C:\Users\rajaissacsamuel.k\.julia\environments\v1.7\Manifest.toml`
[ Info: Precompiling Distributions [31c24e10-a181-5473-b8eb-7969acd0382f]
ERROR: LoadError: ArgumentError: Package PDMats does not have IterativeEigensolvers in its dependencies:
- If you have PDMats checked out for development and have
added IterativeEigensolvers as a dependency but haven't updated your primary
environment's manifest file, try `Pkg.resolve()`.
- Otherwise you may need to report an issue with PDMats
Stacktrace:
[1] require(into::Module, mod::Symbol)
# Base .\loading.jl:980
[2] include
# .\Base.jl:418 [inlined]
[3] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt64}}, source::String)
# Base .\loading.jl:1318
[4] top-level scope
# none:1
[5] eval
# .\boot.jl:373 [inlined]
[6] eval(x::Expr)
# Base.MainInclude .\client.jl:453
[7] top-level scope
# none:1
in expression starting at C:\Users\rajaissacsamuel.k\.julia\packages\PDMats\jTYWO\src\PDMats.jl:3
ERROR: LoadError: Failed to precompile PDMats [90014a1f-27ba-587c-ab20-58faa44d9150] to C:\Users\rajaissacsamuel.k\.julia\compiled\v1.7\PDMats\jl_565F.tmp.
Stacktrace:
[1] error(s::String)
# Base .\error.jl:33
[2] compilecache(pkg::Base.PkgId, path::String, internal_stderr::IO, internal_stdout::IO, ignore_loaded_modules::Bool)
# Base .\loading.jl:1466
[3] compilecache(pkg::Base.PkgId, path::String)
# Base .\loading.jl:1410
[4] _require(pkg::Base.PkgId)
# Base .\loading.jl:1120
[5] require(uuidkey::Base.PkgId)
# Base .\loading.jl:1013
[6] require(into::Module, mod::Symbol)
# Base .\loading.jl:997
[7] include
# .\Base.jl:418 [inlined]
[8] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt64}}, source::Nothing)
# Base .\loading.jl:1318
[9] top-level scope
# none:1
[10] eval
# .\boot.jl:373 [inlined]
[11] eval(x::Expr)
# Base.MainInclude .\client.jl:453
[12] top-level scope
# none:1
in expression starting at C:\Users\rajaissacsamuel.k\.julia\packages\Distributions\KjaXI\src\Distributions.jl:1
ERROR: Failed to precompile Distributions [31c24e10-a181-5473-b8eb-7969acd0382f] to C:\Users\rajaissacsamuel.k\.julia\compiled\v1.7\Distributions\jl_52F6.tmp.
Stacktrace:
[1] error(s::String)
# Base .\error.jl:33
[2] compilecache(pkg::Base.PkgId, path::String, internal_stderr::IO, internal_stdout::IO, ignore_loaded_modules::Bool)
# Base .\loading.jl:1466
[3] compilecache(pkg::Base.PkgId, path::String)
# Base .\loading.jl:1410
[4] _require(pkg::Base.PkgId)
# Base .\loading.jl:1120
[5] require(uuidkey::Base.PkgId)
# Base .\loading.jl:1013
[6] require(into::Module, mod::Symbol)
# Base .\loading.jl:997
[7] eval
# .\boot.jl:373 [inlined]
[8] eval
# .\Base.jl:68 [inlined]
[9] repleval(m::Module, code::Expr, #unused#::String)
# VSCodeServer c:\Users\rajaissacsamuel.k\.vscode\extensions\julialang.language-julia-1.6.17\scripts\packages\VSCodeServer\src\repl.jl:157
[10] (::VSCodeServer.var"#78#80"{Module, Expr, REPL.LineEditREPL, REPL.LineEdit.Prompt})()
# VSCodeServer c:\Users\rajaissacsamuel.k\.vscode\extensions\julialang.language-julia-1.6.17\scripts\packages\VSCodeServer\src\repl.jl:123
[11] with_logstate(f::Function, logstate::Any)
# Base.CoreLogging .\logging.jl:511
[12] with_logger
# .\logging.jl:623 [inlined]
[13] (::VSCodeServer.var"#77#79"{Module, Expr, REPL.LineEditREPL, REPL.LineEdit.Prompt})()
# VSCodeServer c:\Users\rajaissacsamuel.k\.vscode\extensions\julialang.language-julia-1.6.17\scripts\packages\VSCodeServer\src\repl.jl:124
[14] #invokelatest#2
# .\essentials.jl:716 [inlined]
[15] invokelatest(::Any)
# Base .\essentials.jl:714
[16] macro expansion
# c:\Users\rajaissacsamuel.k\.vscode\extensions\julialang.language-julia-1.6.17\scripts\packages\VSCodeServer\src\eval.jl:34 [inlined]
[17] (::VSCodeServer.var"#60#61")()
# VSCodeServer .\task.jl:423
try Pkg.resolve() or Pkg.update(), if that fails try resetting the Julia registry
I want to install Julia in my jupyter notebook. I am getting this. I am not able to find what means the reference to 'no active Project'. Any help will be very welcomed. Thanks
julia> using Pkg
julia> Pkg.add("IJulia")
ERROR: no active project
Stacktrace:
[1] pkgerror(msg::String)
# Pkg.Types C:\Users\madel\Julia-1.7.2\share\julia\stdlib\v1.7\Pkg\src\Types.jl:68
[2] find_project_file(env::Nothing)
# Pkg.Types C:\Users\madel\Julia-1.7.2\share\julia\stdlib\v1.7\Pkg\src\Types.jl:200
[3] Pkg.Types.EnvCache(env::Nothing) (repeats 2 times)
# Pkg.Types C:\Users\madel\Julia-1.7.2\share\julia\stdlib\v1.7\Pkg\src\Types.jl:319
[4] Pkg.Types.Context()
# Pkg.Types .\util.jl:478
[5] add(pkgs::Vector{Pkg.Types.PackageSpec}; io::Base.TTY, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
# Pkg.API C:\Users\madel\Julia-1.7.2\share\julia\stdlib\v1.7\Pkg\src\API.jl:145
[6] add(pkgs::Vector{Pkg.Types.PackageSpec})
# Pkg.API C:\Users\madel\Julia-1.7.2\share\julia\stdlib\v1.7\Pkg\src\API.jl:144
[7] #add#27
# C:\Users\madel\Julia-1.7.2\share\julia\stdlib\v1.7\Pkg\src\API.jl:142 [inlined]
[8] add
# C:\Users\madel\Julia-1.7.2\share\julia\stdlib\v1.7\Pkg\src\API.jl:142 [inlined]
[9] #add#26
# C:\Users\madel\Julia-1.7.2\share\julia\stdlib\v1.7\Pkg\src\API.jl:141 [inlined]
[10] add(pkg::String)
# Pkg.API C:\Users\madel\Julia-1.7.2\share\julia\stdlib\v1.7\Pkg\src\API.jl:141
[11] top-level scope
# REPL[36]:1
julia>
I tried to add a new environment user path as JULIA_HOME to the following route:
C:\Users\madel\Julia-1.7.2\bin and works now. It seems like I was not pointing the right path.
I'm trying to create a POMDP model and solve it. But during the solving process, I get this error:
Got exception outside of a #test
UndefRefError: access to undefined reference
Stacktrace:
[1] getindex
# ./array.jl:801 [inlined]
[2] iterate
# ./array.jl:777 [inlined]
[3] iterate
# ./iterators.jl:159 [inlined]
[4] write(io::IOStream, pomdp::AccPOMDP)
# POMDPFiles ~/.julia/packages/POMDPFiles/vOfxh/src/write.jl:64
[5] #3
# ~/.julia/packages/POMDPSolve/LzAMF/src/solver.jl:175 [inlined]
[6] open(::POMDPSolve.var"#3#4"{AccPOMDP}, ::String, ::Vararg{String, N} where N; kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
# Base ./io.jl:330
[7] open
# ./io.jl:328 [inlined]
[8] solve(solver::POMDPSolveSolver, pomdp::AccPOMDP)
# POMDPSolve ~/.julia/packages/POMDPSolve/LzAMF/src/solver.jl:174
[9] macro expansion
# ~/jl/acc/acc_dev.jl:556 [inlined]
[10] macro expansion
# /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/Test/src/Test.jl:1151 [inlined]
[11] top-level scope
# ~/jl/acc/acc_dev.jl:546
[12] include(mod::Module, _path::String)
# Base ./Base.jl:386
[13] exec_options(opts::Base.JLOptions)
# Base ./client.jl:285
[14] _start()
# Base ./client.jl:485
I'm not so familiar with the Julia Stacktrace, so could you please help me fix this problem?
Caused by stateindex(...) and states(...) wrong implementation in my POMDP model. But after I fix this ans start to solve the problem, the solving just kept run and finally failed. Just want to complain, Julia POMDP is really hard to use in reality...
split is an especially important function in R core. Many Stack Overflow answers offering R-base solutions on data manipulation rely on it. It is the workhorse routine of any group-by operations.
There are also many questions whose solution is just a single line with split. Many people do not know that
split.data.frame can split a matrix by row;
split.default can split a data frame by column.
Perhaps R documentation on split is not doing very well. It does mention the first use, but does not mention the second.
There are four methods for split in R core:
methods(split)
#[1] split.data.frame split.Date split.default split.POSIXct
I will provide an answer explaining in depth how split.data.frame, split.default and the C-level .Internal(split(x, f)) work. Other answers are welcomed on "Date" and "POSIXct" object.
How does split.data.frame work?
function (x, f, drop = FALSE, ...)
lapply(split(x = seq_len(nrow(x)), f = f, drop = drop, ...),
function(ind) x[ind, , drop = FALSE])
It calls split.default to split row index vector seq_len(nrow(x)), then use an lapply loop to extract associated rows into a list entry.
This isn't strictly a "data.frame" method. It splits any 2-dimensional objects by the 1st dimension, including splitting a matrix by rows.
How does split.default work?
function (x, f, drop = FALSE, sep = ".", lex.order = FALSE, ...)
{
if (!missing(...))
.NotYetUsed(deparse(...), error = FALSE)
if (is.list(f))
f <- interaction(f, drop = drop, sep = sep, lex.order = lex.order)
else if (!is.factor(f))
f <- as.factor(f)
else if (drop)
f <- factor(f)
storage.mode(f) <- "integer"
if (is.null(attr(x, "class")))
return(.Internal(split(x, f)))
lf <- levels(f)
y <- vector("list", length(lf))
names(y) <- lf
ind <- .Internal(split(seq_along(x), f))
for (k in lf) y[[k]] <- x[ind[[k]]]
y
}
if x has no classes (i.e., mostly an atomic vector), .Internal(split(x, f)) is used;
otherwise, it uses .Internal(split()) to split the index along x, then uses a for loop to extract associated elements into a list entry.
An atomic vector (see ?vector) is a vector with the following mode:
"logical", "integer", "numeric", "complex", "character" and "raw"
"list"
"expression"
An object with class... Er... there are so many!! Let me just give three examples:
"factor"
"data.frame"
"matrix"
In my opinion the split.default is not well written. There are so many objects with classes, yet split.default would deal with them in the same way via"[". This works fine with "factor" and "data.frame" (so we will be splitting data frame along the columns!), but it definitely does not work with a matrix in a way we expect.
A <- matrix(1:9, 3)
# [,1] [,2] [,3]
#[1,] 1 4 7
#[2,] 2 5 8
#[3,] 3 6 9
split.default(A, c(1, 1, 2)) ## it does not split the matrix by columns!
#$`1`
#[1] 1 2 4 5 7 8
#
#$`2`
#[1] 3 6 9
Actually recycling rule has been applied to c(1, 1, 2), and we are equivalently doing:
split(c(A), rep_len(c(1,1,2), length(A)))
Why doesn't R core write another line for a "matrix", like
for (k in lf) y[[k]] <- x[, ind[[k]], drop = FALSE]
Till now the only way to safely split a matrix by columns is to transpose it, then split.data.frame, then another transpose.
lapply(split.data.frame(t(A), c(1, 1, 2)), t)
Another workaround via lapply(split.default(data.frame(A), c(1, 1, 2)), as.matrix) is buggy if A is a character matrix.
How does .Internal(split(x, f)) work?
This is really the core of the core! I will take a small example below for explanation:
set.seed(0)
f <- sample(factor(letters[1:3]), 10, TRUE)
# [1] c a b b c a c c b b
#Levels: a b c
x <- 0:9
Basically there are 3 steps. To enhance readability, Equivalent R code are provided for each step.
step 1: tabulation (counting occurrence of each factor level)
## a factor has integer mode so `tabulate` works
tab <- tabulate(f, nbins = nlevels(f))
[1] 2 4 4
step 2: storage allocation of the resulting list
result <- vector("list", nlevels(f))
for (i in 1:length(tab)) result[[i]] <- vector(mode(x), tab[i])
names(result) <- levels(f)
I would annotate this list as follows, where each line is a list element which is a vector in this example, and each [ ] is a placeholder for an entry of that vector.
$a: [ ] [ ]
$b: [ ] [ ] [ ] [ ]
$c: [ ] [ ] [ ] [ ]
step 3: element allocation
Now it is useful to uncover the internal integer mode for a factor:
.f <- as.integer(f)
#[1] 3 1 2 2 3 1 3 3 2 2
We need to scan x and .f, filling x[i] into the right entry of result[[.f[i]]], informed by an accumulator buffer vector.
ab <- integer(nlevels(f)) ## accumulator buffer
for (i in 1:length(.f)) {
fi <- .f[i]
counter <- ab[fi] + 1L
result[[fi]][counter] <- x[i]
ab[fi] <- counter
}
In the following illustration, ^ is a pointer to elements that are accessed or updated.
## i = 1
x: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
.f: [3] [1] [2] [2] [3] [1] [3] [3] [2] [2]
^
ab: [0] [0] [0] ## on entry
^
$a: [ ] [ ]
$b: [ ] [ ] [ ] [ ]
$c: [0] [ ] [ ] [ ]
^
ab: [0] [0] [1] ## on exit
^
## i = 2
x: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
.f: [3] [1] [2] [2] [3] [1] [3] [3] [2] [2]
^
ab: [0] [0] [1] ## on entry
^
$a: [1] [ ]
^
$b: [ ] [ ] [ ] [ ]
$c: [0] [ ] [ ] [ ]
ab: [1] [0] [1] ## on exit
^
## i = 3
x: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
.f: [3] [1] [2] [2] [3] [1] [3] [3] [2] [2]
^
ab: [1] [0] [1] ## on entry
^
$a: [1] [ ]
$b: [2] [ ] [ ] [ ]
^
$c: [0] [ ] [ ] [ ]
ab: [1] [1] [1] ## on exit
^
## i = 4
x: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
.f: [3] [1] [2] [2] [3] [1] [3] [3] [2] [2]
^
ab: [1] [1] [1] ## on entry
^
$a: [1] [ ]
$b: [2] [3] [ ] [ ]
^
$c: [0] [ ] [ ] [ ]
ab: [1] [2] [1] ## on exit
^
## i = 5
x: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
.f: [3] [1] [2] [2] [3] [1] [3] [3] [2] [2]
^
ab: [1] [2] [1] ## on entry
^
$a: [1] [ ]
$b: [2] [3] [ ] [ ]
$c: [0] [4] [ ] [ ]
^
ab: [1] [2] [2] ## on exit
^
## i = 6
x: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
.f: [3] [1] [2] [2] [3] [1] [3] [3] [2] [2]
^
ab: [1] [2] [2] ## on entry
^
$a: [1] [5]
^
$b: [2] [3] [ ] [ ]
$c: [0] [4] [ ] [ ]
ab: [2] [2] [2] ## on exit
^
## i = 7
x: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
.f: [3] [1] [2] [2] [3] [1] [3] [3] [2] [2]
^
ab: [2] [2] [2] ## on entry
^
$a: [1] [5]
$b: [2] [3] [ ] [ ]
$c: [0] [4] [6] [ ]
^
ab: [2] [2] [3] ## on exit
^
## i = 8
x: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
.f: [3] [1] [2] [2] [3] [1] [3] [3] [2] [2]
^
ab: [2] [2] [3] ## on entry
^
$a: [1] [5]
$b: [2] [3] [ ] [ ]
$c: [0] [4] [6] [7]
^
ab: [2] [2] [4] ## on exit
^
## i = 9
x: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
.f: [3] [1] [2] [2] [3] [1] [3] [3] [2] [2]
^
ab: [2] [2] [4] ## on entry
^
$a: [1] [5]
$b: [2] [3] [8] [ ]
^
$c: [0] [4] [6] [7]
ab: [2] [3] [4] ## on exit
^
## i = 10
x: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
.f: [3] [1] [2] [2] [3] [1] [3] [3] [2] [2]
^
ab: [2] [3] [4] ## on entry
^
$a: [1] [5]
$b: [2] [3] [8] [9]
^
$c: [0] [4] [6] [7]
ab: [2] [4] [4] ## on exit
^