Stuart Gordon
Stuart Gordon

Reputation: 185

Issues updating list elements

The following function is meant to add parallelism by updating elements of list in chunks, in an attempt to load balance it. However, its giving me: property 'item' cannot be set at xs.[x1] in the internal loop. I have to use a list, as the list past to the function is part of a bigger algorithm. Any suggestions?

let pmap_tpl_parforlb f (xs:list<_>) =
    let chunkLength = xs.Length / numProc 
    Parallel.For(0,numProc, fun c ->    
        let x = c * chunkLength
        let y = (c * chunkLength) + chunkLength
        let x1 = x+1
        for x1 in 0..y-1 do
            xs.[x1] <- f (xs.[x1])
    ) |> ignore
    xs

Upvotes: 0

Views: 89

Answers (2)

Jack P.
Jack P.

Reputation: 11525

The built-in F# list type is immutable, which is why you're getting that error. You can use the index notation (blah.[idx]) to access a list value, but it's extremely uncommon and also slow because it's an O(n) operation.

From the snippet of code you posted, it seems like you should make xs an array instead of a list. Or, use List.toArray or Array.ofList to convert the list to an array before mutating it in the Parallel.For.

Upvotes: 2

usr
usr

Reputation: 171206

  1. xs.Length / numProc is rounding down (you're losing elements that way, e.g. 1 / 8 = 0).
  2. the last chunk might not be of length chunkLength but shorter. You have to reconcile that fact.
  3. Shouldn't x1 start at 0, not at 1?

Anyway, use the debugger to inspect the runtime values of variables and you'll find all bugs.

Upvotes: 0

Related Questions