Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UCS/CONFIG/PARSER: Handle NULL entries in sparse arrays #10305

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/ucp/core/ucp_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,13 @@ const char *ucp_object_versions[] = {
};

const char *ucp_extra_op_attr_flags_names[] = {
[UCP_OP_ATTR_INDEX(UCP_OP_ATTR_FLAG_NO_IMM_CMPL)] = "no_imm_cmpl",
tvegas1 marked this conversation as resolved.
Show resolved Hide resolved
[UCP_OP_ATTR_INDEX(UCP_OP_ATTR_FLAG_FAST_CMPL)] = "fast_cmpl",
[UCP_OP_ATTR_INDEX(UCP_OP_ATTR_FLAG_FORCE_IMM_CMPL)] = "force_imm_cmpl",
[UCP_OP_ATTR_INDEX(UCP_OP_ATTR_FLAG_MULTI_SEND)] = "multi_send",
NULL
[UCP_OP_ATTR_INDEX(UCP_OP_ATTR_FLAG_MULTI_SEND)] = "multi_send"
};

const ucs_config_flags_args_t ucp_extra_op_attr_flags_args = {
.args = ucp_extra_op_attr_flags_names,
.args_size = ucs_static_array_size(ucp_extra_op_attr_flags_names)
};

static UCS_CONFIG_DEFINE_ARRAY(memunit_sizes, sizeof(size_t),
Expand Down Expand Up @@ -542,9 +544,9 @@ static ucs_config_field_t ucp_context_config_table[] = {
{"EXTRA_OP_ATTR_FLAGS", "",
"Additional send/receive operation flags that are added for each request"
"in addition to what is set explicitly by the user. \n"
"Possible values are: no_imm_cmpl, fast_cmpl, force_imm_cmpl, multi_send.",
"Possible values are: fast_cmpl, multi_send.",
ucs_offsetof(ucp_context_config_t, extra_op_attr_flags),
UCS_CONFIG_TYPE_BITMAP(ucp_extra_op_attr_flags_names)},
UCS_CONFIG_TYPE_FLAGS((const void *)&ucp_extra_op_attr_flags_args)},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add few unit tests for this new option (test_config.cc)

brminich marked this conversation as resolved.
Show resolved Hide resolved

{NULL}
};
Expand Down
8 changes: 1 addition & 7 deletions src/ucp/core/ucp_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,8 @@ enum {
UCP_TL_RSC_FLAG_AUX = UCS_BIT(0)
};

#define UCP_OP_ATTR_INDEX_MASK (UCP_OP_ATTR_FLAG_NO_IMM_CMPL | \
UCP_OP_ATTR_FLAG_FORCE_IMM_CMPL | \
UCP_OP_ATTR_FLAG_FAST_CMPL | \
UCP_OP_ATTR_FLAG_MULTI_SEND)

#define UCP_OP_ATTR_INDEX(_op_attr_flag) \
(ucs_ilog2(ucp_proto_select_op_attr_pack((_op_attr_flag), \
UCP_OP_ATTR_INDEX_MASK)))
(ucs_ilog2(ucp_proto_select_op_attr_pack((_op_attr_flag))))


