OSDN Git Service

The multithread handling for MM/MD is improved.
authortoshinagata1964 <toshinagata1964@a2be9bc6-48de-4e38-9406-05402d4bc13c>
Wed, 3 Feb 2010 16:02:23 +0000 (16:02 +0000)
committertoshinagata1964 <toshinagata1964@a2be9bc6-48de-4e38-9406-05402d4bc13c>
Wed, 3 Feb 2010 16:02:23 +0000 (16:02 +0000)
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/molby/trunk@6 a2be9bc6-48de-4e38-9406-05402d4bc13c

MolLib/MD/MDCore.c
MolLib/MD/MDCore.h
memo.txt
wxSources/MyDocument.cpp
wxSources/MyDocument.h

index 9e5337b..4b329e7 100644 (file)
@@ -1588,6 +1588,18 @@ md_prepare(MDArena *arena, int check_only)
                arena->pair_forces = NULL;
        }
 
+       /*  Allocate ring buffer   */
+       if (arena->ring != NULL)
+               free(arena->ring);
+       arena->nringframes = 2000 / mol->natoms;
+       if (arena->nringframes == 0)
+               arena->nringframes = 1;
+       arena->ring = (Vector *)malloc(sizeof(Vector) * mol->natoms * arena->nringframes);
+       if (arena->ring == NULL)
+               md_panic(arena, ERROR_out_of_memory);
+       arena->ring_next = 0;
+       arena->ring_count = 0;
+
        /*  Initialize temperature statistics  */
        arena->sum_temperature = 0.0;
        arena->nsum_temperature = 0;
@@ -3016,6 +3028,8 @@ md_arena_release(MDArena *arena)
                free(arena->old_pos);
        if (arena->graphite != NULL)
                graphite_release(arena->graphite);
+       if (arena->ring != NULL)
+               free(arena->ring);
        free(arena);
 }
 
index 9329d3a..59e8757 100644 (file)
@@ -267,6 +267,11 @@ typedef struct MDArena {
 
        Int    natoms_uniq;     /*  Number of symmetry-unique atoms  */
        
+       Vector *ring;           /*  Ring buffer for sending coordinates between threads */
+       Int    nringframes;     /*  Number of frames in the ring buffer (2000 / natoms)  */
+       Int    ring_next;       /*  Next frame index to store data  */
+       Int    ring_count;      /*  Number of frames currently in the ring buffer  */
+
        /*  Parameters are copied from mol->par and gBuiltinParameters for each call to md_prepare()  */
        Parameter *par;
        
index fe1c24a..cd1dcfe 100755 (executable)
--- a/memo.txt
+++ b/memo.txt
@@ -8,3 +8,7 @@ make -f Makefile_at でビルド。
 なお、Mac 用の gfortran は http://r.research.att.com/tools/ にあるやつがいい。hpc.sourceforge.net のやつはいろいろと使い方が複雑。
 OS 10.4 用のユニバーサルバイナリは、export ISYSROOT='-isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -arch ppc -arch i386' としたあと make -f Makefile_at とすると作ることができる。MacBook 上でビルドして、PowerPC の 10.4 に持って行っても実行できたので、たぶん大丈夫じゃないかと。
 原子タイプのアサインだけなら、antechamber を -c オプション無しで走らせればいいんだな。気がついてなかった。(どれぐらい使えるのかは不明だが。)
+
+2010.2.2.
+  MD/Minimize のサブスレッドの処理を整理(よくフリーズしていたので)。
+  サブスレッドから MM/MD をしているときは、指定したステップが終わるごとにリングバッファに座標データをためこみ、メインスレッドにイベントを投げる。メインスレッドはイベントを捕まえて、リングバッファから座標データを読み込んで、フレームを作成する。サブスレッドから Molecule を直接触ることがなくなったので、少しは安定すると期待しよう。また、ドキュメントを閉じるときにサブスレッドが走っている時は、エラーメッセージを出して閉じるのを拒否するようにした。
index ea2c002..4528df6 100755 (executable)
@@ -64,6 +64,7 @@ const wxEventType MyDocumentEvent = wxNewEventType();
 BEGIN_EVENT_TABLE(MyDocument, wxDocument)
        EVT_COMMAND(MyDocumentEvent_willNeedCleanUndoStack, MyDocumentEvent, MyDocument::OnNeedCleanUndoStack)
        EVT_COMMAND(MyDocumentEvent_documentModified, MyDocumentEvent, MyDocument::OnDocumentModified)
+       EVT_COMMAND(MyDocumentEvent_insertFrameFromMD, MyDocumentEvent, MyDocument::OnInsertFrameFromMD)
        EVT_COMMAND(MyDocumentEvent_updateDisplay, MyDocumentEvent, MyDocument::OnUpdateDisplay)
        EVT_COMMAND(MyDocumentEvent_threadTerminated, MyDocumentEvent, MyDocument::OnSubThreadTerminated)
        EVT_MENU(myMenuID_Import, MyDocument::OnImport)
@@ -396,6 +397,20 @@ MyDocument::CleanUndoStack(bool shouldRegister)
        currentCommand = NULL;
 }
 
