diff --git a/src/solver.cu b/src/solver.cu index 2bdcb59..110b2cd 100644 --- a/src/solver.cu +++ b/src/solver.cu @@ -401,6 +401,7 @@ static pdhg_solver_state_t *initialize_solver_state(const lp_problem_t *working_ (state->num_variables + state->num_constraints + THREADS_PER_BLOCK - 1) / THREADS_PER_BLOCK; state->num_blocks_nnz = (state->constraint_matrix->num_nonzeros + THREADS_PER_BLOCK - 1) / THREADS_PER_BLOCK; + CUDA_CHECK(cudaFree(0)); CUSPARSE_CHECK(cusparseCreate(&state->sparse_handle)); CUBLAS_CHECK(cublasCreate(&state->blas_handle)); CUBLAS_CHECK(cublasSetPointerMode(state->blas_handle, CUBLAS_POINTER_MODE_HOST)); diff --git a/src/utils.cu b/src/utils.cu index ef157db..bcf7e81 100644 --- a/src/utils.cu +++ b/src/utils.cu @@ -386,8 +386,8 @@ bool should_do_adaptive_restart(pdhg_solver_state_t *solver_state, return reason != NULL; } -// The context is created once per process; a later CUDA call on any thread -// waits for it inside the driver. +// The solver thread must initialize the runtime before creating cuSPARSE +// handles, which can otherwise race this background initialization. void cupdlpx_gpu_init_async(void) { static std::once_flag once;