Hello,
I would like to perform crossvalidation and grid search using SVM (and XGBoost), using a parameter grid defined for each method.
In MATLAB, within each split, I can run parfor, and each thread will train some models on the data, using specific parameter combinations.
In Julia, using LIBSVM.jl and XGBoost.jl, I would like to run a Threads.@threads for loop to perform the same. However, this results in crashing and segfaults. I have also tried using MLJScikitLearnInterface, but with similar outcomes.
Interestingly, as you can see from the MWE below, the error only occurs if the function is called twice.
Note: Before the Threads.@threads loop, I set the number of BLAS threads to 1, to have each thread create its own BLAS thread. Moreover, each thread saves the model and the output in a preallocated array, at the index defined by the index of the parameter combination used (there should be no data race or issues with Threads.threadid() AFAIU).
A MWE would be the following:
using Random, LIBSVM, LinearAlgebra.BLAS
function gridsearch(gammas)
models = Vector(undef, length(gammas)) # collector of models
tim = zeros(length(gammas)) # training times
prevBLASthreads = BLAS.get_num_threads();
BLAS.set_num_threads(1);
Threads.@threads for i ∈ eachindex(gammas)
tim[i] = @elapsed models[i] = svmtrain(
rand(10,100), # For this example, random data
rand(1:10,100),
svmtype = SVC,
kernel = Kernel.RadialBasis,
gamma = gammas[i],
)
end
BLAS.set_num_threads(prevBLASthreads);
return models,minimum(tim) # Let us just return models and best time as example
end
@info "Starting"
out1,tim1 = gridsearch([.01;.05;.1;.5;.7]) # This runs
@info "First time done, fastest took $tim1"
out2,tim2 = gridsearch([.01;.05;.1;.5;.7]). # This crashes
@info "Second time done, fastest took $tim2"
I would highly appreciate some opinions on what is happening here. Thanks!