changeset 28518:b8ab8b58547d

accept spmd command blocks as language elements (bug #58676) * pt-spmd.h, pt-spmd.cc: New files. * libinterp/parse-tree/module.mk: Update. * parse.h, oct-parse.yy (base_parser::make_spmd_command): New function. (spmd_command): New non-terminal. (command): Include spmd_command in list of possible commands. * pt-all.h: Also include pt-spmd.h. * pt-walk.h, pt-walk.cc (tree_walker::visit_spmd_command): New virtual function. * pt-eval.h, pt-eval.cc (tree_evaluator::visit_spmd_command): New function. * pt-pr-code.h, pt-pr-code.cc (tree_print_code::visit_spmd_command): New function.
author John W. Eaton <jwe@octave.org>
date Tue, 30 Jun 2020 15:52:25 -0400
parents 6e8a9845d118
children d4563c5d4060
files libinterp/parse-tree/module.mk libinterp/parse-tree/oct-parse.yy libinterp/parse-tree/parse.h libinterp/parse-tree/pt-all.h libinterp/parse-tree/pt-eval.cc libinterp/parse-tree/pt-eval.h libinterp/parse-tree/pt-pr-code.cc libinterp/parse-tree/pt-pr-code.h libinterp/parse-tree/pt-spmd.cc libinterp/parse-tree/pt-spmd.h libinterp/parse-tree/pt-walk.cc libinterp/parse-tree/pt-walk.h
diffstat 12 files changed, 239 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/module.mk	Tue Jun 30 09:34:14 2020 -0700
+++ b/libinterp/parse-tree/module.mk	Tue Jun 30 15:52:25 2020 -0400
@@ -38,6 +38,7 @@
   %reldir%/pt-misc.h \
   %reldir%/pt-pr-code.h \
   %reldir%/pt-select.h \
+  %reldir%/pt-spmd.h \
   %reldir%/pt-stmt.h \
   %reldir%/pt-tm-const.h \
   %reldir%/pt-unop.h \
@@ -87,6 +88,7 @@
   %reldir%/pt-misc.cc \
   %reldir%/pt-pr-code.cc \
   %reldir%/pt-select.cc \
+  %reldir%/pt-spmd.cc \
   %reldir%/pt-stmt.cc \
   %reldir%/pt-tm-const.cc \
   %reldir%/pt-unop.cc \
--- a/libinterp/parse-tree/oct-parse.yy	Tue Jun 30 09:34:14 2020 -0700
+++ b/libinterp/parse-tree/oct-parse.yy	Tue Jun 30 15:52:25 2020 -0400
@@ -254,7 +254,7 @@
 %type <tree_parameter_list_type> param_list1 param_list2
 %type <tree_parameter_list_type> return_list return_list1
 %type <tree_command_type> command select_command loop_command
-%type <tree_command_type> jump_command except_command
+%type <tree_command_type> jump_command spmd_command except_command
 %type <tree_function_def_type> function
 %type <tree_classdef_type> classdef
 %type <tree_command_type> file
@@ -1053,6 +1053,8 @@
                   { $$ = $1; }
                 | jump_command
                   { $$ = $1; }
+                | spmd_command
+                  { $$ = $1; }
                 | except_command
                   { $$ = $1; }
                 | function
@@ -1323,6 +1325,25 @@
                   { $$ = parser.make_return_command ($1); }
                 ;
 
+// =======================
+// Parallel execution pool
+// =======================
+
+spmd_command    : SPMD stash_comment opt_sep opt_list END
+                  {
+                    YYUSE ($3);
+
+                    octave::comment_list *lc = $2;
+                    octave::comment_list *tc = lexer.get_comment ();
+
+                    if (! ($$ = parser.make_spmd_command ($1, $4, $5, lc, tc)))
+                      {
+                        // make_spmd_command deleted $4, LC, and TC.
+                        YYABORT;
+                      }
+                  }
+                ;
+
 // ==========
 // Exceptions
 // ==========
@@ -3223,6 +3244,34 @@
     return new tree_return_command (l, c);
   }
 
