parallel

package
v0.0.0-...-64a59f3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 12, 2025 License: BSD-3-Clause Imports: 4 Imported by: 1

Documentation

Overview

Package parallel provides functions for expressing parallel algorithms.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func And

func And(predicates ...func() bool) bool

And receives zero or more predicate functions and executes them in parallel.

Each predicate is invoked in its own goroutine, and And returns only when all predicates have terminated, combining all return values with the && operator, with true as the default return value.

If one or more predicates panic, the corresponding goroutines recover the panics, and And eventually panics with the left-most recovered panic value.

func Do

func Do(thunks ...func())

Do receives zero or more thunks and executes them in parallel.

Each thunk is invoked in its own goroutine, and Do returns only when all thunks have terminated.

If one or more thunks panic, the corresponding goroutines recover the panics, and Do eventually panics with the left-most recovered panic value.

Example
package main

import (
	"errors"
	"fmt"
	"github.com/intel/forGoParallel/parallel"
)

func main() {
	var fib func(int) (int, error)

	fib = func(n int) (result int, err error) {
		if n < 0 {
			err = errors.New("invalid argument")
		} else if n < 2 {
			result = n
		} else {
			var n1, n2 int
			n1, err = fib(n - 1)
			if err != nil {
				return
			}
			n2, err = fib(n - 2)
			result = n1 + n2
		}
		return
	}

	type intErr struct {
		n   int
		err error
	}

	var parallelFib func(int) intErr

	parallelFib = func(n int) (result intErr) {
		if n < 0 {
			result.err = errors.New("invalid argument")
		} else if n < 20 {
			result.n, result.err = fib(n)
		} else {
			var n1, n2 intErr
			parallel.Do(
				func() { n1 = parallelFib(n - 1) },
				func() { n2 = parallelFib(n - 2) },
			)
			result.n = n1.n + n2.n
			if n1.err != nil {
				result.err = n1.err
			} else {
				result.err = n2.err
			}
		}
		return
	}

	if result := parallelFib(-1); result.err != nil {
		fmt.Println(result.err)
	} else {
		fmt.Println(result.n)
	}

}
Output:

invalid argument

func Or

func Or(predicates ...func() bool) bool

Or receives zero or more predicate functions and executes them in parallel.

Each predicate is invoked in its own goroutine, and Or returns only when all predicates have terminated, combining all return values with the || operator, with false as the default return value.

If one or more predicates panic, the corresponding goroutines recover the panics, and Or eventually panics with the left-most recovered panic value.

func PrefixSum

func PrefixSum[T Addable](slice []T) []T

func Range

func Range(low, high, n int, f func(low, high int))

Range receives a range, a batch count n, and a range function f, divides the range into batches, and invokes the range function for each of these batches in parallel, covering the half-open interval from low to high, including low but excluding high.

The range is specified by a low and high integer, with low <= high. The batches are determined by dividing up the size of the range (high - low) by n. If n is 0, a reasonable default is used that takes runtimes.NumCPU() into account.

The range function is invoked for each batch in its own goroutine, with 0 <= low <= high, and Range returns only when all range functions have terminated.

Range panics if high < low, or if n < 0.

If one or more range function invocations panic, the corresponding goroutines recover the panics, and Range eventually panics with the left-most recovered panic value.

func RangeAnd

func RangeAnd(low, high, n int, f func(low, high int) bool) bool

RangeAnd receives a range, a batch count n, and a range predicate function f, divides the range into batches, and invokes the range predicate for each of these batches in parallel, covering the half-open interval from low to high, including low but excluding high.

The range is specified by a low and high integer, with low <= high. The batches are determined by dividing up the size of the range (high - low) by n. If n is 0, a reasonable default is used that takes runtime.NumCPU() into account.

The range predicate is invoked for each batch in its own goroutine, with 0 <= low <= high, and RangeAnd returns only when all range predicates have terminated, combining all return values with the && operator.

RangeAnd panics if high < low, or if n < 0.

If one or more range predicate invocations panic, the corresponding goroutines recover the panics, and RangeAnd eventually panics with the left-most recovered panic value.

func RangeOr

func RangeOr(low, high, n int, f func(low, high int) bool) bool

RangeOr receives a range, a batch count n, and a range predicate function f, divides the range into batches, and invokes the range predicate for each of these batches in parallel, covering the half-open interval from low to high, including low but excluding high.

The range is specified by a low and high integer, with low <= high. The batches are determined by dividing up the size of the range (high - low) by n. If n is 0, a reasonable default is used that takes runtime.NumCPU() into account.

The range predicate is invoked for each batch in its own goroutine, with 0 <= low <= high, and RangeOr returns only when all range predicates have terminated, combining all return values with the || operator.

RangeOr panics if high < low, or if n < 0.

If one or more range predicate invocations panic, the corresponding goroutines recover the panics, and RangeOr eventually panics with the left-most recovered panic value.

func RangeReduce

func RangeReduce[T any](
	low, high, n int,
	reduce func(low, high int) T,
	join func(x, y T) T,
) T

RangeReduce receives a range, a batch count, a range reduce function, and a join function, divides the range into batches, and invokes the range reducer for each of these batches in parallel, covering the half-open interval from low to high, including low but excluding high. The results of the range reducer invocations are then combined by repeated invocations of join.

The range is specified by a low and high integer, with low <= high. The batches are determined by dividing up the size of the range (high - low) by n. If n is 0, a reasonable default is used that takes runtime.NumCPU() into account.

