blob: 5d22aecc9bb24ac3b53e33936a2756ad1100b460 [file] [log] [blame]
Dmitriy Vyukov95643642012-05-11 10:50:03 +04001// 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
Dmitriy Vyukovd6b9a032012-11-06 12:09:40 +04005// The race detector does not understand ParFor synchronization.
6// +build !race
7
Dmitriy Vyukov95643642012-05-11 10:50:03 +04008package runtime_test
9
10import (
11 . "runtime"
12 "testing"
Dmitriy Vyukov95643642012-05-11 10:50:03 +040013)
14
15// Simple serial sanity test for parallelfor.
16func TestParFor(t *testing.T) {
17 const P = 1
18 const N = 20
19 data := make([]uint64, N)
20 for i := uint64(0); i < N; i++ {
21 data[i] = i
22 }
23 desc := NewParFor(P)
Austin Clementsebbdf2a2015-01-28 15:49:26 -050024 ParForSetup(desc, P, N, true, func(desc *ParFor, i uint32) {
Dmitriy Vyukov95643642012-05-11 10:50:03 +040025 data[i] = data[i]*data[i] + 1
26 })
27 ParForDo(desc)
28 for i := uint64(0); i < N; i++ {
29 if data[i] != i*i+1 {
30 t.Fatalf("Wrong element %d: %d", i, data[i])
31 }
32 }
33}
34
35// Test that nonblocking parallelfor does not block.
36func TestParFor2(t *testing.T) {
37 const P = 7
38 const N = 1003
39 data := make([]uint64, N)
40 for i := uint64(0); i < N; i++ {
41 data[i] = i
42 }
43 desc := NewParFor(P)
Austin Clementsebbdf2a2015-01-28 15:49:26 -050044 ParForSetup(desc, P, N, false, func(desc *ParFor, i uint32) {
45 data[i] = data[i]*data[i] + 1
Dmitriy Vyukov95643642012-05-11 10:50:03 +040046 })
47 for p := 0; p < P; p++ {
48 ParForDo(desc)
49 }
50 for i := uint64(0); i < N; i++ {
51 if data[i] != i*i+1 {
52 t.Fatalf("Wrong element %d: %d", i, data[i])
53 }
54 }
55}
56
57// Test that iterations are properly distributed.
58func TestParForSetup(t *testing.T) {
59 const P = 11
60 const N = 101
61 desc := NewParFor(P)
62 for n := uint32(0); n < N; n++ {
63 for p := uint32(1); p <= P; p++ {
Austin Clementsebbdf2a2015-01-28 15:49:26 -050064 ParForSetup(desc, p, n, true, func(desc *ParFor, i uint32) {})
Dmitriy Vyukov95643642012-05-11 10:50:03 +040065 sum := uint32(0)
66 size0 := uint32(0)
67 end0 := uint32(0)
68 for i := uint32(0); i < p; i++ {
69 begin, end := ParForIters(desc, i)
70 size := end - begin
71 sum += size
72 if i == 0 {
73 size0 = size
74 if begin != 0 {
75 t.Fatalf("incorrect begin: %d (n=%d, p=%d)", begin, n, p)
76 }
77 } else {
78 if size != size0 && size != size0+1 {
79 t.Fatalf("incorrect size: %d/%d (n=%d, p=%d)", size, size0, n, p)
80 }
81 if begin != end0 {
82 t.Fatalf("incorrect begin/end: %d/%d (n=%d, p=%d)", begin, end0, n, p)
83 }
84 }
85 end0 = end
86 }
87 if sum != n {
88 t.Fatalf("incorrect sum: %d/%d (p=%d)", sum, n, p)
89 }
90 }
91 }
92}
93
94// Test parallel parallelfor.
95func TestParForParallel(t *testing.T) {
96 N := uint64(1e7)
97 if testing.Short() {
98 N /= 10
99 }
100 data := make([]uint64, N)
101 for i := uint64(0); i < N; i++ {
102 data[i] = i
103 }
104 P := GOMAXPROCS(-1)
Dmitriy Vyukov6ae448e2012-11-06 20:11:16 +0400105 c := make(chan bool, P)
Dmitriy Vyukov95643642012-05-11 10:50:03 +0400106 desc := NewParFor(uint32(P))
Austin Clementsebbdf2a2015-01-28 15:49:26 -0500107 ParForSetup(desc, uint32(P), uint32(N), false, func(desc *ParFor, i uint32) {
Dmitriy Vyukov95643642012-05-11 10:50:03 +0400108 data[i] = data[i]*data[i] + 1
109 })
110 for p := 1; p < P; p++ {
Dmitriy Vyukov6ae448e2012-11-06 20:11:16 +0400111 go func() {
112 ParForDo(desc)
113 c <- true
114 }()
Dmitriy Vyukov95643642012-05-11 10:50:03 +0400115 }
116 ParForDo(desc)
Dmitriy Vyukov6ae448e2012-11-06 20:11:16 +0400117 for p := 1; p < P; p++ {
118 <-c
119 }
Dmitriy Vyukov95643642012-05-11 10:50:03 +0400120 for i := uint64(0); i < N; i++ {
121 if data[i] != i*i+1 {
122 t.Fatalf("Wrong element %d: %d", i, data[i])
123 }
124 }
Shenghou Maf82c59b2012-10-08 01:56:27 +0800125
126 data, desc = nil, nil
127 GC()
Dmitriy Vyukov95643642012-05-11 10:50:03 +0400128}