@@ -290,7 +290,15 @@ template<typename T>
290290class test_allreduce_alg : public test_allreduce <T>
291291{};
292292
293- using test_allreduce_alg_type = ::testing::Types<TypeOpPair<UCC_DT_INT32, sum>>;
293+ // Expanded type list for allreduce algorithm tests to cover more data types and operations
294+ using test_allreduce_alg_type = ::testing::Types<
295+ TypeOpPair<UCC_DT_INT32, sum>,
296+ TypeOpPair<UCC_DT_FLOAT32, sum>,
297+ TypeOpPair<UCC_DT_INT32, prod>,
298+ TypeOpPair<UCC_DT_INT32, max>,
299+ TypeOpPair<UCC_DT_INT32, min>,
300+ TypeOpPair<UCC_DT_FLOAT64, sum>
301+ >;
294302TYPED_TEST_CASE (test_allreduce_alg, test_allreduce_alg_type);
295303
296304TYPED_TEST (test_allreduce_alg, sra_knomial_pipelined) {
@@ -437,6 +445,95 @@ TYPED_TEST(test_allreduce_alg, rab_pipelined) {
437445 }
438446}
439447
448+ TYPED_TEST (test_allreduce_alg, ring) {
449+ int n_procs = 15 ;
450+ // For algorithm selection, using the algorithm name (as used in the other algorithm tests)
451+ ucc_job_env_t env = {{" UCC_CL_BASIC_TUNE" , " inf" },
452+ {" UCC_TL_UCP_ALLREDUCE_ALG" , " ring" }};
453+ UccJob job (n_procs, UccJob::UCC_JOB_CTX_GLOBAL, env);
454+ UccTeam_h team = job.create_team (n_procs);
455+ int repeat = 3 ;
456+ UccCollCtxVec ctxs;
457+ std::vector<ucc_memory_type_t > mt = {UCC_MEMORY_TYPE_HOST};
458+ 459+ if (UCC_OK == ucc_mc_available (UCC_MEMORY_TYPE_CUDA)) {
460+ mt.push_back (UCC_MEMORY_TYPE_CUDA);
461+ }
462+ if (UCC_OK == ucc_mc_available (UCC_MEMORY_TYPE_CUDA_MANAGED)) {
463+ mt.push_back (UCC_MEMORY_TYPE_CUDA_MANAGED);
464+ }
465+ 466+ // Test with various data sizes: small, medium, large
467+ for (auto count : {8 , 65536 , 123567 }) {
468+ for (auto inplace : {TEST_NO_INPLACE, TEST_INPLACE}) {
469+ for (auto m : mt) {
470+ SET_MEM_TYPE (m);
471+ this ->set_inplace (inplace);
472+ this ->data_init (n_procs, TypeParam::dt, count, ctxs, true );
473+ UccReq req (team, ctxs);
474+ 475+ for (auto i = 0 ; i < repeat; i++) {
476+ req.start ();
477+ req.wait ();
478+ EXPECT_EQ (true , this ->data_validate (ctxs));
479+ this ->reset (ctxs);
480+ }
481+ this ->data_fini (ctxs);
482+ }
483+ }
484+ }
485+ }
486+ 487+ TYPED_TEST (test_allreduce_alg, ring_edge_cases) {
488+ // Test with non-power-of-two team sizes and edge cases
489+ for (auto team_size : {3 , 7 , 13 }) {
490+ ucc_job_env_t env = {{" UCC_CL_BASIC_TUNE" , " inf" },
491+ {" UCC_TL_UCP_ALLREDUCE_ALG" , " ring" }};
492+ UccJob job (team_size, UccJob::UCC_JOB_CTX_GLOBAL, env);
493+ UccTeam_h team = job.create_team (team_size);
494+ UccCollCtxVec ctxs;
495+ 496+ // Test edge cases: empty message, single element, and odd sizes
497+ for (auto count : {0 , 1 , 3 , 17 }) {
498+ SET_MEM_TYPE (UCC_MEMORY_TYPE_HOST);
499+ this ->set_inplace (TEST_NO_INPLACE);
500+ this ->data_init (team_size, TypeParam::dt, count, ctxs, false );
501+ UccReq req (team, ctxs);
502+ 503+ req.start ();
504+ req.wait ();
505+ EXPECT_EQ (true , this ->data_validate (ctxs));
506+ this ->data_fini (ctxs);
507+ }
508+ }
509+ }
510+ 511+ TYPED_TEST (test_allreduce_alg, ring_persistent) {
512+ // Test persistent operation - results should be consistent across multiple calls
513+ int n_procs = 8 ;
514+ ucc_job_env_t env = {{" UCC_CL_BASIC_TUNE" , " inf" },
515+ {" UCC_TL_UCP_ALLREDUCE_ALG" , " ring" }};
516+ UccJob job (n_procs, UccJob::UCC_JOB_CTX_GLOBAL, env);
517+ UccTeam_h team = job.create_team (n_procs);
518+ UccCollCtxVec ctxs;
519+ 520+ SET_MEM_TYPE (UCC_MEMORY_TYPE_HOST);
521+ this ->set_inplace (TEST_NO_INPLACE);
522+ // Use a larger buffer for persistent test
523+ size_t count = 1024 ;
524+ this ->data_init (n_procs, TypeParam::dt, count, ctxs, true );
525+ UccReq req (team, ctxs);
526+ 527+ // Run multiple iterations to verify persistence
528+ for (int i = 0 ; i < 5 ; i++) {
529+ req.start ();
530+ req.wait ();
531+ EXPECT_EQ (true , this ->data_validate (ctxs));
532+ this ->reset (ctxs);
533+ }
534+ this ->data_fini (ctxs);
535+ }
536+ 440537#ifdef HAVE_UCX
441538TYPED_TEST (test_allreduce_alg, sliding_window)
442539{
0 commit comments