typedef struct ucp_context_config {
Expand Down
5 changes: 3 additions & 2 deletions src/ucp/proto/proto_select.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@


/* Pack operation attributes from uint32_t to a uint8_t */
#define ucp_proto_select_op_attr_pack(_op_attr, _mask) \
(((_op_attr) & (_mask)) / UCP_PROTO_SELECT_OP_ATTR_BASE)
#define ucp_proto_select_op_attr_pack(_op_attr) \
(((_op_attr) & (UCP_PROTO_SELECT_OP_ATTR_MASK)) / \
UCP_PROTO_SELECT_OP_ATTR_BASE)


typedef struct {
Expand Down
2 changes: 1 addition & 1 deletion src/ucp/proto/proto_select.inl
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ static UCS_F_ALWAYS_INLINE void ucp_proto_select_param_init_common(
* supported */
select_param->op_id_flags = op_id | op_flags;
select_param->op_attr = ucp_proto_select_op_attr_pack(
op_attr_mask, UCP_PROTO_SELECT_OP_ATTR_MASK);
op_attr_mask);
select_param->dt_class = dt_class;
select_param->mem_type = mem_info->type;
select_param->sys_dev = mem_info->sys_dev;
Expand Down
2 changes: 1 addition & 1 deletion src/ucp/rndv/rndv_ppln.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ ucp_proto_rndv_ppln_probe(const ucp_proto_init_params_t *init_params)
sel_param.op_id_flags = ucp_proto_select_op_id(select_param) |
UCP_PROTO_SELECT_OP_FLAG_PPLN_FRAG;
sel_param.op_attr = ucp_proto_select_op_attr_pack(
UCP_OP_ATTR_FLAG_MULTI_SEND, UCP_PROTO_SELECT_OP_ATTR_MASK);
UCP_OP_ATTR_FLAG_MULTI_SEND);

proto_select = ucp_proto_select_get(worker, init_params->ep_cfg_index,
init_params->rkey_cfg_index,
Expand Down
84 changes: 84 additions & 0 deletions src/ucs/config/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,37 @@ static void __print_table_values(char * const *table, char *buf, size_t max)
*buf = '[';
}

static void __print_sparse_table_values(const char * const *table,
size_t args_size, char *buf,
size_t max)
{
char *ptr = buf, *end = buf + max - 1;
size_t i;

if (ptr < end) {
*ptr++ = '[';
}

/* Ignores NULL entries */
for (i = 0; (i < args_size) && (ptr < end); ++i) {
if (table[i] == NULL) {
continue;
}

if ((ptr > (buf + 1)) && (ptr < end)) {
*ptr++ = '|';
}

ptr += snprintf(ptr, end - ptr, "%s", table[i]);
}

if (ptr < end) {
*ptr++ = ']';
}

*ptr = '\0';
}

void ucs_config_help_enum(char *buf, size_t max, const void *arg)
{
__print_table_values(arg, buf, max);
Expand Down Expand Up @@ -475,6 +506,59 @@ void ucs_config_help_bitmap(char *buf, size_t max, const void *arg)
__print_table_values(arg, buf + strlen(buf), max - strlen(buf));
}

int ucs_config_sscanf_flags(const char *buf, void *dest, const void *arg)
{
char *str = ucs_strdup(buf, "config_sscanf_flags_str");
ucs_config_flags_args_t *args = (ucs_config_flags_args_t*)arg;
char *p, *saveptr;
int ret, i;

if (str == NULL) {
return 0;
}

ret = 1;
*((uint64_t*)dest) = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would propose to create a variable to avoid repetitive casts:
uint64_t *flags = dest;

p = strtok_r(str, ",", &saveptr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider using ucs_string_split

while (p != NULL) {
i = ucs_string_find_in_sparse_list(p, (const char**)args->args,
args->args_size);
if (i < 0) {
ret = 0;
break;
}

ucs_assertv(i < (sizeof(uint64_t) * 8), "bit %d overflows for '%s'", i,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe use CHAR_BIT const instead of 8

p);
*((uint64_t*)dest) |= UCS_BIT(i);
p = strtok_r(NULL, ",", &saveptr);
}

ucs_free(str);
return ret;
}

int ucs_config_sprintf_flags(char *buf, size_t max, const void *src,
const void *arg)
{
ucs_config_flags_args_t *args = (ucs_config_flags_args_t*)arg;
ucs_flags_str(buf, max, *((uint64_t*)src), (const char**)args->args);
return 1;
}

void ucs_config_help_flags(char *buf, size_t max, const void *arg)
{
ucs_config_flags_args_t *args = (ucs_config_flags_args_t*)arg;
int written = snprintf(buf, max, "comma-separated list of: ");

if ((written < 0) || (written >= max)) {
return;
}

__print_sparse_table_values(args->args, args->args_size, buf + written,
max - written);
}

int ucs_config_sscanf_bitmask(const char *buf, void *dest, const void *arg)
{
int ret = sscanf(buf, "%u", (unsigned*)dest);
Expand Down
14 changes: 14 additions & 0 deletions src/ucs/config/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ typedef struct ucs_config_bw_spec {
} ucs_config_bw_spec_t;


typedef struct ucs_config_flags_args {
const char **args;
size_t args_size;
} ucs_config_flags_args_t;

#define UCS_CONFIG_EMPTY_GLOBAL_LIST_ENTRY \
{ \
.name = "", \
Expand Down Expand Up @@ -232,6 +237,10 @@ int ucs_config_sscanf_bitmap(const char *buf, void *dest, const void *arg);
int ucs_config_sprintf_bitmap(char *buf, size_t max, const void *src, const void *arg);
void ucs_config_help_bitmap(char *buf, size_t max, const void *arg);

int ucs_config_sscanf_flags(const char *buf, void *dest, const void *arg);
int ucs_config_sprintf_flags(char *buf, size_t max, const void *src, const void *arg);
void ucs_config_help_flags(char *buf, size_t max, const void *arg);

int ucs_config_sscanf_bitmask(const char *buf, void *dest, const void *arg);
int ucs_config_sprintf_bitmask(char *buf, size_t max, const void *src, const void *arg);

Expand Down Expand Up @@ -384,6 +393,11 @@ void ucs_config_help_generic(char *buf, size_t max, const void *arg);
ucs_config_help_bitmap, ucs_config_doc_nop, \
t}

#define UCS_CONFIG_TYPE_FLAGS(t) {ucs_config_sscanf_flags, ucs_config_sprintf_flags, \
ucs_config_clone_uint, ucs_config_release_nop, \
ucs_config_help_flags, ucs_config_doc_nop, \
t}

#define UCS_CONFIG_TYPE_BITMASK {ucs_config_sscanf_bitmask, ucs_config_sprintf_bitmask, \
ucs_config_clone_uint, ucs_config_release_nop, \
ucs_config_help_generic, ucs_config_doc_nop, \
Expand Down
20 changes: 20 additions & 0 deletions src/ucs/sys/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,26 @@ ssize_t ucs_string_find_in_list(const char *str, const char **string_list,
return -1;
}

ssize_t ucs_string_find_in_sparse_list(const char *str,
const char **string_list,
size_t str_array_size)
{
size_t i;

/* Ignores NULL entries */
for (i = 0; i < str_array_size; ++i) {
if (string_list[i] == NULL) {
continue;
}
if (strcmp(string_list[i], str) == 0) {
return i;
}
}

return -1;
}


char* ucs_string_split(char *str, const char *delim, int count, ...)
{
char *p = str;
Expand Down
12 changes: 12 additions & 0 deletions src/ucs/sys/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,18 @@ const char* ucs_mask_str(uint64_t mask, ucs_string_buffer_t *strb);
ssize_t ucs_string_find_in_list(const char *str, const char **string_list,
int case_sensitive);

/**
* Find a string in an array of strings with NULL entries.
*
* @param str String to search for.
* @param string_list Array of strings.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'd call it str_array to be consistent with str_array_size

* @param str_array_size Number of strings in the array.
*
* @return Index of the string in the array, or -1 if not found.
*/
ssize_t ucs_string_find_in_sparse_list(const char *str,
const char **string_list,
size_t str_array_size);

/**
* Split a string to tokens. The given string is modified in-place.
Expand Down
Loading