Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

color conversion causes error on nvidia GPU's

Open
#587 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
48/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
julia

Research direction

Start by running mwe() under Julia 1.12 with CUDA and compare its behavior with ok1() and ok2(). Inspect the Colors conversion path for RGB values backed by N0f8 when broadcasting XYZ over a CuArray; done means mwe() completes without an illegal memory access and subsequent CUDA array access remains usable.

Written by the indexing model from the issue text.

Description

using CUDA
using Colors
using Colors.FixedPointNumbers

function mwe()  # illegal address error (700) on CUDA
    img = [RGB(0,0,0)]
    XYZ.(cu(img))
end

function ok1()  # no issue
    img = [RGB{Float32}(0,0,0)]
    XYZ.(cu(img))
end

function ok2()  # no issue
    dat = zeros(N0f8, 1)
    Float32.(cu(dat))
end

In the above, after executing mwe(), attempting to access any CUDA array will result in the following stacktrace (in this example when julia tries to print the array)

Error showing value of type CuArray{XYZ{Float32}, 1, CUDA.DeviceMemory}:

SYSTEM (REPL): showing an error caused an error
ERROR: 1-element ExceptionStack:
CUDA error: an illegal memory access was encountered (code 700, ERROR_ILLEGAL_ADDRESS)
Stacktrace:
  [1] throw_api_error(res::CUDA.cudaError_enum)
    @ CUDA ~/.julia/packages/CUDA/G7Cnt/lib/cudadrv/libcuda.jl:30
  [2] isdone
    @ ~/.julia/packages/CUDA/G7Cnt/lib/cudadrv/stream.jl:134 [inlined]
  [3] spinning_synchronization(f::typeof(CUDA.isdone), obj::CuStream)
    @ CUDA ~/.julia/packages/CUDA/G7Cnt/lib/cudadrv/synchronization.jl:79
  [4] synchronize(stream::CuStream; blocking::Bool, spin::Bool)
    @ CUDA ~/.julia/packages/CUDA/G7Cnt/lib/cudadrv/synchronization.jl:196
  [5] synchronize
    @ ~/.julia/packages/CUDA/G7Cnt/lib/cudadrv/synchronization.jl:194 [inlined]
  [6] synchronize
    @ ~/.julia/packages/CUDA/G7Cnt/src/memory.jl:527 [inlined]
  [7] synchronize(x::CuArray{XYZ{Float32}, 1, CUDA.DeviceMemory})
    @ CUDA ~/.julia/packages/CUDA/G7Cnt/src/array.jl:493
  [8] #676
    @ ~/.julia/packages/CUDA/G7Cnt/src/array.jl:613 [inlined]
  [9] #context!#546
    @ ~/.julia/packages/CUDA/G7Cnt/lib/cudadrv/state.jl:168 [inlined]
 [10] context!
    @ ~/.julia/packages/CUDA/G7Cnt/lib/cudadrv/state.jl:163 [inlined]
 [11] unsafe_copyto!(dest::Vector{XYZ{Float32}}, doffs::Int64, src::CuArray{XYZ{Float32}, 1, CUDA.DeviceMemory}, soffs::Int64, n::Int64)
    @ CUDA ~/.julia/packages/CUDA/G7Cnt/src/array.jl:608
 [12] copyto!
    @ ~/.julia/packages/CUDA/G7Cnt/src/array.jl:560 [inlined]
 [13] copyto!
    @ ~/.julia/packages/CUDA/G7Cnt/src/array.jl:564 [inlined]
 [14] copyto_axcheck!
    @ ./abstractarray.jl:1176 [inlined]
 [15] Array
    @ ./array.jl:621 [inlined]
 [16] Array
    @ ./boot.jl:674 [inlined]
 [17] convert
    @ ./array.jl:614 [inlined]
 [18] adapt_storage
    @ ~/.julia/packages/GPUArrays/w335n/src/host/abstractarray.jl:137 [inlined]
 [19] adapt_structure
    @ ~/.julia/packages/Adapt/2UZ81/src/Adapt.jl:57 [inlined]
 [20] adapt
    @ ~/.julia/packages/Adapt/2UZ81/src/Adapt.jl:40 [inlined]
 [21] print_array
    @ ~/.julia/packages/GPUArrays/w335n/src/host/abstractarray.jl:140 [inlined]
 [22] show(io::IOContext{REPL.LimitIO{Base.TTY}}, ::MIME{Symbol("text/plain")}, X::CuArray{XYZ{Float32}, 1, CUDA.DeviceMemory})
    @ Base ./arrayshow.jl:399
 [23] show_repl(io::IO, mime::MIME{Symbol("text/plain")}, x::Any)
    @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:548
 [24] show_limited(io::IO, mime::MIME, x::Any)
    @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:517
 [25] (::REPL.var"#display##0#display##1"{REPL.REPLDisplay{REPL.LineEditREPL}, MIME{Symbol("text/plain")}, Base.RefValue{Any}})(io::Any)
    @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:540
 [26] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
    @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:833
 [27] display(d::REPL.REPLDisplay, mime::MIME{Symbol("text/plain")}, x::Any)
    @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:526
 [28] display
    @ ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:546 [inlined]
 [29] display(x::Any)
    @ Base.Multimedia ./multimedia.jl:340
 [30] (::REPL.var"#print_response##2#print_response##3")()
    @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:590
 [31] repl_backend_loop(backend::REPL.REPLBackend, get_module::Function)
    @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:445
 [32] start_repl_backend(backend::REPL.REPLBackend, consumer::Any; get_module::Function)
    @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:427
 [33] start_repl_backend
    @ ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:424 [inlined]
 [34] run_repl(repl::REPL.AbstractREPL, consumer::Any; backend_on_current_task::Bool, backend::Any)
    @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:653
 [35] run_repl(repl::REPL.AbstractREPL, consumer::Any)
    @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:639
 [36] run_std_repl(REPL::Module, quiet::Bool, banner::Symbol, history_file::Bool)
    @ Base ./client.jl:478
 [37] run_main_repl(interactive::Bool, quiet::Bool, banner::Symbol, history_file::Bool)
    @ Base ./client.jl:499
 [38] repl_main
    @ ./client.jl:586 [inlined]
 [39] _start()
    @ Base ./client.jl:561
