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
|
structure DataParallelDict =
struct
type index = Foreach.index
datatype 'a LIST
= NIL
| CONS of {head:'a, tail:index}
fun initialize toLIST L =
case L of
nil => toLIST NIL
| (head::tail) =>
let
val TAIL = initialize toLIST tail
in
toLIST (CONS {head = head, tail = TAIL})
end
fun initialize (K: index -> index) toLIST L =
case L of
nil => K (toLIST NIL)
| h :: tail =>
let
val newK = fn i => K (toLIST (CONS {head=h, tail=i}))
in
initialize newK toLIST tail
end
val initialize = fn X => initialize (fn (x:index) => x) X
fun initialize (toLIST : 'a list -> index) (L : =
case L of
nil => toLIST NIL
| (head::tail) =>
let
val TAIL = Foreach.Thread.create (fn () => initialize toLIST tail)
in
toLIST (CONS {head = head, tail = Foreach.Thread.join TAIL})
end
fun finalize value =
let
fun conv i =
case value i of
NIL => nil
| CONS{head, tail} => head :: conv tail
in
conv
end
val whereParam =
{(*size = fn L => List.length L + 1,*)
initialize = initialize,
(*default = NIL,*)
finalize = finalize}
fun pmapWithPred f p L =
_foreach id in L where whereParam
with context
do case (#value context id) of
NIL => NIL
| CONS {head, tail} => CONS {head = f head, tail=tail}
while p (id, context)
end
fun makeDict (L : (''a * 'b) list) =
let
val keyVar = MVar.new () : ''a MVar.mvar
val foundVar = MVar.new () : 'b option MVar.mvar
val foundFlag = ref false
fun find (key:''a) : 'b option =
let
val _ = MVar.put (keyVar, key)
in
MVar.take foundVar
end
fun findKey (s,v) =
let
val key = MVar.read keyVar
val _ =
if s = key then
(MVar.put (foundVar, SOME v);
foundFlag := true)
else ()
in
(s,v)
end
fun pred (id, context) =
let
val _ =
if id = Foreach.rootIndex then
if !foundFlag then
(MVar.take keyVar;
foundFlag := false;
())
else (MVar.take keyVar;
MVar.put (foundVar, NONE)
)
else ()
in
true (* continue forevar *)
end
val dict =
Myth.Thread.create (fn () => (pmapWithPred findKey pred L;0))
in
{find=find, dict = dict}
end
end
fun mkList 0 L = L | mkList n L = mkList (n - 1) ((n,n)::L);
fun test n = DataParallelDict.makeDict (mkList n nil);
(*
val {find, dict} = test 100000
val x = find 1
val y = find 2
val z = find 3
*)
|