2011-12-28 35 views
19

Làm cách nào chúng tôi có thể đánh giá sổ ghi chép Mathematica từ dòng lệnh (tức là khi chạy hạt nhân ở chế độ dòng lệnh)?Cách đánh giá sổ ghi chép từ dòng lệnh?

Giả sử chúng tôi đang làm việc trên máy từ xa. Tôi biết nó có thể chuyển đổi sổ ghi chép thành một tập tin m, và đánh giá nó, nhưng tôi tò mò nếu nó có thể làm điều này trực tiếp bằng cách sử dụng sổ ghi chép.


Đây là những gì tôi có cho đến nay:

Thứ nhất, we need to start a headless X server trên máy Linux từ xa, do đó kết thúc trước có thể chạy ở đó (và mở máy tính xách tay). Bỏ qua bước này nếu bạn đang làm việc trên máy cục bộ.

Xvfb :1 & 
export DISPLAY=:1 

Sau khi tôi bắt đầu một hạt nhân Mathematica (math) và làm như sau.

Cần sử dụng UsingFrontEnd vì mở sổ ghi chép yêu cầu giao diện người dùng. test.nb có một ô nhập có chứa a=1.

In[1]:= [email protected]["test.nb"] 

Out[1]= -NotebookObject- 

Sau khi cố gắng đánh giá máy tính xách tay, rõ ràng tôi nhận được một dialog, và tôi cần phải sử dụng Return[] trở lại. Tôi không chắc chắn lý do tại sao dòng đầu vào bắt đầu đếm từ 1 lần nữa (một hạt nhân mới đã được bắt đầu bởi giao diện người dùng?) Lưu ý rằng a không đạt được giá trị.

In[2]:= [email protected][nb] 

In[1]:= a 

Out[1]= a 

In[2]:= Return[] 

Out[2]= a 

Sau khi trở về từ hộp thoại, a vẫn không có giá trị.

In[3]:= a 

Out[3]= a 
+0

Hình như chúng ta đang làm việc trong một cách tương tự và không kém phần lười biếng! – acl

+1

+1 Tôi cũng muốn biết điều này! Tôi rất muốn đánh giá sổ ghi chép của mình trên một hệ thống từ xa trên HPC của chúng tôi. –

Trả lời

10

Đây là trên Windows, sử dụng Arnouds công việc tốt đẹp và chỉ cần thêm đồng bằng cũ MathLink (khá chậm btw ...):

link = LinkCreate["8000", LinkProtocol -> "TCPIP"]; 
UsingFrontEnd[ 
NotebookPauseForEvaluation[nb_] := Module[{}, 
While[ NotebookEvaluatingQ[nb], Pause[.25] ] ]; 
NotebookEvaluatingQ[nb_]:=Module[{}, 
SelectionMove[nb,All,Notebook]; 
[email protected]@Map["Evaluating"/.#&,Developer`CellInformation[nb]] 
]; 
nb = NotebookOpen["G:\\mma\\test.nb"]; 
SelectionMove[nb, Before, Notebook]; 
NotebookWrite[nb, Cell["Link = LinkConnect[\"8000\", LinkProtocol -> \"TCPIP\"]", "Input"]]; 
SelectionMove[nb, After, Notebook]; 
NotebookWrite[nb, Cell["LinkWrite[Link, a]", "Input"]]; 
SelectionMove[nb, All, Notebook]; 
SelectionEvaluate[nb]; 
a = LinkRead[link]; 
Print["a = ",a]; 
] 
+0

Cảm ơn! Chúng ta có thực sự cần 'LinkProtocol ->" TCPIP "' ở đây hay chúng ta có thể sử dụng mặc định hiệu quả hơn không? (Tôi nghĩ rằng theo mặc định nó sử dụng các tập tin ánh xạ bộ nhớ cho commuincation interprocess) – Szabolcs

+0

Có lẽ. Ít nhất tôi không thể làm cho nó hoạt động với LinkProtocol -> "SharedMemory" –

+0

BTW: Tại sao bạn thực sự cần điều này? Việc lưu kết quả của bạn bằng DumpSave hay một số kết quả như vậy không dễ dàng hơn không? –

11

Đây là câu trả lời một phần cho câu hỏi của bạn. Đoạn mã sau mở một sổ ghi chép, gán cho nó một hạt nhân "Thử nghiệm" , đánh giá sổ ghi chép trong hạt nhân đó, đợi cho việc đánh giá kết thúc và lưu sổ ghi chép đã đánh giá. Tuy nhiên, không phải là gây ra a được xác định trong hạt nhân dòng lệnh cục bộ.

này chờ đợi đánh giá kernel để kết thúc trong máy tính xách tay:

NotebookPauseForEvaluation[nb_] := Module[{}, 
While[ NotebookEvaluatingQ[nb], Pause[.25] ] ] 

kiểm tra này, nếu bất kỳ tế bào nào trong máy tính xách tay vẫn còn đang được đánh giá:

NotebookEvaluatingQ[nb_]:=Module[{}, 
SelectionMove[nb,All,Notebook]; 
[email protected]@Map["Evaluating"/.#&,Developer`CellInformation[nb]] 
] 

Đây chỉ là một thông điệp chẩn đoán, khi bạn đang cố gắng xác định lại hạt nhân như "Kiểm tra":

AddTestEvaluator::exists = "Evaluator `1` is already defined, but has a definition that is `2` and not the expected `3`."; 

Đây là mã t o thêm một đánh giá, như "Test" để front-end:

AddTestEvaluator[evaluator_String] := Module[ 
{evaluatornames, testevaluator}, 
evaluatornames = EvaluatorNames /. Options[$FrontEnd, EvaluatorNames]; 
testevaluator = evaluator -> {"AutoStartOnLaunch" -> False}; 
Which[ 
    MemberQ[evaluatornames, evaluator -> {"AutoStartOnLaunch" -> False}], 
    Null, 
    MemberQ[evaluatornames, evaluator -> _], 
    Message[AddTestEvaluator::exists, 
    evaluator, 
    evaluator /. (EvaluatorNames /. Options[$FrontEnd, EvaluatorNames]), 
    {"AutoStartOnLaunch" -> False} 
], 
True, 
AppendTo[evaluatornames, testevaluator]; 
SetOptions[$FrontEnd, EvaluatorNames -> evaluatornames] 
] 
] 

Cuối cùng, đây là đoạn code để đánh giá một máy tính xách tay dưới một hạt nhân "Test" và tiết kiệm hạt nhân đánh giá:

UsingFrontEnd[  
    AddTestEvaluator["Test"]; 
    nb = NotebookOpen["test.nb"]; 
    SetOptions[nb,Evaluator->"Test"]; 
    SelectionMove[nb,All,Notebook]; 
    SelectionEvaluate[nb]; 
    NotebookPauseForEvaluation[nb]; 
    NotebookSave[nb] 
] 

tôi vẫn đang xem xét giải pháp cho vấn đề đầy đủ của bạn (có a được xác định trong lệnh hạt nhân địa phương dòng).

+1

Điều này đã rất hữu ích! Bạn có biết nếu có một cách dễ dàng * * để chuyển các định nghĩa liên kết với một biểu tượng giữa các hạt nhân? Đây chính xác là những gì xảy ra trong quá trình tính toán song song, và những gì 'DistributeDefinitions' làm. Vì vậy, tôi đoán điều này đã được thực hiện. Nhưng các chức năng có thể truy cập người dùng này không? – Szabolcs

Các vấn đề liên quan