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