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!