1
1
# example of a Docker container for CUDA.jl with a specific toolkit embedded at run time.
2
+ #
3
+ # supports selecting a Julia and CUDA toolkit version, as well as baking in specific
4
+ # versions of the CUDA.jl package (identified by a spec recorgnized by the Pkg REPL).
5
+ #
6
+ # CUDA.jl and other packages are shipped in a system depot, with the user depot mounted
7
+ # at `/depot`. persistency is possible by mounting a volume at this location.
8
+ # running with reduced privileges (by using `--user`) is also supported.
2
9
3
- FROM julia:1.8-bullseye
10
+ ARG JULIA_VERSION=1
11
+ FROM julia:${JULIA_VERSION}
12
+
13
+ ARG CUDA_VERSION=12.6
14
+
15
+ ARG PACKAGE_SPEC=CUDA
16
+
17
+ LABEL org.opencontainers.image.authors=
"Tim Besard <[email protected] >" \
18
+ org.opencontainers.image.description="A CUDA.jl container with CUDA ${CUDA_VERSION} and Julia ${JULIA_VERSION}" \
19
+ org.opencontainers.image.title="CUDA.jl" \
20
+ org.opencontainers.image.url="https://juliagpu.org/cuda/" \
21
+ org.opencontainers.image.source="https://github.com/JuliaGPU/CUDA.jl" \
22
+ org.opencontainers.image.licenses="MIT"
4
23
5
24
6
25
# system-wide packages
7
26
27
+ # no trailing ':' as to ensure we don't touch anything outside this directory. without it,
28
+ # Julia touches the compilecache timestamps in its shipped depot (for some reason; a bug?)
8
29
ENV JULIA_DEPOT_PATH=/usr/local/share/julia
9
30
10
- RUN julia -e 'using Pkg; Pkg.add("CUDA")'
31
+ # pre-install the CUDA toolkit from an artifact. we do this separately from CUDA.jl so that
32
+ # this layer can be cached independently. it also avoids double precompilation of CUDA.jl in
33
+ # order to call `CUDA.set_runtime_version!`.
34
+ RUN julia -e '#= configure the preference =# \
35
+ env = "/usr/local/share/julia/environments/v$(VERSION.major).$(VERSION.minor)"; \
36
+ mkpath(env); \
37
+ write("$env/LocalPreferences.toml", \
38
+ "[CUDA_Runtime_jll]\n version = \" ' ${CUDA_VERSION}'\" "); \
39
+ \
40
+ #= install the JLL =# \
41
+ using Pkg; \
42
+ Pkg.add("CUDA_Runtime_jll")' && \
43
+ # = demote the JLL to an [extras] dep =# \
44
+ find /usr/local/share/julia/environments -name Project.toml -exec sed -i 's/deps/extras/' {} + && \
45
+ # = remove nondeterminisms =# \
46
+ cd /usr/local/share/julia && \
47
+ rm -rf compiled registries scratchspaces logs && \
48
+ find -exec touch -h -d "@0" {} + && \
49
+ touch -h -d "@0" /usr/local/share
11
50
12
- # hard-code a CUDA toolkit version
13
- RUN julia -e 'using CUDA; CUDA.set_runtime_version!(v"12.2")'
14
- # re-importing CUDA.jl below will trigger a download of the relevant artifacts
15
-
16
- # generate the device runtime library for all known and supported devices.
17
- # this is to avoid having to do this over and over at run time.
18
- RUN julia -e 'using CUDA; CUDA.precompile_runtime()'
51
+ # install CUDA.jl itself
52
+ RUN julia -e 'using Pkg; pkg"add ' ${PACKAGE_SPEC}'"; \
53
+ using CUDA; CUDA.precompile_runtime()' && \
54
+ # = remove useless stuff =# \
55
+ cd /usr/local/share/julia && \
56
+ rm -rf registries scratchspaces logs
19
57
20
58
21
59
# user environment
@@ -25,6 +63,17 @@ RUN julia -e 'using CUDA; CUDA.precompile_runtime()'
25
63
# case there might not be a (writable) home directory.
26
64
27
65
RUN mkdir -m 0777 /depot
28
- ENV JULIA_DEPOT_PATH=/depot:/usr/local/share/julia
66
+
67
+ # we add the user environment from a start-up script
68
+ # so that the user can mount `/depot` for persistency
69
+ ENV JULIA_DEPOT_PATH=/usr/local/share/julia:
70
+ COPY <<EOF /usr/local/share/julia/config/startup.jl
71
+ if !isdir("/depot/environments/v$(VERSION.major).$(VERSION.minor)" )
72
+ mkpath("/depot/environments" )
73
+ cp("/usr/local/share/julia/environments/v$(VERSION.major).$(VERSION.minor)" ,
74
+ "/depot/environments/v$(VERSION.major).$(VERSION.minor)" )
75
+ end
76
+ pushfirst!(DEPOT_PATH, "/depot" )
77
+ EOF
29
78
30
79
WORKDIR "/workspace"
0 commit comments