Skip to content

Commit

Permalink
prov/cxi: Added collectives logical operators
Browse files Browse the repository at this point in the history
Signed-off-by: Sean Pollard <sean.pollard@hpe.com>
  • Loading branch information
Sean Pollard committed Feb 26, 2025
1 parent 19f453d commit c97c15f
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 0 deletions.
35 changes: 35 additions & 0 deletions prov/cxi/src/cxip_coll.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,9 @@ void _dump_red_pkt(struct red_pkt *pkt, char *dir)
#define COLL_OPCODE_BIT_AND 0x01
#define COLL_OPCODE_BIT_OR 0x02
#define COLL_OPCODE_BIT_XOR 0x03
#define COLL_OPCODE_LOG_AND 0x04
#define COLL_OPCODE_LOG_OR 0x05
#define COLL_OPCODE_LOG_XOR 0x06
#define COLL_OPCODE_INT_MIN 0x10
#define COLL_OPCODE_INT_MAX 0x11
#define COLL_OPCODE_INT_MINMAXLOC 0x12
Expand Down Expand Up @@ -401,11 +404,17 @@ void cxip_coll_populate_opcodes(void)
_int8_16_32_op_to_opcode[FI_BOR] = COLL_OPCODE_BIT_OR;
_int8_16_32_op_to_opcode[FI_BAND] = COLL_OPCODE_BIT_AND;
_int8_16_32_op_to_opcode[FI_BXOR] = COLL_OPCODE_BIT_XOR;
_int8_16_32_op_to_opcode[FI_LOR] = COLL_OPCODE_LOG_OR;
_int8_16_32_op_to_opcode[FI_LAND] = COLL_OPCODE_LOG_AND;
_int8_16_32_op_to_opcode[FI_LXOR] = COLL_OPCODE_LOG_XOR;

/* operations supported by 32, 16, and 8 bit unsigned int operands */
_uint8_16_32_op_to_opcode[FI_BOR] = COLL_OPCODE_BIT_OR;
_uint8_16_32_op_to_opcode[FI_BAND] = COLL_OPCODE_BIT_AND;
_uint8_16_32_op_to_opcode[FI_BXOR] = COLL_OPCODE_BIT_XOR;
_uint8_16_32_op_to_opcode[FI_LOR] = COLL_OPCODE_LOG_OR;
_uint8_16_32_op_to_opcode[FI_LAND] = COLL_OPCODE_LOG_AND;
_uint8_16_32_op_to_opcode[FI_LXOR] = COLL_OPCODE_LOG_XOR;

/* operations supported by 64 bit signed int operands */
_int64_op_to_opcode[FI_MIN] = COLL_OPCODE_INT_MIN;
Expand All @@ -417,6 +426,9 @@ void cxip_coll_populate_opcodes(void)
_uint64_op_to_opcode[FI_BOR] = COLL_OPCODE_BIT_OR;
_uint64_op_to_opcode[FI_BAND] = COLL_OPCODE_BIT_AND;
_uint64_op_to_opcode[FI_BXOR] = COLL_OPCODE_BIT_XOR;
_uint64_op_to_opcode[FI_LOR] = COLL_OPCODE_LOG_OR;
_uint64_op_to_opcode[FI_LAND] = COLL_OPCODE_LOG_AND;
_uint64_op_to_opcode[FI_LXOR] = COLL_OPCODE_LOG_XOR;

