diff --git a/deps/build_local.jl b/deps/build_local.jl index f2d620e0..80e67f51 100644 --- a/deps/build_local.jl +++ b/deps/build_local.jl @@ -62,7 +62,7 @@ if !isfile(joinpath(conda_dir, "condarc-julia.yml")) touch(joinpath(conda_dir, "conda-meta", "history")) end Conda.add_channel("https://software.repos.intel.com/python/conda/", conda_dir) -Conda.add(["dpcpp_linux-64=2025.2.0", "mkl-devel-dpcpp=2025.2.0"], conda_dir) +Conda.add(["dpcpp_linux-64=2026.0.0", "mkl-devel-dpcpp=2026.0.0"], conda_dir) Conda.list(conda_dir) diff --git a/deps/src/onemkl.h b/deps/src/onemkl.h index 0029fb2e..1f850bf2 100644 --- a/deps/src/onemkl.h +++ b/deps/src/onemkl.h @@ -140,8 +140,8 @@ typedef struct omatconvert_descr *omatconvert_descr_t; struct omatadd_descr; typedef struct omatadd_descr *omatadd_descr_t; -const int64_t ONEMKL_VERSION_MAJOR = 2025; -const int64_t ONEMKL_VERSION_MINOR = 2; +const int64_t ONEMKL_VERSION_MAJOR = 2026; +const int64_t ONEMKL_VERSION_MINOR = 0; const int64_t ONEMKL_VERSION_PATCH = 0; void onemkl_version(int64_t *major, int64_t *minor, int64_t *patch); diff --git a/deps/src/onemkl_dft.cpp b/deps/src/onemkl_dft.cpp index 8c10ffb7..9f39c127 100644 --- a/deps/src/onemkl_dft.cpp +++ b/deps/src/onemkl_dft.cpp @@ -116,8 +116,10 @@ static inline config_param to_param(onemklDftConfigParam p) { case ONEMKL_DFT_PARAM_NUMBER_OF_TRANSFORMS: return config_param::NUMBER_OF_TRANSFORMS; case ONEMKL_DFT_PARAM_COMPLEX_STORAGE: return config_param::COMPLEX_STORAGE; case ONEMKL_DFT_PARAM_PLACEMENT: return config_param::PLACEMENT; - case ONEMKL_DFT_PARAM_INPUT_STRIDES: return config_param::INPUT_STRIDES; - case ONEMKL_DFT_PARAM_OUTPUT_STRIDES: return config_param::OUTPUT_STRIDES; + // oneMKL >= 2026.0 dropped the deprecated INPUT_STRIDES/OUTPUT_STRIDES; + // map the legacy parameters onto their FWD_STRIDES/BWD_STRIDES successors. + case ONEMKL_DFT_PARAM_INPUT_STRIDES: return config_param::FWD_STRIDES; + case ONEMKL_DFT_PARAM_OUTPUT_STRIDES: return config_param::BWD_STRIDES; case ONEMKL_DFT_PARAM_FWD_DISTANCE: return config_param::FWD_DISTANCE; case ONEMKL_DFT_PARAM_BWD_DISTANCE: return config_param::BWD_DISTANCE; case ONEMKL_DFT_PARAM_WORKSPACE: return config_param::WORKSPACE; @@ -210,7 +212,28 @@ int onemklDftGetValueInt64(onemklDftDescriptor_t desc, onemklDftConfigParam para int onemklDftGetValueDouble(onemklDftDescriptor_t desc, onemklDftConfigParam param, double *value) { if (!desc || !value) return -2; if (!desc->ptr) return -3; - try { ONEMKL_DFT_DISPATCH_CFG(desc->ptr, d->get_value(to_param(param), value)); return 0; } catch (...) { return -1; } + try { + config_param p = to_param(param); + // oneMKL >= 2026.0 requires a pointer to the descriptor's real scalar type + // (float for single precision, double for double); use a matching temporary + // and widen to double for the C interface. + if (desc->prec == precision::SINGLE) { + float tmp; + if (desc->dom == domain::REAL) + static_cast< descriptor* >(desc->ptr)->get_value(p, &tmp); + else + static_cast< descriptor* >(desc->ptr)->get_value(p, &tmp); + *value = static_cast(tmp); + } else { + double tmp; + if (desc->dom == domain::REAL) + static_cast< descriptor* >(desc->ptr)->get_value(p, &tmp); + else + static_cast< descriptor* >(desc->ptr)->get_value(p, &tmp); + *value = tmp; + } + return 0; + } catch (...) { return -1; } } int onemklDftGetValueInt64Array(onemklDftDescriptor_t desc, onemklDftConfigParam param, int64_t *values, int64_t *n) { @@ -443,8 +466,8 @@ int onemklDftQueryParamIndices(int64_t *out, int64_t n) { config_param::NUMBER_OF_TRANSFORMS, config_param::COMPLEX_STORAGE, config_param::PLACEMENT, - config_param::INPUT_STRIDES, - config_param::OUTPUT_STRIDES, + config_param::FWD_STRIDES, // was INPUT_STRIDES (removed in oneMKL 2026.0) + config_param::BWD_STRIDES, // was OUTPUT_STRIDES (removed in oneMKL 2026.0) config_param::FWD_DISTANCE, config_param::BWD_DISTANCE, config_param::WORKSPACE, diff --git a/lib/mkl/fft.jl b/lib/mkl/fft.jl index 5f5614b1..745ff65f 100644 --- a/lib/mkl/fft.jl +++ b/lib/mkl/fft.jl @@ -93,9 +93,14 @@ function _create_descriptor(sz::NTuple{N,Int}, T::Type, complex::Bool) where {N} prec = T<:Float64 || T<:ComplexF64 ? ONEMKL_DFT_PRECISION_DOUBLE : ONEMKL_DFT_PRECISION_SINGLE dom = complex ? ONEMKL_DFT_DOMAIN_COMPLEX : ONEMKL_DFT_DOMAIN_REAL desc_ref = Ref{onemklDftDescriptor_t}() - # Create descriptor for the full array dimensions + # Create descriptor for the full array dimensions. `lengths` must stay rooted + # across the ccall: oneMKL copies the dimensions out of `pointer(lengths)`, and + # without GC.@preserve the array can be collected first, leaving the descriptor + # with garbage dimensions (commit then fails with FFT_INVALID_DESCRIPTOR). lengths = collect(Int64, sz) - st = length(lengths) == 1 ? onemklDftCreate1D(desc_ref, prec, dom, lengths[1]) : onemklDftCreateND(desc_ref, prec, dom, length(lengths), pointer(lengths)) + st = GC.@preserve lengths (length(lengths) == 1 ? + onemklDftCreate1D(desc_ref, prec, dom, lengths[1]) : + onemklDftCreateND(desc_ref, prec, dom, length(lengths), pointer(lengths))) st == 0 || error("onemkl DFT create failed (status $st)") desc = desc_ref[] # Do not program descriptor scaling; we'll perform inverse normalization manually. @@ -125,8 +130,10 @@ function plan_fft(X::oneAPI.oneArray{T,N}, region) where {T<:Union{ComplexF32,Co strides[i+1] = prod prod *= size(X,i) end - onemklDftSetValueInt64Array(desc, ONEMKL_DFT_PARAM_FWD_STRIDES, pointer(strides), length(strides)) - onemklDftSetValueInt64Array(desc, ONEMKL_DFT_PARAM_BWD_STRIDES, pointer(strides), length(strides)) + GC.@preserve strides begin + onemklDftSetValueInt64Array(desc, ONEMKL_DFT_PARAM_FWD_STRIDES, pointer(strides), length(strides)) + onemklDftSetValueInt64Array(desc, ONEMKL_DFT_PARAM_BWD_STRIDES, pointer(strides), length(strides)) + end end stc = onemklDftCommit(desc, q); stc == 0 || error("commit failed ($stc)") return cMKLFFTPlan{T,MKLFFT_FORWARD,false,N,R,Nothing}(desc,q,size(X),size(X),false,reg,nothing,nothing) @@ -144,8 +151,10 @@ function plan_bfft(X::oneAPI.oneArray{T,N}, region) where {T<:Union{ComplexF32,C @inbounds for i in 1:N strides[i+1]=prod; prod*=size(X,i) end - onemklDftSetValueInt64Array(desc, ONEMKL_DFT_PARAM_FWD_STRIDES, pointer(strides), length(strides)) - onemklDftSetValueInt64Array(desc, ONEMKL_DFT_PARAM_BWD_STRIDES, pointer(strides), length(strides)) + GC.@preserve strides begin + onemklDftSetValueInt64Array(desc, ONEMKL_DFT_PARAM_FWD_STRIDES, pointer(strides), length(strides)) + onemklDftSetValueInt64Array(desc, ONEMKL_DFT_PARAM_BWD_STRIDES, pointer(strides), length(strides)) + end end stc = onemklDftCommit(desc, q); stc == 0 || error("commit failed ($stc)") return cMKLFFTPlan{T,MKLFFT_INVERSE,false,N,R,Nothing}(desc,q,size(X),size(X),false,reg,nothing,nothing) @@ -165,8 +174,10 @@ function plan_fft!(X::oneAPI.oneArray{T,N}, region) where {T<:Union{ComplexF32,C @inbounds for i in 1:N strides[i+1]=prod; prod*=size(X,i) end - onemklDftSetValueInt64Array(desc, ONEMKL_DFT_PARAM_FWD_STRIDES, pointer(strides), length(strides)) - onemklDftSetValueInt64Array(desc, ONEMKL_DFT_PARAM_BWD_STRIDES, pointer(strides), length(strides)) + GC.@preserve strides begin + onemklDftSetValueInt64Array(desc, ONEMKL_DFT_PARAM_FWD_STRIDES, pointer(strides), length(strides)) + onemklDftSetValueInt64Array(desc, ONEMKL_DFT_PARAM_BWD_STRIDES, pointer(strides), length(strides)) + end end stc = onemklDftCommit(desc, q); stc == 0 || error("commit failed ($stc)") cMKLFFTPlan{T,MKLFFT_FORWARD,true,N,R,Nothing}(desc,q,size(X),size(X),false,reg,nothing,nothing) @@ -184,8 +195,10 @@ function plan_bfft!(X::oneAPI.oneArray{T,N}, region) where {T<:Union{ComplexF32, @inbounds for i in 1:N strides[i+1]=prod; prod*=size(X,i) end - onemklDftSetValueInt64Array(desc, ONEMKL_DFT_PARAM_FWD_STRIDES, pointer(strides), length(strides)) - onemklDftSetValueInt64Array(desc, ONEMKL_DFT_PARAM_BWD_STRIDES, pointer(strides), length(strides)) + GC.@preserve strides begin + onemklDftSetValueInt64Array(desc, ONEMKL_DFT_PARAM_FWD_STRIDES, pointer(strides), length(strides)) + onemklDftSetValueInt64Array(desc, ONEMKL_DFT_PARAM_BWD_STRIDES, pointer(strides), length(strides)) + end end stc = onemklDftCommit(desc, q); stc == 0 || error("commit failed ($stc)") cMKLFFTPlan{T,MKLFFT_INVERSE,true,N,R,Nothing}(desc,q,size(X),size(X),false,reg,nothing,nothing) diff --git a/test/onemkl.jl b/test/onemkl.jl index 4a4c7fcd..98774404 100644 --- a/test/onemkl.jl +++ b/test/onemkl.jl @@ -14,7 +14,7 @@ k = 13 @testset "Version" begin version_onemkl = oneMKL.version() - @test version_onemkl ≥ v"2025.2.0" + @test version_onemkl ≥ v"2026.0.0" end ############################################################################################