# HG changeset patch # User Eugenio Gianniti # Date 1406736553 -7200 # Node ID 072aee55bb7575b334f96418c2b6c0721c6adcd8 # Parent 2b51546a28f72c769f4d769621f66880708fbaf6 Import UFL in a parallel-safe fashion diff -r 2b51546a28f7 -r 072aee55bb75 INDEX --- a/INDEX Sat Jul 26 19:38:23 2014 +0200 +++ b/INDEX Wed Jul 30 18:09:13 2014 +0200 @@ -31,3 +31,6 @@ @function/plot @mesh/plot @function/feval +MPI + barrier + is_master_node diff -r 2b51546a28f7 -r 072aee55bb75 inst/import_ufl_BilinearForm.m --- a/inst/import_ufl_BilinearForm.m Sat Jul 26 19:38:23 2014 +0200 +++ b/inst/import_ufl_BilinearForm.m Wed Jul 30 18:09:13 2014 +0200 @@ -29,33 +29,38 @@ function import_ufl_BilinearForm (var_prob) - if nargin != 1 - error ("import_ufl_BilinearForm: wrong number of input parameters."); - elseif ! ischar (var_prob) - error ("import_ufl_BilinearForm: first argument is not a valid string"); + if (is_master_node ()) + if nargin != 1 + error ("import_ufl_BilinearForm: wrong number of input parameters."); + elseif ! ischar (var_prob) + error ("import_ufl_BilinearForm: first argument is not a valid string"); + endif + + if (check_hash (var_prob) || ! check_oct_files (var_prob, "BilinearForm")) + n = length (mfilename ("fullpath")) - length (mfilename()); + path = strtrunc(mfilename ("fullpath"), n); + + private = fullfile (path, "include/"); + output = generate_rhs (var_prob); + output += generate_makefile (var_prob, private); + if output != 0 + error ("Compilation failed"); + else + [output, textfile] = system (sprintf ("make -f Makefile_%s rhs", var_prob)); + if output != 0 + display (text); + error ("Compilation failed"); + endif + [output, textfile] = system (sprintf ("make -f Makefile_%s clean", var_prob)); + if output != 0 + display (text); + error ("Compilation failed"); + endif + save_hash (var_prob); + endif + endif endif - if (check_hash (var_prob) || ! check_oct_files (var_prob, "BilinearForm")) - n = length (mfilename ("fullpath")) - length (mfilename()); - path = strtrunc(mfilename ("fullpath"), n); + barrier (); - private = fullfile (path, "include/"); - output = generate_rhs (var_prob); - output += generate_makefile (var_prob, private); - if output != 0 - error ("Compilation failed"); - else - [output, textfile] = system (sprintf ("make -f Makefile_%s rhs", var_prob)); - if output != 0 - display (text); - error ("Compilation failed"); - endif - [output, textfile] = system (sprintf ("make -f Makefile_%s clean", var_prob)); - if output != 0 - display (text); - error ("Compilation failed"); - endif - save_hash (var_prob); - endif - endif endfunction diff -r 2b51546a28f7 -r 072aee55bb75 inst/import_ufl_FunctionSpace.m --- a/inst/import_ufl_FunctionSpace.m Sat Jul 26 19:38:23 2014 +0200 +++ b/inst/import_ufl_FunctionSpace.m Wed Jul 30 18:09:13 2014 +0200 @@ -27,34 +27,38 @@ function import_ufl_FunctionSpace (var_prob) - if nargin != 1 - error ("import_ufl_FunctionSpace: wrong number of input parameters."); - elseif ! ischar (var_prob) - error ("import_ufl_FunctionSpace: first argument is not a valid string"); - endif + if (is_master_node ()) + if nargin != 1 + error ("import_ufl_FunctionSpace: wrong number of input parameters."); + elseif ! ischar (var_prob) + error ("import_ufl_FunctionSpace: first argument is not a valid string"); + endif - if (check_hash (var_prob) || ! check_oct_files (var_prob, "FunctionSpace")) - n = length (mfilename ("fullpath")) - length (mfilename()); - path = strtrunc(mfilename ("fullpath"), n); + if (check_hash (var_prob) || ! check_oct_files (var_prob, "FunctionSpace")) + n = length (mfilename ("fullpath")) - length (mfilename()); + path = strtrunc(mfilename ("fullpath"), n); - private = fullfile (path, "include/"); - output = generate_fs (var_prob); - output += generate_makefile (var_prob, private); - if output != 0 - error ("Compilation failed"); - else - [output, textfile] = system (sprintf ("make -f Makefile_%s fs", var_prob)); + private = fullfile (path, "include/"); + output = generate_fs (var_prob); + output += generate_makefile (var_prob, private); if output != 0 - display (text); error ("Compilation failed"); + else + [output, textfile] = system (sprintf ("make -f Makefile_%s fs", var_prob)); + if output != 0 + display (text); + error ("Compilation failed"); + endif + [output, textfile] = system (sprintf ("make -f Makefile_%s clean", var_prob)); + if output != 0 + display (text); + error ("Compilation failed"); + endif + save_hash (var_prob); endif - [output, textfile] = system (sprintf ("make -f Makefile_%s clean", var_prob)); - if output != 0 - display (text); - error ("Compilation failed"); - endif - save_hash (var_prob); endif endif + barrier (); + endfunction diff -r 2b51546a28f7 -r 072aee55bb75 inst/import_ufl_Functional.m --- a/inst/import_ufl_Functional.m Sat Jul 26 19:38:23 2014 +0200 +++ b/inst/import_ufl_Functional.m Wed Jul 30 18:09:13 2014 +0200 @@ -26,33 +26,38 @@ ## @end deftypefn function import_ufl_Functional (var_prob) - if nargin != 1 - error ("import_ufl_Functional: wrong number of input parameters."); - elseif ! ischar (var_prob) - error ("import_ufl_Functional: first argument is not a valid string"); + if (is_master_node ()) + if nargin != 1 + error ("import_ufl_Functional: wrong number of input parameters."); + elseif ! ischar (var_prob) + error ("import_ufl_Functional: first argument is not a valid string"); + endif + + if (check_hash (var_prob) || ! check_oct_files (var_prob, "Functional")) + n = length (mfilename ("fullpath")) - length (mfilename()); + path = strtrunc(mfilename ("fullpath"), n); + + private = fullfile (path, "include/"); + output = generate_fun (var_prob); + output += generate_makefile (var_prob, private); + if output != 0 + error ("Compilation failed"); + else + [output, textfile] = system (sprintf ("make -f Makefile_%s fun", var_prob)); + if output != 0 + display (text); + error ("Compilation failed"); + endif + [output, textfile] = system (sprintf ("make -f Makefile_%s clean", var_prob)); + if output != 0 + display (text); + error ("Compilation failed"); + endif + save_hash (var_prob); + endif + endif endif - if (check_hash (var_prob) || ! check_oct_files (var_prob, "Functional")) - n = length (mfilename ("fullpath")) - length (mfilename()); - path = strtrunc(mfilename ("fullpath"), n); + barrier (); - private = fullfile (path, "include/"); - output = generate_fun (var_prob); - output += generate_makefile (var_prob, private); - if output != 0 - error ("Compilation failed"); - else - [output, textfile] = system (sprintf ("make -f Makefile_%s fun", var_prob)); - if output != 0 - display (text); - error ("Compilation failed"); - endif - [output, textfile] = system (sprintf ("make -f Makefile_%s clean", var_prob)); - if output != 0 - display (text); - error ("Compilation failed"); - endif - save_hash (var_prob); - endif - endif endfunction diff -r 2b51546a28f7 -r 072aee55bb75 inst/import_ufl_LinearForm.m --- a/inst/import_ufl_LinearForm.m Sat Jul 26 19:38:23 2014 +0200 +++ b/inst/import_ufl_LinearForm.m Wed Jul 30 18:09:13 2014 +0200 @@ -27,34 +27,39 @@ function import_ufl_LinearForm (var_prob) - if nargin != 1 - error ("import_ufl_LinearForm: wrong number of input parameters."); - elseif ! ischar (var_prob) - error ("import_ufl_LinearForm: first argument is not a valid string"); + if (is_master_node ()) + if nargin != 1 + error ("import_ufl_LinearForm: wrong number of input parameters."); + elseif ! ischar (var_prob) + error ("import_ufl_LinearForm: first argument is not a valid string"); + endif + + if (check_hash (var_prob) || ! check_oct_files (var_prob, "LinearForm")) + n = length (mfilename ("fullpath")) - length (mfilename()); + path = strtrunc(mfilename ("fullpath"), n); + + private = fullfile (path, "include/"); + + output = generate_lhs (var_prob); + output += generate_makefile (var_prob, private); + if output != 0 + error ("Compilation failed"); + else + [output, textfile] = system (sprintf ("make -f Makefile_%s lhs", var_prob)); + if output != 0 + display (text); + error ("Compilation failed"); + endif + [output, textfile] = system (sprintf ("make -f Makefile_%s clean", var_prob)); + if output != 0 + display (text); + error ("Compilation failed"); + endif + save_hash (var_prob); + endif + endif endif - if (check_hash (var_prob) || ! check_oct_files (var_prob, "LinearForm")) - n = length (mfilename ("fullpath")) - length (mfilename()); - path = strtrunc(mfilename ("fullpath"), n); - - private = fullfile (path, "include/"); + barrier (); - output = generate_lhs (var_prob); - output += generate_makefile (var_prob, private); - if output != 0 - error ("Compilation failed"); - else - [output, textfile] = system (sprintf ("make -f Makefile_%s lhs", var_prob)); - if output != 0 - display (text); - error ("Compilation failed"); - endif - [output, textfile] = system (sprintf ("make -f Makefile_%s clean", var_prob)); - if output != 0 - display (text); - error ("Compilation failed"); - endif - save_hash (var_prob); - endif - endif endfunction diff -r 2b51546a28f7 -r 072aee55bb75 inst/import_ufl_Problem.m --- a/inst/import_ufl_Problem.m Sat Jul 26 19:38:23 2014 +0200 +++ b/inst/import_ufl_Problem.m Wed Jul 30 18:09:13 2014 +0200 @@ -26,36 +26,40 @@ function import_ufl_Problem (var_prob) - if nargin != 1 - error ("import_ufl_Problem: wrong number of input parameters."); - elseif ! ischar (var_prob) - error ("import_ufl_Problem: first argument is not a valid string"); - endif + if (is_master_node ()) + if nargin != 1 + error ("import_ufl_Problem: wrong number of input parameters."); + elseif ! ischar (var_prob) + error ("import_ufl_Problem: first argument is not a valid string"); + endif - if (check_hash (var_prob) || ! check_oct_files (var_prob, "Problem")) - n = length (mfilename ("fullpath")) - length (mfilename()); - path = strtrunc(mfilename ("fullpath"), n); + if (check_hash (var_prob) || ! check_oct_files (var_prob, "Problem")) + n = length (mfilename ("fullpath")) - length (mfilename()); + path = strtrunc(mfilename ("fullpath"), n); - private = fullfile (path, "include/"); - output = generate_fs (var_prob); - output += generate_rhs (var_prob); - output += generate_lhs (var_prob); - output += generate_makefile (var_prob, private); - if output != 0 - error ("Compilation failed"); - else - [output, textfile] = system (sprintf ("make -f Makefile_%s all", var_prob)); + private = fullfile (path, "include/"); + output = generate_fs (var_prob); + output += generate_rhs (var_prob); + output += generate_lhs (var_prob); + output += generate_makefile (var_prob, private); if output != 0 - display (text); error ("Compilation failed"); + else + [output, textfile] = system (sprintf ("make -f Makefile_%s all", var_prob)); + if output != 0 + display (text); + error ("Compilation failed"); + endif + [output, textfile] = system (sprintf ("make -f Makefile_%s clean", var_prob)); + if output != 0 + display (text); + error ("Compilation failed"); + endif + save_hash (var_prob); endif - [output, textfile] = system (sprintf ("make -f Makefile_%s clean", var_prob)); - if output != 0 - display (text); - error ("Compilation failed"); - endif - save_hash (var_prob); endif endif + barrier (); + endfunction diff -r 2b51546a28f7 -r 072aee55bb75 inst/ufl.m --- a/inst/ufl.m Sat Jul 26 19:38:23 2014 +0200 +++ b/inst/ufl.m Wed Jul 30 18:09:13 2014 +0200 @@ -59,56 +59,70 @@ "Problem"}; if (numel (varargin) < 1) - if (! is_valid_file_id (fid)) + if (is_master_node () && ! is_valid_file_id (fid)) print_usage (); endif elseif (! all (cellfun ("ischar", varargin))) - error ("ufl: all arguments should be strings"); + if (is_master_node ()) + error ("ufl: all arguments should be strings"); + endif elseif (strcmpi (varargin{1}, "start")) - if (is_valid_file_id (fid)) - error ("ufl: a file is already open"); - else - if (numel (varargin) > 1) - filename = varargin{2}; - if (isempty (regexpi (filename, ".ufl$", "match"))) - filename = [filename, ".ufl"]; + if (is_master_node ()) + if (is_valid_file_id (fid)) + error ("ufl: a file is already open"); + else + if (numel (varargin) > 1) + filename = varargin{2}; + if (isempty (regexpi (filename, ".ufl$", "match"))) + filename = [filename, ".ufl"]; + else + filename = [filename(1:end-4), ".ufl"]; + endif + endif + [~, err, ~] = stat (filename); + if (err == 0) + error (["ufl: a file named ", filename, " already exists"]); else - filename = [filename(1:end-4), ".ufl"]; + fid = fopen (filename, "w"); endif endif - [~, err, ~] = stat (filename); - if (err == 0) - error (["ufl: a file named ", filename, " already exists"]); - else - fid = fopen (filename, "w"); + if (! is_valid_file_id (fid)) + error (["ufl: could not open file ", filename]); endif endif - if (! is_valid_file_id (fid)) - error (["ufl: could not open file ", filename]); - endif elseif (strcmpi (varargin{1}, "end")) - if (! is_valid_file_id (fid)) - error ("ufl: no open file"); - else - fclose (fid); - fid = -1; + if (is_master_node ()) + if (! is_valid_file_id (fid)) + error ("ufl: no open file"); + else + fclose (fid); + fid = -1; + endif endif compile = "Problem"; if (numel (varargin) > 1) compile = validatestring (varargin{2}, opts, "ufl", "content"); endif + # This line is executed by all the nodes since it internally enforces + # that just one is involved eval (["import_ufl_", compile, "(\"", filename(1:end-4), "\");"]); - delete (filename); + if (is_master_node ()) + delete (filename); + endif filename = "default.ufl"; elseif (! is_valid_file_id (fid)) - error ("ufl: no open file"); + if (is_master_node ()) + error ("ufl: no open file"); + endif else - if (is_valid_file_id (fid)) - output = strtrim (sprintf ("%s ", varargin{:})); - fputs (fid, output); - fprintf (fid, "\n"); - else - error ("ufl: no open file"); + if (is_master_node ()) + if (is_valid_file_id (fid)) + output = strtrim (sprintf ("%s ", varargin{:})); + fputs (fid, output); + fprintf (fid, "\n"); + else + error ("ufl: no open file"); + endif endif endif diff -r 2b51546a28f7 -r 072aee55bb75 src/Makefile.in --- a/src/Makefile.in Sat Jul 26 19:38:23 2014 +0200 +++ b/src/Makefile.in Wed Jul 30 18:09:13 2014 +0200 @@ -39,7 +39,9 @@ plot_mesh.oct \ SubSpace.oct \ feval.oct \ - interpolate.oct + interpolate.oct \ + is_master_node.oct \ + barrier.oct all: $(OCTFILES) @@ -152,6 +154,18 @@ libfemfenics_factories.a: femfenics_factory.o uBLAS_factory.o PETSc_factory.o $(AR) $(ARFLAGS) $@ $^ +is_master_node.oct: is_master_node.o + CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -o $@ $< $(LIBS) + +is_master_node.o: is_master_node.cc dolfin_compat.h + CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -o $@ -c $< + +barrier.oct: barrier.o + CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -o $@ $< $(LIBS) + +barrier.o: barrier.cc dolfin_compat.h + CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -o $@ -c $< + clean: $(RM) *.o core octave-core *.oct *~ *.xml *.a diff -r 2b51546a28f7 -r 072aee55bb75 src/barrier.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/barrier.cc Wed Jul 30 18:09:13 2014 +0200 @@ -0,0 +1,44 @@ +/* + Copyright (C) 2014 Eugenio Gianniti + + This program 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. + + This program 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 + this program; if not, see . +*/ + +#include +#include +#include "dolfin_compat.h" + +DEFUN_DLD (barrier, args, nargout, +"-*- texinfo -*-\n\ +@deftypefn {Function File} {} \ +barrier ()\n\ +Set an MPI barrier.\n\ +@end deftypefn") +{ + octave_value retval; + int nargin = args.length (); + + if (nargin > 0 || nargout > 0) + print_usage (); + else + { + dolfin::MPI::barrier ( +#ifdef LATEST_DOLFIN + MPI_COMM_WORLD +#endif + ); + } + + return retval; +} diff -r 2b51546a28f7 -r 072aee55bb75 src/is_master_node.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/is_master_node.cc Wed Jul 30 18:09:13 2014 +0200 @@ -0,0 +1,45 @@ +/* + Copyright (C) 2014 Eugenio Gianniti + + This program 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. + + This program 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 + this program; if not, see . +*/ + +#include +#include +#include "dolfin_compat.h" + +DEFUN_DLD (is_master_node, args, nargout, +"-*- texinfo -*-\n\ +@deftypefn {Function File} {} \ +is_master_process ()\n\ +Return true if called on node zero.\n\ +@end deftypefn") +{ + octave_value retval; + int nargin = args.length (); + + if (nargin > 0 || nargout > 1) + print_usage (); + else + { +#ifdef LATEST_DOLFIN + retval = (dolfin::MPI::rank (MPI_COMM_WORLD) == 0); +#else + // This works also in 1.4.0, but it is now deprecated + retval = (dolfin::MPI::process_number () == 0); +#endif + } + + return retval; +}