xref: /libCEED/julia/LibCEED.jl/src/Ceed.jl (revision 3f21f6b10abeb5d85d3454ea5cd38498737dc88a)
1struct CeedError <: Exception
2    fname::String
3    lineno::Int
4    func::String
5    ecode::Int
6    message::String
7end
8
9# COV_EXCL_START
10function Base.showerror(io::IO, e::CeedError)
11    println(io, "libCEED error code ", e.ecode, " in ", e.func)
12    println(io, e.fname, ':', e.lineno, '\n')
13    println(io, e.message)
14end
15# COV_EXCL_STOP
16
17function handle_ceed_error(
18    ceed::C.Ceed,
19    c_fname::Cstring,
20    lineno::Cint,
21    c_func::Cstring,
22    ecode::Cint,
23    c_format::Cstring,
24    args::Ptr{Cvoid},
25)
26    c_message = ccall(
27        (:CeedErrorFormat, C.libceed),
28        Cstring,
29        (C.Ceed, Cstring, Ptr{Cvoid}),
30        ceed,
31        c_format,
32        args,
33    )
34    fname = unsafe_string(c_fname)
35    func = unsafe_string(c_func)
36    message = unsafe_string(c_message)
37    throw(CeedError(fname, lineno, func, ecode, message))
38end
39
40mutable struct Ceed
41    ref::RefValue{C.Ceed}
42end
43
44"""
45    Ceed(spec="/cpu/self")
46
47Wraps a libCEED `Ceed` object, created with the given resource specification string.
48"""
49function Ceed(spec::AbstractString="/cpu/self")
50    obj = Ceed(Ref{C.Ceed}())
51    C.CeedInit(spec, obj.ref)
52    ehandler = @cfunction(
53        handle_ceed_error,
54        Cint,
55        (C.Ceed, Cstring, Cint, Cstring, Cint, Cstring, Ptr{Cvoid})
56    )
57    C.CeedSetErrorHandler(obj.ref[], ehandler)
58    finalizer(obj) do x
59        # ccall(:jl_safe_printf, Cvoid, (Cstring, Cstring), "Finalizing %s.\n", repr(x))
60        destroy(x)
61    end
62    return obj
63end
64destroy(c::Ceed) = C.CeedDestroy(c.ref) # COV_EXCL_LINE
65Base.getindex(c::Ceed) = c.ref[]
66
67Base.show(io::IO, ::MIME"text/plain", c::Ceed) = ceed_show(io, c, C.CeedView)
68
69"""
70    getresource(c::Ceed)
71
72Returns the resource string associated with the given [`Ceed`](@ref) object.
73"""
74function getresource(c::Ceed)
75    res = Ref{Ptr{Cchar}}()
76    C.CeedGetResource(c[], res)
77    unsafe_string(Cstring(res[]))
78end
79
80"""
81    isdeterministic(c::Ceed)
82
83Returns true if backend of the given [`Ceed`](@ref) object is deterministic, and false
84otherwise.
85"""
86function isdeterministic(c::Ceed)
87    isdet = Ref{Bool}()
88    C.CeedIsDeterministic(c[], isdet)
89    isdet[]
90end
91
92"""
93    get_preferred_memtype(c::Ceed)
94
95Returns the preferred [`MemType`](@ref) (either `MEM_HOST` or `MEM_DEVICE`) of the given
96[`Ceed`](@ref) object.
97"""
98function get_preferred_memtype(c::Ceed)
99    mtype = Ref{MemType}()
100    C.CeedGetPreferredMemType(c[], mtype)
101    mtype[]
102end
103
104"""
105    iscuda(c::Ceed)
106
107Returns true if the given [`Ceed`](@ref) object has resource `"/gpu/cuda/*"` and false
108otherwise.
109"""
110function iscuda(c::Ceed)
111    res_split = split(getresource(c), "/")
112    length(res_split) >= 3 && res_split[3] == "cuda"
113end
114