1 # This file is part of NIT (http://www.nitlanguage.org).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Example implemented from "The computer Language Benchmarks Game" - Fannkuch-Redux
16 # http://benchmarksgame.alioth.debian.org/
18 # Complete description of the fannkuch-redux :
19 # https://benchmarksgame.alioth.debian.org/u64q/fannkuchredux-description.html#fannkuchredux
20 module fannkuchredux
is no_warning
("missing-doc")
27 var p
: Array[Int] is noautoinit
28 var pp
: Array[Int] is noautoinit
29 var count
: Array[Int] is noautoinit
32 for i
in [0..p
.length
[ do printn p
[i
] + 1
36 fun first_permutation
(idx
: Int) do
37 for i
in [0..p
.length
[ do p
[i
] = i
39 var i
= count
.length
- 1
45 p
.copy_to
(0, i
+1, pp
, 0)
58 fun next_permutation
do
72 for j
in [1..i
[ do p
[j
] = p
[j
+1]
80 fun count_flips
: Int do
84 p
.copy_to
(0, pp
.length
, pp
, 0)
101 if pp
[first
] == 0 then break
107 fun run_task
(task
: Int) do
108 var idx_min
= task
* chunk_sz
109 var idx_max
= fact
[n
].min
(idx_min
+ chunk_sz
)
111 first_permutation
(idx_min
)
119 var flips
= count_flips
120 maxflips
= maxflips
.max
(flips
)
129 if i
== idx_max
then break
133 max_flips
[task
] = maxflips
134 chk_sums
[task
] = chk_sum
138 p
= new Array[Int].with_capacity
(n
)
139 for i
in [0..n
[ do p
.add
(0)
140 pp
= new Array[Int].with_capacity
(n
)
141 for i
in [0..n
[ do pp
.add
(0)
142 count
= new Array[Int].with_capacity
(n
)
143 for i
in [0..n
[ do count
.add
(0)
147 task
= task_id
.get_and_increment
148 if task
< n_tasks
then
159 var chunk_sz
: Int is noautoinit
160 var n_tasks
: Int is noautoinit
161 var n
: Int is noautoinit
162 var fact
: Array[Int] is noautoinit
163 var max_flips
: Array[Int] is noautoinit
164 var chk_sums
: Array[Int] is noautoinit
165 var task_id
= new AtomicInt(0)
169 fun print_result
(n
, res
, chk
: Int) do
170 print chk
.to_s
+ "\nPfannfuchen(" + n
.to_s
+ ") = " + res
.to_s
174 if args
.is_empty
then
180 fact
= new Array[Int].with_capacity
(n
+1)
182 for i
in [1..n
] do fact
.add
(fact
[i-1
] * i
)
184 chunk_sz
= (fact
[n
] + n_chunks
- 1) / n_chunks
185 n_tasks
= (fact
[n
] + chunk_sz
- 1) / chunk_sz
186 max_flips
= new Array[Int].with_capacity
(n_tasks
)
187 for i
in [0..n_tasks
[ do max_flips
.add
(0)
188 chk_sums
= new Array[Int].with_capacity
(n_tasks
)
189 for i
in [0..n_tasks
[ do chk_sums
.add
(0)
191 var actors
= new Array[FannkuchRedux].with_capacity
(8)
192 for i
in [0..nb_actors
[ do
193 var a
= new FannkuchRedux
198 for i
in [0..nb_actors
[ do
199 actors
[i
].async
.terminate
200 actors
[i
].async
.wait_termination
204 for i
in max_flips
do res
= res
.max
(i
)
211 print_result
(n
, res
, chk
)