Skip to content

Commit 9b52949

Browse files
authored
[CICD] Add datatype/op CLI support to perf tests (#505)
1 parent de06640 commit 9b52949

14 files changed

Lines changed: 343 additions & 515 deletions

test/include/perf_common.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ struct PerfContext {
2525
uint64_t splitMask;
2626
int localRegister;
2727

28+
// Datatype/op for current iteration
29+
flagcxDataType_t datatype;
30+
flagcxRedOp_t op;
31+
2832
// FlagCX handles
2933
flagcxDeviceHandle_t devHandle;
3034
flagcxComm_t comm;
@@ -78,15 +82,19 @@ void perfTeardown(PerfContext &ctx);
7882
void perfWarmup(PerfContext &ctx, PerfCollFn fn);
7983

8084
// Run the benchmark size sweep with timing, MPI averaging, and
81-
// bandwidth reporting.
85+
// bandwidth reporting. Set iterateOps=false for collectives that don't
86+
// use ctx.op (e.g., allgather, broadcast, sendrecv).
8287
void perfBenchmarkLoop(PerfContext &ctx, PerfCollFn collFn,
8388
PerfBwFactorFn bwFactorFn = nullptr,
8489
PerfDataInitFn dataInitFn = nullptr,
85-
PerfPostIterFn postIterFn = nullptr);
90+
PerfPostIterFn postIterFn = nullptr,
91+
bool iterateOps = true);
8692

8793
// Run the benchmark size sweep with root iteration (for reduce, broadcast,
8894
// scatter, gather). Iterates over roots per size, accumulating BW.
95+
// Set iterateOps=false for collectives that don't use ctx.op.
8996
void perfRootBenchmarkLoop(PerfContext &ctx, PerfRootCollFn collFn,
9097
PerfBwFactorFn bwFactorFn = nullptr,
9198
PerfRootDataInitFn dataInitFn = nullptr,
92-
PerfRootPostIterFn postIterFn = nullptr);
99+
PerfRootPostIterFn postIterFn = nullptr,
100+
bool iterateOps = true);

test/include/tools.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#pragma once
2+
3+
#include "flagcx.h"
14
#include "mpi.h"
25
#include <cstddef>
36
#include <cstdint>
@@ -6,6 +9,21 @@ void initMpiEnv(int argc, char **argv, int &worldRank, int &worldSize,
69
int &proc, int &totalProcs, int &color, MPI_Comm &splitComm,
710
uint64_t splitMask);
811

