-
Notifications
You must be signed in to change notification settings - Fork 1
/
ufrac-mt.scm
130 lines (123 loc) · 3.96 KB
/
ufrac-mt.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
(define-record-type pool
(fields
(mutable items)
(mutable size)
(immutable mutex))
(protocol
(lambda (new)
(lambda (items)
(new items
(length items)
(make-mutex))))))
(define retrieve-items!
(lambda (pool)
(with-mutex (pool-mutex pool)
(let ([items (pool-items pool)])
(cond [(null? items) #f]
[else
(let ([batch-size (min max-batch-size
(pool-size pool))])
(pool-items-set! pool
(list-tail items batch-size))
(pool-size-set! pool
(- (pool-size pool) batch-size))
(list-head items batch-size))])))))
(define add-items!
(lambda (pool items)
(let ([num-items (length items)])
(with-mutex (pool-mutex pool)
(pool-items-set! pool
(append items
(pool-items pool)))
(pool-size-set! pool
(+ num-items
(pool-size pool)))))))
(define BRANCHes)
(define SOLUTIONs)
(define suicide?)
(define counter)
(define max-batch-size 20)
(define number-threads 8)
(define make-processor
;; a processor is both a producer and a consumer
(lambda (n)
(rec processor
(lambda ()
(cond [suicide?
(if verbose?
(printf "processor ~s dying\n" n))]
[else
(if verbose?
(printf "processor ~s looking for branches to kill\n" n))
(let ([jobs (retrieve-items! BRANCHes)])
(cond [jobs
(let ([kill-output (map kill jobs)])
(if verbose?
(printf "processor ~s adding results of killing ~s branches to job-pool\n"
n
(length jobs)))
(add-items! SOLUTIONs
(apply append (map car kill-output)))
(add-items! BRANCHes
(apply append (map cdr kill-output)))
;; (map cadr ...) does not work, as there could be no new branches to compute
)
(vector-set! counter n (+ (vector-ref counter n)
(length jobs)))]))
(processor)])))))
(define (ufrac-mt D r)
(set! BRANCHes (make-pool (list (br-reduce (make-br D r)))))
(set! SOLUTIONs (make-pool '()))
(set! suicide? #f)
(set! counter (make-vector number-threads 0))
(for-each (lambda (x) (fork-thread (make-processor x)))
(range number-threads))
(let ([num-kill (sum (vector->list counter))])
(let loop ()
(sleep (make-time 'time-duration 0 1))
(printf "solutions: ~s branches: ~s killed branches: ~s ~s\n"
(pool-size SOLUTIONs)
(pool-size BRANCHes)
(sum (vector->list counter))
(time-utc->date (current-time)))
(cond [(and (null? (pool-items BRANCHes))
(= num-kill (sum (vector->list counter))))
(sleep (make-time 'time-duration 500000000 0))
(if (and (null? (pool-items BRANCHes))
(= num-kill (sum (vector->list counter))))
(set! suicide? #t))]
[else
(set! num-kill (sum (vector->list counter)))
(loop)])))
(sleep (make-time 'time-duration 10000000 0))
(map br-denoms-sol (pool-items SOLUTIONs)))
(define (ufrac-mt-es D r)
(set! BRANCHes (make-pool (list (br-reduce (make-br D r)))))
(set! SOLUTIONs (make-pool '()))
(set! suicide? #f)
(set! counter (make-vector number-threads 0))
(for-each (lambda (x) (fork-thread (make-processor x)))
(range number-threads))
(let ([num-kill (sum (vector->list counter))])
(let loop ()
(sleep (make-time 'time-duration 0 1))
(printf "solutions: ~s branches: ~s killed branches: ~s ~s\n"
(pool-size SOLUTIONs)
(pool-size BRANCHes)
(sum (vector->list counter))
(time-utc->date (current-time)))
(cond [(positive? (pool-size SOLUTIONs))
(set! suicide? #t)]
[(and (null? (pool-items BRANCHes))
(= num-kill (sum (vector->list counter))))
(sleep (make-time 'time-duration 500000000 0))
(if (and (null? (pool-items BRANCHes))
(= num-kill (sum (vector->list counter))))
(set! suicide? #t))]
[else
(set! num-kill (sum (vector->list counter)))
(loop)])))
(sleep (make-time 'time-duration 10000000 0))
(if (null? (pool-items SOLUTIONs))
#f
(br-denoms-sol (car (pool-items SOLUTIONs)))))