Skip to content

Commit 0ad46ce

Browse files
Add first cut of new automatic thread splitting.
Signed-off-by: Samuel K. Gutierrez <[email protected]>
1 parent 71fff93 commit 0ad46ce

6 files changed

+61
-64
lines changed

include/quo-vadis-pthread.h

+3
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ typedef enum {
5050
QV_POLICY_CHOOSE = 5
5151
} qv_pthread_placement_t;
5252

53+
int *const QV_PTHREAD_SCOPE_SPLIT_PACKED = (int *)0x00000001;
54+
int *const QV_PTHREAD_SCOPE_SPLIT_SPREAD = (int *)0x00000002;
55+
5356
/**
5457
* Similar to pthread_create(3).
5558
*/

src/quo-vadis-pthread.cc

+40-6
Original file line numberDiff line numberDiff line change
@@ -59,22 +59,51 @@ qvi_pthread_start_routine(
5959
pthread_exit(ret);
6060
}
6161

62+
static int
63+
split_color_fixup(
64+
int *kcolors,
65+
int k,
66+
std::vector<int> &kcolorsp
67+
) {
68+
int real_color = QV_SCOPE_SPLIT_UNDEFINED;
69+
70+
if (kcolors == QV_PTHREAD_SCOPE_SPLIT_PACKED) {
71+
real_color = QV_SCOPE_SPLIT_PACKED;
72+
}
73+
else if (kcolors == QV_PTHREAD_SCOPE_SPLIT_SPREAD) {
74+
real_color = QV_SCOPE_SPLIT_SPREAD;
75+
}
76+
// Nothing to do. An automatic coloring was not requested.
77+
if (real_color == QV_SCOPE_SPLIT_UNDEFINED) {
78+
return QV_SUCCESS;
79+
}
80+
// An automatic coloring was requested.
81+
kcolorsp.resize(k);
82+
std::fill(kcolorsp.begin(), kcolorsp.end(), real_color);
83+
return QV_SUCCESS;
84+
}
85+
6286
int
6387
qv_pthread_scope_split(
6488
qv_scope_t *scope,
6589
int npieces,
66-
int *color_array,
67-
int nthreads,
90+
int *kcolors,
91+
int k,
6892
qv_scope_t ***subscopes
6993
) {
70-
const bool invalid_args = !scope || npieces < 0 || !color_array ||
71-
nthreads < 0 || !subscopes;
94+
const bool invalid_args = !scope || npieces < 0 || !kcolors ||
95+
k < 0 || !subscopes;
7296
if (qvi_unlikely(invalid_args)) {
7397
return QV_ERR_INVLD_ARG;
7498
}
7599
try {
100+
std::vector<int> color_fixup;
101+
const int rc = split_color_fixup(kcolors, k, color_fixup);
102+
if (qvi_unlikely(rc != QV_SUCCESS)) return rc;
103+
// Set the colors array to the appropriate data.
104+
int *kcolorsp = color_fixup.empty() ? kcolors : color_fixup.data();
76105
return scope->thread_split(
77-
npieces, color_array, nthreads, QV_HW_OBJ_LAST, subscopes
106+
npieces, kcolorsp, k, QV_HW_OBJ_LAST, subscopes
78107
);
79108
}
80109
qvi_catch_and_return();
@@ -92,7 +121,12 @@ qv_pthread_scope_split_at(
92121
return QV_ERR_INVLD_ARG;
93122
}
94123
try {
95-
return scope->thread_split_at(type, kcolors, k, subscopes);
124+
std::vector<int> color_fixup;
125+
const int rc = split_color_fixup(kcolors, k, color_fixup);
126+
if (qvi_unlikely(rc != QV_SUCCESS)) return rc;
127+
// Set the colors array to the appropriate data.
128+
int *kcolorsp = color_fixup.empty() ? kcolors : color_fixup.data();
129+
return scope->thread_split_at(type, kcolorsp, k, subscopes);
96130
}
97131
qvi_catch_and_return();
98132
}

