Pristine Ack-5.5
[Ack-5.5.git] / lang / occam / test / matmul.ocm
1 #include "dec.ocm"
2
3 proc prompt(value str[])=
4         seq i=[1 for str[byte 0]]
5                 output ! str[byte i]
6 :
7 def N=20 :
8
9 var n:
10 var A[N*N], x[N], k[N], y[N] :
11
12 proc initialise=
13         var c:
14         seq
15                 prompt("n?*n")
16                 c:='*s'
17                 decin(input, n, c)
18
19                 prompt("A?*n")
20                 seq i= [0 for n]
21                         seq j= [0 for n]
22                                 decin(input, A[(i*n)+j], c)
23
24                 prompt("x?*n")
25                 seq i= [0 for n]
26                         decin(input, x[i], c)
27
28                 prompt("k?*n")
29                 seq i= [0 for n]
30                         decin(input, k[i], c)                           :
31                 
32 proc produce.xj(value j, chan south) =
33         -- north row: source of x values
34         while true
35                 south ! x[j]                                            :
36
37 proc consume.yi(value i, chan east) =
38         -- west column: read y values
39         east ? y[i]                                             :
40
41 proc offset(value ki, chan west) =
42         -- east column: source of k offsets
43         while true
44                 west ! ki                                               :
45
46 proc multiplier(value aij, chan north, south, west, east) =
47         -- middle: responsible for a values
48         var xj, aij.times.xj, yi :
49         seq
50                 north ? xj
51                 while true
52                         seq
53                                 par
54                                         south ! xj
55                                         aij.times.xj:= aij*xj
56                                         east ? yi
57                                 par
58                                         west ! yi+aij.times.xj
59                                         north ? xj                      :
60
61 proc sink(chan north) =
62         -- south row: sink for unused outputs
63         while true
64                 north ? any                                             :
65
66 seq
67         initialise
68
69         chan north.south[(N+1)*N], east.west[N*(N+1)] :
70         par
71                 par j= [0 for n]        -- producer of co-ordinates x[j]
72                         produce.xj(j, north.south[j])
73
74                 par                     -- the matrix multiplier
75                         par i= [0 for n]
76                                 offset(k[i], east.west[(n*n)+i])
77                         par i= [0 for n]
78                                 par j= [0 for n]
79                                         multiplier(A[(n*i)+j],
80                                                 north.south[(n*i)+j],
81                                                 north.south[(n*(i+1))+j],
82                                                 east.west[i+(n*j)],
83                                                 east.west[i+(n*(j+1))])
84                         par j= [0 for n]
85                                 sink(north.south[(n*n)+j])
86
87                 seq
88                         par i= [0 for n]-- consumer of transformed co-ordinates
89                                 consume.yi(i, east.west[i])
90
91                         seq i= [0 for n]
92                                 seq
93                                         output ! 'y'; '['
94                                         decout(output, i, 0)
95                                         output ! ']'; '='
96                                         decout(output, y[i], 5)
97                                         output ! '*n'
98                         exit(0)