-
Notifications
You must be signed in to change notification settings - Fork 52
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
Add disk cache infrastructure back with tests #351
Changes from all commits
33171a1
da0edc6
939bf4e
639ac30
c585f72
5d2d446
a7a5a71
ca8e8bb
c8b4f9a
c95966f
051e795
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -127,6 +127,43 @@ end | |
true))) | ||
end | ||
|
||
disk_cache() = parse(Bool, @load_preference("disk_cache", "false")) | ||
function cache_key() | ||
major = @load_preference("cache_key", "") | ||
minor = get(ENV, "JULIA_GPUCOMPILER_CACHE", "") | ||
string(major, "-", minor) | ||
end | ||
|
||
""" | ||
enable_cache!(state::Bool=true) | ||
|
||
Activate the GPUCompiler disk cache in the current environment. | ||
You will need to restart your Julia environment for it to take effect. | ||
|
||
!!! warning | ||
The disk cache is not automatically invalidated. It is sharded upon | ||
`cache_key` (see [`set_cache_key``](@ref)), the GPUCompiler version | ||
and your Julia version. | ||
""" | ||
function enable_cache!(state::Bool=true) | ||
@set_preferences!("disk_cache"=>string(state)) | ||
end | ||
|
||
""" | ||
set_cache_key(key) | ||
|
||
If you are deploying an application it is recommended that you use your | ||
application name and version as a cache key. To minimize the risk of | ||
encountering spurious cache hits. | ||
""" | ||
function set_cache_key(key) | ||
@set_preferences!("cache_key"=>key) | ||
end | ||
|
||
key(ver::VersionNumber) = "$(ver.major)_$(ver.minor)_$(ver.patch)" | ||
cache_path() = @get_scratch!(cache_key() * "-kernels-" * key(VERSION)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe include "cache" in the directory name? Or make this a subdirectory of the existing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might also be confusing to have I know we're bikeshedding here :-) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I was trying to add a dependency on the version of GPUCompiler/CUDA. Cache invalidation is a big potential footgun here. |
||
clear_disk_cache!() = rm(cache_path(); recursive=true, force=true) | ||
|
||
const cache_lock = ReentrantLock() | ||
|
||
""" | ||
|
@@ -173,7 +210,18 @@ end | |
job = CompilerJob(src, cfg) | ||
|
||
asm = nothing | ||
# TODO: consider loading the assembly from an on-disk cache here | ||
# can we load from the disk cache? | ||
if disk_cache() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was frustrated by the need to recompile GPUCompiler to turn caching on and off. I originally had it be a compile time preference which is what we would need for it to be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't realize we had non compile-time preferences... |
||
path = joinpath(cache_path(), "$key.jls") | ||
if isfile(path) | ||
try | ||
asm = deserialize(path) | ||
@debug "Loading compiled kernel from $path" ft tt world cfg | ||
catch ex | ||
@warn "Failed to load compiled kernel at $path" exception=(ex, catch_backtrace()) | ||
end | ||
end | ||
end | ||
|
||
# compile | ||
if asm === nothing | ||
|
@@ -182,6 +230,16 @@ end | |
end | ||
|
||
asm = compiler(job) | ||
|
||
if disk_cache() && !isfile(path) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. |
||
tmppath, io = mktemp(;cleanup=false) | ||
# TODO: We should add correctness checks. | ||
# Like size of data, as well as ft, tt, world, cfg | ||
serialize(io, asm) | ||
close(io) | ||
# atomic move | ||
Base.rename(tmppath, path, force=true) | ||
end | ||
end | ||
|
||
# link (but not if we got here because of forced compilation, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[GPUCompiler] | ||
disk_cache = "true" | ||
vchuravy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
cache_key = "test" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[extras] | ||
GPUCompiler = "61eb1bfa-7361-4325-ad38-22787b887f55" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
using GPUCompiler | ||
using Test | ||
|
||
const TOTAL_KERNELS = 1 | ||
|
||
clear = parse(Bool, ARGS[1]) | ||
|
||
@test GPUCompiler.disk_cache() == true | ||
|
||
if clear | ||
GPUCompiler.clear_disk_cache!() | ||
@test length(readdir(GPUCompiler.cache_path())) == 0 | ||
else | ||
@test length(readdir(GPUCompiler.cache_path())) == TOTAL_KERNELS | ||
end | ||
|
||
using LLVM, LLVM.Interop | ||
|
||
include("util.jl") | ||
include("definitions/native.jl") | ||
|
||
kernel() = return | ||
|
||
const runtime_cache = Dict{UInt, Any}() | ||
|
||
function compiler(job) | ||
return GPUCompiler.compile(:asm, job) | ||
end | ||
|
||
function linker(job, asm) | ||
asm | ||
end | ||
|
||
let (job, kwargs) = native_job(kernel, Tuple{}) | ||
source = job.source | ||
config = job.config | ||
GPUCompiler.cached_compilation(runtime_cache, config, source.ft, source.tt, compiler, linker) | ||
end | ||
|
||
@test length(readdir(GPUCompiler.cache_path())) == TOTAL_KERNELS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.