|
7 | 7 | * Copyright (c) 2012 Sandia National Laboratories. All rights reserved. |
8 | 8 | * Copyright (c) 2013 Los Alamos National Security, LLC. All rights |
9 | 9 | * reserved. |
10 | | - * Copyright (c) 2014 Research Organization for Information Science |
| 10 | + * Copyright (c) 2014-2015 Research Organization for Information Science |
11 | 11 | * and Technology (RIST). All rights reserved. |
12 | 12 | * |
13 | 13 | * Author(s): Torsten Hoefler <[email protected]> |
@@ -63,80 +63,81 @@ int ompi_coll_libnbc_ireduce_scatter_block(void* sendbuf, void* recvbuf, int rec |
63 | 63 |
|
64 | 64 | maxr = (int)ceil((log((double)p)/LOG2)); |
65 | 65 |
|
66 | | - count = 0; |
67 | | - for(r=0;r<p;r++) count += recvcount; |
| 66 | + count = p * recvcount; |
68 | 67 |
|
69 | | - handle->tmpbuf = malloc(ext*count*2); |
70 | | - if(handle->tmpbuf == NULL) { printf("Error in malloc()\n"); return NBC_OOR; } |
| 68 | + if (0 < count) { |
| 69 | + handle->tmpbuf = malloc(ext*count*2); |
| 70 | + if(handle->tmpbuf == NULL) { printf("Error in malloc()\n"); return NBC_OOR; } |
71 | 71 |
|
72 | | - redbuf = ((char*)handle->tmpbuf)+(ext*count); |
| 72 | + redbuf = ((char*)handle->tmpbuf)+(ext*count); |
73 | 73 |
|
74 | | - /* copy data to redbuf if we only have a single node */ |
75 | | - if((p==1) && !inplace) { |
76 | | - res = NBC_Copy(sendbuf, count, datatype, redbuf, count, datatype, comm); |
77 | | - if (NBC_OK != res) { printf("Error in NBC_Copy() (%i)\n", res); return res; } |
78 | | - } |
| 74 | + /* copy data to redbuf if we only have a single node */ |
| 75 | + if((p==1) && !inplace) { |
| 76 | + res = NBC_Copy(sendbuf, count, datatype, redbuf, count, datatype, comm); |
| 77 | + if (NBC_OK != res) { printf("Error in NBC_Copy() (%i)\n", res); return res; } |
| 78 | + } |
79 | 79 |
|
80 | | - firstred = 1; |
81 | | - for(r=1; r<=maxr; r++) { |
82 | | - if((rank % (1<<r)) == 0) { |
83 | | - /* we have to receive this round */ |
84 | | - peer = rank + (1<<(r-1)); |
85 | | - if(peer<p) { |
86 | | - res = NBC_Sched_recv(0, true, count, datatype, peer, schedule); |
87 | | - if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_recv() (%i)\n", res); return res; } |
88 | | - /* we have to wait until we have the data */ |
89 | | - res = NBC_Sched_barrier(schedule); |
90 | | - if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_barrier() (%i)\n", res); return res; } |
| 80 | + firstred = 1; |
| 81 | + for(r=1; r<=maxr; r++) { |
| 82 | + if((rank % (1<<r)) == 0) { |
| 83 | + /* we have to receive this round */ |
| 84 | + peer = rank + (1<<(r-1)); |
| 85 | + if(peer<p) { |
| 86 | + res = NBC_Sched_recv(0, true, count, datatype, peer, schedule); |
| 87 | + if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_recv() (%i)\n", res); return res; } |
| 88 | + /* we have to wait until we have the data */ |
| 89 | + res = NBC_Sched_barrier(schedule); |
| 90 | + if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_barrier() (%i)\n", res); return res; } |
| 91 | + if(firstred) { |
| 92 | + /* take reduce data from the sendbuf in the first round -> save copy */ |
| 93 | + res = NBC_Sched_op(redbuf-(unsigned long)handle->tmpbuf, true, sendbuf, false, 0, true, count, datatype, op, schedule); |
| 94 | + firstred = 0; |
| 95 | + } else { |
| 96 | + /* perform the reduce in my local buffer */ |
| 97 | + res = NBC_Sched_op(redbuf-(unsigned long)handle->tmpbuf, true, redbuf-(unsigned long)handle->tmpbuf, true, 0, true, count, datatype, op, schedule); |
| 98 | + } |
| 99 | + if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_op() (%i)\n", res); return res; } |
| 100 | + /* this cannot be done until handle->tmpbuf is unused :-( */ |
| 101 | + res = NBC_Sched_barrier(schedule); |
| 102 | + if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_barrier() (%i)\n", res); return res; } |
| 103 | + } |
| 104 | + } else { |
| 105 | + /* we have to send this round */ |
| 106 | + peer = rank - (1<<(r-1)); |
91 | 107 | if(firstred) { |
92 | | - /* take reduce data from the sendbuf in the first round -> save copy */ |
93 | | - res = NBC_Sched_op(redbuf-(unsigned long)handle->tmpbuf, true, sendbuf, false, 0, true, count, datatype, op, schedule); |
94 | | - firstred = 0; |
| 108 | + /* we have to send the senbuf */ |
| 109 | + res = NBC_Sched_send(sendbuf, false, count, datatype, peer, schedule); |
95 | 110 | } else { |
96 | | - /* perform the reduce in my local buffer */ |
97 | | - res = NBC_Sched_op(redbuf-(unsigned long)handle->tmpbuf, true, redbuf-(unsigned long)handle->tmpbuf, true, 0, true, count, datatype, op, schedule); |
| 111 | + /* we send an already reduced value from redbuf */ |
| 112 | + res = NBC_Sched_send(redbuf-(unsigned long)handle->tmpbuf, true, count, datatype, peer, schedule); |
98 | 113 | } |
99 | | - if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_op() (%i)\n", res); return res; } |
100 | | - /* this cannot be done until handle->tmpbuf is unused :-( */ |
101 | | - res = NBC_Sched_barrier(schedule); |
102 | | - if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_barrier() (%i)\n", res); return res; } |
103 | | - } |
104 | | - } else { |
105 | | - /* we have to send this round */ |
106 | | - peer = rank - (1<<(r-1)); |
107 | | - if(firstred) { |
108 | | - /* we have to send the senbuf */ |
109 | | - res = NBC_Sched_send(sendbuf, false, count, datatype, peer, schedule); |
110 | | - } else { |
111 | | - /* we send an already reduced value from redbuf */ |
112 | | - res = NBC_Sched_send(redbuf-(unsigned long)handle->tmpbuf, true, count, datatype, peer, schedule); |
| 114 | + if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_send() (%i)\n", res); return res; } |
| 115 | + /* leave the game */ |
| 116 | + break; |
113 | 117 | } |
114 | | - if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_send() (%i)\n", res); return res; } |
115 | | - /* leave the game */ |
116 | | - break; |
117 | 118 | } |
118 | | - } |
119 | 119 |
|
120 | | - res = NBC_Sched_barrier(schedule); |
121 | | - if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_barrier() (%i)\n", res); return res; } |
| 120 | + res = NBC_Sched_barrier(schedule); |
| 121 | + if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_barrier() (%i)\n", res); return res; } |
122 | 122 |
|
123 | | - /* rank 0 is root and sends - all others receive */ |
124 | | - if(rank != 0) { |
125 | | - res = NBC_Sched_recv(recvbuf, false, recvcount, datatype, 0, schedule); |
126 | | - if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_recv() (%i)\n", res); return res; } |
127 | | - } |
| 123 | + /* rank 0 is root and sends - all others receive */ |
| 124 | + if(rank != 0) { |
| 125 | + res = NBC_Sched_recv(recvbuf, false, recvcount, datatype, 0, schedule); |
| 126 | + if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_recv() (%i)\n", res); return res; } |
| 127 | + } |
128 | 128 |
|
129 | | - if(rank == 0) { |
130 | | - offset = 0; |
131 | | - for(r=1;r<p;r++) { |
132 | | - offset += recvcount; |
133 | | - sbuf = ((char *)redbuf) + (offset*ext); |
134 | | - /* root sends the right buffer to the right receiver */ |
135 | | - res = NBC_Sched_send(sbuf-(unsigned long)handle->tmpbuf, true, recvcount, datatype, r, schedule); |
136 | | - if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_send() (%i)\n", res); return res; } |
| 129 | + if(rank == 0) { |
| 130 | + offset = 0; |
| 131 | + for(r=1;r<p;r++) { |
| 132 | + offset += recvcount; |
| 133 | + sbuf = ((char *)redbuf) + (offset*ext); |
| 134 | + /* root sends the right buffer to the right receiver */ |
| 135 | + res = NBC_Sched_send(sbuf-(unsigned long)handle->tmpbuf, true, recvcount, datatype, r, schedule); |
| 136 | + if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_send() (%i)\n", res); return res; } |
| 137 | + } |
| 138 | + res = NBC_Sched_copy(redbuf-(unsigned long)handle->tmpbuf, true, recvcount, datatype, recvbuf, false, recvcount, datatype, schedule); |
| 139 | + if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_copy() (%i)\n", res); return res; } |
137 | 140 | } |
138 | | - res = NBC_Sched_copy(redbuf-(unsigned long)handle->tmpbuf, true, recvcount, datatype, recvbuf, false, recvcount, datatype, schedule); |
139 | | - if (NBC_OK != res) { free(handle->tmpbuf); printf("Error in NBC_Sched_copy() (%i)\n", res); return res; } |
140 | 141 | } |
141 | 142 |
|
142 | 143 | /*NBC_PRINT_SCHED(*schedule);*/ |
|
0 commit comments