2017-12-07 3 views
1

Ich habe etwas Code, der ohne Probleme ohne Parallelisierung läuft. Derselbe Code erzeugt jedoch Ausnahmen, wenn ich versuche, ihn unter Verwendung von PSeq anstelle von Seq auszuführen. Die Nachrichten, die ich bekomme, sehen ein bisschen zufällig aus, sie sind schwer exakt zu replizieren.Kann ich während der Verwendung von open FSharp.Collections.ParallelSeq eine R-Funktion aufrufen?

Hier ist der Code. Wenn die Ausnahme auftritt, werden die drei Zeilen beginnend mit let tmp2 hervorgehoben.

let frameToRMatrix (df: Frame<'R,string>) = 

    let foo k df : float list = 
     df 
     |> Frame.getCol k 
     |> Series.values 
     |> List.ofSeq 

    let folder acc k = (k, foo k df |> box) :: acc 

    let tmp = 
     List.fold folder [] (df.ColumnKeys |> List.ofSeq) 
     |> namedParams 

    let sd = df |> Frame.getCol "Vol0" |> Series.lastValue 
    let sd = sd * 1000.0 |> int 

    printfn "%s" "I was here" 

    let rand = System.Random(sd) 
    let rms = rand.Next(500) 
    System.Threading.Thread.Sleep rms 

    let tmp2 = 
     tmp 
     |> R.cbind // This line prints something on the console the first time it is executed 

    printfn "%s" "And here too" 

    tmp2 

Der obige Code enthält die Generierung von Zufallszahlen und Aufrufe an System.Threading.Thread.Sleep. Wenn ich diesen Code nicht enthalten, die nicht unter sequentieller Ausführung benötigt wird, erhalte ich die Meldung:

System.ArgumentException: 'An item with the same key has already been added.' 

und den folgenden auf der Konsole:

I was here 
I was here 
[1] 4095 

So wird die Ausführung nie auf die And here too Linien .

Wenn ich den Zufallsgenerator und den Aufruf an sleep anschließe, erhalte ich unterschiedliche Ergebnisse, die von den Build-Optionen abhängig zu sein scheinen.

Im Folgenden sind vier Beispiele, mit den Build-Optionen, Fehlermeldung und was ich auf der Konsole sehe. Beachten Sie, dass es in allen Beispielen vier Instanzen von I was here, aber nur drei Instanzen von And here too gibt.

--------------------------------------- 
Any CPU with Prefer 32-bit checked 
    System.Runtime.InteropServices.SEHException: 'External component has thrown an exception.' 

I was here 
I was here 
[1] 4095 
And here too 
I was here 
And here too 
I was here 
And here too 
Warning: stack imbalance in 'lazyLoadDBfetch', 66 then 65 
Error in value[[3L]](cond) : unprotect_ptr: pointer not found 


    --------------------------------------- 
Any CPU with Prefer 32-bit unchecked 
    System.Runtime.InteropServices.SEHException: 'External component has thrown an exception.' 


I was here 
I was here 
[1] 1.759219e+13 
And here too 
I was here 
And here too 
I was here 
And here too 
Error: cons memory exhausted (limit reached?) 
Error: cons memory exhausted (limit reached?) 




    --------------------------------------- 
x86 
System.AccessViolationException" 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.' 


I was here 
I was here 
[1] 4095 
And here too 
I was here 
And here too 
I was here 
And here too 

    --------------------------------------- 
x64 
Exception thrown: 'System.AccessViolationException' in Unknown Module. Attermpted to read or write protected memory. 
$$$ - MachineLearning.signal: Calculating signal for ticker AAPL 
$$$ - MachineLearning.signal: Calculating signal for ticker AAPL 
I was here 
I was here 
[1] 1.759219e+13 
And here too 
I was here 
And here too 
I was here 
And here too 
Error in loadNamespace(name) : 
    no function to return from, jumping to top level 

Antwort

1

Aufgrund meiner Erfahrung mit dem Debuggen subtile Probleme mit Gewinden in dem R-Typ-Anbieter, ich denke, die Antwort ist nein - leider ist die R nativen Interop-Schicht nicht Thread-sicher und so kann man es nicht aus mehrer nennen Threads in Ihrer F # -Anwendung.

Ich denke, dass die standardmäßige Art, R parallel zu betreiben, ist, mehrere R.exe Prozesse zu erzeugen, die die Arbeit machen. Ich glaube nicht, dass Sie mehrere unabhängige R-Prozesse problemlos von F # aus initialisieren können. Daher ist es wahrscheinlich am besten, mehrere .NET-Prozesse zu erstellen, die jeweils eine R-Engine steuern.

+0

Aufruf List.map auf identische Argumente, ich erstellt zwei identische Objekte, Instanzen der gleichen Klasse und führte die gleiche Methode (nennen Sie es Obj.crashable, die eine abgestürzte) für jedes Objekt. Ich habe die crashbaren Methoden so konfiguriert, dass sie nacheinander ausgeführt werden. Die Parallelisierung war also eine höhere Ebene im Aufrufbaum. Interessanterweise stürzte das Programm nicht ab, aber meine CPU-Auslastung blieb bei 15%, genauso wie wenn ich das gleiche tat, aber nur mit einem der beiden Objekte. – Soldalma

Verwandte Themen