The range reducer is invoked for each batch in its own goroutine, with 0 <= low <= high, and RangeReduce returns only when all range reducers and pair reducers have terminated.

RangeReduce panics if high < low, or if n < 0.

If one or more reducer invocations panic, the corresponding goroutines recover the panics, and RangeReduce eventually panics with the left-most recovered panic value.

Example
package main

import (
	"fmt"
	"github.com/intel/forGoParallel/parallel"
)

func numDivisors(n int) int {
	return parallel.RangeReduceSum(
		1, n+1, 0,
		func(low, high int) int {
			var sum int
			for i := low; i < high; i++ {
				if (n % i) == 0 {
					sum++
				}
			}
			return sum
		},
	)
}

func main() {
	findPrimes := func(n int) []int {
		result := parallel.RangeReduce(
			2, n, 0,
			func(low, high int) interface{} {
				var slice []int
				for i := low; i < high; i++ {
					if numDivisors(i) == 2 { // see RangeReduceInt example
						slice = append(slice, i)
					}
				}
				return slice
			},
			func(x, y interface{}) interface{} {
				return append(x.([]int), y.([]int)...)
			},
		)
		return result.([]int)
	}

	fmt.Println(findPrimes(20))

}
Output:

[2 3 5 7 11 13 17 19]

func RangeReduceProduct

func RangeReduceProduct[T Multipliable](
	low, high, n int,
	reduce func(low, high int) T,
) T

RangeReduceProduct receives a range, a batch count, and a range reducer function, divides the range into batches, and invokes the range reducer for each of these batches in parallel, covering the half-open interval from low to high, including low but excluding high. The results of the range reducer invocations are then multiplied with each other.

The range is specified by a low and high integer, with low <= high. The batches are determined by dividing up the size of the range (high - low) by n. If n is 0, a reasonable default is used that takes runtime.NumCPU() into account.

The range reducer is invoked for each batch in its own goroutine, with 0 <= low <= high, and RangeReduceIntProduct returns only when all range reducers and pair reducers have terminated.

RangeReduceIntProduct panics if high < low, or if n < 0.

If one or more reducer invocations panic, the corresponding goroutines recover the panics, and RangeReduceIntProducet eventually panics with the left-most recovered panic value.

func RangeReduceSum

func RangeReduceSum[T Addable](low, high, n int, reduce func(low, high int) T) T

RangeReduceSum receives a range, a batch count, and a range reducer function, divides the range into batches, and invokes the range reducer for each of these batches in parallel, covering the half-open interval from low to high, including low but excluding high. The results of the range reducer invocations are then added together.

The range is specified by a low and high integer, with low <= high. The batches are determined by dividing up the size of the range (high - low) by n. If n is 0, a reasonable default is used that takes runtime.NumCPU() into account.

The range reducer is invoked for each batch in its own goroutine, with 0 <= low <= high, and RangeReduceIntSum returns only when all range reducers and pair reducers have terminated.

RangeReduceIntSum panics if high < low, or if n < 0.

If one or more reducer invocations panic, the corresponding goroutines recover the panics, and RangeReduceIntSum eventually panics with the left-most recovered panic value.

Example
package main

import (
	"fmt"
	"github.com/intel/forGoParallel/parallel"
)

func main() {
	numDivisors := func(n int) int {
		return parallel.RangeReduceSum(
			1, n+1, 0,
			func(low, high int) int {
				var sum int
				for i := low; i < high; i++ {
					if (n % i) == 0 {
						sum++
					}
				}
				return sum
			},
		)
	}

	fmt.Println(numDivisors(12))

}
Output:

6

func Reduce

func Reduce[T any](
	join func(x, y T) T,
	firstFunction func() T,
	moreFunctions ...func() T,
) T

Reduce receives one or more functions, executes them in parallel, and combines their results with the join function in parallel.

Each function is invoked in its own goroutine, and Reduce returns only when all functions have terminated.

If one or more functions panic, the corresponding goroutines recover the panics, and Reduce eventually panics with the left-most recovered panic value.

func ReduceProduct

func ReduceProduct[T Multipliable](functions ...func() T) T

ReduceProduct receives zero or more functions, executes them in parallel, and multiplies their results in parallel.

Each function is invoked in its own goroutine, and ReduceProduct returns only when all functions have terminated.

If one or more functions panic, the corresponding goroutines recover the panics, and ReduceProduct eventually panics with the left-most recovered panic value.

func ReduceSum

func ReduceSum[T Addable](functions ...func() T) (result T)

ReduceSum receives zero or more functions, executes them in parallel, and adds their results in parallel.

Each function is invoked in its own goroutine, and ReduceSum returns only when all functions have terminated.

If one or more functions panic, the corresponding goroutines recover the panics, and ReduceSum eventually panics with the left-most recovered panic value.

Types

type Addable

type Addable interface {
	~uint | ~int | ~uintptr |
		~uint8 | ~uint16 | ~uint32 | ~uint64 |
		~int8 | ~int16 | ~int32 | ~int64 |
		~float32 | ~float64 |
		~complex64 | ~complex128 |
		~string
}

type Multipliable

type Multipliable interface {
	~uint | ~int | ~uintptr |
		~uint8 | ~uint16 | ~uint32 | ~uint64 |
		~int8 | ~int16 | ~int32 | ~int64 |
		~float32 | ~float64 |
		~complex64 | ~complex128
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL