@@ -516,7 +516,7 @@ static inline void ompi_op_reduce(ompi_op_t * op, const void *source,
516516 ompi_datatype_t * dtype )
517517{
518518 MPI_Fint f_dtype , f_count ;
519- int count = full_count ;
519+ int count = ( int ) full_count ;
520520
521521 /*
522522 * Call the reduction function. Two dimensions: a) if both the op
@@ -556,6 +556,34 @@ static inline void ompi_op_reduce(ompi_op_t * op, const void *source,
556556 return ;
557557 }
558558
559+ /*
560+ * If the full_count is > INT_MAX and the user supplied reduction
561+ * op is not of the full count type, we need to do
562+ * in iterations of counts <= INT_MAX.
563+ */
564+
565+ if ( OPAL_UNLIKELY ((full_count > INT_MAX ) &&
566+ (0 == (op -> o_flags & OMPI_OP_FLAGS_BIGCOUNT ))) ) {
567+ size_t done_count = 0 , shift ;
568+ int iter_count ;
569+ ptrdiff_t ext , lb ;
570+
571+ ompi_datatype_get_extent (dtype , & lb , & ext );
572+
573+ while (done_count < full_count ) {
574+ if (done_count + INT_MAX > full_count ) {
575+ iter_count = full_count - done_count ;
576+ } else {
577+ iter_count = INT_MAX ;
578+ }
579+ shift = done_count * ext ;
580+ // Recurse one level in iterations of 'int'
581+ ompi_op_reduce (op , (const char * )source + shift , (char * )target + shift , iter_count , dtype );
582+ done_count += iter_count ;
583+ }
584+ return ;
585+ }
586+
559587 /* User-defined function */
560588 if (0 != (op -> o_flags & OMPI_OP_FLAGS_FORTRAN_FUNC )) {
561589 f_dtype = OMPI_INT_2_FINT (dtype -> d_f_to_c_index );
0 commit comments