xref: /libCEED/julia/LibCEED.jl/src/Ceed.jl (revision 05a9c2bb2f62eff0bfbb15aec60b0312b25f01c2)
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
40"""
41    ceedversion()
42
43Returns a `VersionNumber` corresponding to the version of the libCEED library currently used.
44"""
45function ceedversion()
46    major = Ref{Cint}()
47    minor = Ref{Cint}()
48    patch = Ref{Cint}()
49    release = Ref{Bool}()
50    C.CeedGetVersion(major, minor, patch, release)
51    return VersionNumber(major[], minor[], patch[])
52end
53
54"""
55    isrelease()
56
57Returns true if the libCEED library is a release build, false otherwise.
58"""
59function isrelease()
60    major = Ref{Cint}()
61    minor = Ref{Cint}()
62    patch = Ref{Cint}()
63    release = Ref{Bool}()
64    C.CeedGetVersion(major, minor, patch, release)
65    return release[]
66end
67
68mutable struct Ceed
69    ref::RefValue{C.Ceed}
70end
71
72"""
73    Ceed(spec="/cpu/self")
74
75Wraps a libCEED `Ceed` object, created with the given resource specification string.
76"""
77function Ceed(spec::AbstractString="/cpu/self")
78    obj = Ceed(Ref{C.Ceed}())
79    C.CeedInit(spec, obj.ref)
80    ehandler = @cfunction(
81        handle_ceed_error,
82        Cint,
83        (C.Ceed, Cstring, Cint, Cstring, Cint, Cstring, Ptr{Cvoid})
84    )
85    C.CeedSetErrorHandler(obj.ref[], ehandler)
86    finalizer(obj) do x
87        # ccall(:jl_safe_printf, Cvoid, (Cstring, Cstring), "Finalizing %s.\n", repr(x))
88        destroy(x)
89    end
90    return obj
91end
92destroy(c::Ceed) = C.CeedDestroy(c.ref) # COV_EXCL_LINE
93Base.getindex(c::Ceed) = c.ref[]
94
95Base.show(io::IO, ::MIME"text/plain", c::Ceed) = ceed_show(io, c, C.CeedView)
96
97"""
98    getresource(c::Ceed)
99
100Returns the resource string associated with the given [`Ceed`](@ref) object.
101"""
102function getresource(c::Ceed)
103    res = Ref{Cstring}()
104    C.CeedGetResource(c[], res)
105    unsafe_string(res[])
106end
107
108"""
109    isdeterministic(c::Ceed)
110
111Returns true if backend of the given [`Ceed`](@ref) object is deterministic, and false
112otherwise.
113"""
114function isdeterministic(c::Ceed)
115    isdet = Ref{Bool}()
116    C.CeedIsDeterministic(c[], isdet)
117    isdet[]
118end
119
120"""
121    get_preferred_memtype(c::Ceed)
122
123Returns the preferred [`MemType`](@ref) (either `MEM_HOST` or `MEM_DEVICE`) of the given
124[`Ceed`](@ref) object.
125"""
126function get_preferred_memtype(c::Ceed)
127    mtype = Ref{MemType}()
128    C.CeedGetPreferredMemType(c[], mtype)
129    mtype[]
130end
131
132"""
133    iscuda(c::Ceed)
134
135Returns true if the given [`Ceed`](@ref) object has resource `"/gpu/cuda/*"` and false
136otherwise.
137"""
138function iscuda(c::Ceed)
139    res_split = split(getresource(c), "/")
140    length(res_split) >= 3 && res_split[3] == "cuda"
141end
142