+  // Build an spmd command.
+
+  tree_spmd_command *
+  base_parser::make_spmd_command (token *spmd_tok, tree_statement_list *body,
+                                  token *end_tok, comment_list *lc,
+                                  comment_list *tc)
+  {
+    tree_spmd_command *retval = nullptr;
+
+    if (end_token_ok (end_tok, token::if_end))
+      {
+        int l = spmd_tok->line ();
+        int c = spmd_tok->column ();
+
+        retval = new tree_spmd_command (body, lc, tc, l, c);
+      }
+    else
+      {
+        delete body;
+        delete lc;
+        delete tc;
+
+        end_token_error (end_tok, token::spmd_end);
+      }
+
+    return retval;
+  }
+
   // Start an if command.
 
   tree_if_command_list *
--- a/libinterp/parse-tree/parse.h	Tue Jun 30 09:34:14 2020 -0700
+++ b/libinterp/parse-tree/parse.h	Tue Jun 30 15:52:25 2020 -0400
@@ -81,6 +81,7 @@
   class tree_matrix;
   class tree_matrix;
   class tree_parameter_list;
+  class tree_spmd_command;
   class tree_statement;
   class tree_statement_list;
   class tree_statement_listtree_statement;
@@ -282,6 +283,12 @@
     // Build a return command.
     tree_command * make_return_command (token *return_tok);
 
+    // Build an spmd command.
+
+    tree_spmd_command *
+    make_spmd_command (token *spmd_tok, tree_statement_list *body,
+                       token *end_tok, comment_list *lc, comment_list *tc);
+
     // Start an if command.
     tree_if_command_list *
     start_if_command (tree_expression *expr, tree_statement_list *list);
--- a/libinterp/parse-tree/pt-all.h	Tue Jun 30 09:34:14 2020 -0700
+++ b/libinterp/parse-tree/pt-all.h	Tue Jun 30 15:52:25 2020 -0400
@@ -52,6 +52,7 @@
 #include "pt-misc.h"
 #include "pt-pr-code.h"
 #include "pt-select.h"
+#include "pt-spmd.h"
 #include "pt-stmt.h"
 #include "pt-unop.h"
 #include "pt-pr-code.h"
--- a/libinterp/parse-tree/pt-eval.cc	Tue Jun 30 09:34:14 2020 -0700
+++ b/libinterp/parse-tree/pt-eval.cc	Tue Jun 30 15:52:25 2020 -0400
@@ -2669,6 +2669,16 @@
       }
   }
 
+  void tree_evaluator::visit_spmd_command (tree_spmd_command& cmd)
+  {
+    // For now, we just execute the commands serially.
+
+    tree_statement_list *body = cmd.body ();
+
+    if (body)
+      body->accept (*this);
+  }
+
   void
   tree_evaluator::visit_octave_user_script (octave_user_script&)
   {
--- a/libinterp/parse-tree/pt-eval.h	Tue Jun 30 09:34:14 2020 -0700
+++ b/libinterp/parse-tree/pt-eval.h	Tue Jun 30 15:52:25 2020 -0400
@@ -202,6 +202,8 @@
 
     void visit_complex_for_command (tree_complex_for_command&);
 
+    void visit_spmd_command (tree_spmd_command&);
+
     void visit_octave_user_script (octave_user_script&);
 
     octave_value_list
--- a/libinterp/parse-tree/pt-pr-code.cc	Tue Jun 30 09:34:14 2020 -0700
+++ b/libinterp/parse-tree/pt-pr-code.cc	Tue Jun 30 15:52:25 2020 -0400
@@ -293,6 +293,35 @@
   }
 
   void