src/qvi-pthread.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ qvi_pthread_group::split(
268268
// One thread creates the child group. The rest wait for the instance and
269269
// later grab a pointer to their group based on the sub-group index.
270270
if (sginfo.rank == qvi_subgroup_info::master_rank) {
271-
// Recall this is the parent group.
271+
// Recall that 'this' is the parent group.
272272
rc = qvi_new(&ichild, this, sginfo);
273273
barrier();
274274
}

src/qvi-scope.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -315,11 +315,11 @@ qv_scope::thread_split(
315315
int
316316
qv_scope::thread_split_at(
317317
qv_hw_obj_type_t type,
318-
int *kgroup_ids,
318+
int *kcolors,
319319
uint_t k,
320320
qv_scope_t ***kchildren
321321
) {
322-
return thread_split(hwpool_nobjects(type), kgroup_ids, k, type, kchildren);
322+
return thread_split(hwpool_nobjects(type), kcolors, k, type, kchildren);
323323
}
324324

325325
/*

src/qvi-scope.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ struct qv_scope {
122122
int
123123
thread_split_at(
124124
qv_hw_obj_type_t type,
125-
int *kgroup_ids,
125+
int *kcolors,
126126
uint_t k,
127127
qv_scope_t ***kchildren
128128
);

tests/test-pthread-split.c

+14-54
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ thread_work(
3333
ctu_scope_report(scope, "thread_scope_in_thread_routine");
3434
ctu_emit_task_bind(scope);
3535
#endif
36-
3736
if (rank == 0) {
3837
printf("[%d] ============ Splitting thread scopes in two\n", tid);
3938
}
@@ -81,38 +80,21 @@ main(void)
8180

8281
ctu_emit_task_bind(base_scope);
8382
//
84-
// Test qv_pthread_scope_split
83+
// Test qv_pthread_scope_split()
8584
//
8685
const int npieces = 2;
8786
const int nthreads = ncores;
88-
int colors[nthreads];
8987

9088
printf(
9189
"[%d] Testing thread_scope_split (nthreads=%d, npieces=%d)\n",
9290
tid, nthreads, npieces
9391
);
9492

95-
for (int i = 0 ; i < nthreads ; i++) {
96-
colors[i] = i % npieces;
97-
}
98-
#if 0
99-
printf("Manual values: ");
100-
for (int i = 0 ; i < nthreads ; i++) {
101-
printf("val[%i]:%i | ",i,colors[i]);
102-
}
103-
printf("\n");
104-
#endif
105-
106-
#if 0
107-
fprintf(stdout,"Filled values: ");
108-
for (int i = 0 ; i < nthreads ; i++) {
109-
fprintf(stdout,"val[%i]:%i | ",i,colors[i]);
110-
}
111-
fprintf(stdout,"\n");
112-
#endif
11393
qv_scope_t **th_scopes = NULL;
11494
rc = qv_pthread_scope_split(
115-
base_scope, npieces, colors, nthreads, &th_scopes
95+
base_scope, npieces,
96+
QV_PTHREAD_SCOPE_SPLIT_PACKED,
97+
nthreads, &th_scopes
11698
);
11799
if (rc != QV_SUCCESS) {
118100
ers = "qv_pthread_scope_split() failed";
@@ -152,39 +134,18 @@ main(void)
152134
ers = "qv_pthread_scope_free() failed";
153135
ctu_panic("%s (rc=%s)", ers, qv_strerr(rc));
154136
}
155-
156-
#if 0
137+
//
157138
//Test qv_pthread_scope_split_at
158-
nthreads = 2 * ncores;
159-
160-
printf("[%d] Testing thread_scope_split_at (nthreads=%i)\n", tid, nthreads);
161-
162-
int colors2[nthreads];
163-
for (int i = 0 ; i < nthreads ; i++) {
164-
colors2[i] = i % ncores;
165-
}
166-
167-
fprintf(stdout,"Array values :");
168-
for (int i = 0 ; i < nthreads ; i++) {
169-
fprintf(stdout,"val[%i]: %i |",i,colors2[i]);
170-
}
171-
fprintf(stdout,"\n");
172-
173-
174-
rc = qv_pthread_colors_fill(colors2, nthreads, QV_POLICY_PACKED, stride, ncores);
175-
if (rc != QV_SUCCESS) {
176-
ers = "qv_pthread_colors_fill() failed";
177-
ctu_panic("%s (rc=%s)", ers, qv_strerr(rc));
178-
}
179-
180-
fprintf(stdout,"Array values :");
181-
for (int i = 0 ; i < nthreads ; i++) {
182-
fprintf(stdout,"val[%i]: %i |",i,colors2[i]);
183-
}
184-
fprintf(stdout,"\n");
139+
//
140+
printf(
141+
"[%d] Testing thread_scope_split_at (nthreads=%d, npieces=%d)\n",
142+
tid, nthreads, npieces
143+
);
185144

186145
rc = qv_pthread_scope_split_at(
187-
mpi_scope, QV_HW_OBJ_CORE, colors2, nthreads, &th_scopes
146+
base_scope, QV_HW_OBJ_CORE,
147+
QV_PTHREAD_SCOPE_SPLIT_PACKED,
148+
nthreads, &th_scopes
188149
);
189150
if (rc != QV_SUCCESS) {
190151
ers = "qv_pthread_scope_split_at() failed";
@@ -215,14 +176,13 @@ main(void)
215176
}
216177
//fprintf(stdout,"Thread finished with '%s'\n", (char *)ret);
217178
}
218-
219179
// Clean up.
220180
rc = qv_pthread_scopes_free(nthreads, th_scopes);
221181
if (rc != QV_SUCCESS) {
222182
ers = "qv_pthread_scope_free() failed";
223183
ctu_panic("%s (rc=%s)", ers, qv_strerr(rc));
224184
}
225-
#endif
185+
226186
rc = qv_scope_free(base_scope);
227187
if (rc != QV_SUCCESS) {
228188
ers = "qv_scope_free() failed";

0 commit comments

Comments
 (0)