Stacktrace:
 [1] print_response(errio::IO, response::Any, backend::Union{Nothing, REPL.REPLBackendRef}, show_value::Bool, have_color::Bool, specialdisplay::Union{Nothing, AbstractDisplay})
   @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:599
 [2] (::REPL.var"#print_response##0#print_response##1"{REPL.LineEditREPL, Pair{Any, Bool}, Bool, Bool})(io::Any)
   @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:558
 [3] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
   @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:833
 [4] print_response(repl::REPL.AbstractREPL, response::Any, show_value::Bool, have_color::Bool)
   @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:556
 [5] (::REPL.var"#do_respond#73"{Bool, Bool, REPL.var"#setup_interface##12#setup_interface##13"{REPL.LineEditREPL, REPL.REPLHistoryProvider}, REPL.LineEditREPL, REPL.LineEdit.Prompt})(s::REPL.LineEdit.MIState, buf::Any, ok::Bool)
   @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:1192
 [6] run_interface(terminal::Base.Terminals.TextTerminal, m::REPL.LineEdit.ModalInterface, s::REPL.LineEdit.MIState)
   @ REPL.LineEdit ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/LineEdit.jl:2854
 [7] run_frontend(repl::REPL.LineEditREPL, backend::REPL.REPLBackendRef)
   @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:1663
 [8] (::REPL.var"#61#62"{REPL.LineEditREPL, REPL.REPLBackendRef})()
   @ REPL ~/.julia/juliaup/julia-1.12.0+0.x64.linux.gnu/share/julia/stdlib/v1.12/REPL/src/REPL.jl:650

This is on Julia 1.12.0.

I suspected this may be an issue converting from N0f8 to Float32 but this does not appear to be the case as ok1() and ok2() don't seem to cause any issue. If you asked me yesterday I would have told you yes I have converted colors on GPU before no problem, but now I'm not so sure. I see some pointer and reinterpret shenanigans in the package but those only seem to be for RNG so unrelated. I will probably try to fix this myself (unless somebody comes along and things they have an easy solution), but if I don't or if I fail, here's the issue.

Dominant language
Julia
Stars
225
Forks
53
Avg merge
1d 9h
Merged PRs (30d)
8

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from JuliaGraphics/Colors.jl

All issues in JuliaGraphics/Colors.jl

Similar issues

More Julia issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.