DRI Forum Minutes, June 2001 Meeting
Attendance
Murali Beddhu (MPI Softtech)
Ken Cain (Mercury Computer Systems)
Dennis Cottel (SPAWAR)
Zhenqian Cui (MPI Softtech)
Randy Judd (SPAWAR)
Jeremy Kepner (MIT/LL)
Steve Paavola (Sky Computers)
Brian Sroka (MITRE) - host
Chris Young (MPI Softtech)
Legend: Official decisions made at this meeting are shown in bold
and italic format
Agenda
-
Discuss how the voting process (to occur soon) should take place
-
New proposals
-
[Ken]: VSIPL interoperation proposal
-
[Brian, Murali, and Ken]: DRI shortcut functions to reduce lines of code
dedicated to setup
-
Discuss "mini-proposals" (changes to document following May 2001 meeting
that need review by the forum)
-
Discuss the "big picture" issues surfacing for DRI Forum and DRI technology
-
some applications will require dynamic behavior, currently we have only
worked on fixed/planned transfers due to time constraints
-
DRI Forum needs to develop "front matter" so that we clearly communicate
DRI goals
-
Overlapping process groups in data reorgs
-
Do we need a bufferset object or not? (latest status is that recent activity
has removed it from the spec)
-
Data types in DRI (DRI_Dataspec)
-
Accessor routines for the DRI_Blockinfo object
-
Suggested intermediate goal: settle on data distribution and DRI_Blockinfo
portions of the API, and limit "volatility" in the spec to data movement
(buffering)
Discussion
Agenda item #1: discuss how the voting process (to occur soon) should take
place
-
soon, DRI Forum will be in a position to vote on features of DRI 1.0 --
we need to discuss voting procedures for when that occurs
-
ken: indicated that it would be appropriate for a neutral representative
(from government lab or FFRDC) to lead the portions of the forum meetings
involving voting and associated debates
-
steve: suggests that a third party should record the results (associate
each institution with its vote and optionally its comments on the vote)
for inclusion in the minutes - group agrees
-
recall partial list of voting rules as decided in May 2001 meeting:
-
one vote per institution
-
votes are either "agree", "agree with comments", or "disagree with
comments"
Agenda item #4: the big picture for DRI Forum
-
we need to communicate a roadmap of where DRI is going (in 1.0, and beyond
1.0)
-
describe the whole problem space (perhaps in rewritten preface section
of the document) and show what we address with DRI 1.0, and where we're
going with DRI 1.1 and beyond - group agrees this is important to include
in DRI 1.0 document
-
increasing importance of late binding and dynamic design of applications
that needs to be reflected in DRI
-
DRI Forum has agreed in earlier meetings that early and late binding should
be supported in the MPI binding -- we just have not tackled that part of
the specification yet
-
DRI Forum needs to demonstrate that late binding is compatible and feasible
in the DRI framework
-
may have to wait until DRI 1.1 because the current effort is understaffed
-
pragmatic approach is to solve the first logical "half" of the problem
(early binding / planned-transfer paradigm) with DRI 1.0 and tackle late-binding
and other aspects of dynamic applications for DRI 1.1 and beyond
-
no official resolution
-
ken: a problem is that potential DRI users (the contractor community) is
not participating in the forum (even on the email list if travel budgets
are a concern)
-
contractor participation is critical to getting the requirements right
-
DRI Forum needs to develop "front matter" so that we clearly communicate
DRI promise, goals
-
jeremy: expressed concerns about the current set of DRI documentation
-
too much emphasis on pure technical information, need more front matter
to show to potential sponsors of DRI activities (e.g., reference implementation,
funding/supporting forum participants, etc.)
-
need to emphasize projected benefits of DRI (in terms of lines of code,
$$ savings to programs, etc.)
-
ken: After May 2001 meeting, Anna Rounbehler provided us with a bunch of
questions that we should incorporate into a "Frequently Asked Questions"
list. We will post answers to a FAQ on www.data-re.org (we'll make
it easily accessible from the front page). That will at
least give us a start at defining the problem space, and DRI's (current+future)
mapping onto that space
-
jeremy: indicated an interest in leveraging DRI Forum's body of information
on the data partitioning problem in the emerging HPEC-SI (DOD high performance
embedded software initiative) program
-
open discussion followed
-
ken: requested help from MIT/LL and MITRE to demonstrate "projections"
of applications onto DRI (e.g., how do typical SAR/STAP/hyperspectral imaging/etc.
applications map to DRI?).
-
jeremy: suggested that such help may be possible from MIT/LL, also volunteered
to help review any additional "front matter" presentations/documents that
the DRI Forum produces
Agenda item #3: Discuss "mini-proposals" (changes to document following
May 2001 meeting that need review by the forum)
-
Mini-proposal - pre-defined objects, etc. naming convention
-
steve: suggests naming the objects to indicate more closely what actually
occurs when you use them (e.g., DRI_NO_OVERLAP is better than DRI_OVERLAP_DEFAULT)
-
Group reviews the pre-defined objects in the spec, recommends these
name changes
-
DRI_LAYOUT_ORDER_DEFAULT ==> DRI_ORDER_NOPREFERENCE
-
DRI_DIST_GROUPDIMS_DEFAULT ==> DRI_GROUPDIMS_NOPREFERENCE
-
DRI_LAYOUT_ORDER_GDO_DEFAULT ==> DRI_ORDER_GLOBALDATA
-
DRI_LAYOUT_ALIGN_ALL_DEFAULT ==> DRI_ALIGN_NOPREFERENCE
-
DRI_DIST_GROUPDIMS_ALL_DEFAULT ==> DRI_GROUPDIMS_ALLNOPREFERENCE
-
DRI_LAYOUT_DEFAULT ==> DRI_LAYOUT_GLOBALDATA
-
DRI_OVERLAP_DEFAULT ==> DRI_OVERLAP_NONE
-
DRI_PARTITION_BLOCK_DEFAULT ==> DRI_PARTITION_BLOCK
-
DRI_REORG_DEFAULT ==> THERE IS NO SUCH THING!!!!! REMOVE!
-
mini-proposal: rename DRI_NO_OVERLAP DRI_OVERLAP_DEFAULT (just a subcase
of above)
-
mini-proposal: C binding for DRI_Overlap_create (ovr_type should not be
a pointer arg)
-
Cui: this approach should also apply to all input arguments in the
C language binding (we will have "handles" , not pointers)
-
group agrees
-
miscellaneous: naming convention for object types:
-
DRI_Global_Data ==> DRI_Global_data
-
DRI_Overlap_Type ==> DRI_Overlap_type
-
or just use DRI_Globaldata and DRI_Overlaptype format
-
group lukewarmly agrees to the "no underscore" format
-
mini-proposal: make calling DRI_Distribution_create while not being
a member of the process set (provided as input parameter) illegal
-
mini-proposal: make implementing DRI_Dataspec optional (either use supporting
middleware types or implement DRI_Dataspec yourself). Function signatures
are flexible:
-
This also applies to how we handle DRI_Groups
-
1st approach: force implementation to typedef DRI_Group and DRI_Dataspec
appropriately
-
2nd approach: leave it implementation-dependent, and describe the minimal
set of operations
-
dennis: would really like "fixed" function signatures, and force the first
approach on implementations
-
jon: we voted against element sizes before (as alternative to real data
types)
-
group decides to use the first (typedef) approach
-
group agrees that DRI_Group_import should go away
-
group also agrees that DRI_Group_destroy goes away
-
dennis: note that it is still possible for implementations to define their
own DRI_Group (instead of just typedeffing), and add (non-standard) DRI_Group
functions, if they really do need to be distinct from the supporting environment's
capabilities.
Agenda item #2: discuss new proposals
-
Shortcut functions and objects proposal [authors: Brian, Murali,
and Ken]
-
This refers to some offline work to produce shortcut functions. Ken embedded
the results in a draft version of the DRI document, but this was done very
late (just before the meeting), and this version of the document has not
been posted to www.data-re.org. The shortcut ideas in the proposal are
summarized in a handout, described next.
-
Group reviews a hardcopy handout that shows a progression of ideas and
possible "shortcut" approaches (generic shortcut techniques shown
in the context of how it impacts a 2D cornerturn application fragment)
-
See the minutes "appendix" at the bottom of this document for the full
text of the handout
-
example #1: shows the 2D cornerturn example using the June 2001 version
of the DRI API (this is better than what is in Annex D of the document,
which is out of date)
-
example #2: incorporates the use of new (multi-dimensional) default DRI_Layout
and array of DRI_Partition constructs.
-
example #3: incorporates the creation of the DRI_Global_data object as
a built in feature of a new DRI_Distribution_create_simple shortcut function
-
example #4: attempts further simplification for clique/SPMD data redistribution
setup by making
-
a single DRI_Distribution create call (that produces 2 DRI_Distribution
objects, one for each "side" of the clique/SPMD redistribution)
-
a single DRI_Reorg create call (that produces the 2 corresponding DRI_Reorg
objects)
-
a single DRI_Reorg_getput call (that performs communication in both directions,
equivalent to a DRI_Reorg_put followed by a DRI_Reorg_get -- similar in
spirit to MPI_Sendrecv)
-
Jon: notes that DRI_Reorg_get_blockinfo call is missing in examples.
-
Jon: make sure that people who read DRI spec and in particular all of these
shortcut examples know that this is not only a convenient expression of
the 2D cornerturn, but applies to many more general redistribution scenarios
too.
-
Evaluation of example #2 in the handout
-
group changes notation to DRI_PARTITON_2D_BB, DRI_PARTITION_2D_BW,
DRI_PARTITION_2D_WW, etc. (B= block, W = whole)
-
can also get rid of 2D, 3D distinction in the pre-defined construct
names
-
DRI_LAYOUT_PACKED_01, DRI_LAYOUT_PACKED_10, etc.
-
Expand proposal to allow DRI_LAYOUT_PACKED_0, DRI_LAYOUT_PACKED_01,
... (this can apply to any global data >= 2 dimensions in size. If actual
#dimensions is larger than the # specified in the pre-defined objects,
it is equivalent to a nopreference in the higher global data dimensions)
-
Do we use similar semi-specified approaches with DRI_PARTITION_ shortcuts?
NO! You must specify B or W in all dimensions
-
Steve: would like a DRI_PARTITION shortcut that specifies W in most
contiguous dimension, B in all others. Putting this in journal of development
for now, not putting in the API.
-
Evaluation of example #3 in the handout (eliminating gdo create call and
absorbing into Distribution_create)
-
dennis and brian: don't like removing Global_Data_create from the
fundamental sequence of setup calls -- may lead to confusion
-
group agrees
-
Evaluation of example #4 in the handout (optimizing SPMD with single Distribution_create,
single Reorg_create, and single getput)
-
Steve: alternative to specifying pairs of attributes (one per DRI_Reorg
object to be created), just create a DRI_Distribution_cornerturn_create
that uses reasonable defaults (e.g., for layouts) instead of requiring
user to explicitly specify those properties.
-
DRI_Reorg_create_trans (drinet, name, nrows, ncols, datatype, numbufs,
group, &reorg_send, &reorg_recv)
-
Returns reorg_send, reorg_recv, then user must DRI_Reorg_destroy both at
the end
-
There is an identical signature (and functionality) for DRI_Reorg_create_cornerturn
(so that trans and cornerturn "terminology" are both supported)
-
So, what are these functions equivalent to?
-
<for offline exercise?>
-
what does it mean for the num_buffers property of each reorg? we
only have one numbuffers argument. The policy here is to apply numbuffers
to BOTH channels (they share the buffers)
-
get/put semantics are:
-
DRI_Reorg_get_buffer(reorg_send, &send_buf);
-
<produce the send buf>
-
DRI_Reorg_put_buffer(reorg_send,, &send_buf);
-
DRI_Reorg_get_buffer(reorg_recv, &recv_buf);
-
<consume the received buffer>
-
DRI_Reorg_put_buffer(reorg_recv, &recv_buf)
-
how to handle "byproduct" objects (that would normally be created by the
user, but are now created by the implementation): when creating the
Reorg objects, this function will COPY all of the information from the
intermediate objects created internally (into those Reorg objects). The
intermediate objects (e.g., DRI_Global_data, DRI_Distribution) can be immediately
destroyed after the DRI_Reorg objects have been created.
-
This goes to the more general statement that all "input" object attribute
(e.g., those that are used to compose DRI_Distribution and DRI_Reorg) can
be destroyed safely by the user, because those "output" objects are self-contained.
For DRI_Group, the rules may change because you are subject to the rules
of the supporting middleware. So in that case it may not be safe for user
to destroy the input group construct.
-
Summary of decisions on "shortcuts": keep generic shortcut
techniques demonstrated in examples 1-2, forego 3-4, and consider (after
this meeting) a single-call setup of a clique/SPMD cornerturn (as discussed
in the example #4 discussion above).
-
VSIPL interoperation proposal [author: Ken]:
-
this refers to the proposal that is embedded in the June 8 2001 version
of the DRI document, posted to www.data-re.org prior to this meeting
-
dennis: what if I want to project multiple views onto the data I get from
a DRI_Reorg?
-
jon: we could avoid the callback approach used in the proposal if we had
a way to return worst case size/shape to the user prior to DRI_connect
(perhaps after Distribution_create?). Then users can manually create the
VSIPL blocks and views associated
-
ken: would like to allow the library to make space/time tradeoffs in terms
of how many VSIPL views/blocks get created
-
sample space/time tradeoff: make one VSIPL view and block, even if there
are multiple buffers associated without the Reorg (this is good for space,
and increases execution time -- requires a VSIPL block "rebind" in the
inner loop -- however Randy indicates that this should be relatively cheap
in practice).
-
(the opposite) space/time tradeoff: create a 1-1 association between VSIPL
blocks and underlying memory buffers associated with the DRI_Reorg. Avoids
VSIPL block "rebind" in the inner loop.
-
ken: what are the first principles? then let's take another pass of the
proposal:
-
need a DRI call that will (in a static data partitioning/redistribution
model) return attributes needed to create VSIPL constructs
-
this may just involve getting DRI_Blockinfo early, and then querying
for these attributes
-
in the inner loop:
-
assumptions:
-
to support multiple views, the user must explicitly call the view create
functions, and there is no opportunity for the DRI implementation to automate
the process
-
also, many in the group feel that it is simpler to an end-user if we avoid
a function pointer (callback) approach
-
the user must call vsip_blockrebind and vsip_blockadmit following
a DRI_Reorg_get_buffer
-
... and must call vsip_blockrelease before a DRI_Reorg_put_buffer
-
User creates all VSIPL blocks and views manually, and early (in the
static model)
-
ok now how should we address the first principles?
-
restriction: this approach only works for static distributions/re-distributions
-
In the outer loop:
-
introduce new function, DRI_Reorg_get_null_buffer (returns a buffer
with no associated storage, but with blockinfo and other information embedded)
-
but, how does the user "dispose" of this object? There is no DRI_Buffer_destroy
call (because they are supposed to be maintained by the DRI_Reorg objects).
-
Solution: DRI_Reorg_destroy will delete the DRI_Buffer object generated
by this call
-
call DRI_Buffer_get_blockinfo() with the returned buffer object
-
call a new method on DRI_Blockinfo to return the VSIPL block/view
create properties
-
requires DRI_Blockinfo accessors (to be defined during this meeting)
-
user manually creates a VSIPL block (bound to no memory at this point)
and one or more VSIPL views.
-
In inner loop (no major DRI-related changes -- this is mostly an
example rather than an interoperation with VSIPL approach)
-
NOTE: WE HAVE CHANGED get_buffer PROTOTYPE TO IMMEDIATELY RETURN
THE BUFFER POINTER)
-
DRI_Reorg_get_buffer(reorg_recv, &recv_buf, &ptr_recv)
-
DRI_Reorg_get_buffer(reorg_send, &send_buf, &ptr_send)
-
<do NOT call> DRI_Buffer_get_ptr (...&send_ptr)
-
<do NOT call> DRI_Buffer_get_ptr (...&recv_ptr)
-
vsip_blockrebind(recv_side_vsip_block, ...)
-
vsip_blockrebind(send_side_vsip_block, ...)
-
vsip_blockadmit(recv_side_vsip_block)
-
vsip_blockadmit(send_side_vsip_block)
-
<call a VSIPL computation function here>
-
vsip_blockrelease(recv_side_vsip_block)
-
vsip_blockrelease(send_side_vsip_block)
-
DRI_Reorg_put_buffer(reorg_send, send_buf)
-
DRI_reorg_put_buffer(reorg_recv, recv_buf)
Agenda item: making it legal (but not required) to allow overlapping process
groups in a data reorganization
-
ken: Implementations must support just clique and pipeline reorganizations,
but also they should also be allowed to support overlapping groups if they
can implement it. It should not be a required capability in the standard,
however.
-
dennis: this means that a portable program would have to use either clique
or strictly disjoint groups (no overlapping). non-portable programs could
use overlapping groups.
-
dennis: the way to say this, if we accept it, is to say that behavior
of overlapping group reorgs is implementation-dependent.
-
group agrees that this is how we will handle the issue
Agenda item: DRI_Dataspec types
-
Steve: proposes we add DRI_CHAR, DRI_UNSIGNED_CHAR, DRI_BYTE, DRI_UNSIGNED
-
DRI_CHAR == vsip_scalar_c == MPI_CHAR == signed char
-
DRI_UNSIGNED_CHAR == vsip_scalar_uc == MPI_UNSIGNED_CHAR =s= unsigned
char
-
DRI_BYTE == nothing in VSIPL == MPI_BYTE == nothing in C language
-
group agrees to these changes
Agenda item: DRI_Blockinfo accessors
-
ndims = DRI_Blockinfo_ndims(blockinfo)
-
offset = DRI_Blockinfo_offset(blockinfo)
-
gidx = DRI_Blockinfo_globaldata_index(blockinfo, dim)
-
dimlen = DRI_Blockinfo_length(blockinfo, dim)
-
dimstride = DRI_Blockinfo_stride(blockinfo, dim)
-
num_overlap = DRI_Blockinfo_left_overlap(blockinfo, dim)
-
lpad = DRI_Blockinfo_left_pad(blockinfo, dim)
-
num_overlap = DRI_Blockinfo_right_overlap(blockinfo, dim)
-
rpad = DRI_Blockinfo_right_pad(blockinfo, dim)
-
these are the only DRI_ functions that do not return an error status,
instead returning the desired quantity. The presumption is that these are
the innermost of inner-loop functions and performance is important, and
errors are unlikely at this stage (many should be caught during the process
of creating the associated DRI_Reorg object).
Agenda item: Do we need a bufferset abstraction (or not)?
-
ken: expressed concern that we might be preventing future innovation within
the DRI framework if we hide bufferset creation from users. By leaving
it out of the spec, you now have to create specific interfaces in order
to set up relationships between different channels (e.g., DRI_Reorg_process_inplace).
We only have process_inplace in the spec right now.
-
it is currently unclear what types of buffered communication is possible
(or not) with DRI in its current form
-
At a minimum, we need to understand (and document in the spec) all reasonable
combinations of these features, and what DRI supports with the current
design:
-
in-place vs. out-of-place processing between data reorganization operations
-
in-place vs. out-of-place data reorganizations (reuse source data buffer
to store result is the motivation)
-
clique/SPMD vs. pipeline
-
consider future features that will involve different types of relationships
between DRI Reorg objects, and whether the current design will be difficult
to extend to support. Examples include:
-
more than 1 destination group (as described by Dennis)
-
dynamically changing the destination and/or source group
-
others
-
Then, decide if the current approach is satisfactory or not
-
Group agrees that Ken should investigate. We will not discuss the
topic in detail during this meeting.
Misc topic: early vs. late binding, and being able to control it at a coarse
level
-
jon: would like a flag / option to appear someplace in the API to
say "I want static behavior". This would allow the implementation to do
the best possible optimization of static problems using early binding.
Could be scoped to entire DRI network, to a distribution, to a reorg, etc.
-
steve: alternate approach is to specify reorg attributes like this in a
config file that references the names of the reorgs
-
ken: portability could be achieved for static vs. non static by having
a flag argument (e.g., 32 bit int) appended to the DRI_Reorg_create
function. The first "standard" option would be to specify static
or not.
-
steve: is in support of adding another argument to whatever is the appropriate
function to specify dynamic or static.
-
group: 32 bit integer flag is appropriate, to allow for extensibility.
DRI_Reorg_create(..., options, &reorg_out)
DRI_REORG_STATIC_ONLY is the only flag value supported at this
time, and we expect to consider dynamic behavior in the future
Misc topic: DRI_Reorg_create functions and how the alloc and dealloc handlers
are presented.
-
Need to make a separate C binding so that the presentation is clearer
(for alloc and dealloc handlers).
Misc topic: we're missing DRI_Buffer_get_blockcount
Misc topic: error code approach
Ken: how do people feel about not specifying ANY specific return codes,
and just providing a function that takes an input parameter (the return
code) and generates a human readable string as a result
Dennis: this won't work when you want to write code that can recover
gracefully from some errors.
dennis: also has an aspect of testability -- to be testable, the library
should return precise error codes for specific erroneous situations that
occur
jon&dennis: we do "all or nothing" with respect to defining (or
not) error codes
Appendix: Shortcut proposal handout
+ I forgot to get blockinfo in my examples.
+ I'm performing a clique 2D cornerturn
0. Yesterday's 2D cornerturn without "default" objects (June 8, 2001 version
of DRI document, Annex D)
(see the DRI document! Note that this example is "out of date" because
it does not use the built-in "default" objects that have been
added
to the API between January 2001 and today)
1. Today's 2D cornerturn using recently-added "default" objects
Specifically, using the following default objects:
+ DRI_PARTITION_BLOCK_DEFAULT
+ DRI_PARTITION_WHOLE
+ DRI_LAYOUT_DEFAULT
+ DRI_DIST_GROUPDIMS_ALL_DEFAULT
#define NDIMS 2
int global_dims[NDIMS] = {1024, 256};
int layout_order_recvside[NDIMS] = {1, 0};
DRI_Network *drinet;
DRI_Global_Data *gdo;
DRI_Group *drigroup;
DRI_Partition parts_sendside[NDIMS];
DRI_Partition parts_recvside[NDIMS];
DRI_Distribution *dist_sendside;
DRI_Distribution *dist_recvside;
DRI_Layout *layout_sendside;
DRI_Layout *layout_recvside;
DRI_Reorg *reorg_sendside;
DRI_Reorg *reorg_recvside;
int reorg_numbufs = 2;
DRI_Buffer *buf_send;
DRI_Buffer *buf_recv;
complex_f *send_ptr;
complex_f *recv_ptr;
const char *chan_string = "transpose";
int main (int argc, char **argv) {
MPI_Init (&argc, &argv);
DRI_Init (&argc, &argv, &drinet);
DRI_Group_import (MPI_COMM_WORLD, &drigroup);
DRI_Global_Data_create(NDIMS, global_dims, &gdo);
parts_sendside[0] = DRI_PARTITION_BLOCK_DEFAULT;
parts_sendside[1] = DRI_PARTITION_WHOLE;
parts_recvside[0] = parts_sendside[1];
parts_recvside[1] = parts_sendside[0];
layout_sendside = DRI_LAYOUT_DEFAULT;
DRI_Layout_create_packed (NDIMS, layout_order_recvside, &layout_recvside);
DRI_Distribution_create (gdo, drigroup, DRI_DIST_GROUPDIMS_ALL_DEFAULT,
parts_sendside, DRI_LAYOUT_DEFAULT, &dist_sendside);
DRI_Distribution_create (gdo, drigroup, DRI_DIST_GROUPDIMS_ALL_DEFAULT,
parts_recvside, layout_recvside, &dist_recvside);
DRI_Reorg_create_system (drinet, DRI_REORG_SEND, chan_string,
DRI_COMPLEX,
dist_sendside, reorg_numbufs, &reorg_sendside);
DRI_Reorg_create_system (drinet, DRI_REORG_RECV, chan_string,
DRI_COMPLEX,
dist_recvside, reorg_numbufs, &reorg_recvside);
DRI_connect(drinet);
/***** Entering the operational loop *****/
for (; ;) {
DRI_Reorg_get_buffer (reorg_sendside, &buf_send);
DRI_Buffer_get_ptr (buf_send, &send_ptr);
/* produce data in the send buffer by using send_ptr
*/
DRI_Reorg_put_buffer (reorg_sendside, buf_send);
DRI_Reorg_get_buffer (reorg_recvside, &buf_recv);
DRI_Buffer_get_ptr (buf_recv, &recv_ptr);
/* consume data in the receive buffer by using recv_ptr
*/
DRI_Reorg_put_buffer (reorg_recvside, buf_recv);
}
DRI_Finalize(drinet);
MPI_Finalize();
} /* end of main() */
2. What we could do with NEW canned multi-dimensional layout and partitioning
de
fault parameters?
Using these EXISTING default objects:
+ DRI_DIST_GROUPDIMS_ALL_DEFAULT
Using these PROPOSED new defaults:
+ DRI_PARTITION_BLOCK_2D_10
+ DRI_PARTITION_BLOCK_2D_01
+ DRI_LAYOUT_PACKED_2D_10
+ DRI_LAYOUT_PACKED_2D_01
+ NOTE: These could be implemented in the following way:
const DRI_Partition DRI_PARTITION_BLOCK_2D_10[2]
= {DRI_PARTITION_BLOCK,
DRI_PARTITION_WHOLE};
const DRI_Partition DRI_PARTITION_BLOCK_2D_01[2]
= {DRI_PARTITION_WHOLE,
DRI_PARTITION_BLOCK};
(*** AND WE COULD DO SIMILAR DEFINITIONS FOR
3D, 4D objects! ***)
DRI_Layout DRI_LAYOUT_PACKED_2D_10;
(at DRI_Init time, DRI_Layout_create_packed
is called by library
with ndims=2, order[] =
{1, 0})
DRI_Layout DRI_LAYOUT_PACKED_2D_01;
(at DRI_Init time, DRI_Layout_create_packed
is called by library
with ndims=2, order[] =
{0, 1})
Assumptions: default layout order follows gdo, no overlap
#define NDIMS 2
int global_dims[NDIMS] = {1024, 256};
DRI_Network *drinet;
DRI_Global_Data *gdo;
DRI_Group *drigroup;
DRI_Distribution *dist_sendside;
DRI_Distribution *dist_recvside;
DRI_Reorg *reorg_sendside;
DRI_Reorg *reorg_recvside;
int reorg_numbufs = 2;
DRI_Buffer *buf_send;
DRI_Buffer *buf_recv;
complex_f *send_ptr;
complex_f *recv_ptr;
const char *chan_string = "transpose";
int main (int argc, char **argv) {
MPI_Init (&argc, &argv);
DRI_Init (&argc, &argv, &drinet);
DRI_Group_import (MPI_COMM_WORLD, &drigroup);
DRI_Global_Data_create(NDIMS, global_dims, &gdo);
DRI_Distribution_create (gdo, drigroup, DRI_DIST_GROUPDIMS_ALL_DEFAULT,
DRI_PARTITION_BLOCK_2D_10, DRI_LAYOUT_PACKED_2D_10,
&dist_sendside);
DRI_Distribution_create (gdo, drigroup, DRI_DIST_GROUPDIMS_ALL_DEFAULT,
DRI_PARTITION_BLOCK_2D_01, DRI_LAYOUT_PACKED_2D_01,
&dist_recvside);
DRI_Reorg_create_system (drinet, DRI_REORG_SEND, chan_string,
DRI_COMPLEX,
dist_sendside, reorg_numbufs, &reorg_sendside);
DRI_Reorg_create_system (drinet, DRI_REORG_RECV, chan_string,
DRI_COMPLEX,
dist_recvside, reorg_numbufs, &reorg_recvside);
DRI_connect(drinet);
/***** Entering the operational loop *****/
for (; ;) {
DRI_Reorg_get_buffer (reorg_sendside, &buf_send);
DRI_Buffer_get_ptr (buf_send, &send_ptr);
/* produce data in the send buffer by using send_ptr
*/
DRI_Reorg_put_buffer (reorg_sendside, buf_send);
DRI_Reorg_get_buffer (reorg_recvside, &buf_recv);
DRI_Buffer_get_ptr (buf_recv, &recv_ptr);
/* consume data in the receive buffer by using recv_ptr
*/
DRI_Reorg_put_buffer (reorg_recvside, buf_recv);
}
DRI_Finalize(drinet);
MPI_Finalize();
} /* end of main() */
3. Adding GDO creation step into the Distribution_create calls.
Using these EXISTING shortcut default objects:
+ NONE!
Using these PROPOSED new defaults:
+ DRI_PARTITION_BLOCK_2D_10
+ DRI_PARTITION_BLOCK_2D_01
+ DRI_LAYOUT_PACKED_2D_10
+ DRI_LAYOUT_PACKED_2D_01
and REMOVING the Global_Data_create, instead moving its input parameters
into an alternative DRI_Distribution_create_simple routine
#define NDIMS 2
int global_dims[NDIMS] = {1024, 256};
DRI_Network *drinet;
DRI_Group *drigroup;
DRI_Distribution *dist_sendside;
DRI_Distribution *dist_recvside;
DRI_Reorg *reorg_sendside;
DRI_Reorg *reorg_recvside;
int reorg_numbufs = 2;
DRI_Buffer *buf_send;
DRI_Buffer *buf_recv;
complex_f *send_ptr;
complex_f *recv_ptr;
const char *chan_string = "transpose";
int main (int argc, char **argv) {
MPI_Init (&argc, &argv);
DRI_Init (&argc, &argv, &drinet);
DRI_Group_import (MPI_COMM_WORLD, &drigroup);
DRI_Distribution_create_simple (NDIMS, global_dims, drigroup,
DRI_PARTITION_BLOCK_2D_10,
DRI_LAYOUT_PACKED_2D_10,
&dist_sendside);
DRI_Distribution_create_simple (NDIMS, global_dims, drigroup,
DRI_PARTITION_BLOCK_2D_01,
DRI_LAYOUT_PACKED_2D_01,
&dist_recvside);
DRI_Reorg_create_system (drinet, DRI_REORG_SEND, chan_string,
DRI_COMPLEX,
dist_sendside, reorg_numbufs, &reorg_sendside);
DRI_Reorg_create_system (drinet, DRI_REORG_RECV, chan_string,
DRI_COMPLEX,
dist_recvside, reorg_numbufs, &reorg_recvside);
DRI_connect(drinet);
/***** Entering the operational loop *****/
for (; ;) {
DRI_Reorg_get_buffer (reorg_sendside, &buf_send);
DRI_Buffer_get_ptr (buf_send, &send_ptr);
/* produce data in the send buffer by using send_ptr
*/
DRI_Reorg_put_buffer (reorg_sendside, buf_send);
DRI_Reorg_get_buffer (reorg_recvside, &buf_recv);
DRI_Buffer_get_ptr (buf_recv, &recv_ptr);
/* consume data in the receive buffer by using recv_ptr
*/
DRI_Reorg_put_buffer (reorg_recvside, buf_recv);
}
DRI_Finalize(drinet);
MPI_Finalize();
} /* end of main() */
4. What could we do to simplify SPMD cases?
Using these EXISTING shortcut default objects:
+ NONE!
Using these PROPOSED new defaults:
+ DRI_PARTITION_BLOCK_2D_10
+ DRI_PARTITION_BLOCK_2D_01
+ DRI_LAYOUT_PACKED_2D_10
+ DRI_LAYOUT_PACKED_2D_01
REMOVING the Global_Data_create, instead moving its input parameters
into an alternative DRI_Distribution_create_simple routine
A SINGLE DRI_Distribution creation to create both "sides"
(DRI_Distribution_create_SPMD)
A SINGLE DRI_Reorg creation to create both "sides"
(DRI_Reorg_create_SPMD)
A SINGLE transfer call (DRI_Reorg_getput -- we could use "transfer"
instead)
(DRI_Reorg_SPMD_getput)
#define NDIMS 2
int global_dims[NDIMS] = {1024, 256};
DRI_Network *drinet;
DRI_Group *drigroup;
DRI_Distribution *dist_sendside;
DRI_Distribution *dist_recvside;
DRI_Reorg *reorg_sendside;
DRI_Reorg *reorg_recvside;
int reorg_numbufs = 2;
DRI_Buffer *buf_send;
DRI_Buffer *buf_recv;
complex_f *send_ptr;
complex_f *recv_ptr;
const char *chan_string = "transpose";
int main (int argc, char **argv) {
MPI_Init (&argc, &argv);
DRI_Init (&argc, &argv, &drinet);
DRI_Group_import (MPI_COMM_WORLD, &drigroup);
DRI_Distribution_create_simple_SPMD (NDIMS, global_dims, drigroup,
DRI_PARTITION_BLOCK_2D_10,
DRI_LAYOUT_PACKED_2D_10,
DRI_PARTITION_BLOCK_2D_01,
DRI_LAYOUT_PACKED_2D_01,
&dist_sendside, &dist_recvside);
DRI_Reorg_create_SPMD (drinet, chan_string, DRI_COMPLEX,
reorg_numbufs,
dist_sendside, dist_recvside,
&reorg_sendside, &reorg_recvside);
DRI_connect(drinet);
/***** Entering the operational loop *****/
for (; ;) {
DRI_Reorg_get_buffer (reorg_sendside, &buf_send);
DRI_Buffer_get_ptr (buf_send, &send_ptr);
/* produce data in the send buffer by using send_ptr
*/
DRI_Reorg_SPMD_getput (reorg_sendside, buf_send, reorg_recvside,
&buf_recv);
DRI_Buffer_get_ptr (buf_recv, &recv_ptr);
/* consume data in the receive buffer by using recv_ptr
*/
DRI_Reorg_put_buffer (reorg_recvside, buf_recv);
}
DRI_Finalize(drinet);
MPI_Finalize();
} /* end of main() */