12+
// Datatype tables (aligned with nccl-tests style)
13+
extern const flagcxDataType_t test_types[];
14+
extern const char *test_typenames[];
15+
extern int test_typenum;
16+
17+
// Reduction op tables
18+
extern const flagcxRedOp_t test_ops[];
19+
extern const char *test_opnames[];
20+
extern int test_opnum;
21+
22+
// Returns index into test_types[], or -1 for "all"
23+
int flagcxStringToType(const char *str);
24+
// Returns index into test_ops[], or -1 for "all"
25+
int flagcxStringToOp(const char *str);
26+
927
class timer {
1028
public:
1129
timer();
@@ -27,6 +45,8 @@ class parser {
2745
int getRootRank() const { return root; }
2846
uint64_t getSplitMask() const { return splitMask; }
2947
int getLocalRegister() const { return localRegister; }
48+
int getDataType() const { return datatype; }
49+
int getOp() const { return op; }
3050

3151
size_t minBytes;
3252
size_t maxBytes;
@@ -37,4 +57,6 @@ class parser {
3757
int root;
3858
uint64_t splitMask;
3959
int localRegister;
40-
};
60+
int datatype = -1; // index into test_types[], or -1 for "all"
61+
int op = -1; // index into test_ops[], or -1 for "all"
62+
};

test/perf/host_api/test_allgather.cpp

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,43 +7,18 @@ static void bufSizeFn(PerfContext &ctx, size_t &sBuf, size_t &rBuf) {
77

88
static void collFn(PerfContext &ctx, size_t count) {
99
flagcxAllGather(ctx.sendbuff, ctx.recvbuff, count / ctx.totalProcs,
10-
flagcxFloat, ctx.comm, ctx.stream);
10+
ctx.datatype, ctx.comm, ctx.stream);
1111
}
1212

1313
static double bwFactorFn(int totalProcs) {
1414
return (double)(totalProcs - 1) / (double)totalProcs;
1515
}
1616

17-
static void dataInitFn(PerfContext &ctx, size_t size, size_t count) {
18-
((float *)ctx.hello)[0] = ctx.proc;
19-
ctx.devHandle->deviceMemcpy(ctx.sendbuff, ctx.hello, size / ctx.totalProcs,
20-
flagcxMemcpyHostToDevice, NULL);
21-
if ((ctx.proc == 0 || ctx.proc == ctx.totalProcs - 1) && ctx.color == 0 &&
22-
ctx.printBuffer) {
23-
printf("sendbuff = ");
24-
printf("%f\n", ((float *)ctx.hello)[0]);
25-
}
26-
}
27-
28-
static void postIterFn(PerfContext &ctx, size_t size, size_t count) {
29-
memset(ctx.hello, 0, size);
30-
ctx.devHandle->deviceMemcpy(ctx.hello, ctx.recvbuff, size,
31-
flagcxMemcpyDeviceToHost, NULL);
32-
if ((ctx.proc == 0 || ctx.proc == ctx.totalProcs - 1) && ctx.color == 0 &&
33-
ctx.printBuffer) {
34-
printf("recvbuff = ");
35-
for (int i = 0; i < ctx.totalProcs; i++) {
36-
printf("%f ", ((float *)ctx.hello)[i * (count / ctx.totalProcs)]);
37-
}
38-
printf("\n");
39-
}
40-
}
41-
4217
int main(int argc, char *argv[]) {
4318
PerfContext ctx;
4419
perfSetup(ctx, argc, argv, bufSizeFn);
4520
perfWarmup(ctx, collFn);
46-
perfBenchmarkLoop(ctx, collFn, bwFactorFn, dataInitFn, postIterFn);
21+
perfBenchmarkLoop(ctx, collFn, bwFactorFn, nullptr, nullptr, false);
4722
perfTeardown(ctx);
4823
return 0;
4924
}

test/perf/host_api/test_allreduce.cpp

Lines changed: 6 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include "perf_common.h"
22

33
static void collFn(PerfContext &ctx, size_t count) {
4-
flagcxAllReduce(ctx.sendbuff, ctx.recvbuff, count, flagcxFloat, flagcxSum,
4+
flagcxAllReduce(ctx.sendbuff, ctx.recvbuff, count, ctx.datatype, ctx.op,
55
ctx.comm, ctx.stream);
66
}
77

@@ -18,97 +18,23 @@ static double bwFactorFn(int totalProcs) {
1818
}
1919

2020
static void dataInitFn(PerfContext &ctx, size_t size, size_t count) {
21+
size_t typeSize = getFlagcxDataTypeSize(ctx.datatype);
22+
memset(ctx.hello, 0, size);
2123
for (size_t i = 0; i < count; i++) {
22-
((float *)ctx.hello)[i] = i % 10 * (1 << ctx.proc);
24+
float val = (float)(i % 10) * (1ULL << (ctx.proc % 30));
25+
memcpy((char *)ctx.hello + i * typeSize, &val,
26+
sizeof(float) < typeSize ? sizeof(float) : typeSize);
2327
}
2428
ctx.devHandle->deviceMemcpy(ctx.sendbuff, ctx.hello, size,
2529
flagcxMemcpyHostToDevice, NULL);
2630
ctx.devHandle->deviceMemcpy(ctx.recvbuff, ctx.hello, size,
2731
flagcxMemcpyHostToDevice, NULL);
28-
if (ctx.color == 0 && ctx.printBuffer) {
29-
printf("rank %d sendbuff = ", ctx.proc);
30-
for (size_t i = 0; i < 10; i++) {
31-
printf("%f ", ((float *)ctx.hello)[i]);
32-
}
33-
printf("\n");
34-
}
3532
}
3633

3734
static void postIterFn(PerfContext &ctx, size_t size, size_t count) {
38-
const char *envLocRed = getenv("FLAGCX_UNIRUNNER_USE_LOCRED");
39-
const char *envRingAG = getenv("FLAGCX_UNIRUNNER_USE_RINGAG");
4035
memset(ctx.hello, 0, size);
4136
ctx.devHandle->deviceMemcpy(ctx.hello, ctx.recvbuff, size,
4237
flagcxMemcpyDeviceToHost, NULL);
43-
if (ctx.color == 0 && ctx.printBuffer) {
44-
printf("rank %d recvbuff = ", ctx.proc);
45-
for (size_t i = 0; i < 10; i++) {
46-
printf("%f ", ((float *)ctx.hello)[i]);
47-
}
48-
printf("\n");
49-
50-
if (envLocRed != NULL && atoi(envLocRed) == 1) {
51-
/* red correctness check */
52-
int redCorrect = 1;
53-
for (size_t i = 0; i < count; i++) {
54-
if (i * ctx.totalProcs / count == (size_t)ctx.proc)
55-
continue;
56-
if (((float *)ctx.hello)[i] != (float)(i % 10 * (1 << ctx.proc))) {
57-
printf("rank %d wrong output at offset %lu, expected %f, got %f\n ",
58-
ctx.proc, i, (float)(i % 10 * (1 << ctx.proc)),
59-
((float *)ctx.hello)[i]);
60-
redCorrect = 0;
61-
break;
62-
}
63-
}
64-
for (size_t i = ctx.proc * count / ctx.totalProcs;
65-
i < (ctx.proc + 1) * count / ctx.totalProcs; i++) {
66-
if (((float *)ctx.hello)[i] !=
67-
(float)(i % 10 * (1 << (ctx.proc + 1)))) {
68-
printf("rank %d wrong output at offset %lu, expected %f, got %f\n",
69-
ctx.proc, i, (float)(i % 10 * (1 << (ctx.proc + 1))),
70-
((float *)ctx.hello)[i]);
71-
redCorrect = 0;
72-
break;
73-
}
74-
}
75-
printf("rank %d reduce correctness = %d\n", ctx.proc, redCorrect);
76-
} else if (envRingAG != NULL && atoi(envRingAG) == 1) {
77-
/* p2p correctness check */
78-
int p2pCorrect = 1;
79-
for (size_t i = 0; i < count; i++) {
80-
if (((float *)ctx.hello)[i] !=
81-
(float)(i % 10 * (1 << (i * ctx.totalProcs / count)))) {
82-
printf("rank %d wrong output at offset %lu, expected %f, got %f\n",
83-
ctx.proc, i,
84-
(float)(i % 10 * (1 << (i * ctx.totalProcs / count))),
85-
((float *)ctx.hello)[i]);
86-
p2pCorrect = 0;
87-
break;
88-
}
89-
}
90-
printf("rank %d p2p correctness = %d\n", ctx.proc, p2pCorrect);
91-
} else {
92-
/* all-reduce correctness check */
93-
int arCorrect = 1;
94-
for (size_t i = 0; i < count; i++) {
95-
if ((i % 10 == 0 && ((float *)ctx.hello)[i] != 0) ||
96-
((float *)ctx.hello)[i] /
97-
(float)(i % 10 * ((1 << ctx.totalProcs) - 1)) >
98-
1 + 1e-5 ||
99-
((float *)ctx.hello)[i] /
100-
(float)(i % 10 * ((1 << ctx.totalProcs) - 1)) <
101-
1 - 1e-5) {
102-
printf("rank %d wrong output at offset %lu, expected %f, got %f\n",
103-
ctx.proc, i, (float)(i % 10 * ((1 << ctx.totalProcs) - 1)),
104-
((float *)ctx.hello)[i]);
105-
arCorrect = 0;
106-
break;
107-
}
108-
}
109-
printf("rank %d all-reduce correctness = %d\n", ctx.proc, arCorrect);
110-
}
111-
}
11238
}
11339

11440
int main(int argc, char *argv[]) {

test/perf/host_api/test_alltoall.cpp

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,48 +2,18 @@
22

33
static void collFn(PerfContext &ctx, size_t count) {
44
flagcxAlltoAll(ctx.sendbuff, ctx.recvbuff, count / ctx.totalProcs,
5-
flagcxFloat, ctx.comm, ctx.stream);
5+
ctx.datatype, ctx.comm, ctx.stream);
66
}
77

88
static double bwFactorFn(int totalProcs) {
99
return (double)(totalProcs - 1) / (double)(totalProcs);
1010
}
1111

12-
static void dataInitFn(PerfContext &ctx, size_t size, size_t count) {
13-
for (int i = 0; i < ctx.totalProcs; i++) {
14-
((float *)ctx.hello)[i * (count / ctx.totalProcs)] = 10 * ctx.proc + i;
15-
}
16-
ctx.devHandle->deviceMemcpy(ctx.sendbuff, ctx.hello, size,
17-
flagcxMemcpyHostToDevice, NULL);
18-
if ((ctx.proc == 0 || ctx.proc == ctx.totalProcs - 1) && ctx.color == 0 &&
19-
ctx.printBuffer) {
20-
printf("sendbuff = ");
21-
for (int i = 0; i < ctx.totalProcs; i++) {
22-
printf("%f ", ((float *)ctx.hello)[i * (count / ctx.totalProcs)]);
23-
}
24-
printf("\n");
25-
}
26-
}
27-
28-
static void postIterFn(PerfContext &ctx, size_t size, size_t count) {
29-
memset(ctx.hello, 0, size);
30-
ctx.devHandle->deviceMemcpy(ctx.hello, ctx.recvbuff, size,
31-
flagcxMemcpyDeviceToHost, NULL);
32-
if ((ctx.proc == 0 || ctx.proc == ctx.totalProcs - 1) && ctx.color == 0 &&
33-
ctx.printBuffer) {
34-
printf("recvbuff = ");
35-
for (int i = 0; i < ctx.totalProcs; i++) {
36-
printf("%f ", ((float *)ctx.hello)[i * (count / ctx.totalProcs)]);
37-
}
38-
printf("\n");
39-
}
40-
}
41-
4212
int main(int argc, char *argv[]) {
4313
PerfContext ctx;
4414
perfSetup(ctx, argc, argv);
4515
perfWarmup(ctx, collFn);
46-
perfBenchmarkLoop(ctx, collFn, bwFactorFn, dataInitFn, postIterFn);
16+
perfBenchmarkLoop(ctx, collFn, bwFactorFn, nullptr, nullptr, false);
4717
perfTeardown(ctx);
4818
return 0;
4919
}

test/perf/host_api/test_alltoallv.cpp

Lines changed: 9 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,14 @@ static void warmupFn(PerfContext &ctx, size_t count) {
5555
AlltoallvData *d = (AlltoallvData *)ctx.userData;
5656
computeCounts(ctx, count / ctx.totalProcs);
5757
flagcxAlltoAllv(ctx.sendbuff, d->hSendcounts, d->hSdispls, ctx.recvbuff,
58-
d->hRecvcounts, d->hRdispls, flagcxFloat, ctx.comm,
58+
d->hRecvcounts, d->hRdispls, ctx.datatype, ctx.comm,
5959
ctx.stream);
6060
}
6161

6262
static void collFn(PerfContext &ctx, size_t count) {
6363
AlltoallvData *d = (AlltoallvData *)ctx.userData;
6464
flagcxAlltoAllv(ctx.sendbuff, d->hSendcounts, d->hSdispls, ctx.recvbuff,
65-
d->hRecvcounts, d->hRdispls, flagcxFloat, ctx.comm,
65+
d->hRecvcounts, d->hRdispls, ctx.datatype, ctx.comm,
6666
ctx.stream);
6767
}
6868

@@ -72,63 +72,26 @@ static double bwFactorFn(int totalProcs) {
7272

7373
static void dataInitFn(PerfContext &ctx, size_t size, size_t count) {
7474
AlltoallvData *d = (AlltoallvData *)ctx.userData;
75+
size_t typeSize = getFlagcxDataTypeSize(ctx.datatype);
7576
size_t perPeer = count / ctx.totalProcs;
7677

78+
memset(ctx.hello, 0, size);
7779
for (int i = 0; i < ctx.totalProcs; i++) {
78-
((float *)ctx.hello)[i * perPeer] = 10 * ctx.proc + i;
80+
float val = (float)(10 * ctx.proc + i);
81+
size_t offset = (size_t)i * perPeer * typeSize;
82+
memcpy((char *)ctx.hello + offset, &val,
83+
sizeof(float) < typeSize ? sizeof(float) : typeSize);
7984
}
8085
ctx.devHandle->deviceMemcpy(ctx.sendbuff, ctx.hello, size,
8186
flagcxMemcpyHostToDevice, NULL);
8287

83-
if ((ctx.proc == 0 || ctx.proc == ctx.totalProcs - 1) && ctx.color == 0 &&
84-
ctx.printBuffer) {
85-
printf("sendbuff = ");
86-
for (int i = 0; i < ctx.totalProcs; i++) {
87-
printf("%f ", ((float *)ctx.hello)[i * perPeer]);
88-
}
89-
printf("\n");
90-
}
91-
9288
computeCounts(ctx, perPeer);
93-
94-
if ((ctx.proc == 0 || ctx.proc == ctx.totalProcs - 1) && ctx.color == 0 &&
95-
ctx.printBuffer) {
96-
printf("hSendcounts = ");
97-
for (int i = 0; i < ctx.totalProcs; i++) {
98-
printf("%ld ", d->hSendcounts[i]);
99-
}
100-
printf("\n");
101-
printf("hRecvcounts = ");
102-
for (int i = 0; i < ctx.totalProcs; i++) {
103-
printf("%ld ", d->hRecvcounts[i]);
104-
}
105-
printf("\n");
106-
printf("hSdispls = ");
107-
for (int i = 0; i < ctx.totalProcs; i++) {
108-
printf("%ld ", d->hSdispls[i]);
109-
}
110-
printf("\n");
111-
printf("hRdispls = ");
112-
for (int i = 0; i < ctx.totalProcs; i++) {
113-
printf("%ld ", d->hRdispls[i]);
114-
}
115-
printf("\n");
116-
}
11789
}
11890

11991
static void postIterFn(PerfContext &ctx, size_t size, size_t count) {
120-
size_t perPeer = count / ctx.totalProcs;
12192
memset(ctx.hello, 0, size);
12293
ctx.devHandle->deviceMemcpy(ctx.hello, ctx.recvbuff, size,
12394
flagcxMemcpyDeviceToHost, NULL);
124-
if ((ctx.proc == 0 || ctx.proc == ctx.totalProcs - 1) && ctx.color == 0 &&
125-
ctx.printBuffer) {
126-
printf("recvbuff = ");
127-
for (int i = 0; i < ctx.totalProcs; i++) {
128-
printf("%f ", ((float *)ctx.hello)[i * perPeer]);
129-
}
130-
printf("\n");
131-
}
13295
}
13396

13497
int main(int argc, char *argv[]) {
@@ -143,7 +106,7 @@ int main(int argc, char *argv[]) {
143106
ctx.userData = &data;
144107

145108
perfWarmup(ctx, warmupFn);
146-
perfBenchmarkLoop(ctx, collFn, bwFactorFn, dataInitFn, postIterFn);
109+
perfBenchmarkLoop(ctx, collFn, bwFactorFn, dataInitFn, postIterFn, false);
147110

148111
free(data.hSendcounts);
149112
free(data.hRecvcounts);

0 commit comments

Comments
 (0)