xref: /libCEED/julia/LibCEED.jl/src/LibCEED.jl (revision 5d1e906964b04cb5161d672bdc4191311737c811)
1module LibCEED
2
3using StaticArrays, UnsafeArrays, Requires, Preferences
4using Base: RefValue
5
6# import low-level C interface
7include("C.jl")
8using .C
9
10export @interior_qf,
11    @witharray,
12    @witharray_read,
13    Abscissa,
14    AbscissaAndWeights,
15    Basis,
16    BasisNone,
17    COPY_VALUES,
18    Ceed,
19    CeedDim,
20    CeedInt,
21    CeedInt8,
22    CeedScalar,
23    CeedSize,
24    CeedVector,
25    CeedVectorActive,
26    CeedVectorNone,
27    Context,
28    CopyMode,
29    EVAL_CURL,
30    EVAL_DIV,
31    EVAL_GRAD,
32    EVAL_INTERP,
33    EVAL_NONE,
34    EVAL_WEIGHT,
35    ElemRestriction,
36    ElemRestrictionNone,
37    EvalMode,
38    GAUSS,
39    GAUSS_LOBATTO,
40    HEX,
41    LINE,
42    MEM_DEVICE,
43    MEM_HOST,
44    MemType,
45    NORM_1,
46    NORM_2,
47    NORM_MAX,
48    NOTRANSPOSE,
49    NormType,
50    OWN_POINTER,
51    Operator,
52    PRISM,
53    PYRAMID,
54    QFunction,
55    QFunctionNone,
56    QUAD,
57    QuadMode,
58    RequestImmediate,
59    RequestOrdered,
60    STRIDES_BACKEND,
61    TET,
62    TRANSPOSE,
63    TRIANGLE,
64    Topology,
65    TransposeMode,
66    USE_POINTER,
67    UserQFunction,
68    add_input!,
69    add_output!,
70    apply!,
71    apply_add!,
72    apply,
73    assemble,
74    assemble_add_diagonal!,
75    assemble_diagonal!,
76    axpy!,
77    ceedversion,
78    create_composite_operator,
79    create_elem_restriction,
80    create_elem_restriction_oriented,
81    create_elem_restriction_curl_oriented,
82    create_elem_restriction_strided,
83    create_evector,
84    create_h1_basis,
85    create_hdiv_basis,
86    create_hcurl_basis,
87    create_identity_qfunction,
88    create_interior_qfunction,
89    create_lvector,
90    create_tensor_h1_basis,
91    create_tensor_h1_lagrange_basis,
92    create_vectors,
93    det,
94    extract_array,
95    extract_context,
96    gauss_quadrature,
97    get_libceed_path,
98    get_preferred_memtype,
99    get_scalar_type,
100    getcompstride,
101    getnumelements,
102    getelementsize,
103    getlvectorsize,
104    getmultiplicity!,
105    getmultiplicity,
106    getdimension,
107    getgrad,
108    getgrad1d,
109    getinterp,
110    getinterp1d,
111    getnumcomponents,
112    getnumnodes,
113    getnumnodes1d,
114    getnumqpts,
115    getnumqpts1d,
116    getqref,
117    getqweights,
118    getresource,
119    gettopology,
120    getvoigt!,
121    getvoigt,
122    iscuda,
123    isdeterministic,
124    isrelease,
125    lobatto_quadrature,
126    norm,
127    pointwisemult!,
128    reciprocal!,
129    scale!,
130    set_context!,
131    set_cufunction!,
132    set_data!,
133    set_field!,
134    set_libceed_path!,
135    setarray!,
136    setvalue!,
137    setvoigt!,
138    setvoigt,
139    syncarray!,
140    takearray!,
141    use_prebuilt_libceed!,
142    witharray,
143    witharray_read
144
145include("Globals.jl")
146include("Ceed.jl")
147include("CeedVector.jl")
148include("Basis.jl")
149include("ElemRestriction.jl")
150include("Quadrature.jl")
151include("Context.jl")
152include("UserQFunction.jl")
153include("QFunction.jl")
154include("Request.jl")
155include("Operator.jl")
156include("Misc.jl")
157
158const minimum_libceed_version = v"0.12.0"
159
160function __init__()
161    if !ceedversion_ge(minimum_libceed_version)
162        @warn("""
163              Incompatible libCEED version.
164              LibCEED.jl requires libCEED version at least $minimum_libceed_version.
165              The version of the libCEED library is $(ceedversion())."
166              """)
167    end
168    configure_scalar_type(C.libceed_handle)
169    @require CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" include("Cuda.jl")
170    set_globals()
171end
172
173"""
174    ceedversion()
175
176Returns a `VersionNumber` corresponding to the version of the libCEED library currently used.
177"""
178function ceedversion()
179    major = Ref{Cint}()
180    minor = Ref{Cint}()
181    patch = Ref{Cint}()
182    release = Ref{Bool}()
183    C.CeedGetVersion(major, minor, patch, release)
184    return VersionNumber(major[], minor[], patch[])
185end
186
187"""
188    isrelease()
189
190Returns true if the libCEED library is a release build, false otherwise.
191"""
192function isrelease()
193    major = Ref{Cint}()
194    minor = Ref{Cint}()
195    patch = Ref{Cint}()
196    release = Ref{Bool}()
197    C.CeedGetVersion(major, minor, patch, release)
198    return release[]
199end
200
201"""
202    ceedversion_ge(version::VersionNumber)
203
204Returns true if the libCEED library is at least as current as the specified `version`. Returns
205`true` whenever libCEED is not a release build.
206"""
207ceedversion_ge(version::VersionNumber) = !isrelease() || (ceedversion() >= version)
208
209"""
210    set_libceed_path!(path::AbstractString)
211    set_libceed_path!(:prebuilt)
212    set_libceed_path!(:default)
213
214Sets the path of the libCEED dynamic library. `path` should be the absolute path to the library
215file.
216
217`set_libceed_path!(:prebuilt)` indicates to LibCEED.jl to use the prebuilt version of the libCEED
218library (bundled with libCEED\\_jll).
219
220`set_libceed_path!(:default)` indicates to LibCEED.jl to use the default library. This usually has
221the same effect as `set_libceed_path!(:prebuilt)`, unless a different path has been specified in the
222depot-wide preferences or using
223[Overrides.toml](https://pkgdocs.julialang.org/dev/artifacts/#Overriding-artifact-locations).
224
225This function sets the library path as a _preference_ associated with the currently active
226environment. Changes will take effect after restarting the Julia session. See the [Preferences.jl
227documentation](https://github.com/JuliaPackaging/Preferences.jl) for more information.
228"""
229function set_libceed_path!(path::AbstractString)
230    handle = C.dlopen(path)
231    set_preferences!(C.libCEED_jll, "libceed_path" => path; force=true)
232    @info("""
233            Setting the libCEED library path to $path.
234            Restart the Julia session for changes to take effect.
235            """)
236    configure_scalar_type(handle)
237    (handle != C.libceed_handle) && C.dlclose(handle)
238    return
239end
240
241function set_libceed_path!(sym::Symbol)
242    if sym == :prebuilt
243        set_preferences!(C.libCEED_jll, "libceed_path" => nothing; force=true)
244        @info("""
245              Using the prebuilt libCEED binary.
246              Restart the Julia session for changes to take effect.
247              """)
248    elseif sym == :default
249        delete_preferences!(Preferences.get_uuid(C.libCEED_jll), "libceed_path"; force=true)
250        @info("""
251              Deleting preference for libCEED library path.
252              Restart the Julia session for changes to take effect.
253              """)
254    else
255        error("set_libceed_path(::Symbol) must be called with :prebuilt or :default.")
256    end
257end
258
259"""
260    use_prebuilt_libceed!()
261
262Indicates that the prebuilt version of the libCEED library (bundled with libCEED\\_jll) should be
263used.
264
265Equivalent to `set_libceed_path!(:prebuilt)`.
266"""
267use_prebuilt_libceed!() = set_libceed_path!(:prebuilt)
268
269"""
270    get_libceed_path()
271
272Returns the path to the currently used libCEED library. A different libCEED library can be used by
273calling [`set_libceed_path!`](@ref) or by using a depot-wide Overrides.toml file.
274"""
275get_libceed_path() = C.libCEED_jll.libceed_path
276
277"""
278    get_scalar_type()
279
280Return the type of `CeedScalar` used by the libCEED library (either `Float32` or `Float64`).
281"""
282get_scalar_type() = get_scalar_type(LibCEED.C.libceed_handle)
283
284function get_scalar_type(handle::Ptr{Nothing})
285    # If CeedGetScalarType is not provided by the libCEED shared library, default for Float64
286    sym = LibCEED.C.dlsym(handle, :CeedGetScalarType; throw_error=false)
287    if sym === nothing
288        return Float64
289    else
290        scalar_type = Ref{C.CeedScalarType}()
291        ccall(sym, Cint, (Ptr{C.CeedScalarType},), scalar_type)
292        if scalar_type[] == C.CEED_SCALAR_FP32
293            return Float32
294        elseif scalar_type[] == C.CEED_SCALAR_FP64
295            return Float64
296        else
297            error("Unknown CeedScalar type $(scalar_type[])")
298        end
299    end
300end
301
302function configure_scalar_type(handle::Ptr{Nothing})
303    scalar_type = get_scalar_type(handle)
304    if scalar_type != CeedScalar
305        @set_preferences!("CeedScalar" => string(scalar_type))
306        @warn("""
307              libCEED is compiled with $scalar_type but LibCEED.jl is using $CeedScalar.
308              Configuring LibCEED.jl to use $scalar_type.
309              The Julia session must be restarted for changes to take effect.
310              """)
311    end
312end
313
314end # module
315