UCP: Implementation of routine to query datatype attributes#8150
UCP: Implementation of routine to query datatype attributes#8150yosefe merged 1 commit intoopenucx:masterfrom
Conversation
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
48e3dbb to
28be810
Compare
|
Since nobody reviewed yet, I rebased to have the new ucp.h with |
|
@rakhmets, can you please review? |
| *datatype_p = ucp_dt_from_generic(dt_gen); | ||
| dt_gen->ops = *ops; | ||
| dt_gen->context = context; | ||
| dt_gen->packed_size = 0; |
There was a problem hiding this comment.
btw, maybe use SIZE_MAX as an indication of uninitialized type? I'd guess that zero-sized derived datatype is possible in theory, but currently query routine will always return UNSUPPORTED for such types.
There was a problem hiding this comment.
I actually used 0 to allow checks like if (attr->packed_size), but I changed it according to your suggestion, so we can also use SIZE_MAX now. I think that a datatype of size 0 does not make sense. If you still think it's better to initialize with SIZE_MAX, I am okay doing so, especially since I probably don't know all the data descriptions/types that are possible with UCX.
There was a problem hiding this comment.
i think having 0-sized type is more likely than SIZE_MAX, so I'd change it.
@yosefe, wdyt?
There was a problem hiding this comment.
I don't think we can assume that packed size of bufferA is same as packed size of bufferB. The packing logic depends on the contents - consider compression.
Perhaps dt_query API should also accept buffer pointer and count.
There was a problem hiding this comment.
You are right, if we consider compression, the packed size of a generic datatype can be different depending on the data. I thought of packing more like C struct packing/padding.
This basically means that the packed size can be different for each call to a communication function. Hence, the query would always return the same value for contiguous datatypes and could return different values after each communication operation for the same generic datatype. The function then still serves its purpose and allows me to find out how much data is transferred. However, this behavior has to be documented and I've to check what changes are needed in the implementation.
There was a problem hiding this comment.
yes, IMO we should pass buffer and count and return the packed size of that buffer.
we need to decide on this before the release that freezes the API.
@shamisp WDYT?
There was a problem hiding this comment.
Has a decision been made here? I agree with @yosefe that passing buffer and count and return the buffer size fits better to the existing UCP datatypes. The user of ucp_dt_query can still pass "1" as count to return the size of one element.
There was a problem hiding this comment.
@yosefe This is good question actually. In our recent research work the size also depended on the target EP in addition to buffer and count - think about DT conversion across different architectures. Do we use this for any of the MPI call ? I don't think MPI passes buffer (I have to double check)
There was a problem hiding this comment.
I did not come across the EP during implementation. The current implementation basically returns the last datatype size, which has been determined during the regular message/transfer preparation. This should include the EP.
| * @return Error code as defined by @ref ucs_status_t | ||
| */ | ||
| ucs_status_t ucp_dt_query(ucp_datatype_t datatype, ucp_datatype_attr_t *attr); | ||
| ucs_status_t ucp_dt_query(ucp_datatype_t datatype, const void *buffer, |
There was a problem hiding this comment.
@shamisp do you think it would be better to make buffer,count parameters optional using a struct?
PS. This API was not released yet
There was a problem hiding this comment.
@rdietric let's move buffer,count into ucp_datatype_attr_t (with corresponding flags)
| return UCS_ERR_INVALID_PARAM; | ||
| case UCP_DATATYPE_GENERIC: | ||
| dt_gen = ucp_dt_to_generic(datatype); | ||
| ucs_assert(NULL != dt_gen); |
There was a problem hiding this comment.
return invalid param if NULL
There was a problem hiding this comment.
return invalid param if NULL
f933aeb to
8b4bffb
Compare
| * @return Error code as defined by @ref ucs_status_t | ||
| */ | ||
| ucs_status_t ucp_dt_query(ucp_datatype_t datatype, ucp_datatype_attr_t *attr); | ||
| ucs_status_t ucp_dt_query(ucp_datatype_t datatype, const void *buffer, |
There was a problem hiding this comment.
@rdietric let's move buffer,count into ucp_datatype_attr_t (with corresponding flags)
| */ | ||
| enum ucp_datatype_attr_field { | ||
| UCP_DATATYPE_ATTR_FIELD_PACKED_SIZE = UCS_BIT(0) /**< packed datatype size */ | ||
| /** Query the packed datatype size. */ |
There was a problem hiding this comment.
/** @ref ucp_datatype_attr_t::packed_size field is queried. */
| * @brief UCP datatype attributes | ||
| * | ||
| * This structure provides attributes that can be queried for a UCP datatype. | ||
| * This structure provides attributes of a UCP datatype. |
There was a problem hiding this comment.
This structure provides attributes for querying a UCP datatype
@tonycurtis WDYT?
| * Number of elements in @a buffer. | ||
| * This value is optional. | ||
| * If @ref UCP_DATATYPE_ATTR_FIELD_COUNT is not set in @ref field_mask, the | ||
| * value of this field defaults to 0. |
There was a problem hiding this comment.
maybe the default should be 1?
There was a problem hiding this comment.
I am not sure. 0 should basically signal that this value is not set (invalid). 0 would also enable zero-initialization of all fields after packed_size.
Since you bring this up, what do we expect the packed_size to be for a contiguous datatype, when count >1 is passed? count * sizeOfDatatype?
There was a problem hiding this comment.
IMO the default should be "1" and for contig type we should multiply it by sizeOfDatatype
@shamisp WDYT?
| return UCS_ERR_INVALID_PARAM; | ||
| case UCP_DATATYPE_GENERIC: | ||
| dt_gen = ucp_dt_to_generic(datatype); | ||
| ucs_assert(NULL != dt_gen); |
There was a problem hiding this comment.
return invalid param if NULL
|
LGTM besides :
|
| case UCP_DATATYPE_CONTIG: | ||
| attr->packed_size = ucp_contig_dt_elem_size(datatype); | ||
|
|
||
| if (attr->field_mask & UCP_DATATYPE_ATTR_FIELD_COUNT) { |
There was a problem hiding this comment.
we can treat count as default 1 also for generic and iov
There was a problem hiding this comment.
Makes sense and then also fits to the API documentation.
| if (attr->field_mask & UCP_DATATYPE_ATTR_FIELD_COUNT) { | ||
| count = attr->count; | ||
| } |
There was a problem hiding this comment.
don't initialize count during declaration
use UCP_PARAM_VALUE macro
There was a problem hiding this comment.
Ok, UCP_ATTR_VALUE would work with enum ucp_datatype_attr_field. Or should I change attr to param in the enum? It seems to be used almost interchangeable.
|
@tonycurtis @shamisp can you pls review? |
| datatype_attr.buffer = buf; | ||
| datatype_attr.field_mask |= UCP_DATATYPE_ATTR_FIELD_BUFFER; |
| datatype_attr.buffer = buf; | ||
| datatype_attr.field_mask |= UCP_DATATYPE_ATTR_FIELD_BUFFER; |
Changed the API so that buffer and count are optional input arguments via the `ucp_datatype_attr` parameter. Also added a unit test.
d238631 to
0718940
Compare
|
I squashed the commits and all checks have passed. |
|
👍 |
| * @brief UCP datatype attributes | ||
| * | ||
| * This structure provides attributes that can be queried for a UCP datatype. | ||
| * This structure provides attributes of a UCP datatype. |
| * Number of elements in @a buffer. | ||
| * This value is optional. | ||
| * If @ref UCP_DATATYPE_ATTR_FIELD_COUNT is not set in @ref field_mask, the | ||
| * value of this field defaults to 1. |
There was a problem hiding this comment.
would 0 be a better default size for a NULL buffer?
There was a problem hiding this comment.
We've had this topic before (#8150 (comment)). Intuitively, I would also have taken 0, but there are also arguments for 1. I do not have a strong opinion on this.
There was a problem hiding this comment.
@tonycurtis @shamisp if the default is 0, it means that if this parameter is not supplied the function will always return 0. and that is essentially as if we're making this parameter mandatory.
IMO it should be 1 by default since the neutral value w.r.t. multiplication is 1.
There was a problem hiding this comment.
If @ref UCP_DATATYPE_ATTR_FIELD_COUNT is not set in @ref field_mask, the function executes the query for a single ucp_datatype_t . I think this sounds better. @tonycurtis ?
There was a problem hiding this comment.
@yosefe , @tonycurtis approved the above and I think it sounds better while does not change the meaning
|
On Sep 4, 2022, at 11:29 AM, Yossi Itigin ***@***.***> wrote:
@yosefe commented on this pull request.
In src/ucp/api/ucp.h <#8150 (comment)>:
> */
- size_t packed_size;
+ const void *buffer;
+
+ /**
+ * Number of elements in @A buffer.
+ * This value is optional.
+ * If @ref UCP_DATATYPE_ATTR_FIELD_COUNT is not set in @ref field_mask, the
+ * value of this field defaults to 1.
@tonycurtis <https://github.com/tonycurtis> @shamisp <https://github.com/shamisp> if the default is 0, it means that if this parameter is not supplied the function will always return 0. and that is essentially as if we're making this parameter mandatory.
IMO it should be 1 by default since the neutral value w.r.t. multiplication is 1.
A NULL pointer encapsulating data of length 1 seems weird. Maybe the semantics of this routine need to be revisited?
tony
|
The pointer itself is not mandatory for calculating the size. The single mandatory parameter is the datatype itself, and count=1 by default would mean to calculate the size of a single element. |
@shamisp @tonycurtis WDYT? |
|
Yeah, that sounds good
…On Wed, Sep 21, 2022 at 7:53 PM Pavel Shamis (Pasha) < ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/ucp/api/ucp.h
<#8150 (comment)>:
> */
- size_t packed_size;
+ const void *buffer;
+
+ /**
+ * Number of elements in @A buffer.
+ * This value is optional.
+ * If @ref UCP_DATATYPE_ATTR_FIELD_COUNT is not set in @ref field_mask, the
+ * value of this field defaults to 1.
If @ref UCP_DATATYPE_ATTR_FIELD_COUNT is not set in @ref field_mask, the
function executes the query for a single ucp_datatype_t . I think this
sounds better. @tonycurtis <https://github.com/tonycurtis> ?
—
Reply to this email directly, view it on GitHub
<#8150 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABB6C2CHAD6ILYZGNKVOGRDV7ONXBANCNFSM5UB5KY4A>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
What
Implementation of the the routine
ucp_dt_queryaccording to PR #8120. Currently, the only datatype attribute to query is the packed size.Why ?
The size of a message or data transfer is a performance-relevant information. Performance tools should be able to query this information similar to
MPI_Type_sizeto query the size of any MPI datatypeHow ?
For contig data types, the return value of
ucp_contig_dt_elem_size()provides the element size.For generic data types, a field
packed_sizehas been added toucp_dt_generic_t, which is set with the user-defined pack routine. When the size of the generic data type is queried, the value of this field is used. All other data types are not supported andUCS_ERR_INVALID_PARAMis returned asucs_status_t.A unit tests verifies the expected behavior for contig, iov and generic data types. It is also checked that
UCS_ERR_UNSUPPORTEDis returned, if the generic datatype is queried before packing.