diff --git a/perf/array.jl b/perf/array.jl index 65baa304dd..2a75a1b4a6 100644 --- a/perf/array.jl +++ b/perf/array.jl @@ -138,9 +138,21 @@ let group = addgroup!(group, "random") end let group = addgroup!(group, "sorting") - group["1d"] = @async_benchmarkable sort($gpu_vec) - group["2d"] = @async_benchmarkable sort($gpu_mat; dims=1) - group["by"] = @async_benchmarkable sort($gpu_vec; by=sin) + let group = addgroup!(group, "Float32") + group["1d"] = @async_benchmarkable sort($gpu_vec) + group["by=sin"] = @async_benchmarkable sort($gpu_vec; by=sin) + # group["dims=1"] = @async_benchmarkable sort($gpu_mat; dims=1) + # group["dims=2"] = @async_benchmarkable sort($gpu_mat; dims=2) + # group["dims=1L"] = @async_benchmarkable sort($gpu_mat_long; dims=1) + # group["dims=2L"] = @async_benchmarkable sort($gpu_mat_long; dims=2) + end + let group = addgroup!(group, "Int64") + group["1d"] = @async_benchmarkable sort($gpu_vec_ints) + # group["dims=1"] = @async_benchmarkable sort($gpu_mat_ints; dims=1) + # group["dims=2"] = @async_benchmarkable sort($gpu_mat_ints; dims=2) + # group["dims=1L"] = @async_benchmarkable sort($gpu_mat_long_ints; dims=1) + # group["dims=2L"] = @async_benchmarkable sort($gpu_mat_long_ints; dims=2) + end end let group = addgroup!(group, "permutedims") diff --git a/perf/runbenchmarks.jl b/perf/runbenchmarks.jl index 72d8b1e76a..98935bc466 100644 --- a/perf/runbenchmarks.jl +++ b/perf/runbenchmarks.jl @@ -1,4 +1,6 @@ # benchmark suite execution and codespeed submission +using Pkg +Pkg.add(url="https://github.com/christiangnrd/GPUArrays.jl", rev="sort") using CUDA diff --git a/src/sorting.jl b/src/sorting.jl index 00f7c39a65..54004f8f52 100644 --- a/src/sorting.jl +++ b/src/sorting.jl @@ -970,93 +970,93 @@ end # Base interface implementation -using .BitonicSortImpl -using .QuickSortImpl - - -abstract type SortingAlgorithm end -struct QuickSortAlg <: SortingAlgorithm end -struct BitonicSortAlg <: SortingAlgorithm end - -const QuickSort = QuickSortAlg() -const BitonicSort = BitonicSortAlg() - - -function Base.sort!(c::AnyCuVector, alg::QuickSortAlg; lt=isless, by=identity, rev=false) - # for reverse sorting, invert the less-than function - if rev - lt = !lt - end - - quicksort!(c; lt, by, dims=1) - return c -end - -function Base.sort!(c::AnyCuArray, alg::BitonicSortAlg; kwargs...) - return bitonic_sort!(c; kwargs...) -end - -function Base.sort!(c::AnyCuArray; alg::SortingAlgorithm = BitonicSort, kwargs...) - return sort!(c, alg; kwargs...) -end - -function Base.sort(c::AnyCuArray; kwargs...) - return sort!(copy(c); kwargs...) -end - -function Base.partialsort!(c::AnyCuVector, k::Union{Integer, OrdinalRange}, - alg::BitonicSortAlg; lt=isless, by=identity, rev=false) - - sort!(c, alg; lt, by, rev) - return @allowscalar copy(c[k]) -end - -function Base.partialsort!(c::AnyCuVector, k::Union{Integer, OrdinalRange}, - alg::QuickSortAlg; lt=isless, by=identity, rev=false) - # for reverse sorting, invert the less-than function - if rev - lt = !lt - end - - function out(k::OrdinalRange) - return copy(c[k]) - end - - # work around disallowed scalar index - function out(k::Integer) - return Array(c[k:k])[1] - end - - quicksort!(c; lt, by, dims=1, partial_k=k) - return out(k) -end - -function Base.partialsort!(c::AnyCuArray, k::Union{Integer, OrdinalRange}; - alg::SortingAlgorithm=BitonicSort, kwargs...) - return partialsort!(c, k, alg; kwargs...) -end - -function Base.partialsort(c::AnyCuArray, k::Union{Integer, OrdinalRange}; kwargs...) - return partialsort!(copy(c), k; kwargs...) -end - -function Base.sortperm!(ix::AnyCuArray, A::AnyCuArray; initialized=false, kwargs...) - if axes(ix) != axes(A) - throw(ArgumentError("index array must have the same size/axes as the source array, $(axes(ix)) != $(axes(A))")) - end - - if !initialized - ix .= LinearIndices(A) - end - bitonic_sort!((A, ix); kwargs...) - return ix -end - -function Base.sortperm(c::AnyCuVector; kwargs...) - sortperm!(CuArray(1:length(c)), c; initialized=true, kwargs...) -end - -function Base.sortperm(c::AnyCuArray; dims, kwargs...) - # Base errors for Matrices without dims arg, we should too - sortperm!(reshape(CuArray(1:length(c)), size(c)), c; initialized=true, dims, kwargs...) -end +# using .BitonicSortImpl +# using .QuickSortImpl + + +# abstract type SortingAlgorithm end +# struct QuickSortAlg <: SortingAlgorithm end +# struct BitonicSortAlg <: SortingAlgorithm end + +# const QuickSort = QuickSortAlg() +# const BitonicSort = BitonicSortAlg() + + +# function Base.sort!(c::AnyCuVector, alg::QuickSortAlg; lt=isless, by=identity, rev=false) +# # for reverse sorting, invert the less-than function +# if rev +# lt = !lt +# end + +# quicksort!(c; lt, by, dims=1) +# return c +# end + +# function Base.sort!(c::AnyCuArray, alg::BitonicSortAlg; kwargs...) +# return bitonic_sort!(c; kwargs...) +# end + +# function Base.sort!(c::AnyCuArray; alg::SortingAlgorithm = BitonicSort, kwargs...) +# return sort!(c, alg; kwargs...) +# end + +# function Base.sort(c::AnyCuArray; kwargs...) +# return sort!(copy(c); kwargs...) +# end + +# function Base.partialsort!(c::AnyCuVector, k::Union{Integer, OrdinalRange}, +# alg::BitonicSortAlg; lt=isless, by=identity, rev=false) + +# sort!(c, alg; lt, by, rev) +# return @allowscalar copy(c[k]) +# end + +# function Base.partialsort!(c::AnyCuVector, k::Union{Integer, OrdinalRange}, +# alg::QuickSortAlg; lt=isless, by=identity, rev=false) +# # for reverse sorting, invert the less-than function +# if rev +# lt = !lt +# end + +# function out(k::OrdinalRange) +# return copy(c[k]) +# end + +# # work around disallowed scalar index +# function out(k::Integer) +# return Array(c[k:k])[1] +# end + +# quicksort!(c; lt, by, dims=1, partial_k=k) +# return out(k) +# end + +# function Base.partialsort!(c::AnyCuArray, k::Union{Integer, OrdinalRange}; +# alg::SortingAlgorithm=BitonicSort, kwargs...) +# return partialsort!(c, k, alg; kwargs...) +# end + +# function Base.partialsort(c::AnyCuArray, k::Union{Integer, OrdinalRange}; kwargs...) +# return partialsort!(copy(c), k; kwargs...) +# end + +# function Base.sortperm!(ix::AnyCuArray, A::AnyCuArray; initialized=false, kwargs...) +# if axes(ix) != axes(A) +# throw(ArgumentError("index array must have the same size/axes as the source array, $(axes(ix)) != $(axes(A))")) +# end + +# if !initialized +# ix .= LinearIndices(A) +# end +# bitonic_sort!((A, ix); kwargs...) +# return ix +# end + +# function Base.sortperm(c::AnyCuVector; kwargs...) +# sortperm!(CuArray(1:length(c)), c; initialized=true, kwargs...) +# end + +# function Base.sortperm(c::AnyCuArray; dims, kwargs...) +# # Base errors for Matrices without dims arg, we should too +# sortperm!(reshape(CuArray(1:length(c)), size(c)), c; initialized=true, dims, kwargs...) +# end diff --git a/test/base/sorting.jl b/test/base/sorting.jl index 40bdd3785c..d6836bd42e 100644 --- a/test/base/sorting.jl +++ b/test/base/sorting.jl @@ -277,124 +277,124 @@ end end end -@testset "interface" begin - @testset "quicksort" begin - # pre-sorted - @test check_sort!(Int, 1000000; alg=CUDA.QuickSort) - @test check_sort!(Int32, 1000000; alg=CUDA.QuickSort) - @test check_sort!(Float64, 1000000; alg=CUDA.QuickSort) - @test check_sort!(Float32, 1000000; alg=CUDA.QuickSort) - @test check_sort!(Int32, 1000000; rev=true) - @test check_sort!(Float32, 1000000; rev=true) - - # reverse sorted - @test check_sort!(Int32, 1000000, x -> -x; alg=CUDA.QuickSort) - @test check_sort!(Float32, 1000000, x -> -x; alg=CUDA.QuickSort) - @test check_sort!(Int32, 1000000, x -> -x; rev=true, alg=CUDA.QuickSort) - @test check_sort!(Float32, 1000000, x -> -x; rev=true, alg=CUDA.QuickSort) - - @test check_sort!(Int, 10000, x -> rand(Int); alg=CUDA.QuickSort) - @test check_sort!(Int32, 10000, x -> rand(Int32); alg=CUDA.QuickSort) - @test check_sort!(Int8, 10000, x -> rand(Int8); alg=CUDA.QuickSort) - @test check_sort!(Float64, 10000, x -> rand(Float64); alg=CUDA.QuickSort) - @test check_sort!(Float32, 10000, x -> rand(Float32); alg=CUDA.QuickSort) - @test check_sort!(Float16, 10000, x -> rand(Float16); alg=CUDA.QuickSort) - @test check_sort!(Tuple{Int,Int}, 10000, x -> (rand(Int), rand(Int)); alg=CUDA.QuickSort) - - # non-uniform distributions - @test check_sort!(UInt8, 100000, x -> round(255 * rand() ^ 2); alg=CUDA.QuickSort) - @test check_sort!(UInt8, 100000, x -> round(255 * rand() ^ 3); alg=CUDA.QuickSort) - - # more copies of each value than can fit in one block - @test check_sort!(Int8, 4000000, x -> rand(Int8); alg=CUDA.QuickSort) - - # multiple dimensions - @test check_sort!(Int32, (4, 50000, 4); dims=2) - @test check_sort!(Int32, (2, 2, 50000); dims=3, rev=true) - - # large sizes - @test check_sort!(Float32, 2^25; alg=CUDA.QuickSort) - - # various sync depths - for depth in 0:4 - CUDA.limit!(CUDA.LIMIT_DEV_RUNTIME_SYNC_DEPTH, depth) - @test check_sort!(Int, 100000, x -> rand(Int); alg=CUDA.QuickSort) - end - - # using a `by` argument - @test check_sort(Float32, 100000; by=x->abs(x - 0.5), alg=CUDA.QuickSort) - @test check_sort!(Float32, (100000, 4); by=x->abs(x - 0.5), dims=1) - @test check_sort!(Float32, (4, 100000); by=x->abs(x - 0.5), dims=2) - @test check_sort!(Float64, 400000; by=x->8*x-round(8*x), alg=CUDA.QuickSort) - @test check_sort!(Float64, (100000, 4); by=x->8*x-round(8*x), dims=1) - @test check_sort!(Float64, (4, 100000); by=x->8*x-round(8*x), dims=2) - # target bubble sort by using sub-blocksize input: - @test check_sort!(Int, 200; by=x->x % 2, alg=CUDA.QuickSort) - @test check_sort!(Int, 200; by=x->x % 3, alg=CUDA.QuickSort) - @test check_sort!(Int, 200; by=x->x % 4, alg=CUDA.QuickSort) - end # end quicksort tests - - @testset "bitonic sort" begin - # test various types - @test check_sort(Int, 10000, x -> rand(Int); alg=CUDA.BitonicSort) - @test check_sort!(Int, 10000, x -> rand(Int); alg=CUDA.BitonicSort) - @test check_sort!(Int32, 10000, x -> rand(Int32); alg=CUDA.BitonicSort) - @test check_sort!(Int8, 10000, x -> rand(Int8); alg=CUDA.BitonicSort) - @test check_sort!(Float64, 10000, x -> rand(Float64); alg=CUDA.BitonicSort) - @test check_sort!(Float32, 10000, x -> rand(Float32); alg=CUDA.BitonicSort) - @test check_sort!(Float16, 10000, x -> rand(Float16); alg=CUDA.BitonicSort) - @test check_sort!(Tuple{Int,Int}, 10000, x -> (rand(Int), rand(Int)); alg=CUDA.BitonicSort) - - # test various sizes - @test check_sort!(Float32, 1, x -> rand(Float32); alg=CUDA.BitonicSort) - @test check_sort!(Float32, 2, x -> rand(Float32); alg=CUDA.BitonicSort) - @test check_sort!(Float32, 3, x -> rand(Float32); alg=CUDA.BitonicSort) - @test check_sort!(Float32, 4, x -> rand(Float32); alg=CUDA.BitonicSort) - @test check_sort!(Float32, 1 << 16 + 0, x -> rand(Float32); alg=CUDA.BitonicSort) - @test check_sort!(Float32, 1 << 16 + 1, x -> rand(Float32); alg=CUDA.BitonicSort) - @test check_sort!(Float32, 1 << 16 + 31, x -> rand(Float32); alg=CUDA.BitonicSort) - @test check_sort!(Float32, 1 << 16 + 32, x -> rand(Float32); alg=CUDA.BitonicSort) - @test check_sort!(Float32, 1 << 16 + 33, x -> rand(Float32); alg=CUDA.BitonicSort) - @test check_sort!(Float32, 1 << 16 + 127, x -> rand(Float32); alg=CUDA.BitonicSort) - @test check_sort!(Float32, 1 << 16 + 128, x -> rand(Float32); alg=CUDA.BitonicSort) - @test check_sort!(Float32, 1 << 16 + 129, x -> rand(Float32); alg=CUDA.BitonicSort) - end # end bitonic tests - - @test_throws MethodError check_sort!(Int, (100, 100); alg=CUDA.BitonicSort, dims=1) - - #partial sort - @test check_partialsort!(Int, 100000, 1) - @test check_partialsort!(Int, 100000, 100000) - @test check_partialsort!(Int, 100000, 50000) - @test check_partialsort!(Int, 100000, 10000:20000) - @test check_partialsort!(Int, 100000, 1:100000) - @test check_partialsort!(Float32, 100000, 1; by=x->abs(x - 0.5)) - @test check_partialsort!(Float32, 100000, 100000; by=x->abs(x - 0.5)) - @test check_partialsort!(Float32, 100000, 50000; by=x->abs(x - 0.5)) - @test check_partialsort!(Float32, 100000, 10000:20000; by=x->abs(x - 0.5)) - @test check_partialsort!(Float32, 100000, 1:100000; by=x->abs(x - 0.5)) - - #sort perm - # A set of 1e6 Float32s has ~9.4e5 unique values: stability is non-trivial - @test check_sortperm(Float32, 1000000) - @test check_sortperm(Float32, 1000000; rev=true) - @test check_sortperm(Float32, 1000000; by=x->abs(x-0.5f0)) - @test check_sortperm(Float32, 1000000; rev=true, by=x->abs(x-0.5f0)) - @test check_sortperm(Float64, 1000000) - @test check_sortperm(Float64, 1000000; rev=true) - @test check_sortperm(Float64, 1000000; by=x->abs(x-0.5)) - @test check_sortperm(Float64, 1000000; rev=true, by=x->abs(x-0.5)) - @test check_sortperm(Float32, (100_000, 16); dims=1) - @test check_sortperm(Float32, (100_000, 16); dims=2) - @test check_sortperm(Float32, (100, 256, 256); dims=1) - - # check with Int32 indices - @test check_sortperm!(collect(Int32(1):Int32(1000000)), Float32, 1000000) - # `initialized` kwarg - @test check_sortperm!(collect(Int32(1):Int32(1000000)), Float32, 1000000; initialized=true) - @test check_sortperm!(collect(Int32(1):Int32(1000000)), Float32, 1000000; initialized=false) - # expected error case - @test_throws ArgumentError sortperm!(CuArray(1:3), CuArray(1:4)) - # mismatched types (JuliaGPU/CUDA.jl#2046) - @test check_sortperm!(collect(UInt64(1):UInt64(1000000)), Int64, 1000000) -end +# @testset "interface" begin +# @testset "quicksort" begin +# # pre-sorted +# @test check_sort!(Int, 1000000; alg=CUDA.QuickSort) +# @test check_sort!(Int32, 1000000; alg=CUDA.QuickSort) +# @test check_sort!(Float64, 1000000; alg=CUDA.QuickSort) +# @test check_sort!(Float32, 1000000; alg=CUDA.QuickSort) +# @test check_sort!(Int32, 1000000; rev=true) +# @test check_sort!(Float32, 1000000; rev=true) + +# # reverse sorted +# @test check_sort!(Int32, 1000000, x -> -x; alg=CUDA.QuickSort) +# @test check_sort!(Float32, 1000000, x -> -x; alg=CUDA.QuickSort) +# @test check_sort!(Int32, 1000000, x -> -x; rev=true, alg=CUDA.QuickSort) +# @test check_sort!(Float32, 1000000, x -> -x; rev=true, alg=CUDA.QuickSort) + +# @test check_sort!(Int, 10000, x -> rand(Int); alg=CUDA.QuickSort) +# @test check_sort!(Int32, 10000, x -> rand(Int32); alg=CUDA.QuickSort) +# @test check_sort!(Int8, 10000, x -> rand(Int8); alg=CUDA.QuickSort) +# @test check_sort!(Float64, 10000, x -> rand(Float64); alg=CUDA.QuickSort) +# @test check_sort!(Float32, 10000, x -> rand(Float32); alg=CUDA.QuickSort) +# @test check_sort!(Float16, 10000, x -> rand(Float16); alg=CUDA.QuickSort) +# @test check_sort!(Tuple{Int,Int}, 10000, x -> (rand(Int), rand(Int)); alg=CUDA.QuickSort) + +# # non-uniform distributions +# @test check_sort!(UInt8, 100000, x -> round(255 * rand() ^ 2); alg=CUDA.QuickSort) +# @test check_sort!(UInt8, 100000, x -> round(255 * rand() ^ 3); alg=CUDA.QuickSort) + +# # more copies of each value than can fit in one block +# @test check_sort!(Int8, 4000000, x -> rand(Int8); alg=CUDA.QuickSort) + +# # multiple dimensions +# @test check_sort!(Int32, (4, 50000, 4); dims=2) +# @test check_sort!(Int32, (2, 2, 50000); dims=3, rev=true) + +# # large sizes +# @test check_sort!(Float32, 2^25; alg=CUDA.QuickSort) + +# # various sync depths +# for depth in 0:4 +# CUDA.limit!(CUDA.LIMIT_DEV_RUNTIME_SYNC_DEPTH, depth) +# @test check_sort!(Int, 100000, x -> rand(Int); alg=CUDA.QuickSort) +# end + +# # using a `by` argument +# @test check_sort(Float32, 100000; by=x->abs(x - 0.5), alg=CUDA.QuickSort) +# @test check_sort!(Float32, (100000, 4); by=x->abs(x - 0.5), dims=1) +# @test check_sort!(Float32, (4, 100000); by=x->abs(x - 0.5), dims=2) +# @test check_sort!(Float64, 400000; by=x->8*x-round(8*x), alg=CUDA.QuickSort) +# @test check_sort!(Float64, (100000, 4); by=x->8*x-round(8*x), dims=1) +# @test check_sort!(Float64, (4, 100000); by=x->8*x-round(8*x), dims=2) +# # target bubble sort by using sub-blocksize input: +# @test check_sort!(Int, 200; by=x->x % 2, alg=CUDA.QuickSort) +# @test check_sort!(Int, 200; by=x->x % 3, alg=CUDA.QuickSort) +# @test check_sort!(Int, 200; by=x->x % 4, alg=CUDA.QuickSort) +# end # end quicksort tests + +# @testset "bitonic sort" begin +# # test various types +# @test check_sort(Int, 10000, x -> rand(Int); alg=CUDA.BitonicSort) +# @test check_sort!(Int, 10000, x -> rand(Int); alg=CUDA.BitonicSort) +# @test check_sort!(Int32, 10000, x -> rand(Int32); alg=CUDA.BitonicSort) +# @test check_sort!(Int8, 10000, x -> rand(Int8); alg=CUDA.BitonicSort) +# @test check_sort!(Float64, 10000, x -> rand(Float64); alg=CUDA.BitonicSort) +# @test check_sort!(Float32, 10000, x -> rand(Float32); alg=CUDA.BitonicSort) +# @test check_sort!(Float16, 10000, x -> rand(Float16); alg=CUDA.BitonicSort) +# @test check_sort!(Tuple{Int,Int}, 10000, x -> (rand(Int), rand(Int)); alg=CUDA.BitonicSort) + +# # test various sizes +# @test check_sort!(Float32, 1, x -> rand(Float32); alg=CUDA.BitonicSort) +# @test check_sort!(Float32, 2, x -> rand(Float32); alg=CUDA.BitonicSort) +# @test check_sort!(Float32, 3, x -> rand(Float32); alg=CUDA.BitonicSort) +# @test check_sort!(Float32, 4, x -> rand(Float32); alg=CUDA.BitonicSort) +# @test check_sort!(Float32, 1 << 16 + 0, x -> rand(Float32); alg=CUDA.BitonicSort) +# @test check_sort!(Float32, 1 << 16 + 1, x -> rand(Float32); alg=CUDA.BitonicSort) +# @test check_sort!(Float32, 1 << 16 + 31, x -> rand(Float32); alg=CUDA.BitonicSort) +# @test check_sort!(Float32, 1 << 16 + 32, x -> rand(Float32); alg=CUDA.BitonicSort) +# @test check_sort!(Float32, 1 << 16 + 33, x -> rand(Float32); alg=CUDA.BitonicSort) +# @test check_sort!(Float32, 1 << 16 + 127, x -> rand(Float32); alg=CUDA.BitonicSort) +# @test check_sort!(Float32, 1 << 16 + 128, x -> rand(Float32); alg=CUDA.BitonicSort) +# @test check_sort!(Float32, 1 << 16 + 129, x -> rand(Float32); alg=CUDA.BitonicSort) +# end # end bitonic tests + +# @test_throws MethodError check_sort!(Int, (100, 100); alg=CUDA.BitonicSort, dims=1) + +# #partial sort +# @test check_partialsort!(Int, 100000, 1) +# @test check_partialsort!(Int, 100000, 100000) +# @test check_partialsort!(Int, 100000, 50000) +# @test check_partialsort!(Int, 100000, 10000:20000) +# @test check_partialsort!(Int, 100000, 1:100000) +# @test check_partialsort!(Float32, 100000, 1; by=x->abs(x - 0.5)) +# @test check_partialsort!(Float32, 100000, 100000; by=x->abs(x - 0.5)) +# @test check_partialsort!(Float32, 100000, 50000; by=x->abs(x - 0.5)) +# @test check_partialsort!(Float32, 100000, 10000:20000; by=x->abs(x - 0.5)) +# @test check_partialsort!(Float32, 100000, 1:100000; by=x->abs(x - 0.5)) + +# #sort perm +# # A set of 1e6 Float32s has ~9.4e5 unique values: stability is non-trivial +# @test check_sortperm(Float32, 1000000) +# @test check_sortperm(Float32, 1000000; rev=true) +# @test check_sortperm(Float32, 1000000; by=x->abs(x-0.5f0)) +# @test check_sortperm(Float32, 1000000; rev=true, by=x->abs(x-0.5f0)) +# @test check_sortperm(Float64, 1000000) +# @test check_sortperm(Float64, 1000000; rev=true) +# @test check_sortperm(Float64, 1000000; by=x->abs(x-0.5)) +# @test check_sortperm(Float64, 1000000; rev=true, by=x->abs(x-0.5)) +# @test check_sortperm(Float32, (100_000, 16); dims=1) +# @test check_sortperm(Float32, (100_000, 16); dims=2) +# @test check_sortperm(Float32, (100, 256, 256); dims=1) + +# # check with Int32 indices +# @test check_sortperm!(collect(Int32(1):Int32(1000000)), Float32, 1000000) +# # `initialized` kwarg +# @test check_sortperm!(collect(Int32(1):Int32(1000000)), Float32, 1000000; initialized=true) +# @test check_sortperm!(collect(Int32(1):Int32(1000000)), Float32, 1000000; initialized=false) +# # expected error case +# @test_throws ArgumentError sortperm!(CuArray(1:3), CuArray(1:4)) +# # mismatched types (JuliaGPU/CUDA.jl#2046) +# @test check_sortperm!(collect(UInt64(1):UInt64(1000000)), Int64, 1000000) +# end diff --git a/test/runtests.jl b/test/runtests.jl index 9172d18a5c..4e41a17fc9 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,3 +1,6 @@ +using Pkg +Pkg.add(url="https://github.com/christiangnrd/GPUArrays.jl", rev="sort") + using Distributed using Dates import REPL