+  tree_print_code::visit_spmd_command (tree_spmd_command& cmd)
+  {
+    print_comment_list (cmd.leading_comment ());
+
+    indent ();
+
+    m_os << "spmd";
+
+    newline ();
+
+    tree_statement_list *list = cmd.body ();
+
+    if (list)
+      {
+        increment_indent_level ();
+
+        list->accept (*this);
+
+        decrement_indent_level ();
+      }
+
+    print_indented_comment (cmd.trailing_comment ());
+
+    indent ();
+
+    m_os << "endspmd";
+  }
+
+  void
   tree_print_code::visit_octave_user_script (octave_user_script& fcn)
   {
     reset ();
--- a/libinterp/parse-tree/pt-pr-code.h	Tue Jun 30 09:34:14 2020 -0700
+++ b/libinterp/parse-tree/pt-pr-code.h	Tue Jun 30 15:52:25 2020 -0400
@@ -88,6 +88,8 @@
 
     void visit_complex_for_command (tree_complex_for_command&);
 
+    void visit_spmd_command (tree_spmd_command&);
+
     void visit_octave_user_script (octave_user_script&);
 
     void visit_octave_user_function (octave_user_function&);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/parse-tree/pt-spmd.cc	Tue Jun 30 15:52:25 2020 -0400
@@ -0,0 +1,42 @@
+////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2020 The Octave Project Developers
+//
+// See the file COPYRIGHT.md in the top-level directory of this
+// distribution or <https://octave.org/copyright/>.
+//
+// This file is part of Octave.
+//
+// Octave is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Octave is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Octave; see the file COPYING.  If not, see
+// <https://www.gnu.org/licenses/>.
+//
+////////////////////////////////////////////////////////////////////////
+
+#if defined (HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
+#include "comment-list.h"
+#include "pt-spmd.h"
+#include "pt-stmt.h"
+
+namespace octave
+{
+  tree_spmd_command::~tree_spmd_command (void)
+  {
+    delete m_body;
+    delete m_lead_comm;
+    delete m_trail_comm;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/parse-tree/pt-spmd.h	Tue Jun 30 15:52:25 2020 -0400
@@ -0,0 +1,83 @@
+////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2020 The Octave Project Developers
+//
+// See the file COPYRIGHT.md in the top-level directory of this
+// distribution or <https://octave.org/copyright/>.
+//
+// This file is part of Octave.
+//
+// Octave is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Octave is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Octave; see the file COPYING.  If not, see
+// <https://www.gnu.org/licenses/>.
+//
+////////////////////////////////////////////////////////////////////////
+
+#if ! defined (octave_pt_spmd_command_h)
+#define octave_pt_spmd_command_h 1
+
+#include "octave-config.h"
+
+#include "base-list.h"
+#include "pt-cmd.h"
+#include "pt-walk.h"
+
+namespace octave
+{
+  class tree_comment_list;
+  class tree_statement_list;
+
+  // Spmd.
+
+  class tree_spmd_command : public tree_command
+  {
+  public:
+
+    tree_spmd_command (tree_statement_list *body, comment_list *lc,
+                       comment_list *tc, int l = -1, int c = -1)
+      : tree_command (l, c), m_body (body), m_lead_comm (lc), m_trail_comm (tc)
+    { }
+
+    // No copying!
+
+    tree_spmd_command (const tree_spmd_command&) = delete;
+
+    tree_spmd_command& operator = (const tree_spmd_command&) = delete;
+
+    ~tree_spmd_command (void);
+
+    tree_statement_list * body (void) { return m_body; }
+
+    comment_list * leading_comment (void) { return m_lead_comm; }
+
+    comment_list * trailing_comment (void) { return m_trail_comm; }
+
+    void accept (tree_walker& tw)
+    {
+      tw.visit_spmd_command (*this);
+    }
+
+  private:
+
+    // List of commands.
+    tree_statement_list *m_body;
+
+    // Comment preceding SPMD token.
+    comment_list *m_lead_comm;
+
+    // Comment preceding ENDSPMD token.
+    comment_list *m_trail_comm;
+  };
+}
+
+#endif
--- a/libinterp/parse-tree/pt-walk.cc	Tue Jun 30 09:34:14 2020 -0700
+++ b/libinterp/parse-tree/pt-walk.cc	Tue Jun 30 15:52:25 2020 -0400
@@ -174,6 +174,14 @@
       list->accept (*this);
   }
 
+  void tree_walker::visit_spmd_command (tree_spmd_command& cmd)
+  {
+    tree_statement_list *body = cmd.body ();
+
+    if (body)
+      body->accept (*this);
+  }
+
   void tree_walker::visit_octave_user_script (octave_user_script& fcn)
   {
     tree_statement_list *cmd_list = fcn.body ();
--- a/libinterp/parse-tree/pt-walk.h	Tue Jun 30 09:34:14 2020 -0700
+++ b/libinterp/parse-tree/pt-walk.h	Tue Jun 30 15:52:25 2020 -0400
@@ -53,6 +53,7 @@
   class tree_decl_elt;
   class tree_simple_for_command;
   class tree_complex_for_command;
+  class tree_spmd_command;
   class tree_function_def;
   class tree_identifier;
   class tree_if_clause;
@@ -142,6 +143,8 @@
 
     virtual void visit_complex_for_command (tree_complex_for_command&);
 
+    virtual void visit_spmd_command (tree_spmd_command&);
+
     virtual void visit_octave_user_script (octave_user_script&);
 
     virtual void visit_octave_user_function (octave_user_function&);