Why do prints to console get mixed up when doing parallel computations?

Viewed 146

While running some code that performs parallel computations the output becomes garbled: different messages get mixed up. Here is a sample:

Iteration 1
Iteration
Iteration 23 of 19 - Calculating P&L for test window ending at 10/28/1968 12:00:00 AM

 of
Iteration 4
Iteration  of
Iteration 5
Iteration
Iteration 19 - Calculating P&L for test window ending at  of 19 - Calculating P&L for test window ending at 5/29/1974 12:00:00 AM
6 of 878/18/1971 12:00:00 AM19 - Calculating P&L for test window ending at 3/4/1977 12:00:00 AM


 of 19 of
 of 19 - Calculating P&L for test window ending at 6/25/1985 12:00:00 AM

When running the same program sequentially the console output comes out nice, with no garbling.

Printing to the console is done by this function:

let windowTrainTest (comm: Communication) critFoo count (model: IModel) (assets: Assets) (paramList: Parameters list) =
    // Deleted some code here
    if comm = Verbose then
        let msg1 = sprintf "\nwindowTrainTestPandL: First date: %A, Last date: %A\nBest Criterion: %.2f\n" fDate lDate bestCriterion
        let msg2 = sprintf "Best Parameters: %A\n" bestParameters 
        printfn "%s" <| msg1 + msg2

    (pandl, wgts), bestParameters, ( ["Criterion", bestCriterion]            |> Map.ofList,
                                     ["FirstDate", fDate; "LastDate", lDate] |> Map.ofList )

Parallelization is done by this portion of the program:

let pSeqMapi f (xs: seq<'T>) = xs |> PSeq.mapi f

let trainTest n i (trainSize, fullSize) =
        let takenAssets = assets |> Assets.take (min fullSize len)
        lastDate takenAssets
        |> printfn "\nIteration %d of %d - Calculating P&L for test window ending at %A\n" (i + 1) n
        paramList
        |> windowTrainTest comm' critFoo trainSize model takenAssets

    let mapTrainTest (initSizes: (int * int) list) =
        let f = trainTest initSizes.Length
        match calcType with
        | PSeq -> initSizes |> pSeqMapi f |> List.ofSeq
        | _    -> initSizes |> Seq.mapi f |> List.ofSeq

Is there a way to avoid this kind of behavior, for example by flushing the message to the console?

2 Answers
Related