1 /*
2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 #include "stdioInterf.h"
19 #include "fioMacros.h"
20
21 /* receive single data item */
22
23 void
__fort_rrecvl(int cpu,void * adr,long cnt,long str,int typ,long ilen)24 __fort_rrecvl(int cpu, void *adr, long cnt, long str, int typ, long ilen)
25 {
26 struct ents s;
27 struct ent e;
28
29 if (cnt <= 0) {
30 return;
31 }
32 s.beg = &e;
33 s.avl = (&e) + 1;
34 s.end = s.avl;
35 e.adr = adr;
36 e.str = (str == 0 ? 1 : str);
37 e.cnt = cnt;
38 e.typ = typ;
39 e.ilen = ilen;
40 e.len = cnt * e.ilen;
41 __fort_erecv(cpu, &s);
42 }
43
44 /* send a single data item */
45
46 void
__fort_rsendl(int cpu,void * adr,long cnt,long str,int typ,long ilen)47 __fort_rsendl(int cpu, void *adr, long cnt, long str, int typ, long ilen)
48 {
49 struct ents s;
50 struct ent e;
51
52 if (cnt <= 0) {
53 return;
54 }
55 s.beg = &e;
56 s.avl = (&e) + 1;
57 s.end = s.avl;
58 e.adr = adr;
59 e.str = (str == 0 ? 1 : str);
60 e.cnt = cnt;
61 e.typ = typ;
62 e.ilen = ilen;
63 e.len = cnt * e.ilen;
64 __fort_esend(cpu, &s);
65 }
66
67 /* receive single data item */
68
69 void
__fort_rrecv(int cpu,void * adr,long cnt,long str,int typ)70 __fort_rrecv(int cpu, void *adr, long cnt, long str, int typ)
71 {
72 __fort_rrecvl(cpu, adr, cnt, str, typ, GET_DIST_SIZE_OF(typ));
73 }
74
75 /* send a single data item */
76
77 void
__fort_rsend(int cpu,void * adr,long cnt,long str,int typ)78 __fort_rsend(int cpu, void *adr, long cnt, long str, int typ)
79 {
80 __fort_rsendl(cpu, adr, cnt, str, typ, GET_DIST_SIZE_OF(typ));
81 }
82
83 /* simple broadcast from "src" processor to other processors */
84
85 void
__fort_rbcstl(int src,void * adr,long cnt,long str,int typ,long ilen)86 __fort_rbcstl(int src, void *adr, long cnt, long str, int typ, long ilen)
87 {
88 register int in; /* increment or decrement for other cpu */
89 register int me; /* this cpu's adjusted number */
90 register int cp; /* other cpu's real number */
91 struct ents s;
92 struct ent e;
93 int lcpu, tcpus;
94
95 if (cnt <= 0) {
96 return;
97 }
98 s.beg = &e;
99 s.avl = (&e) + 1;
100 s.end = s.avl;
101 lcpu = GET_DIST_LCPU;
102 e.adr = adr;
103 e.str = (str == 0 ? 1 : str);
104 e.cnt = cnt;
105 e.typ = typ;
106 e.ilen = ilen;
107 e.len = cnt * e.ilen;
108
109 in = 1;
110 tcpus = GET_DIST_TCPUS;
111 while (in < tcpus) {
112 in <<= 1;
113 }
114 in >>= 1;
115
116 me = lcpu - src;
117 me = (me < 0 ? me + tcpus : me);
118 if (me != 0) {
119 while (((in - 1) & me) != 0) {
120 in >>= 1;
121 }
122 cp = (me - in) + src;
123 cp = (cp >= tcpus ? cp - tcpus : cp);
124 __fort_erecv(cp, &s);
125 in >>= 1;
126 }
127 while (in > 0) {
128 if ((me + in) < tcpus) {
129 cp = (me + in) + src;
130 cp = (cp >= tcpus ? cp - tcpus : cp);
131 __fort_esend(cp, &s);
132 }
133 in >>= 1;
134 }
135 }
136
137 /* simple broadcast from "src" processor to other processors */
138
139 void
__fort_rbcst(int src,void * adr,long cnt,long str,int typ)140 __fort_rbcst(int src, void *adr, long cnt, long str, int typ)
141 {
142 __fort_rbcstl(src, adr, cnt, str, typ, GET_DIST_SIZE_OF(typ));
143 }
144