misaochan
misaochan

Reputation: 890

F# Parallel.ForEach invalid method overload

Creating a Parallel.ForEach expression of this form:

    let low = max 1 (k-m)
    let high = min (k-1) n
    let rangesize = (high+1-low)/(PROCS*3)

    Parallel.ForEach(Partitioner.Create(low, high+1, rangesize), (fun j ->

            let i = k - j
            if x.[i-1] = y.[j-1] then
                a.[i] <- b.[i-1] + 1
            else 
                a.[i] <- max c.[i] c.[i-1] 
        )) |> ignore

Causes me to receive the error: No overloads match for method 'ForEach'. However I am using the Parallel.ForEach<TSource> Method (Partitioner<TSource>, Action<TSource>) and it seems right to me. Am I missing something?

Edited: I am trying to obtain the same results as the code below (that does not use a Partitioner):

let low = max 1 (k-m)
let high = min (k-1) n
let rangesize = (high+1-low)/(PROCS*3)

let A = [| low .. high |]
Parallel.ForEach(A, fun (j:int) ->

    let i = k - j
    if x.[i-1] = y.[j-1] then
        a.[i] <- b.[i-1] + 1
    else 
        a.[i] <- max c.[i] c.[i-1] 
    ) |> ignore

Upvotes: 1

Views: 613

Answers (1)

Tomas Petricek
Tomas Petricek

Reputation: 243096

Are you sure that you have opened all necessary namespaces, all the values you are using (low, high and PROCS) are defined and that your code does not accidentally redefine some of the names that you're using (like Partitioner)?

I created a very simple F# script with this code and it seems to be working fine (I refactored the code to create a partitioner called p, but that does not affect the behavior):

open System.Threading.Tasks
open System.Collections.Concurrent

let PROCS = 10
let low, high = 0, 100

let p = Partitioner.Create(low, high+1, high+1-low/(PROCS*3))
Parallel.ForEach(p, (fun j ->
    printfn "%A" j  // Print the desired range (using %A as it is a tuple)
)) |> ignore

It is important that the value j is actually a pair of type int * int, so if the body uses it in a wrong way (e.g. as an int), you will get the error. In that case, you can add a type annotation to j and you would get a more useful error elsewhere:

Parallel.ForEach(p, (fun (j:int * int) ->
    printfn "%d" j // Error here, because `j` is used as an int, but it is a pair!
)) |> ignore

This means that if you want to perform something for all j values in the original range, you need to write something like this:

Parallel.ForEach(p, (fun (loJ, hiJ) ->
  for j in loJ .. hiJ - 1 do // Iterate over all js in this partition
    printfn "%d" j           // process the current j
)) |> ignore

Aside, I guess that the last argument to Partitioner.Create should actually be (high+1-low)/(PROCS*3) - you probably want to divide the total number of steps, not just the low value.

Upvotes: 3

Related Questions