Skip to content

Commit d60237b

Browse files
Checkpoint first cut at new automatic split policies.
Provides a first-cut at the following automatic scope splitting policies: packed and spread. Signed-off-by: Samuel K. Gutierrez <[email protected]>
1 parent 9de6216 commit d60237b

7 files changed

+96
-102
lines changed

include/quo-vadis-pthread.h

+5-17
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,17 @@ int
6666
qv_pthread_scope_split(
6767
qv_scope_t *scope,
6868
int npieces,
69-
int *color_array,
70-
int nthreads,
71-
qv_scope_t ***subscope
69+
int *kcolors,
70+
int k,
71+
qv_scope_t ***subscopes
7272
);
7373

7474
int
7575
qv_pthread_scope_split_at(
7676
qv_scope_t *scope,
7777
qv_hw_obj_type_t type,
78-
int *color_array,
79-
int nthreads,
78+
int *kcolors,
79+
int k,
8080
qv_scope_t ***subscopes
8181
);
8282

@@ -89,18 +89,6 @@ qv_pthread_scopes_free(
8989
qv_scope_t **scopes
9090
);
9191

92-
/**
93-
* Fills color array used in qv_pthread_scope_split*.
94-
*/
95-
int
96-
qv_pthread_colors_fill(
97-
int *color_array,
98-
int array_size,
99-
qv_pthread_placement_t policy,
100-
int stride,
101-
int npieces
102-
);
103-
10492
#ifdef __cplusplus
10593
}
10694
#endif

include/quo-vadis.h

+4
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ const int QV_SCOPE_SPLIT_UNDEFINED = -1;
132132
*/
133133
const int QV_SCOPE_SPLIT_AFFINITY_PRESERVING = -2;
134134

135+
const int QV_SCOPE_SPLIT_PACKED = -3;
136+
137+
const int QV_SCOPE_SPLIT_SPREAD = -4;
138+
135139
/**
136140
*
137141
*/

src/quo-vadis-pthread.cc

+7-51
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,16 @@ qv_pthread_scope_split(
6565
int npieces,
6666
int *color_array,
6767
int nthreads,
68-
qv_scope_t ***subscope
68+
qv_scope_t ***subscopes
6969
) {
7070
const bool invalid_args = !scope || npieces < 0 || !color_array ||
71-
nthreads < 0 || !subscope;
71+
nthreads < 0 || !subscopes;
7272
if (qvi_unlikely(invalid_args)) {
7373
return QV_ERR_INVLD_ARG;
7474
}
7575
try {
7676
return scope->thread_split(
77-
npieces, color_array, nthreads, QV_HW_OBJ_LAST, subscope
77+
npieces, color_array, nthreads, QV_HW_OBJ_LAST, subscopes
7878
);
7979
}
8080
qvi_catch_and_return();
@@ -84,17 +84,15 @@ int
8484
qv_pthread_scope_split_at(
8585
qv_scope_t *scope,
8686
qv_hw_obj_type_t type,
87-
int *color_array,
88-
int nthreads,
87+
int *kcolors,
88+
int k,
8989
qv_scope_t ***subscopes
9090
) {
91-
if (qvi_unlikely(!scope || !color_array || nthreads < 0 || !subscopes)) {
91+
if (qvi_unlikely(!scope || !kcolors || k < 0 || !subscopes)) {
9292
return QV_ERR_INVLD_ARG;
9393
}
9494
try {
95-
return scope->thread_split_at(
96-
type, color_array, nthreads, subscopes
97-
);
95+
return scope->thread_split_at(type, kcolors, k, subscopes);
9896
}
9997
qvi_catch_and_return();
10098
}
@@ -145,48 +143,6 @@ qv_pthread_scopes_free(
145143
qvi_catch_and_return();
146144
}
147145

148-
int
149-
qv_pthread_colors_fill(
150-
int *color_array,
151-
int array_size,
152-
qv_pthread_placement_t policy,
153-
int stride,
154-
int npieces
155-
) {
156-
const bool invalid_args = !color_array || array_size < 0 ||
157-
stride < 1 || npieces < 1;
158-
if (qvi_unlikely(invalid_args)) return QV_ERR_INVLD_ARG;
159-
// TODO(skg) We should use the mapping algorithms in qvi-map for these. The
160-
// problem is that its interfaces aren't yet suited for this type of
161-
// mapping.
162-
switch(policy) {
163-
case QV_POLICY_PACKED: {
164-
// TODO(skg) This looks more like spread.
165-
for(int idx = 0 ; idx < array_size ; idx++){
166-
// color_array[idx] = (idx+idx*(stride-1))%(npieces);
167-
color_array[idx] = (idx*stride)%(npieces);
168-
}
169-
break;
170-
}
171-
case QV_POLICY_SPREAD: {
172-
return QV_ERR_NOT_SUPPORTED;
173-
}
174-
case QV_POLICY_DISTRIBUTE: {
175-
return QV_ERR_NOT_SUPPORTED;
176-
}
177-
case QV_POLICY_SCATTER: {
178-
return QV_ERR_NOT_SUPPORTED;
179-
}
180-
case QV_POLICY_CHOOSE: {
181-
return QV_ERR_NOT_SUPPORTED;
182-
}
183-
default: {
184-
return QV_ERR_INVLD_ARG;
185-
}
186-
}
187-
return QV_SUCCESS;
188-
}
189-
190146
/*
191147
* vim: ft=cpp ts=4 sts=4 sw=4 expandtab
192148
*/

src/qvi-hwsplit.cc

+52
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,54 @@ qvi_hwsplit::split_affinity_preserving(void)
520520
return split_devices_affinity_preserving();
521521
}
522522

523+
// TODO(skg) Add device splitting.
524+
int
525+
qvi_hwsplit::split_packed(void)
526+
{
527+
// cpusets used for mapping.
528+
qvi_hwloc_cpusets_t cpusets;
529+
// Get the primary cpusets for the mapping.
530+
int rc = primary_cpusets(cpusets);
531+
if (rc != QV_SUCCESS) return rc;
532+
// Maintains the mapping between task (consumer) IDs and resource IDs.
533+
qvi_map_t map;
534+
rc = qvi_map_packed(map, m_group_size, cpusets);
535+
if (rc != QV_SUCCESS) return rc;
536+
// Make sure that we mapped all the tasks. If not, this is a bug.
537+
if (qvi_map_nfids_mapped(map) != m_group_size) {
538+
qvi_abort();
539+
}
540+
qvi_hwloc_t *const hwloc = m_rmi->hwloc();
541+
// Update the hardware pools and colors to reflect the new mapping.
542+
return apply_cpuset_mapping(
543+
hwloc, map, cpusets, m_hwpools, m_colors
544+
);
545+
}
546+
547+
// TODO(skg) Add device splitting.
548+
int
549+
qvi_hwsplit::split_spread(void)
550+
{
551+
// cpusets used for mapping.
552+
qvi_hwloc_cpusets_t cpusets;
553+
// Get the primary cpusets for the mapping.
554+
int rc = primary_cpusets(cpusets);
555+
if (rc != QV_SUCCESS) return rc;
556+
// Maintains the mapping between task (consumer) IDs and resource IDs.
557+
qvi_map_t map;
558+
rc = qvi_map_spread(map, m_group_size, cpusets);
559+
if (rc != QV_SUCCESS) return rc;
560+
// Make sure that we mapped all the tasks. If not, this is a bug.
561+
if (qvi_map_nfids_mapped(map) != m_group_size) {
562+
qvi_abort();
563+
}
564+
qvi_hwloc_t *const hwloc = m_rmi->hwloc();
565+
// Update the hardware pools and colors to reflect the new mapping.
566+
return apply_cpuset_mapping(
567+
hwloc, map, cpusets, m_hwpools, m_colors
568+
);
569+
}
570+
523571
/**
524572
* Takes a vector of colors and clamps their values to [0, ndc)
525573
* in place, where ndc is the number of distinct numbers found in values.
@@ -590,6 +638,10 @@ qvi_hwsplit::split(void)
590638
switch (m_colors[0]) {
591639
case QV_SCOPE_SPLIT_AFFINITY_PRESERVING:
592640
return split_affinity_preserving();
641+
case QV_SCOPE_SPLIT_PACKED:
642+
return split_packed();
643+
case QV_SCOPE_SPLIT_SPREAD:
644+
return split_spread();
593645
default:
594646
rc = QV_ERR_INVLD_ARG;
595647
break;

src/qvi-hwsplit.h

+26-18
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* -*- Mode: C++; c-basic-offset:4; indent-tabs-mode:nil -*- */
22
/*
3-
* Copyright (c) 2021-2024 Triad National Security, LLC
3+
* Copyright (c) 2021-2025 Triad National Security, LLC
44
* All rights reserved.
55
*
66
* This file is part of the quo-vadis project. See the LICENSE file at the
@@ -70,7 +70,32 @@ struct qvi_hwsplit {
7070
std::vector<int> m_colors;
7171
/** Vector of task affinities. */
7272
qvi_hwloc_cpusets_t m_affinities;
73+
/** */
74+
qvi_map_fn_t
75+
affinity_preserving_policy(void) const;
76+
/** */
77+
int
78+
split_affinity_preserving_pass1(void);
79+
/** User-defined split. */
80+
int
81+
split_user_defined(void);
82+
/** Affinity preserving split. */
83+
int
84+
split_affinity_preserving(void);
85+
/** */
86+
int
87+
split_packed(void);
88+
/** */
89+
int
90+
split_spread(void);
91+
/** Straightforward user-defined device splitting. */
92+
int
93+
split_devices_user_defined(void);
94+
/** Affinity preserving device splitting. */
95+
int
96+
split_devices_affinity_preserving(void);
7397
public:
98+
// TODO(skg) Cleanup private, protected, public interfaces.
7499
/** Constructor. */
75100
qvi_hwsplit(void) = default;
76101
/** Constructor. */
@@ -124,26 +149,9 @@ struct qvi_hwsplit {
124149
qvi_hwloc_cpusets_t &result
125150
) const;
126151

127-
qvi_map_fn_t
128-
affinity_preserving_policy(void) const;
129152
/** Releases all devices contained in the hardware split. */
130153
int
131154
release_devices(void);
132-
/** Straightforward user-defined device splitting. */
133-
int
134-
split_devices_user_defined(void);
135-
/** Affinity preserving device splitting. */
136-
int
137-
split_devices_affinity_preserving(void);
138-
/** User-defined split. */
139-
int
140-
split_user_defined(void);
141-
142-
int
143-
split_affinity_preserving_pass1(void);
144-
/** Affinity preserving split. */
145-
int
146-
split_affinity_preserving(void);
147155
/** Splits aggregate scope data. */
148156
int
149157
split(void);

tests/test-mpi-scopes.c

+1-11
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,4 @@
11
/* -*- Mode: C; c-basic-offset:4; indent-tabs-mode:nil -*- */
2-
/*
3-
* Copyright (c) 2020-2024 Triad National Security, LLC
4-
* All rights reserved.
5-
*
6-
* Copyright (c) 2020-2021 Lawrence Livermore National Security, LLC
7-
* All rights reserved.
8-
*
9-
* This file is part of the quo-vadis project. See the LICENSE file at the
10-
* top-level directory of this distribution.
11-
*/
122

133
/**
144
* @file test-scopes-mpi.c
@@ -134,7 +124,7 @@ main(
134124
rc = qv_scope_split(
135125
base_scope,
136126
npieces,
137-
gid,
127+
QV_SCOPE_SPLIT_PACKED,
138128
&sub_scope
139129
);
140130
if (rc != QV_SUCCESS) {

tests/test-pthread-split.c

+1-5
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,7 @@ main(void)
103103
}
104104
printf("\n");
105105
#endif
106-
rc = qv_pthread_colors_fill(colors, nthreads, QV_POLICY_PACKED, stride, npieces);
107-
if (rc != QV_SUCCESS) {
108-
ers = "qv_pthread_colors_fill() failed";
109-
ctu_panic("%s (rc=%s)", ers, qv_strerr(rc));
110-
}
106+
111107
#if 0
112108
fprintf(stdout,"Filled values: ");
113109
for (int i = 0 ; i < nthreads ; i++) {

0 commit comments

Comments
 (0)