root/trunk/ProjectFortress/demos/BiCGSTAB2.fss

Revision 3647, 10.5 KB (checked in by sukyoungryu, 7 months ago)

[copyright] Fixed copyright notices.

Line 
1(*******************************************************************************
2  This program is copyrighted free software by Kento Emoto
3  <emoto[at]ipl.t.u-tokyo.ac.jp> developed under the collaborative
4  research on Fortress Programming Language between Sun Microsystems,
5  Inc. and the University of Tokyo.
6
7  You can redistribute it and/or modify it under the following
8  BSD-style license or the Sun Contributor Agreement that Kento Emoto signed.
9
10
11  Copyright 2009 by Kento Emoto
12  All rights reserved.
13
14  Redistribution and use in source and binary forms, with or without
15  modification, are permitted provided that the following conditions
16  are met:
17
18      * Redistributions of source code must retain the above copyright
19        notice, this list of conditions and the following disclaimer.
20      * Redistributions in binary form must reproduce the above copyright
21        notice, this list of conditions and the following disclaimer
22        in the documentation and/or other materials provided with the
23        distribution.
24      * Neither the name of Kento Emoto nor the names of its
25        contributors may be used to endorse or promote products derived
26        from this software without specific prior written permission.
27
28  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
30  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
32  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
35  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
36  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
37  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
38  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
40
41 ******************************************************************************)
42
43(*
44
45This program is modified from the BiCGSTAB.fss to use zero-based
46indexing and algebraic operations on vectors.  It is important to use
47vector operations for efficiency, as well as readability or
48maintainability.
49
50This program is still naive because it has many code duplications and
51naive codes for vector operations. You can improve readability and
52reusability using nice notations provided by Fortress and its library.
53
54*)
55
56component BiCGSTAB2
57
58export Executable
59
60run(args : String...) : () = do
61  println("BiCGSTAB")
62  testrun[\16,16,16\]();
63  (*testrun[\2,2,2\]();*)
64end
65
66(* Makes sample matrix A and vector b s.t. the answer of A x = b is x = 1 . *)
67initilization[\nat imax, nat jmax, nat kmax\]() =
68do
69  (* those allocations of vectors should be factored out as calls of a function *)
70  Ap = array3[\RR64, imax, jmax, kmax\]()
71  Ae = array3[\RR64, imax, jmax, kmax\]()
72  Aw = array3[\RR64, imax, jmax, kmax\]()
73  An = array3[\RR64, imax, jmax, kmax\]()
74  As = array3[\RR64, imax, jmax, kmax\]()
75  At = array3[\RR64, imax, jmax, kmax\]()
76  Ab = array3[\RR64, imax, jmax, kmax\]()
77  Ap.fill(fn (i:ZZ32,j:ZZ32,k:ZZ32):RR64 => 2.0)
78  Ae.fill(fn (i:ZZ32,j:ZZ32,k:ZZ32):RR64 => 1.0)
79  Aw.fill(fn (i:ZZ32,j:ZZ32,k:ZZ32):RR64 => 1.0)
80  An.fill(fn (i:ZZ32,j:ZZ32,k:ZZ32):RR64 => 1.0)
81  As.fill(fn (i:ZZ32,j:ZZ32,k:ZZ32):RR64 => 1.0)
82  At.fill(fn (i:ZZ32,j:ZZ32,k:ZZ32):RR64 => 1.0)
83  Ab.fill(fn (i:ZZ32,j:ZZ32,k:ZZ32):RR64 => 1.0)
84
85  for j <- 0#jmax do
86    for k <- 0#kmax do
87      Aw[0,j,k]    := 0.0
88      Ae[imax-1,j,k] := 0.0
89    end
90  end
91  for i <- 0#imax do
92    for k <- 0#kmax do
93      As[i,0,k]    := 0.0
94      An[i,jmax-1,k] := 0.0
95    end
96  end
97  for i <- 0#imax do
98    for j <- 0#jmax do
99      Ab[i,j,0]    := 0.0
100      At[i,j,kmax-1] := 0.0
101    end
102  end
103
104  (*  PrintMatrix[\imax,jmax,kmax\](Ap, Ae, Aw, An, As, At, Ab) *)
105
106  (*
107  oops! we cant use negative indices!  ... nat is only for non-negative...
108  b = array1[\RR64, imax jmax kmax + 2 jmax imax\]().shift( - jmax imax)
109  c = array1[\RR64, imax jmax kmax + 2 jmax imax\]().shift( - jmax imax)
110
111  i will shift them in the product loop.
112  *)
113
114  b = array1[\RR64, (imax jmax kmax) + (2 jmax imax)\]()
115  x = array1[\RR64, (imax jmax kmax) + (2 jmax imax)\]()
116
117  x.fill(fn (i:ZZ32):RR64 => 0.0)
118  b.fill(fn (i:ZZ32):RR64 => 0.0)
119
120  for i <- 0#imax do
121    for j <- 0#jmax do
122      for k <- 0#kmax do
123        m = i + imax j + imax jmax k + imax jmax
124        b[m] := 2.0
125        if (i>0) AND (i<imax-1) then
126          b[m] := b[m] + 2.0
127        else
128          b[m] := b[m] + 1.0
129        end
130
131        if (j>0) AND (j<jmax-1) then
132          b[m] := b[m] + 2.0
133        else
134          b[m] := b[m] + 1.0
135        end
136
137        if (k>0) AND (k<kmax-1) then
138          b[m] := b[m] + 2.0
139        else
140          b[m] := b[m] + 1.0
141        end
142      end
143    end
144  end
145  (* the answer of Ax=b is x = 1. *)
146  (Ap, Ae, Aw, An, As, At, Ab, b, x)
147end
148(* A sample driver for the BiCGSTAB method. *)
149testrun[\nat imax, nat jmax, nat kmax\]() : () =
150do
151  (Ap, Ae, Aw, An, As, At, Ab, b, x) = initilization[\imax, jmax, kmax\]()
152(*
153  PrintVector[\imax, jmax, kmax\](b)
154  PrintMatrixVector[\imax, jmax, kmax\](Ap, Ae, Aw, An, As, At, Ab, b)
155  MatrixVectorProduct[\imax, jmax, kmax\](Ap, Ae, Aw, An, As, At, Ab, b, x)
156  PrintVector[\imax, jmax, kmax\](x)
157  *)
158
159  st = nanoTime()
160  BiCGSTABband[\imax, jmax, kmax\](Ap,Ae,Aw,An,As,At,Ab,x,b)
161  et = nanoTime()
162  t = et - st
163  ss = t / 1000000000.0
164  println("elapsed time " t " ns ( " ss " s)")
165end
166(* Note
167b must be of [1-imax jamx : imax jmax kmax + imax jmax] for simplicity
168oops! we cant use negative indices for arrays!!!!!!
169ok. i will shift the indices by + imax jmax
170
171conditions for sentinels
172Aw(1,_,_)    = 0
173Ae(imax,_,_) = 0
174As(_,1,_)    = 0
175An(_,jmax,_) = 0
176Ab(_,_,1)    = 0
177At(_,_,kmax) = 0
178
179*)
180(* BiCGSTAB method for band matrix A and vector b.
181   This program uses zero-based indexing
182   to use algebraic operations of vectors in Fortress.
183*)
184BiCGSTABband[\nat imax, nat jmax, nat kmax\](Ap,Ae,Aw,An,As,At,Ab,x2,b2) : (ZZ32, RR64) =
185do
186  (* those allocations of vectors should be factored out as calls of a function *)
187  x  : Vector[\RR64,(imax jmax kmax) + (2 jmax imax)\] := x2
188  b  : Vector[\RR64,(imax jmax kmax) + (2 jmax imax)\] := b2
189  r  : Vector[\RR64,(imax jmax kmax) + (2 jmax imax)\] := b.copy()
190  r' : Vector[\RR64,(imax jmax kmax) + (2 jmax imax)\] := b.copy()
191  p  : Vector[\RR64,(imax jmax kmax) + (2 jmax imax)\] := b.copy()
192  y  : Vector[\RR64,(imax jmax kmax) + (2 jmax imax)\] := b.copy()
193  e  : Vector[\RR64,(imax jmax kmax) + (2 jmax imax)\] := b.copy()
194  v  : Vector[\RR64,(imax jmax kmax) + (2 jmax imax)\] := b.copy()
195  c  : Vector[\RR64,(imax jmax kmax) + (2 jmax imax)\] := b.copy()
196  (* we dont need so many iterations because the matrix is a band matrix. *)
197  itrmax = imax jmax kmax
198  er0 = 1.0 10^(-4)
199
200  MatrixVectorProduct[\imax,jmax,kmax\](Ap,Ae,Aw,An,As,At,Ab,x,c)
201
202(*
203  PrintVector[\imax, jmax, kmax\](x)
204  PrintMatrixVector[\imax, jmax, kmax\](Ap, Ae, Aw, An, As, At, Ab, x)
205  PrintVector[\imax, jmax, kmax\](c)
206  PrintVector[\imax, jmax, kmax\](b)
207  *)
208
209  r := b - c
210  c1 : RR64 := r DOT r
211
212  label MainLoop
213    if (c1 < er0) then exit MainLoop with () end
214    p := r
215    r' := r
216
217(*
218    PrintVector[\imax, jmax, kmax\](p)
219    PrintVector[\imax, jmax, kmax\](r')
220*)
221    it : ZZ32 := 1
222    rr : RR64 := 0
223    while it <= itrmax do
224      MatrixVectorProduct[\imax,jmax,kmax\](Ap,Ae,Aw,An,As,At,Ab,p,y)
225      c2 = r' DOT y
226      alp = c1 / c2
227      e := r - alp y
228      MatrixVectorProduct[\imax,jmax,kmax\](Ap,Ae,Aw,An,As,At,Ab,e,v)
229      ev = e DOT v
230      vv = v DOT v
231      (* We get ev=vv=0 when imax=jmax=kmax=2. Thus, we need to avoid NaN. *)
232      c3 = if (vv=0) AND (ev=0) then 1 else ev / vv end
233      x := x + alp p + c3 e
234      r := e - c3 v
235      rr := r DOT r
236      println(it " residual = " rr)
237      if (rr < er0) then exit MainLoop with (it,rr) end
238      c1 := r' DOT r
239
240      bet = c1 / (c2 c3)
241      p := r + bet (p - c3 y)
242
243      it += 1
244    end
245    (it,rr)
246  end MainLoop
247end
248
249
250(* A product of a 7-band matrix and a vector. *)
251MatrixVectorProduct[\nat imax, nat jmax, nat kmax\]
252(Ap, Ae, Aw, An, As, At, Ab, b, c) : () =
253do
254  for k <- 0#kmax do
255    for j <- 0#jmax do
256      for i <- 0#imax do
257        m = i + imax j + imax jmax k + imax jmax
258        c[m] := Ap[i,j,k] b[m] + Aw[i,j,k] b[m - 1] + Ae[i,j,k] b[m + 1] + As[i,j,k] b[m - imax] + An[i,j,k] b[m + imax] + Ab[i,j,k] b[m - imax jmax] + At[i,j,k] b[m + imax jmax]
259      end
260    end
261  end
262end
263(* A pretty printer for a 7-band matrix.*)
264PrintMatrix[\nat imax, nat jmax, nat kmax\]
265(Ap, Ae, Aw, An, As, At, Ab) : () =
266do
267  for k <- seq(0#kmax) do
268    for j <- seq(0#jmax) do
269      for i <- seq(0#imax) do
270        m = i + imax j + imax jmax k (* mth row *)
271        p : ZZ32 := 0
272        while p < imax jmax kmax do
273          v = case p of
274                m             => Ap[i,j,k]
275                m - 1         => Aw[i,j,k]
276                m + 1         => Ae[i,j,k]
277                m - imax      => As[i,j,k]
278                m + imax      => An[i,j,k]
279                m - imax jmax => Ab[i,j,k]
280                m + imax jmax => At[i,j,k]
281                else          => 0.0
282              end
283          print(v " ")
284          p += 1
285        end
286        println()
287      end
288    end
289  end
290end
291
292(* A pretty printer for a vector (an array). *)
293PrintVector[\nat imax, nat jmax, nat kmax\]
294(s, b) : () =
295do
296print(s " : ")
297PrintVector[\imax, jmax, kmax\](b)
298end
299
300(* A pretty printer for a vector (an array). *)
301PrintVector[\nat imax, nat jmax, nat kmax\]
302(b) : () =
303do
304  for k <- seq(0#kmax) do
305    for j <- seq(0#jmax) do
306      for i <- seq(0#imax) do
307        m = i + imax j + imax jmax k + imax jmax (* mth row *)
308        print(b[m] " ")
309      end
310    end
311  end
312  println()
313end
314
315(* A pretty printer for the pair of a 7-band matrix and a vector (an array). *)
316PrintMatrixVector[\nat imax, nat jmax, nat kmax\]
317(Ap, Ae, Aw, An, As, At, Ab, b) : () =
318do
319  for k <- seq(0#kmax) do
320    for j <- seq(0#jmax) do
321      for i <- seq(0#imax) do
322        m = i + imax j + imax jmax k (* mth row *)
323        p : ZZ32 := 0
324        while p < imax jmax kmax do
325          v = case p of
326                m             => Ap[i,j,k]
327                m - 1         => Aw[i,j,k]
328                m + 1         => Ae[i,j,k]
329                m - imax      => As[i,j,k]
330                m + imax      => An[i,j,k]
331                m - imax jmax => Ab[i,j,k]
332                m + imax jmax => At[i,j,k]
333                else          => 0.0
334              end
335          print(v " ")
336          p += 1
337        end
338        println(": " b[m + imax jmax])
339      end
340    end
341  end
342end
343
344
345end
Note: See TracBrowser for help on using the browser.