1 /* begin_generated_IBM_copyright_prolog                             */
2 /*                                                                  */
3 /* This is an automatically generated copyright prolog.             */
4 /* After initializing,  DO NOT MODIFY OR MOVE                       */
5 /*  --------------------------------------------------------------- */
6 /* Licensed Materials - Property of IBM                             */
7 /* Blue Gene/Q 5765-PER 5765-PRP                                    */
8 /*                                                                  */
9 /* (C) Copyright IBM Corp. 2011, 2012 All Rights Reserved           */
10 /* US Government Users Restricted Rights -                          */
11 /* Use, duplication, or disclosure restricted                       */
12 /* by GSA ADP Schedule Contract with IBM Corp.                      */
13 /*                                                                  */
14 /*  --------------------------------------------------------------- */
15 /*                                                                  */
16 /* end_generated_IBM_copyright_prolog                               */
17 /*  (C)Copyright IBM Corp.  2007, 2011  */
18 /**
19  * \file src/coll/gather/mpido_scan.c
20  * \brief ???
21  */
22 
23 /*#define TRACE_ON */
24 #include <mpidimpl.h>
25 
scan_cb_done(void * ctxt,void * clientdata,pami_result_t err)26 static void scan_cb_done(void *ctxt, void *clientdata, pami_result_t err)
27 {
28    unsigned *active = (unsigned *)clientdata;
29    TRACE_ERR("cb_scan enter, active: %u\n", (*active));
30    (*active)--;
31 }
32 int MPIDO_Doscan(const void *sendbuf, void *recvbuf,
33                int count, MPI_Datatype datatype,
34                MPI_Op op, MPID_Comm * comm_ptr, int *mpierrno, int exflag);
35 
36 
MPIDO_Scan(const void * sendbuf,void * recvbuf,int count,MPI_Datatype datatype,MPI_Op op,MPID_Comm * comm_ptr,int * mpierrno)37 int MPIDO_Scan(const void *sendbuf, void *recvbuf,
38                int count, MPI_Datatype datatype,
39                MPI_Op op, MPID_Comm * comm_ptr, int *mpierrno)
40 {
41    return MPIDO_Doscan(sendbuf, recvbuf, count, datatype,
42                 op, comm_ptr, mpierrno, 0);
43 }
44 
45 
MPIDO_Exscan(const void * sendbuf,void * recvbuf,int count,MPI_Datatype datatype,MPI_Op op,MPID_Comm * comm_ptr,int * mpierrno)46 int MPIDO_Exscan(const void *sendbuf, void *recvbuf,
47                int count, MPI_Datatype datatype,
48                MPI_Op op, MPID_Comm * comm_ptr, int *mpierrno)
49 {
50    return MPIDO_Doscan(sendbuf, recvbuf, count, datatype,
51                 op, comm_ptr, mpierrno, 1);
52 }
53 
MPIDO_Doscan(const void * sendbuf,void * recvbuf,int count,MPI_Datatype datatype,MPI_Op op,MPID_Comm * comm_ptr,int * mpierrno,int exflag)54 int MPIDO_Doscan(const void *sendbuf, void *recvbuf,
55                int count, MPI_Datatype datatype,
56                MPI_Op op, MPID_Comm * comm_ptr, int *mpierrno, int exflag)
57 {
58    MPID_Datatype *dt_null = NULL;
59    MPI_Aint true_lb = 0;
60    int dt_contig, tsize;
61    int mu;
62    char *sbuf, *rbuf;
63    pami_data_function pop;
64    pami_type_t pdt;
65    int rc;
66    pami_metadata_t *my_md;
67 
68    rc = MPIDI_Datatype_to_pami(datatype, &pdt, op, &pop, &mu);
69    if(unlikely(MPIDI_Process.verbose >= MPIDI_VERBOSE_DETAILS_0 && comm_ptr->rank == 0))
70       fprintf(stderr,"rc %u, dt: %p, op: %p, mu: %u, selectedvar %u != %u (MPICH)\n",
71          rc, pdt, pop, mu,
72          (unsigned)comm_ptr->mpid.user_selected_type[PAMI_XFER_SCAN], MPID_COLL_USE_MPICH);
73 
74 
75    pami_xfer_t scan;
76    volatile unsigned scan_active = 1;
77 
78    if((sendbuf == MPI_IN_PLACE) || /* Disable until ticket #627 is fixed */
79       (comm_ptr->mpid.user_selected_type[PAMI_XFER_SCAN] == MPID_COLL_USE_MPICH || rc != MPI_SUCCESS))
80 
81    {
82       if(unlikely(MPIDI_Process.verbose >= MPIDI_VERBOSE_DETAILS_ALL && comm_ptr->rank == 0))
83          fprintf(stderr,"Using MPICH scan algorithm (exflag %d)\n",exflag);
84       if(exflag)
85          return MPIR_Exscan(sendbuf, recvbuf, count, datatype, op, comm_ptr, mpierrno);
86       else
87          return MPIR_Scan(sendbuf, recvbuf, count, datatype, op, comm_ptr, mpierrno);
88    }
89 
90    MPIDI_Datatype_get_info(count, datatype, dt_contig, tsize, dt_null, true_lb);
91    rbuf = (char *)recvbuf + true_lb;
92    if(sendbuf == MPI_IN_PLACE)
93    {
94      if(unlikely(MPIDI_Process.verbose >= MPIDI_VERBOSE_DETAILS_ALL))
95        fprintf(stderr,"scan MPI_IN_PLACE buffering\n");
96       sbuf = rbuf;
97    }
98    else
99    {
100       sbuf = (char *)sendbuf + true_lb;
101    }
102 
103    scan.cb_done = scan_cb_done;
104    scan.cookie = (void *)&scan_active;
105    if(comm_ptr->mpid.user_selected_type[PAMI_XFER_SCAN] == MPID_COLL_OPTIMIZED)
106    {
107       scan.algorithm = comm_ptr->mpid.opt_protocol[PAMI_XFER_SCAN][0];
108       my_md = &comm_ptr->mpid.opt_protocol_md[PAMI_XFER_SCAN][0];
109    }
110    else
111    {
112       scan.algorithm = comm_ptr->mpid.user_selected[PAMI_XFER_SCAN];
113       my_md = &comm_ptr->mpid.user_metadata[PAMI_XFER_SCAN];
114    }
115    scan.cmd.xfer_scan.sndbuf = sbuf;
116    scan.cmd.xfer_scan.rcvbuf = rbuf;
117    scan.cmd.xfer_scan.stype = pdt;
118    scan.cmd.xfer_scan.rtype = pdt;
119    scan.cmd.xfer_scan.stypecount = count;
120    scan.cmd.xfer_scan.rtypecount = count;
121    scan.cmd.xfer_scan.op = pop;
122    scan.cmd.xfer_scan.exclusive = exflag;
123 
124 
125    if(comm_ptr->mpid.user_selected_type[PAMI_XFER_SCAN] == MPID_COLL_ALWAYS_QUERY ||
126       comm_ptr->mpid.user_selected_type[PAMI_XFER_SCAN] == MPID_COLL_CHECK_FN_REQUIRED)
127    {
128       metadata_result_t result = {0};
129       TRACE_ERR("Querying scan protocol %s, type was %d\n",
130          my_md->name,
131          comm_ptr->mpid.user_selected_type[PAMI_XFER_SCAN]);
132       result = my_md->check_fn(&scan);
133       TRACE_ERR("Bitmask: %#X\n", result.bitmask);
134       if(!result.bitmask)
135       {
136          fprintf(stderr,"Query failed for %s.\n",
137             my_md->name);
138       }
139    }
140 
141    if(unlikely(MPIDI_Process.verbose >= MPIDI_VERBOSE_DETAILS_ALL && comm_ptr->rank == 0))
142    {
143       unsigned long long int threadID;
144       MPIU_Thread_id_t tid;
145       MPIU_Thread_self(&tid);
146       threadID = (unsigned long long int)tid;
147       fprintf(stderr,"<%llx> Using protocol %s for scan on %u (exflag %d)\n",
148               threadID,
149               my_md->name,
150               (unsigned) comm_ptr->context_id,
151               exflag);
152    }
153    MPIDI_Post_coll_t scan_post;
154    MPIDI_Context_post(MPIDI_Context[0], &scan_post.state,
155                       MPIDI_Pami_post_wrapper, (void *)&scan);
156    TRACE_ERR("Scan %s\n", MPIDI_Process.context_post.active>0?"posted":"invoked");
157 
158    MPIDI_Update_last_algorithm(comm_ptr,
159       my_md->name);
160 
161    MPID_PROGRESS_WAIT_WHILE(scan_active);
162    TRACE_ERR("Scan done\n");
163    return rc;
164 }
165