~james-page/ubuntu/utopic/gccgo-go/cgo-support

« back to all changes in this revision

Viewing changes to src/pkg/runtime/parfor_test.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-01-27 09:18:55 UTC
  • Revision ID: package-import@ubuntu.com-20140127091855-zxfshmykfsyyw4b2
Tags: upstream-1.2
ImportĀ upstreamĀ versionĀ 1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2012 The Go Authors. All rights reserved.
 
2
// Use of this source code is governed by a BSD-style
 
3
// license that can be found in the LICENSE file.
 
4
 
 
5
// The race detector does not understand ParFor synchronization.
 
6
// +build !race
 
7
 
 
8
package runtime_test
 
9
 
 
10
import (
 
11
        . "runtime"
 
12
        "testing"
 
13
        "unsafe"
 
14
)
 
15
 
 
16
var gdata []uint64
 
17
 
 
18
// Simple serial sanity test for parallelfor.
 
19
func TestParFor(t *testing.T) {
 
20
        const P = 1
 
21
        const N = 20
 
22
        data := make([]uint64, N)
 
23
        for i := uint64(0); i < N; i++ {
 
24
                data[i] = i
 
25
        }
 
26
        desc := NewParFor(P)
 
27
        // Avoid making func a closure: parfor cannot invoke them.
 
28
        // Since it doesn't happen in the C code, it's not worth doing
 
29
        // just for the test.
 
30
        gdata = data
 
31
        ParForSetup(desc, P, N, nil, true, func(desc *ParFor, i uint32) {
 
32
                data := gdata
 
33
                data[i] = data[i]*data[i] + 1
 
34
        })
 
35
        ParForDo(desc)
 
36
        for i := uint64(0); i < N; i++ {
 
37
                if data[i] != i*i+1 {
 
38
                        t.Fatalf("Wrong element %d: %d", i, data[i])
 
39
                }
 
40
        }
 
41
}
 
42
 
 
43
// Test that nonblocking parallelfor does not block.
 
44
func TestParFor2(t *testing.T) {
 
45
        const P = 7
 
46
        const N = 1003
 
47
        data := make([]uint64, N)
 
48
        for i := uint64(0); i < N; i++ {
 
49
                data[i] = i
 
50
        }
 
51
        desc := NewParFor(P)
 
52
        ParForSetup(desc, P, N, (*byte)(unsafe.Pointer(&data)), false, func(desc *ParFor, i uint32) {
 
53
                d := *(*[]uint64)(unsafe.Pointer(desc.Ctx))
 
54
                d[i] = d[i]*d[i] + 1
 
55
        })
 
56
        for p := 0; p < P; p++ {
 
57
                ParForDo(desc)
 
58
        }
 
59
        for i := uint64(0); i < N; i++ {
 
60
                if data[i] != i*i+1 {
 
61
                        t.Fatalf("Wrong element %d: %d", i, data[i])
 
62
                }
 
63
        }
 
64
}
 
65
 
 
66
// Test that iterations are properly distributed.
 
67
func TestParForSetup(t *testing.T) {
 
68
        const P = 11
 
69
        const N = 101
 
70
        desc := NewParFor(P)
 
71
        for n := uint32(0); n < N; n++ {
 
72
                for p := uint32(1); p <= P; p++ {
 
73
                        ParForSetup(desc, p, n, nil, true, func(desc *ParFor, i uint32) {})
 
74
                        sum := uint32(0)
 
75
                        size0 := uint32(0)
 
76
                        end0 := uint32(0)
 
77
                        for i := uint32(0); i < p; i++ {
 
78
                                begin, end := ParForIters(desc, i)
 
79
                                size := end - begin
 
80
                                sum += size
 
81
                                if i == 0 {
 
82
                                        size0 = size
 
83
                                        if begin != 0 {
 
84
                                                t.Fatalf("incorrect begin: %d (n=%d, p=%d)", begin, n, p)
 
85
                                        }
 
86
                                } else {
 
87
                                        if size != size0 && size != size0+1 {
 
88
                                                t.Fatalf("incorrect size: %d/%d (n=%d, p=%d)", size, size0, n, p)
 
89
                                        }
 
90
                                        if begin != end0 {
 
91
                                                t.Fatalf("incorrect begin/end: %d/%d (n=%d, p=%d)", begin, end0, n, p)
 
92
                                        }
 
93
                                }
 
94
                                end0 = end
 
95
                        }
 
96
                        if sum != n {
 
97
                                t.Fatalf("incorrect sum: %d/%d (p=%d)", sum, n, p)
 
98
                        }
 
99
                }
 
100
        }
 
101
}
 
102
 
 
103
// Test parallel parallelfor.
 
104
func TestParForParallel(t *testing.T) {
 
105
        N := uint64(1e7)
 
106
        if testing.Short() {
 
107
                N /= 10
 
108
        }
 
109
        data := make([]uint64, N)
 
110
        for i := uint64(0); i < N; i++ {
 
111
                data[i] = i
 
112
        }
 
113
        P := GOMAXPROCS(-1)
 
114
        c := make(chan bool, P)
 
115
        desc := NewParFor(uint32(P))
 
116
        gdata = data
 
117
        ParForSetup(desc, uint32(P), uint32(N), nil, false, func(desc *ParFor, i uint32) {
 
118
                data := gdata
 
119
                data[i] = data[i]*data[i] + 1
 
120
        })
 
121
        for p := 1; p < P; p++ {
 
122
                go func() {
 
123
                        ParForDo(desc)
 
124
                        c <- true
 
125
                }()
 
126
        }
 
127
        ParForDo(desc)
 
128
        for p := 1; p < P; p++ {
 
129
                <-c
 
130
        }
 
131
        for i := uint64(0); i < N; i++ {
 
132
                if data[i] != i*i+1 {
 
133
                        t.Fatalf("Wrong element %d: %d", i, data[i])
 
134
                }
 
135
        }
 
136
 
 
137
        data, desc = nil, nil
 
138
        GC()
 
139
}