+bool
+MyDocument::Close()
+{
+       if (mol != NULL && mol->mutex != NULL) {
+               const char *msg;
+               if (subThreadKind == 1)
+                       msg = "MM/MD";
+               else msg = "Some background process";
+               MyAppCallback_errorMessageBox("%s is running: please stop it before closing", msg);
+               return false;
+       }
+       return true;
+}
+
 void
 MyDocument::OnNeedCleanUndoStack(wxCommandEvent& event)
 {
@@ -650,8 +665,7 @@ sDoMolecularDynamics(void *argptr, int argnum)
                mol->arena->end_step = mol->arena->start_step;
                md_main(mol->arena, minimize);
        } else if (count > 0) {
-               IntGroup *ig;
-               wxCommandEvent displayEvent(MyDocumentEvent, MyDocumentEvent_updateDisplay);
+               wxCommandEvent insertFrameEvent(MyDocumentEvent, MyDocumentEvent_insertFrameFromMD);
                for (i = 0; i < count; i++) {
                        
                        mol->arena->end_step = mol->arena->start_step + mol->arena->coord_output_freq;
@@ -662,17 +676,30 @@ sDoMolecularDynamics(void *argptr, int argnum)
                                        r = -1;
                                else {
 
-                                       /*  Create a new frame and copy the new coordinates  */
+                                       /*  Copy the coordinate to the ring buffer  */
+                                       Vector *rp = mol->arena->ring + mol->natoms * mol->arena->ring_next;
+                                       Int j;
+                                       Atom *ap;
                                        MoleculeLock(mol);
+                                       for (j = 0, ap = mol->arena->mol->atoms; j < mol->natoms; j++, ap = ATOM_NEXT(ap)) {
+                                               rp[j] = ap->r;
+                                       }
+                                       mol->arena->ring_next = (mol->arena->ring_next + 1) % mol->arena->nringframes;
+                                       if (mol->arena->ring_count < mol->arena->nringframes)
+                                               mol->arena->ring_count++;
+                                       MoleculeUnlock(mol);
+                                       
+                                       /*  Create a new frame and copy the new coordinates  */
+                               /*      MoleculeLock(mol);
                                        ig = IntGroupNewWithPoints(MoleculeGetNumberOfFrames(mol), 1, -1);
                                        MolActionCreateAndPerform(mol, gMolActionInsertFrames, ig, 0, NULL);
                                        IntGroupRelease(ig);                                    
                                        md_copy_coordinates_from_internal(mol->arena);
-                                       MoleculeUnlock(mol);
+                                       MoleculeUnlock(mol); */
 
                                        if (minimize && mol->arena->minimize_complete)
                                                break;
-                                       wxPostEvent(doc, displayEvent);
+                                       wxPostEvent(doc, insertFrameEvent);
                                }
                        }
                        if (r != 0)
@@ -727,6 +754,33 @@ MyDocument::OnStopMDRun(wxCommandEvent &event)
 }
 
 void
+MyDocument::OnInsertFrameFromMD(wxCommandEvent &event)
+{
+       Int i, j, n, old_nframes;
+       Atom *ap;
+
+       /*  Create new frame(s) and copy the new coordinates from the ring buffer  */
+       MoleculeLock(mol);
+       n = mol->arena->ring_count;
+       if (n > 0) {
+               IntGroup *ig;
+               Vector *rp;
+               old_nframes = MoleculeGetNumberOfFrames(mol);
+               ig = IntGroupNewWithPoints(old_nframes, n, -1);
+               MolActionCreateAndPerform(mol, gMolActionInsertFrames, ig, 0, NULL);
+               IntGroupRelease(ig);
+               for (i = 0; i < n; i++) {
+                       MoleculeSelectFrame(mol, old_nframes + i, 1);
+                       rp = mol->arena->ring + ((mol->arena->ring_next + mol->arena->nringframes - n + i) % mol->arena->nringframes) * mol->natoms;
+                       for (j = 0, ap = mol->atoms; j < mol->natoms; j++, ap = ATOM_NEXT(ap))
+                               ap->r = rp[j];
+               }
+               mol->arena->ring_count = 0;
+       }
+       MoleculeUnlock(mol);
+}
+
+void
 MyDocument::OnUpdateDisplay(wxCommandEvent &event)
 {
        MainView *mview = GetMainView();
index 1517b01..930ceef 100755 (executable)
@@ -30,6 +30,7 @@ enum {
        MyDocumentEvent_documentModified,
        MyDocumentEvent_scriptMenuModified,
        MyDocumentEvent_updateDisplay,
+       MyDocumentEvent_insertFrameFromMD,
        MyDocumentEvent_threadTerminated
 };
 
@@ -70,6 +71,8 @@ public:
        void    UpdateModifyFlag();
        void    BeginUndoGrouping();
        void    EndUndoGrouping();
+
+       virtual bool Close();
        
        void    OnNeedCleanUndoStack(wxCommandEvent& event);
 
@@ -115,6 +118,7 @@ public:
        void    OnCreateGamessInput(wxCommandEvent &event);
        void    OnCreateMOCube(wxCommandEvent &event);
        
+       void    OnInsertFrameFromMD(wxCommandEvent &event);
        void    OnUpdateDisplay(wxCommandEvent &event);
        void    OnSubThreadTerminated(wxCommandEvent &event);