@@ -270,51 +270,30 @@ void my_cusparsespmm_preprocess(cusparseHandle_t handle,
270270}
271271#endif
272272
273- #if CUOPT_CUSPARSE_VER_12_7_UP
274- // SpMVOp symbols. Resolved at runtime via dlsym, because the runtime cuSPARSE version
275- // might not match the headers used at compile time. cuSPARSE 12.7 corresponds to CUDA
276- // Toolkit 13.2; cuSPARSE 12.8 corresponds to CUDA Toolkit 13.3. We can go back to
277- // direct linking once CUDA 14 is adopted.
278- using cusparseSpMVOp_destroyDescr_sig = cusparse_sig<cusparseSpMVOpDescr_t>;
279- using cusparseSpMVOp_destroyPlan_sig = cusparse_sig<cusparseSpMVOpPlan_t>;
280- using cusparseSpMVOp_bufferSize_12_7_sig = cusparse_sig<cusparseHandle_t,
281- cusparseOperation_t,
282- cusparseSpMatDescr_t,
283- cusparseDnVecDescr_t,
284- cusparseDnVecDescr_t,
285- cusparseDnVecDescr_t,
286- cudaDataType,
287- size_t *>;
288- using cusparseSpMVOp_createDescr_12_7_sig = cusparse_sig<cusparseHandle_t,
289- cusparseSpMVOpDescr_t*,
290- cusparseOperation_t,
291- cusparseSpMatDescr_t,
292- cusparseDnVecDescr_t,
293- cusparseDnVecDescr_t,
294- cusparseDnVecDescr_t,
295- cudaDataType,
296- void *>;
297273#if CUOPT_CUSPARSE_VER_12_8_UP
298- using cusparseSpMVOp_bufferSize_12_8_sig = cusparse_sig<cusparseHandle_t,
299- cusparseOperation_t,
300- cusparseConstSpMatDescr_t,
301- cusparseConstDnVecDescr_t,
302- cusparseDnVecDescr_t,
303- cusparseDnVecDescr_t,
304- cudaDataType,
305- cusparseSpMVOpAlg_t,
306- size_t *>;
307- using cusparseSpMVOp_createDescr_12_8_sig = cusparse_sig<cusparseHandle_t,
308- cusparseSpMVOpDescr_t*,
309- cusparseOperation_t,
310- cusparseConstSpMatDescr_t,
311- cusparseConstDnVecDescr_t,
312- cusparseDnVecDescr_t,
313- cusparseDnVecDescr_t,
314- cudaDataType,
315- cusparseSpMVOpAlg_t,
316- void *>;
317- #endif // CUOPT_CUSPARSE_VER_12_8_UP
274+ // SpMVOp symbols. Resolved at runtime via dlsym, because the runtime minor version might not match
275+ // the compiled minor version. We can go back to direct linking once CUDA 14 is adopted
276+ using cusparseSpMVOp_destroyDescr_sig = cusparse_sig<cusparseSpMVOpDescr_t>;
277+ using cusparseSpMVOp_destroyPlan_sig = cusparse_sig<cusparseSpMVOpPlan_t>;
278+ using cusparseSpMVOp_bufferSize_sig = cusparse_sig<cusparseHandle_t,
279+ cusparseOperation_t,
280+ cusparseConstSpMatDescr_t,
281+ cusparseConstDnVecDescr_t,
282+ cusparseDnVecDescr_t,
283+ cusparseDnVecDescr_t,
284+ cudaDataType,
285+ cusparseSpMVOpAlg_t,
286+ size_t *>;
287+ using cusparseSpMVOp_createDescr_sig = cusparse_sig<cusparseHandle_t,
288+ cusparseSpMVOpDescr_t*,
289+ cusparseOperation_t,
290+ cusparseConstSpMatDescr_t,
291+ cusparseConstDnVecDescr_t,
292+ cusparseDnVecDescr_t,
293+ cusparseDnVecDescr_t,
294+ cudaDataType,
295+ cusparseSpMVOpAlg_t,
296+ void *>;
318297using cusparseSpMVOp_createPlan_sig =
319298 cusparse_sig<cusparseHandle_t, cusparseSpMVOpDescr_t, cusparseSpMVOpPlan_t*, char *, size_t >;
320299using cusparseSpMVOp_sig = cusparse_sig<cusparseHandle_t,
@@ -325,43 +304,6 @@ using cusparseSpMVOp_sig = cusparse_sig<cusparseHandle_t,
325304 cusparseDnVecDescr_t,
326305 cusparseDnVecDescr_t>;
327306
328- namespace {
329-
330- bool is_cusparse_runtime_12_8_or_newer ()
331- {
332- // cuSPARSE 12.8 is the version shipped with CUDA Toolkit 13.3.
333- int major = 0 , minor = 0 ;
334- auto status = cusparseGetProperty (libraryPropertyType_t::MAJOR_VERSION , &major);
335- if (status != CUSPARSE_STATUS_SUCCESS ) { return false ; }
336- status = cusparseGetProperty (libraryPropertyType_t::MINOR_VERSION , &minor);
337- if (status != CUSPARSE_STATUS_SUCCESS ) { return false ; }
338- return (major > 12 ) || (major == 12 && minor >= 8 );
339- }
340-
341- cusparseStatus_t cusparse_spmvop_buffer_size (cusparseHandle_t handle,
342- cusparseOperation_t opA,
343- cusparseSpMatDescr_t matA,
344- cusparseDnVecDescr_t vecX,
345- cusparseDnVecDescr_t vecY,
346- cusparseDnVecDescr_t vecZ,
347- cudaDataType computeType,
348- size_t * bufferSize)
349- {
350- #if CUOPT_CUSPARSE_VER_12_8_UP
351- if (is_cusparse_runtime_12_8_or_newer ()) {
352- static const auto fn = dynamic_load_runtime::function<cusparseSpMVOp_bufferSize_12_8_sig>(
353- " cusparseSpMVOp_bufferSize" );
354- return (*fn)(
355- handle, opA, matA, vecX, vecY, vecZ, computeType, CUSPARSE_SPMVOP_ALG_DEFAULT , bufferSize);
356- }
357- #endif // CUOPT_CUSPARSE_VER_12_8_UP
358- static const auto fn =
359- dynamic_load_runtime::function<cusparseSpMVOp_bufferSize_12_7_sig>(" cusparseSpMVOp_bufferSize" );
360- return (*fn)(handle, opA, matA, vecX, vecY, vecZ, computeType, bufferSize);
361- }
362-
363- } // namespace
364-
365307cusparseStatus_t cusparse_spmvop_descr_wrapper_t::dlsym_create (cusparseHandle_t handle,
366308 cusparseSpMVOpDescr_t* descr,
367309 cusparseOperation_t opA,
@@ -372,17 +314,10 @@ cusparseStatus_t cusparse_spmvop_descr_wrapper_t::dlsym_create(cusparseHandle_t
372314 cudaDataType computeType,
373315 void * buffer)
374316{
375- #if CUOPT_CUSPARSE_VER_12_8_UP
376- if (is_cusparse_runtime_12_8_or_newer ()) {
377- static const auto fn = dynamic_load_runtime::function<cusparseSpMVOp_createDescr_12_8_sig>(
378- " cusparseSpMVOp_createDescr" );
379- return (*fn)(
380- handle, descr, opA, matA, vecX, vecY, vecZ, computeType, CUSPARSE_SPMVOP_ALG_DEFAULT , buffer);
381- }
382- #endif // CUOPT_CUSPARSE_VER_12_8_UP
383- static const auto fn = dynamic_load_runtime::function<cusparseSpMVOp_createDescr_12_7_sig>(
384- " cusparseSpMVOp_createDescr" );
385- return (*fn)(handle, descr, opA, matA, vecX, vecY, vecZ, computeType, buffer);
317+ static const auto fn =
318+ dynamic_load_runtime::function<cusparseSpMVOp_createDescr_sig>(" cusparseSpMVOp_createDescr" );
319+ return (*fn)(
320+ handle, descr, opA, matA, vecX, vecY, vecZ, computeType, CUSPARSE_SPMVOP_ALG_DEFAULT , buffer);
386321}
387322
388323cusparseStatus_t cusparse_spmvop_descr_wrapper_t::dlsym_destroy (cusparseSpMVOpDescr_t descr)
@@ -504,7 +439,7 @@ void cusparse_spmvop_run(cusparseHandle_t handle,
504439 RAFT_CUSPARSE_TRY (cusparseSetStream (handle, stream));
505440 RAFT_CUSPARSE_TRY ((*func)(handle, plan, alpha, beta, vecX, vecY, vecZ));
506441}
507- #endif // CUOPT_CUSPARSE_VER_12_7_UP
442+ #endif // CUOPT_CUSPARSE_VER_12_8_UP
508443
509444// This cstr is used in pdhg, step size strategy and in cuPDLPx infeasible detection
510445// A_T is owned by the scaled problem
@@ -1428,38 +1363,36 @@ bool is_cusparse_runtime_mixed_precision_supported()
14281363
14291364bool is_cusparse_runtime_spmvop_supported ()
14301365{
1431- #if CUOPT_CUSPARSE_VER_12_7_UP
1432- #if !CUOPT_CUSPARSE_VER_12_8_UP
1433- // Headers older than cuSPARSE 12.8 (CUDA Toolkit 13.3) cannot name the newer SpMVOp
1434- // descriptor types, so do not call the older 12.7 signature against a 12.8+ runtime.
1435- if (is_cusparse_runtime_12_8_or_newer ()) { return false ; }
1436- #endif // !CUOPT_CUSPARSE_VER_12_8_UP
1437- // Probe the runtime to ensure cusparseSpMVOp is supported.
1366+ #if CUOPT_CUSPARSE_VER_12_8_UP
1367+ // Probe the runtimme to ensure cusparseSpMVOp is supported
14381368 static const bool supported =
14391369 dynamic_load_runtime::function<cusparseSpMVOp_sig>(" cusparseSpMVOp" ).has_value ();
14401370 return supported;
14411371#else
14421372 return false ;
1443- #endif // CUOPT_CUSPARSE_VER_12_7_UP
1373+ #endif // CUOPT_CUSPARSE_VER_12_8_UP
14441374}
14451375
14461376// Creates SpMVOp plans. Must be called after scale_problem() so plans use the scaled matrix.
14471377template <typename i_t , typename f_t >
14481378void cusparse_view_t <i_t , f_t >::create_spmv_op_plans(bool is_reflected)
14491379{
1450- #if CUOPT_CUSPARSE_VER_12_7_UP
1380+ #if CUOPT_CUSPARSE_VER_12_8_UP
14511381 if (!is_cusparse_runtime_spmvop_supported () || !(std::is_same_v<f_t , double >)) { return ; }
1382+ static const auto buffer_size =
1383+ dynamic_load_runtime::function<cusparseSpMVOp_bufferSize_sig>(" cusparseSpMVOp_bufferSize" );
14521384 CUSPARSE_CHECK (cusparseSetStream (handle_ptr_->get_cusparse_handle (), handle_ptr_->get_stream ()));
14531385 // Prepare buffers for At_y SpMVOp
14541386 size_t buffer_size_transpose = 0 ;
1455- RAFT_CUSPARSE_TRY (cusparse_spmvop_buffer_size (handle_ptr_->get_cusparse_handle (),
1456- CUSPARSE_OPERATION_NON_TRANSPOSE ,
1457- A_T ,
1458- dual_solution,
1459- current_AtY,
1460- current_AtY,
1461- CUDA_R_64F ,
1462- &buffer_size_transpose));
1387+ RAFT_CUSPARSE_TRY ((*buffer_size)(handle_ptr_->get_cusparse_handle (),
1388+ CUSPARSE_OPERATION_NON_TRANSPOSE ,
1389+ A_T ,
1390+ dual_solution,
1391+ current_AtY,
1392+ current_AtY,
1393+ CUDA_R_64F ,
1394+ CUSPARSE_SPMVOP_ALG_DEFAULT ,
1395+ &buffer_size_transpose));
14631396 buffer_transpose_spmvop.resize (buffer_size_transpose, handle_ptr_->get_stream ());
14641397
14651398 spmv_op_descr_A_t_.create (handle_ptr_->get_cusparse_handle (),
@@ -1476,14 +1409,15 @@ void cusparse_view_t<i_t, f_t>::create_spmv_op_plans(bool is_reflected)
14761409 // Only prepare buffers for A_x if we are using reflected_halpern
14771410 if (is_reflected) {
14781411 size_t buffer_size_non_transpose = 0 ;
1479- RAFT_CUSPARSE_TRY (cusparse_spmvop_buffer_size (handle_ptr_->get_cusparse_handle (),
1480- CUSPARSE_OPERATION_NON_TRANSPOSE ,
1481- A,
1482- reflected_primal_solution,
1483- dual_gradient,
1484- dual_gradient,
1485- CUDA_R_64F ,
1486- &buffer_size_non_transpose));
1412+ RAFT_CUSPARSE_TRY ((*buffer_size)(handle_ptr_->get_cusparse_handle (),
1413+ CUSPARSE_OPERATION_NON_TRANSPOSE ,
1414+ A,
1415+ reflected_primal_solution,
1416+ dual_gradient,
1417+ dual_gradient,
1418+ CUDA_R_64F ,
1419+ CUSPARSE_SPMVOP_ALG_DEFAULT ,
1420+ &buffer_size_non_transpose));
14871421 buffer_non_transpose_spmvop.resize (buffer_size_non_transpose, handle_ptr_->get_stream ());
14881422
14891423 spmv_op_descr_A_.create (handle_ptr_->get_cusparse_handle (),
@@ -1497,7 +1431,7 @@ void cusparse_view_t<i_t, f_t>::create_spmv_op_plans(bool is_reflected)
14971431
14981432 spmv_op_plan_A_.create (handle_ptr_->get_cusparse_handle (), spmv_op_descr_A_);
14991433 }
1500- #endif // CUOPT_CUSPARSE_VER_12_7_UP
1434+ #endif // CUOPT_CUSPARSE_VER_12_8_UP
15011435}
15021436
15031437#if MIP_INSTANTIATE_FLOAT || PDLP_INSTANTIATE_FLOAT
0 commit comments