/* operations supported by 64 bit double operands */
_flt_op_to_opcode[FI_MIN] = COLL_OPCODE_FLT_MINNUM;
Expand All @@ -429,6 +441,9 @@ void cxip_coll_populate_opcodes(void)
_cxi_op_to_redtype[COLL_OPCODE_BIT_OR] = REDTYPE_INT;
_cxi_op_to_redtype[COLL_OPCODE_BIT_AND] = REDTYPE_INT;
_cxi_op_to_redtype[COLL_OPCODE_BIT_XOR] = REDTYPE_INT;
_cxi_op_to_redtype[COLL_OPCODE_LOG_OR] = REDTYPE_INT;
_cxi_op_to_redtype[COLL_OPCODE_LOG_AND] = REDTYPE_INT;
_cxi_op_to_redtype[COLL_OPCODE_LOG_XOR] = REDTYPE_INT;
_cxi_op_to_redtype[COLL_OPCODE_INT_MIN] = REDTYPE_INT;
_cxi_op_to_redtype[COLL_OPCODE_INT_MAX] = REDTYPE_INT;
_cxi_op_to_redtype[COLL_OPCODE_INT_SUM] = REDTYPE_INT;
Expand Down Expand Up @@ -1502,6 +1517,26 @@ static void _reduce(struct cxip_coll_data *accum,
accum->intval.ival[i] ^= coll_data->intval.ival[i];
/* overflow not possible */
break;
case COLL_OPCODE_LOG_AND:
for (i = 0; i < 4; i++)
accum->intval.ival[i] = (accum->intval.ival[i] &&
coll_data->intval.ival[i]);
/* overflow not possible */
break;
case COLL_OPCODE_LOG_OR:
for (i = 0; i < 4; i++)
accum->intval.ival[i] = (accum->intval.ival[i] ||
coll_data->intval.ival[i]);
/* overflow not possible */
break;
case COLL_OPCODE_LOG_XOR:
for (i = 0; i < 4; i++)
accum->intval.ival[i] = ((accum->intval.ival[i] &&
!coll_data->intval.ival[i])
|| (!accum->intval.ival[i] &&
coll_data->intval.ival[i]));
/* overflow not possible */
break;
case COLL_OPCODE_INT_MIN:
for (i = 0; i < 4; i++)
if (accum->intval.ival[i] > coll_data->intval.ival[i])
Expand Down
70 changes: 70 additions & 0 deletions prov/cxi/test/coll.c
Original file line number Diff line number Diff line change
Expand Up @@ -1869,6 +1869,76 @@ Test(coll_reduce_ops, bxor)
STDCLEANUP
}

/* Test logical OR */
Test(coll_reduce_ops, lor)
{
STDINTSETUP
/* max nodes == 32 under NETSIM */
for (i = 0; i < nodes; i++) {
data[i].ival[0] = 1 << i;
data[i].ival[1] = i << 2*i;
data[i].ival[2] = i;
data[i].ival[3] = 2*i;
}
memcpy(&check, &data[0], sizeof(check));
for (i = 1; i < nodes; i++)
for (j = 0; j < 4; j++)
check.ival[j] = (check.ival[j] || data[i].ival[j]);

ret = _allreduceop(FI_LOR, FI_UINT64, 0L, data, rslt, 4, context);
cr_assert(!ret, "_allreduceop() failed\n");
ret = _check_ival(nodes, rslt, &check);
cr_assert(!ret, "compare failed\n");
STDCLEANUP
}

/* Test logical AND */
Test(coll_reduce_ops, land)
{
STDINTSETUP
/* max nodes == 32 under NETSIM */
for (i = 0; i < nodes; i++) {
data[i].ival[0] = ~(1 << i);
data[i].ival[1] = ~(i << 2*i);
data[i].ival[2] = ~i;
data[i].ival[3] = ~(2*i);
}
memcpy(&check, &data[0], sizeof(check));
for (i = 1; i < nodes; i++)
for (j = 0; j < 4; j++)
check.ival[j] = (check.ival[j] && data[i].ival[j]);

ret = _allreduceop(FI_LAND, FI_UINT64, 0L, data, rslt, 4, context);
cr_assert(!ret, "_allreduceop() failed = %d\n", ret);
ret = _check_ival(nodes, rslt, &check);
cr_assert(!ret, "compare failed\n");
STDCLEANUP
}

/* Test logical XOR */
Test(coll_reduce_ops, lxor)
{
STDINTSETUP
/* max nodes == 32 under NETSIM */
for (i = 0; i < nodes; i++) {
data[i].ival[0] = 1 << i;
data[i].ival[1] = ~(i << i);
data[i].ival[2] = i;
data[i].ival[3] = ~i;
}
memcpy(&check, &data[0], sizeof(check));
for (i = 1; i < nodes; i++)
for (j = 0; j < 4; j++)
check.ival[j] = ((check.ival[j] && !data[i].ival[j]) ||
(!check.ival[j] && data[i].ival[j]));

ret = _allreduceop(FI_LXOR, FI_UINT64, 0L, data, rslt, 4, context);
cr_assert(!ret, "_allreduceop() failed\n");
ret = _check_ival(nodes, rslt, &check);
cr_assert(!ret, "compare failed\n");
STDCLEANUP
}

/* Tests int64 minimum */
Test(coll_reduce_ops, imin)
{
Expand Down

0 comments on commit c97c15f

Please sign in to comment.