[test-suite] r312463 - [test-suite] Adding the CLAMR mini-app
Hal Finkel via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 3 20:10:18 PDT 2017
Author: hfinkel
Date: Sun Sep 3 20:10:18 2017
New Revision: 312463
URL: http://llvm.org/viewvc/llvm-project?rev=312463&view=rev
Log:
[test-suite] Adding the CLAMR mini-app
The CLAMR code is a cell-based adaptive mesh refinement (AMR) mini-app
developed as a testbed for hybrid algorithm development using MPI and OpenCL
GPU code. This is a serial configuration for the test suite.
https://github.com/lanl/CLAMR
On an Intel Xeon CPU E5-2699 v4 @ 2.20GHz:
compile_time: 125.6392
exec_time: 7.3060
Maximum resident set size (kbytes): 13232
Patch by Ji Seung "Anna" Kim, thanks!
Includes glibc_compat_rand.{c,h} written by me.
Differential Revision: https://reviews.llvm.org/D36718
Added:
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Bounds.c
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Bounds.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/CLAMR.reference_output
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/CMakeLists.txt
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Cmd.cc
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Cmd.hh
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Comm.cc
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Comm.hh
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Function.cc
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Function.hh
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Globals.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/KDTree.c
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/KDTree.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/LICENSE
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Makefile
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/MallocPlus.cpp
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/MallocPlus.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Parser_math.cc
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Parser_math.hh
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Parser_utils.cc
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Parser_utils.hh
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/PowerParser.cc
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/PowerParser.hh
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Restartblock.cc
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Restartblock.hh
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Variable.cc
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Variable.hh
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Whenthen.cc
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Whenthen.hh
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Word.cc
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Word.hh
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/clamr_cpuonly.cpp
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/crux.cpp
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/crux.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/fmemopen.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/genmalloc.c
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/genmalloc.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/glibc_compat_rand.c
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/glibc_compat_rand.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/graphics.c
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/graphics.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hash.c
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hash.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hsfc.c
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hsfc.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hsfcsort.c
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/input.cpp
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/input.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/memstats.c
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/memstats.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/mesh.cpp
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/mesh.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/partition.cpp
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/partition.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/reduce.c
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/reduce.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/s7.c
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/s7.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/state.cpp
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/state.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/timer.c
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/timer.h
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/zorder.c
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/zorder.h
Modified:
test-suite/trunk/LICENSE.TXT
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CMakeLists.txt
test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/Makefile
Modified: test-suite/trunk/LICENSE.TXT
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/LICENSE.TXT?rev=312463&r1=312462&r2=312463&view=diff
==============================================================================
--- test-suite/trunk/LICENSE.TXT (original)
+++ test-suite/trunk/LICENSE.TXT Sun Sep 3 20:10:18 2017
@@ -86,6 +86,7 @@ smg2000: llvm-test/MultiSourc
miniAMR: llvm-test/MultiSource/Benchmarks/DOE-ProxyApps-C/miniAMR
Pathfinder: llvm-test/MultiSource/Benchmarks/DOE-ProxyApps-C/Pathfinder
XSBench: llvm-test/MultiSource/Benchmarks/DOE-ProxyApps-C/XSBench
+CLAMR: llvm-test/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR
HPCCG: llvm-test/MultiSource/Benchmarks/DOE-ProxyApps-C++/HPCCG
PENNANT: llvm-test/MultiSource/Benchmarks/DOE-ProxyApps-C++/PENNANT
miniFE: llvm-test/MultiSource/Benchmarks/DOE-ProxyApps-C++/miniFE
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Bounds.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Bounds.c?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Bounds.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Bounds.c Sun Sep 3 20:10:18 2017
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2011-2012, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ * This research code is being developed as part of the
+ * 2011 X Division Summer Workshop for the express purpose
+ * of a collaborative code for development of ideas in
+ * the implementation of AMR codes for Exascale platforms
+ *
+ * AMR implementation of the Wave code previously developed
+ * as a demonstration code for regular grids on Exascale platforms
+ * as part of the Supercomputing Challenge and Los Alamos
+ * National Laboratory
+ *
+ * Authors: Bob Robey XCP-2 brobey at lanl.gov
+ * Neal Davis davis68 at lanl.gov, davis68 at illinois.edu
+ * David Nicholaeff dnic at lanl.gov, mtrxknight at aol.com
+ * Dennis Trujillo dptrujillo at lanl.gov, dptru10 at gmail.com
+ * Other LANL authors
+ *
+ */
+#include "Bounds.h"
+
+#define MEMCPY(s,d,n,t) {memcpy((void*)d, (void*)s, n * sizeof(t)); }
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+void Bounds_Copy(TBounds* src, TBounds* dest) {
+ assert(src && dest);
+ MEMCPY(src, dest, 1, TBounds);
+}
+
+void Bounds_Infinite(TBounds* b){
+ assert(b);
+ b->min.x = POSITIVE_INFINITY;
+ b->min.y = POSITIVE_INFINITY;
+ b->max.x = NEGATIVE_INFINITY;
+ b->max.y = NEGATIVE_INFINITY;
+}
+
+void Bounds_AddBounds(TBounds* b, TBounds* add) {
+ assert(b && add);
+ b->min.x = MIN(b->min.x, add->min.x);
+ b->min.y = MIN(b->min.y, add->min.y);
+ b->max.x = MAX(b->max.x, add->max.x);
+ b->max.y = MAX(b->max.y, add->max.y);
+}
+
+void Bounds_AddEpsilon(TBounds* b, double add) {
+ assert(b);
+ b->min.x = b->min.x - add;
+ b->min.y = b->min.y - add;
+ b->max.x = b->max.x + add;
+ b->max.y = b->max.y + add;
+}
+
+bool Bounds_IsOverlappingBounds(TBounds* b, TBounds* tst) {
+ assert(b && tst);
+ if((tst->max.x < b->min.x) || (tst->min.x > b->max.x))
+ return(false);
+ if((tst->max.y < b->min.y) || (tst->min.y > b->max.y))
+ return(false);
+ return(true);
+}
+
+double Bounds_WidthAxis(TBounds* b, unsigned int axis)
+{
+ double width;
+
+ assert(b);
+ if(axis == XAXIS)
+ width = b->max.x - b->min.x;
+ else if(axis == YAXIS)
+ width = b->max.y - b->min.y;
+ else
+ assert(NULL);
+ return(width);
+}
+
+double Bounds_CenterAxis(TBounds* b, unsigned int axis)
+{
+ double center;
+
+ assert(b);
+ if(axis == XAXIS)
+ center = (b->min.x + b->max.x) * 0.5;
+ else if(axis == YAXIS)
+ center = (b->min.y + b->max.y) * 0.5;
+ else
+ assert(NULL);
+ return(center);
+}
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Bounds.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Bounds.h?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Bounds.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Bounds.h Sun Sep 3 20:10:18 2017
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2011-2012, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ * This research code is being developed as part of the
+ * 2011 X Division Summer Workshop for the express purpose
+ * of a collaborative code for development of ideas in
+ * the implementation of AMR codes for Exascale platforms
+ *
+ * AMR implementation of the Wave code previously developed
+ * as a demonstration code for regular grids on Exascale platforms
+ * as part of the Supercomputing Challenge and Los Alamos
+ * National Laboratory
+ *
+ * Authors: Bob Robey XCP-2 brobey at lanl.gov
+ * Neal Davis davis68 at lanl.gov, davis68 at illinois.edu
+ * David Nicholaeff dnic at lanl.gov, mtrxknight at aol.com
+ * Dennis Trujillo dptrujillo at lanl.gov, dptru10 at gmail.com
+ * Other LANL authors
+ *
+ */
+
+#include <stdbool.h>
+
+#ifndef _Bounds_
+#define _Bounds_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "Globals.h"
+
+typedef struct {
+ TVector min, max;
+} TBounds;
+
+extern void Bounds_Copy(TBounds* src, TBounds* dest);
+extern void Bounds_Infinite(TBounds* b);
+extern void Bounds_AddBounds(TBounds* b, TBounds* add);
+extern void Bounds_AddEpsilon(TBounds* b, double add);
+extern bool Bounds_IsOverlappingBounds(TBounds* b, TBounds* tst);
+extern double Bounds_WidthAxis(TBounds* b, unsigned int axis);
+extern double Bounds_CenterAxis(TBounds* b, unsigned int axis);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/CLAMR.reference_output
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/CLAMR.reference_output?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/CLAMR.reference_output (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/CLAMR.reference_output Sun Sep 3 20:10:18 2017
@@ -0,0 +1,19 @@
+Mass of initialized cells equal to 31290.8709635
+Iteration 0 timestep n/a Sim Time 0.0 cells 4412 Mass Sum 31290.8709635
+Iteration 100 timestep 0.000349 Sim Time 0.045244 cells 4652 Mass Sum 31290.8709635 Mass Change 0
+Iteration 200 timestep 0.000386 Sim Time 0.080903 cells 4760 Mass Sum 31290.8709635 Mass Change 0
+Iteration 300 timestep 0.000442 Sim Time 0.121853 cells 4892 Mass Sum 31290.8709635 Mass Change 0
+Iteration 400 timestep 0.000502 Sim Time 0.169292 cells 4976 Mass Sum 31290.8709635 Mass Change -3.63798e-12
+Iteration 500 timestep 0.000614 Sim Time 0.224092 cells 5096 Mass Sum 31290.8709635 Mass Change -3.63798e-12
+Iteration 600 timestep 0.000701 Sim Time 0.288037 cells 5372 Mass Sum 31290.8709635 Mass Change -3.63798e-12
+Iteration 700 timestep 0.000787 Sim Time 0.362393 cells 5780 Mass Sum 31290.8709635 Mass Change -7.27596e-12
+Iteration 800 timestep 0.000922 Sim Time 0.449275 cells 6152 Mass Sum 31290.8709635 Mass Change -1.09139e-11
+Iteration 900 timestep 0.001131 Sim Time 0.551298 cells 6704 Mass Sum 31290.8709635 Mass Change -1.09139e-11
+Iteration 1000 timestep 0.001318 Sim Time 0.672188 cells 7208 Mass Sum 31290.8709635 Mass Change -1.09139e-11
+Using hash tables to calculate neighbors
+hash table size bytes 278784
+Initial order is Hilbert sort. No cycle reorder. Local Stencil is on.
+CPU: rezone frequency 17.1000 percent
+CPU: calc neigh frequency 17.2000 percent
+CPU: refine_smooth_iter per rezone 0.0000
+exit 0
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/CMakeLists.txt?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/CMakeLists.txt (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/CMakeLists.txt Sun Sep 3 20:10:18 2017
@@ -0,0 +1,3 @@
+set(PROG CLAMR)
+set(RUN_OPTIONS -n 64 -t 1000)
+llvm_multisource()
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Cmd.cc
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Cmd.cc?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Cmd.cc (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Cmd.cc Sun Sep 3 20:10:18 2017
@@ -0,0 +1,3972 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+// ***************************************************************************
+// ***************************************************************************
+// This class holds command lines broken up into words.
+// The term command is used in a general sense, it includes variable
+// assignments, do loops, usual commands, etc.
+// ***************************************************************************
+// ***************************************************************************
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <string>
+#include <vector>
+#include <deque>
+#include <sstream>
+#include <map>
+#include <algorithm>
+#include <math.h>
+#include <assert.h>
+
+#include "Parser_utils.hh"
+#include "Variable.hh"
+#include "Function.hh"
+#include "Word.hh"
+#include "Parser_math.hh"
+#include "Cmd.hh"
+
+namespace PP
+{
+using std::cout;
+using std::endl;
+using std::string;
+using std::deque;
+using std::vector;
+using std::stringstream;
+using std::pair;
+using std::ifstream;
+using std::ios;
+using std::setw;
+
+// index base, generally 1 for Fortran style and 0 for C/C++, default 1
+static int index_base = 1;
+static bool case_sensitive = false;
+
+// ===========================================================================
+// Default constructor.
+// ===========================================================================
+Cmd::Cmd()
+{
+ init();
+}
+
+
+// ===========================================================================
+// Constructor including map of variables.
+// ===========================================================================
+Cmd::Cmd(string s, map<string, Variable> *v, map<string, Function> *f,
+ deque<string> *lstr, int lnum, int file_lnum, string fname,
+ stringstream &serr, int &ierr)
+{
+ init();
+ vmap = v;
+ fmap = f;
+ original_str = s;
+ line_number = lnum;
+ file_line_number = file_lnum;
+ filename = fname;
+ lines = lstr;
+ process_string(s, serr, ierr);
+}
+
+
+// ===========================================================================
+// Add a word to this cmd.
+// ===========================================================================
+void Cmd::add_word(string str, int lnum, int file_lnum, string fname)
+{
+ Word w(str, lnum, file_lnum, fname, lines);
+ words.push_back(w);
+}
+
+
+// ===========================================================================
+// Erase a word from this cmd.
+// ===========================================================================
+void Cmd::erase_word(int iw)
+{
+ words.erase(words.begin()+iw);
+}
+void Cmd::erase_last_word()
+{
+ words.erase(words.begin()+(int)words.size()-1);
+}
+
+
+// ===========================================================================
+// Remove words that are commas.
+// ===========================================================================
+void Cmd::remove_commas()
+{
+ for (int i=0; i<(int)words.size(); i++) {
+ if (words[i].is_comma()) {
+ words.erase(words.begin()+i);
+ i -= 1;
+ }
+ }
+}
+
+
+// ===========================================================================
+// Initialize various private data.
+// ===========================================================================
+void Cmd::init()
+{
+ original_str = "";
+ //processed = false;
+ white_space = " \t";
+ delims = " \t()[],*/+-=!#";
+ vmap = NULL;
+ fmap = NULL;
+ line_number = 0;
+ file_line_number = 0;
+ filename = "";
+}
+
+
+// ===========================================================================
+// Set index base for input file indexing. 1 -- Fortran like, 0 -- Other
+// languages
+// ===========================================================================
+void Cmd::set_index_base(int base)
+{
+ //cout << "Info:: Setting index base to " << base << endl;
+ index_base = base;
+}
+
+// ===========================================================================
+// Set case sensitivity for input file commands.
+// ===========================================================================
+void Cmd::set_case_sensitive(bool case_sensitive_in)
+{
+ case_sensitive = case_sensitive_in;
+}
+
+// ===========================================================================
+// Process a string.
+// Break the string into words and copy each word to a double ended queue.
+// ===========================================================================
+void Cmd::process_string(string in_str, stringstream &serr, int &ierr)
+{
+ //cout << "&&&&& Original line = " << endl;
+ //cout << in_str << endl;
+ //cout << "01234567890123456789012345678901234567890123456789" << endl;
+ //cout << "0 1 2 3 4 " << endl;
+
+ string s;
+ int istart = 0;
+ bool found = false;
+ //int plevel = 0;
+ for (;;) {
+ delims = " \t()[],*/+-=!#";
+
+ // Extract the next word from the line.
+ found = extract_next_word(istart, in_str, s, serr, ierr);
+ if (!found) break;
+
+ // Create a new word using the word that was found.
+ // This removes quotes if there are any and types the word.
+ Word w(s, line_number, file_line_number, filename, lines);
+
+ // Copy the word to the end of the queue.
+ words.push_back(w);
+ }
+
+ // Set the command name and type.
+ reset_name_type();
+}
+
+
+// ===========================================================================
+// Given a string, str, and a starting position in
+// that string, istart, extract the next word and
+// pass it back as a string.
+// ===========================================================================
+bool Cmd::extract_next_word(int &istart, string &str, string &word,
+ stringstream &serr, int &ierr)
+{
+ // To suppress compiler warnings of unused parameters
+ //assert(serr == serr);
+ assert(ierr == ierr);
+
+ // If istart is out of bounds then there is nothing to do.
+ if (istart < 0) return false;
+ if (istart >= (int)str.size()) return false;
+
+ // Find the next non blank character.
+ int i1 = str.find_first_not_of(white_space, istart);
+
+ // If a non whitespace character was not found then there are no more
+ // words to extract.
+ if (i1 == (int)string::npos) return false;
+
+ // If the non blank character that was found is a delimiter, like
+ // ()[]+-/* ... then it needs to be a word by itself.
+ if (delims.find(str[i1], 0) != string::npos) {
+ word = str[i1];
+ istart = i1+1;
+ return true;
+ }
+
+ // At this point we have found the start of a word. The end of the
+ // word will be one of the delimiters like ()[]+=-*/spacetab ...
+ string wend = delims;
+
+ // A word delimited by quotes is handled differently. If the i1
+ // position in the string is a beginning quotes then we need to search
+ // for an ending quotes. Anything between quotes is part of the word
+ // including delimters.
+ bool quotes = false;
+ if (str[i1] == '"') {
+ quotes = true;
+ wend = "\"";
+ }
+ if (str[i1] == '\'') {
+ quotes = true;
+ wend = "\'";
+ }
+
+ // Search for the end of the word by finding the next delimiter. The
+ // delimiter is one index past the end of the word.
+ // But if the next delimiter is + or - then we have to consider that
+ // this could be a floating point number in which case we continue
+ // past the + or - to find the next delimiter.
+ int i2;
+ int i1_start = i1+1;
+ for(;;) {
+ i2 = str.find_first_of(wend, i1_start);
+
+ // If a delimiter was not found then the word extends to the end
+ // of the line.
+ if (i2 == (int)string::npos) {
+ i2 = str.size();
+ break;
+ }
+ else {
+ // Check for a floating point number (fpn). For example
+ // 1.34e+14 or -3.8E-19
+ // i2 might point to the + or - in e+14 or E-19, so we check
+ // for that case. Note that if the + or - is not found, then it
+ // could be a number like 1.e14 but then i2 would point to
+ // something after e14 and we would be ok.
+ // If we do find +e or -e, then everything in front of it needs
+ // to be a digit, if not then this is not a number.
+ bool fpn = false;
+ if (str[i2] == '+' || str[i2] == '-') {
+ if (str[i2-1] == 'e' || str[i2-1] == 'E' ||
+ str[i2-1] == 'd' || str[i2-1] == 'D') {
+ fpn = true;
+ for (int j=i1; j<=i2-2; j++) {
+ if (!isdigit(str[j]) && str[j] != '.') {
+ fpn = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!fpn) break;
+ i1_start = i2+1;
+ }
+ }
+
+ // If the word is quoted then it should end in quotes.
+ // We do not check for quotes matching here because at this
+ // point we might be in a comment region where quotes mismatch
+ // is allowed. We check for quotes mismatch later.
+ if (quotes) {
+ if (i2 >= (int)str.size()) i2 = (int)str.size() - 1;
+ }
+ /*
+ if (quotes) {
+ bool missing = false;
+ if (i2 >= (int)str.size()) missing = true;
+ else if (str[i1] == '\"' && str[i2] != '\"') missing = true;
+ else if (str[i1] == '\'' && str[i2] != '\'') missing = true;
+ else if (str[i1] == '\"' && str[i2] == '\'') missing = true;
+ else if (str[i1] == '\'' && str[i2] == '\"') missing = true;
+ if (missing) {
+ fatal_error2(serr, ierr);
+ serr << "Quotes mismatch found." << endl;
+ serr << "A starting quotes must have a closing quotes." << endl;
+ serr << "Double quotes, \", must be matched with double quotes." << endl;
+ serr << "Single quotes, \', must be matched with single quotes." << endl;
+ ierr = 2;
+ return false;
+ }
+ }
+ */
+
+ // We include the quotes symbols in the word. The quote symbols will
+ // be removed elsewhere.
+ if (quotes) i2 += 1;
+
+ // The word is now delimited by i1 and i2-1, return it in word.
+ word = str.substr(i1, i2 - i1);
+
+ // Update the starting point for finding the next word.
+ istart = i2;
+
+ // A word was successfully found so return true.
+ return true;
+}
+
+
+// ===========================================================================
+// Reset the command name and type. Consider the following command:
+// * lasdkj */ cmd = 5.0
+// The original command name is "*", but after the multi-line comment is
+// removed, the command name should be "cmd".
+// ===========================================================================
+void Cmd::reset_name_type()
+{
+ if ((int)words.size() == 0) {
+ cmd_name = " ";
+ cmd_type = " ";
+ return;
+ }
+ cmd_name = words[0].get_string();
+ if (! case_sensitive) {
+ transform(cmd_name.begin(), cmd_name.end(), cmd_name.begin(), tolower);
+ }
+ cmd_type = "command";
+ if (words[0].is_variable()) cmd_type = "assignment";
+ if (cmd_name == "parser_list_variables") cmd_type = "debug";
+ if (cmd_name == "parser_list_functions") cmd_type = "debug";
+ if (cmd_name == "parser_print_fbuffer") cmd_type = "debug";
+ if (cmd_name == "if") cmd_type = "internal_cmd";
+ if (cmd_name == "elseif") cmd_type = "internal_cmd";
+ if (cmd_name == "endif") cmd_type = "internal_cmd";
+ if (cmd_name == "do") cmd_type = "internal_cmd";
+ if (cmd_name == "return") cmd_type = "internal_cmd";
+ if (cmd_name == "enddo") cmd_type = "internal_cmd";
+ if (cmd_name == "stop") cmd_type = "internal_cmd";
+ if (cmd_name == "when") cmd_type = "internal_cmd";
+ if (cmd_name == "endwhen") cmd_type = "internal_cmd";
+}
+
+
+// ===========================================================================
+// Given a line like
+// include filename1 filename2 filename3 ...
+// Find the first filename that exists and return that.
+// This should only be called on the io processor.
+// ===========================================================================
+string Cmd::get_cmd_filename(stringstream &ssfiles)
+{
+ for (int i=1; i<(int)words.size(); i++) {
+ string fn = words[i].get_string();
+
+ // The quotes may still be on the word, strip them off if they are
+ // present.
+ int len = (int)fn.size();
+ if ((fn[len-1] == '\"') || (fn[len-1] == '\'')) {
+ fn.erase(fn.end() - 1);
+ }
+ if ((fn[0] == '\"') || (fn[0] == '\'')) {
+ fn.erase(fn.begin());
+ }
+
+ ssfiles << " " << fn << endl;
+
+ // Open the file to test if it exists.
+ ifstream instm(fn.c_str(), ios::in);
+ instm.close();
+ if( instm.fail() ) continue;
+ return fn;
+ }
+ return "";
+}
+
+
+// ===========================================================================
+// Handle unary minus in a command line (not in math(..))
+// ===========================================================================
+void Cmd::handle_cmd_unary_minus(stringstream &serr, int &ierr)
+{
+ int ipstart = 0;
+ for (;;) {
+ int ip = find(ipstart, (int)words.size()-1, "-");
+
+ // If we do not find any more minus signs then we are done.
+ if (ip == -1) return;
+
+ // The word after the minus sign must be a number.
+ if (!words[ip+1].is_number()) {
+ words[ip+1].fatal_error(serr, ierr);
+ serr << "Expected the object following the unary - to"
+ " be a number." << endl;
+ serr << "Instead, it was " << words[ip+1].get_string() << endl;
+ ierr = 2;
+ return;
+ }
+
+ // Actually do the negate operation.
+ do_unary_op(ip, "-");
+ ipstart = ip+1;
+ continue;
+ }
+}
+
+
+// ===========================================================================
+// Handle unary plus in a command line (not in math(..))
+// ===========================================================================
+void Cmd::handle_cmd_unary_plus(stringstream &serr, int &ierr)
+{
+ int ipstart = 0;
+ for (;;) {
+ int ip = find(ipstart, (int)words.size()-1, "+");
+
+ // If we do not find any more minus signs then we are done.
+ if (ip == -1) return;
+
+ // The word after the plus sign must be a number.
+ if (!words[ip+1].is_number()) {
+ words[ip+1].fatal_error(serr, ierr);
+ serr << "Expected the object following the unary + to"
+ " be a number." << endl;
+ serr << "Instead, it was " << words[ip+1].get_string() << endl;
+ ierr = 2;
+ return;
+ }
+
+ // The + sign is not needed.
+ delete_words(ip, ip);
+ ipstart = ip+1;
+ continue;
+ }
+}
+
+
+// ===========================================================================
+// The following type of command is allowed:
+// a(1) = 15*3.0
+// meaning that 3.0 is to be replicated 15 times and thus a(1)-a(15) is set
+// by this command.
+// ===========================================================================
+void Cmd::handle_cmd_multiplicity(stringstream &serr, int &ierr)
+{
+ int ipstart = 0;
+ for (;;) {
+ int ip = find(ipstart, (int)words.size()-1, "*");
+
+ // If we do not find any more asterisks then we are done.
+ if (ip == -1) return;
+
+ if (ip==0) {
+ fatal_error2(serr, ierr);
+ serr << "Asterisk cannot be at the start of a line." << endl;
+ ierr = 2;
+ return;
+ }
+
+ if (ip == (int)words.size()-1) {
+ words[ip].fatal_error(serr, ierr);
+ serr << "Asterisk cannot be at the end of a line." << endl;
+ ierr = 2;
+ return;
+ }
+
+ // The word after the asterisk must be a number or a boolean.
+ // Wait, why is this? We actually allow strings also, really
+ // we allow anything.
+ //if (!words[ip+1].is_number() && !words[ip+1].is_bool()) {
+ // words[ip+1].fatal_error(serr, ierr);
+ // serr << "Expected the object following the * to"
+ // " be a number or a logical." << endl;
+ // serr << "Instead, it was " << words[ip+1].get_string() << endl;
+ // ierr = 2;
+ // return;
+ //}
+
+ // The word before the asterisk must be a number.
+ if (!words[ip-1].is_number()) {
+ words[ip-1].fatal_error(serr, ierr);
+ serr << "Expected the object before the * to"
+ " be a number." << endl;
+ serr << "Instead, it was " << words[ip-1].get_string() << endl;
+ ierr = 2;
+ return;
+ }
+
+ // Set the multiplicity.
+ int imult = words[ip-1].get_int(serr, ierr);
+ words[ip+1].set_multiplicity(imult);
+ Word w = words[ip+1];
+ replace_words(ip-1, ip+1, w);
+ ipstart = ip;
+ }
+}
+
+
+
+// ***************************************************************************
+// ***************************************************************************
+// Functions for getting values from the commands.
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Get boolean values. This gets all the words past the = sign,
+// converts them to bool (and then to int), and puts them in the output arrays.
+//
+// The expected commands are:
+// cmdname = .true. 0d
+// cmdname(5) = false true false 1d
+// cmdname(5,9) = true false true 2d
+// etc.
+//
+// We also allow
+// cmdname = false true false
+// and we will supply the starting indices of (1) or (1,1), etc.
+//
+// But note that the , is gone at this point, so the 2d command is
+// cmdname ( 5 9 ) = true false true 2d
+//
+// This function works for any dimension, 0,1,2,3,...
+//
+// We pass the result back as an int because of the incompatibility between
+// fortran logical and c++ bool.
+// ===========================================================================
+void Cmd::get_bool_int(string &cname, int *array_vals, const vector<int> &size,
+ vector<Cmd *> &dup_cmd1, vector<int> &dup_wdex1,
+ int dup_fatal, vector<int> &dup_vals,
+ bool skip, stringstream &serr, int &ierr)
+{
+ // Get the dimension of the array, 0,1,2,3,...
+ int dim = (int)size.size();
+
+ // Check syntax, for example an equals sign must be present, and set istart.
+ // istart Position in array_vals where we start filling it.
+ // Note that istart starts from index base (default 1, Fortran style)
+ // Use set_index_base_zero for C/C++ index convention
+ vector<int> istart(dim,0);
+ if (!check_syntax(istart, serr, ierr)) return;
+
+ // If skipping, we don't need to get array values.
+ if (skip) {
+ set_processed(true);
+ return;
+ }
+
+ // Get the number of values past the = sign.
+ // Also mark the words up to and including the = sign as processed.
+ int nvals = 0;
+ if (!get_nvals(istart, size, nvals, serr, ierr)) return;
+
+ // 0d is a special case.
+ if (dim == 0) {
+ bool b = words[2].get_bool(serr, ierr);
+ int cvalue = 0;
+ if (b) cvalue = 1;
+ *array_vals = cvalue;
+ return;
+ }
+
+ // Get the values and return.
+ //int ieqp1 = 5 + dim - 1;
+ int ieqp1 = find_equals() + 1;
+ Parser_utils putils(index_base);
+ int k = putils.start_dex(istart, size);
+ for (int i=ieqp1; i<(int)words.size(); i++) {
+ bool b = words[i].get_bool(serr, ierr);
+ int cvalue = 0;
+ if (b) cvalue = 1;
+ int imult = words[i].get_multiplicity();
+ for (int j=1; j<=imult; j++) {
+ error_dup_line(cname, i, k, dup_wdex1, dup_cmd1, dup_vals,
+ size, dup_fatal, serr, ierr);
+ array_vals[k++] = cvalue;
+ }
+ }
+}
+
+// ===========================================================================
+// Get boolean values. This gets all the words past the = sign,
+// converts them to bool and puts them in the output arrays.
+//
+// The expected commands are:
+// cmdname = .true. 0d
+// cmdname(5) = false true false 1d
+// cmdname(5,9) = true false true 2d
+// etc.
+//
+// We also allow
+// cmdname = false true false
+// and we will supply the starting indices of (1) or (1,1), etc.
+//
+// But note that the , is gone at this point, so the 2d command is
+// cmdname ( 5 9 ) = true false true 2d
+//
+// This function works for any dimension, 0,1,2,3,...
+// ===========================================================================
+void Cmd::get_bool(string &cname, bool *array_vals, const vector<int> &size,
+ vector<Cmd *> &dup_cmd1, vector<int> &dup_wdex1,
+ int dup_fatal, vector<int> &dup_vals,
+ bool skip, stringstream &serr, int &ierr)
+{
+ // Get the dimension of the array, 0,1,2,3,...
+ int dim = (int)size.size();
+
+ // Check syntax, for example an equals sign must be present, and set istart.
+ // istart Position in array_vals where we start filling it.
+ // Note that istart starts from index base (default 1, Fortran style)
+ // Use set_index_base_zero for C/C++ index convention
+ vector<int> istart(dim,0);
+ if (!check_syntax(istart, serr, ierr)) return;
+
+ // If skipping, we don't need to get array values.
+ if (skip) {
+ set_processed(true);
+ return;
+ }
+
+ // Get the number of values past the = sign.
+ // Also mark the words up to and including the = sign as processed.
+ int nvals = 0;
+ if (!get_nvals(istart, size, nvals, serr, ierr)) return;
+
+ // 0d is a special case.
+ if (dim == 0) {
+ bool b = words[2].get_bool(serr, ierr);
+ *array_vals = b;
+ return;
+ }
+
+ // Get the values and return.
+ //int ieqp1 = 5 + dim - 1;
+ int ieqp1 = find_equals() + 1;
+ Parser_utils putils(index_base);
+ int k = putils.start_dex(istart, size);
+ for (int i=ieqp1; i<(int)words.size(); i++) {
+ bool b = words[i].get_bool(serr, ierr);
+ int imult = words[i].get_multiplicity();
+ for (int j=1; j<=imult; j++) {
+ error_dup_line(cname, i, k, dup_wdex1, dup_cmd1, dup_vals,
+ size, dup_fatal, serr, ierr);
+ array_vals[k++] = b;
+ }
+ }
+}
+
+
+// ===========================================================================
+// Get integer values. This gets all the words past the = sign,
+// converts them to int, and puts them in the output arrays.
+//
+// The expected commands are:
+// cmdname = some_int 0d
+// cmdname(5) = 3, 5, -15, 10 1d
+// cmdname(5,9) = 3, 7, -20, 154 2d
+// etc.
+//
+// We also allow
+// cmdname = 3, 5, -15, 10
+// and we will supply the starting indices of (1) or (1,1), etc.
+//
+// But note that the , is gone at this point, so the 2d command is
+// cmdname ( 5 9 ) = 3 7 -20 154 ...
+//
+// This function works for any dimension, 0,1,2,3,...
+// ===========================================================================
+void Cmd::get_int(string &cname, int *array_vals, const vector<int> &size,
+ vector<Cmd *> &dup_cmd1, vector<int> &dup_wdex1,
+ int dup_fatal, vector<int> &dup_vals,
+ bool skip, stringstream &serr, int &ierr)
+{
+ // Get the dimension of the array, 0,1,2,3,...
+ int dim = (int)size.size();
+
+ // Check syntax, for example an equals sign must be present, and set istart.
+ // istart Position in array_vals where we start filling it.
+ // Note that istart starts from index base (default 1, Fortran style)
+ // Use set_index_base_zero for C/C++ index convention
+ vector<int> istart(dim,0);
+ if (!check_syntax(istart, serr, ierr)) return;
+
+ // If skipping, we don't need to get array values.
+ if (skip) {
+ set_processed(true);
+ return;
+ }
+
+ // Get the number of values past the = sign.
+ // Also mark the words up to and including the = sign as processed.
+ int nvals = 0;
+ if (!get_nvals(istart, size, nvals, serr, ierr)) return;
+
+ // 0d is a special case.
+ if (dim == 0) {
+ *array_vals = words[2].get_int(serr, ierr);
+ return;
+ }
+
+ // Get the values and return.
+ //int ieqp1 = 5 + dim - 1;
+ int ieqp1 = find_equals() + 1;
+ Parser_utils putils(index_base);
+ int k = putils.start_dex(istart, size);
+ for (int i=ieqp1; i<(int)words.size(); i++) {
+ int iw = words[i].get_int(serr, ierr);
+ int imult = words[i].get_multiplicity();
+ for (int j=1; j<=imult; j++) {
+ error_dup_line(cname, i, k, dup_wdex1, dup_cmd1, dup_vals,
+ size, dup_fatal, serr, ierr);
+ array_vals[k++] = iw;
+ }
+ }
+}
+
+
+// ===========================================================================
+// Get int64_t values. This gets all the words past the = sign,
+// converts them to int, and puts them in the output arrays.
+//
+// The expected commands are:
+// cmdname = some_int 0d
+// cmdname(5) = 3, 5, -15, 10 1d
+// cmdname(5,9) = 3, 7, -20, 154 2d
+// etc.
+//
+// We also allow
+// cmdname = 3, 5, -15, 10
+// and we will supply the starting indices of (1) or (1,1), etc.
+//
+// But note that the , is gone at this point, so the 2d command is
+// cmdname ( 5 9 ) = 3 7 -20 154 ...
+//
+// This function works for any dimension, 0,1,2,3,...
+// ===========================================================================
+void Cmd::get_int(string &cname, int64_t *array_vals, const vector<int> &size,
+ vector<Cmd *> &dup_cmd1, vector<int> &dup_wdex1,
+ int dup_fatal, vector<int> &dup_vals,
+ bool skip, stringstream &serr, int &ierr)
+{
+ // Get the dimension of the array, 0,1,2,3,...
+ int dim = (int)size.size();
+
+ // Check syntax, for example an equals sign must be present, and set istart.
+ // istart Position in array_vals where we start filling it.
+ // Note that istart starts from index base (default 1, Fortran style)
+ // Use set_index_base_zero for C/C++ index convention
+ vector<int> istart(dim,0);
+ if (!check_syntax(istart, serr, ierr)) return;
+
+ // If skipping, we don't need to get array values.
+ if (skip) {
+ set_processed(true);
+ return;
+ }
+
+ // Get the number of values past the = sign.
+ // Also mark the words up to and including the = sign as processed.
+ int nvals = 0;
+ if (!get_nvals(istart, size, nvals, serr, ierr)) return;
+
+ // 0d is a special case.
+ if (dim == 0) {
+ *array_vals = words[2].get_int64_t(serr, ierr);
+ return;
+ }
+
+ // Get the values and return.
+ //int ieqp1 = 5 + dim - 1;
+ int ieqp1 = find_equals() + 1;
+ Parser_utils putils(index_base);
+ int k = putils.start_dex(istart, size);
+ for (int i=ieqp1; i<(int)words.size(); i++) {
+ int64_t iw = words[i].get_int64_t(serr, ierr);
+ int imult = words[i].get_multiplicity();
+ for (int j=1; j<=imult; j++) {
+ error_dup_line(cname, i, k, dup_wdex1, dup_cmd1, dup_vals,
+ size, dup_fatal, serr, ierr);
+ array_vals[k++] = iw;
+ }
+ }
+}
+
+// ===========================================================================
+// Get the real (double) values. This gets all the words past the = sign,
+// converts them to doubles, and puts them in the output arrays.
+//
+// The expected commands are:
+// cmdname = some_double 0d
+// cmdname(5) = 3.0, 35, -15e20, 10.154 1d
+// cmdname(5,9) = 3.0, 35, -15e20, 10.154 2d
+// etc.
+//
+// We also allow
+// cmdname = 3.0, 35, -15e20, 10.154
+// and we will supply the starting indices of (1) or (1,1), etc.
+//
+// But note that the , is gone at this point, so the 2d command is
+// cmdname ( 5 9 ) = 3.0 35 -15e20 10.154 ...
+//
+// This function works for any dimension, 0,1,2,3,...
+// ===========================================================================
+void Cmd::get_real(string &cname, double *array_vals, const vector<int> &size,
+ vector<Cmd *> &dup_cmd1, vector<int> &dup_wdex1,
+ int dup_fatal, vector<int> &dup_vals,
+ bool skip, stringstream &serr, int &ierr)
+{
+ // Get the dimension of the array, 0,1,2,3,...
+ int dim = (int)size.size();
+
+ // Check syntax, for example an equals sign must be present, and set istart.
+ // istart Position in array_vals where we start filling it.
+ // Note that istart starts from index base (default 1, Fortran style)
+ // Use set_index_base_zero for C/C++ index convention
+ vector<int> istart(dim,0);
+ if (!check_syntax(istart, serr, ierr)) return;
+
+ // If skipping, we don't need to get array values.
+ if (skip) {
+ set_processed(true);
+ return;
+ }
+
+ // Get the number of values past the = sign.
+ // Also mark the words up to and including the = sign as processed.
+ int nvals = 0;
+ if (!get_nvals(istart, size, nvals, serr, ierr)) return;
+
+ // 0d is a special case.
+ // Note that we do not increment dup_vals for 0d because duplicate scalar
+ // commands are handled differently from array commands.
+ if (dim == 0) {
+ *array_vals = words[2].get_double(serr, ierr);
+ return;
+ }
+
+ // All other dimensions.
+ //int ieqp1 = 5 + dim - 1;
+ int ieqp1 = find_equals() + 1;
+ Parser_utils putils(index_base);
+ int k = putils.start_dex(istart, size);
+ for (int i=ieqp1; i<(int)words.size(); i++) {
+ double d = words[i].get_double(serr, ierr);
+ int imult = words[i].get_multiplicity();
+ for (int j=1; j<=imult; j++) {
+ error_dup_line(cname, i, k, dup_wdex1, dup_cmd1, dup_vals,
+ size, dup_fatal, serr, ierr);
+ array_vals[k++] = d;
+ }
+ }
+}
+
+
+// ===========================================================================
+// Get the character values. This gets all the words past the = sign,
+// converts them to chars, and puts them in the output arrays.
+//
+// The expected commands are:
+// cmdname = q 0d single character
+// cmdname = char_string 0d character string
+// cmdname(3) = "May" "the", "force", "be" 1d array of strings
+// cmdname(5,9) = "11" "21" "31" 2d
+// etc.
+//
+// We also allow
+// cmdname = "May" "the", "force", "be"
+// and we will supply the starting indices of (1) or (1,1), etc.
+//
+// But note that the , is gone at this point, so the 2d command is
+// cmdname ( 5 9 ) = "11" "21" "31"
+//
+// This function works for any dimension, 0,1,2,3,...
+// For 0d, it has an extra flag to distinguish between single characters
+// and a character string.
+// ===========================================================================
+void Cmd::get_char(string &cname, vector<string> &vstr, const vector<int> &size,
+ bool single_char, vector<Cmd *> &dup_cmd1,
+ vector<int> &dup_wdex1, int dup_fatal,
+ vector<int> &dup_vals, bool skip,
+ stringstream &serr, int &ierr)
+{
+ // Get the dimension of the array, 0,1,2,3,...
+ int dim = (int)size.size();
+
+ // Check syntax, for example an equals sign must be present, and set istart.
+ // istart Position in array_vals where we start filling it.
+ // Note that istart starts from index base (default 1, Fortran style)
+ // Use set_index_base_zero for C/C++ index convention
+ vector<int> istart(dim,0);
+ if (!check_syntax(istart, serr, ierr)) return;
+
+ // If skipping, we don't need to get array values.
+ if (skip) {
+ set_processed(true);
+ return;
+ }
+
+ // Get the number of values past the = sign.
+ // Also mark the words up to and including the = sign as processed.
+ int nvals = 0;
+ if (!get_nvals(istart, size, nvals, serr, ierr)) return;
+
+ // 0d is a special case - get a single char
+ if (dim == 0 && single_char) {
+ vstr[0] = words[2].get_single_char(serr, ierr);
+ return;
+ }
+
+ // 0d is a special case - get a single string
+ if (dim == 0) {
+ vstr[0] = words[2].get_stringp();
+ return;
+ }
+
+ // Get the value and return, dim > 0.
+ // get_stringp is the same as get_string except get_stringp also marks
+ // the word as being processed.
+ //int ieqp1 = 5 + dim - 1;
+ int ieqp1 = find_equals() + 1;
+ Parser_utils putils(index_base);
+ int k = putils.start_dex(istart, size);
+ for (int i=ieqp1; i<(int)words.size(); i++) {
+ string s = words[i].get_stringp();
+ int imult = words[i].get_multiplicity();
+ for (int j=1; j<=imult; j++) {
+ error_dup_line(cname, i, k, dup_wdex1, dup_cmd1, dup_vals,
+ size, dup_fatal, serr, ierr);
+ vstr[k++] = s;
+ }
+ }
+
+}
+
+
+// ===========================================================================
+// Get sizes of arrays, this works for dimensions 1,2,3,...
+//
+// The size vector contains the sizes (or bounds) of each array dimensions.
+// It is assumed in this routine that all but the last size is known (this
+// is input) and that this routine will determine the last size. See the
+// get_sizeb function below where a different assumption is made.
+//
+// Suppose, for example, we have a 3d array called a3d which is dimensioned
+// a3d(5,3,:). The first two dimensions are known, 5 and 3, the last dimension
+// is unknown and will be determined by this routine.
+//
+// size is a vector of ints of size 3, with elements 5,3,? where the ? is
+// to be determined.
+//
+// Note that this routine is called in a loop over all the lines in the
+// input which is why we set the size using maximum.
+// ===========================================================================
+void Cmd::get_size(vector<int> &size, stringstream &serr, int &ierr)
+{
+ // Get the dimension of the array, 0,1,2,3,...
+ int dim = (int)size.size();
+
+ // Check syntax, also sets istart.
+ // istart Position in array where we start filling it.
+ // Example command might be a3d(3,2,2) = ... In this case istart
+ // would be a vector of length 3 contining 3,2,2
+ // Note that istart starts from index base (default 1, Fortran style)
+ // Use set_index_base_zero for C/C++ index convention
+ vector<int> istart(dim,0);
+ if (!check_syntax(istart, serr, ierr)) return;
+
+ // Get the number of values past the = sign.
+ int nvals = 0;
+ vector<int> size0(dim,0);
+ if (!get_nvals(istart, size0, nvals, serr, ierr)) return;
+
+ int sm = 1;
+ for (int i=0; i<dim-1; i++) {
+ sm *= size[i];
+ }
+
+ // Set the size.
+ int maxval = istart[dim-1] + (nvals-1)/sm;
+ if (maxval > size[dim-1]) {
+ size[dim-1] = maxval;
+ }
+}
+
+
+// ===========================================================================
+// This is a special purpose routine to get sizes for certain 2d arrays.
+//
+// Suppose we have the following input
+// mults(1,1) = 0. 0. 1. 5. 6. 9.
+// mults(1,2) = 3. 5. 8. 9. 10. 11. 20. 10
+// mults(1,3) = 30. 5. 38. 3.
+// In this case we don't know the size of either of the array dimensions, and
+// of course the user does not know the size either and thus cannot somehow
+// merge the above two lines.
+//
+// The purpose of this function is to obtain sizes for both the array
+// dimensions so memory allocation of the array can be done.
+//
+// The size vector contains the sizes (or bounds) of each array dimensions.
+// For the above example, this function would determine size[0] to be 8 and
+// size[1] to be 3. 8 is just the max of the number of values put in per
+// entry and 3 is just the max of the second index.
+//
+// Note that this routine is called in a loop over all the lines in the
+// input which is why we set the size using maximum.
+//
+// This routine only works for 2d arrays.
+// ===========================================================================
+void Cmd::get_sizeb(vector<int> &size, stringstream &serr, int &ierr)
+{
+ // Get the dimension of the array, 0,1,2,3,...
+ int dim = (int)size.size();
+
+ // This is a special purpose routine, dim must be 2.
+ if (dim != 2) {
+ fatal_error2(serr, ierr);
+ serr << "Cmd.cc, get_sizeb, internal error." << endl;
+ serr << "dim != 2, dim=" << dim << endl << endl;
+ ierr = 2;
+ return;
+ }
+
+ // Check syntax, also sets istart.
+ // istart Position in array where we start filling it.
+ // Example command might be a3d(3,2,2) = ... In this case istart
+ // would be a vector of length 3 contining 3,2,2
+ // Note that istart starts from index base (default 1, Fortran style)
+ // Use set_index_base_zero for C/C++ index convention
+ vector<int> istart(dim,0);
+ if (!check_syntax(istart, serr, ierr)) return;
+
+ // Get the number of values past the = sign.
+ int nvals = 0;
+ vector<int> size0(dim,0);
+ if (!get_nvals(istart, size0, nvals, serr, ierr)) return;
+
+ // Set the size vector
+ int maxval = istart[0] + nvals - 1;
+ if (maxval > size[0]) {
+ size[0] = maxval;
+ }
+
+ maxval = istart[1];
+ if (maxval > size[1]) {
+ size[1] = maxval;
+ }
+}
+
+
+// ===========================================================================
+// Check command syntax for any dimension array. The expected command is:
+// cmdname = .true. 0d
+// cmdname(5) = 1, 3, -4 1d
+// cmdname(3,4) = 1.e19, 23., -45. 2d
+// etc.
+//
+// We also allow
+// cmdname = "May" "the", "force", "be"
+// and we will supply the starting indices of (1) or (1,1), etc.
+//
+// Note that at this point, the commas have been removed so the 2d command
+// is actually
+// cmdname ( 3 4 ) = 1.e19 23. -45.
+// ===========================================================================
+bool Cmd::check_syntax(vector<int> &istart, stringstream &serr, int &ierr)
+{
+ // Get the dimension of the array, 0,1,2,3,...
+ int dim = (int)istart.size();
+
+ bool skip_check = false;
+ if (dim > 0) {
+ int ieqt = find_equals();
+ if (ieqt == 1) skip_check = true;
+ }
+
+ // Must be at least a certain number of words on the line.
+ int nw_min = 3;
+ int nw_min_wc = 3;
+ if (dim > 0 && (!skip_check)) {
+ nw_min = 6 + dim - 1;
+ nw_min_wc = nw_min + dim - 1;
+ }
+ if ((int)words.size() < nw_min) {
+ fatal_error2(serr, ierr);
+ serr << "Expected number words in this line >= " << nw_min_wc << endl;
+ serr << "Actual number words = " << words.size() << endl << endl;
+ ierr = 2;
+ // If there aren't enough words on the line, then it is hopeless.
+ return false;
+ }
+
+
+ // Word at index ieq must be an = sign.
+ int ieq = 1;
+ int ieq_wc = 2;
+ if (dim > 0 && (!skip_check)) {
+ ieq = 4 + dim -1;
+ ieq_wc = ieq + 1 + dim - 1;
+ }
+ if (words[ieq].get_string() != "=") {
+ words[ieq].fatal_error(serr, ierr);
+ serr << "Expected an equals sign for symbol " << ieq_wc << endl;
+ serr << "Instead symbol " << ieq_wc << " is: " <<
+ words[ieq].get_string() << endl << endl;
+ ierr = 2;
+ }
+
+ // The value must not have any multiplicity, i.e. be just a single value.
+ // This only applies to 0d, values for arrays can have multiplicity.
+ if (dim == 0) {
+ if (words[2].get_multiplicity() != 1) {
+ words[2].fatal_error(serr, ierr);
+ serr << "Multiplicity not equal 1 for " << words[2].get_string() << endl;
+ serr << "Multiplicity is: " << words[2].get_multiplicity() << endl << endl;
+ ierr = 2;
+ }
+ }
+
+ // Nothing more to check for 0d.
+ if (dim == 0) return true;
+
+ if (!skip_check) {
+ // Word at index 1 must be a "(".
+ if (words[1].get_string() != "(") {
+ words[1].fatal_error(serr, ierr);
+ serr << "Expected an open parenthesis ,(, following the command name"
+ " in this line," << endl;
+ serr << "For example: " << cmd_name << "(...) = ..." << endl;
+ serr << "Instead found: " << words[1].get_string() << endl << endl;
+ ierr = 2;
+ }
+
+ // There must be a closing parenthses.
+ int irp = 3 + dim - 1;
+ if (words[irp].get_string() != ")") {
+ words[irp].fatal_error(serr, ierr);
+ serr << "Expected a close parenthesis ,), following the array indices"
+ " in this line," << endl;
+ serr << "For example: " << cmd_name << "(...) = ..." << endl;
+ serr << "Instead found: " << words[irp].get_string() << endl << endl;
+ ierr = 2;
+ }
+ }
+
+
+ // istart Position in array_vals where we start filling it.
+ // Note that istart starts from index base (default 1, Fortran style)
+ // Use set_index_base_zero for C/C++ index convention
+ if (skip_check) {
+ for (int i=0; i<dim; i++) {
+ istart[i] = index_base;
+ }
+ }
+ else {
+ int ierr2 = 0;
+ for (int i=0; i<dim; i++) {
+ int iloc = 2 + i;
+ istart[i] = words[iloc].get_int(serr, ierr);
+ if (ierr < 2 && istart[i] < index_base) {
+ words[iloc].fatal_error(serr, ierr);
+ serr << "The index for the array must be an integer that is >= " << index_base << endl;
+ serr << "Integer includes numbers like 3, 3., 3.0, but not 3.5" << endl;
+ serr << "The index input is: " << istart[i] << endl << endl;
+ ierr2 = 2;
+ }
+ }
+ if (ierr2 == 2) ierr = 2;
+ }
+
+ for (int i=0; i<dim; i++) {
+ if (istart[i] < index_base) return false;
+ }
+ return true;
+}
+
+
+// ===========================================================================
+// Get the number of values (nvals) past the = sign.
+// Check that nvals does not exceed array size.
+// Also mark the words up to and including the = sign as processed.
+//
+// Works for any array dimension = 0,1,2,3,...
+// ===========================================================================
+bool Cmd::get_nvals(vector<int> &istart, const vector<int> &size,
+ int &nvals, stringstream &serr, int &ierr)
+{
+ int nvals_cur;
+ // Get the array dimension, 0,1,2,3,...
+ int dim = (int)istart.size();
+
+ // 0d is a special case.
+ if (dim == 0) {
+ nvals = 1;
+ //if (size[0] == 0) return true;
+ words[0].set_processed(true);
+ words[1].set_processed(true);
+ return true;
+ }
+
+ // Index of word after equals sign.
+ //int ieqp1 = 5 + dim - 1;
+ int ieqp1 = find_equals() + 1;
+
+ // nvals Number of values after the = sign.
+ nvals = 0;
+ for (int i=ieqp1; i<(int)words.size(); i++) {
+ nvals_cur = words[i].get_multiplicity();
+ if( nvals_cur <= 0 ){
+ fatal_error2(serr, ierr);
+ serr << "Count must be positive [" << nvals_cur << "]" << endl;
+ ierr = 2;
+ }
+ nvals += nvals_cur;
+ }
+
+ // This is for the get size function. We just want nvals and do not want
+ // to do the check or marking as processed.
+ if (size[0] == 0) return true;
+
+ // Get the max size of the array.
+ //int maxvals = size1*size2;
+ int maxvals = size[0];
+ for (int i=2; i<=dim; i++) {
+ maxvals *= size[i-1];
+ }
+
+ //int ip = istart[0]-1;
+ //if (dim == 2) {
+ // ip = istart[0]-1 + (istart[1]-1)*size[0];
+ //}
+ //if (dim == 3) {
+ // ip = istart[0]-1 + (istart[1]-1)*size[0] + (istart[2]-1)*size[0]*size[1];
+ //}
+ //if (dim == 4) {
+ // ip = istart[0]-1 + (istart[1]-1)*size[0] + (istart[2]-1)*size[0]*size[1] +
+ // (istart[3]-1)*size[0]*size[1]*size[2];
+ //}
+ //ip += nvals - maxvals;
+
+ // Find the excess, i.e. the max array position the user is trying to
+ // fill compared with the max size allowed.
+ Parser_utils putils(index_base);
+ int ix = putils.start_dex(istart, size);
+ int excess = ix + nvals - maxvals;
+
+ //cout << "&&&&&cw ip = " << ip << " excess = " << excess << endl;
+
+ // Check that the number of values input by the user does not exceed
+ // the array size.
+ //int excess = istart1 - 1 + (istart2-1)*size1 + nvals - maxvals;
+ if (excess > 0) {
+ fatal_error2(serr, ierr);
+ serr << "Maximum number of values allowed = " << maxvals << endl;
+ serr << "(for multi-dimension arrays this max number is" << endl;
+ serr << " max_dim1 * max_dim2 * ...)" << endl;
+ serr << "This command exceeds that value by " <<
+ excess << endl << endl;
+ ierr = 2;
+ }
+
+ // If fatal errors, then do not attempt further processing.
+ if (ierr == 2) return false;
+
+ // Mark as processed.
+ for (int i=0; i<ieqp1; i++) {
+ words[i].set_processed(true);
+ }
+
+ return true;
+}
+
+
+
+// ***************************************************************************
+// ***************************************************************************
+// Handle variables.
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Check for the user defining variable dimensions for multi-dimensional
+// arrays.
+//
+// This function works for any dimension, 0,1,2,3,...
+// ===========================================================================
+bool Cmd::check_for_dimension(stringstream &serr, int &ierr)
+{
+ // First do some checks.
+ string varname = words[0].get_string();
+ if (!words[0].is_variable()) return false;
+
+ for (int i=0; i<(int)words.size(); i++) {
+ if (words[i].get_string() == "=") {
+ return false;
+ }
+ }
+
+ if (words[1].get_string() != "dimension") return false;
+
+ // Find the variable, if not found, then create it.
+ map<string, Variable>::iterator p;
+ p = vmap->find(varname);
+ if (p == vmap->end()) {
+ Variable v(varname);
+ vmap->insert(pair<string, Variable>(v.get_varname(), v));
+ }
+ p = vmap->find(varname);
+
+ // Extract the bounds from the line.
+ vector<int> bounds;
+ for (int i=2; i<(int)words.size(); i++) {
+ if (words[i].get_string() == "(") continue;
+ if (words[i].is_comma()) continue;
+ if (words[i].get_string() == ":") continue;
+ if (words[i].get_string() == ")") break;
+
+ // Get the bounds, note that this also makes sure it is an integer.
+ bounds.push_back(words[i].get_int(serr, ierr));
+ }
+
+ // Actually set the bounds for the variable.
+ int lnum = words[0].get_line_number();
+ int file_lnum = words[0].get_file_line_number();
+ string fname = words[0].get_filename();
+ p->second.set_bounds(bounds, lnum, file_lnum, fname,
+ lines, serr, ierr);
+
+ return true;
+}
+
+
+// ===========================================================================
+// Check for the command
+// variable_description variable_name description
+// If found, then set the description for the variable.
+// Create the variable if necessary.
+// ===========================================================================
+bool Cmd::check_for_var_description(stringstream &serr, int &ierr)
+{
+ if (words[0].get_string() != "variable_description") return false;
+
+ // Must be 3 words in the line.
+ if (words.size() != 3) {
+ words[0].fatal_error(serr, ierr);
+ serr << "The variable_description command must have 3 words on the"
+ " line" << endl;
+ serr << "First word = variable_description" << endl;
+ serr << "Second word = name of the variable" << endl;
+ serr << "Third word = description (usually some phrase in quotes)" << endl;
+ serr << "This command has " << words.size() <<
+ " words instead of 3 words." << endl;
+ ierr = 2;
+ return true;
+ }
+
+ // The variable name is word 1.
+ string varname = words[1].get_string();
+ if (!words[1].is_variable()) {
+ words[0].fatal_error(serr, ierr);
+ serr << "Expected a variable name as word 2" << endl;
+ serr << "Variable names must begin with the $ character." << endl;
+ serr << "This variable name does not begin with a $ character." << endl;
+ serr << "Note that putting quotes around a variable name makes it" << endl;
+ serr << "a string, not a variable." << endl;
+ serr << "Variable name = " << varname << endl;
+ ierr = 2;
+ return true;
+ }
+
+ // Get the description.
+ string vardes = words[2].get_string();
+
+ // Find the variable, if not found, then create it.
+ map<string, Variable>::iterator p;
+ p = vmap->find(varname);
+ if (p == vmap->end()) {
+ Variable v(varname);
+ vmap->insert(pair<string, Variable>(v.get_varname(), v));
+ }
+ p = vmap->find(varname);
+
+ // Cannot change pre-defined variables.
+ if (p->second.is_pre_defined()) {
+ words[0].fatal_error(serr, ierr);
+ serr << "Cannot change the description for a pre-defined"
+ " variable" << endl;
+ serr << "Variable name = " << varname << " is pre-defined." << endl;
+ ierr = 2;
+ return true;
+ }
+
+ // Actually set the description.
+ p->second.set_description(vardes);
+
+ return true;
+}
+
+
+// ===========================================================================
+// Go through each word on the line (starting after the equals sign if
+// present), and replace each variable with its value.
+// This is for scalar variables only.
+// ===========================================================================
+void Cmd::substitute_variables(stringstream &serr, int &ierr)
+{
+ int irstart = 0;
+ for (int i=0; i<(int)words.size(); i++) {
+ if (words[i].get_string() == "=") {
+ irstart = 1;
+ break;
+ }
+ }
+ int nw1 = (int)words.size()-1;
+ subvar_w0(irstart, nw1, serr, ierr);
+}
+
+
+// ===========================================================================
+// Scan words i1 through i2 inclusive, replace any variables found with
+// their value.
+// If the variable is followed by ++ or --, handle that also.
+// This is for scalar variables only.
+// ===========================================================================
+void Cmd::subvar_w0(int i1, int &i2, stringstream &serr, int &ierr)
+{
+ for (int i=i1; i<=i2; i++) {
+ string s = words[i].get_string();
+ if (words[i].is_variable()) {
+ int increment = 0;
+ if (i < i2) {
+ string ppmm = words[i+1].get_string();
+ if (ppmm == "++") increment = 1;
+ if (ppmm == "--") increment = -1;
+ }
+ subvar0(i, s, increment, serr, ierr);
+ if (increment != 0) {
+ delete_words(i+1,i+1);
+ i2 -= 1;
+ }
+ }
+ }
+}
+
+
+// ===========================================================================
+// Given a variable name, varname, and its index in the words array, vardex,
+// replace it with its value.
+// This is for scalar variables only.
+// ===========================================================================
+void Cmd::subvar0(int vardex, string &varname, int increment,
+ stringstream &serr, int &ierr)
+{
+ vector<int> adex;
+
+ map<string, Variable>::iterator p;
+ p = vmap->find(varname);
+ if (p != vmap->end()) {
+ int lnum = words[vardex].get_line_number();
+ int file_lnum = words[vardex].get_file_line_number();
+ string fname = words[vardex].get_filename();
+ string svalue = p->second.get_var_value(adex, words[vardex].get_string(),
+ lnum, file_lnum, fname,
+ lines, serr, ierr);
+ //int increment = words[vardex].get_increment();
+ if (increment != 0) p->second.bump_var(adex, increment,
+ lnum, file_lnum, fname,
+ lines, serr, ierr);
+ //words[vardex].set_increment(0);
+ words[vardex].set_value(svalue);
+ }
+ else {
+ // The variable has not been defined yet.
+ words[vardex].fatal_error(serr, ierr);
+ serr << "Attempted to use a variable before it was defined."
+ << endl;
+ serr << "Undefined variable = " << varname << endl;
+ ierr = 2;
+ }
+}
+
+
+// ===========================================================================
+// Store the variable value(s), define if needed.
+// Examples:
+// $radius = 3.0 0d
+// $radius(1) = 3.0 4. 5.6e19 1d
+// $radius(3,4) = 3.0 4. 5.6e19 4 5 9 2d
+// ...
+//
+// This function works for any dimension, 0,1,2,3,...
+// ===========================================================================
+void Cmd::set_variables(stringstream &serr, int &ierr)
+{
+ //cout << "&&&&&cw Enter set_variables, words[0] = " << words[0].get_string() << endl;
+ int ieq = -1;
+ for (int i=0; i<(int)words.size(); i++) {
+ if (words[i].get_string() == "=") {
+ ieq = i;
+ break;
+ }
+ }
+
+ // If an equals sign was not found on the line, then this is not a
+ // variable assignment.
+ if (ieq == -1) return;
+
+ // If the first character of the first word is not a $, then this is not
+ // a variable assignment.
+ string vname = words[0].get_string();
+ if (!words[0].is_variable()) return;
+
+ // Define a few common things.
+ int lnum = words[0].get_line_number();
+ int file_lnum = words[0].get_file_line_number();
+ string fname = words[0].get_filename();
+ vector<string> valvec;
+
+ int dim = 0;
+ if (ieq >= 4) dim = ieq - 3;
+ //cout << "&&&&&cw vname=" << vname << " ieq=" << ieq << " dim=" << dim << endl;
+
+ // Do some checking.
+ if (dim == 0) {
+ // Must be 3 words in the line (for example: $radius = 3.0)
+ if (words.size() != 3) {
+ fatal_error2(serr, ierr);
+ serr << "Expected number words in this line = 3" << endl;
+ serr << "Actual number words = " << words.size() << endl << endl;
+ ierr = 2;
+ // If there aren't enough words on the line, then it is hopeless.
+ if (words.size() < 3) return;
+ }
+
+ // The value must not have any multiplicity, i.e. be just a single value.
+ // This only applies to 0d, values for arrays can have multiplicity.
+ if (words[2].get_multiplicity() != 1) {
+ words[2].fatal_error(serr, ierr);
+ serr << "Multiplicity not equal 1 for " << words[2].get_string() << endl;
+ serr << "Multiplicity is: " << words[2].get_multiplicity() << endl << endl;
+ ierr = 2;
+ }
+ }
+
+ if (dim > 0) {
+ int nw_min = dim + 5;
+ int nw_min_wc = nw_min + dim - 1;
+ if ((int)words.size() < nw_min) {
+ fatal_error2(serr, ierr);
+ serr << "Expected number of symbols in this line >= " << nw_min_wc << endl;
+ serr << "Actual number of symbols is less than expected." << endl << endl;
+ ierr = 2;
+ // If there aren't enough words on the line, then it is hopeless.
+ return;
+ }
+
+ // Word at index 1 must be a "(".
+ if (words[1].get_string() != "(") {
+ words[1].fatal_error(serr, ierr);
+ serr << "Expected an open parenthesis ,(, following the variable name"
+ " in this line," << endl;
+ serr << "For example: " << vname << "(...) = ..." << endl;
+ serr << "Instead found: " << words[1].get_string() << endl << endl;
+ ierr = 2;
+ return;
+ }
+
+ // There must be a closing parenthses.
+ int irp = 3 + dim - 1;
+ if (words[irp].get_string() != ")") {
+ words[irp].fatal_error(serr, ierr);
+ serr << "Expected a close parenthesis ,), following the array indices"
+ " in this line," << endl;
+ serr << "For example: " << vname << "(...) = ..." << endl;
+ serr << "Instead found: " << words[irp].get_string() << endl << endl;
+ ierr = 2;
+ return;
+ }
+ }
+
+ // Store the values in a vector.
+ for (int i=ieq+1; i<(int)words.size(); i++) {
+ int imult = words[i].get_multiplicity();
+ string s = words[i].get_string();
+ for (int j=1; j<=imult; j++) {
+ valvec.push_back(s);
+ }
+ }
+
+ // Store the array indices in a vector.
+ vector<int> istart(dim,0);
+ int ierr2 = 0;
+ for (int d=0; d<dim; d++) {
+ istart[d] = words[d+2].get_int(serr, ierr);
+ if (istart[d] <= 0) {
+ words[d+2].fatal_error(serr, ierr);
+ serr << "The index for the array must be an integer that is >= " << index_base << endl;
+ serr << "Integer includes numbers like 3, 3., 3.0, but not 3.5" << endl;
+ serr << "The index input is: " << istart[d] << endl << endl;
+ ierr2 = 2;
+ }
+ }
+ if (ierr2 == 2) {
+ ierr = 2;
+ return;
+ }
+
+ // Find the variable name in the variable map.
+ map<string, Variable>::iterator p;
+ p = vmap->find(vname);
+
+ // If the variable is found in the variable map, then replace
+ // its value with the new value. If the variable is not found
+ // in the variable map, then add it as a new variable.
+ if (p != vmap->end()) {
+ p->second.set_var_value(istart, valvec, lnum, file_lnum, fname,
+ lines, serr, ierr);
+ }
+ else {
+ Variable v(vname, istart, valvec, lnum, file_lnum, fname, lines,
+ serr, ierr);
+ vmap->insert(pair<string, Variable>(v.get_varname(), v));
+ }
+}
+
+
+
+// ===========================================================================
+// Evaluate a variable.
+// We have a word followed by multiple arguments. Find out if the word is
+// a variable, use the arguments to get the variable value, replace the
+// variable and arguments with its value.
+//
+// This function works for any dimension, 0,1,2,3,...
+// ===========================================================================
+bool Cmd::evaluate_variable(int iw1, int &i2, int &nargs,
+ stringstream &serr, int &ierr)
+{
+ // If there is no map of variables, then we do nothing.
+ if (vmap == NULL) return false;
+
+ // Do nothing if the word is not a variable (begins with $).
+ if (!words[iw1].is_variable()) return false;
+
+ // Get the variable name.
+ string varname = words[iw1].get_string();
+
+ // Find the variable.
+ map<string, Variable>::iterator p;
+ p = vmap->find(varname);
+
+ // The variable was not found.
+ if (p == vmap->end()) {
+ words[iw1].fatal_error(serr, ierr);
+ serr << "Trying to use a variable before it is defined." << endl;
+ serr << "Undefined variable = " << varname << endl;
+ serr << "The list of defined variables (at this point) is:" << endl;
+ for (p=vmap->begin(); p!=vmap->end(); p++) {
+ serr << p->second.get_varname() << endl;
+ }
+ ierr = 2;
+ return true;
+ }
+
+ // The variable was found, do the evaluation and replace the words.
+
+ // Check to see if all the variable arguments have a value.
+ bool has_value = true;
+ for (int i=0; i<nargs; i++) {
+ int j = iw1 + 1 + i;
+ if (!words[j].is_number()) {
+ has_value = false;
+ words[j].fatal_error(serr, ierr);
+ serr << "Expected a number for variable index " <<
+ i+1 << endl;
+ serr << "Instead found: " << words[j].get_string() << endl;
+ ierr = 2;
+ }
+ }
+ if (!has_value) return true;
+
+ // Check to see if all the variable arguments are integer.
+ bool all_int = true;
+ for (int i=0; i<nargs; i++) {
+ int j = iw1 + 1 + i;
+ if (!words[j].is_integer()) {
+ all_int = false;
+ words[j].fatal_error(serr, ierr);
+ serr << "Expected an integer for variable index " <<
+ i+1 << endl;
+ serr << "Instead found: " << words[j].get_string() << endl;
+ ierr = 2;
+ }
+ }
+ if (!all_int) return true;
+
+ // All the indices have values and are ints.
+ // Load all the arguments into a vector of ints.
+ vector<int> vdex;
+ for (int i=0; i<nargs; i++) {
+ int j = iw1 + 1 + i;
+ int iv = words[j].get_int();
+ vdex.push_back(iv);
+ }
+
+ // Check for ++ or -- following the variable.
+ int increment = 0;
+ int ippmm = iw1 + nargs + 1;
+ if (ippmm <= i2 && ippmm <(int)words.size()) {
+ string sppmm = words[ippmm].get_string();
+ if (sppmm == "++") increment = 1;
+ if (sppmm == "--") increment = -1;
+ }
+
+ // Evaluate the variable and replace the words.
+ // Works in any dimensionality.
+ int ln = words[iw1].get_line_number();
+ int file_ln = words[iw1].get_file_line_number();
+ string fname = words[iw1].get_filename();
+ string result = p->second.get_var_value(vdex, varname, ln, file_ln,
+ fname, lines, serr, ierr);
+ //int increment = words[iw1].get_increment();
+ if (increment != 0) p->second.bump_var(vdex, increment, ln, file_ln,
+ fname, lines, serr, ierr);
+ //words[iw1].set_increment(0);
+ Word w(result, ln, file_ln, fname, lines);
+ replace_words(iw1, iw1+nargs, w);
+ i2 -= nargs;
+
+ // If the variable was followed by a ++ or --, then remove the
+ // ++ or -- since it has been used.
+ if (increment != 0) {
+ delete_words(iw1+1, iw1+1);
+ i2 -= 1;
+ }
+
+ return true;
+}
+
+
+
+
+
+
+// ***************************************************************************
+// ***************************************************************************
+// Math evaluation.
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Math evaluation driver.
+// ===========================================================================
+void Cmd::math_eval(stringstream &serr, int &ierr)
+{
+ // Combine * * into **, i.e. form the exponentiation operator.
+ handle_star_star();
+
+ // Ops like .and., .eq., ... can at this point be part of larger words,
+ // they need to be extracted as individual words.
+ handle_ops();
+
+ //cout << "&&&&&cw Cmd.cc, Enter math_eval" << endl;
+ //for (int i=0; i<(int)words.size(); i++) {
+ // cout << words[i].get_string() << endl;
+ //}
+
+ int ieq = find_any_char(0, (int)words.size()-1, "=");
+
+ bool ifcmd = false;
+ if (words[0].get_string() == "if") {
+ ifcmd = true;
+ ieq = -1;
+ }
+
+ for (int i=0; i<(int)words.size(); i++) {
+ if (words[i].get_string() == "(" /*&& i>ieq*/) {
+ if (ifcmd && i>1) continue;
+ if (i > (int)words.size()-2) {
+ words[i].fatal_error(serr, ierr);
+ serr << "Expected (...)" << endl;
+ serr << "Found " << words[(int)words.size()-2].get_string() <<
+ words[(int)words.size()-1].get_string() << endl;
+ ierr = 2;
+ return;
+ }
+
+ // The starting index of the math expression.
+ int istart = i+1;
+
+ // Find the ending index of the math expression.
+ int iclose = find_closing_symbol("(", ")", istart);
+ if (iclose == -1) {
+ words[i+1].fatal_error(serr, ierr);
+ serr << "Did not find a closing parenthesis, ), in"
+ " math expression" << endl;
+ serr << "Check for unbalanced parentheses in math expression." << endl;
+ ierr = 2;
+ return;
+ }
+ int iend = iclose - 1;
+
+ int iwres = 0;
+ int nargs = 0;
+ for (;;) {
+ if (!handle_innermost_parens(istart, iend, iwres, nargs, true,
+ serr, ierr)) break;
+ bool isvar = false;
+ bool doit = true;
+ if (iwres <= 0) doit = false;
+ if (cmd_type == "assignment" && iwres==1) doit = false;
+ if (doit) {
+ isvar = evaluate_variable(iwres-1, iend, nargs, serr, ierr);
+ }
+ if ((iwres > 0) && (!isvar)) {
+ evaluate_function(iwres-1, iend, nargs, serr, ierr);
+ }
+ }
+
+ // Now set ihip1,2 to the original set of parens and handle those.
+ // This will do a math eval inside the parens, handle multiple arguments
+ // and possibly remove the parens.
+ // We do not remove the parens if this is a command line or an assignment
+ // line and we are to the left of the equals because a lot of checks
+ // depend on the parens being there.
+ int ihip1 = istart-1;
+ int ihip2 = iend + 1;
+ bool remp = true;
+ if (ieq>ihip2 && ihip1==1) remp = false;
+ handle_innermost_parens(ihip1, ihip2, iwres, nargs, remp,
+ serr, ierr);
+
+ // Handle the case of a variable array, i.e. evaluate and replace
+ // the variable array reference. We of course do not do this for
+ // an assignment statement where we are to the left of the equals.
+ //bool isvar = false;
+ bool doit = true;
+ if (iwres <= 0) doit = false;
+ if (cmd_type == "assignment" && iwres==1) doit = false;
+ if (doit) {
+ // We use ihip3 to account for ++ or -- following a
+ // variable array reference.
+ int ihip3 = ihip2 + 1;
+ //isvar = evaluate_variable(iwres-1, ihip3, nargs, serr, ierr);
+ evaluate_variable(iwres-1, ihip3, nargs, serr, ierr);
+ }
+
+ // Do not allow a function outside of parens. We could do this
+ // but for now all math is inside parens.
+ //if ((iwres > 0) && (!isvar)) {
+ // evaluate_function(iwres-1, iend, nargs, serr, ierr);
+ //}
+
+ } // if find (
+ } // End of loop through all words on the line.
+
+ //cout << "&&&&&cw Cmd.cc, Exit math_eval" << endl;
+}
+
+
+// ===========================================================================
+// Handle the innermost set of parentheses.
+// The return value is false if parens were not found or if they were
+// unbalanced. If parens were found and handled then true is returned.
+// iwres is an output quantity and is the location of the resultant word.
+// ===========================================================================
+bool Cmd::handle_innermost_parens(int &i1, int &i2, int &iwres, int &nargs,
+ bool remp, stringstream &serr, int &ierr)
+{
+ // If no innermost parens are found then iwres is meaningless.
+ iwres = -1;
+
+ // Search for the innermost left parens. It is ok if there is no left
+ // parens, this line just does not have parens.
+ int ip1 = find_last("(", i1, i2);
+ if (ip1 == -1) return false;
+
+ // After evaluation, the resultant word will be at ip1.
+ iwres = ip1;
+
+ int ipstart = ip1 + 1;
+ bool done = false;
+ nargs = 1;
+ for (;;) {
+ int ip2 = find_any_char(ipstart, i2, ",)");
+ if (ip2 == -1) {
+ words[ipstart].fatal_error(serr, ierr);
+ serr << "Did not find a closing parenthesis, ), in"
+ " math expression" << endl;
+ serr << "Check for unbalanced parentheses in math expression." << endl;
+ ierr = 2;
+ return false;
+ }
+
+ if (words[ip2].get_string() == ")") done = true;
+ if (words[ip2].is_comma()) nargs += 1;
+
+ if (remp) {
+ delete_words(ip2, ip2);
+ i2 -= 1;
+ }
+ int ip21a = ip2 - 1;
+ int ip21 = ip2 - 1;
+ seval(ipstart, ip21, serr, ierr);
+ i2 -= ip21a - ip21;
+
+ if (done) break;
+
+ ipstart += 1;
+ }
+
+ // Delete the leading paren.
+ if (remp) {
+ delete_words(ip1, ip1);
+ i2 -= 1;
+ }
+
+ return true;
+}
+
+
+// ===========================================================================
+// Simple evaluation of a series of words i1 to i2 inclusive.
+// ===========================================================================
+void Cmd::seval(int &i1, int &i2, stringstream &serr, int &ierr)
+{
+ Parser_math pmath;
+
+ subvar_w0(i1, i2, serr, ierr);
+ handle_unary_op(i1, i2, "-", serr, ierr);
+ handle_unary_op(i1, i2, "+", serr, ierr);
+
+ // Level Operators
+ // ----- -----------------------
+ // 8 ()
+ // 7 ++ --
+ // 6 **
+ // 5 * /
+ // 4 + -
+ // 3 .gt. .ge. .lt. .le. .eq. .ne.
+ // 2 .not.
+ // 1 .and.
+ // 0 .or.
+ for (int level=6; level>=0; level--) {
+ for (int i=i1; i<=i2; i+=1) {
+ if (words[i].is_operator(level)) {
+ int ln = words[i].get_line_number();
+ int file_ln = words[i].get_file_line_number();
+ string fname = words[i].get_filename();
+ Word w("", ln, file_ln, fname, lines);
+
+ string op_type = words[i].get_op_type();
+ if (op_type == "arithmetic")
+ pmath.do_op(i-1, i, i+1, words, w, serr, ierr);
+ if (op_type == "relational")
+ pmath.do_op_relational(i-1, i, i+1, words, w, serr, ierr);
+ if (op_type == "logical" && level == 2) // .not. is unary
+ pmath.do_op_not(i, i+1, words, w, serr, ierr);
+ if (op_type == "logical" && level != 2)
+ pmath.do_op_logical(i-1, i, i+1, words, w, serr, ierr);
+
+ // level 2, .not., is unary and is handled differently.
+ if (level == 2) {
+ replace_words(i, i+1, w);
+ i2 -= 1;
+ }
+ else {
+ replace_words(i-1, i+1, w);
+ i2 -= 2;
+ i -= 1;
+ }
+ continue;
+ }
+ }
+ }
+ //cout << "&&&&&cw Leave seval" << endl;
+}
+
+
+// ===========================================================================
+// Handle unary plus and minus.
+// utype is either "+" or "-".
+// ===========================================================================
+void Cmd::handle_unary_op(int i1, int &ipend, string utype,
+ stringstream &serr, int &ierr)
+{
+ int ipstart = i1;
+ for (;;) {
+ int ip = find(ipstart, ipend, utype);
+
+ // If we do not find any more plus/minus signs then we are done.
+ if (ip == -1) return;
+
+ // Fatal error is the plus/minus sign is the last word on the line.
+ if (ip >= ((int)words.size()-1)) {
+ words[ip].fatal_error(serr, ierr);
+ serr << "Found a " << utype << " sign at the end of a line." << endl;
+ serr << "Expected something to the right of the " << utype
+ << " sign to operate on." << endl;
+ ierr = 2;
+ return;
+ }
+
+
+ // If the plus/minus sign is the first word on the line, then it has
+ // to be a unary op. The word after the plus/minus sign must be a
+ // number or variable.
+ // This should never happen because we are always inside (...)
+ // and will never be word 0, still we should be general and take care
+ // of this case.
+ if (ip == 0) {
+ if (!words[ip+1].is_number()) {
+ words[ip+1].fatal_error(serr, ierr);
+ serr << "Expected the object following the unary " << utype
+ << " to be a number." << endl;
+ serr << "Instead, it was " << words[ip+1].get_string() << endl;
+ ierr = 2;
+ return;
+ }
+
+ // Actually do the negate operation.
+ do_unary_op(ip, utype);
+ ipstart = ip+1;
+ ipend -= 1;
+ continue;
+ }
+
+ // Check to see if the +/- is a binary op. If so, then nothing needs
+ // to be done with this +/- sign, binary ops are handled elsewhere.
+ if (words[ip-1].is_number() &&
+ (words[ip+1].is_number() || words[ip+1].get_string() == "-" ||
+ words[ip+1].get_string() == "+")
+ ) {
+ ipstart = ip+1;
+ continue;
+ }
+
+ // Check to see if the +/- is a unary op.
+ if (!words[ip-1].is_number() && words[ip+1].is_number()) {
+ do_unary_op(ip, utype);
+ ipstart = ip+1;
+ ipend -= 1;
+ continue;
+ }
+
+ // Check for an error.
+ if (!words[ip-1].is_number() &&
+ !words[ip+1].is_number()) {
+ words[ip-1].fatal_error(serr, ierr);
+ serr << "Expected the object following the unary " << utype << " to"
+ " be a number." << endl;
+ serr << "Instead, it was " << words[ip+1].get_string() << endl;
+ ierr = 2;
+ return;
+ }
+
+ words[ip].fatal_error(serr, ierr);
+ serr << "Unknown error with unary " << utype << endl;
+ serr << "Error with words: " << endl;
+ serr << words[ip].get_string() << words[ip+1].get_string() << endl;
+ ierr = 2;
+ return;
+ }
+}
+
+
+
+// ===========================================================================
+// Do a unary operation.
+// The minus sign is at word ip and the word to be negated is at word ip+1.
+// After negation, both words get replaced by the new negated word.
+// If the unary op is plus then all we need to do is get rid of the + sign.
+// ===========================================================================
+void Cmd::do_unary_op(int ip, string utype)
+{
+ if (utype == "+") {
+ delete_words(ip,ip);
+ return;
+ }
+
+ if (utype == "-") {
+ if (words[ip+1].is_number()) {
+ Word w = words[ip+1];
+ w.negate_value();
+ replace_words(ip, ip+1, w);
+ return;
+ }
+ }
+}
+
+
+
+// ===========================================================================
+// Check to see that all ++ and -- have been handled and removed.
+// ===========================================================================
+void Cmd::check_ppmm(stringstream &serr, int &ierr)
+{
+ for (int i=0; i<(int)words.size(); i++) {
+ string s = words[i].get_string();
+ if (s == "++" || s == "--") {
+ words[i].fatal_error(serr, ierr);
+ serr << "Misplaced " << s << " operator." << endl;
+ serr << "++ and -- operators must follow a variable or " << endl;
+ serr << "an element of an array variable. " << endl;
+ ierr = 2;
+ }
+ }
+}
+
+
+// ===========================================================================
+// Evaluate a function.
+// ===========================================================================
+void Cmd::evaluate_function(int iw1, int &i2, int &nargs,
+ stringstream &serr, int &ierr)
+{
+ // If there is no map of functions, then we do nothing.
+ if (fmap == NULL) return;
+
+ // If the word at iw1 is not a string then it will not be a function.
+ if (!words[iw1].is_string()) return;
+
+ // Find the function.
+ string s = words[iw1].get_string();
+ map<string, Function>::iterator p;
+ p = fmap->find(s);
+
+ // The function was not found.
+ if (p == fmap->end()) {
+ words[iw1].fatal_error(serr, ierr);
+ serr << "Expected a function" << endl;
+ serr << "Instead found: " << words[iw1].get_string() << endl;
+ serr << "The list of known functions is:" << endl;
+ for (p=fmap->begin(); p!=fmap->end(); p++) {
+ serr << p->second.get_name() << endl;
+ }
+ ierr = 2;
+ return;
+ }
+
+ // The function was found, do the evaluation and replace the words.
+
+ // Common items needed for all types of functions.
+ int ln = words[iw1].get_line_number();
+ int file_ln = words[iw1].get_file_line_number();
+ string fname = words[iw1].get_filename();
+
+
+ // Is a variable defined or not.
+ if (s == "defined") {
+ string varname = words[iw1+1].get_string();
+ string result = "true";
+ map<string, Variable>::iterator p;
+ p = vmap->find(varname);
+ if (p == vmap->end()) result = "false";
+ Word w(result, ln, file_ln, fname, lines);
+ replace_words(iw1, iw1+nargs, w);
+ i2 -= nargs;
+ return;
+ }
+
+
+ // String functions - string arguments, string results.
+ if (p->second.get_type() == "string") {
+ // Load all the arguments into a vector of strings.
+ vector<string> vs;
+ for (int i=0; i<nargs; i++) {
+ int j = iw1 + 1 + i;
+ string s = words[j].get_string();
+ vs.push_back(s);
+ }
+
+ // Calculate the function and replace the words.
+ string result = p->second.evaluate(vs, serr, ierr, ln, file_ln,
+ fname, lines);
+ Word w(result, ln, file_ln, fname, lines);
+ replace_words(iw1, iw1+nargs, w);
+ i2 -= nargs;
+ }
+
+
+ // Real functions - double arguments, double results.
+ if (p->second.get_type() == "real") {
+ // Check to see if all the function arguments have a value.
+ bool has_value = true;
+ for (int i=0; i<nargs; i++) {
+ int j = iw1 + 1 + i;
+ if (!words[j].is_number()) {
+ has_value = false;
+ words[j].fatal_error(serr, ierr);
+ serr << "Expected a number for function argument number " <<
+ i+1 << endl;
+ serr << "Instead found: " << words[j].get_string() << endl;
+ ierr = 2;
+ }
+ }
+ if (!has_value) return;
+
+ // All the arguments have values so we can deal with them
+ // as doubles.
+ // Load all the arguments into a vector of doubles.
+ vector<double> vd;
+ for (int i=0; i<nargs; i++) {
+ int j = iw1 + 1 + i;
+ double d = words[j].get_double();
+ vd.push_back(d);
+ }
+
+ // Calculate the function and replace the words.
+ double result = p->second.evaluate(vd, serr, ierr, ln, file_ln,
+ fname, lines);
+ Word w(result, ln, file_ln, fname, lines);
+ replace_words(iw1, iw1+nargs, w);
+ i2 -= nargs;
+ }
+}
+
+
+
+// ===========================================================================
+// When two "*" characters are together, assume that is the exponentiation
+// operator, "**", and replace both "*"'s with "**".
+// ===========================================================================
+void Cmd::handle_star_star()
+{
+ for (int i=0; i<(int)words.size()-1; i++) {
+ if (words[i].get_string() == "*" && words[i+1].get_string() == "*") {
+ int lnum = words[i].get_line_number();
+ int file_ln = words[i].get_file_line_number();
+ string fname = words[i].get_filename();
+ string s = "**";
+ Word w(s, lnum, file_ln, fname, lines);
+ replace_words(i, i+1, w);
+ }
+ }
+}
+
+
+// ===========================================================================
+// The parser does not automatically separate operators like .eq., .ne., etc.
+// For example, the phrase a.eq.b will be one word when it should be 3 words.
+// This routine finds those cases and splits the one word into multiple words.
+// ===========================================================================
+void Cmd::handle_ops()
+{
+ vector<string> subs;
+ subs.push_back(".eq.");
+ subs.push_back(".ne.");
+ subs.push_back(".gt.");
+ subs.push_back(".ge.");
+ subs.push_back(".lt.");
+ subs.push_back(".le.");
+ subs.push_back(".hgeq.");
+ subs.push_back(".hgne.");
+ subs.push_back(".hggt.");
+ subs.push_back(".hgge.");
+ subs.push_back(".hglt.");
+ subs.push_back(".hgle.");
+ subs.push_back(".not.");
+ subs.push_back(".and.");
+ subs.push_back(".or.");
+
+ for (int i=0; i<(int)words.size(); i++) {
+ string fstr = words[i].get_string();
+ for (int j=0; j<(int)subs.size(); j++) {
+ vector<string> vs;
+ bool b = separate_str(subs[j], fstr, vs);
+ if (b) {
+ vector<Word> vw;
+ for (int k=0; k<(int)vs.size(); k++) {
+ int lnum = words[i].get_line_number();
+ int file_lnum = words[i].get_file_line_number();
+ string fname = words[i].get_filename();
+ Word w(vs[k], lnum, file_lnum, fname, lines);
+ vw.push_back(w);
+ //cout << vs[k] << endl;
+ }
+ replace_words(i, i, vw);
+ i--;
+ break;
+ }
+ }
+
+
+ //int lnum = words[i].get_line_number();
+ //string s = "**";
+ //Word w(s, lnum, lines);
+ //replace_words(i, i+1, w);
+ }
+}
+
+
+// ===========================================================================
+// After the line has mostly been processed, check for any misplaced math
+// operations. For example, the following line
+// xcenter = 1.0 + 2.0
+// has a misplaced math op in it, i.e. it should be in parentheses
+// xcenter = (1.0 + 2.0)
+// ===========================================================================
+void Cmd::check_misplaced_math(stringstream &serr, int &ierr)
+{
+ for (int i=0; i<(int)words.size(); i++) {
+ if (words[i].is_operator()) {
+ words[i].fatal_error(serr, ierr);
+ serr << "Misplaced math operation." << endl;
+ serr << "All math operations must be inside parentheses." << endl;
+ ierr = 2;
+ }
+ }
+}
+
+
+// ***************************************************************************
+// ***************************************************************************
+// Handle if/elseif/else/endif
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Handle if/elseif/else/endif statements.
+// ===========================================================================
+void Cmd::handle_if(bool &skip, deque<bool> &skip_level,
+ deque<bool> &satisfied, stringstream &serr, int &ierr)
+{
+ // If's can be nested to any level, the number of levels is determined
+ // by the size of skip_level, the size of satisfied would also work here.
+ int nlevels = (int)skip_level.size();
+
+ // The endif statement ends a block if.
+ if (words[0].get_string() == "endif") {
+ if ((int)words.size() > 1) {
+ words[1].fatal_error(serr, ierr);
+ serr << "The endif (or end if) statement should not have "
+ "anything else on the line." << endl;
+ serr << "Found other words on the line." << endl;
+ ierr = 2;
+ }
+
+ // The if level has ended, just erase it.
+ skip_level.erase(skip_level.begin()+nlevels-1);
+ satisfied.erase(satisfied.begin()+nlevels-1);
+ skip = true;
+ return;
+ }
+
+ // Else statment.
+ if (words[0].get_string() == "else") {
+ if ((int)words.size() > 1) {
+ words[1].fatal_error(serr, ierr);
+ serr << "The else statement should not have "
+ "anything else on the line." << endl;
+ serr << "Found other words on the line." << endl;
+ ierr = 2;
+ }
+
+ // If the if has been satisfied before this else, then just
+ // skip the else block. Otherwise the if will be satisfied and
+ // we do not skip the else block.
+ if (satisfied[nlevels-1]) {
+ skip_level[nlevels-1] = true;
+ }
+ else {
+ satisfied[nlevels-1] = true;
+ skip_level[nlevels-1] = false;
+ }
+ skip = true;
+ return;
+ }
+
+ // If any level is in skip mode, then we will skip this line.
+ // This is mostly for non if related lines, but the skip flag is
+ // used below.
+ skip = false;
+ for (int n=0; n<nlevels; n++) {
+ if (skip_level[n]) {
+ skip = true;
+ }
+ }
+
+
+ // Process the elseif statement.
+ if (words[0].get_string() == "elseif") {
+ if (satisfied[nlevels-1]) {
+ skip_level[nlevels-1] = true;
+ }
+ else {
+ // If we are in skip mode at a higher level, then we can ignore this
+ // elseif.
+ if (skip && !skip_level[nlevels-1]) return;
+
+ // Do some syntax checking.
+ int wsize = (int)words.size();
+
+ if (wsize > 1) {
+ if (words[1].get_string() != "(") {
+ words[1].fatal_error(serr, ierr);
+ serr << "Expected an open parentheses, (, following " <<
+ words[0].get_string() << endl;
+ serr << "Instead found: " << words[1].get_string() << endl;
+ ierr = 2;
+ }
+ }
+
+ int nw = wsize-2;
+ if (nw >= 0) {
+ if (words[nw].get_string() != ")") {
+ words[nw].fatal_error(serr, ierr);
+ serr << "Expected a close parentheses, ), as the next to last "
+ "symbol on the line." << endl;
+ serr << "Instead found: " << words[nw].get_string() << endl;
+ ierr = 2;
+ }
+ }
+
+ nw = wsize-1;
+ if (nw >= 0) {
+ if (words[nw].get_string() != "then") {
+ words[nw].fatal_error(serr, ierr);
+ serr << "Expected then as the last word on the line." << endl;
+ serr << "Instead found: " << words[nw].get_string() << endl;
+ ierr = 2;
+ }
+ }
+
+ // Evaluate the conditional.
+ math_eval(serr, ierr);
+
+ if (words[1].get_bool(serr, ierr)) {
+ satisfied[nlevels-1] = true;
+ skip_level[nlevels-1] = false;
+ }
+ else {
+ skip_level[nlevels-1] = true;
+ }
+
+ }
+
+ // Set skip to skip the elseif statement.
+ skip = true;
+ return;
+ }
+
+
+
+
+ if (words[0].get_string() == "if") {
+ //cout << "&&&&&cw Cmd.cc, if statment encountered" << endl;
+
+ // If we are in skip mode at a higher level, then we can ignore this
+ // if.
+ if (skip) {
+ skip_level.push_back(true);
+ satisfied.push_back(true);
+ return;
+ }
+
+ // Do some syntax checking.
+ int wsize = (int)words.size();
+
+ if (wsize > 1) {
+ if (words[1].get_string() != "(") {
+ words[1].fatal_error(serr, ierr);
+ serr << "Expected an open parentheses, (, following " <<
+ words[0].get_string() << endl;
+ serr << "Instead found: " << words[1].get_string() << endl;
+ ierr = 2;
+ }
+ }
+
+ // Evaluate the conditional.
+ math_eval(serr, ierr);
+
+ //for (int i=0; i<(int)words.size(); i++) {
+ // cout << words[i].get_string() << endl;
+ //}
+
+ // Single line if
+ if (words[2].get_string() != "then") {
+ if (words[1].get_bool(serr, ierr)) {
+ delete_words(0,1);
+ reset_name_type();
+ skip = false;
+ }
+ else {
+ skip = true;
+ }
+ return;
+ }
+
+ // Multi-block if
+ if (words[2].get_string() == "then") {
+ if (words[1].get_bool(serr, ierr)) {
+ skip_level.push_back(false);
+ satisfied.push_back(true);
+ skip = true;
+ }
+ else {
+ skip_level.push_back(true);
+ satisfied.push_back(false);
+ skip = true;
+ }
+ return;
+ }
+ }
+
+
+ //for (int i=0; i<(int)words.size(); i++) {
+ // if (words[i].get_string() == "*" && words[i+1].get_string() == "*") {
+ // }
+ //}
+}
+
+
+// ***************************************************************************
+// ***************************************************************************
+// Handle do loops
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Handle do loops.
+// ===========================================================================
+void Cmd::handle_do(bool &skip, deque<int> &do_start, int &cdex,
+ bool &end_do_loop, stringstream &serr, int &ierr)
+{
+ // Do's can be nested to any level, the number of levels is determined
+ // by the size of do_start.
+ int nlevels = (int)do_start.size();
+
+ // End of do loop, go back to do line.
+ if (words[0].get_string() == "enddo") {
+ //cout << "&&&&&cw Cmd, handle_do, start of enddo, cdex=" << cdex << endl;
+ if ((int)words.size() > 1) {
+ words[1].fatal_error(serr, ierr);
+ serr << "The enddo (or end do) statement should not have "
+ "anything else on the line." << endl;
+ serr << "Found other words on the line." << endl;
+ ierr = 2;
+ }
+
+ cdex = do_start[nlevels-1] - 1;
+ skip = true;
+ return;
+ }
+
+
+ // Cycle command encountered.
+ if (words[0].get_string() == "cycle") {
+ if ((int)words.size() > 1) {
+ words[1].fatal_error(serr, ierr);
+ serr << "The cycle statement should not have "
+ "anything else on the line." << endl;
+ serr << "Found other words on the line." << endl;
+ ierr = 2;
+ }
+
+ cdex = do_start[nlevels-1] - 1;
+ skip = true;
+ return;
+ }
+
+ // Break out of the do loop.
+ if (words[0].get_string() == "exit") {
+ if ((int)words.size() > 1) {
+ words[1].fatal_error(serr, ierr);
+ serr << "The exit statement should not have "
+ "anything else on the line." << endl;
+ serr << "Found other words on the line." << endl;
+ ierr = 2;
+ }
+
+ end_do_loop = true;
+ return;
+ }
+
+ if (words[0].get_string() == "do") {
+
+ //for (int i=0; i<(int)words.size(); i++) {
+ // cout << words[i].get_string() << endl;
+ //}
+
+ // Evaluate any math expressions on the do line.
+ math_eval(serr, ierr);
+
+ // Replace any simple variables on the line with their values.
+ // Of course, do not replace the loop variable.
+ int ieq = -1;
+ for (int i=0; i<(int)words.size(); i++) {
+ if (words[i].get_string() == "=") {
+ ieq = i;
+ break;
+ }
+ }
+ if (ieq >= 0) {
+ int nw1 = (int)words.size()-1;
+ subvar_w0(ieq+1, nw1, serr, ierr);
+ }
+
+ // Handle unary minus
+ handle_cmd_unary_minus(serr, ierr);
+
+ // Number of words on the line after math evaluation.
+ int nwords = (int)words.size();
+
+ // Get the loop variable name.
+ string do_varname = "$i";
+ bool isvar = true;
+ if (nwords>1) {
+ do_varname = words[1].get_string();
+ if (!words[1].is_variable()) isvar = false;
+ }
+
+ // Expecting 6 or 8 words, i.e. "do $i = 1 , 10"
+ if (nwords < 6) {
+ words[0].fatal_error(serr, ierr);
+ serr << "Expected at least 6 words on this line after any math evaluations."
+ << endl;
+ serr << "For example, " << endl
+ << " do " << do_varname << " = 1 , 10" << endl;
+ serr << "Instead found " << nwords << " words on the line." << endl;
+ serr << "The line (after any math evaluations have been done) is:" << endl;
+ serr << " ";
+ for (int iw=0; iw<nwords; iw++) {
+ serr << words[iw].get_string() << " ";
+ }
+ serr << endl;
+ ierr = 2;
+ return;
+ }
+
+ // Variables must begin with a $
+ if (!isvar) {
+ words[0].fatal_error(serr, ierr);
+ serr << "Loop variable names must begin with a $ sign." << endl;
+ serr << "Note that putting quotes around a variable name makes it" << endl;
+ serr << "a string, not a variable." << endl;
+ serr << "Instead found: " << do_varname << endl;
+ ierr = 2;
+ return;
+ }
+
+ // Word 3 must be an = sign.
+ if (words[2].get_string() != "=") {
+ words[2].fatal_error(serr, ierr);
+ serr << "The third word must be an = sign." << endl;
+ serr << "Instead found: " << words[2].get_string() << endl;
+ ierr = 2;
+ return;
+ }
+
+ // Word 5 must be a comma.
+ if (!words[4].is_comma()) {
+ words[4].fatal_error(serr, ierr);
+ serr << "The fifth word must be a comma." << endl;
+ serr << "Instead found: " << words[4].get_string() << endl;
+ ierr = 2;
+ return;
+ }
+
+ // The get_int functions generate an error if the values are
+ // not integer.
+ int i1 = words[3].get_int(serr, ierr);
+ int i2 = words[5].get_int(serr, ierr);
+
+ // Get the step (increment) if specified.
+ int istep = 1;
+ if (nwords > 7) istep = words[7].get_int(serr, ierr);
+
+ string s1 = words[3].get_string();
+ string s2 = words[5].get_string();
+
+ bool do_continue = false;
+ if (nlevels > 0) {
+ if (do_start[nlevels-1] == cdex) do_continue = true;
+ }
+
+ if (do_continue) { // This do has already been encountered.
+ //cout << "&&&&&cw Cmd, handle_do, do:continue" << endl;
+
+ // Find the variable in the list of variables, increment it, test for
+ // ending the loop, and store the incremented value.
+ map<string, Variable>::iterator p;
+ p = vmap->find(do_varname);
+ if (p != vmap->end()) {
+ string do_var_value = p->second.get_var_value();
+ int lnum = words[0].get_line_number();
+ int file_lnum = words[0].get_file_line_number();
+ string fname = words[0].get_filename();
+ Word w(do_var_value, lnum, file_lnum, filename, lines);
+ int ival = w.get_int(serr, ierr);
+ ival += istep;
+ //cout << "&&&&&cw Cmd, handle_do, do:continue, do_var_value=" << ival << endl;
+ if (istep >= 0 && ival > i2) {
+ end_do_loop = true;
+ return;
+ }
+ if (istep < 0 && ival < i2) {
+ end_do_loop = true;
+ return;
+ }
+ stringstream ss;
+ ss << ival;
+ string sval = ss.str();
+ vector<string> valvec;
+ valvec.push_back(sval);
+ vector<int> istart(0,0);
+ p->second.set_var_value(istart, valvec, lnum, file_lnum, fname,
+ lines, serr, ierr);
+ }
+ else {
+ words[1].fatal_error(serr, ierr);
+ serr << "The loop variable, " << do_varname <<
+ " was not found in the variable list." << endl;
+ serr << "This should not happen, possible code bug?" << endl;
+ ierr = 2;
+ return;
+ }
+ }
+ else { // A new do loop has been encountered.
+ do_start.push_back(cdex);
+
+ // It is possible that we don't execute the do loop at all.
+ if (istep >= 0 && i1 > i2) {
+ end_do_loop = true;
+ return;
+ }
+ if (istep < 0 && i1 < i2) {
+ end_do_loop = true;
+ return;
+ }
+
+ //cout << "&&&&&cw Cmd, handle_do, do:start, cdex=" << cdex << endl;
+ //cout << "&&&&&cw Cmd, handle_do, do:start, s1=" << s1 << endl;
+ //cout << "&&&&&cw Cmd, handle_do, do:start, s2=" << s2 << endl;
+
+ // Store the loop variable, create it if necessary.
+ vector<int> istart(0,0);
+ int lnum = words[0].get_line_number();
+ int file_lnum = words[0].get_file_line_number();
+ string fname = words[0].get_filename();
+ vector<string> valvec;
+ valvec.push_back(s1);
+ map<string, Variable>::iterator p;
+ p = vmap->find(do_varname);
+ if (p != vmap->end()) {
+ p->second.set_var_value(istart, valvec, lnum, file_lnum, fname,
+ lines, serr, ierr);
+ }
+ else {
+ Variable v(do_varname, istart, valvec, lnum, file_lnum, fname,
+ lines, serr, ierr);
+ vmap->insert(pair<string, Variable>(v.get_varname(), v));
+ }
+ }
+ skip = true;
+ return;
+ }
+}
+
+
+
+// ===========================================================================
+// Starting at a do statement, find the matching enddo.
+// ===========================================================================
+bool Cmd::find_matching_enddo(int &dlev, bool &stop_checking)
+{
+ if (words[0].get_string() == "enddo") {
+ if (dlev == 1) return true;
+ dlev -= 1;
+ return false;
+ }
+ if (words[0].get_string() == "do") {
+ dlev += 1;
+ return false;
+ }
+
+ // If we are in main and hit a subroutine statement then that is the
+ // end of main and we need to stop checking.
+ if (words[0].get_string() == "subroutine") {
+ stop_checking = true;
+ return false;
+ }
+
+ // If we are in a subroutine and hit an endsubroutine statement then
+ // we need to stop checking.
+ if (words[0].get_string() == "endsubroutine") {
+ stop_checking = true;
+ return false;
+ }
+
+ return false;
+}
+
+
+
+// ***************************************************************************
+// ***************************************************************************
+// Subroutines
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Handle subroutines.
+// ===========================================================================
+void Cmd::handle_subroutines(bool &skip, bool &go_to_sub, string &sub_name,
+ bool &go_to_call, stringstream &serr, int &ierr)
+{
+ // To suppress compiler warnings of unused parameters
+ assert(skip == skip);
+ //assert(serr == serr);
+ assert(ierr == ierr);
+
+ //
+ if (words[0].get_string() == "call") {
+ sub_name = words[1].get_string();
+ go_to_sub = true;
+ return;
+ }
+
+ if (words[0].get_string() == "endsubroutine" ||
+ words[0].get_string() == "return") {
+ go_to_call = true;
+ return;
+ }
+
+}
+
+
+// ===========================================================================
+// Searching for subroutine sub_name.
+// ===========================================================================
+bool Cmd::find_subroutine(string &sub_name)
+{
+ if ((int)words.size() < 2) return false;
+ if (words[0].get_string() == "subroutine" &&
+ words[1].get_string() == sub_name) return true;
+ return false;
+}
+
+
+// ===========================================================================
+// A call statement has been encountered, get the arguments, if any.
+// The call is expected to be
+// call subname ( arg1, arg2, ...)
+// ===========================================================================
+void Cmd::get_call_args(vector<string> &sargs, vector<bool> &sargs_isvar,
+ stringstream &serr, int &ierr)
+{
+ //debug_print_words("Cmd, enter get_call_args");
+
+ // We do not want to modify the words on this line, but we have to
+ // temporarily to get the math eval to work right. Therefore store the
+ // words on the line and restore them later.
+ deque <Word> words_store;
+ for (int i=0; i<(int)words.size(); i++) {
+ words_store.push_back(words[i]);
+ }
+
+ // Erase the call and the subroutine name.
+ erase_word(0);
+ erase_word(0);
+
+ // Erase the opening and closing parens.
+ if ((int)words.size() > 0) {
+ if (words[0].get_string() == "(") erase_word(0);
+ }
+ if ((int)words.size() > 0) {
+ if (words[(int)words.size()-1].get_string() == ")") erase_last_word();
+ }
+ //debug_print_words("Cmd, get_call_args, after erase");
+
+ // Do a math eval to get one word arguments. If the arguments are
+ // variables they will not be evaluated, so we will end up with a mix
+ // of variables and numbers.
+ if ((int)words.size() > 0) {
+ math_eval(serr, ierr);
+ int wlen = (int)words.size() - 1;
+ handle_unary_op(0, wlen, "-", serr, ierr);
+ wlen = (int)words.size() - 1;
+ handle_unary_op(0, wlen, "+", serr, ierr);
+ }
+
+ //debug_print_words("Cmd, get_call_args, after math eval");
+
+ // Store the arguments in the vector of strings, sargs, to be returned
+ // to the calling code and also store in the class, call_args.
+ call_args.clear();
+ call_args_isvar.clear();
+ for (int i=0; i<(int)words.size(); i++) {
+ if (words[i].is_comma()) continue;
+ sargs.push_back(words[i].get_string());
+ sargs_isvar.push_back(words[i].is_variable());
+ call_args.push_back(words[i].get_string());
+ call_args_isvar.push_back(words[i].is_variable());
+ }
+
+ // Restore the words before leaving this function.
+ words.clear();
+ for (int i=0; i<(int)words_store.size(); i++) {
+ words.push_back(words_store[i]);
+ }
+ //debug_print_words("Cmd, get_call_args, after restoring words");
+}
+
+
+// ===========================================================================
+// A subroutine statement has been encountered, get the arguments, if any.
+// The subroutine statement is expected to be
+// subroutine subname ( arg1, arg2, ...)
+// ===========================================================================
+void Cmd::get_sub_args(vector<string> &sargs, vector<bool> &sargs_isvar)
+{
+ sub_args.clear();
+ sub_args_isvar.clear();
+ for (int i=3; i<(int)words.size(); i+=2) {
+ sargs.push_back(words[i].get_string());
+ sargs_isvar.push_back(words[i].is_variable());
+ sub_args.push_back(words[i].get_string());
+ sub_args_isvar.push_back(words[i].is_variable());
+ }
+}
+
+
+// ===========================================================================
+// Accessor functions for the calling and subroutine arguments.
+// ===========================================================================
+void Cmd::copy_call_args(vector<string> &sargs, vector<bool> &sargs_isvar)
+{
+ for (int i=0; i<(int)call_args.size(); i++) {
+ sargs.push_back(call_args[i]);
+ sargs_isvar.push_back(call_args_isvar[i]);
+ }
+}
+
+void Cmd::copy_sub_args(vector<string> &sargs, vector<bool> &sargs_isvar)
+{
+ for (int i=0; i<(int)sub_args.size(); i++) {
+ sargs.push_back(sub_args[i]);
+ sargs_isvar.push_back(sub_args_isvar[i]);
+ }
+}
+
+
+
+
+// ***************************************************************************
+// ***************************************************************************
+// Handle comments.
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Process single line comments.
+// ===========================================================================
+void Cmd::single_line_comments()
+{
+ for (int i=0; i<(int)words.size()-1; i++) {
+ if ((words[i].get_string() == "!") ||
+ (words[i].get_string() == "#") ||
+ (words[i].get_string() == "/" && words[i+1].get_string() == "/")
+ ) {
+ words.erase(words.begin()+i, words.begin()+(int)words.size());
+ break;
+ }
+ }
+
+ // Handle the case where the last word might be an ! or a #
+ int ilast = (int)words.size()-1;
+ if (ilast < 0) return;
+ if ((words[ilast].get_string() == "!") || (words[ilast].get_string() == "#"))
+ words.erase(words.begin()+ilast);
+}
+
+
+// ===========================================================================
+// Process multi-line comments.
+// ===========================================================================
+void Cmd::multi_line_comments(int &level)
+{
+ /*
+ cout << "*** Enter multi_line_comments, level=" << level << endl;
+ cout << "**** original string: " << original_str << endl;
+ stringstream ss;
+ print_using_words(ss);
+ cout << " print words before:" << endl;
+ cout << " " << ss.str() << endl;
+ */
+
+ int istart = -1;
+ if (level > 0) istart = 0;
+
+ for (int i=0; i<(int)words.size()-1; i++) {
+ //cout << "Top of i loop, i=" << i << endl;
+ if (words[i].get_string() == "/" && words[i+1].get_string() == "*") {
+ if (level == 0) istart = i;
+ level += 1;
+ //cout << "found /*, i=" << i << endl;
+ i += 1;
+ continue;
+ }
+
+ if (words[i].get_string() == "*" && words[i+1].get_string() == "/") {
+ if (level == 0) {
+ cout << "Error in line " << line_number << " umatched */" << endl;
+ }
+ //cout << "found */, istart=" << istart << " words[istart]=" <<
+ // words[istart].get_string() << endl;
+ //cout << "found */, i=" << i << " words[i]=" <<
+ // words[i].get_string() << endl;
+ //cout << "found */, i+1=" << i+1 << " words[i+1]=" <<
+ // words[i+1].get_string() << endl;
+ words.erase(words.begin()+istart, words.begin()+i+2);
+ level -= 1;
+ int ndel = i+1-istart+1;
+ //cout << "ndel=" << ndel << " i=" << i << endl;
+ i = i+1-ndel+1;
+ //cout << "after changing i, i=" << i << " words[i]=" <<
+ // words[i].get_string() << endl;
+ if (level > 0) istart = i;
+ continue;
+ }
+
+ }
+
+ if (level > 0) {
+ words.erase(words.begin()+istart, words.begin()+(int)words.size());
+ }
+
+ /*
+ stringstream ss1;
+ print_using_words(ss1);
+ cout << " print words after:" << endl;
+ cout << " " << ss1.str() << endl;
+
+ cout << endl << "**********" << endl;
+ */
+}
+
+
+// ***************************************************************************
+// ***************************************************************************
+// Miscellaneous
+// ***************************************************************************
+// ***************************************************************************
+
+
+// ===========================================================================
+// Go through every word on the line, check for matching quotes, then remove
+// them.
+// ===========================================================================
+void Cmd::handle_quotes(stringstream &serr, int &ierr)
+{
+ for (int i=0; i<(int)words.size(); i++) {
+ words[i].handle_quotes(serr, ierr);
+ }
+}
+
+
+
+// ===========================================================================
+// The execution line arguments are expected to be of the form
+// -v r1=5 -v somevar = 14
+// The -v is a keyword indicating that a variable setting follows. There is
+// no $ because the shell does not allow that.
+// At this point the execution line arguments have been parsed into words.
+// This function extracts the variable definitions, inserts the $, and turns
+// them into separate lines, and returns that in string sout. Then the
+// parser can simply add that to the top of the user input file.
+// ===========================================================================
+void Cmd::handle_exe_args(string &sout)
+{
+ // We use a stringstream here instead of modifying sout directly so that
+ // we can use endl instead of \n since endl is portable and \n is not.
+ stringstream ss;
+ bool line;
+ for (int i=0; i<(int)words.size()-1; i++) {
+ // if you hit a -<letter>
+ if (words[i].get_string() == "-" &&
+ ( words[i+1].get_string() == "v" ||
+ words[i+1].get_string() == "l" ) ) {
+ // get type of argument
+ line = true;
+ if( words[i+1].get_string() == "v" ){
+ line = false;
+ }
+ // move in after the -<letter> and stuff line until next -<letter>
+ int istart = i+2;
+ for (int j=istart; j<(int)words.size(); j++) {
+ // stop at next -<letter>
+ if (j < (int)words.size()-1) {
+ if (words[j].get_string() == "-" &&
+ ( words[j+1].get_string() == "v" ||
+ words[j+1].get_string() == "l" ) ) {
+ break;
+ }
+ }
+ string sj = words[j].get_string();
+ if (j == istart && !line) {
+ sj.insert(sj.begin(), '$');
+ }
+ ss << sj << " ";
+ }
+ ss << endl;
+ }
+ }
+ sout = ss.str();
+}
+
+
+// ===========================================================================
+// Consider the following input
+// 2.0, 3.0 e15, -7.0
+// The issue is with the middle two words, "3.0 e15", the old parser ignored
+// the space and treated this as one word, 3.0e15. The new parser treats is
+// as two words.
+//
+// This should have been treated as an input error by the old parser but was
+// not, so now we have to deal with it.
+//
+// This routine detects this situation and allows the calling code to deal
+// with it according to the action input, allowed action values are:
+//
+// ignore Treat it as two words and silently continue.
+// fix Merge the two words into one word, as the old parser did.
+// error Generate a fatal error, force the user to fix it.
+//
+// ===========================================================================
+void Cmd::deprecated_input01(string action, stringstream &serr, int &ierr)
+{
+ //if (cmd_name != "depcmd01") return;
+
+ if (cmd_type != "command") return;
+
+ for (int i=0; i<(int)words.size()-2; i++) {
+ // A comma must be found first.
+ if (!words[i].is_comma()) continue;
+
+ // There could be a unary plus or minus on the next number, if so
+ // then skip it. At this point, the unary plus and minus have not
+ // been merged with their number.
+ int in1 = i+1;
+ string spm = words[i+1].get_string();
+ string s1;
+ if (spm == "+" || spm == "-") {
+ s1 = spm;
+ in1 += 1;
+ }
+ s1 += words[in1].get_string();
+
+ // in1 is where the first number is, it needs to be a number.
+ if (!words[in1].is_number()) continue;
+
+ // in2 is where the second number is, it needs to be a number.
+ int in2 = in1 + 1;
+ if (in2 > (int)words.size() - 1) break;
+ if (!words[in2].is_number()) continue;
+ string s2 = words[in2].get_string();
+ s2.erase(s2.begin());
+
+ // The first character of the second number should be an e or E.
+ // But at this point we have already detected this and prepended
+ // a 1 on to the word. So the first character should be 1 and the
+ // second character should be e or E
+ char c30 = words[in2].get_string()[0];
+ if (c30 != '1') continue;
+
+ char c31 = words[in2].get_string()[1];
+ if (c31 != 'e' && c31 != 'E') continue;
+
+ // The next word, if present should be a comma.
+ int ic2 = in2 + 1;
+ if (ic2 <= (int)words.size()-1) {
+ if (!words[ic2].is_comma()) continue;
+ }
+
+ // A deprecated input has been found, ignore it, fix it, or
+ // generate a fatal error.
+ if (action == "ignore") continue;
+ if (action == "fix") {
+ words[in2].erase_char(0);
+ merge_words(in1, in2);
+ continue;
+ }
+ if (action == "error") {
+ words[in1].fatal_error(serr, ierr);
+ serr << "Possible error, detected the following" << endl;
+ serr << " comma digits space exponent comma" << endl;
+ serr << "The digits and exponent are separated by one or more spaces,"
+ << endl;
+ serr << "this is not allowed for a single number." << endl;
+ serr << "The digits are: " << s1 << " and the exponent is: "
+ << s2 << endl;
+ serr << "If this is one number, then remove the space." << endl;
+ serr << "If this is two numbers, then put a comma between the"
+ << " digits and exponent."<< endl;
+ serr << "This error (and the same error in subsequent lines) can"
+ << endl;
+ serr << "be controlled with the following input file command"
+ << endl;
+ serr << "and arguments (put before the lines with errors)" << endl;
+ serr << " depcmd_dse argument" << endl;
+ serr << "where argument has one of the following values:" << endl;
+ serr << " fix Silently remove the space, merge into one number" << endl;
+ serr << " ignore Silently treat as two numbers" << endl;
+ serr << " error Generate fatal error (default)" << endl;
+ serr << "While the default is to generate an error, if the" << endl;
+ serr << "command name is matdef, then the default is fix." << endl;
+ ierr = 2;
+ continue;
+ }
+ }
+}
+
+
+
+// ===========================================================================
+// Fatal error
+// This is mainly meant to be called from some other class that does not
+// know about words.
+// ===========================================================================
+void Cmd::fatal_error(int iw, stringstream &serr, int &ierr)
+{
+ // To suppress compiler warnings of unused parameters
+ assert(ierr == ierr);
+
+ int lnum = words[iw].get_line_number();
+ int file_lnum = words[iw].get_file_line_number();
+ string fname = words[iw].get_filename();
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_lnum << ":" << endl;
+ serr << " " << (*lines)[lnum-1] << endl;
+ serr << "in file: " << fname << endl;
+}
+
+// ===========================================================================
+// This is meant to be called from within this class.
+// ===========================================================================
+void Cmd::fatal_error2(stringstream &serr, int &ierr)
+{
+ // To suppress compiler warnings of unused parameters
+ assert(ierr == ierr);
+
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_line_number << ":" << endl;
+ serr << " " << (*lines)[line_number-1] << endl;
+ serr << "in file: " << filename << endl;
+}
+
+
+// ===========================================================================
+// Warning
+// ===========================================================================
+void Cmd::warning(int iw, stringstream &serr, int &ierr)
+{
+ // To suppress compiler warnings of unused parameters
+ assert(ierr == ierr);
+
+ int lnum = words[iw].get_line_number();
+ int file_lnum = words[iw].get_file_line_number();
+ string fname = words[iw].get_filename();
+ serr << endl;
+ serr << "*** WARNING in line " << file_lnum << ":" << endl;
+ serr << " " << (*lines)[lnum-1] << endl;
+ serr << "in file: " << fname << endl;
+}
+
+
+// ===========================================================================
+// This is used when printing duplicate lines warnings.
+// ===========================================================================
+void Cmd::print_duplicate_line(int iw, stringstream &ss, int fn_width,
+ int lnum_width, string after_lnum)
+{
+ int lnum = words[iw].get_line_number();
+ int file_lnum = words[iw].get_file_line_number();
+ string fname = words[iw].get_filename();
+ ss << setw(fn_width) << fname;
+ ss << setw(lnum_width) << file_lnum << after_lnum;
+ ss << (*lines)[lnum-1];
+ //print_using_words_fm(ss);
+}
+
+
+// ===========================================================================
+// Get the filename size and line number size for formatting purposes
+// when printing duplicate lines warnings.
+// ===========================================================================
+void Cmd::get_duplicate_sizes(int iw, int &fn_width, int &lnum_width)
+{
+ int file_lnum = words[iw].get_file_line_number();
+ string fname = words[iw].get_filename();
+ fn_width = (int)fname.size();
+ lnum_width = 1;
+ if (file_lnum >= 10) lnum_width = 2;
+ if (file_lnum >= 100) lnum_width = 3;
+ if (file_lnum >= 1000) lnum_width = 4;
+ if (file_lnum >= 10000) lnum_width = 5;
+ if (file_lnum >= 100000) lnum_width = 6;
+ if (file_lnum >= 1000000) lnum_width = 7;
+}
+
+
+// ===========================================================================
+// Look at the places where this function is called to understand the
+// following indices.
+// wdex = i Index into the words array.
+// cdex = k C index in the output array.
+// ===========================================================================
+void Cmd::error_dup_line(string &cname, int wdex, int cdex,
+ vector<int> &dup_wdex1, vector<Cmd *> &dup_cmd1,
+ vector<int> &dup_vals, const vector<int> &size,
+ int dup_fatal, stringstream &serr, int &ierr)
+{
+ if (dup_vals[cdex] == 0) {
+ dup_cmd1[cdex] = this;
+ dup_wdex1[cdex] = wdex;
+ }
+ dup_vals[cdex] += 1;
+ if (dup_fatal == 0) return;
+ if (dup_vals[cdex] > 1) {
+ int wdex1 = dup_wdex1[cdex];
+ Cmd *cmd = dup_cmd1[cdex];
+
+ // Get the dimension of the array, 0,1,2,3,...
+ int dim = (int)size.size();
+
+ if (dup_fatal == 2) words[wdex].fatal_error(serr, ierr);
+ if (dup_fatal == 1) words[wdex].warning(serr, ierr);
+ int tot_size = 1;
+ for (int ts=0; ts<dim; ts++) {
+ tot_size *= size[ts];
+ }
+ vector<int> irdices(dim, 0);
+ Parser_utils putils(index_base);
+ putils.reverse_dex(cdex, tot_size, irdices, size);
+ serr << "A duplicate value has been specified for: " << cname << "(";
+ for (int irdex=0; irdex<dim; irdex++) {
+ serr << irdices[irdex];
+ if (irdex < dim-1) serr << ",";
+ }
+ serr << ") = " <<
+ words[wdex].get_string() << endl;
+
+ serr << "This array element was first specified in line " <<
+ cmd->get_file_line_number(wdex1) << endl;
+ string fname = cmd->get_filename(wdex1);
+ serr << " " << (*lines)[cmd->get_line_number(wdex1)-1] <<
+ endl;
+ serr << "in file: " << fname << endl;
+
+ if (dup_fatal == 2) {
+ serr << "This fatal error can be turned into a warning with the command " <<
+ endl << " duplicate_array_values = warning" << endl;
+ }
+ if (dup_fatal == 1) {
+ serr << "This warning can be turned into a fatal error with the command " <<
+ endl << " duplicate_array_values = fatal" << endl;
+ }
+ serr << "Duplicate array value checking can be turned off totally with" <<
+ endl << " duplicate_array_values = none" << endl;
+ serr << "This is not recommended since you will lose the opportunity" <<
+ endl << "to check for legimate errors in your input." << endl;
+
+ ierr = 1;
+ if (dup_fatal == 2) ierr = 3;
+ }
+}
+
+
+// ===========================================================================
+// There are some commands that can be written as two words such as "end if",
+// "else if", and "end do". Find these and combine them into one word.
+// ===========================================================================
+void Cmd::handle_two_words()
+{
+ // Handle + + -> ++
+ for (int i=0; i<(int)words.size()-1; i++) {
+ if (words[i].get_string() == "+" && words[i+1].get_string() == "+") {
+ bool combine = false;
+ if (i == (int)words.size()-2) combine = true;
+ if (i < (int)words.size()-2) {
+ if (!words[i+2].is_numvar()) combine = true;
+ }
+ if (combine) {
+ int lnum = words[i].get_line_number();
+ int file_lnum = words[i].get_file_line_number();
+ string fname = words[i].get_filename();
+ string s = "++";
+ Word w(s, lnum, file_lnum, fname, lines);
+ replace_words(i, i+1, w);
+ }
+ }
+ }
+
+ // Handle - - -> --
+ for (int i=0; i<(int)words.size()-1; i++) {
+ if (words[i].get_string() == "-" && words[i+1].get_string() == "-") {
+ bool combine = false;
+ if (i == (int)words.size()-2) combine = true;
+ if (i < (int)words.size()-2) {
+ if (!words[i+2].is_numvar()) combine = true;
+ }
+ if (combine) {
+ int lnum = words[i].get_line_number();
+ int file_lnum = words[i].get_file_line_number();
+ string fname = words[i].get_filename();
+ string s = "--";
+ Word w(s, lnum, file_lnum, fname, lines);
+ replace_words(i, i+1, w);
+ }
+ }
+ }
+
+
+ // The rest of these have at least two words on the line,
+ // like "end subroutine".
+ if ((int)words.size() < 2) return;
+
+ // Common settings.
+ int lnum = words[0].get_line_number();
+ int file_lnum = words[0].get_file_line_number();
+ string fname = words[0].get_filename();
+
+ // Handle the case where enddo is written as two
+ // words, just combine them into one word.
+ if (words[0].get_string() == "end" && words[1].get_string() == "do") {
+ string s = "enddo";
+ Word w(s, lnum, file_lnum, fname, lines);
+ replace_words(0, 1, w);
+ }
+
+ // Handle the case where endsubroutine is written as two
+ // words, just combine them into one word.
+ if (words[0].get_string() == "end" && words[1].get_string() == "subroutine") {
+ string s = "endsubroutine";
+ Word w(s, lnum, file_lnum, fname, lines);
+ replace_words(0, 1, w);
+ }
+
+ // Handle the case where endwhen is written as two
+ // words, just combine them into one word.
+ if (words[0].get_string() == "end" && words[1].get_string() == "when") {
+ string s = "endwhen";
+ Word w(s, lnum, file_lnum, fname, lines);
+ replace_words(0, 1, w);
+ }
+
+ // Handle the case where endif and elseif are written as two
+ // words, just combine them into one word.
+ if (words[0].get_string() == "end" && words[1].get_string() == "if") {
+ string s = "endif";
+ Word w(s, lnum, file_lnum, fname, lines);
+ replace_words(0, 1, w);
+ }
+ if (words[0].get_string() == "else" && words[1].get_string() == "if") {
+ string s = "elseif";
+ Word w(s, lnum, file_lnum, fname, lines);
+ replace_words(0, 1, w);
+ }
+}
+
+
+// ===========================================================================
+// Check for end of input. There are several ways user input ends:
+// End of file
+// Encounter a stop command
+// Encounter a fatal error command.
+// ===========================================================================
+bool Cmd::check_input_end(bool kill_run, stringstream &serr, int &ierr)
+{
+ // To suppress compiler warnings of unused parameters
+ assert(kill_run == kill_run);
+
+ if (words[0].get_string() == "fatal_error") {
+ int lnum = words[0].get_line_number();
+ int file_lnum = words[0].get_file_line_number();
+ string fname = words[0].get_filename();
+ serr << endl;
+ serr << "*** User has issued a fatal_error command in line "
+ << file_lnum << ":" << endl;
+ serr << " " << (*lines)[lnum-1] << endl;
+ serr << "in file: " << fname << endl;
+ serr << endl << "The user supplied fatal_error message is: " << endl;
+ serr << " ";
+ string s = (*lines)[lnum-1];
+ int i1 = s.find("f", 0);
+ for (int i=i1+12; i<(int)s.size(); i++) {
+ serr << s[i];
+ }
+ serr << endl;
+ ierr = 2;
+ return true;
+ }
+
+ if (words[0].get_string() == "stop") return true;
+ return false;
+}
+
+
+
+
+// ***************************************************************************
+// ***************************************************************************
+// Operations on the deque of words.
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Find the first occurrence of string s in part of the line.
+// ===========================================================================
+int Cmd::find(int i1, int i2, string s)
+{
+ for (int i=i1; i<=i2; i++) {
+ if (words[i].get_string() == s) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+// ===========================================================================
+// Find the first occurrence of any character in string s in part of
+// the line.
+// ===========================================================================
+int Cmd::find_any_char(int i1, int i2, string s)
+{
+ for (int i=i1; i<=i2; i++) {
+ for (int j=0; j<(int)s.size(); j++) {
+ string ssub = s.substr(j, 1);
+ if (words[i].get_string() == ssub) {
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+
+// ===========================================================================
+// Find the last occurrence of string s in the line.
+// ===========================================================================
+int Cmd::find_last(string s, int i1, int i2)
+{
+ int iloc = -1;
+ for (int i=i1; i<=i2; i++) {
+ if (words[i].get_string() == s) {
+ iloc = i;
+ }
+ }
+ return iloc;
+}
+
+
+// ===========================================================================
+// Given an input string, fstr, and a sub string, subs, find the first
+// occurrence of subs in fstr. Return in the string vector, vs, the string
+// to the left of subs, if any, the sub string itself, subs, and the string
+// to the right of subs, if any.
+// ===========================================================================
+bool Cmd::separate_str(string &subs, string &fstr, vector<string> &vs)
+{
+ // Make sure the return vector is empty.
+ vs.clear();
+
+ // Find the sub string, if not found, then nothing more to do.
+ int loc = (int)fstr.find(subs,0);
+ if (loc == (int)string::npos) return false;
+
+ // If fstr only contains subs and nothing more, then there is nothing
+ // to do.
+ if (subs == fstr) return false;
+
+ // Anything to the left of the sub string is the first string returned.
+ if (loc > 0) {
+ string s1 = fstr.substr(0,loc);
+ vs.push_back(s1);
+ }
+
+ // The sub string itself is the second string returned.
+ vs.push_back(subs);
+
+ // Find the number of characters to the right of the sub string.
+ int subs_len = (int)subs.size();
+ int fstr_len = (int)fstr.size();
+ int istart = loc + subs_len;
+ int nchar = fstr_len - istart;
+
+ // Anything to the right of the sub string is the third string returned.
+ if (nchar > 0) {
+ string s2 = fstr.substr(istart,nchar);
+ vs.push_back(s2);
+ }
+
+ return true;
+}
+
+
+// ===========================================================================
+// Find the location of the closing symbol that matches the opening symbol.
+// Symbol examples are (), [], {}
+// We assume that the opening symbol has been found and we are starting the
+// search after the opening symbol location.
+// Nesting is handled, for example, (...(...(...)...)...)
+// ===========================================================================
+int Cmd::find_closing_symbol(string opensym, string closesym, int i1)
+{
+ int level = 0;
+ for (int i=i1; i<(int)words.size(); i++) {
+ string w = words[i].get_string();
+ if (w == opensym) {
+ level += 1;
+ continue;
+ }
+ if (w == closesym) {
+ if (level == 0) return i;
+ level -= 1;
+ continue;
+ }
+ }
+ return -1;
+}
+
+
+// ===========================================================================
+// Delete words i1 through i2 inclusive from the deque.
+// ===========================================================================
+void Cmd::delete_words(int i1, int i2)
+{
+ deque<Word>::iterator p = words.begin();
+ words.erase(p + i1, p + i2 + 1);
+}
+
+
+// ===========================================================================
+// Replace words i1 through i2 inclusive with word w.
+// ===========================================================================
+void Cmd::replace_words(int i1, int i2, Word &w)
+{
+ delete_words(i1, i2);
+ deque<Word>::iterator p = words.begin();
+ words.insert(p + i1, w);
+}
+
+
+// ===========================================================================
+// Replace words i1 through i2 inclusive with all the words in vector vw.
+// ===========================================================================
+void Cmd::replace_words(int i1, int i2, vector<Word> &vw)
+{
+ delete_words(i1, i2);
+ for (int i=(int)vw.size()-1; i>=0; i--) {
+ deque<Word>::iterator p = words.begin();
+ words.insert(p + i1, vw[i]);
+ }
+}
+
+
+// ===========================================================================
+// Merge words i1 through i2 inclusive into one word located at i1, remove
+// words i1+1 through i2 inclusive.
+// ===========================================================================
+void Cmd::merge_words(int i1, int i2)
+{
+ int lnum = words[i1].get_line_number();
+ int file_lnum = words[i1].get_file_line_number();
+ string fname = words[i1].get_filename();
+ string s = words[i1].get_string();
+
+ for (int i=i1+1; i<=i2; i++) {
+ s += words[i].get_string();
+ }
+
+ Word w(s, lnum, file_lnum, fname, lines);
+ replace_words(i1, i2, w);
+}
+
+
+// ===========================================================================
+// Find the equals sign on the line.
+// ===========================================================================
+int Cmd::find_equals()
+{
+ int ieq = -1;
+ for (int i=0; i<(int)words.size(); i++) {
+ if (words[i].get_string() == "=") {
+ ieq = i;
+ break;
+ }
+ }
+ return ieq;
+}
+
+
+
+// ***************************************************************************
+// ***************************************************************************
+// Handle processed flags.
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Set all the processed flags in the line to be false.
+// ===========================================================================
+void Cmd::clear_processed()
+{
+ for (int i=0; i<(int)words.size(); i++) {
+ words[i].set_processed(false);
+ }
+}
+
+void Cmd::set_processed(bool ip)
+{
+ for (int i=0; i<(int)words.size(); i++) {
+ words[i].set_processed(ip);
+ }
+}
+
+
+
+// ===========================================================================
+// Check processed flags for each word.
+// ===========================================================================
+void Cmd::check_processed(bool &good, stringstream &serr, int &ierr)
+{
+ // First we check to see if any of the words on the line have been
+ // processed. If none of the words have been processed, then we print
+ // the entire line as an error. This saves the user from having to
+ // wade through an error print for every word on the line.
+ bool p = false;
+ for (int i=0; i<(int)words.size(); i++) {
+ p = words[i].get_processed();
+ if (p) break;
+ }
+
+ if (!p) {
+ good = false;
+ words[0].fatal_error(serr, ierr);
+ serr << "This line has not been processed." << endl;
+ ierr = 2;
+
+ return;
+ }
+
+
+ // At least one word on the line has been processed.
+ // Check all the words on the line, throw an error for any word not
+ // processed.
+ for (int i=0; i<(int)words.size(); i++) {
+ p = words[i].get_processed();
+
+ if (!p) {
+ good = false;
+ words[i].fatal_error(serr, ierr);
+ serr << "A word on this line has not been processed." << endl;
+ serr << "Not proccessed word = " << words[i].get_string() << endl;
+ ierr = 2;
+
+ }
+ }
+}
+
+
+// ***************************************************************************
+// ***************************************************************************
+// Debug
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Print all the words on the line mainly for debugging.
+// Output is to a stringstream so the calling method can decide what to do
+// with the output - send it to the screen, use it for testing, whatever.
+// ===========================================================================
+void Cmd::print_all_words()
+{
+ stringstream ss;
+ print_all_words(ss);
+ cout << ss.str();
+}
+
+void Cmd::print_all_words(stringstream &ss)
+{
+ ss << "*** Command name = " << cmd_name << endl;
+ for (int i=0; i<(int)words.size(); i++) {
+ stringstream ss2;
+ words[i].print_type(ss2);
+ ss << words[i].get_string() << " " << ss2.str() << endl;
+ }
+ ss << endl;
+}
+
+
+// ===========================================================================
+// Print all the words on the line mainly for debugging.
+// Output is to a stringstream so the calling method can decide what to do
+// with the output - send it to the screen, use it for testing, whatever.
+// ===========================================================================
+void Cmd::print_using_words(stringstream &ss)
+{
+ for (int i=0; i<(int)words.size(); i++) {
+ bool enc_quote = true;
+ if (i == 0) enc_quote = false;
+ ss << words[i].get_print_string(enc_quote) << " ";
+ }
+}
+
+// ===========================================================================
+// Another version of printing all the words on the line.
+// This version is mainly for printing out the final cmds buffer.
+//
+// The output is formatted, commas are put back in, spaces are handled better,
+// if a line is too long (see nctot_max), it is split into more than one line.
+//
+// For example, suppose the words on a line were
+// a4d ( 1 1 1 2 ) = -3.4 4.7 5.2 4.6e19
+// spaces are used to delimit the words, but it is not very readable. This
+// routine will print the above line as
+// a4d(1, 1, 1, 2) = -3.4, 4.7, 5.2, 4.6e19
+// This has the added advantage that spaces can be eliminated and a compact
+// form can be achieved.
+//
+// Another example is the line
+// strinsert_cmd01 = Use The Force
+// The string "Use The Force" is actually one word, even though it appears to
+// be three words. This routine prints this correctly as
+// strinsert_cmd01 = "Use The Force"
+// ===========================================================================
+void Cmd::print_using_words_fm(stringstream &ss)
+{
+ //debug_print_words("print_using_words_fm");
+ int nctot_max = 75;
+ int istart = 0;
+ int ieq = -1;
+ int ip1 = -1;
+ int ip2 = -1;
+ for (;;) {
+ if (istart > 0) ss << " ";
+ int nctot = 0;
+ bool done = false;
+ for (int i=istart; i<(int)words.size(); i++) {
+ bool enc_quote = true;
+ if (i == 0) enc_quote = false;
+ string s = words[i].get_print_string(enc_quote);
+ if (s == "=") ieq = i;
+ if (s == "(") ip1 = i;
+ if (s == ")") ip2 = i;
+ string sp = "";
+ if (i<(int)words.size()-1) {
+ sp = words[i+1].get_print_string(enc_quote);
+ }
+ if (sp == ")") ip2 = i+1;
+ int nc = (int)s.size();
+ if ((i>istart) && (nc+1+nctot > nctot_max)) {
+ istart = i;
+ break;
+ }
+ if (i >= (int)words.size()-1) {
+ done = true;
+ ss << s;
+ }
+ else {
+ string endstr = " ";
+ int endinc = 1;
+ if (ieq > -1) {
+ if (i > ieq) {
+ endstr = ", ";
+ endinc = 2;
+ }
+ }
+ if (ip1 > -1 && (ip2 == -1 || i < ip2)) {
+ if (i > ip1 && (ip2 == -1 || i < ip2-1)) {
+ endstr = ", ";
+ endinc = 2;
+ }
+ }
+ if (endstr == " ") {
+ if (s == "(") {
+ endstr = "";
+ endinc = 0;
+ }
+ if (i == ip2-1) {
+ endstr = "";
+ endinc = 0;
+ }
+ if (i == 0 && sp == "(") {
+ endstr = "";
+ endinc = 0;
+ }
+ }
+ ss << s << endstr;
+ nctot += nc + endinc;
+ }
+ }
+ if (done) break;
+ ss << endl;
+ }
+}
+
+
+// ===========================================================================
+// Print the original command before processing, mainly for debugging.
+// Output is to a stringstream so the calling method can decide what to do
+// with the output - send it to the screen, use it for testing, whatever.
+// ===========================================================================
+void Cmd::print_original_string(stringstream &ss)
+{
+ ss << original_str;
+}
+
+
+// ===========================================================================
+// This is mainly for debugging this class. It prints on all procs.
+// ===========================================================================
+void Cmd::debug_print_words(string s)
+{
+ cout << s << endl;
+ cout << " ";
+ for (int i=0; i<(int)words.size(); i++) {
+ bool enc_quote = true;
+ if (i == 0) enc_quote = false;
+ cout << words[i].get_print_string(enc_quote) << " ";
+ }
+ cout << endl;
+}
+
+
+
+
+
+
+} // End of the PP namespace
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Cmd.hh
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Cmd.hh?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Cmd.hh (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Cmd.hh Sun Sep 3 20:10:18 2017
@@ -0,0 +1,306 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+#ifndef CMDHHINCLUDE
+#define CMDHHINCLUDE
+
+// ***************************************************************************
+// ***************************************************************************
+// Generalized command class.
+// ***************************************************************************
+// ***************************************************************************
+
+#include <string>
+#include <deque>
+#include <vector>
+#include <map>
+#include <sstream>
+#include "Variable.hh"
+#include "Function.hh"
+
+namespace PP
+{
+using std::string;
+using std::deque;
+using std::vector;
+using std::map;
+using std::stringstream;
+
+//class Variable;
+//class Function;
+
+class Cmd
+{
+public:
+ Cmd();
+ Cmd(string s, map<string, Variable> *v, map<string, Function> *f,
+ deque<string> *lstr, int lnum, int file_lnum, string fname,
+ stringstream &serr, int &ierr);
+
+ void set_index_base(int base);
+ void set_case_sensitive(bool case_sensitive_in);
+
+ void add_word(string str, int lnum, int file_lnum, string fname);
+ void erase_word(int iw);
+ void erase_last_word();
+ void reset_name_type();
+ void delete_words(int i1, int i2);
+ void check_ppmm(stringstream &serr, int &ierr);
+ void remove_commas();
+ void handle_two_words();
+ bool check_input_end(bool kill_run, stringstream &serr, int &ierr);
+ void print_duplicate_line(int iw, stringstream &ss, int fn_width,
+ int lnum_width, string after_lnum);
+ void get_duplicate_sizes(int iw, int &fn_width, int &lnum_width);
+
+ string get_cmd_filename(stringstream &ssfiles);
+ void handle_quotes(stringstream &serr, int &ierr);
+ void handle_exe_args(string &sout);
+ void deprecated_input01(string action, stringstream &serr, int &ierr);
+ void fatal_error(int iw, stringstream &serr, int &ierr);
+ void warning(int iw, stringstream &serr, int &ierr);
+
+ void get_bool_int(string &cname, int *array_vals, const vector<int> &size,
+ vector<Cmd *> &dup_cmd1, vector<int> &dup_wdex1,
+ int dup_fatal, vector<int> &dup_vals,
+ bool skip, stringstream &serr, int &ierr);
+
+ void get_bool(string &cname, bool *array_vals, const vector<int> &size,
+ vector<Cmd *> &dup_cmd1, vector<int> &dup_wdex1,
+ int dup_fatal, vector<int> &dup_vals,
+ bool skip, stringstream &serr, int &ierr);
+
+ void get_int(string &cname, int *array_vals, const vector<int> &size,
+ vector<Cmd *> &dup_cmd1, vector<int> &dup_wdex1,
+ int dup_fatal, vector<int> &dup_vals,
+ bool skip, stringstream &serr, int &ierr);
+
+ void get_int(string &cname, int64_t *array_vals, const vector<int> &size,
+ vector<Cmd *> &dup_cmd1, vector<int> &dup_wdex1,
+ int dup_fatal, vector<int> &dup_vals,
+ bool skip, stringstream &serr, int &ierr);
+
+ void get_real(string &cname, double *array_vals, const vector<int> &size,
+ vector<Cmd *> &dup_cmd1, vector<int> &dup_wdex1,
+ int dup_fatal, vector<int> &dup_vals,
+ bool skip, stringstream &serr, int &ierr);
+
+ void get_char(string &cname, vector<string> &vstr, const vector<int> &size,
+ bool single_char, vector<Cmd *> &dup_cmd1,
+ vector<int> &dup_wdex1, int dup_fatal,
+ vector<int> &dup_vals, bool skip,
+ stringstream &serr, int &ierr);
+
+ void get_size(vector<int> &size, stringstream &serr, int &ierr);
+ void get_sizeb(vector<int> &size, stringstream &serr, int &ierr);
+
+ // Handle unary minus and plus in command lines.
+ void handle_cmd_unary_minus(stringstream &serr, int &ierr);
+ void handle_cmd_unary_plus(stringstream &serr, int &ierr);
+
+ // Handle multiplicity in command lines, i.e. a(1)=15*3.0
+ void handle_cmd_multiplicity(stringstream &serr, int &ierr);
+
+ // Handle variables.
+ bool check_for_dimension(stringstream &serr, int &ierr);
+ bool check_for_var_description(stringstream &serr, int &ierr);
+ void substitute_variables(stringstream &serr, int &ierr);
+ void set_variables(stringstream &serr, int &ierr);
+
+ // Math evaluation.
+ void math_eval(stringstream &serr, int &ierr);
+ void check_misplaced_math(stringstream &serr, int &ierr);
+
+ // Handle comments.
+ void single_line_comments();
+ void multi_line_comments(int &level);
+
+ // Handle processed flags.
+ void clear_processed();
+ void set_processed(bool ip);
+ void check_processed(bool &good, stringstream &serr, int &ierr);
+
+ // If statements.
+ void handle_if(bool &skip, deque<bool> &skip_level,
+ deque<bool> &satisfied,
+ stringstream &serr, int &ierr);
+
+ // Do loops.
+ void handle_do(bool &skip, deque<int> &do_start, int &cdex,
+ bool &end_do_loop, stringstream &serr, int &ierr);
+ bool find_matching_enddo(int &dlev, bool &stop_checking);
+
+ // Subroutines
+ void handle_subroutines(bool &skip,
+ bool &go_to_sub, string &sub_name,
+ bool &go_to_call,
+ stringstream &serr, int &ierr);
+ bool find_subroutine(string &sub_name);
+ void get_call_args(vector<string> &sargs, vector<bool> &sargs_isvar,
+ stringstream &serr, int &ierr);
+ void get_sub_args(vector<string> &sargs, vector<bool> &sargs_isvar);
+ void copy_call_args(vector<string> &sargs, vector<bool> &sargs_isvar);
+ void copy_sub_args(vector<string> &sargs, vector<bool> &sargs_isvar);
+
+ // Accessor functions.
+ string get_cmd_name() { return cmd_name; }
+ string get_cmd_type() { return cmd_type; }
+ int get_nwords() { return words.size(); }
+ string get_string(int iw) {
+ if ((int)words.size() <= iw) return "";
+ return words[iw].get_string();
+ }
+ string get_original_str() { return original_str; }
+
+ int get_line_number(int iw) { return words[iw].get_line_number(); }
+ int get_file_line_number(int iw) { return words[iw].get_file_line_number(); }
+ string get_filename(int iw) { return words[iw].get_filename(); }
+ string get_filename() { return filename; }
+ deque<string> *get_lines() { return lines; }
+
+ void set_filename(string fn) {
+ filename = fn;
+ for (int iw=0; iw<(int)words.size(); iw++) {
+ words[iw].set_filename(fn);
+ }
+ }
+
+ bool is_include() { if(words[0].get_string() == "include") return true;
+ return false; }
+
+ // Debug
+ void print_all_words();
+ void print_all_words(stringstream &ss);
+ void print_using_words(stringstream &ss);
+ void print_using_words_fm(stringstream &ss);
+ void print_original_string(stringstream &ss);
+
+
+private:
+ // Initialization method for this class.
+ void init();
+
+ void process_string(string in_str, stringstream &serr, int &ierr);
+ bool extract_next_word(int &istart, string &str, string &word,
+ stringstream &serr, int &ierr);
+ int find_closing_symbol(string opensym, string closesym, int i1);
+ bool handle_innermost_parens(int &i1, int &i2, int &iwres, int &nargs,
+ bool remp, stringstream &serr, int &ierr);
+ void evaluate_function(int iw1, int &i2, int &nargs,
+ stringstream &serr, int &ierr);
+ void seval(int &i1, int &i2, stringstream &serr, int &ierr);
+ void handle_unary_op(int i1, int &i2, string utype,
+ stringstream &serr, int &ierr);
+ void do_unary_op(int ip, string utype);
+ void handle_star_star(); // ** exponentiation
+ void handle_ops();
+
+ void subvar_w0(int i1, int &i2, stringstream &serr, int &ierr);
+ void subvar0(int vardex, string &varname, int increment,
+ stringstream &serr, int &ierr);
+ bool evaluate_variable(int iw1, int &i2, int &nargs,
+ stringstream &serr, int &ierr);
+
+ int find(int i1, int i2, string s);
+ int find_last(string s, int i1, int i2);
+ int find_any_char(int i1, int i2, string s);
+ void replace_words(int i1, int i2, Word &w);
+ void replace_words(int i1, int i2, vector<Word> &vw);
+ void merge_words(int i1, int i2);
+ bool separate_str(string &subs, string &fstr, vector<string> &vs);
+ int find_equals();
+
+ bool check_syntax(vector<int> &istart, stringstream &serr, int &ierr);
+ bool get_nvals(vector<int> &istart, const vector<int> &size,
+ int &nvals, stringstream &serr, int &ierr);
+ void debug_print_words(string s);
+
+ void fatal_error2(stringstream &serr, int &ierr);
+ void error_dup_line(string &cname, int wdex, int cdex,
+ vector<int> &dup_wdex1, vector<Cmd *> &dup_cmd1,
+ vector<int> &dup_vals, const vector<int> &size,
+ int dup_fatal, stringstream &serr, int &ierr);
+
+
+ // This is needed for telling the user what line in the input
+ // file or include file the error occurred on.
+ //
+ // line_number The line_number corresponding to this command, this is
+ // an index into lines and starts from 1, not 0.
+ // lines Pointer to the deque of original lines. This contains all
+ // the lines from the input file and any include files.
+ // file_line_number The line number in the input file or include file.
+ // filename The name of the input file or include file.
+ //
+ // file_line_number and filename are needed to that the user can open
+ // the file and go to the line in error.
+ int line_number, file_line_number;
+ string filename;
+ deque<string> *lines;
+
+ // index base, generally 1 for Fortran style and 0 for C/C++, default 1
+ // int index_base; -- using static variable instead
+
+ // The original string before processing.
+ string original_str;
+
+ // Pointer to the map of variables.
+ map<string, Variable> *vmap;
+
+ // Pointer to the map of functions.
+ map<string, Function> *fmap;
+
+ // Definitions of white space, delimiters, etc.
+ string white_space;
+ string delims;
+
+ // Storage for all the words on the line.
+ deque <Word> words;
+
+ // The name and type of the command.
+ string cmd_name;
+ string cmd_type;
+
+ // Used for subroutines.
+ vector<string> call_args, sub_args;
+ vector<bool> call_args_isvar, sub_args_isvar;
+};
+
+
+} // end of PP namespace
+
+#endif
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Comm.cc
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Comm.cc?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Comm.cc (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Comm.cc Sun Sep 3 20:10:18 2017
@@ -0,0 +1,117 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+#include <cstdlib>
+#include <assert.h>
+#include "Comm.hh"
+
+namespace PP {
+
+
+// ===========================================================================
+// Constructor
+// ===========================================================================
+Comm::Comm()
+{
+ npes = 1;
+ mype = 0;
+ iope = 0;
+
+#ifdef HAVE_MPI
+ int argc = 1;
+ char **argv = NULL;
+
+ int init_check;
+ MPI_Initialized(&init_check);
+ //printf("DEBUG -- mpi initialized %d\n",init_check);
+
+ init_flag = 0;
+ if (! init_check) {
+ // Only way for init_flag to be true is here; must be false otherwise
+ init_flag = 1;
+ MPI_Init(&argc, &argv);
+ }
+ //printf("DEBUG -- comm constructor -- init_flag %d\n",init_flag);
+
+ MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
+ MPI_Comm_size(MPI_COMM_WORLD, &npes );
+ MPI_Comm_rank(MPI_COMM_WORLD, &mype );
+#endif
+}
+
+// ===========================================================================
+// Destructor
+// ===========================================================================
+Comm::~Comm()
+{
+ //printf("DEBUG -- comm destructor -- init_flag %d\n",init_flag);
+#ifdef HAVE_MPI
+ if (init_flag) {
+ init_flag = 0;
+ MPI_Finalize();
+ }
+#endif
+}
+
+// ===========================================================================
+// Broadcast
+// ===========================================================================
+void Comm::broadcast(char *buffer, int count)
+{
+ // To suppress compiler warnings of unused parameters
+ assert(buffer == buffer);
+ assert(count == count);
+
+ if (npes == 1) return;
+#ifdef HAVE_MPI
+ MPI_Bcast(buffer, count, MPI_CHAR, 0, MPI_COMM_WORLD);
+#endif
+}
+
+// ===========================================================================
+// Error handling
+// ===========================================================================
+void Comm::global_abort_parser()
+{
+#ifdef HAVE_MPI
+ MPI_Abort(MPI_COMM_WORLD, 1);
+#endif
+ exit(1);
+}
+// ===========================================================================
+} // End of PP namespace
+
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Comm.hh
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Comm.hh?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Comm.hh (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Comm.hh Sun Sep 3 20:10:18 2017
@@ -0,0 +1,93 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+#ifndef COMMHHINCLUDE
+#define COMMHHINCLUDE
+
+#ifdef __MPI__
+#define HAVE_MPI
+#endif
+
+#ifdef HAVE_MPI
+#define MPI_NO_CPPBIND
+#include "mpi.h"
+#endif
+
+namespace PP {
+
+class Comm
+{
+ public:
+
+ Comm();
+ ~Comm();
+
+ void broadcast(char *buffer, int count);
+ void global_abort_parser();
+
+ int getProcRank(void) const {
+ return(mype);
+ }
+
+ int getNumProcs(void) const {
+ return(npes);
+ }
+
+ int getIORank(void) const {
+ return(iope);
+ }
+
+ bool isIOProc(void) const {
+ if (mype == iope) return true;
+ return false;
+ }
+
+
+ private:
+ int init_flag;
+
+ int npes, mype, iope;
+
+ //Comm(const Comm&);
+ //Comm& operator=(const Comm&);
+};
+
+
+} // End of PP namespace
+
+#endif
+
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Function.cc
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Function.cc?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Function.cc (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Function.cc Sun Sep 3 20:10:18 2017
@@ -0,0 +1,324 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+// ***************************************************************************
+// ***************************************************************************
+// This class holds information about a function. It is mostly for use with
+// the parser.
+// ***************************************************************************
+// ***************************************************************************
+#include <iostream>
+#include <iomanip>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <deque>
+#include <cctype>
+#include <cmath>
+
+#include "stdio.h"
+#include "stdlib.h"
+
+#include "Function.hh"
+
+namespace PP
+{
+using std:: string;
+using std::cout;
+using std::endl;
+using std::deque;
+using std::stringstream;
+using std::setprecision;
+using std::vector;
+
+
+// ===========================================================================
+// Default constructor.
+// ===========================================================================
+Function::Function()
+{
+ name = "__NO_NAME_GIVEN__";
+ external = true;
+ nargs = 1;
+ description = " ";
+ type = "real";
+}
+
+
+// ===========================================================================
+// Most used constructor for functions.
+// ===========================================================================
+Function::Function(string nme, bool ext, int na, string ftype, string fdes)
+{
+ name = nme;
+ external = ext;
+ nargs = na;
+ description = fdes;
+ type = ftype;
+}
+
+
+// ===========================================================================
+// Evaluate the function. This is for the case that the arguments all have
+// values (double type values) and the function can be evaluated to a double.
+// ===========================================================================
+double Function::evaluate(vector<double> &vd, stringstream &serr, int &ierr,
+ int line_number, int file_line_number,
+ string filename, deque<string> *lines)
+{
+ // Verify that the number of args needed is equal to the number of args
+ // supplied.
+ int nvd = (int)vd.size();
+ if (nvd != nargs) {
+ args_mismatch_err(nvd, nargs, serr, ierr, line_number,
+ file_line_number, filename, lines);
+ return 0.;
+ }
+
+ // Functions with one argument.
+ if (nargs == 1) {
+ double d = vd[0];
+ if (name == "acos") {
+ if (d < -1. || d > 1.) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_line_number << ":" << endl;
+ serr << " " << (*lines)[line_number-1] << endl;
+ serr << "in file: " << filename << endl;
+ serr << "Argument to acos is out of bounds." << endl;
+ serr << "Argument = " << d << endl;
+ serr << "This must be between -1. and 1." << endl;
+ ierr = 2;
+ return 0.;
+ }
+ return acos(d);
+ }
+
+ if (name == "asin") {
+ if (d < -1. || d > 1.) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_line_number << ":" << endl;
+ serr << " " << (*lines)[line_number-1] << endl;
+ serr << "in file: " << filename << endl;
+ serr << "Argument to asin is out of bounds." << endl;
+ serr << "Argument = " << d << endl;
+ serr << "This must be between -1. and 1." << endl;
+ ierr = 2;
+ return 0.;
+ }
+ return asin(d);
+ }
+
+ if (name == "atan") return atan(d);
+ if (name == "ceil") return ceil(d);
+ if (name == "cos") return cos(d);
+ if (name == "cosh") return cosh(d);
+ if (name == "exp") return exp(d);
+ if (name == "fabs") return fabs(d);
+ if (name == "floor") return floor(d);
+ if (name == "log") return log(d);
+ if (name == "log10") return log10(d);
+ if (name == "sin") return sin(d);
+ if (name == "sinh") return sinh(d);
+ if (name == "sqrt") return sqrt(d);
+ if (name == "tan") return tan(d);
+ if (name == "tanh") return tanh(d);
+ }
+
+ // Functions with two arguments.
+ if (nargs == 2) {
+ double d1 = vd[0];
+ double d2 = vd[1];
+
+ if (name == "atan2") return atan2(d1, d2);
+ if (name == "fmod") return fmod(d1, d2);
+
+ if (name == "max") {
+ double result = d2;
+ if (d1 > d2) result = d1;
+ return result;
+ }
+
+ if (name == "min") {
+ double result = d2;
+ if (d1 < d2) result = d1;
+ return result;
+ }
+
+ if (name == "pow") {
+ if (d1 <= 0.) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_line_number << ":" << endl;
+ serr << " " << (*lines)[line_number-1] << endl;
+ serr << "in file: " << filename << endl;
+ serr << "First argument (base) to pow is out of bounds." << endl;
+ serr << "Argument = " << d1 << endl;
+ serr << "This must be greater than 0." << endl;
+ ierr = 2;
+ return 0.;
+ }
+ return pow(d1, d2);
+ }
+ }
+
+
+ // If we get down to this point, then the name supplied at
+ // construction was not recognized as a function name.
+ // This should never happen because we check for a valid function
+ // name before entering this function.
+ name_err(serr, ierr, line_number, file_line_number, filename, lines);
+ return 0.;
+}
+
+
+// ===========================================================================
+// Evaluate the function. This is for string functions.
+// ===========================================================================
+string Function::evaluate(vector<string> &vs, stringstream &serr, int &ierr,
+ int line_number, int file_line_number,
+ string filename, deque<string> *lines)
+{
+ // Verify that the number of args needed is equal to the number of args
+ // supplied.
+ int nvs = (int)vs.size();
+ if (nvs != nargs) {
+ args_mismatch_err(nvs, nargs, serr, ierr, line_number,
+ file_line_number, filename, lines);
+ return "";
+ }
+
+ // Functions with one argument.
+ if (nargs == 1) {
+ string s1 = vs[0];
+ if (name == "strlen") {
+ int len = (int)s1.size();
+ stringstream ss;
+ ss << len;
+ return ss.str();
+ }
+
+ if (name == "strtrim") {
+ int len = (int)s1.size();
+ if (len == 0) return s1;
+ string whitespace = " \t";
+ int iend = s1.find_last_not_of(whitespace, len - 1);
+ int NPOS = (int)string::npos;
+ if (iend == NPOS) return s1;
+ s1.erase(iend+1, (len-1) -(iend+1) + 1);
+ return s1;
+ }
+ }
+
+ // Functions with two arguments.
+ if (nargs == 2) {
+ string s1 = vs[0];
+ string s2 = vs[1];
+ if (name == "strcat") {
+ return s1+s2;
+ }
+ }
+
+ // Functions with three arguments.
+ if (nargs == 3) {
+ string s1 = vs[0];
+ string s2 = vs[1];
+ string s3 = vs[2];
+ if (name == "strerase") {
+ int i1 = atoi(s2.c_str()) - 1; // minus 1 to get c index
+ int i2 = atoi(s3.c_str()) - 1;
+ s1.erase(i1, i2-i1+1);
+ return s1;
+ }
+
+ if (name == "strinsert") {
+ int i1 = atoi(s2.c_str()) - 1; // minus 1 to get c index
+ s1.insert(i1, s3);
+ return s1;
+ }
+
+ if (name == "strsubstr") {
+ int i1 = atoi(s2.c_str()) - 1; // minus 1 to get c index
+ int nchar = atoi(s3.c_str());
+ string sret = s1.substr(i1, nchar);
+ return sret;
+ }
+ }
+
+ // If we get down to this point, then the name supplied at
+ // construction was not recognized as a function name.
+ // This should never happen because we check for a valid function
+ // name before entering this function.
+ name_err(serr, ierr, line_number, file_line_number, filename, lines);
+ return "";
+}
+
+
+// ===========================================================================
+// Name not recognized error.
+// ===========================================================================
+void Function::name_err(stringstream &serr, int &ierr,
+ int line_number, int file_line_number,
+ string filename, deque<string> *lines)
+{
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_line_number << ":" << endl;
+ serr << " " << (*lines)[line_number-1] << endl;
+ serr << "in file: " << filename << endl;
+ serr << "** Math function fatal error **" << endl;
+ serr << "Name not recognized as a function." << endl;
+ serr << "Name = " << name << endl;
+ ierr = 2;
+}
+
+
+// ===========================================================================
+// Number of args mismatch error.
+// ===========================================================================
+void Function::args_mismatch_err(int nargs_found, int nargs_expected,
+ stringstream &serr, int &ierr,
+ int line_number, int file_line_number,
+ string filename, deque<string> *lines)
+{
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_line_number << ":" << endl;
+ serr << " " << (*lines)[line_number-1] << endl;
+ serr << "in file: " << filename << endl;
+ serr << "For function " << name << endl;
+ serr << "Number of args expected = " << nargs_expected << endl;
+ serr << "Number of args found = " << nargs_found << endl;
+ ierr = 2;
+}
+
+} // End of the PP namespace
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Function.hh
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Function.hh?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Function.hh (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Function.hh Sun Sep 3 20:10:18 2017
@@ -0,0 +1,120 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+#ifndef FUNCTIONHHINCLUDE
+#define FUNCTIONHHINCLUDE
+
+// ***************************************************************************
+// ***************************************************************************
+// This class holds information about a function. It is mostly for use with
+// the parser.
+// ***************************************************************************
+// ***************************************************************************
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <deque>
+
+namespace PP
+{
+using std::string;
+using std::deque;
+using std::stringstream;
+using std::vector;
+
+enum FuncType {FUNC_};
+
+//class ErrorState;
+
+class Function
+{
+
+public:
+ Function();
+ Function(string nme, bool ext, int na, string ftype, string fdes);
+
+ // Evaluate the function.
+ double evaluate(vector<double> &vd, stringstream &serr, int &ierr,
+ int line_number, int file_line_number,
+ string filename, deque<string> *lines);
+
+ string evaluate(vector<string> &vs, stringstream &serr, int &ierr,
+ int line_number, int file_line_number,
+ string filename, deque<string> *lines);
+
+ // Accessor methods.
+ string get_name() { return name; }
+ int get_num_args() { return nargs; }
+ string get_description() { return description; }
+ string get_type() { return type; }
+
+private:
+
+ void name_err(stringstream &serr, int &ierr,
+ int line_number, int file_line_number,
+ string filename, deque<string> *lines);
+
+ void args_mismatch_err(int nargs_found, int nargs_expected,
+ stringstream &serr, int &ierr,
+ int line_number, int file_line_number,
+ string filename, deque<string> *lines);
+
+ // The name of the function.
+ string name;
+
+ // Whether the function is external or internal. External functions
+ // are C++ functions like sin(), log(), ... Internal functions
+ // are defined within the input to the parser (this feature is not
+ // implemented yet).
+ bool external;
+
+ // The number of arguments for the function.
+ int nargs;
+
+ // A text description of the function.
+ string description;
+
+ // The type of function. Allowed types are:
+ // real double arguments, double result (cos, sin, log, ...)
+ // string string arguments, string results (strlen, strcat, ...)
+ string type;
+};
+
+
+} // End of the PP namespace
+
+#endif
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Globals.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Globals.h?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Globals.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Globals.h Sun Sep 3 20:10:18 2017
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2011-2012, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ * This research code is being developed as part of the
+ * 2011 X Division Summer Workshop for the express purpose
+ * of a collaborative code for development of ideas in
+ * the implementation of AMR codes for Exascale platforms
+ *
+ * AMR implementation of the Wave code previously developed
+ * as a demonstration code for regular grids on Exascale platforms
+ * as part of the Supercomputing Challenge and Los Alamos
+ * National Laboratory
+ *
+ * Authors: Bob Robey XCP-2 brobey at lanl.gov
+ * Neal Davis davis68 at lanl.gov, davis68 at illinois.edu
+ * David Nicholaeff dnic at lanl.gov, mtrxknight at aol.com
+ * Dennis Trujillo dptrujillo at lanl.gov, dptru10 at gmail.com
+ * Other LANL authors
+ *
+ */
+#ifndef _Globals_
+#define _Globals_
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+//#define NDEBUG 1
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define ENTITY_COINCIDENCE_TOLERANCE ((double)1.0E-5)
+
+#define KDTREE_ELEMENT_BLOCKING_SIZE ((long)1024)
+
+#define POSITIVE_INFINITY (+1.0E+64)
+#define NEGATIVE_INFINITY (-1.0E+64)
+
+#define XAXIS ((unsigned long)0)
+#define YAXIS ((unsigned long)1)
+
+typedef struct {
+ double x, y;
+} TVector;
+
+//#ifndef _BOOL
+//typedef unsigned char boolean;
+//#define true ((boolean)1)
+//#define false ((boolean)0)
+//#endif
+
+#ifndef SWAP
+#define SWAP(a,b,t) {t h; h = a; a = b; b = h; }
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/KDTree.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/KDTree.c?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/KDTree.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/KDTree.c Sun Sep 3 20:10:18 2017
@@ -0,0 +1,712 @@
+/*
+ * Copyright (c) 2011-2012, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ * This research code is being developed as part of the
+ * 2011 X Division Summer Workshop for the express purpose
+ * of a collaborative code for development of ideas in
+ * the implementation of AMR codes for Exascale platforms
+ *
+ * AMR implementation of the Wave code previously developed
+ * as a demonstration code for regular grids on Exascale platforms
+ * as part of the Supercomputing Challenge and Los Alamos
+ * National Laboratory
+ *
+ * Authors: Bob Robey XCP-2 brobey at lanl.gov
+ * Neal Davis davis68 at lanl.gov, davis68 at illinois.edu
+ * David Nicholaeff dnic at lanl.gov, mtrxknight at aol.com
+ * Dennis Trujillo dptrujillo at lanl.gov, dptru10 at gmail.com
+ * Other LANL authors
+ *
+ */
+#include <math.h>
+#include "KDTree.h"
+
+#define MALLOC(n,t) ((t*)(malloc(n * sizeof(t))))
+#define REALLOC(p,n,t) ((t*)(realloc((void*)p, n * sizeof(t))))
+#define FREE(p) { if (p) free(p); }
+
+static void median_sort(TKDTree* t,
+ unsigned int cut_direction, int k, int num, int* idx)
+{
+ int left, mid, right, a, i, j;
+
+ for (left = 0, right = num - 1; (right - left) > 1;) {
+ mid = (left + right) / 2;
+ SWAP(idx[mid], idx[left + 1], int);
+ if(Bounds_CenterAxis(&(t->elements[idx[left + 1]]), cut_direction) >
+ Bounds_CenterAxis(&(t->elements[idx[right]]), cut_direction))
+ SWAP(idx[left + 1], idx[right], int);
+ if(Bounds_CenterAxis(&(t->elements[idx[left]]), cut_direction) >
+ Bounds_CenterAxis(&(t->elements[idx[right]]), cut_direction))
+ SWAP(idx[left], idx[right], int);
+ if(Bounds_CenterAxis(&(t->elements[idx[left + 1]]), cut_direction) >
+ Bounds_CenterAxis(&(t->elements[idx[left]]), cut_direction))
+ SWAP(idx[left + 1], idx[left], int);
+ a = idx[left];
+ i = left + 1;
+ j = right;
+ while (1) {
+ for (i++;
+ Bounds_CenterAxis(&(t->elements[idx[i]]), cut_direction) <
+ Bounds_CenterAxis(&(t->elements[a]), cut_direction);
+ i++);
+ for (j--;
+ Bounds_CenterAxis(&(t->elements[idx[j]]), cut_direction) >
+ Bounds_CenterAxis(&(t->elements[a]), cut_direction);
+ j--);
+ if(j < i)
+ break;
+ SWAP(idx[i], idx[j], int);
+ }
+ idx[left] = idx[j];
+ idx[j] = a;
+ if(j >= k)
+ right = j - 1;
+ if(j <= k)
+ left = i;
+ }
+ if(((right - left) ==1) &&
+ (Bounds_CenterAxis(&(t->elements[idx[right]]), cut_direction) <
+ Bounds_CenterAxis(&(t->elements[idx[left]]), cut_direction)))
+ SWAP(idx[right], idx[left], int);
+}
+
+void KDTree_Initialize(TKDTree* t)
+{
+ assert(t);
+ /* Flush the overall tree extent */
+ Bounds_Infinite(&(t->extent));
+ /* Allocate the initial memory for tree elements */
+ t->elements_num = 0;
+ t->elements_allocated = KDTREE_ELEMENT_BLOCKING_SIZE;
+ t->elements = MALLOC(t->elements_allocated, TBounds);
+ assert(t->elements);
+ /* Start without a built tree */
+ t->tree_built = false;
+ t->tree_size = 0;
+ t->tree_safety_boxes = NULL;
+ t->tree_link = NULL;
+}
+
+void KDTree_Finalize(TKDTree* t)
+{
+ free(t->elements);
+}
+
+void KDTree_Destroy(TKDTree* t)
+{
+ assert(t);
+ /* Flush the overall tree extent */
+ Bounds_Infinite(&(t->extent));
+ /* Destroy the element list */
+ t->elements_num = 0;
+ t->elements_allocated = 0;
+ FREE(t->elements);
+ t->elements = NULL;
+ /* Destroy the actual tree */
+ t->tree_built = false;
+ t->tree_size = 0;
+ FREE(t->tree_safety_boxes);
+ t->tree_safety_boxes = NULL;
+ FREE(t->tree_link);
+ t->tree_link = NULL;
+}
+
+
+
+void KDTree_AddElement(TKDTree* t, TBounds* add)
+{
+ assert(t && add);
+ /* Destroy the current tree if it is built */
+ if(t->tree_built) {
+ t->tree_built = false;
+ t->tree_size = 0;
+ FREE(t->tree_safety_boxes);
+ t->tree_safety_boxes = NULL;
+ FREE(t->tree_link);
+ t->tree_link = NULL;
+ }
+ /* Expand the element array if necessary */
+ if(t->elements_num == t->elements_allocated) {
+ t->elements_allocated += KDTREE_ELEMENT_BLOCKING_SIZE;
+ t->elements = REALLOC(t->elements, t->elements_allocated, TBounds);
+ assert(t->elements);
+ }
+ /* Add the new element to the overall extent and the element list */
+ Bounds_AddBounds(&(t->extent), add);
+ Bounds_Copy(add, &(t->elements[t->elements_num]));
+ t->elements_num++;
+}
+
+void KDTree_CreateTree(TKDTree* t)
+{
+ unsigned int i;
+ int next_node, stack_ptr, min, mid, max, parent, cut_direction;
+ double width, max_width;
+ int* stack;
+ int* idx;
+
+ assert(t);
+ /* If the tree is already built, we don't have to do anything */
+ if(t->tree_built)
+ return;
+ /* If there are no elements in the tree, we don't have to do anything */
+ if(t->elements_num > 0) {
+ /* Allocate the k-D tree memory */
+ t->tree_size = 2 * t->elements_num;
+ t->tree_safety_boxes = MALLOC(t->tree_size, TBounds);
+ t->tree_link = MALLOC(t->tree_size, int);
+ /* Create and initialize temporary arrays */
+ next_node = 0;
+ stack_ptr = 0;
+ stack = MALLOC(3 * t->tree_size, int);
+ idx = MALLOC(t->elements_num, int);
+ for (i = 0; (int)i < t->elements_num; i++) {
+ idx[i] = i;
+ }
+ /* Setup the root node of the tree and put it on the stack */
+ stack[stack_ptr++] = 0; /* Node Number in the Tree */
+ stack[stack_ptr++] = 0; /* Element Span Minumum */
+ stack[stack_ptr++] = t->elements_num - 1; /* Element Span Maximum */
+ Bounds_Copy(&(t->extent), &(t->tree_safety_boxes[0]));
+ next_node++;
+ /* Construct k-D tree by setting up each pair of child nodes */
+ while (stack_ptr) {
+ /* Pop the top entry off the stack */
+ max = stack[--stack_ptr];
+ min = stack[--stack_ptr];
+ parent = stack[--stack_ptr];
+ /* If the current node should be a leaf node, make it one */
+ if ((max - min) == 0) {
+ Bounds_Copy(&(t->elements[idx[min]]), &(t->tree_safety_boxes[parent]));
+ t->tree_link[parent] = - idx[min];
+ continue;
+ }
+ /* Select optimum cutting direction for the parent node's safety box */
+ cut_direction = -1;
+ max_width = NEGATIVE_INFINITY;
+ for (i = 0; i < 2; i++) {
+ width = Bounds_WidthAxis(&(t->tree_safety_boxes[parent]), i);
+ if(width > max_width) {
+ max_width = width;
+ cut_direction = i;
+ }
+ }
+ assert(cut_direction >= 0);
+ /* Do a median sort of the elements under the parent node. The sort key
+ is the center point of the element bounding boxes along the selected
+ cutting direction. */
+ mid = (min + max) /2;
+ median_sort(t, (unsigned int)cut_direction, mid - min, max - min + 1, &(idx[min]));
+ /* Give the parent a reference to its two children */
+ t->tree_link[parent] = next_node;
+ /* Add the "left" child to the tree and the stack */
+ stack[stack_ptr++] = next_node; /* Node Number in the Tree */
+ stack[stack_ptr++] = min; /* Element Span Minimum */
+ stack[stack_ptr++] = mid; /* Element Span Maximum */
+ Bounds_Infinite(&(t->tree_safety_boxes[next_node]));
+ for (i = min; (int)i <= mid; i++) {
+ Bounds_AddBounds(&(t->tree_safety_boxes[next_node]),
+ &(t->elements[idx[i]]));
+ }
+ next_node++;
+ /* Add the "right" child to the tree and the stack */
+ stack[stack_ptr++] = next_node; /* Node Number in the Tree */
+ stack[stack_ptr++] = mid + 1; /* Element Span Minimum */
+ stack[stack_ptr++] = max; /* Element Span Maximum */
+ Bounds_Infinite(&(t->tree_safety_boxes[next_node]));
+ for (i = min + 1; (int)i <= max; i++) {
+ Bounds_AddBounds(&(t->tree_safety_boxes[next_node]),
+ &(t->elements[idx[i]]));
+ }
+ next_node++;
+ }
+ /* Destroy the temporary arrays */
+ FREE(stack);
+ FREE(idx);
+ }
+ /* Mark the tree "built" */
+ t->tree_built = true;
+}
+
+void KDTree_QueryBoxIntersect(TKDTree* t,
+ int* result_num, int* result_indicies,
+ TBounds* box)
+{
+ int stack_ptr, node;
+ TBounds sb;
+ int* stack;
+
+ assert(t && result_num && result_indicies && box);
+ /* Build the k-D tree if necessary */
+ if(!t->tree_built){
+ //printf("BUILDING TREE... \n");
+ //fflush(stdout);
+ KDTree_CreateTree(t);
+ }
+ /* Allocate the results array */
+ *result_num = 0;
+ /* Create the temporary stack array */
+ stack_ptr = 0;
+ stack = MALLOC(t->tree_size, int);
+
+ /* Put the root node of the tree onto the stack */
+ stack[stack_ptr++] = 0;
+ /* Search the k-D tree until the stack is empty */
+
+ while (stack_ptr) {
+ /* Pop the top entry off the stack */
+ node = stack[--stack_ptr];
+ /* Check if the query box intersects an epsilon-expanded safety box for
+ the current node. */
+ Bounds_Copy(&(t->tree_safety_boxes[node]), &sb);
+ //Bounds_AddEpsilon(&sb, ENTITY_COINCIDENCE_TOLERANCE);
+ /* If the query box doesn't intersect this node's safety box, we are done
+ visiting the node and should continue with the next node */
+ if(!Bounds_IsOverlappingBounds(&sb, box))
+ continue;
+ /* If the current node is a leaf node, add it to the collision list. If
+ the current node is an interior node, add its children to the stack. */
+ if(t->tree_link[node] <= 0) {
+ result_indicies[*result_num] = - t->tree_link[node];
+ (*result_num)++;
+ }
+ else {
+ stack[stack_ptr++] = t->tree_link[node];
+ stack[stack_ptr++] = t->tree_link[node] + 1;
+ }
+ }
+ /* Destroy the temporary stack array */
+ FREE(stack);
+}
+
+void KDTree_QueryCircleIntersect_Double(TKDTree* t,
+ int* result_num, int* result_indicies,
+ double circ_radius, int ncells,
+ double *x, double *dx, double *y, double *dy)
+{
+ assert(t && result_num && result_indicies && circ_radius);
+ /* Build the k-D tree if necessary */
+ if(!t->tree_built){
+ //printf("BUILDING TREE... \n");
+ //fflush(stdout);
+ KDTree_CreateTree(t);
+ }
+
+ int nez;
+ int *ind=(int *)malloc(ncells*sizeof(int));
+
+ TBounds box;
+ box.min.x = -circ_radius;
+ box.max.x = circ_radius;
+ box.min.y = -circ_radius;
+ box.max.y = circ_radius;
+ KDTree_QueryBoxIntersect(t, &nez, ind, &box);
+
+ //for (int ic=0; ic<nez; ic++) {
+ // printf("box is ind[%d]=%d\n",ic,ind[ic]);
+ //}
+
+ /* Allocate the results array */
+ *result_num = 0;
+
+ double rad1, rad2, rad3, rad4;
+ int ii;
+ for (int i=0; i<nez; ++i){
+ ii = ind[i];
+ rad1 = sqrt( pow(x[ii], 2.0) + pow(y[ii], 2.0) );
+ rad2 = sqrt( pow(x[ii]+dx[ii],2.0) + pow(y[ii], 2.0) );
+ rad3 = sqrt( pow(x[ii]+dx[ii],2.0) + pow(y[ii]+dy[ii],2.0) );
+ rad4 = sqrt( pow(x[ii] ,2.0) + pow(y[ii]+dy[ii],2.0) );
+
+ if ((circ_radius < rad1 && circ_radius > rad2 ) ||
+ (circ_radius > rad1 && circ_radius < rad2 ) ) {
+ result_indicies[*result_num] = ind[i];
+ (*result_num)++;
+ } else if ((circ_radius < rad2 && circ_radius > rad3 ) ||
+ (circ_radius > rad2 && circ_radius < rad3 ) ) {
+ result_indicies[*result_num] = ind[i];
+ (*result_num)++;
+ } else if ((circ_radius < rad3 && circ_radius > rad4 ) ||
+ (circ_radius > rad3 && circ_radius < rad4 ) ) {
+ result_indicies[*result_num] = ind[i];
+ (*result_num)++;
+ } else if ((circ_radius < rad4 && circ_radius > rad1 ) ||
+ (circ_radius > rad4 && circ_radius < rad1 ) ) {
+ result_indicies[*result_num] = ind[i];
+ (*result_num)++;
+ }
+ } // for
+ free(ind);
+}
+
+void KDTree_QueryCircleIntersect_Float(TKDTree* t,
+ int* result_num, int* result_indicies,
+ double circ_radius, int ncells,
+ float *x, float *dx, float *y, float *dy)
+{
+ assert(t && result_num && result_indicies && circ_radius);
+ /* Build the k-D tree if necessary */
+ if(!t->tree_built){
+ //printf("BUILDING TREE... \n");
+ //fflush(stdout);
+ KDTree_CreateTree(t);
+ }
+
+ int nez;
+ int *ind=(int *)malloc(ncells*sizeof(int));
+
+ TBounds box;
+ box.min.x = -circ_radius;
+ box.max.x = circ_radius;
+ box.min.y = -circ_radius;
+ box.max.y = circ_radius;
+ KDTree_QueryBoxIntersect(t, &nez, ind, &box);
+
+ //for (int ic=0; ic<nez; ic++) {
+ // printf("box is ind[%d]=%d\n",ic,ind[ic]);
+ //}
+
+ /* Allocate the results array */
+ *result_num = 0;
+
+ double rad1, rad2, rad3, rad4;
+ int ii;
+ for (int i=0; i<nez; ++i){
+ ii = ind[i];
+ rad1 = sqrt( pow(x[ii], 2.0) + pow(y[ii], 2.0) );
+ rad2 = sqrt( pow(x[ii]+dx[ii],2.0) + pow(y[ii], 2.0) );
+ rad3 = sqrt( pow(x[ii]+dx[ii],2.0) + pow(y[ii]+dy[ii],2.0) );
+ rad4 = sqrt( pow(x[ii] ,2.0) + pow(y[ii]+dy[ii],2.0) );
+
+ if ((circ_radius < rad1 && circ_radius > rad2 ) ||
+ (circ_radius > rad1 && circ_radius < rad2 ) ) {
+ result_indicies[*result_num] = ind[i];
+ (*result_num)++;
+ } else if ((circ_radius < rad2 && circ_radius > rad3 ) ||
+ (circ_radius > rad2 && circ_radius < rad3 ) ) {
+ result_indicies[*result_num] = ind[i];
+ (*result_num)++;
+ } else if ((circ_radius < rad3 && circ_radius > rad4 ) ||
+ (circ_radius > rad3 && circ_radius < rad4 ) ) {
+ result_indicies[*result_num] = ind[i];
+ (*result_num)++;
+ } else if ((circ_radius < rad4 && circ_radius > rad1 ) ||
+ (circ_radius > rad4 && circ_radius < rad1 ) ) {
+ result_indicies[*result_num] = ind[i];
+ (*result_num)++;
+ }
+ } // for
+ free(ind);
+}
+
+void KDTree_QueryCircleIntersectWeighted_Double(TKDTree* t,
+ int* result_num, int* result_indicies, double *weight,
+ double circ_radius, int ncells,
+ double *x, double *dx, double *y, double *dy)
+{
+ assert(t && result_num && result_indicies && circ_radius);
+ /* Build the k-D tree if necessary */
+ if(!t->tree_built){
+ //printf("BUILDING TREE... \n");
+ //fflush(stdout);
+ KDTree_CreateTree(t);
+ }
+
+ int nez;
+ int *ind=(int *)malloc(ncells*sizeof(int));
+
+ TBounds box;
+ box.min.x = -circ_radius;
+ box.max.x = circ_radius;
+ box.min.y = -circ_radius;
+ box.max.y = circ_radius;
+ KDTree_QueryBoxIntersect(t, &nez, ind, &box);
+
+ //for (int ic=0; ic<nez; ic++) {
+ // printf("box is ind[%d]=%d\n",ic,ind[ic]);
+ //}
+
+ /* Allocate the results array */
+ *result_num = 0;
+
+ double rad1, rad2, rad3, rad4;
+ int cuts_bottom, cuts_top, cuts_left, cuts_right;
+ int vertical_half, horizontal_half;
+ int ii;
+ for (int i=0; i<nez; ++i){
+ ii = ind[i];
+ rad1 = sqrt( pow(x[ii], 2.0) + pow(y[ii], 2.0) );
+ rad2 = sqrt( pow(x[ii]+dx[ii],2.0) + pow(y[ii], 2.0) );
+ rad3 = sqrt( pow(x[ii]+dx[ii],2.0) + pow(y[ii]+dy[ii],2.0) );
+ rad4 = sqrt( pow(x[ii] ,2.0) + pow(y[ii]+dy[ii],2.0) );
+
+ cuts_bottom=0;
+ cuts_top=0;
+ cuts_left=0;
+ cuts_right=0;
+ if ((circ_radius < rad1 && circ_radius > rad2 ) ||
+ (circ_radius > rad1 && circ_radius < rad2 ) ) {
+ cuts_bottom=1;
+ }
+ if ((circ_radius < rad2 && circ_radius > rad3 ) ||
+ (circ_radius > rad2 && circ_radius < rad3 ) ) {
+ cuts_right=1;
+ }
+ if ((circ_radius < rad3 && circ_radius > rad4 ) ||
+ (circ_radius > rad3 && circ_radius < rad4 ) ) {
+ cuts_top=1;
+ }
+ if ((circ_radius < rad4 && circ_radius > rad1 ) ||
+ (circ_radius > rad4 && circ_radius < rad1 ) ) {
+ cuts_left=1;
+ }
+
+ horizontal_half=0;
+ vertical_half=0;
+ if (x[ii]+0.5*dx[ii] > 0.0) horizontal_half = RIGHT_HALF;
+ if (y[ii]+0.5*dy[ii] > 0.0) vertical_half = TOP_HALF;
+
+
+ if (horizontal_half == RIGHT_HALF && vertical_half == TOP_HALF) { /* quadrant 1 */
+ weight[*result_num] = (circ_radius - rad1)/(rad3-rad1);
+ } else if (horizontal_half == LEFT_HALF && vertical_half == TOP_HALF) { /* quadrant 2 */
+ weight[*result_num] = (circ_radius - rad2)/(rad4-rad2);
+ } else if (horizontal_half == LEFT_HALF && vertical_half == BOTTOM_HALF) { /* quadrant 3 */
+ weight[*result_num] = (circ_radius - rad3)/(rad1-rad3);
+ } else if (horizontal_half == RIGHT_HALF && vertical_half == BOTTOM_HALF) { /* quadrant 4 */
+ weight[*result_num] = (circ_radius - rad4)/(rad2-rad4);
+ } else {
+ weight[*result_num] = 0.5;
+ }
+ if (cuts_bottom || cuts_top || cuts_left || cuts_right) {
+ result_indicies[*result_num] = ind[i];
+ (*result_num)++;
+ }
+
+ } // for
+ free(ind);
+}
+
+void KDTree_QueryCircleIntersectWeighted_Float(TKDTree* t,
+ int* result_num, int* result_indicies, double *weight,
+ double circ_radius, int ncells,
+ float *x, float *dx, float *y, float *dy)
+{
+ assert(t && result_num && result_indicies && circ_radius);
+ /* Build the k-D tree if necessary */
+ if(!t->tree_built){
+ //printf("BUILDING TREE... \n");
+ //fflush(stdout);
+ KDTree_CreateTree(t);
+ }
+
+ int nez;
+ int *ind=(int *)malloc(ncells*sizeof(int));
+
+ TBounds box;
+ box.min.x = -circ_radius;
+ box.max.x = circ_radius;
+ box.min.y = -circ_radius;
+ box.max.y = circ_radius;
+ KDTree_QueryBoxIntersect(t, &nez, ind, &box);
+
+ //for (int ic=0; ic<nez; ic++) {
+ // printf("box is ind[%d]=%d\n",ic,ind[ic]);
+ //}
+
+ /* Allocate the results array */
+ *result_num = 0;
+
+ double rad1, rad2, rad3, rad4;
+ int cuts_bottom, cuts_top, cuts_left, cuts_right;
+ int vertical_half, horizontal_half;
+ int ii;
+ for (int i=0; i<nez; ++i){
+ ii = ind[i];
+ rad1 = sqrt( pow(x[ii], 2.0) + pow(y[ii], 2.0) );
+ rad2 = sqrt( pow(x[ii]+dx[ii],2.0) + pow(y[ii], 2.0) );
+ rad3 = sqrt( pow(x[ii]+dx[ii],2.0) + pow(y[ii]+dy[ii],2.0) );
+ rad4 = sqrt( pow(x[ii] ,2.0) + pow(y[ii]+dy[ii],2.0) );
+
+ cuts_bottom=0;
+ cuts_top=0;
+ cuts_left=0;
+ cuts_right=0;
+ if ((circ_radius < rad1 && circ_radius > rad2 ) ||
+ (circ_radius > rad1 && circ_radius < rad2 ) ) {
+ cuts_bottom=1;
+ }
+ if ((circ_radius < rad2 && circ_radius > rad3 ) ||
+ (circ_radius > rad2 && circ_radius < rad3 ) ) {
+ cuts_right=1;
+ }
+ if ((circ_radius < rad3 && circ_radius > rad4 ) ||
+ (circ_radius > rad3 && circ_radius < rad4 ) ) {
+ cuts_top=1;
+ }
+ if ((circ_radius < rad4 && circ_radius > rad1 ) ||
+ (circ_radius > rad4 && circ_radius < rad1 ) ) {
+ cuts_left=1;
+ }
+
+ horizontal_half=0;
+ vertical_half=0;
+ if (x[ii]+0.5*dx[ii] > 0.0) horizontal_half = RIGHT_HALF;
+ if (y[ii]+0.5*dy[ii] > 0.0) vertical_half = TOP_HALF;
+
+
+ if (horizontal_half == RIGHT_HALF && vertical_half == TOP_HALF) { /* quadrant 1 */
+ weight[*result_num] = (circ_radius - rad1)/(rad3-rad1);
+ } else if (horizontal_half == LEFT_HALF && vertical_half == TOP_HALF) { /* quadrant 2 */
+ weight[*result_num] = (circ_radius - rad2)/(rad4-rad2);
+ } else if (horizontal_half == LEFT_HALF && vertical_half == BOTTOM_HALF) { /* quadrant 3 */
+ weight[*result_num] = (circ_radius - rad3)/(rad1-rad3);
+ } else if (horizontal_half == RIGHT_HALF && vertical_half == BOTTOM_HALF) { /* quadrant 4 */
+ weight[*result_num] = (circ_radius - rad4)/(rad2-rad4);
+ } else {
+ weight[*result_num] = 0.5;
+ }
+ if (cuts_bottom || cuts_top || cuts_left || cuts_right) {
+ result_indicies[*result_num] = ind[i];
+ (*result_num)++;
+ }
+
+ } // for
+ free(ind);
+}
+
+void KDTree_QueryCircleInterior_Double(TKDTree* t,
+ int* result_num, int* result_indicies,
+ double circ_radius, int ncells,
+ double *x, double *dx, double *y, double *dy)
+{
+ assert(t && result_num && result_indicies && circ_radius);
+ /* Build the k-D tree if necessary */
+ if(!t->tree_built){
+ //printf("BUILDING TREE... \n");
+ //fflush(stdout);
+ KDTree_CreateTree(t);
+ }
+
+ int nez;
+ int *ind=(int *)malloc(ncells*sizeof(int));
+
+ TBounds box;
+ box.min.x = -circ_radius;
+ box.max.x = circ_radius;
+ box.min.y = -circ_radius;
+ box.max.y = circ_radius;
+ KDTree_QueryBoxIntersect(t, &nez, ind, &box);
+
+ //for (int ic=0; ic<nez; ic++) {
+ // printf("box is ind[%d]=%d\n",ic,ind[ic]);
+ //}
+
+ /* Allocate the results array */
+ *result_num = 0;
+
+ double rad1, rad2, rad3, rad4;
+ int ii;
+ for (int i=0; i<nez; ++i){
+ ii = ind[i];
+ rad1 = sqrt( pow(x[ii], 2.0) + pow(y[ii], 2.0) );
+ rad2 = sqrt( pow(x[ii]+dx[ii],2.0) + pow(y[ii], 2.0) );
+ rad3 = sqrt( pow(x[ii]+dx[ii],2.0) + pow(y[ii]+dy[ii],2.0) );
+ rad4 = sqrt( pow(x[ii] ,2.0) + pow(y[ii]+dy[ii],2.0) );
+
+ if ((circ_radius > rad1 || circ_radius > rad2 ) ||
+ (circ_radius > rad3 || circ_radius > rad4 ) ) {
+ result_indicies[*result_num] = ind[i];
+ (*result_num)++;
+ }
+ } // for
+ free(ind);
+}
+
+void KDTree_QueryCircleInterior_Float(TKDTree* t,
+ int* result_num, int* result_indicies,
+ double circ_radius, int ncells,
+ float *x, float *dx, float *y, float *dy)
+{
+ assert(t && result_num && result_indicies && circ_radius);
+ /* Build the k-D tree if necessary */
+ if(!t->tree_built){
+ //printf("BUILDING TREE... \n");
+ //fflush(stdout);
+ KDTree_CreateTree(t);
+ }
+
+ int nez;
+ int *ind=(int *)malloc(ncells*sizeof(int));
+
+ TBounds box;
+ box.min.x = -circ_radius;
+ box.max.x = circ_radius;
+ box.min.y = -circ_radius;
+ box.max.y = circ_radius;
+ KDTree_QueryBoxIntersect(t, &nez, ind, &box);
+
+ //for (int ic=0; ic<nez; ic++) {
+ // printf("box is ind[%d]=%d\n",ic,ind[ic]);
+ //}
+
+ /* Allocate the results array */
+ *result_num = 0;
+
+ double rad1, rad2, rad3, rad4;
+ int ii;
+ for (int i=0; i<nez; ++i){
+ ii = ind[i];
+ rad1 = sqrt( pow(x[ii], 2.0) + pow(y[ii], 2.0) );
+ rad2 = sqrt( pow(x[ii]+dx[ii],2.0) + pow(y[ii], 2.0) );
+ rad3 = sqrt( pow(x[ii]+dx[ii],2.0) + pow(y[ii]+dy[ii],2.0) );
+ rad4 = sqrt( pow(x[ii] ,2.0) + pow(y[ii]+dy[ii],2.0) );
+
+ if ((circ_radius > rad1 || circ_radius > rad2 ) ||
+ (circ_radius > rad3 || circ_radius > rad4 ) ) {
+ result_indicies[*result_num] = ind[i];
+ (*result_num)++;
+ }
+ } // for
+ free(ind);
+}
+
+
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/KDTree.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/KDTree.h?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/KDTree.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/KDTree.h Sun Sep 3 20:10:18 2017
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2011-2012, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ * This research code is being developed as part of the
+ * 2011 X Division Summer Workshop for the express purpose
+ * of a collaborative code for development of ideas in
+ * the implementation of AMR codes for Exascale platforms
+ *
+ * AMR implementation of the Wave code previously developed
+ * as a demonstration code for regular grids on Exascale platforms
+ * as part of the Supercomputing Challenge and Los Alamos
+ * National Laboratory
+ *
+ * Authors: Bob Robey XCP-2 brobey at lanl.gov
+ * Neal Davis davis68 at lanl.gov, davis68 at illinois.edu
+ * David Nicholaeff dnic at lanl.gov, mtrxknight at aol.com
+ * Dennis Trujillo dptrujillo at lanl.gov, dptru10 at gmail.com
+ * Other LANL authors
+ *
+ *
+ * Implements a 2-dimensional k-D tree. One begins to use the k-D tree by
+ * adding the bounding box of geometric "elements" to the tree structure
+ * through a call to "KDTreeAddElement". Every element should be of the same
+ * type, but could be a single point, a line segment, triangles, etc. Once
+ * all the element bounding boxes have been added, the user of the structure
+ * may make queries against the tree. The actual tree is constructed lazily
+ * when an actual query occurs on the structure.
+ *
+ * This version only has one query -- intersection of a box with the elements
+ * and a set of "candidate" elements are returned. The candidates are identified
+ * by an index number (0, ...) signifying the order in which the element was
+ * added to the tree. It is up to the calling code to do additional processing
+ * based on the type of element being used to determine "real" intersections.
+ *
+ * The process of actually building the tree takes "n log n" time. Queries
+ * take "log n" time.
+ *
+ */
+
+#ifndef _KDTree_
+#define _KDTree_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "Globals.h"
+#include "Bounds.h"
+
+#define LEFT_HALF 0
+#define RIGHT_HALF 1
+#define BOTTOM_HALF 0
+#define TOP_HALF 1
+
+typedef struct {
+ TBounds extent;
+ int elements_num, elements_allocated;
+ TBounds* elements;
+ bool tree_built;
+ int tree_size;
+ TBounds* tree_safety_boxes;
+ int * tree_link;
+} TKDTree;
+
+extern void KDTree_Initialize(TKDTree *t);
+extern void KDTree_Finalize(TKDTree *t);
+extern void KDTree_Destroy(TKDTree* t);
+extern void KDTree_AddElement(TKDTree* t, TBounds* add);
+extern void KDTree_CreateTree(TKDTree* t);
+extern void KDTree_QueryBoxIntersect(TKDTree* t,
+ int* result_num, int* result_indicies,
+ TBounds* box);
+
+void KDTree_QueryCircleIntersect_Double(TKDTree* t,
+ int* result_num, int* result_indicies,
+ double radius, int ncells,
+ double *x, double *dx, double *y, double *dy);
+void KDTree_QueryCircleIntersect_Float(TKDTree* t,
+ int* result_num, int* result_indicies,
+ double radius, int ncells,
+ float *x, float *dx, float *y, float *dy);
+
+void KDTree_QueryCircleIntersectWeighted_Double(TKDTree* t,
+ int* result_num, int* result_indicies, double *weight,
+ double circ_radius, int ncells,
+ double *x, double *dx, double *y, double *dy);
+void KDTree_QueryCircleIntersectWeighted_Float(TKDTree* t,
+ int* result_num, int* result_indicies, double *weight,
+ double circ_radius, int ncells,
+ float *x, float *dx, float *y, float *dy);
+
+void KDTree_QueryCircleInterior_Double(TKDTree* t,
+ int* result_num, int* result_indicies,
+ double circ_radius, int ncells,
+ double *x, double *dx, double *y, double *dy);
+void KDTree_QueryCircleInterior_Float(TKDTree* t,
+ int* result_num, int* result_indicies,
+ double circ_radius, int ncells,
+ float *x, float *dx, float *y, float *dy);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/LICENSE
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/LICENSE?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/LICENSE (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/LICENSE Sun Sep 3 20:10:18 2017
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2011-2012, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * CLAMR -- LA-CC-11-094
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Makefile
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Makefile?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Makefile (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Makefile Sun Sep 3 20:10:18 2017
@@ -0,0 +1,5 @@
+LEVEL = ../../../..
+
+PROG = CLAMR
+RUN_OPTIONS = -n 64 -t 1000
+include $(LEVEL)/MultiSource/Makefile.multisrc
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/MallocPlus.cpp
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/MallocPlus.cpp?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/MallocPlus.cpp (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/MallocPlus.cpp Sun Sep 3 20:10:18 2017
@@ -0,0 +1,1227 @@
+/*
+ * Copyright (c) 2011-2014, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ * This research code is being developed as part of the
+ * 2011 X Division Summer Workshop for the express purpose
+ * of a collaborative code for development of ideas in
+ * the implementation of AMR codes for Exascale platforms
+ *
+ * AMR implementation of the Wave code previously developed
+ * as a demonstration code for regular grids on Exascale platforms
+ * as part of the Supercomputing Challenge and Los Alamos
+ * National Laboratory
+ *
+ * Authors: Bob Robey XCP-2 brobey at lanl.gov
+ * Neal Davis davis68 at lanl.gov, davis68 at illinois.edu
+ * David Nicholaeff dnic at lanl.gov, mtrxknight at aol.com
+ * Dennis Trujillo dptrujillo at lanl.gov, dptru10 at gmail.com
+ *
+ */
+
+// SKG TODO op realloc (similar to managed)
+
+#undef HAVE_OPENCL
+
+#include "MallocPlus.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <algorithm>
+#include <queue>
+#include <string.h>
+#ifdef HAVE_OPENCL
+#include "ezcl/ezcl.h"
+#endif
+
+#ifndef DEBUG
+#define DEBUG 0
+#endif
+#define WARNING_SUPPRESSION 0
+
+#ifdef HAVE_CL_DOUBLE
+#ifdef HAVE_OPENCL
+typedef cl_double2 cl_real2;
+#endif
+#else
+#ifdef HAVE_OPENCL
+typedef cl_float2 cl_real2;
+#endif
+#endif
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef SWAP_PTR
+#define SWAP_PTR(xnew,xold,xtmp) (xtmp=xnew, xnew=xold, xold=xtmp)
+#endif
+
+typedef unsigned int uint;
+map<void *,malloc_plus_memory_entry*>::iterator it_save, it_end;
+map<string, malloc_plus_memory_entry*, cmp_str>::iterator it_save_by_name, it_end_by_name;
+
+#if defined(HAVE_MPI)
+void
+MallocPlus::pinit(MPI_Comm smComm, std::size_t memPoolSize)
+{
+#if defined(HAVE_J7)
+ try {
+ j7 = new J7(smComm, memPoolSize);
+ }
+ catch(...) {
+ std::cerr << "*** pinit failure ***" << std::endl;
+ throw;
+ }
+#else
+ // Just to suppress compiler warnings
+ if (WARNING_SUPPRESSION) printf("DEBUG memPoolSize = %lu smComm = %p\n",memPoolSize,smComm);
+#endif
+}
+
+void
+MallocPlus::pfini(void)
+{
+#if defined(HAVE_J7)
+ try {
+ delete j7;
+ j7 = NULL;
+ }
+ catch(...) {
+ std::cerr << "*** pfini failure ***" << std::endl;
+ throw;
+ }
+#endif
+}
+#endif // if defined(HAVE_MPI)
+
+void *MallocPlus::memory_malloc(size_t nelem, size_t elsize, const char *name, int flags){
+ malloc_plus_memory_entry *memory_item = (malloc_plus_memory_entry *)malloc(sizeof(malloc_plus_memory_entry));
+
+ memory_item->mem_nelem = (size_t *)malloc(1*sizeof(size_t));
+ memory_item->mem_nelem[0] = nelem;
+ memory_item->mem_ndims = 1;
+ memory_item->mem_elsize = elsize;
+ memory_item->mem_flags = flags;
+
+ // allocate memory on the accelerator if flag is set
+ if ((flags & DEVICE_REGULAR_MEMORY) != 0){
+#ifdef HAVE_OPENCL
+ cl_context context = ezcl_get_context();
+ memory_item->mem_capacity = nelem;
+ memory_item->mem_ptr = ezcl_device_memory_malloc(context, NULL, name, nelem, elsize, CL_MEM_READ_WRITE, 0);
+#endif
+ }
+ // Managed memory allocates extra space and expands as necessary to reduce allocations
+ else if ((flags & HOST_MANAGED_MEMORY) != 0){
+ memory_item->mem_capacity = 2 * nelem;
+ memory_item->mem_ptr = malloc(2* nelem*elsize);
+ }
+#ifdef HAVE_J7
+ // experimental shared memory allocation
+ else if (flags & LOAD_BALANCE_MEMORY) {
+ memory_item->mem_capacity = nelem;
+ memory_item->mem_ptr = j7->memAlloc(nelem * elsize);
+ }
+#endif
+ // Just regular memory allocation
+ else {
+ memory_item->mem_capacity = nelem;
+ memory_item->mem_ptr = malloc(nelem*elsize);
+ }
+
+ memory_item->mem_name = strdup(name); // Mallocs memory for copy
+
+ //printf("MALLOC_PLUS_MEMORY_MALLOC: DEBUG -- malloc plus memory pointer for :%s: is %p nelements %ld elsize is %ld flags %d\n",memory_item->mem_name,memory_item->mem_ptr,memory_item->mem_nelem[0],memory_item->mem_elsize,memory_item->mem_flags);
+
+ // Insert entry into dictionary -- two versions, one by name and another by pointer address
+ memory_name_dict.insert(std::pair<string, malloc_plus_memory_entry*>(name, memory_item) );
+ memory_ptr_dict.insert(std::pair<void*, malloc_plus_memory_entry*>(memory_item->mem_ptr, memory_item) );
+
+ if (DEBUG) printf("MALLOC_PLUS_MEMORY_MALLOC: DEBUG -- malloc plus memory pointer for :%s: is %p nelements %ld elsize is %ld\n",memory_item->mem_name,memory_item->mem_ptr,memory_item->mem_nelem[0],memory_item->mem_elsize);
+
+ // return the pointer for use by the calling routine
+ return(memory_item->mem_ptr);
+}
+
+void *MallocPlus::memory_realloc(size_t nelem, void *malloc_mem_ptr){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+ void *mem_ptr=NULL;
+
+ if (it != memory_ptr_dict.end() ){
+ // "second" will be the pointer to the memory entry data structure -- the value
+ // associated with the key
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("MALLOC_PLUS_MEMORY_REALLOC: DEBUG -- reallocated memory pointer %p\n",memory_item->mem_ptr);
+
+ // memory pointer will probably change, so delete the dictionary entry
+ // named dictionary entry does not need to change; the pointer in the data structure
+ // will just be updated, but the pointer to the memory entry data structure
+ // will be the same
+ memory_ptr_dict.erase(it);
+
+ if (memory_item->mem_flags & HOST_MANAGED_MEMORY){
+ // Check to see if memory needs to be expanded
+ if (nelem > memory_item->mem_capacity) {
+ // Need to realloc memory. Allocate extra for growth of array.
+ mem_ptr=realloc(memory_item->mem_ptr, 2*nelem*memory_item->mem_elsize);
+ memory_item->mem_capacity = 2*nelem;
+ memory_item->mem_nelem[0] = nelem;
+ memory_item->mem_ptr = mem_ptr;
+ } else {
+ // Just move size to use more of memory buffer
+ memory_item->mem_nelem[0] = nelem;
+ }
+ }
+#ifdef HAVE_J7
+ else if (memory_item->mem_flags & LOAD_BALANCE_MEMORY) {
+ mem_ptr = j7->memRealloc(memory_item->mem_ptr, nelem * memory_item->mem_elsize);
+ memory_item->mem_capacity = nelem;
+ memory_item->mem_nelem[0] = nelem;
+ memory_item->mem_ptr = mem_ptr;
+ }
+#endif
+ else {
+ mem_ptr=realloc(memory_item->mem_ptr, nelem*memory_item->mem_elsize);
+ memory_item->mem_capacity = nelem;
+ memory_item->mem_nelem[0] = nelem;
+ memory_item->mem_ptr = mem_ptr;
+ }
+
+ // Put the pointer entry back into the dictionary
+ memory_ptr_dict.insert(std::pair<void*, malloc_plus_memory_entry*>(memory_item->mem_ptr, memory_item) );
+ } else {
+ if (DEBUG) printf("Warning -- memory pointer %p not found\n",malloc_mem_ptr);
+ }
+
+ return(mem_ptr);
+}
+
+void *MallocPlus::memory_realloc(size_t nelem, const char *name){
+ map <string, malloc_plus_memory_entry*>::iterator it = memory_name_dict.find(name);
+ void *mem_ptr=NULL;
+
+ if (it != memory_name_dict.end() ){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("MALLOC_PLUS_MEMORY_REALLOC: DEBUG -- "
+ "reallocated memory pointer %p\n",memory_item->mem_ptr);
+
+ // Need to get the iterator for the pointer entry; the one above is for the name entry
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(memory_item->mem_ptr);
+ memory_ptr_dict.erase(it);
+
+ if (memory_item->mem_flags & HOST_MANAGED_MEMORY) {
+ // Check to see if memory needs to be expanded
+ if (nelem > memory_item->mem_capacity) {
+ // Need to realloc memory. Allocate extra for growth of array.
+ mem_ptr=realloc(memory_item->mem_ptr, 2*nelem*memory_item->mem_elsize);
+ memory_item->mem_capacity = 2*nelem;
+ memory_item->mem_nelem[0] = nelem;
+ memory_item->mem_ptr = mem_ptr;
+ } else {
+ // Just move size to use more of memory buffer
+ memory_item->mem_nelem[0] = nelem;
+ }
+ }
+#ifdef HAVE_J7
+ else if (memory_item->mem_flags & LOAD_BALANCE_MEMORY) {
+ mem_ptr = j7->memRealloc(memory_item->mem_ptr, nelem * memory_item->mem_elsize);
+ memory_item->mem_capacity = nelem;
+ memory_item->mem_nelem[0] = nelem;
+ memory_item->mem_ptr = mem_ptr;
+ }
+#endif
+ else {
+ //memory_name_dict.erase(it);
+ mem_ptr=realloc(memory_item->mem_ptr, nelem*memory_item->mem_elsize);
+ memory_item->mem_capacity = nelem;
+ memory_item->mem_nelem[0] = nelem;
+ memory_item->mem_ptr = mem_ptr;
+ //memory_name_dict.insert(std::pair<string, malloc_plus_memory_entry*>(name, memory_item) );
+ }
+
+ memory_ptr_dict.insert(std::pair<void*, malloc_plus_memory_entry*>(memory_item->mem_ptr, memory_item) );
+ } else {
+ if (DEBUG) printf("Warning -- memory named %s not found\n",name);
+ }
+
+ return(mem_ptr);
+}
+
+void *MallocPlus::memory_request(size_t new_capacity, void *malloc_mem_ptr){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+ void *mem_ptr=NULL;
+
+ if (it != memory_ptr_dict.end() ){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("MALLOC_PLUS_MEMORY_REQUEST: DEBUG -- reallocated memory pointer %p\n",memory_item->mem_ptr);
+ memory_ptr_dict.erase(it);
+ mem_ptr=realloc(memory_item->mem_ptr, new_capacity*memory_item->mem_elsize);
+ memory_item->mem_capacity = new_capacity;
+ memory_item->mem_ptr = mem_ptr;
+ memory_ptr_dict.insert(std::pair<void*, malloc_plus_memory_entry*>(mem_ptr, memory_item) );
+ } else {
+ if (DEBUG) printf("Warning -- memory pointer %p not found\n",malloc_mem_ptr);
+ }
+
+ return(mem_ptr);
+}
+
+// Increases the capacity of the allocated memory, primarily for the managed memory functionality
+void *MallocPlus::memory_request(size_t new_capacity, const char *name){
+ map <string, malloc_plus_memory_entry*>::iterator it = memory_name_dict.find(name);
+ void *mem_ptr=NULL;
+
+ if (it != memory_name_dict.end() ){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("MALLOC_PLUS_MEMORY_REQUEST: DEBUG -- reallocated memory pointer %p\n",memory_item->mem_ptr);
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(memory_item->mem_ptr);
+ memory_ptr_dict.erase(it);
+ mem_ptr=realloc(memory_item->mem_ptr, new_capacity*memory_item->mem_elsize);
+ memory_item->mem_capacity = new_capacity;
+ memory_item->mem_ptr = mem_ptr;
+ memory_ptr_dict.insert(std::pair<void*, malloc_plus_memory_entry*>(mem_ptr, memory_item) );
+ } else {
+ if (DEBUG) printf("Warning -- memory named %s not found\n",name);
+ }
+
+ return(mem_ptr);
+}
+
+void MallocPlus::memory_realloc_all(size_t nelem){
+ // Need a copy of the dictionary since we will be modifying while being used
+ map <void *, malloc_plus_memory_entry*> memory_ptr_dict_old = memory_ptr_dict;
+
+ // Need iterators to both new and old; new will be modified during the loop
+ map<void *, malloc_plus_memory_entry*>::iterator it_old;
+ map<void *, malloc_plus_memory_entry*>::iterator it_new;
+ void *mem_ptr=NULL;
+
+ for ( it_old=memory_ptr_dict_old.begin(); it_old != memory_ptr_dict_old.end(); it_old++){
+ // Get the memory entry for the old dictionary
+ malloc_plus_memory_entry *memory_item = it_old->second;
+
+ // Get the iterator to the new dictionary by memory pointer and delete it
+ // since it will probably change
+ // The dictionary by name does not need to be updated
+ it_new = memory_ptr_dict.find(memory_item->mem_ptr);
+ memory_ptr_dict.erase(it_new);
+
+ if (memory_item->mem_flags & HOST_MANAGED_MEMORY) {
+ if (nelem > memory_item->mem_capacity) {
+ mem_ptr=realloc(memory_item->mem_ptr, nelem*memory_item->mem_elsize);
+ if (DEBUG) printf("MALLOC_PLUS_MEMORY_REALLOC_ALL: DEBUG -- reallocated memory pointer %p new pointer %p\n",memory_item->mem_ptr,mem_ptr);
+ memory_item->mem_capacity = nelem;
+ memory_item->mem_nelem[0] = nelem;
+ memory_item->mem_ptr = mem_ptr;
+ } else {
+ memory_item->mem_nelem[0] = nelem;
+ }
+ }
+#ifdef HAVE_J7
+ else if (it->mem_flags & LOAD_BALANCE_MEMORY) {
+ mem_ptr = j7->memRealloc(memory_item->mem_ptr, nelem * memory_item->mem_elsize);
+ memory_item->mem_capacity = nelem;
+ memory_item->mem_nelem[0] = nelem;
+ memory_item->mem_ptr = mem_ptr;
+ }
+#endif
+ else {
+ mem_ptr=realloc(memory_item->mem_ptr, nelem*memory_item->mem_elsize);
+ if (DEBUG) printf("MALLOC_PLUS_MEMORY_REALLOC_ALL: DEBUG -- reallocated memory pointer %p new pointer %p\n",memory_item->mem_ptr,mem_ptr);
+ memory_item->mem_capacity = nelem;
+ memory_item->mem_nelem[0] = nelem;
+ memory_item->mem_ptr = mem_ptr;
+ }
+
+ //Insert the entry back into the dictionary
+ memory_ptr_dict.insert(std::pair<void*, malloc_plus_memory_entry*>(mem_ptr, memory_item) );
+ }
+}
+
+void MallocPlus::memory_request_all(size_t new_capacity){
+ map <void *, malloc_plus_memory_entry*> memory_ptr_dict_old = memory_ptr_dict;
+
+ map<void *, malloc_plus_memory_entry*>::iterator it_old;
+ map<void *, malloc_plus_memory_entry*>::iterator it_new;
+
+ for ( it_old=memory_ptr_dict_old.begin(); it_old != memory_ptr_dict_old.end(); it_old++){
+ malloc_plus_memory_entry *memory_item = it_old->second;
+
+ it_new = memory_ptr_dict.find(memory_item->mem_ptr);
+ memory_ptr_dict.erase(it_new);
+
+ void *mem_ptr=realloc(memory_item->mem_ptr, new_capacity*memory_item->mem_elsize);
+ if (DEBUG) printf("MALLOC_PLUS_MEMORY_REQUEST_ALL: DEBUG -- reallocated memory pointer %p new pointer %p\n",memory_item->mem_ptr,mem_ptr);
+ memory_item->mem_capacity = new_capacity;
+ memory_item->mem_ptr = mem_ptr;
+
+ memory_ptr_dict.insert(std::pair<void*, malloc_plus_memory_entry*>(mem_ptr, memory_item) );
+ }
+}
+
+// This routine is for memory allocated by the host program and added to the database
+void *MallocPlus::memory_add(void *malloc_mem_ptr, size_t nelem, size_t elsize, const char *name, int flags){
+ malloc_plus_memory_entry *memory_item = (malloc_plus_memory_entry *)malloc(sizeof(malloc_plus_memory_entry));
+
+ memory_item->mem_nelem = (size_t *)malloc(1*sizeof(size_t));
+ memory_item->mem_nelem[0] = nelem;
+ memory_item->mem_ndims = 1;
+ memory_item->mem_capacity = nelem;
+ memory_item->mem_elsize = elsize;
+ memory_item->mem_flags = flags;
+ memory_item->mem_ptr = malloc_mem_ptr;
+ memory_item->mem_name = strdup(name); // mallocs memory
+ memory_ptr_dict.insert(std::pair<void *, malloc_plus_memory_entry*>(malloc_mem_ptr, memory_item) );
+ memory_name_dict.insert(std::pair<string, malloc_plus_memory_entry*>(name, memory_item) );
+ if (DEBUG) printf("MALLOC_PLUS_MEMORY_ADD: DEBUG -- added memory pointer for %s is %p\n",name,malloc_mem_ptr);
+
+ return(malloc_mem_ptr);
+}
+
+// This routine is for memory allocated by the host program and added to the database
+void *MallocPlus::memory_add(void *malloc_mem_ptr, int ndim, size_t *nelem, size_t elsize, const char *name, int flags){
+ malloc_plus_memory_entry *memory_item = (malloc_plus_memory_entry *)malloc(sizeof(malloc_plus_memory_entry));
+
+ memory_item->mem_nelem = (size_t *)malloc(ndim*sizeof(size_t));
+ for (int i=0; i<ndim; i++){
+ memory_item->mem_nelem[i] = nelem[i];
+ }
+ memory_item->mem_ndims = ndim;
+ memory_item->mem_capacity = 0;
+ memory_item->mem_elsize = elsize;
+ memory_item->mem_flags = flags;
+ memory_item->mem_ptr = malloc_mem_ptr;
+ memory_item->mem_name = strdup(name); // mallocs memory
+ memory_ptr_dict.insert(std::pair<void *, malloc_plus_memory_entry*>(malloc_mem_ptr, memory_item) );
+ memory_name_dict.insert(std::pair<string, malloc_plus_memory_entry*>(name, memory_item) );
+ if (DEBUG) printf("MALLOC_PLUS_MEMORY_ADD: DEBUG -- added memory pointer for %s is %p\n",name,malloc_mem_ptr);
+
+ return(malloc_mem_ptr);
+}
+
+double *MallocPlus::memory_reorder(double *malloc_mem_ptr, int *iorder){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+
+ if (it != memory_ptr_dict.end() ){
+ malloc_plus_memory_entry *memory_item = it->second;
+ double *ptr;
+
+ memory_ptr_dict.erase(it);
+
+ if (DEBUG) printf("Found memory item ptr %p name %s\n",memory_item->mem_ptr,memory_item->mem_name);
+ double *tmp = (double *)malloc(memory_item->mem_nelem[0]*memory_item->mem_elsize);
+#ifdef _OPENMP
+#pragma omp parallel for
+#endif
+ for (uint ic = 0; ic < memory_item->mem_nelem[0]; ic++){
+ tmp[ic] = malloc_mem_ptr[iorder[ic]];
+ }
+ SWAP_PTR(malloc_mem_ptr, tmp, ptr);
+ free(tmp);
+ memory_item->mem_ptr = malloc_mem_ptr;
+
+ memory_ptr_dict.insert(std::pair<void *, malloc_plus_memory_entry*>(malloc_mem_ptr, memory_item) );
+ } else {
+ if (DEBUG) printf("Warning -- memory pointer %p not found\n",malloc_mem_ptr);
+ }
+
+ return(malloc_mem_ptr);
+}
+
+float *MallocPlus::memory_reorder(float *malloc_mem_ptr, int *iorder){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+
+ if (it != memory_ptr_dict.end() ){
+ malloc_plus_memory_entry *memory_item = it->second;
+ float *ptr;
+
+ memory_ptr_dict.erase(it);
+
+ if (DEBUG) printf("Found memory item ptr %p name %s\n",memory_item->mem_ptr,memory_item->mem_name);
+ float *tmp = (float *)malloc(memory_item->mem_nelem[0]*memory_item->mem_elsize);
+#ifdef _OPENMP
+#pragma omp parallel for
+#endif
+ for (uint ic = 0; ic < memory_item->mem_nelem[0]; ic++){
+ tmp[ic] = malloc_mem_ptr[iorder[ic]];
+ }
+ SWAP_PTR(malloc_mem_ptr, tmp, ptr);
+ free(tmp);
+ memory_item->mem_ptr = malloc_mem_ptr;
+
+ memory_ptr_dict.insert(std::pair<void*, malloc_plus_memory_entry*>(malloc_mem_ptr, memory_item) );
+ } else {
+ if (DEBUG) printf("Warning -- memory pointer %p not found\n",malloc_mem_ptr);
+ }
+
+ return(malloc_mem_ptr);
+}
+
+int *MallocPlus::memory_reorder(int *malloc_mem_ptr, int *iorder){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+
+ if (it != memory_ptr_dict.end() ){
+ malloc_plus_memory_entry *memory_item = it->second;
+ int *ptr;
+
+ memory_ptr_dict.erase(it);
+
+ if (DEBUG) printf("Found memory item ptr %p name %s\n",memory_item->mem_ptr,memory_item->mem_name);
+ int *tmp = (int *)malloc(memory_item->mem_nelem[0]*memory_item->mem_elsize);
+#ifdef _OPENMP
+#pragma omp parallel for
+#endif
+ for (uint ic = 0; ic < memory_item->mem_nelem[0]; ic++){
+ tmp[ic] = malloc_mem_ptr[iorder[ic]];
+ }
+ SWAP_PTR(malloc_mem_ptr, tmp, ptr);
+ free(tmp);
+ memory_item->mem_ptr = malloc_mem_ptr;
+
+ memory_ptr_dict.insert(std::pair<void*, malloc_plus_memory_entry*>(malloc_mem_ptr, memory_item) );
+ } else {
+ if (DEBUG) printf("Warning -- memory pointer %p not found\n",malloc_mem_ptr);
+ }
+
+ return(malloc_mem_ptr);
+}
+
+int *MallocPlus::memory_reorder_indexarray(int *malloc_mem_ptr, int *iorder, int *inv_iorder){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+
+ if (it != memory_ptr_dict.end() ){
+ malloc_plus_memory_entry *memory_item = it->second;
+ int *ptr;
+
+ if (DEBUG) printf("Found memory_item ptr %p name %s\n",memory_item->mem_ptr,memory_item->mem_name);
+ memory_ptr_dict.erase(it);
+ int *tmp = (int *)malloc(memory_item->mem_nelem[0]*memory_item->mem_elsize);
+ for (uint ic = 0; ic < memory_item->mem_nelem[0]; ic++){
+ tmp[ic] = inv_iorder[malloc_mem_ptr[iorder[ic]]];
+ }
+ SWAP_PTR(malloc_mem_ptr, tmp, ptr);
+ free(tmp);
+ memory_item->mem_ptr = malloc_mem_ptr;
+ memory_ptr_dict.insert(std::pair<void*, malloc_plus_memory_entry*>(malloc_mem_ptr, memory_item) );
+ } else {
+ if (DEBUG) printf("Warning -- memory pointer %p not found\n",malloc_mem_ptr);
+ }
+
+ return(malloc_mem_ptr);
+}
+
+void MallocPlus::memory_reorder_all(int *iorder){
+ map <void *, malloc_plus_memory_entry*> memory_ptr_dict_old = memory_ptr_dict;
+ map <void *, malloc_plus_memory_entry*>::iterator it_old;
+ vector<int> inv_iorder;
+
+ for ( it_old=memory_ptr_dict_old.begin(); it_old != memory_ptr_dict_old.end(); it_old++){
+ malloc_plus_memory_entry *memory_item_old = it_old->second;
+
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(memory_item_old->mem_ptr);
+ malloc_plus_memory_entry *memory_item = it_old->second;
+ memory_ptr_dict.erase(it);
+
+ if (memory_item_old->mem_flags & 0x100) {
+ if (inv_iorder.size() < memory_item_old->mem_nelem[0]) {
+ inv_iorder.resize(memory_item_old->mem_nelem[0]);
+ for (int ic = 0; ic < (int)memory_item_old->mem_nelem[0]; ic++){
+ inv_iorder[iorder[ic]] = ic;
+ }
+ }
+ int *ptr;
+ int *malloc_mem_ptr = (int *)memory_item_old->mem_ptr;
+ int *tmp = (int *)malloc(memory_item_old->mem_nelem[0]*memory_item_old->mem_elsize);
+ for (uint ic = 0; ic < memory_item_old->mem_nelem[0]; ic++){
+ tmp[ic] = inv_iorder[malloc_mem_ptr[iorder[ic]]];
+ }
+ memory_replace(malloc_mem_ptr, tmp);
+ SWAP_PTR(malloc_mem_ptr, tmp, ptr);
+ free(tmp);
+ memory_item->mem_ptr = malloc_mem_ptr;
+ memory_ptr_dict.insert(std::pair<void*, malloc_plus_memory_entry*>(malloc_mem_ptr, memory_item) );
+ } else if (memory_item_old->mem_elsize == 8){
+ double *ptr;
+ double *malloc_mem_ptr = (double *)memory_item_old->mem_ptr;
+ double *tmp = (double *)malloc(memory_item_old->mem_nelem[0]*memory_item_old->mem_elsize);
+
+ for (uint ic = 0; ic < memory_item_old->mem_nelem[0]; ic++){
+ tmp[ic] = malloc_mem_ptr[iorder[ic]];
+ }
+
+ SWAP_PTR(malloc_mem_ptr, tmp, ptr);
+ free(tmp);
+ memory_item->mem_ptr = malloc_mem_ptr;
+ memory_ptr_dict.insert(std::pair<void*, malloc_plus_memory_entry*>(malloc_mem_ptr, memory_item) );
+ } else {
+ float *ptr;
+ float *malloc_mem_ptr = (float *)memory_item_old->mem_ptr;
+ float *tmp = (float *)malloc(memory_item_old->mem_nelem[0]*memory_item_old->mem_elsize);
+ for (uint ic = 0; ic < memory_item_old->mem_nelem[0]; ic++){
+ tmp[ic] = malloc_mem_ptr[iorder[ic]];
+ }
+ memory_replace(malloc_mem_ptr, tmp);
+ SWAP_PTR(malloc_mem_ptr, tmp, ptr);
+ free(tmp);
+ memory_item->mem_ptr = malloc_mem_ptr;
+ memory_ptr_dict.insert(std::pair<void*, malloc_plus_memory_entry*>(malloc_mem_ptr, memory_item) );
+ }
+
+ }
+
+ inv_iorder.clear();
+}
+
+void MallocPlus::memory_report(void){
+ map<void *, malloc_plus_memory_entry*>::iterator it_ptr;
+
+ for ( it_ptr=memory_ptr_dict.begin(); it_ptr != memory_ptr_dict.end(); it_ptr++){
+ malloc_plus_memory_entry *memory_item = it_ptr->second;
+
+ printf("MallocPlus ptr %p: name %10s ptr %p dims %lu nelem (",
+ it_ptr->first,memory_item->mem_name,memory_item->mem_ptr,memory_item->mem_ndims);
+
+ char nelemstring[80];
+ char *str_ptr = nelemstring;
+ str_ptr += sprintf(str_ptr,"%lu", memory_item->mem_nelem[0]);
+ for (uint i = 1; i < memory_item->mem_ndims; i++){
+ str_ptr += sprintf(str_ptr,", %lu", memory_item->mem_nelem[i]);
+ }
+ printf("%12s",nelemstring);
+
+ printf(") elsize %lu flags %d capacity %lu\n",
+ memory_item->mem_elsize,memory_item->mem_flags,memory_item->mem_capacity);
+ }
+
+ map<string, malloc_plus_memory_entry*>::iterator it_name;
+
+ for ( it_name=memory_name_dict.begin(); it_name != memory_name_dict.end(); it_name++){
+ malloc_plus_memory_entry *memory_item = it_name->second;
+
+ printf("MallocPlus name %14s: name %10s ptr %p dims %lu nelem (",
+ it_name->first.c_str(),memory_item->mem_name,memory_item->mem_ptr,memory_item->mem_ndims);
+
+ char nelemstring[80];
+ char *str_ptr = nelemstring;
+ str_ptr += sprintf(str_ptr,"%lu", memory_item->mem_nelem[0]);
+ for (uint i = 1; i < memory_item->mem_ndims; i++){
+ str_ptr += sprintf(str_ptr,", %lu", memory_item->mem_nelem[i]);
+ }
+ printf("%12s",nelemstring);
+
+ printf(") elsize %lu flags %d capacity %lu\n",
+ memory_item->mem_elsize,memory_item->mem_flags,memory_item->mem_capacity);
+ }
+}
+
+void *MallocPlus::memory_delete(void *malloc_mem_ptr){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+
+ if (it != memory_ptr_dict.end()){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("MALLOC_PLUS_MEMORY_REMOVE: DEBUG -- removed memory pointer %p\n",memory_item->mem_ptr);
+
+ if ((memory_item->mem_flags & DEVICE_REGULAR_MEMORY) != 0){
+#ifdef HAVE_OPENCL
+ //printf("MALLOC_PLUS_MEMORY_REMOVE: DEBUG -- removed memory pointer %p\n",memory_item->mem_ptr);
+ ezcl_device_memory_delete(memory_item->mem_ptr);
+#endif
+ }
+#ifdef HAVE_J7
+ else if (memory_item->mem_flags & LOAD_BALANCE_MEMORY) {
+ j7->memFree(memory_item->mem_ptr);
+ }
+#endif
+ else {
+ free(memory_item->mem_ptr);
+ }
+
+ memory_ptr_dict.erase(it);
+ // Need to delete the entry in the name dictionary. This is done in a separate scope
+ // so the iterator "it" is isolated for this use
+ {
+ map <string, malloc_plus_memory_entry*>::iterator it = memory_name_dict.find(memory_item->mem_name);
+ memory_name_dict.erase(it);
+ }
+
+ free(memory_item->mem_nelem);
+ free(memory_item->mem_name);
+ free(memory_item);
+ } else {
+ if (DEBUG) printf("Warning -- memory pointer %p not found\n",malloc_mem_ptr);
+ }
+
+ return(NULL);
+}
+
+void *MallocPlus::memory_delete(const char *name){
+ map <string, malloc_plus_memory_entry*>::iterator it = memory_name_dict.find(name);
+
+ if (it != memory_name_dict.end()){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("MALLOC_PLUS_MEMORY_REMOVE: DEBUG -- removed memory pointer %p\n",memory_item->mem_ptr);
+ if ((memory_item->mem_flags & DEVICE_REGULAR_MEMORY) != 0){
+#ifdef HAVE_OPENCL
+ ezcl_device_memory_delete(memory_item->mem_ptr);
+#endif
+ }
+#ifdef HAVE_J7
+ else if (memory_item->mem_flags & LOAD_BALANCE_MEMORY) {
+ j7->memFree(memory_item->mem_ptr);
+ }
+#endif
+ else {
+ free(memory_item->mem_ptr);
+ }
+
+ memory_name_dict.erase(it);
+ {
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(memory_item->mem_ptr);
+ memory_ptr_dict.erase(it);
+ }
+
+ free(memory_item->mem_nelem);
+ free(memory_item->mem_name);
+ free(memory_item);
+ } else {
+ if (DEBUG) printf("Warning -- memory named %s not found\n",name);
+ }
+
+ return(NULL);
+}
+
+void MallocPlus::memory_delete_all(void){
+ map <void *, malloc_plus_memory_entry*> memory_ptr_dict_old = memory_ptr_dict;
+ map <void *, malloc_plus_memory_entry*>::iterator it;
+
+ for ( it=memory_ptr_dict_old.begin(); it != memory_ptr_dict_old.end(); it++){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("MALLOC_PLUS_MEMORY_REMOVE: DEBUG -- removed memory pointer %p name %s\n",memory_item->mem_ptr,memory_item->mem_name);
+
+ if ((memory_item->mem_flags & DEVICE_REGULAR_MEMORY) != 0){
+#ifdef HAVE_OPENCL
+ ezcl_device_memory_delete(memory_item->mem_ptr);
+#endif
+ } else {
+ free(memory_item->mem_ptr);
+ }
+
+ free(memory_item->mem_nelem);
+ free(memory_item->mem_name);
+ free(memory_item);
+ }
+
+ memory_ptr_dict.clear();
+ memory_name_dict.clear();
+}
+
+// For memory that was allocated by the host and added to the database with the
+// memory_add function. This is the corresponding routine to delete the dictionary entry.
+// The memory itself is not freed.
+void MallocPlus::memory_remove(void *malloc_mem_ptr){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+
+ if (it != memory_ptr_dict.end()){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("MALLOC_PLUS_MEMORY_REMOVE: DEBUG -- removed memory pointer %p\n",memory_item->mem_ptr);
+ memory_ptr_dict.erase(it);
+ {
+ map <string, malloc_plus_memory_entry*>::iterator it = memory_name_dict.find(memory_item->mem_name);
+ memory_name_dict.erase(it);
+ }
+ free(memory_item->mem_nelem);
+ free(memory_item->mem_name);
+ free(memory_item);
+ } else {
+ if (DEBUG) printf("Warning -- memory pointer %p not found\n",malloc_mem_ptr);
+ }
+}
+
+void MallocPlus::memory_remove(const char *name){
+ map <string, malloc_plus_memory_entry*>::iterator it = memory_name_dict.find(name);
+
+ if (it != memory_name_dict.end()){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("MALLOC_PLUS_MEMORY_REMOVE: DEBUG -- removed memory pointer %p\n",memory_item->mem_ptr);
+ memory_name_dict.erase(it);
+ {
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(memory_item->mem_ptr);
+ memory_ptr_dict.erase(it);
+ }
+ free(memory_item->mem_nelem);
+ free(memory_item->mem_name);
+ free(memory_item);
+ } else {
+ if (DEBUG) printf("Warning -- memory named %s not found\n",name);
+ }
+}
+
+void *MallocPlus::memory_begin(void){
+ it_save = memory_ptr_dict.begin();
+ malloc_plus_memory_entry *memory_item = it_save->second;
+ return(memory_item->mem_ptr);
+}
+
+void *MallocPlus::memory_next(void){
+ map <void *, malloc_plus_memory_entry*>::iterator it;
+
+ it_save++;
+ it = it_save;
+
+ if (it != memory_ptr_dict.end()){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("Found memory item ptr %p name %s\n",memory_item->mem_ptr,memory_item->mem_name);
+ return(memory_item->mem_ptr);
+ } else {
+ if (DEBUG) printf("Warning -- memory not found\n");
+ return(NULL);
+ }
+}
+
+void *MallocPlus::memory_by_name_begin(void){
+ it_save_by_name = memory_name_dict.begin();
+ malloc_plus_memory_entry *memory_item = it_save->second;
+ return(memory_item->mem_ptr);
+}
+
+void *MallocPlus::memory_by_name_next(void){
+ map<string, malloc_plus_memory_entry*, cmp_str>::iterator it_by_name;
+
+ it_save_by_name++;
+ it_by_name = it_save_by_name;
+
+ if (it_by_name != memory_name_dict.end()){
+ malloc_plus_memory_entry *memory_item = it_by_name->second;
+
+ if (DEBUG) printf("Found memory item ptr %p name %s\n",memory_item->mem_ptr,memory_item->mem_name);
+ return(memory_item->mem_ptr);
+ } else {
+ if (DEBUG) printf("Warning -- memory not found\n");
+ return(NULL);
+ }
+}
+
+malloc_plus_memory_entry* MallocPlus::memory_entry_begin(void){
+ it_save = memory_ptr_dict.begin();
+ malloc_plus_memory_entry *memory_item = it_save->second;
+ return(memory_item);
+}
+
+malloc_plus_memory_entry* MallocPlus::memory_entry_next(void){
+ it_save++;
+ if (it_save == memory_ptr_dict.end()) return(NULL);
+ malloc_plus_memory_entry *memory_item = it_save->second;
+ if (DEBUG) printf("Found memory item ptr %p name %s\n",memory_item->mem_ptr,memory_item->mem_name);
+ return(memory_item);
+}
+
+malloc_plus_memory_entry* MallocPlus::memory_entry_end(void){
+ return(NULL);
+}
+
+malloc_plus_memory_entry* MallocPlus::memory_entry_by_name_begin(void){
+ it_save_by_name = memory_name_dict.begin();
+ malloc_plus_memory_entry *memory_item = it_save_by_name->second;
+ return(memory_item);
+}
+
+malloc_plus_memory_entry* MallocPlus::memory_entry_by_name_next(void){
+ it_save_by_name++;
+ if (it_save_by_name == memory_name_dict.end()) return(NULL);
+ malloc_plus_memory_entry *memory_item = it_save_by_name->second;
+ if (DEBUG) printf("Found memory item ptr %p name %s\n",memory_item->mem_ptr,memory_item->mem_name);
+ return(memory_item);
+}
+
+malloc_plus_memory_entry* MallocPlus::memory_entry_by_name_end(void){
+ return(NULL);
+}
+
+size_t MallocPlus::get_memory_size(void *malloc_mem_ptr){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+
+ if (it != memory_ptr_dict.end()){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("Found memory item ptr %p name %s\n",memory_item->mem_ptr,memory_item->mem_name);
+ return(memory_item->mem_nelem[0]);
+ } else {
+ if (DEBUG) printf("Warning -- memory not found\n");
+ }
+ return(0);
+}
+
+int MallocPlus::get_memory_elemsize(void *malloc_mem_ptr){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+
+ if (it != memory_ptr_dict.end()){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("Found memory item ptr %p name %s\n",memory_item->mem_ptr,memory_item->mem_name);
+ return(memory_item->mem_elsize);
+ } else {
+ if (DEBUG) printf("Warning -- memory not found\n");
+ }
+ return(0);
+}
+
+int MallocPlus::get_memory_flags(void *malloc_mem_ptr){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+
+ if (it != memory_ptr_dict.end()){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("Found memory item ptr %p name %s attribute %d\n",memory_item->mem_ptr,memory_item->mem_name,memory_item->mem_flags);
+ return(memory_item->mem_flags);
+ } else {
+ if (DEBUG) printf("Warning -- memory not found\n");
+ }
+ return(0);
+}
+
+size_t MallocPlus::get_memory_capacity(void *malloc_mem_ptr){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+
+ if (it != memory_ptr_dict.end()){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("Found memory item ptr %p name %s\n",memory_item->mem_ptr,memory_item->mem_name);
+ return(memory_item->mem_capacity);
+ } else {
+ if (DEBUG) printf("Warning -- memory not found\n");
+ }
+ return(0);
+}
+
+const char * MallocPlus::get_memory_name(void *malloc_mem_ptr){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+
+ if (it != memory_ptr_dict.end()){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("Found memory item ptr %p name %s\n",memory_item->mem_ptr,memory_item->mem_name);
+ return(memory_item->mem_name);
+ } else {
+ if (DEBUG) printf("Warning -- memory not found\n");
+ }
+ return(NULL);
+}
+
+void *MallocPlus::memory_replace(void *malloc_mem_ptr_old, void * const malloc_mem_ptr_new){
+ map <void *, malloc_plus_memory_entry*>::iterator it_old = memory_ptr_dict.find(malloc_mem_ptr_old);
+ map <void *, malloc_plus_memory_entry*>::iterator it_new = memory_ptr_dict.find(malloc_mem_ptr_new);
+
+ if (it_old != memory_ptr_dict.end() && it_new != memory_ptr_dict.end() ){
+ malloc_plus_memory_entry *memory_item_old = it_old->second;
+ malloc_plus_memory_entry *memory_item_new = it_new->second;
+
+ // erase the entries in the pointer dictionary
+ memory_ptr_dict.erase(it_new);
+ memory_ptr_dict.erase(it_old);
+ // get the iterators for the named dictionary
+ map <string, malloc_plus_memory_entry*>::iterator it_old = memory_name_dict.find(memory_item_old->mem_name);
+ map <string, malloc_plus_memory_entry*>::iterator it_new = memory_name_dict.find(memory_item_new->mem_name);
+ memory_name_dict.erase(it_new);
+ memory_name_dict.erase(it_old);
+
+ if (DEBUG) printf("Found memory item ptr_old %p name %s ptr_new %p name %s\n",memory_item_old->mem_ptr,memory_item_old->mem_name,memory_item_new->mem_ptr,memory_item_new->mem_name);
+
+ if ((memory_item_old->mem_flags & DEVICE_REGULAR_MEMORY) != 0){
+#ifdef HAVE_OPENCL
+ if (DEBUG) printf("Deleting device memory name %s pointer %p\n",memory_item_old->mem_name,memory_item_old->mem_ptr);
+ ezcl_device_memory_replace(&memory_item_old->mem_ptr, &memory_item_new->mem_ptr);
+#endif
+ }
+#ifdef HAVE_J7
+ else if (memory_item->mem_flags & LOAD_BALANCE_MEMORY) {
+ j7->memFree(memory_item_old->mem_ptr);
+ memory_item_old->mem_ptr = memory_item_new->mem_ptr;
+ }
+#endif
+ else {
+ free(memory_item_old->mem_ptr);
+ memory_item_old->mem_ptr = memory_item_new->mem_ptr;
+ }
+
+ memory_item_old->mem_nelem[0] = memory_item_new->mem_nelem[0];
+ memory_item_old->mem_capacity = memory_item_new->mem_capacity;
+ memory_item_old->mem_elsize = memory_item_new->mem_elsize;
+ memory_item_old->mem_flags = memory_item_new->mem_flags;
+ malloc_mem_ptr_old = (void *)malloc_mem_ptr_new;
+ free(memory_item_new->mem_nelem);
+ free(memory_item_new->mem_name);
+ free(memory_item_new);
+
+ memory_ptr_dict.insert(std::pair<void*, malloc_plus_memory_entry*>(malloc_mem_ptr_old, memory_item_old) );
+ memory_name_dict.insert(std::pair<const char*, malloc_plus_memory_entry*>(memory_item_old->mem_name, memory_item_old) );
+
+ return(memory_item_old->mem_ptr);
+ } else {
+ if (DEBUG) printf("Warning -- memory not found\n");
+ }
+ return(NULL);
+}
+
+void MallocPlus::memory_swap(int **malloc_mem_ptr_old, int **malloc_mem_ptr_new){
+ map <void *, malloc_plus_memory_entry*>::iterator it_old = memory_ptr_dict.find(*malloc_mem_ptr_old);
+ map <void *, malloc_plus_memory_entry*>::iterator it_new = memory_ptr_dict.find(*malloc_mem_ptr_new);
+
+ if (it_old != memory_ptr_dict.end() && it_new != memory_ptr_dict.end() ){
+ // Swap the memory entries during the retrieval
+ malloc_plus_memory_entry *memory_item_new = it_old->second;
+ malloc_plus_memory_entry *memory_item_old = it_new->second;
+
+ if (DEBUG) printf("Found memory item ptr_old %p name %s ptr_new %p name %s\n",memory_item_old->mem_ptr,memory_item_old->mem_name,memory_item_new->mem_ptr,memory_item_new->mem_name);
+
+ const char *mem_name_tmp;
+ mem_name_tmp = memory_item_old->mem_name;
+ memory_item_old->mem_name = memory_item_new->mem_name;
+ memory_item_new->mem_name = (char *)mem_name_tmp;
+
+ // Delete the ptr entries
+ memory_ptr_dict.erase(it_old);
+ memory_ptr_dict.erase(it_new);
+
+ memory_ptr_dict.insert(std::pair<void *, malloc_plus_memory_entry*>(memory_item_old->mem_ptr, memory_item_old) );
+ memory_ptr_dict.insert(std::pair<void *, malloc_plus_memory_entry*>(memory_item_new->mem_ptr, memory_item_new) );
+
+ // Delete the named entries
+ map <string, malloc_plus_memory_entry*>::iterator it_name_old = memory_name_dict.find(memory_item_old->mem_name);
+ map <string, malloc_plus_memory_entry*>::iterator it_name_new = memory_name_dict.find(memory_item_new->mem_name);
+ memory_name_dict.erase(it_name_old);
+ memory_name_dict.erase(it_name_new);
+
+ memory_name_dict.insert(std::pair<string, malloc_plus_memory_entry*>(memory_item_old->mem_name, memory_item_old) );
+ memory_name_dict.insert(std::pair<string, malloc_plus_memory_entry*>(memory_item_new->mem_name, memory_item_new) );
+
+ // memory items have been swapped, so return the new pointers
+ *malloc_mem_ptr_old = (int *)memory_item_old->mem_ptr;
+ *malloc_mem_ptr_new = (int *)memory_item_new->mem_ptr;
+ } else {
+ if (DEBUG) printf("Warning -- memory not found\n");
+ }
+}
+
+void MallocPlus::memory_swap(float **malloc_mem_ptr_old, float **malloc_mem_ptr_new){
+ map <void *, malloc_plus_memory_entry*>::iterator it_old = memory_ptr_dict.find(*malloc_mem_ptr_old);
+ map <void *, malloc_plus_memory_entry*>::iterator it_new = memory_ptr_dict.find(*malloc_mem_ptr_new);
+
+ if (it_old != memory_ptr_dict.end() && it_new != memory_ptr_dict.end() ){
+ // Swap the memory entries during the retrieval
+ malloc_plus_memory_entry *memory_item_new = it_old->second;
+ malloc_plus_memory_entry *memory_item_old = it_new->second;
+
+ if (DEBUG) printf("Found memory item ptr_old %p name %s ptr_new %p name %s\n",memory_item_old->mem_ptr,memory_item_old->mem_name,memory_item_new->mem_ptr,memory_item_new->mem_name);
+
+ const char *mem_name_tmp;
+ mem_name_tmp = memory_item_old->mem_name;
+ memory_item_old->mem_name = memory_item_new->mem_name;
+ memory_item_new->mem_name = (char *)mem_name_tmp;
+
+ // Delete the ptr entries
+ memory_ptr_dict.erase(it_old);
+ memory_ptr_dict.erase(it_new);
+
+ memory_ptr_dict.insert(std::pair<void *, malloc_plus_memory_entry*>(memory_item_old->mem_ptr, memory_item_old) );
+ memory_ptr_dict.insert(std::pair<void *, malloc_plus_memory_entry*>(memory_item_new->mem_ptr, memory_item_new) );
+
+ // Delete the named entries
+ map <string, malloc_plus_memory_entry*>::iterator it_old = memory_name_dict.find(memory_item_old->mem_name);
+ map <string, malloc_plus_memory_entry*>::iterator it_new = memory_name_dict.find(memory_item_new->mem_name);
+ memory_name_dict.erase(it_old);
+ memory_name_dict.erase(it_new);
+
+ memory_name_dict.insert(std::pair<string, malloc_plus_memory_entry*>(memory_item_old->mem_name, memory_item_old) );
+ memory_name_dict.insert(std::pair<string, malloc_plus_memory_entry*>(memory_item_new->mem_name, memory_item_new) );
+
+ // memory items have been swapped, so return the new pointers
+ *malloc_mem_ptr_old = (float *)memory_item_old->mem_ptr;
+ *malloc_mem_ptr_new = (float *)memory_item_new->mem_ptr;
+ } else {
+ if (DEBUG) printf("Warning -- memory not found\n");
+ }
+}
+
+void MallocPlus::memory_swap(double **malloc_mem_ptr_old, double **malloc_mem_ptr_new){
+ map <void *, malloc_plus_memory_entry*>::iterator it_old = memory_ptr_dict.find(*malloc_mem_ptr_old);
+ map <void *, malloc_plus_memory_entry*>::iterator it_new = memory_ptr_dict.find(*malloc_mem_ptr_new);
+
+ if (it_old != memory_ptr_dict.end() && it_new != memory_ptr_dict.end() ){
+ // Swap the memory entries during the retrieval
+ malloc_plus_memory_entry *memory_item_new = it_old->second;
+ malloc_plus_memory_entry *memory_item_old = it_new->second;
+
+ if (DEBUG) printf("Found memory item ptr_old %p name %s ptr_new %p name %s\n",memory_item_old->mem_ptr,memory_item_old->mem_name,memory_item_new->mem_ptr,memory_item_new->mem_name);
+
+ const char *mem_name_tmp;
+ mem_name_tmp = memory_item_old->mem_name;
+ memory_item_old->mem_name = memory_item_new->mem_name;
+ memory_item_new->mem_name = (char *)mem_name_tmp;
+
+ // Delete the ptr entries
+ memory_ptr_dict.erase(it_old);
+ memory_ptr_dict.erase(it_new);
+
+ memory_ptr_dict.insert(std::pair<void *, malloc_plus_memory_entry*>(memory_item_old->mem_ptr, memory_item_old) );
+ memory_ptr_dict.insert(std::pair<void *, malloc_plus_memory_entry*>(memory_item_new->mem_ptr, memory_item_new) );
+
+ // Delete the named entries
+ map <string, malloc_plus_memory_entry*>::iterator it_old = memory_name_dict.find(memory_item_old->mem_name);
+ map <string, malloc_plus_memory_entry*>::iterator it_new = memory_name_dict.find(memory_item_new->mem_name);
+ memory_name_dict.erase(it_old);
+ memory_name_dict.erase(it_new);
+
+ memory_name_dict.insert(std::pair<char const *, malloc_plus_memory_entry*>(memory_item_old->mem_name, memory_item_old) );
+ memory_name_dict.insert(std::pair<char const *, malloc_plus_memory_entry*>(memory_item_new->mem_name, memory_item_new) );
+
+ // memory items have been swapped, so return the new pointers
+ *malloc_mem_ptr_old = (double *)memory_item_old->mem_ptr;
+ *malloc_mem_ptr_new = (double *)memory_item_new->mem_ptr;
+ } else {
+ if (DEBUG) printf("Warning -- memory not found\n");
+ }
+}
+
+// This duplicates memory for a variable and makes a new dictionary entry for the new variable
+void *MallocPlus::memory_duplicate(void *malloc_mem_ptr, const char *addname){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+ void *mem_ptr_dup;
+
+ if (it != memory_ptr_dict.end()){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ // The memory_malloc will add the database entry
+ mem_ptr_dup = memory_malloc(memory_item->mem_nelem[0], memory_item->mem_elsize, addname, memory_item->mem_flags);
+ return(mem_ptr_dup);
+ } else {
+ if (DEBUG) printf("Warning -- memory not found\n");
+ }
+ return(NULL);
+}
+
+void *MallocPlus::get_memory_ptr(const char *name){
+ map <string, malloc_plus_memory_entry*>::iterator it = memory_name_dict.find(name);
+
+ if (it != memory_name_dict.end()){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("Found memory item ptr %p name %s\n",memory_item->mem_ptr,memory_item->mem_name);
+ return(memory_item->mem_ptr);
+ } else {
+ if (DEBUG) printf("Warning -- memory not found\n");
+ }
+ return(NULL);
+}
+
+bool MallocPlus::check_memory_attribute(void *malloc_mem_ptr, int attribute){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+
+ if (it != memory_ptr_dict.end()){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("Found memory item ptr %p name %s attribute %d\n",memory_item->mem_ptr,memory_item->mem_name,memory_item->mem_flags);
+ bool bvalue = false;
+ if (memory_item->mem_flags & attribute) bvalue = true;
+
+ return bvalue;
+ } else {
+ printf("Error -- memory not found\n");
+ exit(1);
+ }
+}
+
+void MallocPlus::set_memory_attribute(void *malloc_mem_ptr, int attribute){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+
+ if (it != memory_ptr_dict.end()){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("Found memory item ptr %p name %s attribute %d\n",memory_item->mem_ptr,memory_item->mem_name,memory_item->mem_flags);
+ memory_item->mem_flags |= attribute;
+ } else {
+ if (DEBUG) printf("Warning -- memory not found\n");
+ }
+}
+
+void MallocPlus::clear_memory_attribute(void *malloc_mem_ptr, int attribute){
+ map <void *, malloc_plus_memory_entry*>::iterator it = memory_ptr_dict.find(malloc_mem_ptr);
+
+ if (it != memory_ptr_dict.end()){
+ malloc_plus_memory_entry *memory_item = it->second;
+
+ if (DEBUG) printf("Found memory item ptr %p name %s attribute %d\n",memory_item->mem_ptr,memory_item->mem_name,memory_item->mem_flags);
+ memory_item->mem_flags &= ~attribute;
+ if (DEBUG) printf("Found memory item ptr %p name %s attribute %d\n",memory_item->mem_ptr,memory_item->mem_name,memory_item->mem_flags);
+ } else {
+ if (DEBUG) printf("Warning -- memory not found\n");
+ }
+}
+
+extern "C" {
+ MallocPlus *MallocPlus_new(){
+ return new MallocPlus;
+ }
+
+ void MallocPlus_memory_report(MallocPlus *mem_object) {
+ mem_object->memory_report();
+ }
+
+ void MallocPlus_memory_add(MallocPlus *mem_object, void *dbleptr, size_t nelem,
+ size_t elsize, char *name, unsigned long long flags){
+// printf("DEBUG -- nelem %lu elsize %lu\n", nelem, elsize);
+ mem_object->memory_add(dbleptr, nelem, elsize, name,
+ (unsigned long long)flags);
+ }
+ void MallocPlus_memory_add_nD(MallocPlus *mem_object, void *dbleptr, int ndim, size_t *nelem,
+ size_t elsize, char *name, unsigned long long flags){
+// printf("DEBUG -- ndim %d nelem[0] %lu elsize %lu\n",ndim, nelem[0], elsize);
+ mem_object->memory_add(dbleptr, ndim, nelem, elsize, name,
+ (unsigned long long)flags);
+ }
+}
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/MallocPlus.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/MallocPlus.h?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/MallocPlus.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/MallocPlus.h Sun Sep 3 20:10:18 2017
@@ -0,0 +1,812 @@
+/*
+ * Copyright (c) 2011-2013, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ * This research code is being developed as part of the
+ * 2011 X Division Summer Workshop for the express purpose
+ * of a collaborative code for development of ideas in
+ * the implementation of AMR codes for Exascale platforms
+ *
+ * AMR implementation of the Wave code previously developed
+ * as a demonstration code for regular grids on Exascale platforms
+ * as part of the Supercomputing Challenge and Los Alamos
+ * National Laboratory
+ *
+ * Authors: Bob Robey XCP-2 brobey at lanl.gov
+ *
+ */
+#ifndef MALLOCPLUS_H_
+#define MALLOCPLUS_H_
+
+#include <map>
+#include <string>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define HOST_REGULAR_MEMORY 0x00000
+#define HOST_MANAGED_MEMORY 0x00001
+#define DEVICE_REGULAR_MEMORY 0x00002
+#define INDEX_ARRAY_MEMORY 0x00004
+#define LOAD_BALANCE_MEMORY 0x00008
+#define RESTART_DATA 0x00010
+#define REPLICATED_DATA 0x00020
+#define DISTRIBUTED_INT_DATA 0x00040
+#define DISTRIBUTED_DOUBLE_DATA 0x00080
+
+#if defined(HAVE_MPI)
+#include "mpi.h"
+#if defined(HAVE_J7)
+#include "j7/j7.h"
+#endif
+#endif
+
+using namespace std;
+
+/****************************************************************//**
+ * \brief
+ * Memory entry with fields for each entry in database
+ *******************************************************************/
+struct malloc_plus_memory_entry {
+ void *mem_ptr; //!< memory pointer for entry
+ size_t mem_capacity; //!< allocated capacity for memory buffer
+ //!< this may be larger than the number of
+ //!< elements and is used to internally handle
+ //!< memory resizing
+ size_t *mem_nelem; //!< number of elements
+ size_t mem_ndims; //!< number of dimensions
+ size_t mem_elsize; //!< element size for type of data
+ int mem_flags; //!< flags for special handling
+ char *mem_name; //!< name of memory entry
+};
+
+struct cmp_str
+{
+ bool operator()(char const *a, char const *b)
+ {
+ return strcmp(a, b) < 0;
+ }
+};
+
+/****************************************************************//**
+ * MallocPlus class
+ * Provide an enhanced memory allocation package with database
+ * of allocations, sizes and contiguous memory allocations for
+ * multi-dimensional arrays
+ *******************************************************************/
+class MallocPlus {
+//protected:
+public:
+ map<string, malloc_plus_memory_entry*> memory_name_dict; //!< Dictionary entries by name
+ map<void*, malloc_plus_memory_entry*> memory_ptr_dict; //!< Dictionary entries by pointer
+
+#if defined(HAVE_MPI) && defined(HAVE_J7)
+private:
+ J7 *j7;
+#endif
+
+public:
+ // if we have MPI support enable these routines. they only really do anything
+ // if we also have j7 support, but that's okay; we don't want ifdefs all
+ // over.
+#if defined(HAVE_MPI)
+ // parallel initialization routine
+ void pinit(MPI_Comm smComm, std::size_t memPoolSize);
+ // parallel finalization routine
+ void pfini(void);
+#endif
+
+/****************************************************************//**
+ * \brief
+ * Allocates memory for a 1D array and put entry in database
+ *
+ * **Parameters**
+ * * size_t nelem -- number of elements in array
+ * * size_t elsize -- element size in bytes
+ * * const char *name -- name of array
+ * * int flags -- flags for special handling, default is 0
+ *
+ * Typical Usage
+ *
+ * double *density = my_mem->memory_malloc(ncells, sizeof(double),
+ * "Density");
+ *******************************************************************/
+ void *memory_malloc(size_t nelem, size_t elsize, const char *name, int flags=0);
+
+/****************************************************************//**
+ * \brief
+ * Duplicate memory and add new entry into database
+ *
+ * **Parameters**
+ * * void *malloc_mem_ptr -- memory pointer to duplicate
+ * * const char *addname -- new name for variable
+ *
+ * Typical Usage
+ *
+ * double *new_density = my_mem->memory_duplicate(density, "Density_new");
+ *******************************************************************/
+ void *memory_duplicate(void *malloc_mem_ptr, const char *addname);
+
+/****************************************************************//**
+ * \brief
+ * Reallocates memory for memory pointer in database
+ *
+ * **Parameters**
+ * * size_t nelem -- number of elements for new allocation
+ * * void *malloc_mem_ptr -- memory pointer to duplicate
+ *
+ * Typical Usage
+ *
+ * double *density = my_mem->memory_realloc(new_ncells, density);
+ *******************************************************************/
+ void *memory_realloc(size_t nelem, void *malloc_mem_ptr);
+
+/****************************************************************//**
+ * \brief
+ * Reallocates memory for named entry in database
+ *
+ * **Parameters**
+ * * size_t nelem -- number of elements for new allocation
+ * * const char *name -- named entry to duplicate
+ *
+ * Typical Usage
+ *
+ * double *density = my_mem->memory_realloc(new_ncells, "Density");
+ *******************************************************************/
+ void *memory_realloc(size_t nelem, const char *name);
+
+/****************************************************************//**
+ * \brief
+ * Request memory buffer capacity reallocation for memory pointer in database.
+ * This only changes the capacity for managed memory and does not change
+ * the current number of elements registered for the array.
+ *
+ * **Parameters**
+ * * size_t capacity -- capacity in number of elements for reallocation
+ * * void *malloc_mem_ptr -- memory pointer to reallocate more capacity
+ *
+ * Typical Usage
+ *
+ * double *density = my_mem->memory_request(new_capacity, density);
+ *******************************************************************/
+ void *memory_request(size_t new_capacity, void *malloc_mem_ptr);
+
+/****************************************************************//**
+ * \brief
+ * Request memory buffer capacity reallocation for named entry in database.
+ * This only changes the capacity for managed memory and does not change
+ * the current number of elements registered for the array.
+ *
+ * **Parameters**
+ * * size_t capacity -- capacity in number of elements for reallocation
+ * * const char *name -- named entry in database
+ *
+ * Typical Usage
+ *
+ * double *density = my_mem->memory_request(new_capacity, "Density");
+ *******************************************************************/
+ void *memory_request(size_t new_capacity, const char *name);
+
+/****************************************************************//**
+ * \brief
+ * Reallocates memory for all arrays in the database. Element size stays
+ * the same.
+ *
+ * **Parameters**
+ * * size_t nelem -- number of elements for new allocation
+ *
+ * Typical Usage
+ *
+ * my_mem->memory_realloc_all(new_ncells);
+ *******************************************************************/
+ void memory_realloc_all(size_t nelem);
+
+/****************************************************************//**
+ * \brief
+ * Requests capacity reallocation for all arrays in the database. Element
+ * size and number of elements stays the same. The maximum memory
+ * capacity is increased.
+ *
+ * **Parameters**
+ * * size_t capacity -- number of elements for new allocation
+ *
+ * Typical Usage
+ *
+ * my_mem->memory_realloc_all(new_capacity);
+ *******************************************************************/
+ void memory_request_all(size_t new_capacity);
+
+/****************************************************************//**
+ * \brief
+ * Replaces a database entry with another database entry, effectively
+ * renaming the entry and deallocating the memory for the old entry
+ * and removing the other database entry. Both the return and the
+ * first argument old memory pointer gets reset to the new memory
+ * location.
+ *
+ * **Parameters**
+ * * void *malloc_mem_ptr_old -- memory pointer to entry to replace
+ * * void * const malloc_mem_ptr_new -- memory pointer to entry to
+ * put in place of old memory
+ *
+ * Typical Usage
+ *
+ * double *density_new = (double *)my_mem->memory_malloc(new_ncells,
+ * sizeof(double), "Density_new");
+ * ... lots of calculations of density_new from density (old) ...
+ * density = (double *)my_mem->memory_replace(density, density_new);
+ *******************************************************************/
+ void *memory_replace(void *malloc_mem_ptr_old, void * const malloc_mem_ptr_new);
+
+/****************************************************************//**
+ * \brief
+ * Swaps a database entry with another database entry, effectively
+ * renaming both entries. The new pointers are returned in the
+ * two arguments.
+ *
+ * **Parameters**
+ * * void *malloc_mem_ptr_old -- memory pointer to swap
+ * * void *malloc_mem_ptr_new -- memory pointer to swap
+ *
+ * Typical Usage
+ *
+ * int *level_old = (int *)my_mem->memory_malloc(new_ncells,
+ * sizeof(int), "level_old");
+ * level = (int *)my_mem->memory_swap(&level, &level_old);
+ * ... lots of calculations of level from level_new ...
+ * my_mem->memory_delete(level_old);
+ *******************************************************************/
+ void memory_swap(int **malloc_mem_ptr_old, int **malloc_mem_ptr_new);
+
+/****************************************************************//**
+ * \brief
+ * Swaps a database entry with another database entry, effectively
+ * renaming both entries. The new pointers are returned in the
+ * two arguments.
+ *
+ * **Parameters**
+ * * void *malloc_mem_ptr_old -- memory pointer to swap
+ * * void *malloc_mem_ptr_new -- memory pointer to swap
+ *
+ * Typical Usage
+ *
+ * float *density_old = (float *)my_mem->memory_malloc(new_ncells,
+ * sizeof(float), "Density_old");
+ * density = (float *)my_mem->memory_swap(&density, &density_old);
+ * ... lots of calculations of density from density_new ...
+ * my_mem->memory_delete(density_old);
+ *******************************************************************/
+ void memory_swap(float **malloc_mem_ptr_old, float **malloc_mem_ptr_new);
+
+/****************************************************************//**
+ * \brief
+ * Swaps a database entry with another database entry, effectively
+ * renaming both entries. The new pointers are returned in the
+ * two arguments.
+ *
+ * **Parameters**
+ * * void *malloc_mem_ptr_old -- memory pointer to swap
+ * * void *malloc_mem_ptr_new -- memory pointer to swap
+ *
+ * Typical Usage
+ *
+ * double *density_old = (double *)my_mem->memory_malloc(new_ncells,
+ * sizeof(double), "Density_old");
+ * density = (double *)my_mem->memory_swap(&density, &density_old);
+ * ... lots of calculations of density from density_new ...
+ * my_mem->memory_delete(density_old);
+ *******************************************************************/
+ void memory_swap(double **malloc_mem_ptr_old, double **malloc_mem_ptr_new);
+
+/****************************************************************//**
+ * \brief
+ * Adds an entry for an already allocated array into the database
+ *
+ * **Parameters**
+ * * void *malloc_mem_ptr -- memory pointer to add
+ * * size_t nelem -- number of elements in array
+ * * size_t elsize -- element size in bytes
+ * * const char *name -- name of array
+ * * int flags -- flags for special handling, default is 0
+ *
+ * Typical Usage
+ *
+ * double *density = my_mem->memory_add(density, ncells, sizeof(double),
+ * "Density");
+ *******************************************************************/
+ void *memory_add(void *malloc_mem_ptr, size_t nelem, size_t elsize,
+ const char *name, int flags=0);
+
+ void *memory_add(void *malloc_mem_ptr, int ndim, size_t *nelem, size_t elsize,
+ const char *name, int flags=0);
+
+/****************************************************************//**
+ * \brief
+ * Reorders all of the arrays in the database by the indices in the
+ * iorder array. The reorder does the following:
+ * tmp[ic] = density[iorder[ic]];
+ * SWAP_PTR(tmp, density);
+ * Note that the pointer value will change during the operation and
+ * will be returned in the return value.
+ *
+ * **Parameters**
+ * * double *malloc_mem_ptr -- memory pointer to entry to reorder
+ * * int *iorder -- index array for reordering
+ *
+ * Typical Usage
+ *
+ * double *density = my_mem->memory_reorder_all(density, iorder);
+ *******************************************************************/
+ double *memory_reorder(double *malloc_mem_ptr, int *iorder);
+
+/****************************************************************//**
+ * \brief
+ * Reorders all of the arrays in the database by the indices in the
+ * iorder array. The reorder does the following:
+ * tmp[ic] = density[iorder[ic]];
+ * SWAP_PTR(tmp, density);
+ * Note that the pointer value will change during the operation and
+ * will be returned in the return value.
+ *
+ * **Parameters**
+ * * float *malloc_mem_ptr -- memory pointer to entry to reorder
+ * * int *iorder -- index array for reordering
+ *
+ * Typical Usage
+ *
+ * float *density = my_mem->memory_reorder_all(density, iorder);
+ *******************************************************************/
+ float *memory_reorder(float *malloc_mem_ptr, int *iorder);
+
+/****************************************************************//**
+ * \brief
+ * Reorders all of the arrays in the database by the indices in the
+ * iorder array. The reorder does the following:
+ * tmp[ic] = level[iorder[ic]];
+ * SWAP_PTR(tmp, level);
+ * Note that the pointer value will change during the operation and
+ * will be returned in the return value.
+ *
+ * **Parameters**
+ * * int *malloc_mem_ptr -- memory pointer to entry to reorder
+ * * int *iorder -- index array for reordering
+ *
+ * Typical Usage
+ *
+ * int *level = my_mem->memory_reorder_all(level, iorder);
+ *******************************************************************/
+ int *memory_reorder(int *malloc_mem_ptr, int *iorder);
+
+/****************************************************************//**
+ * \brief
+ * Reorders an index array in the database by the indices in the
+ * iorder array and reindexes the array by the inverse order given
+ * by inv_iorder. The reorder does the following:
+ * tmp[ic] = inv_iorder[level[iorder[ic]]];
+ * SWAP_PTR(tmp, level);
+ * Note that the pointer value will change during the operation and
+ * will be returned in the return value.
+ *
+ * **Parameters**
+ * * int *malloc_mem_ptr -- memory pointer to entry to reorder
+ * * int *iorder -- index array for reordering
+ * * int *inv_order -- inverse index array for reordering
+ *
+ * Typical Usage
+ *
+ * int *level = my_mem->memory_reorder_all(level, iorder, inv_iorder);
+ *******************************************************************/
+ int *memory_reorder_indexarray(int *malloc_mem_ptr, int *iorder, int *inv_iorder);
+
+/****************************************************************//**
+ * \brief
+ * Reorders all of the arrays in the database by the indices in the
+ * iorder array. The reorder does the following:
+ * tmp[ic] = density[iorder[ic]];
+ * SWAP_PTR(tmp, density);
+ * Note that the pointer value will change during the operation and
+ * must be retrieved from the database.
+ *
+ * **Parameters**
+ * * int *iorder -- index array for reordering
+ *
+ * Typical Usage
+ *
+ * my_mem->memory_reorder_all(iorder);
+ *******************************************************************/
+ void memory_reorder_all(int *iorder);
+
+/****************************************************************//**
+ * \brief
+ * Prints out a report of all the arrays in the database.
+ *
+ * Typical Usage
+ *
+ * my_mem->memory_report();
+ *******************************************************************/
+ void memory_report(void);
+
+/****************************************************************//**
+ * \brief
+ * Deallocates memory for a memory pointer in the database and removes the
+ * entry from the database.
+ *
+ * Typical Usage
+ *
+ * my_mem->memory_delete(density);
+ *******************************************************************/
+ void *memory_delete(void *malloc_mem_ptr);
+
+/****************************************************************//**
+ * \brief
+ * Deallocates memory for a named entry in the database and removes the
+ * entry from the database.
+ *
+ * Typical Usage
+ *
+ * my_mem->memory_delete("Density");
+ *******************************************************************/
+ void *memory_delete(const char *name);
+
+/****************************************************************//**
+ * \brief
+ * Deallocates memory for all arrays in the database.
+ *
+ * Typical Usage
+ *
+ * my_mem->memory_delete_all();
+ *******************************************************************/
+ void memory_delete_all(void);
+
+/****************************************************************//**
+ * \brief
+ * Removes the entry for a memory pointer from the database. (This does
+ * not delete the memory).
+ *
+ * Typical Usage
+ *
+ * my_mem->memory_delete(density);
+ *******************************************************************/
+ void memory_remove(void *malloc_mem_ptr);
+
+/****************************************************************//**
+ * \brief
+ * Removes the entry for a named entry from the database. (This does
+ * not delete the memory).
+ *
+ * Typical Usage
+ *
+ * my_mem->memory_delete("Density");
+ *******************************************************************/
+ void memory_remove(const char *name);
+
+/****************************************************************//**
+ * \brief
+ * Gets initial memory pointer from database for iterating over the
+ * entries and processing each.
+ *
+ * Typical Usage
+ *
+ * for (void *mem_ptr = my_mem.memory_begin(); mem_ptr!=NULL;
+ * mem_ptr = my_mem.memory_next() ){
+ * ... process entries ...
+ * }
+ *******************************************************************/
+ void *memory_begin(void);
+
+/****************************************************************//**
+ * \brief
+ * Gets next memory pointer from database for iterating over the
+ * entries and processing each. Note that their is an implied caching
+ * of the current memory pointer in MallocPlus.
+ *
+ * Typical Usage
+ *
+ * for (void *mem_ptr = my_mem.memory_begin(); mem_ptr!=NULL;
+ * mem_ptr = my_mem.memory_next() ){
+ * ... process entries ...
+ * }
+ *******************************************************************/
+ void *memory_next(void);
+
+/****************************************************************//**
+ * \brief
+ * Gets initial memory pointer from database for iterating over the
+ * entries and processing each.
+ *
+ * Typical Usage
+ *
+ * for (void *mem_ptr = my_mem.memory_by_name_begin(); mem_ptr!=NULL;
+ * mem_ptr = my_mem.memory_by_name_next() ){
+ * ... process entries ...
+ * }
+ *******************************************************************/
+ void *memory_by_name_begin(void);
+
+/****************************************************************//**
+ * \brief
+ * Gets next memory pointer from database for iterating over the
+ * entries and processing each. Note that their is an implied caching
+ * of the current memory pointer in MallocPlus.
+ *
+ * Typical Usage
+ *
+ * for (void *mem_ptr = my_mem.memory_by_name_begin(); mem_ptr!=NULL;
+ * mem_ptr = my_mem.memory_by_name_next() ){
+ * ... process entries ...
+ * }
+ *******************************************************************/
+ void *memory_by_name_next(void);
+
+/****************************************************************//**
+ * \brief
+ * Gets initial memory entry from database for iterating over the
+ * entries and processing each.
+ *
+ * Typical Usage
+ *
+ * malloc_plus_memory_entry memory_item;
+ * for (memory_item = my_mem.memory_entry_begin();
+ * memory_item != my_mem.memory_entry_end();
+ * memory_item = my_mem.memory_entry_next() ){
+ * ... process entries ...
+ * }
+ *******************************************************************/
+ malloc_plus_memory_entry *memory_entry_begin(void);
+
+/****************************************************************//**
+ * \brief
+ * Gets next memory entry from database for iterating over the
+ * entries and processing each.
+ *
+ * Typical Usage
+ *
+ * malloc_plus_memory_entry memory_item;
+ * for (memory_item = my_mem.memory_entry_begin();
+ * memory_item != my_mem.memory_entry_end();
+ * memory_item = my_mem.memory_entry_next() ){
+ * ... process entries ...
+ * }
+ *******************************************************************/
+ malloc_plus_memory_entry *memory_entry_next(void);
+
+/****************************************************************//**
+ * \brief
+ * Gets initial memory iterator from database for iterating over the
+ * entries and processing each.
+ *
+ * Typical Usage
+ *
+ * malloc_plus_memory_entry *memory_item;
+ * for (memory_item = my_mem.memory_entry_begin();
+ * memory_item != my_mem.memory_entry_end();
+ * memory_item = my_mem.memory_entry_next() ){
+ * ... process entries ...
+ * }
+ *******************************************************************/
+ malloc_plus_memory_entry *memory_entry_end(void);
+
+/****************************************************************//**
+ * \brief
+ * Gets initial memory entry from name database for iterating over the
+ * entries and processing each.
+ *
+ * Typical Usage
+ *
+ * malloc_plus_memory_entry memory_item;
+ * for (memory_item = my_mem.memory_entry_by_name_begin();
+ * memory_item != my_mem.memory_entry_by_name_end();
+ * memory_item = my_mem.memory_entry_by_name_next() ){
+ * ... process entries ...
+ * }
+ *******************************************************************/
+ malloc_plus_memory_entry *memory_entry_by_name_begin(void);
+
+/****************************************************************//**
+ * \brief
+ * Gets next memory entry from database for iterating over the
+ * entries and processing each.
+ *
+ * Typical Usage
+ *
+ * malloc_plus_memory_entry memory_item;
+ * for (memory_item = my_mem.memory_entry_by_name_begin();
+ * memory_item != my_mem.memory_entry_by_name_end();
+ * memory_item = my_mem.memory_entry_by_name_next() ){
+ * ... process entries ...
+ * }
+ *******************************************************************/
+ malloc_plus_memory_entry *memory_entry_by_name_next(void);
+
+/****************************************************************//**
+ * \brief
+ * Gets initial memory iterator from database for iterating over the
+ * entries and processing each.
+ *
+ * Typical Usage
+ *
+ * malloc_plus_memory_entry *memory_item;
+ * for (memory_item = my_mem.memory_entry_by_name_begin();
+ * memory_item != my_mem.memory_entry_by_name_end();
+ * memory_item = my_mem.memory_entry_by_name_next() ){
+ * ... process entries ...
+ * }
+ *******************************************************************/
+ malloc_plus_memory_entry *memory_entry_by_name_end(void);
+
+/****************************************************************//**
+ * \brief
+ * Get number of elements for a memory pointer in the database.
+ *
+ * **Parameters**
+ * * void *malloc_mem_ptr -- memory pointer for entry in the database
+ *
+ * Typical Usage
+ *
+ * size_t nsize = my_mem->get_memory_size(density);
+ *******************************************************************/
+ size_t get_memory_size(void *malloc_mem_ptr);
+
+/****************************************************************//**
+ * \brief
+ * Get the memory capacity in number of elements for a memory pointer
+ * in the database. Memory capacity is the overallocated size of the
+ * array in schemes where memory is managed internally to reduce
+ * the number of reallocations.
+ *
+ * **Parameters**
+ * * void *malloc_mem_ptr -- memory pointer for entry in the database
+ *
+ * Typical Usage
+ *
+ * size_t var_capacity = my_mem->get_memory_capacity(density);
+ *******************************************************************/
+ size_t get_memory_capacity(void *malloc_mem_ptr);
+
+/****************************************************************//**
+ * \brief
+ * Get the element size for a memory pointer in the database.
+ *
+ * **Parameters**
+ * * void *malloc_mem_ptr -- memory pointer for entry in the database
+ *
+ * Typical Usage
+ *
+ * int elsize = my_mem->get_memory_elemsize(density);
+ *******************************************************************/
+ int get_memory_elemsize(void *malloc_mem_ptr);
+
+/****************************************************************//**
+ * \brief
+ * Get name for a memory pointer in the database.
+ *
+ * **Parameters**
+ * * void *malloc_mem_ptr -- memory pointer for entry in the database
+ *
+ * Typical Usage
+ *
+ * const char *var_name = my_mem->get_memory_name(density);
+ *******************************************************************/
+ const char *get_memory_name(void *malloc_mem_ptr);
+
+/****************************************************************//**
+ * \brief
+ * Get memory pointer for a named entry from the database.
+ *
+ * **Parameters**
+ * * const char *name -- name of entry in the database
+ *
+ * Typical Usage
+ *
+ * density = my_mem->get_memory_ptr("Density");
+ *******************************************************************/
+ void *get_memory_ptr(const char *name);
+
+/****************************************************************//**
+ * \brief
+ * Set a memory attribute for a memory pointer in the database.
+ *
+ * **Parameters**
+ * * void *malloc_mem_ptr -- memory pointer of entry in the database
+ * * int attribute -- flag to set for entry
+ *
+ * Typical Usage
+ *
+ * my_mem->set_memory_attribute(density, HOST_MANAGED_MEMORY);
+ *******************************************************************/
+ void set_memory_attribute(void *malloc_mem_ptr, int attribute);
+
+/****************************************************************//**
+ * \brief
+ * Clear memory attribute for a memory pointer in the database.
+ *
+ * **Parameters**
+ * * void *malloc_mem_ptr -- memory pointer of entry in the database
+ * * int attribute -- flag to clear for entry
+ *
+ * Typical Usage
+ *
+ * my_mem->clear_memory_attribute(density, HOST_MANAGED_MEMORY);
+ *******************************************************************/
+ void clear_memory_attribute(void *malloc_mem_ptr, int attribute);
+
+/****************************************************************//**
+ * \brief
+ * Get memory attributes for a memory pointer in the database. Returns
+ * the flag field.
+ *
+ * **Parameters**
+ * * void *malloc_mem_ptr -- memory pointer of entry in the database
+ *
+ * Typical Usage
+ *
+ * int flag = my_mem->get_memory_attribute(density);
+ *******************************************************************/
+ int get_memory_flags(void *malloc_mem_ptr);
+
+/****************************************************************//**
+ * \brief
+ * Checks the setting for a memory attribute for a memory pointer in
+ * the database. Returns true for set and false for unset.
+ *
+ * **Parameters**
+ * * void *malloc_mem_ptr -- memory pointer of entry in the database
+ * * int attribute -- flag to check setting for entry
+ *
+ * Typical Usage
+ *
+ * bool flag = my_mem->check_memory_attribute(density, HOST_MANAGED_MEMORY);
+ *******************************************************************/
+ bool check_memory_attribute(void *malloc_mem_ptr, int attribute);
+};
+
+extern "C" {
+ MallocPlus *MallocPlus_new();
+
+ void MallocPlus_memory_report(MallocPlus *mem_object);
+
+ void MallocPlus_memory_add(MallocPlus *mem_object, void *dbleptr,
+ size_t nelem, size_t elsize, char *name, unsigned long long flags);
+ void MallocPlus_memory_add_nD(MallocPlus *mem_object, void *dbleptr,
+ int ndim, size_t *nelem, size_t elsize, char *name, unsigned long long flags);
+}
+
+#endif // ifndef MALLOCPLUS_H_
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Parser_math.cc
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Parser_math.cc?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Parser_math.cc (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Parser_math.cc Sun Sep 3 20:10:18 2017
@@ -0,0 +1,326 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+// ***************************************************************************
+// ***************************************************************************
+// This class collects various parser math functions.
+//
+// There are two reasons to have this class:
+// 1. To keep the command processing class from getting too big.
+// 2. Some of these functions are used in more than one class.
+// ***************************************************************************
+// ***************************************************************************
+
+#include <iostream>
+#include <iomanip>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <deque>
+#include <math.h>
+
+#include "Word.hh"
+#include "Parser_math.hh"
+
+namespace PP
+{
+using std:: string;
+using std::cout;
+using std::endl;
+using std::stringstream;
+using std::setprecision;
+using std::vector;
+using std::deque;
+
+
+// ===========================================================================
+// Default constructor.
+// ===========================================================================
+Parser_math::Parser_math()
+{
+}
+
+
+// ===========================================================================
+// Do a single arithmetic binary operation involving 3 words. i1, on the left,
+// is supposed to be a number, i2 is the operator, and i3, on the right, is
+// supposed to be a number.
+// The result is put in word wres.
+// ===========================================================================
+void Parser_math::do_op(int i1, int i2, int i3,deque <Word> &wq, Word &wres,
+ stringstream &serr, int &ierr)
+{
+ // The words to the left and right of the operator have to be a number.
+ if ((!wq[i1].is_number()) || (!wq[i3].is_number())) {
+ wq[i2].fatal_error(serr, ierr);
+ serr << "Expected some number " << wq[i2].get_string() <<
+ " some number" << endl;
+ serr << "But did not find a number, instead found" << endl;
+ serr << wq[i1].get_string() << wq[i2].get_string() <<
+ wq[i3].get_string() << endl;
+ ierr = 2;
+ wres.set_value(0.);
+ return;
+ }
+
+
+ double d1 = wq[i1].get_double();
+ string op = wq[i2].get_string();
+ double d2 = wq[i3].get_double();
+
+ double result = 0.;
+
+ if (op == "+") result = d1 + d2;
+ if (op == "-") result = d1 - d2;
+ if (op == "*") result = d1 * d2;
+
+ if (op == "**") {
+ if (d1 == 0. && d2 >= 0.) {
+ wres.set_value(0.);
+ return;
+ }
+
+ if (d1 == 0. && d2 < 0.) {
+ wq[i2].fatal_error(serr, ierr);
+ serr << "Trying to exponentiate 0 to a negative power." << endl;
+ serr << "Base = " << d1 << " Exponent = " << d2 << endl;
+ ierr = 2;
+ wres.set_value(0.);
+ return;
+ }
+
+ if (d1 < 0. && !wq[i3].is_integer()) {
+ wq[i2].fatal_error(serr, ierr);
+ serr << "Trying to exponentiate a negative number to a non-integer power." << endl;
+ serr << "Base = " << d1 << " Exponent = " << d2 << endl;
+ ierr = 2;
+ wres.set_value(0.);
+ return;
+ }
+
+ result = pow(d1,d2);
+ }
+
+ if (op == "/") {
+ if (d2 == 0.) {
+ if (d1 == 0.) result = 0.;
+ else result = 1.e30;
+ wq[i2].fatal_error(serr, ierr);
+ serr << "Divide by 0." << endl;
+ serr << "Numerator = " << d1 << " Denominator = " << d2 << endl;
+ ierr = 2;
+ wres.set_value(result);
+ return;
+ }
+ result = d1 / d2;
+ }
+
+ // Do not implement the % operator, it is too much like the fortran %
+ // operator which is for referencing components of a fortran structure.
+ /*
+ if (op == "%") {
+ if (d2 == 0.) {
+ result = 0.;
+ wq[i2].fatal_error(serr, ierr);
+ serr << "Modulus (%) second argument is 0." << endl;
+ serr << "First arg = " << d1 << " second arg = " << d2 << endl;
+ ierr = 2;
+ wres.set_value(result);
+ return;
+ }
+ result = ((int)d1) % ((int)d2);
+ }
+ */
+
+ wres.set_value(result);
+}
+
+
+// ===========================================================================
+// Do a single relational binary operation involving 3 words.
+// Relational operators include .eq., .ne., .le., ...
+// The result is either true or false and is put in word wres.
+// ===========================================================================
+void Parser_math::do_op_relational(int i1, int i2, int i3, deque <Word> &wq,
+ Word &wres, stringstream &serr, int &ierr)
+{
+ string s1 = wq[i1].get_string();
+ string op = wq[i2].get_string();
+ string s3 = wq[i3].get_string();
+ bool result = false;
+
+ //cout << "&&&&&cw op = " << s1 << op << s3 << endl;
+
+ if ((wq[i1].is_bool()) && (wq[i3].is_bool())) {
+ if (op == ".gt." || op == ".ge." || op == ".lt." || op == ".le.") {
+ wq[i2].fatal_error(serr, ierr);
+ serr << "Does not make sense to compare logical values" << endl;
+ serr << " with greater than or less than" << endl;
+ serr << " " << s1 << " " << op << " " << s3 << endl;
+ ierr = 2;
+ wres.set_value(false);
+ return;
+ }
+ }
+
+ if ( ((wq[i1].is_bool()) && (!wq[i3].is_bool())) ||
+ ((!wq[i1].is_bool()) && (wq[i3].is_bool()))
+ ) {
+ wq[i2].fatal_error(serr, ierr);
+ serr << "Does not make sense to compare logical and" << endl;
+ serr << " non-logical values" << endl;
+ serr << " " << s1 << " " << op << " " << s3 << endl;
+ ierr = 2;
+ wres.set_value(false);
+ return;
+ }
+
+ if ( ((wq[i1].is_number()) && (!wq[i3].is_number())) ||
+ ((!wq[i1].is_number()) && (wq[i3].is_number()))
+ ) {
+ wq[i2].fatal_error(serr, ierr);
+ serr << "Does not make sense to compare numerical and" << endl;
+ serr << " non-numerical values" << endl;
+ serr << " " << s1 << " " << op << " " << s3 << endl;
+ ierr = 2;
+ wres.set_value(false);
+ return;
+ }
+
+ // Compare two numbers.
+ if ( (wq[i1].is_number()) && (wq[i3].is_number()) ) {
+ double d1 = wq[i1].get_double();
+ double d3 = wq[i3].get_double();
+ if (op == ".gt.") result = d1 > d3;
+ if (op == ".ge.") result = d1 >= d3;
+ if (op == ".lt.") result = d1 < d3;
+ if (op == ".le.") result = d1 <= d3;
+ if (op == ".eq.") result = d1 == d3;
+ if (op == ".ne.") result = d1 != d3;
+ //cout << "&&&&&cw relational result = " << result << endl;
+ wres.set_value(result);
+ return;
+ }
+
+ if ( (wq[i1].is_bool()) && (wq[i3].is_bool()) ) {
+ bool b1 = wq[i1].get_bool(serr, ierr);
+ bool b3 = wq[i3].get_bool(serr, ierr);
+ if (op == ".eq.") result = b1 == b3;
+ if (op == ".ne.") result = b1 != b3;
+ //cout << "&&&&&cw relational result = " << result << endl;
+ wres.set_value(result);
+ return;
+ }
+
+ // Compare two strings.
+ if (op == ".gt.") result = s1 > s3;
+ if (op == ".ge.") result = s1 >= s3;
+ if (op == ".lt.") result = s1 < s3;
+ if (op == ".le.") result = s1 <= s3;
+ if (op == ".eq.") result = s1 == s3;
+ if (op == ".ne.") result = s1 != s3;
+ wres.set_value(result);
+ return;
+}
+
+// ===========================================================================
+// Do the .not. operation, this is different from all the others in that
+// .not. is a unary operator, the others are binary ops.
+// The result is either true or false and is put in word wres.
+// ===========================================================================
+void Parser_math::do_op_not(int i2, int i3, deque <Word> &wq,
+ Word &wres, stringstream &serr, int &ierr)
+{
+ string op = wq[i2].get_string();
+ string s3 = wq[i3].get_string();
+ bool result = false;
+
+ if (!wq[i3].is_bool()) {
+ wq[i2].fatal_error(serr, ierr);
+ serr << "The word following the .not. operator must be"
+ " true or false." << endl;
+ serr << "Instead the word following .not. is " << s3 << endl;
+ ierr = 2;
+ wres.set_value(false);
+ return;
+ }
+
+ result = true;
+ if (wq[i3].get_bool(serr, ierr) == true) result = false;
+ wres.set_value(result);
+ return;
+}
+
+
+// ===========================================================================
+// Do a single logical binary operation involving 3 words.
+// The binary logical operators are .and. and .or.
+// The result is either true or false and is put in word wres.
+// ===========================================================================
+void Parser_math::do_op_logical(int i1, int i2, int i3, deque <Word> &wq,
+ Word &wres, stringstream &serr, int &ierr)
+{
+ string s1 = wq[i1].get_string();
+ string op = wq[i2].get_string();
+ string s3 = wq[i3].get_string();
+ bool result = false;
+
+ //cout << "&&&&&cw logical = " << s1 << op << s3 << endl;
+
+ // For .and. and .or., both operands must be boolean.
+ if ((!wq[i1].is_bool()) || (!wq[i3].is_bool())) {
+ wq[i2].fatal_error(serr, ierr);
+ serr << "The operator is " << op << endl;
+ serr << "The two operands (on the left and right of the operator)" << endl;
+ serr << "must be logical values (true or false)." << endl;
+ serr << " " << s1 << " " << op << " " << s3 << endl;
+ ierr = 2;
+ wres.set_value(false);
+ return;
+ }
+
+ bool b1 = wq[i1].get_bool(serr, ierr);
+ bool b3 = wq[i3].get_bool(serr, ierr);
+ if (op == ".and.") result = b1 && b3;
+ if (op == ".or.") result = b1 || b3;
+ //cout << "&&&&&cw logical result = " << result << endl;
+ wres.set_value(result);
+ return;
+}
+
+
+
+} // End of the PP namespace
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Parser_math.hh
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Parser_math.hh?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Parser_math.hh (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Parser_math.hh Sun Sep 3 20:10:18 2017
@@ -0,0 +1,85 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+#ifndef PARSERMATHHHINCLUDE
+#define PARSERMATHHHINCLUDE
+
+// ***************************************************************************
+// ***************************************************************************
+// This class collects various parser math functions.
+// There are two reasons to have this class:
+// 1. To keep the command processing class from getting too big.
+// 2. Some of these functions are used in more than one class.
+// ***************************************************************************
+// ***************************************************************************
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <deque>
+
+namespace PP
+{
+using std::string;
+using std::stringstream;
+using std::vector;
+using std::deque;
+
+
+class Parser_math
+{
+
+public:
+ Parser_math();
+
+ void do_op(int i1, int i2, int i3, deque <Word> &wq, Word &wres,
+ stringstream &serr, int &ierr);
+ void do_op_relational(int i1, int i2, int i3, deque <Word> &wq,
+ Word &wres, stringstream &serr, int &ierr);
+ void do_op_logical(int i1, int i2, int i3, deque <Word> &wq,
+ Word &wres, stringstream &serr, int &ierr);
+ void do_op_not(int i2, int i3, deque <Word> &wq,
+ Word &wres, stringstream &serr, int &ierr);
+
+
+private:
+
+};
+
+
+} // End of the PP namespace
+
+#endif
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Parser_utils.cc
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Parser_utils.cc?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Parser_utils.cc (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Parser_utils.cc Sun Sep 3 20:10:18 2017
@@ -0,0 +1,329 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+// ***************************************************************************
+// ***************************************************************************
+// This class collects various low level utilities for the parser.
+// ***************************************************************************
+// ***************************************************************************
+
+#include <iostream>
+#include <iomanip>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <deque>
+
+#include "Parser_utils.hh"
+
+namespace PP
+{
+using std:: string;
+using std::cout;
+using std::endl;
+using std::stringstream;
+using std::setprecision;
+using std::vector;
+using std::deque;
+using std::setw;
+
+static int index_base = 1; // For Fortran, 0 for C/C++style
+
+
+// ===========================================================================
+// Default constructor.
+// ===========================================================================
+Parser_utils::Parser_utils(int base)
+{
+ index_base = base;
+}
+
+
+// ===========================================================================
+// Given an array command like
+// cmd(5,3) = 1.0, 3.0, -5.0
+// find the starting position in a 1d array.
+//
+// The indices in cmd are referenced from 1 (i.e. fortran) while the 1d array
+// is referenced from 0 (C++).
+//
+// This function works for any dimension array, 0,1,2,3,...
+//
+// Example 1: Consider a 1d command
+// cmd(5) = 1.0, 3.4
+// We start filling the 1d fortran array at position 5 and put in two values.
+// Subtract 1 to reference from 0, so this function returns 4.
+//
+// Example 2: Consider the 2d command above:
+// cmd(5,3) = 1.0, 3.0, -5.0
+// We also need to know that the max size of the first dimension is say 7.
+// Since in fortran, the first index varies fastest, the fortran 1d index
+// would be
+// 5 + (3-1)*7 = 19
+// Subtract 1 to reference from 0, thus the return value is 18.
+//
+// The istart vector contains the indices, for example 2 this would be 5 and
+// 3. The size vector contains the max size of each dimension, for example 2
+// this would be 7 and whatever for the second dimension.
+// ===========================================================================
+int Parser_utils::start_dex(vector<int> &istart, const vector<int> &size)
+{
+ // Get the array dimension, 0,1,2,3,...
+ int dim = (int)istart.size();
+
+ // 0d is a special case.
+ if (dim == 0) return 0;
+
+ // Find the index.
+ // Adjustment for base 1
+ int ix = istart[0]-index_base;
+ for (int i=1; i<dim; i++) {
+ int t = istart[i]-index_base;
+ for (int j=0; j<i; j++) {
+ t *= size[j];
+ }
+ ix += t;
+ }
+
+ return ix;
+}
+
+
+// ===========================================================================
+// This is the reverse of the start_dex function above.
+// Given the 1d index, icdex (from 0 to nvals-1), find the corresponding
+// multi dimensional fortran indices (each starting from 1).
+//
+// Example 1: Consider a 1d array
+// var1d(1) = 1 3 5 9 -4 -5 6
+// Suppose the user inputs icdex=3, corresponding to array value 9.
+// This 1d case is very simple, all we do is add 1 to icdex to get a reference
+// from 1, thus returning 4.
+//
+// Example 1: Consider a 2d array
+// $var2d(1,1) = 11. 21. 31. 12. 22. 32. 13. 23. 33.
+// Where the max of the first dimension is 3. Suppose the user specifies
+// icdex = 5, this corresponds to array value 32. The two indices returned
+// would be 3,2 (referenced from 1).
+//
+// The istart vector contains the output indices, for example 2 this would be 3
+// and 2. The size vector contains the max size of each dimension, for example
+// 2 this would be 3 and whatever for the second dimension. The number of
+// elements in size is normally dim-1, but it does not hurt if it has dim
+// elements (in which case the last element is not referenced or used).
+// ===========================================================================
+void Parser_utils::reverse_dex(int icdex,
+ int nvals,
+ vector<int> &istart,
+ const vector<int> &size)
+{
+ // Get the dimension.
+ int dim = (int)istart.size();
+
+ // Nothing to do for scalars.
+ if (dim == 0) return;
+
+ // Start at 1,1,1,1,1,1,...
+ for (int i=0; i<dim; i++) {
+ istart[i] = index_base;
+ }
+
+ // Get the first 1d index (referenced from 0)
+ int i1 = start_dex(istart, size);
+ if (i1 == icdex) return;
+
+ // Go through all indices until the desired one is found.
+ // Yes, this is inefficient, but dim is a small integer, like 2,3,4, so
+ // the efficiency does not really matter.
+ // Perhaps somebody can devise a better algorithm someday.
+ for (int i1dex=0; i1dex<nvals; i1dex++) {
+ for (int i=0; i<dim; i++) {
+ if (i < dim-1) {
+ if (istart[i] == size[i]) {
+ istart[i] = index_base;
+ }
+ else {
+ istart[i] += 1;
+ break;
+ }
+ }
+ else {
+ istart[i] += 1;
+ break;
+ }
+ }
+
+ i1 = start_dex(istart, size);
+ if (i1 == icdex) return;
+ }
+}
+
+
+
+// ***************************************************************************
+// ***************************************************************************
+// Utilities for printing to the screen (or to a file).
+// ***************************************************************************
+// ***************************************************************************
+
+
+
+// ===========================================================================
+
+
+// Line
+// Filename Number Command
+// ------------ ------ ------------------------------------------------
+// test.in 4 some_logical_cmd = false
+// test.in 28 some_logical_cmd = false
+// test.in 170 some_logical_cmd = false
+// test.in 175 some_logical_cmd = true //No space betwe ...
+// test_inc1.in 2 some_logical_cmd = true
+// test_inc3.in 2 some_logical_cmd = true
+//
+// test.in 442 strinsert_cmd01 = "test duplicates commands"
+// test.in 456 strinsert_cmd01 = "test duplicates commands"
+
+
+
+// Given a header row of strings and several data rows of string where each
+// row consists of the same number of columns, list all the rows with the
+// columns lined up and the headers centered on the columns.
+// ===========================================================================
+void Parser_utils::print_strings(vector< vector<string> > rows, int n_header_rows,
+ int offset, int col_spacing, int line_len_max,
+ stringstream &ss)
+{
+ // Get the number of columns.
+ int ncol = (int)rows[0].size();
+
+ // Find the max number of characters in each column for all the rows.
+ vector<int> maxc(ncol, 0);
+ for (int row=0; row<(int)rows.size(); row++) {
+ for (int c=0; c<ncol; c++) {
+ string s = rows[row][c];
+ if ((int)s.size() > maxc[c]) maxc[c] = (int)s.size();
+ }
+ }
+
+ // Find the column widths.
+ vector<int> col_width(ncol,0);
+ for (int c=0; c<ncol; c++) {
+ if (maxc[c] > col_width[c]) col_width[c] = maxc[c];
+ }
+
+ // Spacing between columns.
+ vector<int> cspace(ncol, col_spacing);
+ cspace[0] = offset;
+
+ // Limit the lines to a max length.
+ if (line_len_max > 0) {
+ int line_len = 0;
+ for (int c=0; c<ncol; c++) {
+ line_len += cspace[c] + col_width[c];
+ }
+ int excess_c = line_len - line_len_max;
+
+ if (excess_c > 0) {
+ col_width[ncol-1] -= excess_c;
+ for (int row=0; row<(int)rows.size(); row++) {
+ int len = 0;
+ for (int c=0; c<ncol; c++) {
+ string s = rows[row][c];
+ if (c < ncol-1) len += cspace[c] + col_width[c];
+ if (c == ncol-1) len += cspace[c] + (int)s.size();
+ }
+ if (len <= line_len_max) continue;
+
+ int c = ncol -1;
+ string s = rows[row][c];
+ int ec = len - line_len_max;
+ int start = (int)s.size() - ec - 4;
+ if (start < 0) start = 0;
+ int nc = ec+4;
+ if (nc > (int)s.size()) nc = (int)s.size();
+ s.erase(start, nc);
+ rows[row][c] = s + " ...";
+ }
+ }
+ }
+
+
+ // Write the rows.
+ for (int row=0; row<(int)rows.size(); row++) {
+
+ // Insert the line of dashes after the header rows.
+ if (row == n_header_rows) {
+ for (int c=0; c<ncol; c++) {
+ for (int i=0; i<cspace[c]; i++) ss << " ";
+ for (int i=0; i<col_width[c]; i++) ss << "-";
+ }
+ ss << endl;
+ }
+
+ for (int c=0; c<ncol; c++) {
+ // Use nc to center the headers, but not center the data.
+ int nc = maxc[c];
+ if (row < n_header_rows) nc = (int)rows[row][c].size();
+
+ int nsp_left = 0;
+ int nsp_right = 0;
+ int dsp = col_width[c] - nc;
+ if (dsp > 0) {
+ nsp_left = dsp/2;
+ nsp_right = col_width[c] - nsp_left - nc;
+ }
+ for (int i=0; i<cspace[c]; i++) ss << " ";
+ for (int i=0; i<nsp_left; i++) ss << " ";
+
+
+ if (row >= n_header_rows) {
+ if (c < ncol-1) ss << setw(maxc[c]) << rows[row][c];
+ if (c == ncol-1) ss << rows[row][c];
+ }
+ else {
+ ss << rows[row][c];
+ }
+
+ for (int i=0; i<nsp_right; i++) ss << " ";
+ }
+ ss << endl;
+ }
+}
+
+
+
+} // End of the PP namespace
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Parser_utils.hh
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Parser_utils.hh?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Parser_utils.hh (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Parser_utils.hh Sun Sep 3 20:10:18 2017
@@ -0,0 +1,80 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+#ifndef PARSERUTILSHHINCLUDE
+#define PARSERUTILSHHINCLUDE
+
+// ***************************************************************************
+// ***************************************************************************
+// This class collects various low level utilities for the parser.
+// ***************************************************************************
+// ***************************************************************************
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <deque>
+
+namespace PP
+{
+using std::string;
+using std::stringstream;
+using std::vector;
+using std::deque;
+
+
+class Parser_utils
+{
+
+public:
+ Parser_utils(int base);
+
+ int start_dex(vector<int> &istart, const vector<int> &size);
+ void reverse_dex(int icdex, int nvals, vector<int> &istart,
+ const vector<int> &size);
+
+ void print_strings(vector< vector<string> > rows, int n_header_rows,
+ int offset, int col_spacing, int line_len_max,
+ stringstream &ss);
+
+private:
+
+};
+
+
+} // End of the PP namespace
+
+#endif
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/PowerParser.cc
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/PowerParser.cc?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/PowerParser.cc (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/PowerParser.cc Sun Sep 3 20:10:18 2017
@@ -0,0 +1,3269 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+// ***************************************************************************
+// ***************************************************************************
+// Provide a class that parses text files into lines and words.
+// ***************************************************************************
+// ***************************************************************************
+
+#include "PowerParser.hh"
+#include "Parser_utils.hh"
+#include "Variable.hh"
+#include "Function.hh"
+#include <cctype>
+#include <cstdio>
+#include <unistd.h>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <limits>
+#include <algorithm>
+#include <stdint.h>
+#include <string.h>
+#include <cstdlib>
+#include <assert.h>
+
+namespace PP
+{
+using std::cout;
+using std::endl;
+using std::string;
+using std::ifstream;
+using std::ios;
+using std::deque;
+using std::map;
+using std::pair;
+using std::vector;
+using std::stringstream;
+using std::setw;
+using std::setprecision;
+using std::numeric_limits;
+
+static int index_base = 1;
+static bool case_sensitive = false;
+
+// ===========================================================================
+// Various constructors.
+// ===========================================================================
+PowerParser::PowerParser()
+{
+ comm = new Comm();
+
+ init(); // Init vars, setup functions, ...
+ nrb_on_dump = 0;
+ coutbuf = NULL;
+}
+
+PowerParser::PowerParser(string filename)
+{
+ comm = new Comm();
+
+ init(); // Init vars, setup functions, ...
+ nrb_on_dump = 0;
+ parse_file(filename); // Parse the file.
+ coutbuf = NULL;
+}
+
+PowerParser::PowerParser(const char *filename)
+{
+ comm = new Comm();
+
+ string fstring(filename);
+
+ init(); // Init vars, setup functions, ...
+ nrb_on_dump = 0;
+ parse_file(fstring); // Parse the file.
+ coutbuf = NULL;
+}
+
+// ===========================================================================
+// Destructor
+// ===========================================================================
+PowerParser::~PowerParser()
+{
+ fileout.close();
+ if (coutbuf != NULL) cout.rdbuf(coutbuf); // restore cout's original streambuf
+ delete comm;
+
+ cmd_strings.clear();
+ vmap.clear();
+ fmap.clear();
+ cmds.clear();
+ cmdsf.clear();
+ whenthens.clear();
+ restartblocks.clear();
+ pre_defined_varss.str("");
+}
+
+// ===========================================================================
+// Parse a file. The basic strategy is to read the file into a string on the
+// io processor, broadcast the string to all the other processors, then parse
+// the string.
+// ===========================================================================
+void PowerParser::parse_file(string filename)
+{
+ // Read the file into a string. This simply copies every character in
+ // the file to the string including end of line characters.
+ // Note that only the io processor reads the file into the string.
+ string s_in = "";
+ read_into_string(filename, s_in);
+
+ // Broadcast the buffer string to all the other processors. After this
+ // braodcast, all the processors should have the same buffer string.
+ broadcast_buffer(s_in);
+
+ // Parse the string. After this is done, the parser is ready to be used
+ // by the application code.
+ parse_string(filename, s_in);
+}
+
+void PowerParser::parse_file(const char *filename)
+{
+ string fstring(filename);
+ parse_file(fstring);
+}
+
+int PowerParser::NumIncludeFiles()
+{
+ return IncludeFiles.size();
+}
+
+string PowerParser::GetIncludeFile(int i)
+{
+ if (0 <= i && i < IncludeFiles.size()) return IncludeFiles[i];
+ return string("");
+}
+
+void PowerParser::ListIncludeFiles()
+{
+ int i, num_include;
+ num_include = NumIncludeFiles();
+ std::cerr << "Number of include files = " << num_include << "\n";
+ for (i = 0; i < num_include; ++i)
+ {
+ std::cerr << "Include file << "<< i << " = " << GetIncludeFile(i) << "\n";
+ }
+}
+
+// ===========================================================================
+// Given a multi-line string on every processor, parse it into cmds and words.
+// After calling this function, the parser is ready for use.
+// ===========================================================================
+void PowerParser::parse_string(string filename, string buffer)
+{
+ // Get command lines from the buffer and store them as strings.
+ int current_pos = 0;
+ string sline1 = "";
+ string sline = "";
+ int file_line_number = 0;
+ bool exe_args_inserted = false;
+ for (;;) {
+ // Get the next line from the buffer. No processing is done, just
+ // get each line. This does, however, remove the end of line
+ // characters (either \r\n or only \n) from the string.
+ if (!get_line_from_string(buffer, sline1, current_pos)) break;
+ line_number += 1;
+ file_line_number += 1;
+
+ // Store the line without any processing. This is done so that a
+ // fortran routine can get each original line and echo it to an
+ // output file.
+ cmd_strings.push_back(sline1);
+
+ // The line, sline1, may be composed of sub-lines separated by
+ // semicolons. Loop through the line extracting each semicolon
+ // separated sub-line and process it.
+ int current_sc_pos = 0;
+ for (;;) {
+ if (!get_sc_line_from_string(sline1, sline, current_sc_pos)) break;
+
+ // Flag for making the command or not.
+ bool make_cmd = true;
+
+ // Get rid of leading and trailing blanks and tabs.
+ eliminate_white_space(sline);
+
+ // If after removing white space, the resulting line string is empty,
+ // then do not turn it into a command.
+ if ((int)sline.size() == 0) make_cmd = false;
+
+ // Turn the line into a command. This creates the words. Empty lines
+ // can be skipped.
+ if (make_cmd) {
+ stringstream serr;
+ int ierr = 0;
+ Cmd cmd(sline, &vmap, &fmap, &cmd_strings,
+ line_number, file_line_number, filename, serr, ierr);
+ process_error(serr, ierr);
+ if (cmd.get_string(0) == "set_index_base_zero") {
+ // C/C++ index convention
+ cmd.set_index_base(0);
+ Variable v(0);
+ index_base = 0;
+ }
+ if (cmd.get_string(0) == "set_index_base_one") {
+ // Fortran index convention
+ cmd.set_index_base(1);
+ Variable v(1);
+ index_base = 1;
+ }
+ if (cmd.get_string(0) == "set_case_sensitive") {
+ cmd.set_case_sensitive(true);
+ case_sensitive = true;
+ }
+ if (cmd.get_string(0) == "set_case_insensitive") {
+ cmd.set_case_sensitive(false);
+ case_sensitive = false;
+ }
+ if (cmd.get_string(0) == "put_exe_args_here") {
+ if (exe_args_str != "") {
+ parse_string("execution line arguments", exe_args_str);
+ exe_args_inserted = true;
+ }
+ }
+ else if (cmd.is_include()) {
+ string fname = "";
+ stringstream ssfiles;
+ if(comm->isIOProc()) {
+ fname = cmd.get_cmd_filename(ssfiles);
+ }
+ broadcast_buffer(fname);
+ map<int,string>::iterator ifp;
+ int isize = IncludeFiles.size();
+ IncludeFiles[isize] = fname;
+ if (fname == "") {
+ stringstream serr;
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_line_number << ":" << endl;
+ serr << " " << cmd_strings[line_number-1] << endl;
+ serr << "in file: " << filename << endl;
+ serr << "Could not open include file." << endl;
+ serr << "The name of the file and any alternates are:" << endl;
+ serr << ssfiles.str() << endl;
+ int ierr = 2;
+ process_error(serr, ierr);
+ return;
+ }
+ parse_file(fname);
+ }
+ else {
+ cmds.push_back(cmd);
+ }
+ }
+ }
+ }
+ // process inserted command line args if not parsing just the args
+ if (filename != "execution line arguments" &&
+ filename != "exe_args_tmp" &&
+ exe_args_str != "") {
+ // if inserting manually, remove the tmp insertion at the beginning
+ if (exe_args_inserted) {
+ for (int i=0; i<(int)cmds.size(); i++) {
+ if (cmds[i].get_filename() == "exe_args_tmp") {
+ cmds.erase(cmds.begin()+i);
+ i -= 1;
+ }
+ }
+ }
+ // change the file name to the real name for args
+ else {
+ for (int i=0; i<(int)cmds.size(); i++) {
+ if (cmds[i].get_filename() == "exe_args_tmp") {
+ cmds[i].set_filename("execution line arguments");
+ }
+ }
+ }
+ }
+}
+
+
+// ===========================================================================
+// Handle the execution line arguments.
+// ===========================================================================
+void PowerParser::handle_exe_args(string other_args)
+{
+ if ((int)other_args.size() == 0) return;
+
+ stringstream serr;
+ int ierr = 0;
+ Cmd cmd(other_args, &vmap, &fmap, &cmd_strings,
+ 1, 1, "", serr, ierr);
+ process_error(serr, ierr);
+ //print_line(cmd);
+ exe_args_str = "";
+ cmd.handle_exe_args(exe_args_str);
+ if (cmd.get_nwords() == 0) {
+ exe_args_str = "";
+ return;
+ }
+ parse_string("exe_args_tmp", exe_args_str);
+}
+
+
+// ===========================================================================
+// Clear out the parser and re-init.
+// ===========================================================================
+void PowerParser::clear_and_init()
+{
+ // comm does not need to be reset
+ cmd_strings.clear();
+ vmap.clear();
+ fmap.clear();
+ cmds.clear();
+ cmdsf.clear();
+ whenthens.clear();
+ restartblocks.clear();
+ pre_defined_varss.str("");
+
+ // Do not clear out the restart block info from the dump since the whole
+ // point of doing this function is to be able to reset the parser with
+ // the restart block info from the dump.
+
+ //for (int i=0; i<(int)bnames_on_dump.size(); i++) {
+ // cout << "&&&&&cw PowerParser.cc, clear_and_init, bnames_on_dump = " <<
+ // bnames_on_dump[i] << endl;
+ // cout << "&&&&&cw PowerParser.cc, clear_and_init, baflags_on_dump = " <<
+ // baflags_on_dump[i] << endl;
+ //}
+
+ // Do the initialization again.
+ init();
+}
+
+// ===========================================================================
+// Echo user input to a stringstream.
+// ===========================================================================
+void PowerParser::echo_input_start()
+{
+ ssfout.str("");
+ echo_input_ss(ssfout);
+ ssfout_current_pos = 0;
+}
+void PowerParser::echo_input_ss(stringstream &ssinp)
+{
+ if (!comm->isIOProc()) return;
+ for (int i=0; i<(int)cmd_strings.size(); i++) {
+ ssinp << cmd_strings[i] << endl;
+ }
+}
+
+
+// ===========================================================================
+// The input file(s) has been read and put into commands. Now do the
+// compilation phase.
+// ===========================================================================
+void PowerParser::compile_buffer(int &return_value)
+{
+ // At this point, the list of variables only contains the pre-defined
+ // parser variables, thus if we list the variables at this point we will
+ // have a list of only the pre-defined variables. This is stored in a
+ // stringstream to be printed later.
+ string lv1 = "********** List of pre-defined parser variables";
+ string lv2 = "********** End list of pre-defined parser variables";
+ list_vars_ss(lv1, lv2, "", pre_defined_varss);
+
+ int return_local;
+
+ return_local =-1;
+ return_value = 0;
+
+ // Handle single line (! and //) comments and multi line
+ // comments (/* ... */)
+ // The level variable is used for nested multi line comments.
+ int level = 0;
+ for (int i=0; i<(int)cmds.size(); i++) {
+ cmds[i].single_line_comments();
+ cmds[i].multi_line_comments(level);
+ }
+
+ // Check for matching quotes and remove them.
+ int ierr = 0;
+ stringstream serr;
+ for (int i=0; i<(int)cmds.size(); i++) {
+ cmds[i].handle_quotes(serr, ierr);
+ }
+ return_local = process_error_return_int(serr, ierr);
+ return_value = return_local;
+
+ if (return_local > 0) {
+ cout << "handle quotes gave error " << ierr << endl;
+ if (return_local > 1) return;
+ }
+
+ // Remove empty lines.
+ for (int i=0; i<(int)cmds.size(); i++) {
+ if (cmds[i].get_nwords() == 0) {
+ cmds.erase(cmds.begin()+i);
+ i -= 1;
+ continue;
+ }
+ }
+
+ // Handle continuation lines (ending in & or ,).
+ // Continuation lines are merged into one long (possibly very long)
+ // line.
+ for (int i=(int)cmds.size()-1; i>=0; i--) {
+ int nw1 = cmds[i].get_nwords();
+ if (cmds[i].get_string(nw1-1) == "&" ||
+ cmds[i].get_string(nw1-1) == ",") {
+ if (cmds[i].get_string(nw1-1) == "&")
+ cmds[i].erase_word(nw1-1);
+ int nw2 = cmds[i+1].get_nwords();
+ for (int j=0; j<nw2; j++) {
+ cmds[i].add_word(cmds[i+1].get_string(j),
+ cmds[i+1].get_line_number(j),
+ cmds[i+1].get_file_line_number(j),
+ cmds[i+1].get_filename(j)
+ );
+ }
+ cmds.erase(cmds.begin()+i+1);
+ continue;
+ }
+ }
+
+
+ // Reset the command name and type. Consider the following command:
+ // * lasdkj */ cmd = 5.0
+ // The original command name is "*", but after the multi-line comment is
+ // removed, the command name should be "cmd".
+ for (int i=0; i<(int)cmds.size(); i++) {
+ cmds[i].reset_name_type();
+ }
+
+
+ // Debug: print each command.
+ //for (int i=0; i<(int)cmds.size(); i++) {
+ //stringstream ss3;
+ //cmds[i].print_all_words(ss3);
+ //cmds[i].print_using_words(ss3);
+ //cmds[i].print_original_string(ss3);
+ //cout << ss3.str() << endl;
+
+ //cout << "Command name = " << cmds[i].get_cmd_name() << endl;
+ //cout << "Command type = " << cmds[i].get_cmd_type() << endl;
+ //}
+ //cout << endl;
+
+ // Handle all the variable dimension statements.
+ ierr = 0;
+ serr.str("");
+ for (int i=0; i<(int)cmds.size(); i++) {
+ if (cmds[i].check_for_dimension(serr, ierr)) {
+ cmds.erase(cmds.begin()+i);
+ i--;
+ continue;
+ }
+ }
+ return_local = process_error_return_int(serr, ierr);
+
+ if (return_local > 0) {
+ cout << "handle variable dimension statement has error " << ierr << endl;
+ if (return_local > 1) return;
+ }
+
+ // Combine things like "end if" into one word, i.e. "endif".
+ for (int i=0; i<(int)cmds.size(); i++) {
+ cmds[i].handle_two_words();
+ }
+
+ // Handle the case of a space between digits and the e for reals.
+ // For example, in the following,
+ // 1.0, 2.3 e14, -5.6
+ // there is a space between 2.3 and e14 which should most likely
+ // be treated as a single number, 2.3e14.
+ ierr = 0;
+ serr.str("");
+ string action = "error";
+ bool action_set = false;
+ for (int i=0; i<(int)cmds.size(); i++) {
+ if (cmds[i].get_cmd_name() == "depcmd_dse") {
+ action = cmds[i].get_string(1);
+ action_set = true;
+ cmds.erase(cmds.begin()+i);
+ i--;
+ continue;
+ }
+ if (cmds[i].get_cmd_name() == "matdef") {
+ if (!action_set) action = "fix";
+ }
+ cmds[i].deprecated_input01(action, serr, ierr);
+ }
+
+ return_local = process_error_return_int(serr, ierr);
+ return_value = return_local;
+ if (return_local > 0) {
+ cout << "handle space between digits has error " << ierr << endl;
+ if (return_local > 1) return;
+ }
+
+
+ // This is the main loop where most everything is done.
+ bool print_final_buffer = false;
+ deque<bool> skip_level;
+ deque<bool> satisfied;
+ deque<int> do_start;
+ string sub_name = "";
+ deque<int> icall, isub;
+ bool skip_sub = false;
+ int nwhen = 0;
+ int when_level = 0;
+ bool single_line_when = false;
+ int nrb = 0; // Number of restart blocks
+ bool single_line_rb = false; // Flag for single line restart blocks
+ bool skiprb = false; // Flag for skipping cmds in restart block
+ for (int i=0; i<(int)cmds.size(); i++) {
+ // Work with cmdi, so that cmds will be available for do loops.
+ Cmd cmdi = cmds[i];
+ //print_line(cmdi);
+
+ if (cmdi.get_cmd_name() == "parser_redirect_to_file") {
+ string fname;
+ int nw = cmdi.get_nwords();
+ if (nw > 1) {
+ fname = cmdi.get_string(1);
+ } else {
+ fname = "parser.out";
+ }
+ if (comm->isIOProc()) {
+ //cout << "DEBUG fname is " << fname << endl;
+ //cout << "Redirecting output to file" << endl;
+ cout.flush();
+ coutbuf = cout.rdbuf();
+ fileout.open(fname.c_str());
+ cout.rdbuf(fileout.rdbuf());
+ //cout << "Start of output to file" << endl;
+ }
+
+ continue;
+ }
+
+ // Handle restart_block commands.
+ if (cmdi.get_string(0) == "restart_block") {
+ Restartblock rb(nrb, cmdi, skiprb, single_line_rb,
+ bnames_on_dump, baflags_on_dump,
+ rbsatprb_on_dump, rbsat_on_dump,
+ serr, ierr);
+ restartblocks.push_back(rb);
+
+ for (int rbi=0; rbi<(int)restartblocks.size(); rbi++) {
+ string rbi_name = restartblocks[rbi].get_name();
+ for (int rbj=rbi+1; rbj<(int)restartblocks.size(); rbj++) {
+ if (rbi_name == restartblocks[rbj].get_name()) {
+ cmdi.fatal_error(0, serr, ierr);
+ serr << "Restart block names must be unique." << endl;
+ serr << "Non unique name = " << rbi_name << endl;
+ ierr = 2;
+ }
+ }
+ }
+
+ if (single_line_rb && skiprb) {
+ skiprb = false;
+ continue;
+ }
+ bool cflag = true;
+ if (single_line_rb && !skiprb) cflag = false;
+ if (cflag) continue;
+ }
+ if (cmdi.get_string(0) == "end_restart_block") {
+ skiprb = false;
+ continue;
+ }
+ if (skiprb) continue;
+
+
+ if (skip_sub) {
+ if (cmdi.get_string(0) == "endsubroutine") {
+ skip_sub = false;
+ //cout << "endsubroutine found, turning skip_sub to false" << endl;
+ }
+ continue;
+ }
+
+ return_local = ierr;
+ return_value = return_local;
+ if (return_local > 0) {
+ if (return_local > 1) return;
+ }
+
+
+
+ // List variables, functions, etc.
+ if (cmdi.get_cmd_name() == "parser_list_variables") {
+ string lv1 = "********** Debugging: list variable names and values "
+ "available in input file.";
+ string lv2 = "********** Debugging END: list variable names and values";
+ string var_to_list = "";
+ int nw = cmdi.get_nwords();
+ if (nw > 1) var_to_list = cmdi.get_string(1);
+ if (comm->isIOProc()) cout << endl;
+ list_vars(lv1, lv2, var_to_list);
+ if (comm->isIOProc()) cout << endl;
+ continue;
+ }
+ if (cmdi.get_cmd_name() == "parser_list_functions") {
+ string lf1 = "********** Debugging: list function names available in input file.";
+ string lf2 = "********** Debugging END: list function names.";
+ if (comm->isIOProc()) cout << endl;
+ list_funcs(lf1, lf2);
+ if (comm->isIOProc()) cout << endl;
+ continue;
+ }
+ if (cmdi.get_cmd_name() == "parser_print_fbuffer") {
+ print_final_buffer = true;
+ continue;
+ }
+
+ // Handle when ... then commands.
+ string wtcmd = cmdi.get_string(0);
+ if (wtcmd == "when" || wtcmd == "whenever") {
+ bool skipwhen = true;
+ bool ever_flag = false;
+ if (wtcmd == "whenever") ever_flag = true;
+ Whenthen wt(nwhen, cmdi, skipwhen, single_line_when, ever_flag, serr, ierr);
+ when_level += 1;
+ whenthens.push_back(wt);
+ if (skipwhen) continue;
+ }
+ if (cmdi.get_string(0) == "endwhen") {
+ when_level -= 1;
+ if (when_level < 0) {
+ cmdi.fatal_error(0, serr, ierr);
+ serr << "Extra endwhen (or end when) found with no matching "
+ "when command." << endl;
+ serr << "Make sure every when command has one and only one"
+ << endl << "matching endwhen command." << endl;
+ ierr = 2;
+ }
+ return_local = ierr;
+ if (return_local > return_value) {
+ return_value = return_local;
+ }
+ if (return_local > 0) {
+ cout << "handle endwhen " << ierr << endl;
+ return;
+ }
+ continue;
+ }
+
+
+ // Handle if/elseif/else/endif statements.
+ bool skip = false;
+ cmdi.handle_if(skip, skip_level, satisfied, serr, ierr);
+ if (skip) continue;
+
+ // Handle do loops. Note that we terminate if there is an error to
+ // avoid the possibility of an infinite loop.
+ int cdex = i;
+ bool end_do = false;
+ int ierr2 = 0;
+ cmdi.handle_do(skip, do_start, cdex, end_do, serr, ierr2);
+ if (ierr2 == 2) {
+ ierr = 2;
+ return_local = ierr;
+ if (return_local > return_value) {
+ return_value = return_local;
+ }
+ if (return_local > 0) {
+ cout << "handle endwhen " << ierr << endl;
+ }
+ break;
+ }
+ if (end_do) {
+ if (!end_do_loop(i, do_start, serr, ierr)) break;
+ continue;
+ }
+ i = cdex;
+ if (skip) continue;
+
+ // Handle call/subroutines.
+ bool go_to_sub = false;
+ bool go_to_call = false;
+ cmdi.handle_subroutines(skip, go_to_sub, sub_name, go_to_call,
+ serr, ierr);
+ if (go_to_call) {
+ end_do_ret(i, do_start, serr, ierr);
+ return_local = jump_to_call(i, icall, isub, serr, ierr);
+ if (return_local > return_value) {
+ return_value = return_local;
+ }
+ if (return_local > 0) {
+ cout << "jump_to_call error " << ierr << endl;
+ }
+ continue;
+ }
+
+ if (go_to_sub) {
+ icall.push_back(i);
+ return_local = jump_to_sub(i, sub_name, serr, ierr);
+ isub.push_back(i);
+ if (return_local > return_value) {
+ return_value = return_local;
+ }
+ if (return_local > 0) {
+ cout << "jump_to_sub error " << ierr << endl;
+ }
+ continue;
+ }
+
+ if (cmdi.get_string(0) == "subroutine") {
+ //cout << "subroutine found!!!, turning skip_sub to true" << endl;
+ skip_sub = true;
+ continue;
+ }
+
+ // Check for a variable description command. If found we set the description,
+ // then go to the next line.
+ if (cmdi.check_for_var_description(serr, ierr)) continue;
+
+ // Stop if we hit a stop command or a fatal_error command
+ bool kill_run = false;
+ if (cmdi.check_input_end(kill_run, serr, ierr)) {
+ // Killing the calculation will be done, for example, if the user
+ // issues a fatal_error command.
+ if (kill_run) {
+ return_local = process_error_return_int(serr, ierr);
+ if (return_local > return_value) {
+ return_value = return_local;
+ }
+ if (return_local > 0) {
+ cout << "handle endwhen " << ierr << endl;
+ if (return_local > 1) return;
+ }
+ }
+
+ // Clear out all do's so we don't get an error about unmatched
+ // do/enddo.
+ do_start.clear();
+ break;
+ }
+
+ cmdi.math_eval(serr, ierr);
+ cmdi.substitute_variables(serr, ierr); // Sub vars not in math expressions.
+ cmdi.check_ppmm(serr, ierr); // All ++, -- should be gone.
+ cmdi.remove_commas();
+ cmdi.handle_cmd_unary_minus(serr, ierr);
+ cmdi.handle_cmd_unary_plus(serr, ierr);
+ cmdi.handle_cmd_multiplicity(serr, ierr);
+ cmdi.check_misplaced_math(serr, ierr);
+ cmdi.set_variables(serr, ierr);
+
+ // Copy the command to the final commands deque.
+ if (cmdi.get_cmd_type() == "command") {
+ if (when_level > 0) {
+ whenthens[nwhen-1].add_cmdf(cmdi);
+ if (single_line_when) {
+ when_level -= 1;
+ single_line_when = false;
+ }
+ }
+ else {
+ cmdsf.push_back(cmdi);
+ }
+ }
+ }
+ // Print error messages and terminate if fatal.
+ return_local = process_error_return_int(serr, ierr);
+ if (return_local > return_value) {
+ return_value = return_local;
+ }
+ if (return_local > 0) {
+ return_value = return_local;
+ if (return_local > 1) return;
+ }
+
+ // Check that an enddo was found for every do.
+ check_enddo(do_start, serr, ierr);
+
+ // Print error messages and terminate if fatal.
+ return_local = process_error_return_int(serr, ierr);
+ if (return_local > return_value) {
+ return_value = return_local;
+ }
+ if (return_local > 0) {
+ return_value = return_local;
+ if (comm->isIOProc()) {
+ cout << "handle enddo is wrong with err " << ierr << endl;
+ }
+ if (return_local > 1) return;
+ }
+
+ // Set the processed flag in every word in every command to be false.
+ // At the end of parsing, if any word has not been processed in some way,
+ // then that is a fatal error.
+ for (int i=0; i<(int)cmdsf.size(); i++) {
+ cmdsf[i].clear_processed();
+ }
+
+ // If this is a recreate of the parser, then there might be some commands
+ // that have already been processed, set these.
+ cmd_set_reprocessed(true);
+
+ // Check and print duplicate scalar commands.
+ // Remove duplicate scalar commands.
+ // Process the duplicate_array_values command.
+ return_local = process_dav_cmd();
+ if (return_local > return_value) {
+ return_value = return_local;
+ }
+ if (return_local > 0) {
+ if (comm->isIOProc()) {
+ cout << "Checked for duplicate arrays and error is " << return_local << endl;
+ }
+ }
+ //check_duplicates();
+
+ // Debug: print each of the final commands to the screen.
+ if (print_final_buffer) {
+ if (comm->isIOProc()) {
+ cout << "********************************************************************************\n"
+ << "********** Echo final parser buffer, this is what the code uses to set internal \n"
+ << "********** code variables." << endl;
+ list_cmdsf("", "");
+ cout << "********** End of echo final parser buffer.\n"
+ << "********************************************************************************\n\n"
+ << endl;
+
+ cout << "********************************************************************************\n"
+ << "********** Echo final when...then parser buffers, this is what the code uses to \n"
+ << "********** set internal code variables when processing when...then commands." << endl;
+ list_wt_cmdsf();
+ cout << "********** End of echo final when...then parser buffers.\n"
+ << "********************************************************************************\n\n"
+ << endl;
+
+ cout << "********************************************************************************\n"
+ << "********** Echo restart block information." << endl;
+ list_rb();
+ cout << "********** End of echo restart block information.\n"
+ << "********************************************************************************\n\n"
+ << endl;
+ }
+ }
+
+ // Return the to the calling program
+
+ return;
+}
+
+
+// ===========================================================================
+// A "endsubroutine" or "return" command has been found. Jump back to the call
+// statement. This sets the loop index i so that we end up on the line after
+// the call.
+// ===========================================================================
+int PowerParser::jump_to_call(int &i, deque<int> &icall, deque<int> &isub,
+ stringstream &serr, int &ierr)
+{
+ int return_value;
+ int return_local;
+ return_value = 0;
+ return_local = 0;
+
+ int icsize = (int)icall.size();
+ if (icsize == 0) {
+ cmds[i].fatal_error(0, serr, ierr);
+ serr << "icall size = 0, this should never happen." << endl;
+ ierr = 2;
+ return_value = process_error_return_int(serr, ierr);
+ if (return_local > return_value) {
+ return_value = return_local;
+ }
+ if (return_local > 0) {
+ cout << "jump_to_call icall error " << ierr << endl;
+ if (return_local > 1) return return_value;
+ }
+ }
+ i = icall[icsize-1];
+ icall.erase(icall.begin()+icsize-1);
+
+ vector<string> call_args;
+ vector<bool> call_args_isvar;
+ cmds[i].copy_call_args(call_args, call_args_isvar);
+ int idex_sub = isub[(int)isub.size()-1];
+ vector<string> sub_args;
+ vector<bool> sub_args_isvar;
+ cmds[idex_sub].copy_sub_args(sub_args, sub_args_isvar);
+ //cout << "jump_to_call, sub args, then call args" << endl;
+ //for (int j=0; j<(int)sub_args.size(); j++) {
+ // cout << sub_args[j] << endl;
+ //}
+ //for (int j=0; j<(int)call_args.size(); j++) {
+ // cout << call_args[j] << endl;
+ //}
+ //cout << "--------------------------------" << endl;
+
+ for (int j=0; j<(int)sub_args.size(); j++) {
+ string sub_var = sub_args[j];
+ string call_var = call_args[j];
+
+ map<string, Variable>::iterator psub;
+ psub = vmap.find(sub_var);
+ string sub_value = "";
+ if (psub != vmap.end()) {
+ sub_value = psub->second.get_var_value();
+ }
+ else {
+ cmds[i].fatal_error(0, serr, ierr);
+ serr << "Subroutine argument not found." << endl;
+ serr << "This should not happen." << endl;
+ ierr = 2;
+ return_value = process_error_return_int(serr, ierr);
+ if (return_local > return_value) {
+ return_value = return_local;
+ }
+ if (return_local > 0) {
+ cout << "jump_to_call Subroutine argument not found " << endl;
+ if (return_local > 1) return return_value;
+ }
+ }
+
+ if (!call_args_isvar[j]) {
+ if (sub_value != call_var) {
+ cmds[i].fatal_error(0, serr, ierr);
+ cmds[isub[(int)isub.size()-1]].fatal_error(0, serr, ierr);
+ serr << "The calling argument, argument number " << j+1
+ << ", (after any math eval) is " << call_var << endl;
+ serr << "The corrseponding subroutine dummy argument, "
+ << sub_var << ", has"
+ << " the value of " << sub_value << endl;
+ serr << "These are different and should not be." << endl;
+ serr << "The calling argument is not a variable and thus"
+ " is fixed and cannot be changed." << endl;
+ serr << "The dummy argument was changed in the subroutine," << endl;
+ serr << "thus you are trying to change a fixed quantity which"
+ " is not allowed." << endl;
+ ierr = 2;
+ return_value = process_error_return_int(serr, ierr);
+ if (return_local > return_value) {
+ return_value = return_local;
+ }
+ if (return_local > 0) {
+ cout << "jump_to_call subroutine arguments errors " << endl;
+ if (return_local > 1) return return_value;
+ }
+ }
+ }
+ else {
+ map<string, Variable>::iterator pcall;
+ pcall = vmap.find(call_var);
+ if (pcall != vmap.end()) {
+ pcall->second = psub->second;
+ pcall->second.set_temporary(false);
+ pcall->second.set_varname(call_var);
+ }
+ else {
+ cmds[i].fatal_error(0, serr, ierr);
+ serr << "Calling argument not found." << endl;
+ serr << "This should not happen." << endl;
+ ierr = 2;
+ return_value = process_error_return_int(serr, ierr);
+ if (return_local > return_value) {
+ return_value = return_local;
+ }
+ if (return_local > 0) {
+ cout << "jump_to_call calling argument not found " << endl;
+ if (return_local > 1) return return_value;
+ }
+ }
+ }
+
+ }
+
+ // Erase temporary variables.
+ // There should be a better way to do this.
+ map<string, Variable>::iterator p;
+ for (;;) {
+ bool erase_done = false;
+ for(p = vmap.begin(); p != vmap.end(); p++) {
+ if (p->second.is_temporary()) {
+ vmap.erase(p);
+ erase_done = true;
+ break;
+ }
+ }
+ if (!erase_done) break;
+ }
+
+ // Remove the index to the subroutine line.
+ isub.erase(isub.begin()+(int)isub.size()-1);
+
+ return return_value;
+
+} // End of jump_to_call
+
+
+// ===========================================================================
+// A "call" command has been found. Find the subroutine it is trying to call
+// and set the loop index, i, to the subroutine line so we will end up on the
+// line after the subroutine.
+// ===========================================================================
+int PowerParser::jump_to_sub(int &i, string &sub_name,
+ stringstream &serr, int &ierr)
+{
+ int return_value;
+ int return_local;
+ return_value = 0;
+ return_local = 0;
+
+ // At this point, i is the index for the call line.
+ //cout << "&&&&&cw PowerParser loop, jump_to_sub, i=" << i << endl;
+
+ // Find the line index, cdex, for the subroutine.
+ int cdex = -1;
+ for (int j=0; j<(int)cmds.size(); j++) {
+ if (cmds[j].find_subroutine(sub_name)) {
+ cdex = j;
+ break;
+ }
+ }
+
+ if (cdex == -1) {
+ cmds[i].fatal_error(0, serr, ierr);
+ serr << "Subroutine " << sub_name << " not found." << endl;
+ ierr = 2;
+ return_value = process_error_return_int(serr, ierr);
+ if (return_local > return_value) {
+ return_value = return_local;
+ }
+ if (return_local > 0) {
+ cout << "Subroutine name not found " << ierr << endl;
+ if (return_local > 1) return return_value;
+ }
+ }
+
+ // Get the calling arguments. This will potentially be a mix
+ // of variable names and numbers. This does not modify the words
+ // in cmds[i], but it does store the call arguments in cmds[i].
+ vector<string> call_args;
+ vector<bool> call_args_isvar;
+ cmds[i].get_call_args(call_args, call_args_isvar, serr, ierr);
+ //for (int j=0; j<(int)call_args.size(); j++) {
+ // cout << call_args[j] << endl;
+ //}
+
+ // Get the subroutine arguments.
+ // This does not modify the words in cmds[cdex], but it does store
+ // the subroutine arguments in cmds[cdex]
+ //print_line(cdex);
+ vector<string> sub_args;
+ vector<bool> sub_args_isvar;
+ cmds[cdex].get_sub_args(sub_args, sub_args_isvar);
+ //for (int j=0; j<(int)sub_args.size(); j++) {
+ // cout << sub_args[j] << endl;
+ //}
+
+ // Error checking.
+ int ncall_args = (int)call_args.size();
+ int nsub_args = (int)sub_args.size();
+ if (ncall_args != nsub_args) {
+ cmds[i].fatal_error(0, serr, ierr);
+ cmds[cdex].fatal_error(0, serr, ierr);
+ serr << "Number of calling arguments = " << ncall_args << endl;
+ serr << "Number of subroutine arguments = " << nsub_args << endl;
+ serr << "These must be the same." << endl;
+ ierr = 2;
+ return_local = process_error_return_int(serr, ierr);
+ if (return_local > return_value) {
+ return_value = return_local;
+ }
+ if (return_local > 0) {
+ cout << "Arguments in subroutine and in calling are different " << ierr << endl;
+ if (return_local > 1) return return_value;
+ }
+ }
+
+ for (int j=0; j<(int)sub_args.size(); j++) {
+ if (!sub_args_isvar[j]) {
+ cmds[cdex].fatal_error(0, serr, ierr);
+ serr << "Subroutine dummy arguments must always be variables." << endl;
+ serr << "Argument " << j+1 << ", " << sub_args[j] << ", "
+ << "is not a variable." << endl;
+ serr << "Remember that variables always begin with a"
+ " dollar sign, $" << endl;
+ serr << "Note that putting quotes around a variable name makes it" << endl;
+ serr << "a string, not a variable." << endl;
+ ierr = 2;
+ return_local = process_error_return_int(serr, ierr);
+ if (return_local > return_value) {
+ return_value = return_local;
+ }
+ if (return_local > 0) {
+ cout << "Dummy arguments must be variables " << ierr << endl;
+ if (return_local > 1) return return_value;
+ }
+ }
+ }
+
+
+ // Define new, temporary variables for the subroutine dummy arguments.
+ // Set their values to the call values.
+ for (int j=0; j<(int)sub_args.size(); j++) {
+ string sub_vname = sub_args[j];
+ string call_vname = call_args[j];
+
+ // Find the subroutine variable name in the variable map.
+ map<string, Variable>::iterator psub;
+ psub = vmap.find(sub_vname);
+
+ if (psub != vmap.end()) {
+ cmds[cdex].fatal_error(0, serr, ierr);
+ serr << "Argument " << j+1 << ", " << sub_args[j] << ", "
+ << "is both a global variable and a dummy subroutine argument." << endl;
+ serr << "This is not allowed, dummy subroutine arguments "
+ "cannot also be" << endl;
+ serr << "global variables." << endl;
+ ierr = 2;
+ return_local = process_error_return_int(serr, ierr);
+ if (return_local > return_value) {
+ return_value = return_local;
+ }
+ if (return_local > 0) {
+ cout << "Dummy argument cannot be global variable " << ierr << endl;
+ if (return_local > 1) return return_value;
+ }
+ }
+ else {
+ // If the calling argument is a variable, then we set the
+ // temporary variable equal to the calling variable. This passes
+ // in the correct value, but it also passes in arrays, and
+ // whatever characteristics the calling variable has.
+ //
+ // If the calling argument is not a variable, then we just
+ // create the new, temporary variable and give it the calling
+ // argument as its value.
+ if (call_args_isvar[j]) {
+ map<string, Variable>::iterator pcall;
+ pcall = vmap.find(call_vname);
+ if (pcall != vmap.end()) {
+ Variable v = pcall->second;
+ v.set_varname(sub_vname);
+ v.set_temporary(true);
+ vmap.insert(pair<string, Variable>(v.get_varname(), v));
+ }
+ else {
+ // FATAL ERROR
+ // calling argument variable not defined.
+ }
+ }
+ else {
+ vector<int> istart(0,0);
+ vector<string> valvec;
+ valvec.push_back(call_vname);
+ int lnum = cmds[cdex].get_line_number(0);
+ int file_lnum = cmds[cdex].get_file_line_number(0);
+ string fname = cmds[cdex].get_filename(0);
+ Variable v(sub_vname, istart, valvec, lnum, file_lnum,
+ fname, &cmd_strings, serr, ierr);
+ v.set_temporary(true);
+ vmap.insert(pair<string, Variable>(v.get_varname(), v));
+ }
+
+ }
+ }
+
+ // Set the loop index to the index of the subroutine so we
+ // will end up at the line after the subroutine line.
+ i = cdex;
+ return return_value;
+} // End of jump_to_sub
+
+
+
+
+// ===========================================================================
+// End a do loop. This happens when a do loop has gone through all its
+// iterations or when an exit statment is encountered.
+// Basically, find the matching enddo and continue after that statement.
+// ===========================================================================
+bool PowerParser::end_do_loop(int &i, deque<int> &do_start,
+ stringstream &serr, int &ierr)
+{
+ int rtvl = 0;
+ // Find the matching enddo.
+ // Stop checking will be true if we are in main and hit a subroutine
+ // statement or if we are in a subroutine and hit an endsubroutine
+ // statement.
+ int cdex = -1;
+ int dlev = 1;
+ for (int j=i+1; j<(int)cmds.size(); j++) {
+ bool stop_checking = false;
+ if (cmds[j].find_matching_enddo(dlev, stop_checking)) {
+ cdex = j;
+ break;
+ }
+ if (stop_checking) break;
+ }
+
+ // If the matching enddo was not found then that is a fatal error.
+ int nlevels = (int)do_start.size();
+ if (cdex == -1) {
+ if (nlevels > 0) {
+ int ido = do_start[nlevels-1];
+ cmds[ido].fatal_error(0, serr, ierr);
+ }
+ serr << "No enddo found for do statement." << endl;
+ ierr = 2;
+ rtvl = process_error_return_int(serr, ierr);
+ if (rtvl > 0) cout << "Enddo not found " << endl;
+ return false;
+ }
+
+ // We are done with this do loop, so we can get rid of the reference
+ // to it.
+ if (nlevels > 0) {
+ do_start.erase(do_start.begin()+nlevels-1);
+ }
+
+ // Set the loop index to the enddo statement so that we will start
+ // processing immediately after the enddo.
+ i = cdex;
+ return true;
+} // End end_do_loop
+
+
+// ===========================================================================
+// A return statement in a subroutine has been encountered. We need to handle
+// the do loops before returning to the call statement, otherwise the code
+// will complain about do loops without enddo statements.
+// This routine searches from the return statement to the endsubroutine
+// statement, finds any free enddo's and erases the corresponding references
+// to the do statements.
+// ===========================================================================
+void PowerParser::end_do_ret(int &i, deque<int> &do_start,
+ stringstream &serr, int &ierr)
+{
+ // To suppress compiler warnings of unused parameters
+ //assert(serr == serr);
+ assert(ierr == ierr);
+
+ int istart = i;
+ for (;;) {
+
+ // Find an enddo.
+ // Stop checking will be true if we are in main and hit a subroutine
+ // statement or if we are in a subroutine and hit an endsubroutine
+ // statement.
+ int cdex = -1;
+ int dlev = 1;
+ bool stop_checking = false;
+ for (int j=istart; j<(int)cmds.size(); j++) {
+ if (cmds[j].find_matching_enddo(dlev, stop_checking)) {
+ cdex = j;
+ istart = j+1;
+ break;
+ }
+ if (stop_checking) break;
+ }
+
+ // If we don't find an enddo, then we are done.
+ if (cdex == -1) break;
+ if (stop_checking) break;
+
+ // We are done with this do loop, so we can get rid of the reference
+ // to it.
+ int nlevels = (int)do_start.size();
+ if (nlevels > 0) {
+ do_start.erase(do_start.begin()+nlevels-1);
+ }
+ }
+} // End end_do_ret
+
+
+
+
+// ===========================================================================
+// Check that an enddo was found for every do.
+// ===========================================================================
+void PowerParser::check_enddo(deque<int> &do_start, stringstream &serr, int &ierr)
+{
+ for (int i=0; i<(int)do_start.size(); i++) {
+ int ido = do_start[i];
+ cmds[ido].fatal_error(0, serr, ierr);
+ serr << "No enddo found for do statement." << endl;
+ ierr = 2;
+ }
+}
+
+
+// ===========================================================================
+// Check all processed flags on every command. If any word on any command
+// has not been processed, then that is a fatal error.
+// ===========================================================================
+void PowerParser::check_processed(bool &good)
+{
+ int rtvl = 0;
+ int ierr = 0;
+ stringstream serr;
+
+ for (int i=0; i<(int)cmdsfp->size(); i++) {
+ (*cmdsfp)[i].check_processed(good, serr, ierr);
+ }
+
+ process_error(serr, ierr);
+}
+
+
+// ===========================================================================
+// Process the duplicate array values command.
+// ===========================================================================
+int PowerParser::process_dav_cmd()
+{
+ int rtvl = 0;
+ int return_value = 0;
+
+ // Process the duplicate_array_values command.
+ // Note that duplicate array values are processed when the calls are made
+ // from the host code to actually extract information from the final
+ // buffer.
+ for (int i=0; i<(int)cmdsfp->size(); i++) {
+ string cmdi = (*cmdsfp)[i].get_string(0);
+ if (cmdi != "duplicate_array_values") continue;
+ (*cmdsfp)[i].set_processed(true);
+ string vali = (*cmdsfp)[i].get_string(2);
+ if (vali == "warning") dup_fatal = 1;
+ else if (vali == "fatal") dup_fatal = 2;
+ else if (vali == "none") dup_fatal = 0;
+ else {
+ int ierr = 0;
+ stringstream serr;
+ (*cmdsfp)[i].fatal_error(0, serr, ierr);
+ serr << "The value for the duplicate_array_values command must" << endl <<
+ "be either none, warning, or fatal" << endl;
+ ierr = 2;
+ cout << "The value for the duplicate_array_values command must" << endl;
+ cout << "be either none, warning, or fatal" << endl;
+ rtvl = process_error_return_int(serr, ierr);
+ if (rtvl > return_value) {
+ return_value = rtvl;
+ }
+
+ if (rtvl > 0) {
+ cout << "Duplicate array values not recognized " << ierr << endl;
+ }
+ return return_value;
+ }
+ if (dup_fatal > 0 ) return dup_fatal;
+ }
+ return 0;
+}
+
+
+// ===========================================================================
+// If commands appear more than once in the input file(s), print a warning
+// to the user.
+// ===========================================================================
+void PowerParser::check_duplicates()
+{
+ // Check for and print and duplicate scalar commands in the input file.
+ //if (comm->isIOProc()) {
+ // cout << "********************************************************************************" << endl;
+ //}
+ //bool found_any = false;
+ bool fany;
+ check_dup_scalar(-1, fany);
+ //if (fany) found_any = true;
+ for (int wtn=0; wtn<(int)whenthens.size(); wtn++) {
+ check_dup_scalar(wtn, fany);
+ //if (fany) found_any = true;
+ }
+ wt_reset();
+
+ // If duplicate scalar commands are not found, we do not really need to
+ // pollute the output telling the user that.
+ //if (!found_any) {
+ // if (comm->isIOProc()) {
+ // cout << "********** No Duplicate Scalar Commands Found in User Input File" << endl;
+ // }
+ //}
+ //if (comm->isIOProc()) {
+ // cout << "********************************************************************************" << endl;
+ // cout << endl << endl;
+ //}
+
+
+ // Remove and duplicate scalar commands from the final buffer.
+ remove_dup_scalar(-1);
+ for (int wtn=0; wtn<(int)whenthens.size(); wtn++) {
+ remove_dup_scalar(wtn);
+ }
+ wt_reset();
+}
+
+// ===========================================================================
+// Check for duplicate scalar commands in the user input file.
+// Print a table of any duplicate scalar commands to stdout.
+// ===========================================================================
+void PowerParser::check_dup_scalar(int wtn, bool &found_any)
+{
+ vector< vector<string> > rows;
+
+ vector<string> row1;
+ row1.push_back(" ");
+ row1.push_back("Line");
+ row1.push_back(" ");
+ rows.push_back(row1);
+
+ vector<string> row2;
+ row2.push_back("Filename");
+ row2.push_back("Number");
+ row2.push_back("Command");
+ rows.push_back(row2);
+
+ int n_header_rows = (int)rows.size();
+
+ if (wtn < 0) cmdsfp = &cmdsf;
+ else cmdsfp = whenthens[wtn].get_cmdsf_ptr();
+
+ vector<string> cmds_done;
+ found_any = false;
+ for (int i=0; i<(int)cmdsfp->size(); i++) {
+ bool already_printed_i = false;
+ string cmdi = (*cmdsfp)[i].get_string(0);
+ string w1i = (*cmdsfp)[i].get_string(1);
+ if (w1i == "(") continue;
+
+ bool already_done = false;
+ for (int j=0; j<(int)cmds_done.size(); j++) {
+ if (cmdi == cmds_done[j]) {
+ already_done = true;
+ break;
+ }
+ }
+ if (already_done) continue;
+
+ bool found = false;
+ for (int j=i+1; j<(int)cmdsfp->size(); j++) {
+ string cmdj = (*cmdsfp)[j].get_string(0);
+ if (cmdi == cmdj) {
+ stringstream ss;
+ if (!already_printed_i) {
+ vector<string> row;
+ set_dup_row(row, (*cmdsfp)[i], 0);
+ rows.push_back(row);
+ already_printed_i = true;
+ }
+ vector<string> row;
+ set_dup_row(row, (*cmdsfp)[j], 0);
+ rows.push_back(row);
+ found = true;
+ found_any = true;
+ }
+ }
+ if (found) {
+ cmds_done.push_back(cmdi);
+ vector<string> row;
+ row.push_back(" "); row.push_back(" "); row.push_back(" ");
+ rows.push_back(row);
+ }
+ }
+
+ if (found_any) {
+ if (comm->isIOProc()) {
+ cout << endl;
+ if (wtn < 0) {
+ cout << "********** WARNING: Duplicate Scalar Commands Found in User Input File" << endl;
+ cout << " The following commands appear more than once in the user input file." << endl;
+ }
+ else {
+ cout << "********** WARNING: Duplicate Scalar Commands Found in when...then" << endl;
+ cout << " The following commands appear more than once in the when...then." << endl;
+ }
+ cout << " The last instance of the command will be used." << endl;
+ cout << " Is this what you want??" << endl << endl;
+ stringstream ssout;
+ Parser_utils putils(index_base);
+ putils.print_strings(rows, n_header_rows, 4, 3, 80, ssout);
+ cout << ssout.str() << endl;
+ }
+ }
+}
+
+
+// ===========================================================================
+// Helper function for check_dup_scalar.
+// The duplicate scalar commands are printed as rows with each row containing
+// the file name the duplicate command was found in, the line number, and the
+// command line itself.
+// Given the duplicate command, this function generates that row of
+// information and adds it to the row vector.
+// ===========================================================================
+void PowerParser::set_dup_row(vector<string> &row, Cmd &cmdi, int iw)
+{
+ int lnum = cmdi.get_line_number(iw);
+ int file_lnum = cmdi.get_file_line_number(iw);
+ string fname = cmdi.get_filename(iw);
+
+ row.push_back(fname);
+ stringstream ss;
+ ss << file_lnum;
+ row.push_back(ss.str());
+ row.push_back(cmd_strings[lnum-1]);
+}
+
+
+
+// ===========================================================================
+// Remove duplicate scalar commands in the user input file.
+// Keep only the last instance of the command.
+// ===========================================================================
+void PowerParser::remove_dup_scalar(int wtn)
+{
+ if (wtn < 0) cmdsfp = &cmdsf;
+ else cmdsfp = whenthens[wtn].get_cmdsf_ptr();
+
+ for (int i=(int)cmdsfp->size()-1; i>=0; i--) {
+ string cmdi = (*cmdsfp)[i].get_string(0);
+ string w1i = (*cmdsfp)[i].get_string(1);
+ if (w1i == "(") continue;
+
+ for (int j=i-1; j>=0; j--) {
+ string cmdj = (*cmdsfp)[j].get_string(0);
+ if (cmdi == cmdj) {
+ cmdsfp->erase(cmdsfp->begin()+j);
+ i--;
+ }
+ }
+ }
+}
+
+// ===========================================================================
+// Helper function to convert doubles to strings.
+// ===========================================================================
+std::string const to_string( double const x )
+{
+ std::ostringstream tmp;
+ tmp << std::setprecision(16) << x;
+ return tmp.str();
+}
+
+// ===========================================================================
+// Initialize the parser. This will typically be called by the
+// constructors.
+// ===========================================================================
+void PowerParser::init()
+{
+ line_number = 0;
+ cmdsfp = &cmdsf;
+ dup_fatal = 1;
+ ierr_global = 0;
+
+ // make a little smaller (2.0) to avoid floating point excepting on some
+ // compilers
+ double huge_double = numeric_limits<double>::max( )/2.0;
+ Word whuge_double(huge_double, 1, 1, "", NULL);
+ Variable vhuge_double("$huge_double", whuge_double.get_string(), true, "largest double/2.0");
+ vmap.insert(pair<string, Variable>(vhuge_double.get_varname(), vhuge_double));
+
+ float huge_float = numeric_limits<float>::max( );
+ Word whuge_float(huge_float, 1, 1, "", NULL);
+ Variable vhuge_float("$huge_float", whuge_float.get_string(), true, "largest float");
+ vmap.insert(pair<string, Variable>(vhuge_float.get_varname(), vhuge_float));
+
+ int huge_int = numeric_limits<int>::max( );
+ Word whuge_int(huge_int, 1, 1, "", NULL);
+ Variable vhuge_int("$huge_int", whuge_int.get_string(), true, "largest integer");
+ vmap.insert(pair<string, Variable>(vhuge_int.get_varname(), vhuge_int));
+
+ double tiny_double = numeric_limits<double>::min( );
+ Word wtiny_double(tiny_double, 1, 1, "", NULL);
+ Variable vtiny_double("$tiny_double", wtiny_double.get_string(), true, "tiniest double");
+ vmap.insert(pair<string, Variable>(vtiny_double.get_varname(), vtiny_double));
+
+ float tiny_float = numeric_limits<float>::min( );
+ Word wtiny_float(tiny_float, 1, 1, "", NULL);
+ Variable vtiny_float("$tiny_float", wtiny_float.get_string(), true, "tiniest float");
+ vmap.insert(pair<string, Variable>(vtiny_float.get_varname(), vtiny_float));
+
+ int tiny_int = numeric_limits<int>::min( );
+ Word wtiny_int(tiny_int, 1, 1, "", NULL);
+ Variable vtiny_int("$tiny_int", wtiny_int.get_string(), true, "tiniest integer");
+ vmap.insert(pair<string, Variable>(vtiny_int.get_varname(), vtiny_int));
+
+ int ncores_tot = comm->getNumProcs();
+ Word wncores_tot(ncores_tot, 1, 1, "", NULL);
+ Variable vncores_tot("$ncores_tot", wncores_tot.get_string(), true, "total number of cores");
+ vmap.insert(pair<string, Variable>(vncores_tot.get_varname(), vncores_tot));
+
+
+ // ***********************************************************************
+ // Define the default functions.
+ Function facos("acos", true, 1, "real",
+ "arccosine, radians, arg -1 to 1");
+ fmap.insert(pair<string, Function>(facos.get_name(), facos));
+
+ Function fasin("asin", true, 1, "real",
+ "arcsine, radians, arg -1 to 1");
+ fmap.insert(pair<string, Function>(fasin.get_name(), fasin));
+
+ Function fatan("atan", true, 1, "real", "arctangent, returns radians");
+ fmap.insert(pair<string, Function>(fatan.get_name(), fatan));
+
+ Function fceil("ceil", true, 1, "real", "round up (smallest int >= arg)");
+ fmap.insert(pair<string, Function>(fceil.get_name(), fceil));
+
+ Function fcos("cos", true, 1, "real", "cosine, arg in radians");
+ fmap.insert(pair<string, Function>(fcos.get_name(), fcos));
+
+ Function fcosh("cosh", true, 1, "real", "hyperbolic cosine");
+ fmap.insert(pair<string, Function>(fcosh.get_name(), fcosh));
+
+ Function fexp("exp", true, 1, "real", "exponential");
+ fmap.insert(pair<string, Function>(fexp.get_name(), fexp));
+
+ Function ffabs("fabs", true, 1, "real", "absolute value of a real");
+ fmap.insert(pair<string, Function>(ffabs.get_name(), ffabs));
+
+ Function ffloor("floor", true, 1, "real",
+ "round down (largest int <= arg)");
+ fmap.insert(pair<string, Function>(ffloor.get_name(), ffloor));
+
+ Function flog("log", true, 1, "real", "log to base e, arg>0");
+ fmap.insert(pair<string, Function>(flog.get_name(), flog));
+
+ Function flog10("log10", true, 1, "real", "log to base 10, arg>0");
+ fmap.insert(pair<string, Function>(flog10.get_name(), flog10));
+
+ Function fsin("sin", true, 1, "real", "sine, arg in radians");
+ fmap.insert(pair<string, Function>(fsin.get_name(), fsin));
+
+ Function fsinh("sinh", true, 1, "real", "hyperbolic sine");
+ fmap.insert(pair<string, Function>(fsinh.get_name(), fsinh));
+
+ Function fsqrt("sqrt", true, 1, "real", "square root (arg >= 0)");
+ fmap.insert(pair<string, Function>(fsqrt.get_name(), fsqrt));
+
+ Function ftan("tan", true, 1, "real", "tangent, arg in radians");
+ fmap.insert(pair<string, Function>(ftan.get_name(), ftan));
+
+ Function ftanh("tanh", true, 1, "real", "hyperbolic tangent");
+ fmap.insert(pair<string, Function>(ftanh.get_name(), ftanh));
+
+ Function fatan2("atan2", true, 2, "real", "arctangent, 2 args");
+ fmap.insert(pair<string, Function>(fatan2.get_name(), fatan2));
+
+ Function ffmod("fmod", true, 2, "real", "remainder of arg1/arg2");
+ fmap.insert(pair<string, Function>(ffmod.get_name(), ffmod));
+
+ Function fpow("pow", true, 2, "real", "arg1 raised to arg2 power");
+ fmap.insert(pair<string, Function>(fpow.get_name(), fpow));
+
+ Function ffmax("max", true, 2, "real", "return the greater of two args");
+ fmap.insert(pair<string, Function>(ffmax.get_name(), ffmax));
+
+ Function ffmin("min", true, 2, "real", "return the lesser of two args");
+ fmap.insert(pair<string, Function>(ffmin.get_name(), ffmin));
+
+ Function fstrlen("strlen", true, 1, "string", "number of chars in arg");
+ fmap.insert(pair<string, Function>(fstrlen.get_name(), fstrlen));
+
+ Function fstrcat("strcat", true, 2, "string", "concatenate two strings");
+ fmap.insert(pair<string, Function>(fstrcat.get_name(), fstrcat));
+
+ Function fstrerase("strerase", true, 3, "string", "erase chars from string");
+ fmap.insert(pair<string, Function>(fstrerase.get_name(), fstrerase));
+
+ Function fstrinsert("strinsert", true, 3, "string", "insert chars into string");
+ fmap.insert(pair<string, Function>(fstrinsert.get_name(), fstrinsert));
+
+ Function fstrsubstr("strsubstr", true, 3, "string", "get sub string");
+ fmap.insert(pair<string, Function>(fstrsubstr.get_name(), fstrsubstr));
+
+ Function fstrtrim("strtrim", true, 1, "string", "remove trailing whitespace");
+ fmap.insert(pair<string, Function>(fstrtrim.get_name(), fstrtrim));
+
+ Function fdefined("defined", true, 1, "logical", "is a variable defined or not");
+ fmap.insert(pair<string, Function>(fdefined.get_name(), fdefined));
+}
+
+void PowerParser::dictionary_add(char *name, double value, bool pred, char *vdesc)
+{
+ Variable *Var_entry = new Variable(name, to_string(value), pred, vdesc);
+ vmap.insert(pair<string, Variable>(Var_entry->get_varname(), *Var_entry));
+}
+
+void PowerParser::dictionary_env_add(char *name, bool pred)
+{
+ const char *getenv_p;
+ const char *getenv_p_not_defined = "";
+
+ getenv_p = getenv(name);
+ if( getenv_p == NULL ){
+ getenv_p = getenv_p_not_defined;
+ }
+
+ int len_name = strlen(name);
+
+ // One extra character for $ and another for null termination
+ char *varname = (char *)malloc(sizeof(char)*(len_name+2));
+
+ varname[0] = '$';
+ strncpy(varname+1, name, len_name+1);
+
+ Variable *Var_entry = new Variable(varname, getenv_p, pred, name);
+ vmap.insert(pair<string, Variable>(Var_entry->get_varname(), *Var_entry));
+
+ free(varname);
+}
+
+
+// ===========================================================================
+// Read a file into a string.
+// This is only done on the io processor.
+// ===========================================================================
+void PowerParser::read_into_string(string filename, string &s_in)
+{
+ if(comm != NULL) {
+ if(!comm->isIOProc()) return;
+ }
+
+ // Its OK if an input file is not specified.
+ if (filename == " ") {
+ s_in = " ";
+ return;
+ }
+
+ // Open the input data file.
+ ifstream in_stream(filename.c_str(), ios::in);
+ if( !in_stream ) {
+ stringstream serr;
+ serr << endl << "*** FATAL ERROR" << endl;
+ serr << "Could not open input (or include) file." << endl;
+ serr << "The name of the file is " << filename << endl;
+ if (filename == "") {
+ serr << "(The file name is blank.)" << endl;
+ }
+ int ierr = 2;
+ process_error(serr, ierr);
+ return;
+ }
+
+ // Read each character and store in a string. We use a string so we
+ // don't have to fiddle with memory allocation and reallocation.
+ // There are more efficient ways to do this, but whatever way is
+ // used has to handle arbitrarily long files.
+ char c;
+ while (in_stream) {
+ in_stream.get(c);
+ if (!in_stream) break;
+ s_in += c;
+ }
+
+ // Check for a 0 size input file, this might be an indication of a
+ // full file system.
+ if( (int)s_in.size() == 0 ) {
+ stringstream serr;
+ serr << endl << "*** FATAL ERROR" << endl;
+ serr << "The name of the input file is " << filename << endl;
+ serr << "This file exists, but its size is 0 bytes, (empty file)." << endl;
+ serr << "Perhaps the file system is full??" << endl;
+ serr << "Use a unix command like \"df -k .\" to find out how full the"
+ " file system is." << endl;
+ int ierr = 2;
+ process_error(serr, ierr);
+ return;
+ }
+
+ // Now that the file contents are transferred to a string we do not need
+ // the data file anymore and can close it.
+ in_stream.close();
+}
+
+
+//+***************************************************************************
+// ***************************************************************************
+// Driver functions for getting values from the commands.
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Driver for getting boolean values as integers.
+// This works for arrays of any dimension, 0,1,2,3,...
+// ===========================================================================
+void PowerParser::get_bool_int(string &cname,
+ int *cvalue,
+ const vector<int> &size,
+ bool skip)
+{
+ // Note that we do not default cvalue. Its value only changes if the
+ // command is found.
+
+ // Used in checking for duplicate array values
+ int dim = (int)size.size();
+ int tot_size = 1;
+ for (int i=0; i<dim; i++) {
+ tot_size *= size[i];
+ }
+ vector<int> dup_vals(tot_size, 0);
+ vector<Cmd *> dup_cmd1(tot_size);
+ vector<int> dup_wdex1(tot_size, -1);
+
+ int ierr = 0;
+ stringstream serr;
+ if (! case_sensitive) {
+ transform(cname.begin(), cname.end(), cname.begin(), tolower);
+ }
+ for (int i=0; i<(int)cmdsfp->size(); i++) {
+ if ((*cmdsfp)[i].get_cmd_name() == cname) {
+ (*cmdsfp)[i].get_bool_int(cname, cvalue, size, dup_cmd1, dup_wdex1,
+ dup_fatal, dup_vals, skip, serr, ierr);
+ processed_cmd_names.push_back(cname);
+ }
+ }
+
+ // Process errors, global abort if ierr==2
+ process_error(serr, ierr);
+}
+
+void PowerParser::get_bool_int(const char *cname,
+ int *cvalue,
+ const vector<int> &size,
+ bool skip)
+{
+ string cstring(cname);
+ get_bool_int( cstring, cvalue, size, skip);
+}
+
+void PowerParser::get_bool(string &cname,
+ bool *cvalue,
+ const vector<int> &size,
+ bool skip)
+{
+ // Note that we do not default cvalue. Its value only changes if the
+ // command is found.
+
+ // Used in checking for duplicate array values
+ int dim = (int)size.size();
+ int tot_size = 1;
+ for (int i=0; i<dim; i++) {
+ tot_size *= size[i];
+ }
+ vector<int> dup_vals(tot_size, 0);
+ vector<Cmd *> dup_cmd1(tot_size);
+ vector<int> dup_wdex1(tot_size, -1);
+
+ int ierr = 0;
+ stringstream serr;
+ for (int i=0; i<(int)cmdsfp->size(); i++) {
+ if ((*cmdsfp)[i].get_cmd_name() == cname) {
+ (*cmdsfp)[i].get_bool(cname, cvalue, size, dup_cmd1, dup_wdex1,
+ dup_fatal, dup_vals, skip, serr, ierr);
+ processed_cmd_names.push_back(cname);
+ }
+ }
+
+ // Process errors, global abort if ierr==2
+ process_error(serr, ierr);
+}
+
+void PowerParser::get_bool(const char *cname,
+ bool *cvalue,
+ const vector<int> &size,
+ bool skip)
+{
+ string cstring(cname);
+ get_bool( cstring, cvalue, size, skip);
+}
+
+
+// ===========================================================================
+// Driver for getting integer values.
+// This works for arrays of any dimension, 0,1,2,3,...
+// ===========================================================================
+template< typename T >
+void PowerParser::get_int(string &cname, T *cvalue, const vector<int> &size, bool skip)
+{
+ // Note that we do not default cvalue. Its value only changes if the
+ // command is found.
+
+ // Used in checking for duplicate array values
+ int dim = (int)size.size();
+ int tot_size = 1;
+ for (int i=0; i<dim; i++) {
+ tot_size *= size[i];
+ }
+ vector<int> dup_vals(tot_size, 0);
+ vector<Cmd *> dup_cmd1(tot_size);
+ vector<int> dup_wdex1(tot_size, -1);
+
+ int ierr = 0;
+ stringstream serr;
+ if (! case_sensitive) {
+ transform(cname.begin(), cname.end(), cname.begin(), tolower);
+ }
+ for (int i=0; i<(int)cmdsfp->size(); i++) {
+ if ((*cmdsfp)[i].get_cmd_name() == cname) {
+ (*cmdsfp)[i].get_int(cname, cvalue, size, dup_cmd1, dup_wdex1,
+ dup_fatal, dup_vals, skip, serr, ierr);
+ processed_cmd_names.push_back(cname);
+ }
+ }
+
+ // Process errors, global abort if ierr==2
+ process_error(serr, ierr);
+}
+
+//! Explicit instantiation of supported template types. If more types are
+//! needed those explicit versions must be listed here. We are not using
+//! automatic inclusion (we would need to move the function definition into
+//! the header file for that). The listed versions below are the only ones
+//! that will be included in the library.
+template void PowerParser::get_int(
+ string &cname, int *cvalue, const vector<int> &size, bool skip);
+template void PowerParser::get_int(
+ string &cname, int64_t *cvalue, const vector<int> &size, bool skip);
+
+template< typename T >
+void PowerParser::get_int(const char *cname,
+ T *cvalue,
+ const vector<int> &size,
+ bool skip)
+{
+ string cstring(cname);
+ get_int( cstring, cvalue, size, skip);
+}
+
+template void PowerParser::get_int(
+ const char *cname, int *cvalue, const vector<int> &size, bool skip);
+template void PowerParser::get_int(
+ const char *cname, int64_t *cvalue, const vector<int> &size, bool skip);
+
+// ===========================================================================
+// Driver for getting real values.
+// This works for arrays of any dimension, 0,1,2,3,...
+// ===========================================================================
+void PowerParser::get_real(string &cname,
+ double *cvalue,
+ const vector<int> &size,
+ bool skip)
+{
+ // Note that we do not default cvalue. Its values only change if the
+ // command is found.
+
+ // Used in checking for duplicate array values
+ int dim = (int)size.size();
+ int tot_size = 1;
+ for (int i=0; i<dim; i++) {
+ tot_size *= size[i];
+ }
+ vector<int> dup_vals(tot_size, 0);
+ vector<Cmd *> dup_cmd1(tot_size);
+ vector<int> dup_wdex1(tot_size, -1);
+
+ int ierr = 0;
+ stringstream serr;
+ if (! case_sensitive) {
+ transform(cname.begin(), cname.end(), cname.begin(), tolower);
+ }
+ for (int i=0; i<(int)cmdsfp->size(); i++) {
+ if ((*cmdsfp)[i].get_cmd_name() == cname) {
+ (*cmdsfp)[i].get_real(cname, cvalue, size, dup_cmd1, dup_wdex1,
+ dup_fatal, dup_vals, skip, serr, ierr);
+ processed_cmd_names.push_back(cname);
+ }
+ }
+
+ // Process errors, global abort if ierr==2
+ process_error(serr, ierr);
+}
+
+void PowerParser::get_real(const char *cname,
+ double *cvalue,
+ const vector<int> &size,
+ bool skip)
+{
+ string cstring(cname);
+ get_real( cstring, cvalue, size, skip);
+}
+
+// ===========================================================================
+// Driver for getting character strings.
+// This works for arrays of any dimension, 0,1,2,3,...
+// ===========================================================================
+void PowerParser::get_char(string &cname,
+ vector<string> &vstr,
+ const vector<int> &size,
+ bool single_char,
+ bool skip)
+{
+ // Note that we do not default cvalue. Its value only changes if the
+ // command is found.
+
+ // Used in checking for duplicate array values
+ int dim = (int)size.size();
+ int tot_size = 1;
+ for (int i=0; i<dim; i++) {
+ tot_size *= size[i];
+ }
+ vector<int> dup_vals(tot_size, 0);
+ vector<Cmd *> dup_cmd1(tot_size);
+ vector<int> dup_wdex1(tot_size, -1);
+
+ int ierr = 0;
+ stringstream serr;
+ if (! case_sensitive) {
+ transform(cname.begin(), cname.end(), cname.begin(), tolower);
+ }
+ for (int i=0; i<(int)cmdsfp->size(); i++) {
+ if ((*cmdsfp)[i].get_cmd_name() == cname) {
+ (*cmdsfp)[i].get_char(cname, vstr, size, single_char, dup_cmd1,
+ dup_wdex1, dup_fatal, dup_vals,
+ skip, serr, ierr);
+ processed_cmd_names.push_back(cname);
+ }
+ }
+
+ // Process errors, global abort if ierr==2
+ process_error(serr, ierr);
+}
+
+void PowerParser::get_char(const char *cname,
+ vector<string> &vstr,
+ const vector<int> &size,
+ bool single_char,
+ bool skip)
+{
+ string cstring(cname);
+ get_char( cstring, vstr, size, single_char, skip);
+}
+
+// ===========================================================================
+// Driver for getting array sizes.
+// ===========================================================================
+void PowerParser::get_size(string &cname, vector<int> &size)
+{
+ int ierr = 0;
+ stringstream serr;
+ if (! case_sensitive) {
+ transform(cname.begin(), cname.end(), cname.begin(), tolower);
+ }
+ for (int i=0; i<(int)cmdsfp->size(); i++) {
+ if ((*cmdsfp)[i].get_cmd_name() == cname) {
+ (*cmdsfp)[i].get_size(size, serr, ierr);
+ }
+ }
+
+ // Process errors, global abort if ierr==2
+ process_error(serr, ierr);
+}
+
+
+// ===========================================================================
+// Driver for getting array sizes. Version to get all sizes
+// ===========================================================================
+void PowerParser::get_sizeb(string &cname, vector<int> &size)
+{
+ int ierr = 0;
+ stringstream serr;
+ if (! case_sensitive) {
+ transform(cname.begin(), cname.end(), cname.begin(), tolower);
+ }
+ for (int i=0; i<(int)cmdsfp->size(); i++) {
+ if ((*cmdsfp)[i].get_cmd_name() == cname) {
+ (*cmdsfp)[i].get_sizeb(size, serr, ierr);
+ }
+ }
+
+ // Process errors, global abort if ierr==2
+ process_error(serr, ierr);
+}
+
+
+// ===========================================================================
+// Check if the input command, cname, appears in the final, parsed user input.
+//
+// The two outputs are in_input and in_whenthen,
+// in_input command is in (or not) the main part of the input, i.e.
+// everything except the when...then statements.
+// in_whenthen command is in (or not) at least one when...then statement.
+// ===========================================================================
+void PowerParser::cmd_in_input(string &cname, bool &in_input, bool &in_whenthen)
+{
+ in_input = false;
+ in_whenthen = false;
+
+ if (! case_sensitive) {
+ transform(cname.begin(), cname.end(), cname.begin(), tolower);
+ }
+ for (int i=0; i<(int)cmdsfp->size(); i++) {
+ if ((*cmdsfp)[i].get_cmd_name() == cname) {
+ in_input = true;
+ break;
+ }
+ }
+
+ for (int wtn=0; wtn<(int)whenthens.size(); wtn++) {
+ cmdsfp = whenthens[wtn].get_cmdsf_ptr();
+ for (int i=0; i<(int)cmdsfp->size(); i++) {
+ if ((*cmdsfp)[i].get_cmd_name() == cname) {
+ in_whenthen = true;
+ break;
+ }
+ }
+ if (in_whenthen) break;
+ }
+
+ wt_reset();
+}
+
+
+// ===========================================================================
+// Set the processed flag for all words for all commands that match cname.
+// The value to set the processed flag to is bval.
+// This sets the processed flag for commands in the final buffer and in the
+// when...then final buffers.
+// ===========================================================================
+void PowerParser::cmd_set_processed(string &cname, bool bval)
+{
+ if (! case_sensitive) {
+ transform(cname.begin(), cname.end(), cname.begin(), tolower);
+ }
+ for (int i=0; i<(int)cmdsfp->size(); i++) {
+ if ((*cmdsfp)[i].get_cmd_name() == cname) {
+ (*cmdsfp)[i].set_processed(bval);
+ }
+ }
+ for (int wtn=0; wtn<(int)whenthens.size(); wtn++) {
+ cmdsfp = whenthens[wtn].get_cmdsf_ptr();
+ for (int i=0; i<(int)cmdsfp->size(); i++) {
+ if ((*cmdsfp)[i].get_cmd_name() == cname) {
+ (*cmdsfp)[i].set_processed(bval);
+ }
+ }
+ }
+ wt_reset();
+}
+
+
+// ===========================================================================
+// ===========================================================================
+void PowerParser::cmd_set_reprocessed(bool bval)
+{
+ for (int c=0; c<(int)processed_cmd_names.size(); c++) {
+ string cname = processed_cmd_names[c];
+ cmd_set_processed(cname, bval);
+ }
+}
+
+
+// ===========================================================================
+// Process errors.
+// ===========================================================================
+void PowerParser::process_error_global(int &return_value)
+{
+ int return_val_local;
+ int ierr = ierr_global;
+
+ return_val_local = 0;
+ if (ierr == 0) {
+ return_value = 0;
+ return;
+ }
+
+ return_val_local = process_error_return_int(serr_global, ierr);
+ return_value = return_val_local;
+}
+
+// ===========================================================================
+//
+
+void PowerParser::process_error(stringstream &serr, int &ierr)
+{
+ if (ierr == 0) return;
+
+ if (ierr == 3) {
+ serr_global << serr.str();
+ ierr_global = ierr;
+ return;
+ }
+
+ string err_type = "Warnings";
+ if (ierr == 2) err_type = "Fatal errors";
+
+ if (comm->isIOProc()) {
+ cout << endl;
+ cout << err_type << " have been encountered while parsing the user"
+ " input file." << endl;
+ cout << "Note that often fixing the first error will also fix the"
+ " other errors." << endl;
+ cout << serr.str() << endl;
+ fflush(NULL);
+ }
+ if (ierr == 2) {
+ // Force all processors to quit.
+ // We have the problem that the non-IO procs may kill the calculation
+ // before the IO proc can finish printing the error messages, thus
+ // force the IO proc to do the global abort but still allow the
+ // possibility that the IO proc may not have aborted, some other
+ // proc might have.
+ if (comm->isIOProc()) {
+ comm->global_abort_parser();
+ }
+ else {
+ sleep(2);
+ comm->global_abort_parser();
+ }
+ }
+
+
+ // A possible sleep function if the library sleep function is not portable.
+ // #include <time.h>
+ // void sleep(unsigned int mseconds)
+ // {
+ // clock_t goal = mseconds + clock();
+ // while (goal > clock());
+ // }
+
+
+ // A better function is the following since it uses CLOCKS_PER_SEC and
+ // thus does not assume its value.
+ //
+ //#include <time.h>
+ //void wait ( int seconds )
+ //{
+ // clock_t endwait;
+ // endwait = clock () + seconds * CLOCKS_PER_SEC ;
+ // while (clock() < endwait) {}
+ //}
+
+ // We might want to put this in Comm, i.e. modify global_abort.
+}
+
+
+// ===========================================================================
+int PowerParser::process_error_return_int(stringstream &serr, int &ierr)
+{
+ int return_value;
+
+ return_value = ierr;
+
+ if (ierr == 0) return(return_value);
+
+ return_value = ierr;
+
+ if (ierr == 3) {
+ serr_global << serr.str();
+ ierr_global = ierr;
+ cout << "Error encountered in process_error_return_int -- err code is " << ierr << endl;
+ fflush(NULL);
+ }
+
+ if (comm->isIOProc()) {
+ cout << endl;
+ cout << "Error encountered while parsing the user input file -- err code is "
+ << ierr << endl;
+ cout << "Note that often fixing the first error will also fix the"
+ " other errors." << endl;
+ cout << serr.str() << endl;
+ cout.flush();
+ fflush(NULL);
+ }
+
+ return(return_value);
+
+
+ // A possible sleep function if the library sleep function is not portable.
+ // #include <time.h>
+ // void sleep(unsigned int mseconds)
+ // {
+ // clock_t goal = mseconds + clock();
+ // while (goal > clock());
+ // }
+
+
+ // A better function is the following since it uses CLOCKS_PER_SEC and
+ // thus does not assume its value.
+ //
+ //#include <time.h>
+ //void wait ( int seconds )
+ //{
+ // clock_t endwait;
+ // endwait = clock () + seconds * CLOCKS_PER_SEC ;
+ // while (clock() < endwait) {}
+ //}
+
+}
+
+
+//+***************************************************************************
+// ***************************************************************************
+// When...then commands
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Check if a when...then condition is satisfied.
+// ===========================================================================
+void PowerParser::wt_check(int wtn, vector<string> &code_varnames,
+ vector<string> &code_values,
+ vector<int> &vv_active, int *wtci)
+{
+ stringstream serr;
+ int ierr = 0;
+ whenthens[wtn-1].check_wt(code_varnames, code_values, vv_active, wtci,
+ serr, ierr);
+ process_error(serr, ierr);
+ if ( (*wtci) == 1) {
+ cmdsfp = whenthens[wtn-1].get_cmdsf_ptr();
+ }
+}
+
+
+// ===========================================================================
+// Set the commands final buffer pointer.
+// This is also done in the check routine.
+// ===========================================================================
+void PowerParser::wt_set_cmdsfp(int wtn)
+{
+ cmdsfp = whenthens[wtn-1].get_cmdsf_ptr();
+}
+
+
+// ===========================================================================
+// Reset the commands final buffer pointer.
+// ===========================================================================
+void PowerParser::wt_reset()
+{
+ cmdsfp = &cmdsf;
+}
+
+
+// ===========================================================================
+// ===========================================================================
+void PowerParser::wt_casize(int wtn, int *wt_casize)
+{
+ // To suppress compiler warnings of unused parameters
+ assert(wt_casize == wt_casize);
+
+ whenthens[wtn-1].get_char_array_size(wt_casize);
+}
+
+
+// ===========================================================================
+// ===========================================================================
+void PowerParser::wt_carray(int wtn, char *wt_ca, int wt_casize)
+{
+ // To suppress compiler warnings of unused parameters
+ assert(wt_casize == wt_casize);
+
+ string sc;
+ whenthens[wtn-1].get_char_array(sc);
+ for (int i=0; i<(int)sc.size(); i++) {
+ wt_ca[i] = sc[i];
+ }
+}
+
+
+// ===========================================================================
+// ===========================================================================
+void PowerParser::wt_satsize(int wtn, int *wt_satsize)
+{
+ // To suppress compiler warnings of unused parameters
+ assert(wt_satsize == wt_satsize);
+
+ whenthens[wtn-1].get_satsize(wt_satsize);
+}
+
+
+// ===========================================================================
+// ===========================================================================
+void PowerParser::wt_getsat(int wtn, int *wt_sat, int wt_satsize)
+{
+ // To suppress compiler warnings of unused parameters
+ assert(wt_satsize == wt_satsize);
+
+ whenthens[wtn-1].getsat(wt_sat);
+}
+
+
+// ===========================================================================
+// ===========================================================================
+void PowerParser::wt_setsat(int wtn, int *wt_sat, int wt_satsize)
+{
+ // To suppress compiler warnings of unused parameters
+ assert(wt_satsize == wt_satsize);
+
+ whenthens[wtn-1].setsat(wt_sat);
+}
+
+
+// ===========================================================================
+// Get and Set the processed flag for a whenthen.
+// ===========================================================================
+void PowerParser::wt_getprocessed(int wtn, int *wtp)
+{
+ whenthens[wtn-1].getprocessed(wtp);
+}
+
+void PowerParser::wt_setprocessed(int wtn, int wtp)
+{
+ whenthens[wtn-1].setprocessed(wtp);
+}
+
+
+// ===========================================================================
+// Get and Set the sequence index for a whenthen.
+// ===========================================================================
+void PowerParser::wt_getseq(int wtn, int *wtseq)
+{
+ whenthens[wtn-1].getseq(wtseq);
+}
+
+void PowerParser::wt_setseq(int wtn, int wtseq)
+{
+ whenthens[wtn-1].setseq(wtseq);
+}
+
+
+
+
+//+***************************************************************************
+// ***************************************************************************
+// restart_block commands
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Check if a restart block condition is satisfied.
+// ===========================================================================
+void PowerParser::rb_check(vector<string> &code_varnames,
+ vector<string> &code_values,
+ vector<int> &vv_active, int *rbci,
+ int *rb_ntriggered, int *rb_triggered_indices)
+{
+ stringstream serr;
+ int ierr = 0;
+ *rbci = 0;
+ *rb_ntriggered = 0;
+ for (int i=0; i<(int)restartblocks.size(); i++) {
+ int ri = 0;
+ restartblocks[i].check_rb(code_varnames, code_values, vv_active, &ri,
+ serr, ierr);
+ if (ri == 1) {
+ *rbci = 1;
+ rb_triggered_indices[*rb_ntriggered] = i;
+ *rb_ntriggered += 1;
+ }
+ }
+ process_error(serr, ierr);
+}
+
+
+// ===========================================================================
+// Get/set the restart block names
+// ===========================================================================
+void PowerParser::get_rb_names(vector<string> &rb_names_vstr)
+{
+ rb_names_vstr.clear();
+ for (int i=0; i<(int)restartblocks.size(); i++) {
+ rb_names_vstr.push_back(restartblocks[i].get_name());
+ }
+}
+void PowerParser::set_rb_names(vector<string> &rb_names_vstr)
+{
+ bnames_on_dump.clear();
+ for (int i=0; i<(int)rb_names_vstr.size(); i++) {
+ bnames_on_dump.push_back(rb_names_vstr[i]);
+ }
+}
+
+
+// ===========================================================================
+// Get/set the restart block activity flags.
+// ===========================================================================
+void PowerParser::get_rb_aflags(int *rb_aflags)
+{
+ for (int i=0; i<(int)restartblocks.size(); i++) {
+ rb_aflags[i] = restartblocks[i].get_aflag();
+ }
+}
+void PowerParser::set_rb_aflags(int *rb_aflags, int rb_num)
+{
+ baflags_on_dump.clear();
+ for (int j=0; j<rb_num; j++) {
+ baflags_on_dump.push_back(rb_aflags[j]);
+ }
+}
+
+
+// ===========================================================================
+// Get/set the restart block satsize.
+// satsize is defined as the total number of sub-conditions over all restart
+// blocks.
+// ===========================================================================
+void PowerParser::get_rb_satsize(int *rb_satsize)
+{
+ int rb_sum = 0;
+ for (int i=0; i<(int)restartblocks.size(); i++) {
+ rb_sum += restartblocks[i].get_satsize();
+ }
+ *rb_satsize = rb_sum;
+}
+
+void PowerParser::set_rb_satsize(int rb_satsize)
+{
+ satsize_on_dump = rb_satsize;
+}
+
+
+// ===========================================================================
+// Get/set the number of sub-conditions per restart block
+// ===========================================================================
+void PowerParser::get_rb_satprb(int *rb_satprb)
+{
+ for (int i=0; i<(int)restartblocks.size(); i++) {
+ rb_satprb[i] = restartblocks[i].get_satsize();
+ }
+}
+
+void PowerParser::set_rb_satprb(int *rb_satprb, int rb_num)
+{
+ rbsatprb_on_dump.clear();
+ for (int i=0; i<rb_num; i++) {
+ rbsatprb_on_dump.push_back(rb_satprb[i]);
+ }
+}
+
+
+// ===========================================================================
+// Get/set the satisfied flag for each sub-condition for each restart block
+// ===========================================================================
+void PowerParser::get_rb_sat(int *rb_sat)
+{
+ int k = 0;
+ for (int i=0; i<(int)restartblocks.size(); i++) {
+ for (int j=0; j<(int)restartblocks[i].get_satsize(); j++) {
+ rb_sat[k] = restartblocks[i].get_sat(j);
+ k++;
+ }
+ }
+}
+
+
+void PowerParser::set_rb_sat(int *rb_sat, int rb_satsize)
+{
+ rbsat_on_dump.clear();
+ for (int i=0; i<rb_satsize; i++) {
+ bool b = false;
+ if (rb_sat[i] == 1) b = true;
+ rbsat_on_dump.push_back(b);
+ }
+}
+
+
+// ===========================================================================
+// Get a combined list of the restart block variable names. Note that there
+// might be more than one variable name per restart block depending on how
+// complicated the condition is.
+// ===========================================================================
+int PowerParser::get_rb_num_varnames()
+{
+ int numv = 0;
+ for (int i=0; i<(int)restartblocks.size(); i++) {
+ numv += restartblocks[i].get_num_varnames();
+ }
+ for (int i=0; i<(int)whenthens.size(); i++) {
+ numv += whenthens[i].get_num_varnames();
+ }
+ return numv;
+}
+void PowerParser::get_rb_varnames(vector<string> &rb_varnames_vstr)
+{
+ rb_varnames_vstr.clear();
+ for (int i=0; i<(int)restartblocks.size(); i++) {
+ int numv = restartblocks[i].get_num_varnames();
+ for (int j=0; j<numv; j++) {
+ rb_varnames_vstr.push_back(restartblocks[i].get_varname(j));
+ }
+ }
+ for (int i=0; i<(int)whenthens.size(); i++) {
+ int numv = whenthens[i].get_num_varnames();
+ for (int j=0; j<numv; j++) {
+ rb_varnames_vstr.push_back(whenthens[i].get_varname(j));
+ }
+ }
+}
+
+
+// ===========================================================================
+// Print info about restart blocks.
+// ===========================================================================
+void PowerParser::list_rb()
+{
+ stringstream ssc;
+ list_rb_ss(ssc);
+ if (comm->isIOProc()) {
+ cout << ssc.str();
+ }
+}
+
+void PowerParser::list_rb_start()
+{
+ ssfout.str("");
+ list_rb_ss(ssfout);
+ ssfout_current_pos = 0;
+}
+
+void PowerParser::list_rb_ss(stringstream &ssc)
+{
+ int rblen = (int)restartblocks.size();
+ if (rblen <= 0) {
+ ssc << endl << "No restart blocks have been specified."
+ << endl << endl;
+ return;
+ }
+
+ for (int rb=0; rb<rblen; rb++) {
+ list_one_rb_ss(ssc, rb);
+ }
+}
+
+void PowerParser::list_rb1_start(int *rb)
+{
+ ssfout.str("");
+ list_rb1_ss(ssfout, rb);
+ ssfout_current_pos = 0;
+}
+
+void PowerParser::list_rb1_ss(stringstream &ssc, int *rbp)
+{
+ int rb = *rbp;
+ int rblen = (int)restartblocks.size();
+ if (rb < 0) {
+ ssc << endl << "List restart block error: rb<0"
+ << endl << endl;
+ return;
+ }
+ if (rb >= rblen) {
+ ssc << endl << "List restart block error: rb>=rblen"
+ << endl << endl;
+ return;
+ }
+
+ list_one_rb_ss(ssc, rb);
+}
+
+
+// ===========================================================================
+// List info for one restart block, index=rb
+// ===========================================================================
+void PowerParser::list_one_rb_ss(stringstream &ssc, int rb)
+{
+ ssc << endl;
+ ssc << "** Echo restart block info, restart block name = "
+ << restartblocks[rb].get_name() << endl;
+ string s = "false";
+ if (restartblocks[rb].get_aflag() == 1) s = "true";
+ ssc << " Active flag = " << s << endl;
+ ssc << " Condition for this restart block =" << endl;
+ restartblocks[rb].list_condition(" ", " ", ssc);
+ ssc << endl;
+ ssc << " Number of sub-conditions = " <<
+ restartblocks[rb].get_satsize() << endl;
+ for (int i=0; i<restartblocks[rb].get_satsize(); i++) {
+ string t = "false";
+ if (restartblocks[rb].get_sat(i) == 1) t = "true";
+ ssc << " For sub-condition " << i+1 <<
+ ", satisfied flag = " << t << endl;
+ }
+ ssc << endl;
+}
+
+//+***************************************************************************
+// ***************************************************************************
+// Debugging commands/functions.
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Print a cmds line.
+// ===========================================================================
+void PowerParser::print_line(int i)
+{
+ if (!comm->isIOProc()) return;
+ stringstream ss3;
+ cmds[i].print_using_words(ss3);
+ cout << ss3.str() << endl;
+}
+
+void PowerParser::print_line(Cmd &cmd)
+{
+ if (!comm->isIOProc()) return;
+ //cout << cmd.get_cmd_name() << endl;
+ //if (cmd.get_cmd_name() != "acmd5") return;
+ stringstream ss3;
+ cmd.print_using_words(ss3);
+ //cmd.print_all_words(ss3);
+ cout << ss3.str() << endl;
+}
+
+
+// ===========================================================================
+// List variables
+//
+// lv1 and lv2 are header and footer strings to delimit the list.
+//
+// var_to_list is a specific variable to list. If it is blank then all vars
+// will be listed, otherwise only the specific var will be listed.
+// ===========================================================================
+void PowerParser::list_vars(string lv1, string lv2, string var_to_list)
+{
+ stringstream ssv;
+ list_vars_ss(lv1, lv2, var_to_list, ssv);
+ if (comm->isIOProc()) {
+ cout << ssv.str();
+ }
+}
+
+void PowerParser::list_vars_start()
+{
+ ssfout.str("");
+ ssfout << pre_defined_varss.str() << endl;
+ list_vars_ss("", "", "", ssfout);
+ ssfout_current_pos = 0;
+}
+
+void PowerParser::list_vars_ss(string lv1, string lv2, string var_to_list,
+ stringstream &ssvars)
+{
+ if (!comm->isIOProc()) return;
+ ssvars << lv1 << endl;
+
+ map<string, Variable>::iterator p;
+
+ // Holds the various header and data rows to be printed.
+ vector< vector<string> > rows;
+
+ // Construct the header row.
+ vector<string> header_row;
+ header_row.push_back("Variable name");
+ header_row.push_back("Value");
+ header_row.push_back("Description");
+ rows.push_back(header_row);
+ int n_header_rows = (int)rows.size();
+
+ // Set the number of columns.
+ int ncol = (int)header_row.size();
+
+ // Construct the data rows.
+ for(p = vmap.begin(); p != vmap.end(); p++) {
+ string vname = p->first;
+ if (var_to_list != "") {
+ if (vname != var_to_list) continue;
+ }
+ int nvalues = p->second.get_nvalues();
+ string description = p->second.get_description();
+
+ int ndim = p->second.get_ndim();
+ vector<int> istart(ndim,0);
+
+ for (int n=0; n<nvalues; n++) {
+ string vnamep = vname;
+ if (nvalues > 1) {
+ p->second.get_indices(n, istart);
+ stringstream ss;
+ ss << vname << "(";
+ for (int d=0; d<ndim; d++) {
+ if (d < ndim-1) ss << istart[d] << ",";
+ else ss << istart[d];
+ }
+ ss << ")";
+ vnamep = ss.str();
+ }
+ string value = p->second.get_var_value(n);
+ vector<string> sv;
+ for (int c=0; c<ncol; c++) {
+ if (c == 0) sv.push_back(vnamep);
+ if (c == 1) sv.push_back(value);
+ if (c == 2) sv.push_back(description);
+ }
+ rows.push_back(sv);
+ }
+ }
+
+ // List the data with the columns lined up.
+ Parser_utils putils(index_base);
+ putils.print_strings(rows, n_header_rows, 3, 3, 85, ssvars);
+
+ ssvars << lv2 << endl;
+}
+
+
+// ===========================================================================
+// List functions.
+// ===========================================================================
+void PowerParser::list_funcs(string lf1, string lf2)
+{
+ stringstream ssf;
+ list_funcs_ss(lf1, lf2, ssf);
+ if (comm->isIOProc()) {
+ cout << ssf.str();
+ }
+
+ // Alternate method.
+ //list_funcs_start();
+ //for (;;) {
+ // string sline;
+ // if (!get_ssfout_line(sline)) break;
+ // if (comm->isIOProc()) {
+ // cout << sline << endl;
+ // }
+ //}
+}
+
+void PowerParser::list_funcs_start()
+{
+ ssfout.str("");
+ list_funcs_ss("", "", ssfout);
+ ssfout_current_pos = 0;
+}
+
+void PowerParser::list_funcs_ss(string lf1, string lf2, stringstream &ssfunc)
+{
+ if (!comm->isIOProc()) return;
+ ssfunc << lf1 << endl;
+
+ map<string, Function>::iterator p;
+
+ // Holds the various header and data rows to be printed.
+ vector< vector<string> > rows;
+
+ // Construct the header row.
+ vector<string> header_row;
+ header_row.push_back("Function name");
+ header_row.push_back("nargs");
+ header_row.push_back("type");
+ header_row.push_back("Description");
+ rows.push_back(header_row);
+ int n_header_rows = (int)rows.size();
+
+ // Set the number of columns.
+ int ncol = (int)header_row.size();
+
+ // Construct the data rows.
+ for(p = fmap.begin(); p != fmap.end(); p++) {
+ string fname = p->first;
+ vector<string> sv;
+ int nargs = p->second.get_num_args();
+ stringstream ss;
+ ss << nargs;
+ string type = p->second.get_type();
+ string fdes = p->second.get_description();
+ for (int c=0; c<ncol; c++) {
+ if (c == 0) sv.push_back(fname);
+ if (c == 1) sv.push_back(ss.str());
+ if (c == 2) sv.push_back(type);
+ if (c == 3) sv.push_back(fdes);
+ }
+ rows.push_back(sv);
+ }
+
+ // List the data with the columns lined up.
+ Parser_utils putils(index_base);
+ putils.print_strings(rows, n_header_rows, 3, 4, 85, ssfunc);
+
+ ssfunc << lf2 << endl;
+}
+
+
+
+// ===========================================================================
+// List final set of commands.
+// ===========================================================================
+void PowerParser::list_cmdsf(string lc1, string lc2)
+{
+ stringstream ssc;
+ list_cmdsf_ss(lc1, lc2, ssc);
+ if (comm->isIOProc()) {
+ cout << ssc.str();
+ }
+}
+
+void PowerParser::list_cmdsf_start()
+{
+ ssfout.str("");
+ list_cmdsf_ss("", "", ssfout);
+ ssfout_current_pos = 0;
+}
+
+void PowerParser::list_cmdsf_ss(string lc1, string lc2,
+ stringstream &ssc)
+{
+ if (!comm->isIOProc()) return;
+ ssc << lc1;
+
+ for (int i=0; i<(int)cmdsfp->size(); i++) {
+ (*cmdsfp)[i].print_using_words_fm(ssc);
+ //(*cmdsfp)[i].print_all_words(ssc);
+ //(*cmdsfp)[i].print_original_string(ssc);
+ ssc << endl;
+ }
+
+ for (int wt=0; wt<(int)whenthens.size(); wt++) {
+ ssc << "when (";
+ whenthens[wt].list_condition("", " ", ssc);
+ ssc << ") then " << endl;
+ whenthens[wt].list_cmdsf_ss(ssc);
+ ssc << "endwhen" << endl;
+ }
+
+ ssc << lc2;
+}
+
+
+void PowerParser::list_wt_cmdsf()
+{
+ stringstream ssc;
+ list_wt_cmdsf_ss(ssc);
+ if (comm->isIOProc()) {
+ cout << ssc.str();
+ }
+}
+
+void PowerParser::list_wt_cmdsf_start()
+{
+ ssfout.str("");
+ list_wt_cmdsf_ss(ssfout);
+ ssfout_current_pos = 0;
+}
+
+void PowerParser::list_wt_cmdsf_ss(stringstream &ssc)
+{
+ int wtlen = (int)whenthens.size();
+ if (wtlen <= 0) {
+ ssc << endl << "No when...then commands have been specified."
+ << endl << endl;
+ return;
+ }
+
+ for (int wt=0; wt<wtlen; wt++) {
+ ssc << endl;
+ ssc << "** Echo when...then final buffer, when...then number = "
+ << wt+1 << endl;
+ ssc << " Condition for this when...then =" << endl;
+ whenthens[wt].list_condition(" ", " ", ssc);
+ ssc << endl;
+ ssc << " Commands for this when...then =" << endl;
+ whenthens[wt].list_cmdsf_ss(ssc);
+ ssc << endl;
+ }
+}
+
+
+
+//+***************************************************************************
+// ***************************************************************************
+// Low level functions.
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Get a line from the ssfout stringstream.
+// ===========================================================================
+bool PowerParser::get_ssfout_line(string &sline)
+{
+ string s = ssfout.str();
+ if (!get_line_from_string(s, sline,
+ ssfout_current_pos)) return false;
+ return true;
+}
+
+
+// ===========================================================================
+// Broadcast the buffer the all the other processors.
+// ===========================================================================
+void PowerParser::broadcast_buffer(string &s_in)
+{
+ // If there is no comm or if there is only one processor, then we don't
+ // have to do anything.
+ if (comm == NULL) return;
+ if (comm->getNumProcs() == 1) return;
+
+ // Get the length of the input string on the io processor.
+ int cbuffer_len = 0;
+ if(comm->isIOProc()) cbuffer_len = (int)s_in.size();
+
+ // Broadcast the length of the input buffer to the other processors.
+ comm->broadcast((char*)&cbuffer_len, sizeof(int));
+
+ // All processors allocate memory for the buffer.
+ vector<char> cbuffer(cbuffer_len, 'a');
+
+ // The io processor fills the buffer from the string.
+ if(comm->isIOProc()) {
+ for (int i=0; i<cbuffer_len; i++) cbuffer[i] = s_in[i];
+ }
+
+ // The io processor broadcasts the buffer to everyone.
+ char *cb = &cbuffer[0];
+ comm->broadcast(cb, cbuffer_len);
+
+ // On all the other processors, copy the buffer into the string.
+ if(!comm->isIOProc()) {
+ s_in.resize(cbuffer_len);
+ for (int i=0; i<cbuffer_len; i++) s_in[i] = cbuffer[i];
+ }
+}
+
+
+
+// ===========================================================================
+// Get the next line from the buffer without any processing.
+// Starting at the current position in the buffer, current_pos, search for
+// the next \n. The output string is from the current position to the \n (but
+// does not include the \n). Also remove any \r in the string.
+// ===========================================================================
+bool PowerParser::get_line_from_string(string &strn, string &sout, int ¤t_pos)
+{
+ // Default the output.
+ sout = "";
+
+ // If the current position is at or beyond the end of the input string,
+ // then nothing further needs to be done.
+ int strn_len = (int)strn.size();
+ if (current_pos >= strn_len) return false;
+
+ for (int i = current_pos; i<strn_len; i++) {
+ // If we encounter an eol, then we are done.
+ if (strn[i] == '\n') {
+ current_pos = i+1;
+ return true;
+ }
+
+ // Some systems use \r\n instead of \n only. Ignore any \r characters.
+ if (strn[i] == '\r') continue;
+
+ // If we get to this point, then all that remains is to add the
+ // character to the output string.
+ sout += strn[i];
+ }
+
+ // If we reach this point then we have gone through the entire input
+ // string and have found that it does not end in a \n. This is ok and does
+ // happen sometimes. We just set the current position to one past the
+ // end of the buffer and return success.
+ current_pos = strn_len;
+ return true;
+}
+
+
+// ===========================================================================
+// This is similar to the get_line_from_string() but this routine gets
+// lines from the input string that are separated by semicolons.
+// Starting at the current position in the buffer, current_pos, search for
+// the next ;. The output string is from the current position to the ; (but
+// does not include the ;).
+// ===========================================================================
+bool PowerParser::get_sc_line_from_string(string &strn, string &sout, int ¤t_pos)
+{
+ // Default the output.
+ sout = "";
+
+ // If the current position is at or beyond the end of the input string,
+ // then nothing further needs to be done.
+ int strn_len = (int)strn.size();
+ if (current_pos >= strn_len) return false;
+
+ bool ignore_sc = false;
+ for (int i = current_pos; i<strn_len; i++) {
+ if (strn[i] == '!') ignore_sc = true;
+ if (strn[i] == '#') ignore_sc = true;
+ if (i < strn_len-1) {
+ if (strn[i] == '/' && strn[i+1] == '/') ignore_sc = true;
+ }
+
+ // If we encounter a semicolon, then we are done.
+ if (!ignore_sc) {
+ if (strn[i] == ';') {
+ current_pos = i+1;
+ return true;
+ }
+ }
+
+ // If we get to this point, then all that remains is to add the
+ // character to the output string.
+ sout += strn[i];
+ }
+
+ // If we reach this point then we have gone through the entire input
+ // string and have found that it does not end in a ;. This is ok and does
+ // happen sometimes. We just set the current position to one past the
+ // end of the buffer and return success.
+ current_pos = strn_len;
+ return true;
+}
+
+
+// ===========================================================================
+// Get rid of leading and trailing blanks and tabs.
+// ===========================================================================
+void PowerParser::eliminate_white_space(string &sline)
+{
+ int NPOS = (int)string::npos;
+
+ // Eliminate leading stuff first.
+ int len = (int)sline.size();
+ if (len == 0) return;
+ string whitespace = " \t";
+ int istart = sline.find_first_not_of(whitespace, 0);
+ if (istart == NPOS) istart = (int)sline.size();
+ sline.erase(0, istart);
+
+ // Now eliminate trailing stuff.
+ len = (int)sline.size();
+ if (len == 0) return;
+ int iend = sline.find_last_not_of(whitespace, len - 1);
+ if (iend == NPOS) return;
+ sline.erase(iend+1, (len-1) -(iend+1) + 1);
+
+ return;
+}
+
+
+// ===========================================================================
+// Convert an array of characters into a vector of C++ strings.
+//
+// chars_1d The array of characters (input). This is composed of a sequence
+// of strings, each one nchar long. The number of strings is nv.
+// vstr Vector of C++ strings (output). There will be nv number of
+// C++ strings in this vector. The length of each C++ string will
+// vary depending on how much white space is removed.
+// nv Number of strings in chars_1d (input).
+// nchar Number of characters in each string in chars_1d (input).
+//
+// Why would anyone want to do this?
+// When passing strings between Fortran and C++ it is cleaner and easier to
+// pass a packed array of single characters. This routine takes that packed
+// array and converts it to something familiar to C++ developers.
+// ===========================================================================
+void PowerParser::chars_to_vstr(char *chars_1d, vector<string> &vstr,
+ int nv, int nchar)
+{
+ // Temporary storage for each string in the array of characters.
+ char *cnchar = new char[nchar];
+
+ // Loop through all the strings in the array of characters.
+ for (int i=0; i<nv; i++) {
+
+ // Copy each string in the 1d array into a temporary array of chars.
+ // This will be used to create the C++ string.
+ int istart = i * nchar;
+ for (int c=istart; c<istart+nchar; c++) {
+ cnchar[c-istart] = chars_1d[c];
+ }
+ int cnchar_len = nchar;
+
+ // Remove trailing spaces.
+ for (int c=nchar-1; c >= 0; c--) {
+ if (cnchar[c] != ' ') {
+ cnchar_len = c+1;
+ break;
+ }
+ }
+
+ // Create the C++ string.
+ string s(cnchar,cnchar_len);
+
+ // Remove leading spaces.
+ int i2=0;
+ for (int c=0; c<(int)s.size(); c++) {
+ if (s[c] != ' ') {
+ i2=c;
+ break;
+ }
+ }
+ if (i2 != 0) s.erase(s.begin(), s.begin()+i2);
+
+ // Add the string to the vector of strings.
+ vstr.push_back(s);
+ }
+ delete [] cnchar;
+}
+
+
+// ===========================================================================
+// Convert a vector of C++ strings into a packed array of characters.
+//
+// chars_1d The array of characters (output). This is composed of a sequence
+// of strings, each one nchar long. The number of strings is nv.
+// vstr Vector of C++ strings (input). There will be nv number of
+// C++ strings in this vector. The length of each C++ string will
+// vary, whitespace is added to each C++ string to make its length
+// nchar.
+// nv Number of strings in chars_1d (input).
+// nchar Number of characters in each string in chars_1d (input).
+//
+// Why would anyone want to do this?
+// When passing strings between Fortran and C++ it is cleaner and easier to
+// pass a packed array of single characters. This routine takes the vector
+// of strings and converts that to a packed character array.
+// ===========================================================================
+void PowerParser::vstr_to_chars(char *chars_1d, vector<string> &vstr,
+ int nv, int nchar)
+{
+ // To suppress compiler warnings of unused parameters
+ assert(nv == nv);
+
+ // Loop through each string in the vector of strings.
+ for (int strdex=0; strdex<(int)vstr.size(); strdex++) {
+
+ // Starting location in the 1d array of characters for each string.
+ int i1d = strdex * nchar;
+
+ // Number of characters in the C++ string. Should be smaller or
+ // equal to nchar, but we handle the case where it is larger
+ // than nchar.
+ int nc = (int)vstr[strdex].size();
+ if (nc > nchar) nc = nchar;
+
+ // Copy the string into the 1d character array.
+ for (int c=i1d; c<i1d+nc; c++) {
+ chars_1d[c] = vstr[strdex][c-i1d];
+ }
+
+ // Pad with blanks.
+ for (int c=i1d+nc; c<i1d+nchar; c++) {
+ chars_1d[c] = ' ';
+ }
+ }
+}
+
+
+
+
+} // end of PP namespace
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/PowerParser.hh
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/PowerParser.hh?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/PowerParser.hh (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/PowerParser.hh Sun Sep 3 20:10:18 2017
@@ -0,0 +1,717 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+// ***************************************************************************
+// ***************************************************************************
+// Provide a class that parses text files into lines and words.
+// ***************************************************************************
+// ***************************************************************************
+#ifndef PARSEHHINCLUDE
+#define PARSEHHINCLUDE
+
+// Need to include Cmd.hh because on the PGI compiler, the deque<Cmd>
+// declaration did not work with just doing "class Cmd;", we need to fully
+// include Cmd.hh.
+#include "Comm.hh"
+#include <sstream>
+#include <fstream>
+#include "Word.hh"
+#include "Cmd.hh"
+#include "Restartblock.hh"
+#include "Whenthen.hh"
+
+/****************************************************************//**
+ * PP is the namespace for PowerParser. Example:
+ *
+ * using namespace PP;
+ *******************************************************************/
+namespace PP
+{
+using std::ofstream;
+using std::streambuf;
+
+/****************************************************************//**
+ * PowerParser class
+ * Provide a class that parses text files into lines and words.
+ *******************************************************************/
+class PowerParser
+{
+
+public:
+
+ ofstream fileout;
+ streambuf *coutbuf;
+
+ // Constructors, destructors and drivers.
+/****************************************************************//**
+ * \brief
+ * Constructor with no arguments
+ *
+ * Typical Usage
+ *
+ * PowerParser parse;
+ * or
+ * PowerParser *parse = new PowerParser();
+ *******************************************************************/
+ PowerParser(void);
+
+/****************************************************************//**
+ * \brief
+ * Constructor -- with input filename in string format
+ *
+ * **Parameters**
+ * * string filename[in] -- the input file. The file will be
+ * read in, broadcast, and then parsed
+ *
+ * Typical Usage
+ *
+ * string fin("simfile.in");
+ * PowerParser parse(fin);
+ * or
+ * string fin("simfile.in");
+ * PowerParser *parse = new PowerParser(fin);
+ *******************************************************************/
+ PowerParser(string filename);
+
+/****************************************************************//**
+ * \brief
+ * Constructor -- with input filename in char array format
+ *
+ * **Parameters**
+ * * const char *filename[in] -- the input file. The file will be
+ * read in, broadcast, and then parsed
+ *
+ * Typical Usage
+ *
+ * PowerParser parse("simfile.in");
+ * or
+ * PowerParser *parse = new PowerParser("simfile.in");
+ *******************************************************************/
+ PowerParser(const char *filename);
+
+/****************************************************************//**
+ * \brief
+ * Destructor with no arguments
+ *
+ * Typical Usage
+ *
+ * delete parse;
+ *******************************************************************/
+ ~PowerParser(void);
+
+ void dictionary_add(char *name, double value, bool pred, char *vdesc);
+ void dictionary_env_add(char *name, bool pred);
+
+/****************************************************************//**
+ * \brief
+ * Reads the file in on the IO processor, broadcast the string
+ * to all the other processors, then parse the string.
+ *
+ * **Parameters**
+ * * string filename
+ *
+ * Typical Usage
+ *
+ * string fin("simfile.in");
+ * PowerParser parse();
+ * parse.parse_file(fin);
+ *******************************************************************/
+ void parse_file(string filename);
+
+/****************************************************************//**
+ * \brief
+ * Reads the file in on the IO processor, broadcast the string
+ * to all the other processors, then parse the string.
+ *
+ * **Parameters**
+ * * const char *filename
+ *
+ * Typical Usage
+ *
+ * PowerParser parse();
+ * parse.parse_file("simfile.in");
+ *******************************************************************/
+ void parse_file(const char *filename);
+
+/****************************************************************//**
+ * \brief
+ * Given a multi-line string on every processor, parse it into cmds
+ * and words. After calling this function, the parser is ready for use.
+ *******************************************************************/
+ void parse_string(string filename, string s_in);
+
+/****************************************************************//**
+ * \brief
+ * The input file(s) has been read and put into commands. Now do the
+ * compilation phase.
+ *******************************************************************/
+ void compile_buffer(int &return_value);
+
+/****************************************************************//**
+ * \brief
+ * Handle the execution line arguments
+ *******************************************************************/
+ void handle_exe_args(string other_argggs);
+
+/****************************************************************//**
+ * \brief
+ * Clear out the parser and re-init
+ *******************************************************************/
+ void clear_and_init();
+
+/****************************************************************//**
+ *******************************************************************/
+ void store_exe_args(string &oargs, string &fname) {
+ other_args = oargs;
+ file_name = fname;
+ }
+
+/****************************************************************//**
+ *******************************************************************/
+ void get_exe_args(string &oargs, string &fname) {
+ oargs = other_args;
+ fname = file_name;
+ }
+
+/****************************************************************//**
+ * \brief
+ * String version of the driver for getting boolean values as integers.
+ * This works for arrays of any dimension, 0,1,2,3,...
+ *
+ * **Parameters**
+ * * string &cname -- key word in input file
+ * * int *cvalue -- variable to set in simulation code
+ * * const vector<int> &size = vector<int>() -- sizes of array,
+ * (default is null for a scalar).
+ * * bool skip = false -- skip setting variable, (default is false)
+ *
+ * Typical Usage
+ *
+ * for scalars
+ * string InputName("OutputGraphics");
+ * int iflag = 0;
+ * parse.get_bool_int(InputName, &iflag);
+ * or for arrays
+ * string InputName("OutputGraphicsTypes");
+ * vector<int> iflags[2] = {0, 0};
+ * vector<int> size = {2};
+ * parse.get_bool_int(InputName, &iflags[0], size);
+ *******************************************************************/
+ void get_bool_int(string &cname,
+ int *cvalue,
+ const vector<int> &size = vector<int>(), // optional argument
+ bool skip = false); // optional argument
+
+/****************************************************************//**
+ * \brief
+ * String version of the driver for getting boolean values.
+ * This works for arrays of any dimension, 0,1,2,3,...
+ *
+ * **Parameters**
+ * * string &cname -- key word in input file
+ * * bool *cvalue -- variable to set in simulation code
+ * * const vector<int> &size = vector<int>() -- sizes of array,
+ * (default is null for a scalar).
+ * * bool skip = false -- skip setting variable, (default is false)
+ *
+ * Typical Usage
+ *
+ * for scalars
+ * string InputName("OutputGraphics");
+ * bool iflag = 0;
+ * parse.get_bool(InputName, &iflag);
+ * or for arrays
+ * string InputName("OutputGraphicsTypes");
+ * vector<bool> iflags[2] = {0, 0};
+ * vector<int> size = {2};
+ * parse.get_bool(InputName, &iflags[0], size);
+ *******************************************************************/
+ void get_bool(string &cname,
+ bool *cvalue,
+ const vector<int> &size = vector<int>(), // optional argument
+ bool skip = false); // optional argument
+
+/****************************************************************//**
+ * \brief
+ * String version of the driver for getting integer values.
+ * This works for arrays of any dimension, 0,1,2,3,...
+ *
+ * **Parameters**
+ * * const char *cname -- key word in input file
+ * * int *cvalue -- variable to set in simulation code. Int can be
+ * either standard int or long long int
+ * * const vector<int> &size = vector<int>() -- sizes of array,
+ * (default is null for a scalar).
+ * * bool skip = false -- skip setting variable, (default is false)
+ *
+ * Typical Usage
+ *
+ * for scalars
+ * int ivalue = 0;
+ * parse.get_int("Num_Cycles", &ivalue);
+ * or for arrays
+ * vector<int> ivalue[2] = {0, 0};
+ * vector<int> size = {2};
+ * parse.get_int("Dimensions", &ivalue[0], size);
+ *******************************************************************/
+ template< typename T >
+ void get_int(string &cname,
+ T *cvalue,
+ const vector<int> &size = vector<int>(), // optional argument
+ bool skip = false); // optional argument
+
+/****************************************************************//**
+ * \brief
+ * String version of the driver for getting real values.
+ * This works for arrays of any dimension, 0,1,2,3,...
+ *
+ * **Parameters**
+ * * const char *cname -- key word in input file
+ * * double *cvalue -- variable to set in simulation code.
+ * * const vector<int> &size = vector<int>() -- sizes of array,
+ * (default is null for a scalar).
+ * * bool skip = false -- skip setting variable, (default is false)
+ *
+ * Typical Usage
+ *
+ * for scalars
+ * double rvalue = 0;
+ * parse.get_real("TimeStop", &rvalue);
+ * or for arrays
+ * vector<double> rvalues[2] = {0.0, 0.0};
+ * vector<int> size = {2};
+ * parse.get_real("DumpTimes", &rvalues[0], size);
+ *******************************************************************/
+ void get_real(string &cname,
+ double *cvalue,
+ const vector<int> &size = vector<int>(), // optional argument
+ bool skip = false); // optional argument
+
+/****************************************************************//**
+ *******************************************************************/
+ void get_char(string &cname,
+ vector<string> &vstr,
+ const vector<int> &size = vector<int>(), // optional argument
+ bool single_char = false, // optional argument
+ bool skip = false); // optional argument
+
+ // These are just convenience function to allow char arrays for get variable so
+ // the calls are simpler. They convert the cname to a string and call the
+ // string versions above
+
+/****************************************************************//**
+ * \brief
+ * Char array version of the driver for getting boolean values as integers.
+ * This works for arrays of any dimension, 0,1,2,3,...
+ *
+ * **Parameters**
+ * * const char *cname -- key word in input file
+ * * int *cvalue -- variable to set in simulation code
+ * * const vector<int> &size = vector<int>() -- sizes of array,
+ * (default is null for a scalar).
+ * * bool skip = false -- skip setting variable, (default is false)
+ *
+ * Typical Usage
+ *
+ * for scalars
+ * int iflag = 0;
+ * parse.get_bool_int("OutputGraphics", &iflag);
+ * or for arrays
+ * vector<int> iflags[2] = {0, 0};
+ * vector<int> size = {2};
+ * parse.get_bool_int("OutputGraphicsTypes", &iflags[0], size);
+ *******************************************************************/
+ void get_bool_int(const char *cname,
+ int *cvalue,
+ const vector<int> &size = vector<int>(), // optional argument
+ bool skip = false); // optional argument
+
+/****************************************************************//**
+ * \brief
+ * Char array version of the driver for getting boolean values.
+ * This works for arrays of any dimension, 0,1,2,3,...
+ *
+ * **Parameters**
+ * * const char *cname -- key word in input file
+ * * bool *cvalue -- variable to set in simulation code
+ * * const vector<int> &size = vector<int>() -- sizes of array,
+ * (default is null for a scalar).
+ * * bool skip = false -- skip setting variable, (default is false)
+ *
+ * Typical Usage
+ *
+ * for scalars
+ * bool iflag = 0;
+ * parse.get_bool("OutputGraphics", &iflag);
+ * or for arrays
+ * vector<bool> iflags[2] = {0, 0};
+ * vector<int> size = {2};
+ * parse.get_bool("OutputGraphicsTypes", &iflags[0], size);
+ *******************************************************************/
+ void get_bool(const char *cname,
+ bool *cvalue,
+ const vector<int> &size = vector<int>(), // optional argument
+ bool skip = false); // optional argument
+
+/****************************************************************//**
+ * \brief
+ * Char array version of the driver for getting integer values.
+ * This works for arrays of any dimension, 0,1,2,3,...
+ *
+ * **Parameters**
+ * * const char *cname -- key word in input file
+ * * int *cvalue -- variable to set in simulation code. Int can be
+ * either standard int or long long int
+ * * const vector<int> &size = vector<int>() -- sizes of array,
+ * (default is null for a scalar).
+ * * bool skip = false -- skip setting variable, (default is false)
+ *
+ * Typical Usage
+ *
+ * for scalars
+ * int ivalue = 0;
+ * parse.get_int("Num_Cycles", &ivalue);
+ * or for arrays
+ * vector<int> ivalue[2] = {0, 0};
+ * vector<int> size = {2};
+ * parse.get_int("Dimensions", &ivalue[0], size);
+ *******************************************************************/
+ template< typename T >
+ void get_int(const char *cname,
+ T *cvalue,
+ const vector<int> &size = vector<int>(), // optional argument
+ bool skip = false); // optional argument
+
+/****************************************************************//**
+ * \brief
+ * Char array version of the driver for getting real values.
+ * This works for arrays of any dimension, 0,1,2,3,...
+ *
+ * **Parameters**
+ * * const char *cname -- key word in input file
+ * * double *cvalue -- variable to set in simulation code.
+ * * const vector<int> &size = vector<int>() -- sizes of array,
+ * (default is null for a scalar).
+ * * bool skip = false -- skip setting variable, (default is false)
+ *
+ * Typical Usage
+ *
+ * for scalars
+ * double rvalue = 0;
+ * parse.get_real("TimeStop", &rvalue);
+ * or for arrays
+ * vector<real> rvalue[2] = {0.0, 0.0};
+ * vector<int> size = {2};
+ * parse.get_real("DumpTimes", &rvalue[0], size);
+ *******************************************************************/
+ void get_real(const char *cname,
+ double *cvalue,
+ const vector<int> &size = vector<int>(), // optional argument
+ bool skip = false); // optional argument
+
+/****************************************************************//**
+ *******************************************************************/
+ void get_char(const char *cname,
+ vector<string> &vstr,
+ const vector<int> &size = vector<int>(), // optional argument
+ bool single_char = false, // optional argument
+ bool skip = false); // optional argument
+
+
+/****************************************************************//**
+ * \brief
+ * Driver for getting array sizes.
+ *******************************************************************/
+ void get_size(string &cname, vector<int> &size);
+
+/****************************************************************//**
+ * \brief
+ * Driver for getting array sizes. Version to get all sizes
+ *******************************************************************/
+ void get_sizeb(string &cname, vector<int> &size);
+
+
+/****************************************************************//**
+ * \brief
+ * Check if the input command, cname, appears in the final, parsed user input.
+ *
+ * The two outputs are in_input and in_whenthen,
+ * in_input command is in (or not) the main part of the input, i.e.
+ * everything except the when...then statements.
+ * in_whenthen command is in (or not) at least one when...then statement.
+ *******************************************************************/
+ void cmd_in_input(string &cname, bool &in_input, bool &in_whenthen);
+
+/****************************************************************//**
+ * \brief
+ * Set the processed flag for all words for all commands that match cname.
+ * The value to set the processed flag to is bval.
+ * This sets the processed flag for commands in the final buffer and in the
+ * when...then final buffers.
+ *******************************************************************/
+ void cmd_set_processed(string &cname, bool bval);
+
+/****************************************************************//**
+ * \brief
+ * Check all processed flags on every command. If any word on any command
+ * has not been processed, then that is a fatal error.
+ *******************************************************************/
+ void check_processed(bool &good);
+
+/****************************************************************//**
+ * \brief
+ * If commands appear more than once in the input file(s), print a warning
+ * to the user.
+ *******************************************************************/
+ void check_duplicates();
+
+
+/****************************************************************//**
+ * \brief
+ * Echo user input to a stringstream.
+ *******************************************************************/
+ void echo_input_start();
+
+/****************************************************************//**
+ * \brief
+ * Echo user input to a stringstream.
+ *******************************************************************/
+ void echo_input_ss(stringstream &ssinp);
+
+/****************************************************************//**
+ * Get a line from the ssfout stringstream. (low-level function)
+ *******************************************************************/
+ bool get_ssfout_line(string &sline);
+
+ // Communications object from the infrastructure.
+/****************************************************************//**
+ * \brief
+ * Holds internal comm class for PowerParser. Comm is initialized
+ * automatically and will use an already initialized MPI or
+ * initialize it itself. This is meant to be for use internal to
+ * the package, but developers can get the number of processors
+ * and rank with
+ *
+ * int mype = parse->comm->getProcRank();
+ * int npes = parse->comm->getNumProcs();
+ *******************************************************************/
+ Comm *comm;
+
+/****************************************************************//**
+ *******************************************************************/
+ void list_funcs_start();
+
+/****************************************************************//**
+ *******************************************************************/
+ void list_vars_start();
+
+/****************************************************************//**
+ *******************************************************************/
+ void list_cmdsf_start();
+
+/****************************************************************//**
+ *******************************************************************/
+ void list_wt_cmdsf_start();
+
+ void process_error_global(int &return_value);
+
+
+ void rb_check(vector<string> &code_varnames,
+ vector<string> &code_values,
+ vector<int> &vv_active, int *rbci,
+ int *rb_ntriggered, int *rb_triggered_indices);
+ int get_rb_num_varnames();
+ void get_rb_varnames(vector<string> &rb_varnames_vstr);
+ void get_num_rb(int *rbnum) { *rbnum = (int)restartblocks.size(); }
+ void set_num_rb(int rbnum) { nrb_on_dump = rbnum; }
+ void get_rb_names(vector<string> &rb_names_vstr);
+ void set_rb_names(vector<string> &rb_names_vstr);
+ void get_rb_aflags(int *rb_aflags);
+ void set_rb_aflags(int *rb_aflags, int rb_num);
+ void get_rb_satsize(int *rb_satsize);
+ void set_rb_satsize(int rb_satsize);
+ void get_rb_satprb(int *rb_satprb);
+ void set_rb_satprb(int *rb_satprb, int rb_num);
+ void get_rb_sat(int *rb_sat);
+ void set_rb_sat(int *rb_sat, int rb_satsize);
+ void list_rb();
+ void list_rb_start();
+ void list_rb_ss(stringstream &ssc);
+ void list_rb1_start(int *rb);
+ void list_rb1_ss(stringstream &ssc, int *rbp);
+ void list_one_rb_ss(stringstream &ssc, int rb);
+
+
+ void get_num_whenthen(int *wtnum) { *wtnum = (int)whenthens.size(); }
+ void wt_check(int wtn, vector<string> &code_varnames,
+ vector<string> &code_values,
+ vector<int> &vv_active, int *wtci);
+ void wt_set_cmdsfp(int wtn);
+ void wt_reset();
+ void wt_casize(int wtn, int *wt_casize);
+ void wt_carray(int wtn, char *wt_ca, int wt_casize);
+
+ void wt_satsize(int wtn, int *wt_satsize);
+ void wt_getsat(int wtn, int *wt_sat, int wt_satsize);
+ void wt_setsat(int wtn, int *wt_sat, int wt_satsize);
+ void wt_getprocessed(int wtn, int *wtp);
+ void wt_setprocessed(int wtn, int wtp);
+ void wt_getseq(int wtn, int *wtseq);
+ void wt_setseq(int wtn, int wtseq);
+
+ void chars_to_vstr(char *chars_1d, vector<string> &vstr,
+ int nv, int nchar);
+ void vstr_to_chars(char *chars_1d, vector<string> &vstr,
+ int nv, int nchar);
+
+ void ListIncludeFiles();
+ int NumIncludeFiles();
+ string GetIncludeFile(int);
+
+
+
+private:
+
+ void init();
+ int process_dav_cmd();
+ void check_dup_scalar(int wtn, bool &found_any);
+ void set_dup_row(vector<string> &row, Cmd &cmdi, int iw);
+ void remove_dup_scalar(int wtn);
+ void read_into_string(string filename, string &s_in);
+ void broadcast_buffer(string &s_in);
+ bool get_line_from_string(string &strn, string &sout, int ¤t_pos);
+ bool get_sc_line_from_string(string &strn, string &sout, int ¤t_pos);
+ void store_line_strings(string &s_in);
+ void eliminate_white_space(string &sline);
+ void cmd_set_reprocessed(bool bval);
+ int process_error_return_int(stringstream &serr, int &ierr);
+ void process_error(stringstream &serr, int &ierr);
+
+ void list_vars(string lv1, string lv2, string var_to_list);
+ void list_vars_ss(string lv1, string lv2, string var_to_list,
+ stringstream &ssvars);
+
+ void list_funcs(string lf1, string lf2);
+ void list_funcs_ss(string lf1, string lf2, stringstream &ssfunc);
+
+ void list_cmdsf(string lc1, string lc2);
+ void list_cmdsf_ss(string lc1, string lc2,
+ stringstream &ssc);
+ void list_wt_cmdsf();
+ void list_wt_cmdsf_ss(stringstream &ssc);
+
+ void print_strings(vector< vector<string> > rows, int n_header_rows,
+ int offset, int col_spacing, int line_len_max,
+ stringstream &ss);
+ bool end_do_loop(int &i, deque<int> &do_start,
+ stringstream &serr, int &ierr);
+ void end_do_ret(int &i, deque<int> &do_start,
+ stringstream &serr, int &ierr);
+ void check_enddo(deque<int> &do_start, stringstream &serr, int &ierr);
+ int jump_to_call(int &i, deque<int> &icall, deque<int> &isub,
+ stringstream &serr, int &ierr);
+ int jump_to_sub(int &i, string &sub_name,
+ stringstream &serr, int &ierr);
+ void print_line(int i);
+ void print_line(Cmd &cmd);
+
+ // Store exe line arguments.
+ string other_args, file_name;
+
+ // A double ended queue for storing the original lines. This is
+ // before the lines get turned into Cmds.
+ // line_number is an index into cmd_strings, note that it starts
+ // from 1, not 0.
+ deque<string> cmd_strings;
+ int line_number;
+
+ // Define a map for a set of variables.
+ map<string, Variable> vmap;
+
+ // Maintain a list of included files
+
+ std::map<int,string> IncludeFiles;
+
+ // Define a map for the functions.
+ map<string, Function> fmap;
+
+ // A double ended queue for storing the commands.
+ deque<Cmd> cmds;
+ deque<Cmd> cmdsf;
+ deque<Cmd> *cmdsfp;
+
+ // Store cmd names that have been processed, used for clearing and
+ // recreating the parser.
+ deque<string> processed_cmd_names;
+
+ // Related to writing output to a fortran file.
+ int ssfout_current_pos;
+ stringstream ssfout;
+
+ // Used for storing the list of pre-defined variables to be printed
+ // out later.
+ stringstream pre_defined_varss;
+
+ // Used for storing multiple errors and processing them later.
+ stringstream serr_global;
+ int ierr_global;
+
+ // The execution line arguments are put in this string.
+ string exe_args_str;
+
+ // The when ... then objects.
+ deque<Whenthen> whenthens;
+
+ // Restart blocks.
+ deque<Restartblock> restartblocks;
+ int nrb_on_dump;
+ deque<string> bnames_on_dump;
+ deque<bool> baflags_on_dump;
+ int satsize_on_dump;
+ deque<bool> rbsat_on_dump;
+ deque<int> rbsatprb_on_dump;
+
+ // Flag for whether duplicate array values will be none, fatal, or
+ // a warning, determined by the duplicate_array_values command.
+ // dup_fatal = 0 Turn off duplicate array value checking
+ // dup_fatal = 1 Duplicate array value checking is a warning
+ // dup_fatal = 2 Duplicate array value checking is a fatal error
+ int dup_fatal;
+};
+
+} // end of PP namespace
+
+#endif
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Restartblock.cc
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Restartblock.cc?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Restartblock.cc (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Restartblock.cc Sun Sep 3 20:10:18 2017
@@ -0,0 +1,598 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+// ***************************************************************************
+// ***************************************************************************
+// Restart Blocks
+// Run the code until a restart block condition is satisfied. Set the restart
+// block as active, write a restart dump, stop the code, and restart.
+// ***************************************************************************
+// ***************************************************************************
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <string>
+#include <vector>
+#include <deque>
+#include <sstream>
+#include <map>
+#include <math.h>
+
+#include "Variable.hh"
+#include "Function.hh"
+#include "Word.hh"
+#include "Parser_math.hh"
+#include "Cmd.hh"
+#include "Restartblock.hh"
+
+namespace PP
+{
+using std::cout;
+using std::endl;
+using std::string;
+using std::deque;
+using std::vector;
+using std::stringstream;
+using std::pair;
+using std::ifstream;
+using std::ios;
+
+
+// ===========================================================================
+// Default constructor.
+// ===========================================================================
+Restartblock::Restartblock()
+{
+ active = -1;
+}
+
+// ===========================================================================
+// Usual constructor.
+// restart_block name (time .eq. 50) then
+// ===========================================================================
+Restartblock::Restartblock(int &nrb, Cmd &cmdi, bool &skiprb,
+ bool &single_line_rb,
+ deque<string> &bnames_on_dump,
+ deque<bool> &baflags_on_dump,
+ deque<int> &rbsatprb_on_dump,
+ deque<bool> &rbsat_on_dump,
+ stringstream &serr, int &ierr)
+{
+ //cout << "&&&&&cw ********** Restartblock.cc, Enter Constructor **********" << endl;
+ active = -1;
+ nrb += 1;
+ skiprb = true;
+ single_line_rb = false;
+ int nwords = cmdi.get_nwords();
+
+ // &&&&&cw
+ //stringstream ssprint;
+ //cmdi.print_using_words(ssprint);
+ //cout << ssprint.str() << endl;
+
+ if (nwords < 8) {
+ cmdi.fatal_error(0, serr, ierr);
+ serr << "A restart block line must have at least 8 words on it (the "
+ << endl
+ << "opening and closing parentheses each count as a word)"
+ << endl;
+ serr << "This restart block command only has " << nwords <<
+ " words on it." << endl;
+ serr << "Expected something like (this has 8 words):" << endl;
+ serr << " restart_block after5 (time .gt. 5) then" << endl;
+ serr << "Or perhaps a single line restart block like (this has 13 words):"
+ << endl;
+ serr << " restart_block after5 (time .gt. 5) sizemat(2) = 0.005" << endl;
+ ierr = 2;
+ return;
+ }
+
+ string p2 = cmdi.get_string(2);
+ if (p2 != "(") {
+ cmdi.fatal_error(2, serr, ierr);
+ serr << "Expected an open parentheses following the restart block name.."
+ << endl;
+ serr << "Instead found " << p2 << " following the restart block name."
+ << endl;
+ serr << "The restart block command should be something like:" << endl;
+ serr << " restart_block t_is_gt_5 (time .gt. 5) then" << endl;
+ serr << "Or perhaps a single line restart block like:" << endl;
+ serr << " restart_block t_is_gt_5 (time .gt. 5) sizemat(2) = 0.005" << endl;
+ ierr = 2;
+ return;
+ }
+
+
+ for (int i=1; i<nwords-1; i++) {
+ string t1 = cmdi.get_string(i);
+ if (t1 == "then") {
+ cmdi.fatal_error(i, serr, ierr);
+ serr << "Found a then keyword embedded in the restart_block command."
+ << endl;
+ serr << "If a then keyword is present it must be the last "
+ "word on the line." << endl;
+ serr << "The restart_block command should be something like:" << endl;
+ serr << " restart_block t_is_gt_5 (time .gt. 5) then" << endl;
+ serr << "Or perhaps a single line restart block like:" << endl;
+ serr << " restart_block t_is_gt_5 (time .gt. 5) sizemat(2) = 0.005" << endl;
+ ierr = 2;
+ return;
+ }
+ }
+
+
+ // Find the closing parenthesis
+ int close_paren_dex = -1;
+ for (int i=2; i<nwords; i++) {
+ string pi = cmdi.get_string(i);
+ if (pi == "then") break;
+ if (pi == ")") {
+ close_paren_dex = i;
+ break;
+ }
+ }
+
+ if (close_paren_dex == -1) {
+ cmdi.fatal_error(0, serr, ierr);
+ serr << "Expected a close parentheses following the condition."
+ << endl;
+ serr << "Did not find a close parentheses." << endl;
+ serr << "The restart_block command should be something like:" << endl;
+ serr << " restart_block t_is_gt_5 (time .gt. 5) then" << endl;
+ serr << "Or perhaps a single line restart block like:" << endl;
+ serr << " restart_block t_is_gt_5 (time .gt. 5) sizemat(2) = 0.005" << endl;
+ ierr = 2;
+ return;
+ }
+
+
+ int nw = close_paren_dex - 3;
+ if ((nw+1)%4 != 0) {
+ cmdi.fatal_error(0, serr, ierr);
+ serr << "Wrong number of words in the restart_block condition."
+ << endl;
+ serr << "The number of words in this condition is " << nw << endl;
+ serr << "The number of words + 1 should be a multiple of 4." << endl;
+ serr << "The condition should be something like:" << endl;
+ serr << " time .gt. 5" << endl;
+ serr << "This has 3 words and 3+1 is a multiple of 4." << endl;
+ serr << "Or the following is valid" << endl;
+ serr << " time .gt. 5 .and. ncycle .ge. 10" << endl;
+ serr << "This has 7 words and 7+1 is a multiple of 4." << endl;
+ ierr = 2;
+ return;
+ }
+
+
+
+
+ for (int i=3; i<close_paren_dex; i+=4) {
+ add_word(cmdi, i, varname);
+ add_word(cmdi, i+1, relation);
+ add_word(cmdi, i+2, value);
+
+ if (i+3 < close_paren_dex) add_word(cmdi, i+3, logop);
+ else add_word(cmdi, i+3, logop, "none");
+
+ satisfied.push_back("false");
+ }
+
+
+ // Check to make sure that the relation is valid.
+ for (int n=0; n<(int)varname.size(); n++) {
+ bool valid_relation = false;
+ if (relation[n].get_string() == ".hglt.") valid_relation = true;
+ if (relation[n].get_string() == ".hgle.") valid_relation = true;
+ if (relation[n].get_string() == ".hgeq.") valid_relation = true;
+ if (relation[n].get_string() == ".hgne.") valid_relation = true;
+ if (relation[n].get_string() == ".hggt.") valid_relation = true;
+ if (relation[n].get_string() == ".hgge.") valid_relation = true;
+ if (relation[n].get_string() == ".lt.") valid_relation = true;
+ if (relation[n].get_string() == ".le.") valid_relation = true;
+ if (relation[n].get_string() == ".eq.") valid_relation = true;
+ if (relation[n].get_string() == ".ne.") valid_relation = true;
+ if (relation[n].get_string() == ".gt.") valid_relation = true;
+ if (relation[n].get_string() == ".ge.") valid_relation = true;
+
+ if (!valid_relation) {
+ relation[n].fatal_error(serr, ierr);
+ serr << "Invalid restart_block relation." << endl;
+ serr << "Expected .lt., .le., .eq., .ne., .gt., .ge." << endl;
+ serr << "Also could be .hglt., .hgle., .hgeq., .hgne., .hggt., .hgge." << endl;
+ serr << "Instead found relation: " << relation[n].get_string() << endl;
+ ierr = 2;
+ return;
+ }
+ }
+
+ // The name of the restart block is the second word on the
+ // restart_block command.
+ name = cmdi.get_string(1);
+ //cout << "&&&&&cw Restartblock.cc, name1 = " << name << endl;
+ //cout << "&&&&&cw Restartblock.cc, satsize = " << satisfied.size() << endl;
+
+ // If this is a restart, then restart block names and active flags
+ // could be stored on the restart dump. If this restart block matches
+ // any stored on the dump, then set the active flag to what is on
+ // the dump.
+ for (int i=0; i<(int)bnames_on_dump.size(); i++) {
+ //cout << "&&&&&cw Restartblock.cc, name = " << name << endl;
+ //cout << "&&&&&cw Restartblock.cc, bnames_on_dump = " <<
+ // bnames_on_dump[i] << endl;
+ //cout << "&&&&&cw Restartblock.cc, baflags_on_dump = " <<
+ // baflags_on_dump[i] << endl;
+ if (name == bnames_on_dump[i]) {
+ active = 0;
+ if (baflags_on_dump[i]) active = 1;
+
+ int satdex = 0;
+ for (int j=0; j<i; j++) {
+ satdex += rbsatprb_on_dump[j];
+ }
+ for (int j=satdex; j<satdex+rbsatprb_on_dump[i]; j++) {
+ string s = "false";
+ if (rbsat_on_dump[j]) s = "true";
+ satisfied[j-satdex] = s;
+ }
+
+ break;
+ }
+ }
+ //cout << "&&&&&cw Restartblock.cc, after set restart" << endl;
+
+
+ // If this restart block is active, that means we want to process
+ // the commands in the block, therefore we set the skip flag to false.
+ if (active == 1) skiprb = false;
+
+
+ // Set the has gotten to flags.
+ for (int n=0; n<(int)varname.size(); n++) {
+ bool hg = false;
+
+ if (relation[n].get_string() == ".hglt.") {
+ hg = true;
+ relation[n].set_value(".lt.");
+ }
+ else if (relation[n].get_string() == ".hgle.") {
+ hg = true;
+ relation[n].set_value(".le.");
+ }
+ else if (relation[n].get_string() == ".hgeq.") {
+ hg = true;
+ relation[n].set_value(".eq.");
+ }
+ else if (relation[n].get_string() == ".hgne.") {
+ hg = true;
+ relation[n].set_value(".ne.");
+ }
+ else if (relation[n].get_string() == ".hggt.") {
+ hg = true;
+ relation[n].set_value(".gt.");
+ }
+ else if (relation[n].get_string() == ".hgge.") {
+ hg = true;
+ relation[n].set_value(".ge.");
+ }
+
+
+ has_got.push_back(hg);
+ }
+
+
+ // Handle single line restart_block
+ if (cmdi.get_string(nwords-1) != "then") {
+ single_line_rb = true;
+ cmdi.delete_words(0, 5);
+ cmdi.reset_name_type();
+ }
+ //cout << "&&&&&cw ********** Restartblock.cc, Exit Constructor **********" << endl;
+}
+
+
+// ===========================================================================
+// Add word to the deque wq.
+// ===========================================================================
+void Restartblock::add_word(Cmd &cmdi, int idex, deque<Word> &wq)
+{
+ int ln = cmdi.get_line_number(idex);
+ int file_ln = cmdi.get_file_line_number(idex);
+ string fname = cmdi.get_filename(idex);
+ deque<string> *lines = cmdi.get_lines();
+ Word w(cmdi.get_string(idex), ln, file_ln, fname, lines);
+ wq.push_back(w);
+}
+
+void Restartblock::add_word(Cmd &cmdi, int idex, deque<Word> &wq, string sadd)
+{
+ int ln = cmdi.get_line_number(idex);
+ int file_ln = cmdi.get_file_line_number(idex);
+ string fname = cmdi.get_filename(idex);
+ deque<string> *lines = cmdi.get_lines();
+ Word w(sadd, ln, file_ln, fname, lines);
+ wq.push_back(w);
+}
+
+
+// ===========================================================================
+// This is the check for when the condition is satisfied.
+// ===========================================================================
+void Restartblock::check_rb(vector<string> &code_varnames,
+ vector<string> &code_values,
+ vector<int> &vv_active, int *rbci,
+ stringstream &serr, int &ierr)
+{
+ *rbci = 0;
+ //if (active==1) return;
+
+ Parser_math pmath;
+
+ deque<Word> wordsf;
+
+ bool skip_sat = false;
+ int num_sub_cond = (int)varname.size();
+ for (int n=0; n<num_sub_cond; n++) {
+ deque<Word> words;
+
+ if (satisfied[n] == "true") {
+ int ln = varname[n].get_line_number();
+ int file_ln = varname[n].get_file_line_number();
+ string fname = varname[n].get_filename();
+ deque<string> *lines = varname[n].get_lines();
+ Word w("true", ln, file_ln, fname, lines);
+ words.push_back(w);
+ }
+ else {
+ words.push_back(varname[n]);
+ words.push_back(relation[n]);
+ words.push_back(value[n]);
+
+ process_words(words, code_varnames, code_values, vv_active,
+ serr, ierr);
+
+ if (has_got[n]) {
+ if (words[0].get_bool(serr, ierr)) {
+ bool doit = true;
+ if (n > 0) {
+ if (logop[n-1].get_string() == ".andthen." && skip_sat) {
+ doit = false;
+ }
+ }
+ if (doit) satisfied[n] = "true";
+ }
+ else {
+ skip_sat = true;
+ }
+ }
+ }
+
+ wordsf.push_back(words[0]);
+ if (logop[n].get_string() == "none") break;
+ else wordsf.push_back(logop[n]);
+ }
+
+ process_words(wordsf, code_varnames, code_values, vv_active,
+ serr, ierr);
+
+ // rbci is an output flag telling the code to write a dump and end
+ // the calculation or not. rbci=0 means do not end the calc,
+ // rbci=1 tells the code to end the calc.
+ // Basically, if the condition changes from its previous value, then
+ // set rbci to 1.
+
+ // This is the current value of the condition that was calculated above.
+ bool b = wordsf[0].get_bool(serr, ierr);
+
+ // *rcbi is the key output result from this function
+ // *rbci = 0 Calling code does nothing
+ // *rbci = 1 Calling code stops calculation, normally does restart
+ *rbci = 0;
+
+ // Here we check to see if the condition has changed, i.e. is b different
+ // from the active flag. If so, then we end the calculation.
+ // When the restart block is first created, the active flag is set to -1,
+ // this is for runs from scratch.
+ // If this is a restart, then the active flag will come from the dump and
+ // be either 0 or 1.
+ // So if active is -1 and the condition is true, then we end the calculation
+ // right away (this should not be common, but could happen).
+ //
+ // Changed on 7/2/10 - The original idea for restart blocks was that they
+ // would trigger when the condition changed from false to true. But they
+ // would also trigger when the condition changed back from true to false.
+ // This causes problems for the users when the restart block would
+ // repeatedly trigger because the condition oscillates between true and
+ // false. Therefore, change the restart blocks so they trigger once and
+ // only once (which happens when the condition first becomes true). If
+ // the users ever need a restart block that also triggers when the
+ // condition changes from true to false, then some
+ // sort of option could be put in to allow this.
+ if (b && active == -1) { *rbci = 1; active = 1; return; } // Trigger
+ if (b && active == 0) { *rbci = 1; active = 1; return; } // Trigger
+ if (b && active == 1) { *rbci = 0; return; } // Do nothing
+ if (!b && active == -1) { *rbci = 0; active = 0; return; } // Do nothing
+ if (!b && active == 0) { *rbci = 0; return; } // Do nothing
+
+ // This is the true to false trigger that causes problems.
+ //if (!b && active == 1) { *rbci = 1; active = 0; return; } // Trigger
+}
+
+
+
+// ===========================================================================
+// Given a deque of words, go through them evaluating relational and logical
+// operators. The words should evaluate to one final word.
+// ===========================================================================
+void Restartblock::process_words(deque <Word> &words, vector<string> &code_varnames,
+ vector<string> &code_values,
+ vector<int> &vv_active,
+ stringstream &serr, int &ierr)
+{
+ Parser_math pmath;
+
+ // Replace any code vars with their values.
+ int i2 = (int)words.size();
+ for (int i=0; i<i2; i++) {
+ for (int j=0; j<(int)code_varnames.size(); j++) {
+ if (words[i].get_string() == code_varnames[j]) {
+ int ln = words[i].get_line_number();
+ int file_ln = words[i].get_file_line_number();
+ string fname = words[i].get_filename();
+ deque<string> *lines = words[i].get_lines();
+ if (vv_active[j] == 0) {
+ Word wj("false", ln, file_ln, fname, lines);
+ replace_words(i, i+2, words, wj);
+ i2 -= 2;
+ break;
+ }
+ else {
+ Word wj(code_values[j], ln, file_ln, fname, lines);
+ words[i] = wj;
+ }
+ }
+ }
+ }
+
+ int i1 = 0;
+ i2 = (int)words.size() - 1;
+ for (int level=6; level>=0; level--) {
+ for (int i=i1; i<=i2; i+=1) {
+ if (words[i].is_operator(level)) {
+ int ln = words[i].get_line_number();
+ int file_ln = words[i].get_file_line_number();
+ string fname = words[i].get_filename();
+ deque<string> *lines = words[i].get_lines();
+ Word w("", ln, file_ln, fname, lines);
+
+ string op_type = words[i].get_op_type();
+
+ if (op_type == "relational") {
+ pmath.do_op_relational(i-1, i, i+1, words, w, serr, ierr);
+ }
+
+ if (op_type == "logical" && level == 2) // .not. is unary
+ pmath.do_op_not(i, i+1, words, w, serr, ierr);
+
+ if (op_type == "logical" && level != 2)
+ pmath.do_op_logical(i-1, i, i+1, words, w, serr, ierr);
+
+ // level 2, .not., is unary and is handled differently.
+ if (level == 2) {
+ replace_words(i, i+1, words, w);
+ i2 -= 1;
+ }
+ else {
+ replace_words(i-1, i+1, words, w);
+ i2 -= 2;
+ i -= 1;
+ }
+ continue;
+ }
+ }
+ }
+
+ // The condition has to evaluate to a single boolean value.
+ if ((int)words.size() != 1) {
+ words[0].fatal_error(serr, ierr);
+ serr << "restart_block condition did not evaluate to a single boolean value."
+ << endl;
+ serr << "Fix the restart_block condition" << endl;
+ ierr = 2;
+ }
+}
+
+
+// ===========================================================================
+// List the condition for this restart block to a stringstream.
+// This is done to let the user indentify this restart block. It is
+// also useful for debugging.
+// ===========================================================================
+void Restartblock::list_condition(string offset1, string offset2,
+ stringstream &ssc)
+{
+ for (int n=0; n<(int)varname.size(); n++) {
+
+ string relstr = relation[n].get_string();
+ string rstr = relstr;
+ if (has_got[n]) {
+ if (relstr == ".lt.") rstr = ".hglt.";
+ if (relstr == ".le.") rstr = ".hgle.";
+ if (relstr == ".eq.") rstr = ".hgeq.";
+ if (relstr == ".ne.") rstr = ".hgne.";
+ if (relstr == ".gt.") rstr = ".hggt.";
+ if (relstr == ".ge.") rstr = ".hgge.";
+ }
+ relstr = rstr;
+
+ string offset = offset1;
+ if (n > 0) offset = offset2;
+
+ ssc << offset << varname[n].get_string() << " "
+ << relstr << " " << value[n].get_string();
+
+ if (logop[n].get_string() == "none") break;
+ ssc << " " << logop[n].get_string();
+ ssc << endl;
+ }
+}
+
+
+// ===========================================================================
+// Delete words i1 through i2 inclusive from the deque.
+// ===========================================================================
+void Restartblock::delete_words(int i1, int i2, deque <Word> &words)
+{
+ deque<Word>::iterator p = words.begin();
+ words.erase(p + i1, p + i2 + 1);
+}
+
+
+// ===========================================================================
+// Replace words i1 through i2 inclusive with word w.
+// ===========================================================================
+void Restartblock::replace_words(int i1, int i2, deque <Word> &words, Word &w)
+{
+ delete_words(i1, i2, words);
+ deque<Word>::iterator p = words.begin();
+ words.insert(p + i1, w);
+}
+
+
+
+} // End of the PP namespace
+
+
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Restartblock.hh
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Restartblock.hh?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Restartblock.hh (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Restartblock.hh Sun Sep 3 20:10:18 2017
@@ -0,0 +1,136 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+#ifndef RESTARTBLOCKHHINCLUDE
+#define RESTARTBLOCKHHINCLUDE
+
+// ***************************************************************************
+// ***************************************************************************
+// Restart Blocks
+// Run the code until a restart block condition is satisfied. Set the restart
+// block as active, write a restart dump, stop the code, and restart.
+// ***************************************************************************
+// ***************************************************************************
+
+#include <string>
+#include <deque>
+#include <vector>
+#include <map>
+#include <sstream>
+
+#include "Word.hh"
+
+namespace PP
+{
+using std::string;
+using std::deque;
+using std::vector;
+using std::map;
+using std::stringstream;
+
+class Restartblock
+{
+
+public:
+ Restartblock();
+ Restartblock(int &nrb, Cmd &cmdi, bool &skiprb,
+ bool &single_line_rb,
+ deque<string> &bnames_on_dump,
+ deque<bool> &baflags_on_dump,
+ stringstream &serr, int &ierr);
+
+ Restartblock(int &nrb, Cmd &cmdi, bool &skiprb,
+ bool &single_line_rb,
+ deque<string> &bnames_on_dump,
+ deque<bool> &baflags_on_dump,
+ deque<int> &rbsatprb_on_dump,
+ deque<bool> &rbsat_on_dump,
+ stringstream &serr, int &ierr);
+
+
+ void check_rb(vector<string> &code_varnames,
+ vector<string> &code_values,
+ vector<int> &vv_active, int *rbci,
+ stringstream &serr, int &ierr);
+
+ void list_condition(string offset1, string offset2,
+ stringstream &ssc);
+
+ string get_name() { return name; }
+ int get_aflag() { return active; }
+ void set_aflag(int af) { active = af; }
+ int get_satsize() { return (int)satisfied.size(); }
+ int get_sat(int j) { if (satisfied[j] == "true") return 1; return 0; }
+ int get_num_varnames() { return (int)varname.size(); }
+ string get_varname(int i) { return varname[i].get_string(); }
+
+
+private:
+
+ void add_word(Cmd &cmdi, int idex, deque<Word> &wq);
+ void add_word(Cmd &cmdi, int idex, deque<Word> &wq, string sadd);
+ void process_words(deque <Word> &words, vector<string> &code_varnames,
+ vector<string> &code_values, vector<int> &vv_active,
+ stringstream &serr, int &ierr);
+ void delete_words(int i1, int i2, deque <Word> &words);
+ void replace_words(int i1, int i2, deque <Word> &words, Word &w);
+
+
+ // The condition: varname relation value logical varname relation value etc.
+ // Example: time .gt. 3.0 .and. ncycle .ge. 50
+ // The condition is thought of as a sequence of subconditions connected by
+ // logical operators. The above example has two subconditions connected by the
+ // .and. logical operator.
+ deque<Word> varname; // Host code variable name to be replaced by host code value.
+ deque<Word> relation; // Relation between varname and value, like .gt., .hglt., ...
+ deque<Word> value; // Value to compare with host code value.
+ deque<Word> logop; // Logical operator connecting subconditions.
+ deque<string> satisfied; // Satisfied flag for each subcondition.
+ deque<bool> has_got; // Has got flag for the relation. This is true if
+ // the relation is .hggt., .hglt., ..., false otherwise.
+
+ // The restart_block commands are processed if active is true (== 1)
+ int active;
+
+ // The name of this restart block.
+ string name;
+};
+
+
+} // end of PP namespace
+
+#endif
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Variable.cc
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Variable.cc?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Variable.cc (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Variable.cc Sun Sep 3 20:10:18 2017
@@ -0,0 +1,491 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+// ***************************************************************************
+// ***************************************************************************
+// This class holds information about a variable. It is mostly for use with
+// the parser.
+// ***************************************************************************
+// ***************************************************************************
+
+#include <iostream>
+#include <iomanip>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <deque>
+
+#include "Parser_utils.hh"
+#include "Word.hh"
+#include "Variable.hh"
+
+namespace PP
+{
+using std:: string;
+using std::cout;
+using std::endl;
+using std::stringstream;
+using std::setprecision;
+using std::vector;
+using std::deque;
+
+static int index_base = 1;
+
+
+// ===========================================================================
+// Default constructor.
+// ===========================================================================
+Variable::Variable()
+{
+ name = "__NO_NAME_GIVEN__";
+ value.push_back("__NO_VALUE_GIVEN__");
+ ndim = -1;
+ lnum_ndim = 0;
+ lnum_bounds = 0;
+ pre_defined = false;
+ description = "";
+ temporary = false;
+}
+
+// ===========================================================================
+// Constructor to reset index base
+// ===========================================================================
+Variable::Variable(int base)
+{
+ index_base = base;
+}
+
+// ===========================================================================
+// Constructor given a string as input. This constructs a scalar variable.
+// ===========================================================================
+Variable::Variable(string nme, string v, bool pred, string tdes)
+{
+ name = nme;
+ value.push_back(v);
+ ndim = 0;
+ lnum_ndim = 0;
+ lnum_bounds = 0;
+ pre_defined = pred;
+ description = tdes;
+ temporary = false;
+}
+
+
+// ===========================================================================
+// Constructor for variables with no value.
+// ===========================================================================
+Variable::Variable(string nme)
+{
+ name = nme;
+ value.push_back("__NO_VALUE_GIVEN__");
+ ndim = -1;
+ lnum_ndim = 0;
+ lnum_bounds = 0;
+ pre_defined = false;
+ description = "";
+ temporary = false;
+}
+
+
+// ===========================================================================
+// Constructor given a vector of strings as input.
+// ===========================================================================
+Variable::Variable(string nme, vector<int> &istart, vector<string> &valvec,
+ int lnum, int file_lnum, string fname, deque<string> *lines,
+ stringstream &serr, int &ierr)
+{
+ name = nme;
+ ndim = -1;
+ lnum_ndim = 0;
+ lnum_bounds = 0;
+ pre_defined = false;
+ description = "";
+ temporary = false;
+ set_var_value(istart, valvec, lnum, file_lnum, fname, lines, serr, ierr);
+}
+
+
+// ===========================================================================
+// istart gives the starting location in the array for setting values.
+// The istart indices start from 1 (fortran based).
+//
+// This function works for any dimension, 0,1,2,3,...
+// ===========================================================================
+void Variable::set_var_value(vector<int> &istart, vector<string> &valvec,
+ int lnum, int file_lnum, string fname,
+ deque<string> *lines, stringstream &serr, int &ierr)
+{
+ // Cannot redefine a pre-defined variable.
+ if (pre_defined) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_lnum << ":" << endl;
+ serr << " " << (*lines)[lnum-1] << endl;
+ serr << "in file: " << fname << endl;
+ serr << "Cannot redefine a pre-defined variable." << endl;
+ ierr = 2;
+ return;
+ }
+
+ // Set the array dimension and make sure the user is not trying to
+ // change it.
+ int ndim_new = (int)istart.size();
+ if (ndim >= 0) {
+ if (ndim != ndim_new) {
+ // Throw an error
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_lnum << ":" << endl;
+ serr << " " << (*lines)[lnum-1] << endl;
+ serr << "in file: " << fname << endl;
+ serr << "Cannot redefine the dimensionality of a variable." << endl;
+ serr << "Original number of dimensions = " << ndim << endl;
+ serr << "New number of dimensions = " << ndim_new << endl;
+ if (lnum_ndim > 0) {
+ serr << "Previously set in line " << lnum_ndim << ":" << endl;
+ serr << " " << (*lines)[lnum_ndim-1] << endl;
+ }
+ ierr = 2;
+ return;
+ }
+ }
+ else {
+ ndim = ndim_new;
+ lnum_ndim = lnum;
+ }
+
+ int bsize = (int)maxdim.size();
+
+ if (ndim == 0 && bsize > 0) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_lnum << ":" << endl;
+ serr << " " << (*lines)[lnum-1] << endl;
+ serr << "in file: " << fname << endl;
+ serr << "Array boundaries not allowed for scalar variable." << endl;
+ if (lnum_bounds > 0) {
+ serr << "Array boundaries were set in line " << lnum_bounds << ":" << endl;
+ serr << " " << (*lines)[lnum_bounds-1] << endl;
+ }
+ ierr = 2;
+ return;
+ }
+
+ if (ndim > 0) {
+ if (ndim != bsize+1) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_lnum << ":" << endl;
+ serr << " " << (*lines)[lnum-1] << endl;
+ serr << "in file: " << fname << endl;
+ serr << "Number of dimensions = " << ndim << endl;
+ serr << "Number of array boundaries + 1 = " << bsize+1 << endl;
+ serr << "These should match but don't. " << endl;
+ ierr = 2;
+ return;
+ }
+ }
+
+ // Find the 1d starting position given multiple array indices.
+ Parser_utils putils(index_base);
+ int i1 = putils.start_dex(istart, maxdim);
+
+ // nvals Number of values after the = sign.
+ // Note that multiplicity is already handled, i.e. valvec has already
+ // been expanded to include multiplicites.
+ int nvals = (int)valvec.size();
+
+ // Get memory that we need.
+ if (i1+nvals > (int)value.size()) {
+ value.resize(i1+nvals, "");
+ }
+
+ // Store the array values.
+ for (int i=i1; i<i1+nvals; i++) {
+ value[i] = valvec[i-i1];
+ }
+}
+
+
+// ===========================================================================
+// Increment (or decrement) a variable value by an integer amount.
+// ===========================================================================
+void Variable::bump_var(vector<int> &istart, int increment,
+ int lnum, int file_lnum, string fname,
+ deque<string> *lines, stringstream &serr, int &ierr)
+{
+ // Find the 1d starting position given multiple array indices.
+ Parser_utils putils(index_base);
+ int i1 = putils.start_dex(istart, maxdim);
+
+ // We are incrementing an existing variable, so i1 should be valid.
+ if (i1 >= (int)value.size()) {
+ // Fatal Error
+ }
+
+ Word w1(value[i1], lnum, file_lnum, fname, lines);
+ if (!w1.is_number()) { } // FATAL ERROR
+
+ stringstream ss;
+ if (w1.is_integer()) {
+ int ia1 = w1.get_int(serr, ierr);
+ int ia = ia1 + increment;
+ ss << ia;
+ }
+ else {
+ double d1 = w1.get_double(serr, ierr);
+ double d = d1 + increment;
+ ss << setprecision(15) << d;
+ }
+ value[i1] = ss.str();
+}
+
+
+
+// ===========================================================================
+// The problem with multi-dimensional variable arrays is that the user has
+// to tell us the bounds on every dimension except the last one. This info
+// is input in the bounds vector and stored.
+//
+// This function works for any dimension, 0,1,2,3,...
+// ===========================================================================
+void Variable::set_bounds(vector<int> &bounds, int lnum, int file_lnum,
+ string fname, deque<string> *lines,
+ stringstream &serr, int &ierr)
+
+{
+ // Cannot redefine a pre-defined variable.
+ if (pre_defined) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_lnum << ":" << endl;
+ serr << " " << (*lines)[lnum-1] << endl;
+ serr << "in file: " << fname << endl;
+ serr << "Cannot redefine a pre-defined variable." << endl;
+ ierr = 2;
+ return;
+ }
+
+ // Set the array dimension and make sure the user is not trying to
+ // change it.
+ int ndim_new = (int)bounds.size() + 1;
+ if (ndim >= 0) {
+ if (ndim != ndim_new) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_lnum << ":" << endl;
+ serr << " " << (*lines)[lnum-1] << endl;
+ serr << "in file: " << fname << endl;
+ serr << "Cannot redefine the dimensionality of a variable "
+ "(set_bounds)." << endl;
+ serr << "Original number of dimensions = " << ndim << endl;
+ serr << "New number of dimensions = " << ndim_new << endl;
+ if (lnum_ndim > 0) {
+ serr << "Previously set in line " << lnum_ndim << ":" << endl;
+ serr << " " << (*lines)[lnum_ndim-1] << endl;
+ }
+ ierr = 2;
+ return;
+ }
+ }
+ else {
+ ndim = ndim_new;
+ lnum_ndim = lnum; // Store line num for better err messages.
+ }
+
+ // Check to make sure the user is not reseting the bounds.
+ if ((int)maxdim.size() > 0) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_lnum << ":" << endl;
+ serr << " " << (*lines)[lnum-1] << endl;
+ serr << "in file: " << fname << endl;
+ serr << "The bounds on this array has already been set," << endl;
+ serr << "cannot reset them." << endl;
+ if (lnum_bounds > 0) {
+ serr << "Previously set in line " << lnum_bounds << ":" << endl;
+ serr << " " << (*lines)[lnum_bounds-1] << endl;
+ }
+ ierr = 2;
+ return;
+ }
+
+ // Store the line num where bounds were set for better err messages.
+ lnum_bounds = lnum;
+
+ // Store the bounds.
+ maxdim.clear();
+ for (int i=0; i<(int)bounds.size(); i++) {
+ maxdim.push_back(bounds[i]);
+ }
+}
+
+
+// ===========================================================================
+// Given indices, in adex, get the value of the variable.
+// For example, suppose you want the value of
+// $var2d(3,5)
+// The adex vector contains 2 numbers, 3 and 5, for the fortran indices.
+// The start_dex function is used to get the 1d index into the value array.
+//
+// This function works for any dimension, 0,1,2,3,...
+// ===========================================================================
+string Variable::get_var_value(vector<int> &adex, string vname, int lnum,
+ int file_lnum, string fname, deque<string> *lines,
+ stringstream &serr, int &ierr)
+{
+ int adex_size = (int)adex.size();
+
+ // Special case for scalar variables.
+ if (ndim == 0 || adex_size == 0) return value[0];
+
+ // The adex indices and bounds indices must match.
+ if (adex_size - 1 != (int)maxdim.size()) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_lnum << ":" << endl;
+ serr << " " << (*lines)[lnum-1] << endl;
+ serr << "in file: " << fname << endl;
+ serr << "The dimensionality of variable " << vname << endl;
+ serr << "does not match what was previously set." << endl;
+ if (lnum_bounds > 0) {
+ serr << "Previous dimensionality set in line " << lnum_bounds << ":" << endl;
+ serr << " " << (*lines)[lnum_bounds-1] << endl;
+ }
+ ierr = 2;
+ return "";
+ }
+
+ // Indices cannot exceed max allowed.
+ // Remember that adex if referenced from 1 (fortran index).
+ for (int d=0; d<(int)maxdim.size(); d++) {
+ if (adex[d] > maxdim[d]) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_lnum << ":" << endl;
+ serr << " " << (*lines)[lnum-1] << endl;
+ serr << "in file: " << fname << endl;
+ serr << "Variable name = " << vname << endl;
+ serr << "The value for dimension " << d+1 << " = " << adex[d] << endl;
+ serr << "This exceeds the max dimension of " << maxdim[d] << endl;
+ if (lnum_bounds > 0) {
+ serr << "The array bounds were set in line " << lnum_bounds << ":" << endl;
+ serr << " " << (*lines)[lnum_bounds-1] << endl;
+ }
+ ierr = 2;
+ }
+ }
+
+ if (ierr == 2) return "";
+
+ // Indices cannot be < 1.
+ for (int d=0; d<(int)adex.size(); d++) {
+ if (adex[d] < 1) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_lnum << ":" << endl;
+ serr << " " << (*lines)[lnum-1] << endl;
+ serr << "in file: " << fname << endl;
+ serr << "Variable name = " << vname << endl;
+ serr << "Expected index greater than or equal to 1 " << endl;
+ serr << "Instead, index = " << adex[d] << endl;
+ ierr = 2;
+ }
+ }
+
+ if (ierr == 2) return "";
+
+
+ // Using the indices in adex and the bounds for multi-d arrays, maxdim,
+ // get the 1d index into the value array.
+ Parser_utils putils(index_base);
+ int i1 = putils.start_dex(adex, maxdim);
+
+ // Check that the value array size has not been exceeded.
+ if (i1 >= (int)value.size()) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_lnum << ":" << endl;
+ serr << " " << (*lines)[lnum-1] << endl;
+ serr << "in file: " << fname << endl;
+ serr << "Variable name = " << vname << endl;
+ serr << "Exceeded array bounds. Check to make sure you are not" << endl;
+ serr << "requesting an array element you have not yet set." << endl;
+
+ vector<int> maxdex((int)adex.size(), 0);
+ get_indices((int)value.size()-1, maxdex);
+ for (int d=0; d<(int)adex.size(); d++) {
+ string s = "";
+ if (adex[d] > maxdex[d]) s = " ERROR, max exceeded";
+ serr << " Requested index = " << adex[d]
+ << " Max index = " << maxdex[d] << s << endl;
+ }
+
+ ierr = 2;
+ return "";
+ }
+
+ // Return the value.
+ return value[i1];
+}
+
+
+
+// ===========================================================================
+// Given the 1d index, icdex (starting from 0), find the corresponding
+// multi dimensional fortran indices (each starting from 1).
+//
+// Example 1: Consider a 1d array
+// var1d(1) = 1 3 5 9 -4 -5 6
+// Suppose icdex=3, corresponding to array value 9.
+// This 1d case is very simple, all we do is add 1 to icdex to get a reference
+// from 1, thus returning 4.
+//
+// Example 1: Consider a 2d array
+// $var2d(1,1) = 11. 21. 31. 12. 22. 32. 13. 23. 33.
+// Where the max of the first dimension is 3. Suppose the user specifies
+// icdex = 5, this corresponds to array value 32. The two indices returned
+// would be 3,2 (referenced from 1).
+//
+// The adex vector contains the output indices, for example 2 this would be 3
+// and 2.
+//
+// This function works for any dimension, 0,1,2,3,...
+// ===========================================================================
+void Variable::get_indices(int icdex, vector<int> &adex)
+{
+ // Nothing to do for scalar variables.
+ if (ndim == 0) return;
+
+ // Given icdex, get the indices.
+ int nvalues = (int)value.size();
+ Parser_utils putils(index_base);
+ putils.reverse_dex(icdex, nvalues, adex, maxdim);
+}
+
+
+
+
+} // End of the PP namespace
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Variable.hh
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Variable.hh?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Variable.hh (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Variable.hh Sun Sep 3 20:10:18 2017
@@ -0,0 +1,130 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+#ifndef VARIABLEHHINCLUDE
+#define VARIABLEHHINCLUDE
+
+// ***************************************************************************
+// ***************************************************************************
+// This class holds information about a variable.
+// ***************************************************************************
+// ***************************************************************************
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <deque>
+
+namespace PP
+{
+using std::string;
+using std::stringstream;
+using std::vector;
+using std::deque;
+
+
+
+class Variable
+{
+
+public:
+ Variable();
+ Variable(int base);
+ Variable(string nme, string v, bool pred, string tdes);
+ Variable(string nme);
+ Variable(string nme, vector<int> &istart, vector<string> &vvec,
+ int lnum, int file_lnum, string fname, deque<string> *lines,
+ stringstream &serr, int &ierr);
+
+ // Accessor methods.
+ string get_varname() { return name; }
+ void set_varname(string s) { name = s; }
+ int get_ndim() { return ndim; }
+
+ int get_nvalues() { return (int)value.size(); }
+
+ string get_var_value() { return value[0]; }
+ string get_var_value(int idex) { return value[idex]; }
+ string get_var_value(vector<int> &adex, string vname, int lnum,
+ int file_lnum, string fname, deque<string> *lines,
+ stringstream &serr, int &ierr);
+
+
+ void set_var_value(vector<int> &istart, vector<string> &valvec,
+ int lnum, int file_lnum, string fname,
+ deque<string> *lines, stringstream &serr, int &ierr);
+ void bump_var(vector<int> &istart, int increment,
+ int lnum, int file_lnum, string fname,
+ deque<string> *lines, stringstream &serr, int &ierr);
+
+
+ void set_bounds(vector<int> &bounds, int lnum, int file_lnum,
+ string fname, deque<string> *lines,
+ stringstream &serr, int &ierr);
+
+ void get_indices(int icdex, vector<int> &adex);
+
+ string get_description() { return description; }
+ void set_description(string vardes) { description = vardes; }
+
+ bool is_pre_defined() { return pre_defined; }
+
+ void set_temporary(bool b) { temporary = b; }
+ bool is_temporary() { return temporary; }
+
+private:
+
+ // name The name of the variable.
+ // value Vector containing the values of the variable.
+ // ndim Number of dimensions, for example var(9,3) has ndim=2
+ // maxdim Max num for each dimension except the last.
+ // lnum_ndim The line number where ndim was set.
+ // lnum_bounds The line number where maxdim was set.
+ // pre_defined Pre-defined vars cannot be redefined.
+ // description Text description of the variable.
+ // temporary A temporary variable.
+ string name;
+ vector<string> value;
+ int ndim, lnum_bounds, lnum_ndim;
+ vector<int> maxdim;
+ bool pre_defined, temporary;
+ string description;
+};
+
+
+} // End of the PP namespace
+
+#endif
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Whenthen.cc
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Whenthen.cc?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Whenthen.cc (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Whenthen.cc Sun Sep 3 20:10:18 2017
@@ -0,0 +1,633 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+// ***************************************************************************
+// ***************************************************************************
+// ***************************************************************************
+// ***************************************************************************
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <string>
+#include <vector>
+#include <deque>
+#include <sstream>
+#include <map>
+#include <math.h>
+
+#include "Variable.hh"
+#include "Function.hh"
+#include "Word.hh"
+#include "Parser_math.hh"
+#include "Cmd.hh"
+#include "Whenthen.hh"
+
+namespace PP
+{
+using std::cout;
+using std::endl;
+using std::string;
+using std::deque;
+using std::vector;
+using std::stringstream;
+using std::pair;
+using std::ifstream;
+using std::ios;
+
+
+// ===========================================================================
+// Default constructor.
+// ===========================================================================
+Whenthen::Whenthen()
+{
+ processed = false;
+ seqdex = -1;
+ ever_flag = false;
+}
+
+
+// ===========================================================================
+// Usual constructor.
+// ===========================================================================
+Whenthen::Whenthen(int &nwhen, Cmd &cmdi, bool &skipwhen,
+ bool &single_line_when, bool eflag,
+ stringstream &serr, int &ierr)
+{
+ processed = false;
+ seqdex = -1;
+ ever_flag = eflag;
+ nwhen += 1;
+ skipwhen = true;
+ single_line_when = false;
+ int nwords = cmdi.get_nwords();
+
+ // &&&&&cw
+ //stringstream ssprint;
+ //cmdi.print_using_words(ssprint);
+ //cout << ssprint.str() << endl;
+
+ if (nwords < 7) {
+ cmdi.fatal_error(0, serr, ierr);
+ serr << "A when command line must have at least 7 words on it (the "
+ << endl
+ << "opening and closing parenthses each count as a word)"
+ << endl;
+ serr << "This when command only has " << nwords << " words on it." << endl;
+ serr << "Expected something like (this has 7 words):" << endl;
+ serr << " when (time .gt. 5) then" << endl;
+ serr << "Or perhaps a single line when like (this has 9 words):" << endl;
+ serr << " when (time .gt. 5) shortmodcyc = 5" << endl;
+ ierr = 2;
+ return;
+ }
+
+ string p1 = cmdi.get_string(1);
+ if (p1 != "(") {
+ cmdi.fatal_error(1, serr, ierr);
+ serr << "Expected an open parentheses following the when keyword."
+ << endl;
+ serr << "Instead found " << p1 << " following the when keyword."
+ << endl;
+ serr << "The when command should be something like:" << endl;
+ serr << " when (time .gt. 5) then" << endl;
+ serr << "Or perhaps a single line when like:" << endl;
+ serr << " when (time .gt. 5) shortmodcyc = 5" << endl;
+ ierr = 2;
+ return;
+ }
+
+
+ for (int i=1; i<nwords-1; i++) {
+ string t1 = cmdi.get_string(i);
+ if (t1 == "then") {
+ cmdi.fatal_error(i, serr, ierr);
+ serr << "Found a then keyword embedded in the when command."
+ << endl;
+ serr << "If a then keyword is present it must be the last "
+ "word on the line." << endl;
+ serr << "The when command should be something like:" << endl;
+ serr << " when (time .gt. 5) then" << endl;
+ serr << "Or perhaps a single line when like:" << endl;
+ serr << " when (time .gt. 5) shortmodcyc = 5" << endl;
+ ierr = 2;
+ return;
+ }
+ }
+
+
+ // Find the closing parenthesis
+ int close_paren_dex = -1;
+ for (int i=2; i<nwords; i++) {
+ string pi = cmdi.get_string(i);
+ if (pi == "then") break;
+ if (pi == ")") {
+ close_paren_dex = i;
+ break;
+ }
+ }
+
+ if (close_paren_dex == -1) {
+ cmdi.fatal_error(0, serr, ierr);
+ serr << "Expected a close parentheses following the condition."
+ << endl;
+ serr << "Did not find a close parentheses." << endl;
+ serr << "The when command should be something like:" << endl;
+ serr << " when (time .gt. 5) then" << endl;
+ serr << "Or perhaps a single line when like:" << endl;
+ serr << " when (time .gt. 5) shortmodcyc = 5" << endl;
+ ierr = 2;
+ return;
+ }
+
+
+ int nw = close_paren_dex - 2;
+ if ((nw+1)%4 != 0) {
+ cmdi.fatal_error(0, serr, ierr);
+ serr << "Wrong number of words in the when...then condition."
+ << endl;
+ serr << "The number of words in this condition is " << nw << endl;
+ serr << "The number of words + 1 should be a multiple of 4." << endl;
+ serr << "The condition should be something like:" << endl;
+ serr << " time .gt. 5" << endl;
+ serr << "This has 3 words and 3+1 is a multiple of 4." << endl;
+ serr << "Or the following is valid" << endl;
+ serr << " time .gt. 5 .and. ncycle .ge. 10" << endl;
+ serr << "This has 7 words and 7+1 is a multiple of 4." << endl;
+ ierr = 2;
+ return;
+ }
+
+
+
+
+ for (int i=2; i<close_paren_dex; i+=4) {
+ add_word(cmdi, i, varname);
+ add_word(cmdi, i+1, relation);
+ add_word(cmdi, i+2, value);
+
+ if (i+3 < close_paren_dex) add_word(cmdi, i+3, logop);
+ else add_word(cmdi, i+3, logop, "none");
+
+ satisfied.push_back("false");
+ }
+
+
+ // Check to make sure that the relation is valid.
+ for (int n=0; n<(int)varname.size(); n++) {
+ bool valid_relation = false;
+ if (relation[n].get_string() == ".hglt.") valid_relation = true;
+ if (relation[n].get_string() == ".hgle.") valid_relation = true;
+ if (relation[n].get_string() == ".hgeq.") valid_relation = true;
+ if (relation[n].get_string() == ".hgne.") valid_relation = true;
+ if (relation[n].get_string() == ".hggt.") valid_relation = true;
+ if (relation[n].get_string() == ".hgge.") valid_relation = true;
+ if (relation[n].get_string() == ".lt.") valid_relation = true;
+ if (relation[n].get_string() == ".le.") valid_relation = true;
+ if (relation[n].get_string() == ".eq.") valid_relation = true;
+ if (relation[n].get_string() == ".ne.") valid_relation = true;
+ if (relation[n].get_string() == ".gt.") valid_relation = true;
+ if (relation[n].get_string() == ".ge.") valid_relation = true;
+
+ if (!valid_relation) {
+ relation[n].fatal_error(serr, ierr);
+ serr << "Invalid when...then relation." << endl;
+ serr << "Expected .lt., .le., .eq., .ne., .gt., .ge." << endl;
+ serr << "Also could be .hglt., .hgle., .hgeq., .hgne., .hggt., .hgge." << endl;
+ serr << "Instead found relation: " << relation[n].get_string() << endl;
+ ierr = 2;
+ return;
+ }
+ }
+
+
+ // Set the has gotten to flags.
+ for (int n=0; n<(int)varname.size(); n++) {
+ bool hg = false;
+
+ if (relation[n].get_string() == ".hglt.") {
+ hg = true;
+ relation[n].set_value(".lt.");
+ }
+ else if (relation[n].get_string() == ".hgle.") {
+ hg = true;
+ relation[n].set_value(".le.");
+ }
+ else if (relation[n].get_string() == ".hgeq.") {
+ hg = true;
+ relation[n].set_value(".eq.");
+ }
+ else if (relation[n].get_string() == ".hgne.") {
+ hg = true;
+ relation[n].set_value(".ne.");
+ }
+ else if (relation[n].get_string() == ".hggt.") {
+ hg = true;
+ relation[n].set_value(".gt.");
+ }
+ else if (relation[n].get_string() == ".hgge.") {
+ hg = true;
+ relation[n].set_value(".ge.");
+ }
+
+
+ has_got.push_back(hg);
+ }
+
+
+ // Handle single line when...then
+ if (cmdi.get_string(nwords-1) != "then") {
+ single_line_when = true;
+ cmdi.delete_words(0, 5);
+ cmdi.reset_name_type();
+ skipwhen = false;
+ }
+}
+
+
+// ===========================================================================
+// Add word.
+// ===========================================================================
+void Whenthen::add_word(Cmd &cmdi, int idex, deque<Word> &wq)
+{
+ int ln = cmdi.get_line_number(idex);
+ int file_ln = cmdi.get_file_line_number(idex);
+ string fname = cmdi.get_filename(idex);
+ deque<string> *lines = cmdi.get_lines();
+ Word w(cmdi.get_string(idex), ln, file_ln, fname, lines);
+ wq.push_back(w);
+}
+
+void Whenthen::add_word(Cmd &cmdi, int idex, deque<Word> &wq, string sadd)
+{
+ int ln = cmdi.get_line_number(idex);
+ int file_ln = cmdi.get_file_line_number(idex);
+ string fname = cmdi.get_filename(idex);
+ deque<string> *lines = cmdi.get_lines();
+ Word w(sadd, ln, file_ln, fname, lines);
+ wq.push_back(w);
+}
+
+
+
+// ===========================================================================
+// Add a command to the deque of commands for this whenthen.
+// ===========================================================================
+void Whenthen::add_cmdf(Cmd &cmdi)
+{
+ cmdsf.push_back(cmdi);
+}
+
+
+// ===========================================================================
+// This is the check for when the condition is satisfied.
+// ===========================================================================
+void Whenthen::check_wt(vector<string> &code_varnames,
+ vector<string> &code_values,
+ vector<int> &vv_active,
+ int *wtci, stringstream &serr, int &ierr)
+{
+ *wtci = 0;
+ if (processed) return;
+
+ Parser_math pmath;
+
+ deque<Word> wordsf;
+
+ bool skip_sat = false;
+ int num_sub_cond = (int)varname.size();
+ for (int n=0; n<num_sub_cond; n++) {
+ deque<Word> words;
+
+ if (satisfied[n] == "true") {
+ int ln = varname[n].get_line_number();
+ int file_ln = varname[n].get_file_line_number();
+ string fname = varname[n].get_filename();
+ deque<string> *lines = varname[n].get_lines();
+ Word w("true", ln, file_ln, fname, lines);
+ words.push_back(w);
+ }
+ else {
+ words.push_back(varname[n]);
+ words.push_back(relation[n]);
+ words.push_back(value[n]);
+
+ process_words(words, code_varnames, code_values, vv_active,
+ serr, ierr);
+
+ if (has_got[n]) {
+ if (words[0].get_bool(serr, ierr)) {
+ bool doit = true;
+ if (n > 0) {
+ if (logop[n-1].get_string() == ".andthen." && skip_sat) {
+ doit = false;
+ }
+ }
+ if (doit) satisfied[n] = "true";
+ }
+ else {
+ skip_sat = true;
+ }
+ }
+ }
+
+ wordsf.push_back(words[0]);
+ if (logop[n].get_string() == "none") break;
+ else wordsf.push_back(logop[n]);
+ }
+
+ process_words(wordsf, code_varnames, code_values, vv_active,
+ serr, ierr);
+
+ // The output value, wtci, defaults to false (0). If the condition
+ // is satisfied then the output is true (1).
+ if (wordsf[0].get_bool(serr, ierr)) {
+ *wtci = 1;
+ if (!ever_flag) processed = true;
+ return;
+ }
+}
+
+
+
+// ===========================================================================
+// Given a deque of words, go through them evaluating relational and logical
+// operators. The words should evaluate to one final word.
+// ===========================================================================
+void Whenthen::process_words(deque <Word> &words, vector<string> &code_varnames,
+ vector<string> &code_values,
+ vector<int> &vv_active,
+ stringstream &serr, int &ierr)
+{
+ Parser_math pmath;
+
+ // Replace any code vars with their values.
+ int i2 = (int)words.size();
+ for (int i=0; i<i2; i++) {
+ for (int j=0; j<(int)code_varnames.size(); j++) {
+ if (words[i].get_string() == code_varnames[j]) {
+ int ln = words[i].get_line_number();
+ int file_ln = words[i].get_file_line_number();
+ string fname = words[i].get_filename();
+ deque<string> *lines = words[i].get_lines();
+ if (vv_active[j] == 0) {
+ Word wj("false", ln, file_ln, fname, lines);
+ replace_words(i, i+2, words, wj);
+ i2 -= 2;
+ break;
+ }
+ else {
+ Word wj(code_values[j], ln, file_ln, fname, lines);
+ words[i] = wj;
+ }
+ }
+ }
+ }
+
+ int i1 = 0;
+ i2 = (int)words.size() - 1;
+ for (int level=6; level>=0; level--) {
+ for (int i=i1; i<=i2; i+=1) {
+ if (words[i].is_operator(level)) {
+ int ln = words[i].get_line_number();
+ int file_ln = words[i].get_file_line_number();
+ string fname = words[i].get_filename();
+ deque<string> *lines = words[i].get_lines();
+ Word w("", ln, file_ln, fname, lines);
+
+ string op_type = words[i].get_op_type();
+
+ if (op_type == "relational") {
+ pmath.do_op_relational(i-1, i, i+1, words, w, serr, ierr);
+ }
+
+ if (op_type == "logical" && level == 2) // .not. is unary
+ pmath.do_op_not(i, i+1, words, w, serr, ierr);
+
+ if (op_type == "logical" && level != 2)
+ pmath.do_op_logical(i-1, i, i+1, words, w, serr, ierr);
+
+ // level 2, .not., is unary and is handled differently.
+ if (level == 2) {
+ replace_words(i, i+1, words, w);
+ i2 -= 1;
+ }
+ else {
+ replace_words(i-1, i+1, words, w);
+ i2 -= 2;
+ i -= 1;
+ }
+ continue;
+ }
+ }
+ }
+
+ // The condition has to evaluate to a single boolean value.
+ if ((int)words.size() != 1) {
+ words[0].fatal_error(serr, ierr);
+ serr << "When...then condition did not evaluate to a single boolean value."
+ << endl;
+ serr << "Fix the when...then condition" << endl;
+ ierr = 2;
+ }
+}
+
+
+// ===========================================================================
+// ===========================================================================
+void Whenthen::get_char_array_size(int *ca_size)
+{
+ string sc;
+ get_char_array(sc);
+ (*ca_size) = (int)sc.size();
+}
+
+
+// ===========================================================================
+// ===========================================================================
+void Whenthen::get_char_array(string &sc)
+{
+ for (int n=0; n<(int)varname.size(); n++) {
+ sc += varname[n].get_string();
+ sc += relation[n].get_string();
+ sc += value[n].get_string();
+ sc += logop[n].get_string();
+ if (has_got[n]) sc += "hasgot";
+ }
+ for (int n=0; n<(int)cmdsf.size(); n++) {
+ int nw = cmdsf[n].get_nwords();
+ for (int i=0; i<nw; i++) {
+ sc += cmdsf[n].get_string(i);
+ }
+ }
+}
+
+
+// ===========================================================================
+// ===========================================================================
+void Whenthen::get_satsize(int *sat_size)
+{
+ (*sat_size) = (int)satisfied.size();
+}
+
+
+// ===========================================================================
+// Get and Set the satisfied flags.
+// ===========================================================================
+void Whenthen::getsat(int *sat)
+{
+ for (int i=0; i<(int)satisfied.size(); i++) {
+ if (satisfied[i] == "true") sat[i] = 1;
+ if (satisfied[i] == "false") sat[i] = 0;
+ }
+}
+
+void Whenthen::setsat(int *sat)
+{
+ for (int i=0; i<(int)satisfied.size(); i++) {
+ if (sat[i] == 1) satisfied[i] = "true";
+ if (sat[i] == 0) satisfied[i] = "false";
+ }
+}
+
+
+// ===========================================================================
+// Get and Set the processed flag for a whenthen.
+// ===========================================================================
+void Whenthen::getprocessed(int *wtp)
+{
+ *wtp = 0;
+ if (processed) *wtp = 1;
+}
+
+void Whenthen::setprocessed(int wtp)
+{
+ processed = false;
+ if (wtp == 1) processed = true;
+}
+
+
+// ===========================================================================
+// Get and Set the sequence index.
+// ===========================================================================
+void Whenthen::getseq(int *wtseq)
+{
+ *wtseq = seqdex;
+}
+
+void Whenthen::setseq(int wtseq)
+{
+ seqdex = wtseq;
+}
+
+
+
+
+// ===========================================================================
+// List the final commands deque for this whenthen to a stringstream.
+// This is done to let the user know what the final commands are. It is
+// also useful for debugging.
+// ===========================================================================
+void Whenthen::list_cmdsf_ss(stringstream &ssc)
+{
+ for (int i=0; i<(int)cmdsf.size(); i++) {
+ ssc << " ";
+ cmdsf[i].print_using_words_fm(ssc);
+ ssc << endl;
+ }
+}
+
+
+// ===========================================================================
+// List the condition for this whenthen to a stringstream.
+// This is done to let the user indentify this whenthen. It is
+// also useful for debugging.
+// ===========================================================================
+void Whenthen::list_condition(string offset1, string offset2,
+ stringstream &ssc)
+{
+ for (int n=0; n<(int)varname.size(); n++) {
+
+ string relstr = relation[n].get_string();
+ string rstr = relstr;
+ if (has_got[n]) {
+ if (relstr == ".lt.") rstr = ".hglt.";
+ if (relstr == ".le.") rstr = ".hgle.";
+ if (relstr == ".eq.") rstr = ".hgeq.";
+ if (relstr == ".ne.") rstr = ".hgne.";
+ if (relstr == ".gt.") rstr = ".hggt.";
+ if (relstr == ".ge.") rstr = ".hgge.";
+ }
+ relstr = rstr;
+
+ string offset = offset1;
+ if (n > 0) offset = offset2;
+
+ ssc << offset << varname[n].get_string() << " "
+ << relstr << " " << value[n].get_string();
+
+ if (logop[n].get_string() == "none") break;
+ ssc << " " << logop[n].get_string();
+ ssc << endl;
+ }
+}
+
+
+// ===========================================================================
+// Delete words i1 through i2 inclusive from the deque.
+// ===========================================================================
+void Whenthen::delete_words(int i1, int i2, deque <Word> &words)
+{
+ deque<Word>::iterator p = words.begin();
+ words.erase(p + i1, p + i2 + 1);
+}
+
+
+// ===========================================================================
+// Replace words i1 through i2 inclusive with word w.
+// ===========================================================================
+void Whenthen::replace_words(int i1, int i2, deque <Word> &words, Word &w)
+{
+ delete_words(i1, i2, words);
+ deque<Word>::iterator p = words.begin();
+ words.insert(p + i1, w);
+}
+
+
+
+
+
+} // End of the PP namespace
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Whenthen.hh
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Whenthen.hh?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Whenthen.hh (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Whenthen.hh Sun Sep 3 20:10:18 2017
@@ -0,0 +1,139 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+#ifndef WHENTHENHHINCLUDE
+#define WHENTHENHHINCLUDE
+
+// ***************************************************************************
+// ***************************************************************************
+
+// ***************************************************************************
+// ***************************************************************************
+
+#include <string>
+#include <deque>
+#include <vector>
+#include <map>
+#include <sstream>
+
+#include "Word.hh"
+
+namespace PP
+{
+using std::string;
+using std::deque;
+using std::vector;
+using std::map;
+using std::stringstream;
+
+class Whenthen
+{
+
+public:
+ Whenthen();
+ Whenthen(int &nwhen, Cmd &cmdi, bool &skipwhen, bool &single_line_when,
+ bool eflag, stringstream &serr, int &ierr);
+ void add_cmdf(Cmd &cmdi);
+ void list_condition(string offset1, string offset2,
+ stringstream &ssc);
+ void list_cmdsf_ss(stringstream &ssc);
+
+ void check_wt(vector<string> &code_varnames,
+ vector<string> &code_values,
+ vector<int> &vv_active,
+ int *wtci, stringstream &serr, int &ierr);
+
+ deque<Cmd> *get_cmdsf_ptr() { return &cmdsf; }
+
+ void get_char_array_size(int *ca_size);
+ void get_char_array(string &sc);
+
+ void get_satsize(int *sat_size);
+ void getsat(int *sat);
+ void setsat(int *sat);
+ void getprocessed(int *wtp);
+ void setprocessed(int wtp);
+ void getseq(int *wtseq);
+ void setseq(int wtseq);
+ int get_num_varnames() { return (int)varname.size(); }
+ string get_varname(int i) { return varname[i].get_string(); }
+
+
+private:
+
+ void add_word(Cmd &cmdi, int idex, deque<Word> &wq);
+ void add_word(Cmd &cmdi, int idex, deque<Word> &wq, string sadd);
+ void process_words(deque <Word> &words, vector<string> &code_varnames,
+ vector<string> &code_values,
+ vector<int> &vv_active,
+ stringstream &serr, int &ierr);
+ void delete_words(int i1, int i2, deque <Word> &words);
+ void replace_words(int i1, int i2, deque <Word> &words, Word &w);
+
+ // The condition: varname relation value logical varname relation value etc.
+ // Example: time .gt. 3.0 .and. ncycle .ge. 50
+ // The condition is thought of as a sequence of subconditions connected by
+ // logical operators. The above example has two subconditions connected by the
+ // .and. logical operator.
+ deque<Word> varname; // Host code variable name to be replaced by host code value.
+ deque<Word> relation; // Relation between varname and value, like .gt., .hglt., ...
+ deque<Word> value; // Value to compare with host code value.
+ deque<Word> logop; // Logical operator connecting subconditions.
+ deque<string> satisfied; // Satisfied flag for each subcondition.
+ deque<bool> has_got; // Has got flag for the relation. This is true if
+ // the relation is .hggt., .hglt., ..., false otherwise.
+
+ // Commands to be done when the condition is satisfied.
+ deque<Cmd> cmdsf;
+
+ // The whenthen is only done once when the condition is satisfied.
+ // This flag keeps it from being done again.
+ bool processed;
+
+ // This flag is used to distinguish between the when command and the
+ // whenever command.
+ bool ever_flag;
+
+ // This is a sequence index to keep track of what order the whenthen's
+ // have been processed in.
+ int seqdex;
+};
+
+
+} // end of PP namespace
+
+#endif
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Word.cc
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Word.cc?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Word.cc (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Word.cc Sun Sep 3 20:10:18 2017
@@ -0,0 +1,1193 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+// ***************************************************************************
+// ***************************************************************************
+// This class holds each word from the line.
+// ***************************************************************************
+// ***************************************************************************
+
+#include <iostream>
+#include <iomanip>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <map>
+#include <deque>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#ifdef SGI
+#else
+#include <cctype>
+#endif
+
+#include "Word.hh"
+
+namespace PP
+{
+using std::string;
+using std::cout;
+using std::endl;
+//using std::isdigit;
+using std::stringstream;
+using std::setprecision;
+using std::vector;
+using std::map;
+using std::deque;
+using std::pair;
+
+
+// ===========================================================================
+// Default constructor.
+// ===========================================================================
+Word::Word()
+{
+ wstr = "";
+ init();
+}
+
+
+// ===========================================================================
+// Construct given a string.
+// ===========================================================================
+Word::Word(string s)
+{
+ wstr = s;
+ init();
+ set_type();
+}
+
+
+// ===========================================================================
+// Construct given a string. Also set the map of variables.
+// ===========================================================================
+Word::Word(string s, int lnum, int file_lnum, string fname,
+ deque<string> *lstr)
+{
+ wstr = s;
+ init();
+ line_number = lnum;
+ file_line_number = file_lnum;
+ filename = fname;
+ lines = lstr;
+ set_type();
+}
+
+
+// ===========================================================================
+// Construct given a double
+// ===========================================================================
+Word::Word(double d, int lnum, int file_lnum, string fname,
+ deque<string> *lstr)
+{
+ stringstream ss;
+ ss << setprecision(15) << d;
+ wstr = ss.str();
+ init();
+ type = DOUBLE;
+ line_number = lnum;
+ file_line_number = file_lnum;
+ filename = fname;
+ lines = lstr;
+}
+
+
+// ===========================================================================
+// Construct given an integer.
+// ===========================================================================
+Word::Word(int ia, int lnum, int file_lnum, string fname,
+ deque<string> *lstr)
+{
+ stringstream ss;
+ ss << ia;
+ wstr = ss.str();
+ init();
+ type = DOUBLE;
+ line_number = lnum;
+ file_line_number = file_lnum;
+ filename = fname;
+ lines = lstr;
+}
+
+
+// ===========================================================================
+/*! = operator. */
+// ===========================================================================
+Word Word::operator=(const Word &ws)
+{
+ if (&ws == this) return *this;
+ wstr = ws.wstr;
+ processed = ws.processed;
+ type = ws.type;
+ negate = ws.negate;
+ line_number = ws.line_number;
+ file_line_number = ws.file_line_number;
+ filename = ws.filename;
+ lines = ws.lines;
+ multiplicity = ws.multiplicity;
+ op_level = ws.op_level;
+ op_type = ws.op_type;
+ return *this;
+}
+
+
+// ===========================================================================
+/*! Copy constructor. */
+// ===========================================================================
+Word::Word(const Word &ws)
+{
+ wstr = ws.wstr;
+ processed= ws.processed;
+ type = ws.type;
+ negate = ws.negate;
+ line_number = ws.line_number;
+ file_line_number = ws.file_line_number;
+ filename = ws.filename;
+ lines = ws.lines;
+ multiplicity = ws.multiplicity;
+ op_level = ws.op_level;
+ op_type = ws.op_type;
+}
+
+
+// ===========================================================================
+// Common initialization routine called from constructors.
+// ===========================================================================
+void Word::init()
+{
+ processed = false;
+ type = WUNKNOWN;
+ negate = false;
+ lines = NULL;
+ line_number = 0;
+ file_line_number = 0;
+ filename = "";
+ multiplicity = 1;
+ op_level = -1;
+ op_type = "";
+}
+
+
+
+// ===========================================================================
+/*! Destructor */
+// ===========================================================================
+Word::~Word()
+{
+}
+
+
+// ***************************************************************************
+// ***************************************************************************
+// ***************************************************************************
+// Change the value of a word.
+// ***************************************************************************
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Set the word to a double.
+// ===========================================================================
+void Word::set_value(double d)
+{
+ stringstream ss;
+ ss << setprecision(15) << d;
+ wstr = ss.str();
+ set_type();
+}
+
+
+// ===========================================================================
+// Set the word to a string.
+// ===========================================================================
+void Word::set_value(string s)
+{
+ wstr = s;
+ set_type();
+}
+
+
+// ===========================================================================
+// Set the word to a string.
+// Use this when you want to do set_value("lasjdf"), otherwise c++ cannot
+// get which set_type to use (and it does not tell you it is having trouble).
+// ===========================================================================
+void Word::set_value(const char *s)
+{
+ wstr = s;
+ set_type();
+}
+
+
+// ===========================================================================
+// Set the word to a boolean.
+// ===========================================================================
+void Word::set_value(bool b)
+{
+ if (!b) wstr = "false";
+ if (b) wstr = "true";
+ set_type();
+}
+
+
+
+
+// ***************************************************************************
+// ***************************************************************************
+// ***************************************************************************
+// This section handles the type of the word, whether it is an operator,
+// a function, a string, etc.
+// ***************************************************************************
+// ***************************************************************************
+// ***************************************************************************
+
+
+// ===========================================================================
+/*! Set the type of word. */
+// ===========================================================================
+void Word::set_type()
+{
+ // Make sure the type is initialized. If the word is not anything else,
+ // then it is a string.
+ type = WSTRING;
+
+ // Just for convenience.
+ int len = (int)wstr.size();
+
+ // First determine if the word starts and ends with quotes. If it does,
+ // then it is a string. We do not strip off the quote symbols at this
+ // point because we might be in a comment region where the quotes donot
+ // matter. Later after the comments are stripped out, we check for
+ // matching quotes and remove them.
+ if ((wstr[0] == '\"') || (wstr[0] == '\'') ||
+ (wstr[len-1] == '\"') || (wstr[len-1] == '\'')) {
+ type = WSTRING;
+ //wstr.erase(wstr.end() - 1);
+ //wstr.erase(wstr.begin());
+ return;
+ }
+
+ // Check for a delimiter.
+ if (wstr == "(") { type = OPEN_PARENS; return; }
+ if (wstr == ")") { type = CLOSED_PARENS; return; }
+ if (wstr == "[") { type = OPEN_SQUARE_BRACKET; return; }
+ if (wstr == "]") { type = CLOSED_SQUARE_BRACKET; return; }
+ if (wstr == "{") { type = OPEN_BRACE; return; }
+ if (wstr == "}") { type = CLOSED_BRACE; return; }
+
+ // Comma is used for a couple of things.
+ if (wstr == ",") { type = COMMA; return; }
+
+ // Variables always begin with $. Of course, if the word is in quotes it is
+ // not a variable even if it does begin with $.
+ if (wstr[0] == '$') { type = VARIABLE; return; }
+
+ // Check for an operator.
+ if (wstr == "++") { type=OPERATOR; op_level=7; op_type="arithmetic"; return; }
+ if (wstr == "--") { type=OPERATOR; op_level=7; op_type="arithmetic"; return; }
+
+ if (wstr == "**") { type=OPERATOR; op_level=6; op_type="arithmetic"; return; }
+
+ // Do not implement the % operator, it is too much like the fortran %
+ // operator which is for referencing components of a fortran structure.
+ //if (wstr == "%") { type=OPERATOR; op_level=5; op_type="arithmetic"; return; }
+ if (wstr == "*") { type=OPERATOR; op_level=5; op_type="arithmetic"; return; }
+ if (wstr == "/") { type=OPERATOR; op_level=5; op_type="arithmetic"; return; }
+
+ if (wstr == "+") { type=OPERATOR; op_level=4; op_type="arithmetic"; return; }
+ if (wstr == "-") { type=OPERATOR; op_level=4; op_type="arithmetic"; return; }
+
+ if (wstr == ".gt.") { type=OPERATOR; op_level=3; op_type="relational"; return; }
+ if (wstr == ".ge.") { type=OPERATOR; op_level=3; op_type="relational"; return; }
+ if (wstr == ".lt.") { type=OPERATOR; op_level=3; op_type="relational"; return; }
+ if (wstr == ".le.") { type=OPERATOR; op_level=3; op_type="relational"; return; }
+ if (wstr == ".eq.") { type=OPERATOR; op_level=3; op_type="relational"; return; }
+ if (wstr == ".ne.") { type=OPERATOR; op_level=3; op_type="relational"; return; }
+
+ if (wstr == ".hggt.") { type=OPERATOR; op_level=3; op_type="relational"; return; }
+ if (wstr == ".hgge.") { type=OPERATOR; op_level=3; op_type="relational"; return; }
+ if (wstr == ".hglt.") { type=OPERATOR; op_level=3; op_type="relational"; return; }
+ if (wstr == ".hgle.") { type=OPERATOR; op_level=3; op_type="relational"; return; }
+ if (wstr == ".hgeq.") { type=OPERATOR; op_level=3; op_type="relational"; return; }
+ if (wstr == ".hgne.") { type=OPERATOR; op_level=3; op_type="relational"; return; }
+
+ if (wstr == ".not.") { type=OPERATOR; op_level=2; op_type="logical"; return; }
+
+ if (wstr == ".and.") { type=OPERATOR; op_level=1; op_type="logical"; return; }
+
+ if (wstr == ".or.") { type=OPERATOR; op_level=0; op_type="logical"; return; }
+
+ // Equals sign.
+ if (wstr == "=") { type = EQUALS; return; }
+
+ // At this point the word is either a string or a number.
+
+ // If the word begins with a + or - sign, then it is numeric.
+ bool start_with_pm = false;
+ if (wstr[0] == '+') start_with_pm = true;
+ if (wstr[0] == '-') start_with_pm = true;
+
+ // If the word does not begin with a + or - sign or a digit, or a
+ // ., or an e or a d then it is a string.
+ if (!start_with_pm) {
+ if(!isdigit(wstr[0])) {
+ if (wstr[0] != '.') {
+ if (wstr[0] != 'e') {
+ if (wstr[0] != 'E') {
+ if (wstr[0] != 'd') {
+ if (wstr[0] != 'D') {
+ type = WSTRING; return;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Check for all digits, i.e. an integer.
+ bool is_number = true;
+ int istart = 0;
+ if (start_with_pm) istart = 1;
+ for (int i=istart; i<(int)wstr.size(); i++) {
+ if (!isdigit(wstr[i])) {
+ is_number = false;
+ break;
+ }
+ }
+ if (is_number) { type = INTEGER; return; }
+
+ // Check for floating point.
+ // If there is anything in the string that is not a component of a
+ // floating point number, then that makes it a string.
+ is_number = true;
+ for (int i=0; i<(int)wstr.size(); i++) {
+ if (!isdigit(wstr[i]) && wstr[i]!='.' && wstr[i]!='e' && wstr[i]!='E' &&
+ wstr[i]!='d' && wstr[i]!='D' && wstr[i]!='+' && wstr[i]!='-') {
+ is_number = false;
+ break;
+ }
+ }
+ //if (is_number) { type = DOUBLE; return; }
+ if (!is_number) { type = WSTRING; return; }
+
+ // We suspect a floating point number.
+ // At this point, everything in the string is a component of a floating
+ // point number, i.e. "+ - digit e E d D ."
+ type = DOUBLE;
+
+ // Check that strings that start with "e E d D" really are numbers.
+ // And for numbers like e+01, e-05, etc, the atof or strtod functions do not
+ // interpret those as numbers, therefore we insert a 1 in front of the e
+ // so that atof and strtod will call it a number.
+ if (wstr[0] == 'e' || wstr[0] == 'E' || wstr[0] == 'd' || wstr[0] == 'D') {
+
+ // Check for proper syntax after the "e E d D".
+ if (!check_after_e(wstr, 1, (int)wstr.size()-1)) {
+ type = WSTRING;
+ return;
+ }
+
+ // This appears to be a number, insert the digit.
+ wstr.insert(0, "1");
+ return;
+ }
+
+ // The string appears to be a floating point number (fpn), check syntax.
+ // First, find the location of the "e E d D". Check that there can be
+ // only one "e E d D" in the string.
+ int ie = -1;
+ for (int i=0; i<(int)wstr.size(); i++) {
+ if (wstr[i] == 'e' || wstr[i] == 'E' || wstr[i] == 'd' ||
+ wstr[i] == 'D') {
+ ie = i;
+ break;
+ }
+ }
+ if (ie > -1) {
+ for (int i=ie+1; i<(int)wstr.size(); i++) {
+ if (wstr[i] == 'e' || wstr[i] == 'E' || wstr[i] == 'd' ||
+ wstr[i] == 'D') {
+ type = WSTRING;
+ return;
+ }
+ }
+ }
+
+ // Check that the characters before the "e E d D" are valid. If no
+ // "e E d D" was found then check the entire string as if it preceeded
+ // an "e E d D".
+ int ic1 = 0;
+ int ic2 = (int)wstr.size() - 1;
+ if (ie > -1) {
+ ic2 = ie - 1;
+ }
+ if (!check_before_e(wstr, ic1, ic2)) {
+ type = WSTRING;
+ return;
+ }
+
+ // All other cases handled, this must be a fpn (type DOUBLE).
+ return;
+}
+
+
+// ===========================================================================
+// The input string, s, could be a floating point number (fpn). It has been
+// determined that s contains an "e E d D" located at position i2+1. Check
+// everything before the "e E d D", postions i1 through i2 inclusive to
+// verify that this is a fpn.
+//
+// It is also possible that an "e E d D" was not found in which case the
+// entire string is checked as if it preceeded an "e E d D".
+//
+// Return false if this is a string
+// true if this could be a fpn
+// ===========================================================================
+bool Word::check_before_e(string s, int i1, int i2)
+{
+ // If there is nothing before the "e E d D" then this still could be a fpn.
+ int size = i2 - i1 + 1;
+ if (size < 1) return true;
+
+ // The first character could be "+ -", but the remaining characters
+ // cannot be "+ -".
+ int ie1 = i1;
+ if (s[i1] == '+' || s[i1] == '-') ie1 = i1+1;
+ for (int i=ie1; i<=i2; i++) {
+ if (s[i] == '+' || s[i] == '-') return false;
+ }
+
+ // Locate the optional "." character. There can only be one ".".
+ int pointdex = -1;
+ for (int i=ie1; i<=i2; i++) {
+ if (s[i] == '.') {
+ pointdex = i;
+ break;
+ }
+ }
+ if (pointdex > -1) {
+ for (int i=pointdex+1; i<=i2; i++) {
+ if (s[i] == '.') return false;
+ }
+ }
+
+
+ // Everything before and after the point must be a digit (except
+ // that the very first character could be "+ -").
+ if (pointdex > -1) {
+ for (int i=ie1; i<pointdex; i++) {
+ if (!isdigit(s[i])) return false;
+ }
+ for (int i=pointdex+1; i<=i2; i++) {
+ if (!isdigit(s[i])) return false;
+ }
+ }
+
+ // If there is no point then everything must be digits (except
+ // that the very first character could be "+ -").
+ if (pointdex == -1) {
+ for (int i=ie1; i<=i2; i++) {
+ if (!isdigit(s[i])) return false;
+ }
+ }
+
+ // All other cases handled, this could be a fpn.
+ return true;
+}
+
+
+// ===========================================================================
+// The input string, s, could be a floating point number (fpn). It has been
+// determined that s contains an "e E d D" located at position i1-1. Check
+// everything after the "e E d D", postions i1 through i2 inclusive to
+// verify that this is a fpn.
+//
+// Return false if this is a string
+// true if this could be a fpn
+// ===========================================================================
+bool Word::check_after_e(string s, int i1, int i2)
+{
+ // If there is nothing after the "e E d D" then that is not a number.
+ int size = i2 - i1 + 1;
+ if (size < 1) return false;
+
+ // The character following the "e E d D" must be "+ - digit"
+ if (s[i1] != '+' && s[i1] != '-' && (!isdigit(s[i1])))
+ return false;
+
+ // Everything after the e or e+ or e- must be a digit.
+ int ie1 = i1;
+ if (s[i1] == '+' || s[i1] == '-') ie1 = i1+1;
+ for (int i=ie1; i<=i2; i++) {
+ if (!isdigit(s[i])) return false;
+ }
+
+ // All other cases handled, this could be a fpn.
+ return true;
+}
+
+
+
+// ===========================================================================
+/*! Print the type of word. */
+// ===========================================================================
+void Word::print_type(stringstream &ss)
+{
+ if (type == WUNKNOWN) ss << "unknown";
+ if (type == WSTRING) ss << "string";
+ if (type == INTEGER) ss << "integer";
+ if (type == DOUBLE) ss << "double";
+ if (type == EQUALS) ss << "=";
+ if (type == OPERATOR) ss << "operator";
+ if (type == OPEN_PARENS) ss << "(";
+ if (type == CLOSED_PARENS) ss << ")";
+ if (type == OPEN_SQUARE_BRACKET) ss << "[";
+ if (type == CLOSED_SQUARE_BRACKET) ss << "]";
+ if (type == OPEN_BRACE) ss << "{";
+ if (type == CLOSED_BRACE) ss << "}";
+ if (type == COMMA) ss << ",";
+ if (type == VARIABLE) ss << "variable";
+}
+
+
+// ===========================================================================
+// Check to see if the word is boolean (true or false)
+// ===========================================================================
+bool Word::is_bool()
+{
+ bool retValue = false;
+
+ // We don't want to test all possible combinations of spellings for
+ // "True" vs "true" vs "tRue" etc. So we create a temporary string that
+ // is all lower case and compare against the temporary.
+
+ // Create a copy of the string that can be modified locally.
+ string str( wstr );
+
+ // Force the string to all lower case.
+ string_to_lower( str );
+
+ // The comparison is a character-by-character over the length of the
+ // first string. To avoid uninitialized memory reads we convert char
+ // array literals to strings.
+ if( str == string("true") || str == string(".true.") )
+ retValue = true;
+ if ( str == string("false") || str == string(".false.") )
+ retValue = true;
+
+ return retValue;
+}
+
+
+// ***************************************************************************
+// ***************************************************************************
+// ***************************************************************************
+// This section provides the methods for returning the word as double,
+// int, bool, etc.
+// ***************************************************************************
+// ***************************************************************************
+// ***************************************************************************
+
+// ===========================================================================
+// Get the word as a boolean
+// ===========================================================================
+bool Word::get_bool(stringstream &serr, int &ierr)
+{
+ // Mark this word as having been processed.
+ processed = true;
+
+ bool retValue = false;
+
+ // We don't want to test all possible combinations of spellings for
+ // "True" vs "true" vs "tRue" etc. So we create a temporary string that
+ // is all lower case and compare against the temporary.
+ string str( wstr );
+
+ // Force the string to all lower case.
+ string_to_lower( str );
+
+ // The comparison is a character-by-character over the length of the
+ // first string. To avoid uninitialized memory reads we convert char
+ // array literals to strings.
+ if( str == string("true") || str == string(".true.") )
+ retValue = true;
+ else if ( str == string("false") || str == string(".false.") )
+ retValue = false;
+ else { // We default any other bool value to false but also warn the user.
+ if (lines != NULL) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_line_number << ":" << endl;
+ serr << " " << (*lines)[line_number-1] << endl;
+ serr << "in file: " << filename << endl;
+ }
+ serr << "Values on this line should be true or false "
+ "(or .true. or .false.)" << endl;
+ serr << " (any case is fine, for example true, True, TrUe "
+ "are all ok)" << endl;
+ serr << "Instead found value: " << wstr << endl << endl;
+ ierr = 2;
+ retValue = false;
+ }
+
+ // Apply the negate flag if it is turned on.
+ if (negate) {
+ bool b = false;
+ if (retValue == false) b = true;
+ retValue = b;
+ }
+
+ return retValue;
+}
+
+
+// ===========================================================================
+// Get the word as as int, error processing version.
+// ===========================================================================
+int Word::get_int(stringstream &serr, int &ierr)
+{
+ // Mark this word as having been processed.
+ processed = true;
+
+ // The word must at least be a number.
+ if ((type != DOUBLE) && (type != INTEGER)) {
+ if (lines != NULL) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_line_number << ":" << endl;
+ serr << " " << (*lines)[line_number-1] << endl;
+ serr << "in file: " << filename << endl;
+ }
+ serr << "Expected a numerical, integer value." << endl;
+ serr << "Instead got: " << wstr << endl << endl;
+ ierr = 2;
+ return 0;
+ }
+
+ // The word might begin with a + or - sign.
+ bool start_with_pm = false;
+ if (wstr[0] == '+') start_with_pm = true;
+ if (wstr[0] == '-') start_with_pm = true;
+
+ // We allow 2. or 2.0 for example as an integer, but not 2.3.
+ bool dot_found = false;
+ bool is_int = true;
+ int istart = 0;
+ if (start_with_pm) istart = 1;
+ for (int i=istart; i<(int)wstr.size(); i++) {
+ if (!isdigit(wstr[i]) && wstr[i]!='.' ) {
+ is_int = false;
+ break;
+ }
+ if (wstr[i]=='.' ) {
+ dot_found = true;
+ continue;
+ }
+ if (dot_found && wstr[i]!='0' ) {
+ is_int = false;
+ break;
+ }
+ }
+ if (!is_int) {
+ if (lines != NULL) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_line_number << ":" << endl;
+ serr << " " << (*lines)[line_number-1] << endl;
+ serr << "in file: " << filename << endl;
+ }
+ serr << "Expected an integer." << endl;
+ serr << "For example, 2 or 3, even 2. or 2.0 is ok." << endl;
+ serr << "Instead got: " << wstr << endl << endl;
+ ierr = 2;
+ return 0;
+ }
+
+
+ // Apply the negate flag if it is turned on.
+ int iret = atoi(wstr.c_str() );
+ if (negate) iret *= -1;
+ return iret;
+}
+
+int64_t Word::get_int64_t(stringstream &serr, int &ierr)
+{
+ // Mark this word as having been processed.
+ processed = true;
+
+ // The word must at least be a number.
+ if ((type != DOUBLE) && (type != INTEGER)) {
+ if (lines != NULL) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_line_number << ":" << endl;
+ serr << " " << (*lines)[line_number-1] << endl;
+ serr << "in file: " << filename << endl;
+ }
+ serr << "Expected a numerical, integer value." << endl;
+ serr << "Instead got: " << wstr << endl << endl;
+ ierr = 2;
+ return 0;
+ }
+
+ // The word might begin with a + or - sign.
+ bool start_with_pm = false;
+ if (wstr[0] == '+') start_with_pm = true;
+ if (wstr[0] == '-') start_with_pm = true;
+
+ // We allow 2. or 2.0 for example as an integer, but not 2.3.
+ bool dot_found = false;
+ bool is_int = true;
+ int istart = 0;
+ if (start_with_pm) istart = 1;
+ for (int i=istart; i<(int)wstr.size(); i++) {
+ if (!isdigit(wstr[i]) && wstr[i]!='.' ) {
+ is_int = false;
+ break;
+ }
+ if (wstr[i]=='.' ) {
+ dot_found = true;
+ continue;
+ }
+ if (dot_found && wstr[i]!='0' ) {
+ is_int = false;
+ break;
+ }
+ }
+ if (!is_int) {
+ if (lines != NULL) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_line_number << ":" << endl;
+ serr << " " << (*lines)[line_number-1] << endl;
+ serr << "in file: " << filename << endl;
+ }
+ serr << "Expected an integer." << endl;
+ serr << "For example, 2 or 3, even 2. or 2.0 is ok." << endl;
+ serr << "Instead got: " << wstr << endl << endl;
+ ierr = 2;
+ return 0;
+ }
+
+ std::stringstream sstr(wstr);
+ int64_t iret;
+ sstr >> iret;
+ // Apply the negate flag if it is turned on.
+ if (negate) iret *= -1;
+ return iret;
+}
+
+// ===========================================================================
+// Get the word as a double, error processing version.
+// ===========================================================================
+double Word::get_double(stringstream &serr, int &ierr)
+{
+ // Mark this word as having been processed.
+ processed = true;
+
+ // The word must at least be a number.
+ if ((type != DOUBLE) && (type != INTEGER)) {
+ if (lines != NULL) {
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_line_number << ":" << endl;
+ serr << " " << (*lines)[line_number-1] << endl;
+ serr << "in file: " << filename << endl;
+ }
+ serr << "Expected a numerical value." << endl;
+ serr << "Instead got: " << wstr << endl << endl;
+ ierr = 2;
+ return 0;
+ }
+
+ // Use a temporary string that might be modified.
+ string s = wstr;
+
+ // We allow exponents using d and D in addition to e and E, for example
+ // 1.d14 or -1.38D-18. The problem with this is that atof and strtod
+ // do not allow d or D, therefore we have to replace d or D with e
+ // before sending it to atof or strtod.
+ if (type == DOUBLE) {
+ for (int i=0; i<(int)s.size(); i++) {
+ if (s[i] == 'd') s[i] = 'e';
+ if (s[i] == 'D') s[i] = 'e';
+ }
+ }
+
+ // Convert the string to a double.
+ double d = atof(s.c_str());
+
+ // Apply the negate flag if it is turned on.
+ if (negate) d *= -1.0;
+ return d;
+}
+
+
+// ===========================================================================
+// Get the word as a single character, error processing version.
+// ===========================================================================
+char Word::get_single_char(stringstream &serr, int &ierr)
+{
+ // To suppress compiler warnings of unused parameters
+ //assert(serr == serr);
+ assert(ierr == ierr);
+
+ // Mark this word as having been processed.
+ processed = true;
+
+ return wstr[0];
+}
+
+
+// ===========================================================================
+// Get the word as an int, no error processing version.
+// ===========================================================================
+int Word::get_int()
+{
+ int dummy;
+ return get_val( dummy );
+}
+
+// support uint64_t
+int64_t Word::get_int64_t()
+{
+ int64_t dummy;
+ return get_val( dummy );
+}
+
+// ===========================================================================
+// Get the word as a float
+// ===========================================================================
+float Word::get_float()
+{
+ float dummy;
+ return get_val( dummy );
+}
+
+// ===========================================================================
+// Get the word as a double
+// ===========================================================================
+double Word::get_double()
+{
+ double dummy;
+ return get_val( dummy );
+}
+
+
+// ===========================================================================
+// Get the word as a Type T.
+// ===========================================================================
+template< class T >
+T Word::get_val( T &dummyValue )
+{
+ // To suppress compiler warnings of unused parameters
+ assert(dummyValue == dummyValue);
+
+ T retValue;
+
+ // Mark this word as having been processed.
+ processed = true;
+
+ // Convert the word to the requested data type.
+ retValue = convertFromString( retValue, wstr );
+
+ return retValue;
+}
+
+//! Explicit instantiation of supported template types. If more types are
+//! needed those explicit versions must be listed here. We are not using
+//! automatic inclusion (we would need to move the function definition into
+//! the header file for that). The listed versions below are the only ones
+//! that will be included in the library.
+template int Word::get_val( int& );
+template int64_t Word::get_val( int64_t& );
+template float Word::get_val( float& );
+template double Word::get_val( double& );
+//template bool Word::get_val( bool& );
+template string Word::get_val( string& );
+
+// ===========================================================================
+// Convert from string to return type explicitly.
+// ===========================================================================
+
+//! rtti is only used for type identification (each overloaded function must
+//! have a unique signature. The return value is not part of the signature).
+
+// Convert string to integer.
+int Word::convertFromString( const int &rtti, const string &s ) const
+{
+ // To suppress compiler warnings of unused parameters
+ assert(rtti == rtti);
+
+ int iret = atoi( s.c_str() );
+ if (negate) iret *= -1;
+ return iret;
+}
+
+// Convert string to int64_t.
+int64_t Word::convertFromString( const int64_t &rtti, const string &s ) const
+{
+ // To suppress compiler warnings of unused parameters
+ assert(rtti == rtti);
+
+ int64_t iret;
+ std::stringstream( s ) >> iret;
+ if (negate) iret *= -1;
+ return iret;
+}
+
+// Convert string to string (do nothing).
+string Word::convertFromString( const string &rtti, const string &s ) const
+{
+ // To suppress compiler warnings of unused parameters
+ assert(rtti == rtti);
+
+ return s;
+}
+
+// Convert string to float.
+float Word::convertFromString( const float &rtti, const string &s ) const
+{
+ // To suppress compiler warnings of unused parameters
+ assert(rtti == rtti);
+
+ // Use a temporary string that might be modified.
+ string sm = s;
+
+ // We allow exponents using d and D in addition to e and E, for example
+ // 1.d14 or -1.38D-18. The problem with this is that atof and strtod
+ // do not allow d or D, therefore we have to replace d or D with e
+ // before sending it to atof or strtod.
+ for (int i=0; i<(int)sm.size(); i++) {
+ if (sm[i] == 'd') sm[i] = 'e';
+ if (sm[i] == 'D') sm[i] = 'e';
+ }
+
+ float f = (float)atof( sm.c_str() );
+ if (negate) f *= -1.;
+ return f;
+}
+
+// Convert string to double.
+double Word::convertFromString( const double &rtti, const string &s ) const
+{
+ // To suppress compiler warnings of unused parameters
+ assert(rtti == rtti);
+
+ // Use a temporary string that might be modified.
+ string sm = s;
+
+ // We allow exponents using d and D in addition to e and E, for example
+ // 1.d14 or -1.38D-18. The problem with this is that atof and strtod
+ // do not allow d or D, therefore we have to replace d or D with e
+ // before sending it to atof or strtod.
+ for (int i=0; i<(int)sm.size(); i++) {
+ if (sm[i] == 'd') sm[i] = 'e';
+ if (sm[i] == 'D') sm[i] = 'e';
+ }
+
+ double d = atof( sm.c_str() );
+ if (negate) d *= -1.;
+ return d;
+}
+
+
+// ***************************************************************************
+// ***************************************************************************
+// ***************************************************************************
+// Utility functions.
+// ***************************************************************************
+// ***************************************************************************
+// ***************************************************************************
+
+
+// ===========================================================================
+// Return the word as a string for printing. This is usually just the word
+// but if it has multiplicity, then include that in the return string.
+// ===========================================================================
+string Word::get_print_string(bool enc_quotes)
+{
+ bool equotes = true;
+ if (!enc_quotes) equotes = false;
+ if (wstr == "true") equotes = false;
+ if (wstr == "false") equotes = false;
+
+
+ string sq = "";
+
+ if (equotes) {
+ if (type == WSTRING) sq = "\"";
+ sq += wstr;
+ if (type == WSTRING) sq += "\"";
+ }
+ else {
+ sq = wstr;
+ }
+
+ if (multiplicity <= 1) return sq;
+
+ stringstream ss;
+ ss << multiplicity;
+ string s = "";
+ s = ss.str() + "*" + sq;
+ return s;
+}
+
+
+// ===========================================================================
+// If a word starts or ends with quotes, make sure the quotes match, if not
+// generate a fatal error, and then strip off the quotes.
+// ===========================================================================
+void Word::handle_quotes(stringstream &serr, int &ierr)
+{
+ // Just for convenience.
+ int len = (int)wstr.size();
+
+ // Check for matching quotes, generate a fatal error if they do not match.
+ bool ferr = false;
+ if ((wstr[0] == '\"') && (wstr[len-1] != '\"')) ferr = true;
+ if ((wstr[0] == '\'') && (wstr[len-1] != '\'')) ferr = true;
+ if ((wstr[len-1] == '\"') && (wstr[0] != '\"')) ferr = true;
+ if ((wstr[len-1] == '\'') && (wstr[0] != '\'')) ferr = true;
+
+ if (ferr) {
+ fatal_error(serr, ierr);
+ serr << "Quotes mismatch found." << endl;
+ serr << "A starting quotes must have a closing quotes." << endl;
+ serr << "Double quotes, \", must be matched with double quotes."
+ << endl;
+ serr << "Single quotes, \', must be matched with single quotes."
+ << endl;
+ ierr = 2;
+ }
+
+ // Determine if the word starts and ends with quotes. If it does,
+ // then we strip off the quote symbols.
+ if (((wstr[0] == '\"') || (wstr[0] == '\'')) &&
+ ((wstr[len-1] == '\"') || (wstr[len-1] == '\''))) {
+ wstr.erase(wstr.end() - 1);
+ wstr.erase(wstr.begin());
+ return;
+ }
+}
+
+
+// ===========================================================================
+// Erase a single character from the word, ic is the index of the character
+// to be erased (starting from 0).
+// ===========================================================================
+void Word::erase_char(int ic)
+{
+ if (ic >= (int)wstr.size()) return;
+ wstr.erase(wstr.begin() + ic);
+}
+
+
+
+// ===========================================================================
+// Fatal error
+// ===========================================================================
+void Word::fatal_error(stringstream &serr, int &ierr)
+{
+ // To suppress compiler warnings of unused parameters
+ assert(ierr == ierr);
+
+ serr << endl;
+ serr << "*** FATAL ERROR in line " << file_line_number << ":" << endl;
+ serr << " " << (*lines)[line_number-1] << endl;
+ serr << "in file: " << filename << endl;
+}
+
+void Word::warning(stringstream &serr, int &ierr)
+{
+ // To suppress compiler warnings of unused parameters
+ assert(ierr == ierr);
+
+ serr << endl;
+ serr << "*** WARNING in line " << file_line_number << ":" << endl;
+ serr << " " << (*lines)[line_number-1] << endl;
+ serr << "in file: " << filename << endl;
+}
+
+
+// ===========================================================================
+// Negate a word.
+// ===========================================================================
+void Word::negate_value()
+{
+ int len = (int)wstr.size();
+
+ if (type == INTEGER || type == DOUBLE) {
+ negate = false;
+
+ // If the string starts with a - sign, then delete it.
+ for (int i=0; i<len; i++) {
+ if (wstr[i] == ' ' || wstr[i] == '\t') continue;
+ if (wstr[i] == '-') {
+ wstr[i] = ' ';
+ return;
+ }
+ break;
+ }
+
+ // The string did not start with a minus sign so insert one.
+ // Using insert causes link problems with SGI CC
+ string s = "-" + wstr;
+ wstr = s;
+ //wstr.insert(0, s);
+ return;
+ }
+}
+
+
+
+// ===========================================================================
+// Convert the input string to lower case.
+// ===========================================================================
+void Word::string_to_lower( string &s ) const
+{
+ int i, c, d;
+ int len = (int)s.size();
+ for (i=0; i<len; i++) {
+ c = (int)s[i];
+ d = c;
+ if (isalpha(c)) d = tolower(c);
+ s[i] = (char)d;
+ }
+}
+
+
+
+} // End of the PP namespace
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Word.hh
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/Word.hh?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Word.hh (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/Word.hh Sun Sep 3 20:10:18 2017
@@ -0,0 +1,244 @@
+/* Copyright 2015. Los Alamos National Security, LLC. This material was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Under this license, it is required to include a reference to this work. We
+ * request that each derivative work contain a reference to LANL Copyright
+ * Disclosure C15076/LA-CC-15-054 so that this work's impact can be roughly
+ * measured.
+ *
+ * This is LANL Copyright Disclosure C15076/LA-CC-15-054
+ */
+
+/*
+ * PowerParser is a general purpose input file parser for software applications.
+ *
+ * Authors: Chuck Wingate XCP-2 caw at lanl.gov
+ * Robert Robey XCP-2 brobey at lanl.gov
+ */
+
+#ifndef WORDHHINCLUDE
+#define WORDHHINCLUDE
+
+// ***************************************************************************
+// ***************************************************************************
+// This class holds each word from the line.
+// ***************************************************************************
+// ***************************************************************************
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <map>
+#include <deque>
+#include <stdint.h>
+
+namespace PP
+{
+using std::string;
+using std::stringstream;
+using std::vector;
+using std::map;
+using std::deque;
+
+enum WordType {WUNKNOWN, WSTRING, INTEGER, DOUBLE, EQUALS, OPERATOR,
+ OPEN_PARENS, CLOSED_PARENS,
+ OPEN_SQUARE_BRACKET, CLOSED_SQUARE_BRACKET,
+ OPEN_BRACE, CLOSED_BRACE,
+ COMMA, VARIABLE};
+
+class Word
+{
+
+public:
+ Word();
+ Word(string s);
+ Word(string s, int lnum, int file_lnum, string fname,
+ deque<string> *lstr);
+ Word(double d, int lnum, int file_lnum, string fname,
+ deque<string> *lstr);
+ Word(int ia, int lnum, int file_lnum, string fname,
+ deque<string> *lstr);
+ Word operator=(const Word &);
+ Word(const Word &);
+ ~Word();
+
+ // Given a word, change its value.
+ void set_value(double d);
+ void set_value(string s);
+ void set_value(const char *s);
+ void set_value(bool b);
+
+ // Print the type of word to a stringstream.
+ void print_type(stringstream &ss);
+
+ // Set the type of word.
+ void set_type();
+
+ // Get the operator type, arithmetic, relational, ...
+ string get_op_type() {return op_type;}
+
+ bool is_operator() { if (type == OPERATOR) return true; return false; }
+
+ bool is_operator(int level) {
+ if (type != OPERATOR) return false;
+ if (level == op_level) return true;
+ return false;
+ }
+
+ bool is_bool();
+
+ bool is_string() { if (type == WSTRING) return true; return false; }
+
+ bool is_integer() { if (type == INTEGER) return true; return false; }
+
+ bool is_number() { if (type == INTEGER || type == DOUBLE) return true;
+ return false; }
+
+ bool is_numvar() { if (type == INTEGER || type == DOUBLE ||
+ type == VARIABLE) return true;
+ return false; }
+
+ bool has_value() { if (type == INTEGER || type == DOUBLE) return true;
+ return false; }
+
+ bool is_variable() { if (type == VARIABLE) return true; return false; }
+
+ bool is_comma() { if (type == COMMA) return true; return false; }
+
+ /*! \brief Get the word as a string. */
+ string get_string() { return wstr; }
+ string get_print_string(bool enc_quotes);
+ string get_stringp() { processed=true; return wstr; }
+ char get_single_char(stringstream &serr, int &ierr);
+
+ /*! \brief Get the word as a float. */
+ float get_float();
+
+ /*! \brief Get the word as a double. */
+ double get_double();
+ double get_double(stringstream &serr, int &ierr);
+
+ // Get the word as an int, without and with error processing.
+ int get_int();
+ int get_int(stringstream &serr, int &ierr);
+
+ int64_t get_int64_t();
+ int64_t get_int64_t(stringstream &serr, int &ierr);
+
+ /*! \brief Get the word as a boolean. */
+ bool get_bool(stringstream &serr, int &ierr);
+
+ /*! \brief Templated get method for get_double, get_int, etc. */
+ template< class T >
+ T get_val( T &dummy );
+
+ /*!
+ * \brief Convert string s to the type of the first argument. Function
+ * returns the converted value as a reference and as the function
+ * result.
+ *
+ * These overloaded functions are the base for the templated accessor
+ * functions "get_val()".
+ *
+ * \param rtti - Convert the string s into the type of rtti and return it.
+ */
+ int convertFromString ( const int &rtti, const string &s ) const;
+ int64_t convertFromString ( const int64_t &rtti, const string &s ) const;
+ string convertFromString ( const string &rtti, const string &s ) const;
+ float convertFromString ( const float &rtti, const string &s ) const;
+ double convertFromString ( const double &rtti, const string &s ) const;
+ //bool convertFromString ( const bool &rtti, const string &s ) const;
+
+ /*! \brief Negate the word or set a flag to negate it later. */
+ void negate_value();
+
+ // Handle errors.
+ void fatal_error(stringstream &serr, int &ierr);
+ void warning(stringstream &serr, int &ierr);
+
+ // Miscellaneous functions.
+ void handle_quotes(stringstream &serr, int &ierr);
+ void erase_char(int ic);
+
+ // Accessor methods.
+ void set_word(string str) { wstr = str; }
+ void set_processed(bool p) { processed = p; }
+ bool get_processed() { return processed; }
+ int get_line_number() { return line_number; }
+ int get_file_line_number() { return file_line_number; }
+ string get_filename() { return filename; }
+ deque<string> *get_lines() { return lines; }
+ void set_filename(string fn) { filename = fn; }
+ int get_multiplicity() { return multiplicity; }
+ void set_multiplicity(int m) { multiplicity = m; }
+
+private:
+ void init();
+ bool check_before_e(string s, int i1, int i2);
+ bool check_after_e(string s, int i1, int i2);
+
+ // This is the basic storage for the word.
+ string wstr;
+
+ // The type of word, like operator, string, variable, etc.
+ WordType type;
+
+ // Flag for testing whether this word was processed or not.
+ bool processed;
+
+ // Flag to negate a variable.
+ bool negate;
+
+ // This word is repeated multiplicity times.
+ int multiplicity;
+
+ // If the word is an operator, then this is its level, i.e. "**" has
+ // the highest level, then "*","/", etc.
+ int op_level;
+
+ // The operator type, arithmetic, relational, ...
+ string op_type;
+
+ // Convert the input string to lower case.
+ void string_to_lower( string &s ) const;
+
+ // This is needed for telling the user what line in the input
+ // file or include file the error occurred on.
+ //
+ // line_number The line_number corresponding to this command, this is
+ // an index into lines and starts from 1, not 0.
+ // lines Pointer to the deque of original lines. This contains all
+ // the lines from the input file and any include files.
+ // file_line_number The line number in the input file or include file.
+ // filename The name of the input file or include file.
+ //
+ // file_line_number and filename are needed to that the user can open
+ // the file and go to the line in error.
+ int line_number, file_line_number;
+ string filename;
+ deque<string> *lines;
+
+};
+
+
+} // end of PP namespace
+
+#endif
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/clamr_cpuonly.cpp
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/clamr_cpuonly.cpp?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/clamr_cpuonly.cpp (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/clamr_cpuonly.cpp Sun Sep 3 20:10:18 2017
@@ -0,0 +1,832 @@
+/*
+ * Copyright (c) 2011-2012, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ * This research code is being developed as part of the
+ * 2011 X Division Summer Workshop for the express purpose
+ * of a collaborative code for development of ideas in
+ * the implementation of AMR codes for Exascale platforms
+ *
+ * AMR implementation of the Wave code previously developed
+ * as a demonstration code for regular grids on Exascale platforms
+ * as part of the Supercomputing Challenge and Los Alamos
+ * National Laboratory
+ *
+ * Authors: Bob Robey XCP-2 brobey at lanl.gov
+ * Neal Davis davis68 at lanl.gov, davis68 at illinois.edu
+ * David Nicholaeff dnic at lanl.gov, mtrxknight at aol.com
+ * Dennis Trujillo dptrujillo at lanl.gov, dptru10 at gmail.com
+ *
+ */
+
+#include <algorithm>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <vector>
+//#include "graphics/display.h"
+#include "graphics.h"
+#include "input.h"
+#include "mesh.h"
+#include "partition.h"
+#include "state.h"
+#include "timer.h"
+#include "memstats.h"
+#include "crux.h"
+#include "PowerParser.hh"
+#include "MallocPlus.h"
+#ifdef HAVE_ITTNOTIFY
+#include <ittnotify.h>
+#endif
+
+using namespace PP;
+
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+
+#ifndef DEBUG
+#define DEBUG 0
+#endif
+#undef DEBUG_RESTORE_VALS
+
+#define MIN3(x,y,z) ( min( min(x,y), z) )
+
+static int do_cpu_calc = 1;
+static int do_gpu_calc = 0;
+
+typedef unsigned int uint;
+
+static bool do_display_graphics = false;
+
+#ifdef HAVE_GRAPHICS
+static double circle_radius=-1.0;
+#ifdef FULL_PRECISION
+ void (*set_display_cell_coordinates)(double *, double *, double *, double *) = &set_display_cell_coordinates_double;
+ void (*set_display_cell_data)(double *) = &set_display_cell_data_double;
+#else
+ void (*set_display_cell_coordinates)(float *, float *, float *, float *) = &set_display_cell_coordinates_float;
+ void (*set_display_cell_data)(float *) = &set_display_cell_data_float;
+#endif
+#endif
+
+static int view_mode = 0;
+
+#ifdef FULL_PRECISION
+#define SUM_ERROR 2.0e-16
+ void (*set_graphics_cell_coordinates)(double *, double *, double *, double *) = &set_graphics_cell_coordinates_double;
+ void (*set_graphics_cell_data)(double *) = &set_graphics_cell_data_double;
+#else
+#define SUM_ERROR 1.0e-8
+ void (*set_graphics_cell_coordinates)(float *, float *, float *, float *) = &set_graphics_cell_coordinates_float;
+ void (*set_graphics_cell_data)(float *) = &set_graphics_cell_data_float;
+#endif
+
+void store_crux_data(Crux *crux, int ncycle);
+void restore_crux_data_bootstrap(Crux *crux, char *restart_file, int rollback_counter);
+void restore_crux_data(Crux *crux);
+
+bool restart, // Flag to start from a back up file; init in input.cpp::parseInput().
+ verbose, // Flag for verbose command-line output; init in input.cpp::parseInput().
+ localStencil, // Flag for use of local stencil; init in input.cpp::parseInput().
+ face_based, // Flag for face-based finite difference;
+ outline; // Flag for drawing outlines of cells; init in input.cpp::parseInput().
+int outputInterval, // Periodicity of output; init in input.cpp::parseInput().
+ crux_type, // Type of checkpoint/restart -- CRUX_NONE, CRUX_IN_MEMORY, CRUX_DISK;
+ // init in input.cpp::parseInput().
+ enhanced_precision_sum,// Flag for enhanced precision sum (default true); init in input.cpp::parseInput().
+ lttrace_on, // Flag to turn on logical time trace package;
+ do_quo_setup, // Flag to turn on quo dynamic scheduling policies package;
+ levmx, // Maximum number of refinement levels; init in input.cpp::parseInput().
+ nx, // x-resolution of coarse grid; init in input.cpp::parseInput().
+ ny, // y-resolution of coarse grid; init in input.cpp::parseInput().
+ niter, // Maximum iterations; init in input.cpp::parseInput().
+ graphic_outputInterval, // Periodicity of graphic output that is saved; init in input.cpp::parseInput()
+ checkpoint_outputInterval, // Periodicity of checkpoint output that is saved; init in input.cpp::parseInput()
+ num_of_rollback_states,// Maximum number of rollback states to maintain; init in input.cpp::parseInput()
+ backup_file_num,// Backup file number to restart simulation from; init in input.cpp::parseInput()
+ numpe, //
+ ndim = 2; // Dimensionality of problem (2 or 3).
+double upper_mass_diff_percentage; // Flag for the allowed pecentage difference to the total
+ // mass per output intervals; init in input.cpp::parseInput().
+
+char *restart_file;
+
+static int it = 0;
+
+enum partition_method initial_order, // Initial order of mesh.
+ cycle_reorder; // Order of mesh every cycle.
+static Mesh *mesh; // Object containing mesh information
+static State *state; // Object containing state information corresponding to mesh
+static Crux *crux; // Object containing checkpoint/restart information
+static PowerParser *parse; // Object containing input file parsing
+
+static real_t circ_radius = 0.0;
+static int next_cp_cycle = 0;
+static int next_graphics_cycle = 0;
+
+// Set up timing information.
+static struct timeval tstart, tstart_cpu, tstart_partmeas;
+
+static double H_sum_initial = 0.0;
+static double cpu_time_graphics = 0.0;
+static double cpu_time_calcs = 0.0;
+static double cpu_time_partmeas = 0.0;
+
+static int ncycle = 0;
+static double simTime = 0.0;
+static double deltaT = 0.0;
+char total_sim_time_log[] = {"total_execution_time.log"};
+struct timeval total_exec;
+
+static int mype=0;
+int main(int argc, char **argv) {
+
+ // Needed for code to compile correctly on the Mac
+ int numpe=-1;
+
+ // Process command-line arguments, if any.
+ parseInput(argc, argv);
+
+#ifdef _OPENMP
+ int nt = 0;
+ int tid = 0;
+
+ nt = omp_get_max_threads();
+ tid = omp_get_thread_num();
+ if (0 == tid && mype == 0) {
+ printf("--- max num openmp threads: %d\n", nt);
+ }
+#pragma omp parallel firstprivate(nt, tid)
+ {
+ nt = omp_get_num_threads();
+ tid = omp_get_thread_num();
+
+#pragma omp master
+ if (mype == 0) {
+ printf("--- num openmp threads in parallel region: %d\n", nt);
+ }
+ }
+#endif
+
+ parse = new PowerParser();
+
+ struct timeval tstart_setup;
+ cpu_timer_start(&tstart_setup);
+
+ crux = new Crux(crux_type, num_of_rollback_states, restart);
+
+ circ_radius = 6.0;
+ // Scale the circle appropriately for the mesh size.
+ circ_radius = circ_radius * (real_t) nx / 128.0;
+ int boundary = 1;
+ int parallel_in = 0;
+ double deltax_in = 1.0;
+ double deltay_in = 1.0;
+
+ if (restart){
+ restore_crux_data_bootstrap(crux, restart_file, 0);
+ mesh = new Mesh(nx, ny, levmx, ndim, deltax_in, deltay_in, boundary, parallel_in, do_gpu_calc);
+ mesh->init(nx, ny, circ_radius, initial_order, do_gpu_calc);
+
+ state = new State(mesh);
+ restore_crux_data(crux);
+ mesh->proc.resize(mesh->ncells);
+ mesh->calc_distribution(numpe);
+ } else {
+ mesh = new Mesh(nx, ny, levmx, ndim, deltax_in, deltay_in, boundary, parallel_in, do_gpu_calc);
+ if (DEBUG) {
+ //if (mype == 0) mesh->print();
+
+ char filename[10];
+ sprintf(filename,"out%1d",mype);
+ mesh->fp=fopen(filename,"w");
+
+ //mesh->print_local();
+ }
+
+ mesh->init(nx, ny, circ_radius, initial_order, do_gpu_calc);
+ state = new State(mesh);
+ state->init(do_gpu_calc);
+ mesh->proc.resize(mesh->ncells);
+ mesh->calc_distribution(numpe);
+ state->fill_circle(circ_radius, 100.0, 7.0);
+ }
+
+ size_t &ncells = mesh->ncells;
+
+ if (graphic_outputInterval > niter) next_graphics_cycle = graphic_outputInterval;
+ if (checkpoint_outputInterval > niter) next_cp_cycle = checkpoint_outputInterval;
+
+
+ // Kahan-type enhanced precision sum implementation.
+ double H_sum = state->mass_sum(enhanced_precision_sum);
+ if (mype == 0) printf ("Mass of initialized cells equal to %14.12lg\n", H_sum);
+ H_sum_initial = H_sum;
+
+ if(upper_mass_diff_percentage < 0){
+ upper_mass_diff_percentage = H_sum_initial * SUM_ERROR;
+ //printf("Setting sum mass error to %16.8lg\n",upper_mass_diff_percentage);
+ }
+
+ double cpu_time_main_setup = cpu_timer_stop(tstart_setup);
+ #ifdef TIMING
+ mesh->parallel_output("CPU: setup time time was",cpu_time_main_setup, 0, "s");
+ #endif
+
+ long long mem_used = memstats_memused();
+ #ifdef MEMORY
+ if (mem_used > 0) {
+ mesh->parallel_output("Memory used in startup ",mem_used, 0, "kB");
+ mesh->parallel_output("Memory peak in startup ",memstats_mempeak(), 0, "kB");
+ mesh->parallel_output("Memory free at startup ",memstats_memfree(), 0, "kB");
+ mesh->parallel_output("Memory available at startup ",memstats_memtotal(), 0, "kB");
+ }
+ #endif
+
+ if (mype == 0) {
+ if (ncycle != 0){
+ printf("Iteration %3d timestep %lf Sim Time %lf cells %ld Mass Sum %14.12lg\n",
+ ncycle, deltaT, simTime, ncells, H_sum);
+ } else {
+ printf("Iteration 0 timestep n/a Sim Time 0.0 cells %ld Mass Sum %14.12lg\n", ncells, H_sum);
+ }
+ }
+
+ for (int i = 0; i < MESH_COUNTER_SIZE; i++){
+ mesh->cpu_counters[i]=0;
+ }
+ for (int i = 0; i < MESH_TIMER_SIZE; i++){
+ mesh->cpu_timers[i]=0.0;
+ }
+
+ cpu_timer_start(&tstart_cpu);
+
+#ifdef HAVE_GRAPHICS
+ do_display_graphics = true;
+ set_display_mysize(ncells);
+ set_display_cell_coordinates(&mesh->x[0], &mesh->dx[0], &mesh->y[0], &mesh->dy[0]);
+ set_display_cell_data(&state->H[0]);
+ set_display_cell_proc(&mesh->proc[0]);
+
+ set_display_window((float)mesh->xmin, (float)mesh->xmax,
+ (float)mesh->ymin, (float)mesh->ymax);
+ set_display_outline((int)outline);
+ set_display_viewmode(view_mode);
+#endif
+
+ if (ncycle == next_graphics_cycle){
+ set_graphics_outline(outline);
+ set_graphics_window((float)mesh->xmin, (float)mesh->xmax,
+ (float)mesh->ymin, (float)mesh->ymax);
+ set_graphics_mysize(ncells);
+ set_graphics_cell_coordinates(&mesh->x[0], &mesh->dx[0],
+ &mesh->y[0], &mesh->dy[0]);
+ set_graphics_cell_data(&state->H[0]);
+ set_graphics_cell_proc(&mesh->proc[0]);
+ set_graphics_viewmode(view_mode);
+
+ if (mype == 0) {
+ init_graphics_output();
+ set_graphics_cell_proc(&mesh->proc[0]);
+ write_graphics_info(0,0,0.0,0,0);
+ }
+ next_graphics_cycle += graphic_outputInterval;
+ }
+
+#ifdef HAVE_GRAPHICS
+ set_display_circle_radius(circle_radius);
+ init_display(&argc, argv, "Shallow Water");
+ draw_scene();
+ //if (verbose) sleep(5);
+ sleep(2);
+
+ // Clear superposition of circle on grid output.
+ circle_radius = -1.0;
+#endif
+ cpu_time_graphics += cpu_timer_stop(tstart_cpu);
+
+ // Set flag to show mesh results rather than domain decomposition.
+ view_mode = 1;
+
+ if (ncycle == next_cp_cycle) store_crux_data(crux, ncycle);
+
+ cpu_timer_start(&tstart);
+#ifdef HAVE_GRAPHICS
+ set_idle_function(&do_calc);
+ start_main_loop();
+#else
+#ifdef HAVE_ITTNOTIFY
+__itt_resume();
+__SSC_MARK(0x111);
+#endif
+ for (it = ncycle; it < 10000000; it++) {
+ do_calc();
+ }
+#ifdef HAVE_ITTNOTIFY
+__itt_pause();
+__SSC_MARK(0x222);
+#endif
+#endif
+
+ return 0;
+}
+
+extern "C" void do_calc(void)
+{ double g = 9.80;
+ double sigma = 0.95;
+ int icount, jcount;
+ static int rollback_attempt = 0;
+ static double total_program_time = 0;
+
+ // Initialize state variables for GPU calculation.
+ size_t &ncells = mesh->ncells;
+
+ vector<int> mpot;
+
+ size_t new_ncells = 0;
+ double H_sum = -1.0;
+
+ // Main loop.
+ int endcycle = MIN3(niter, next_cp_cycle, next_graphics_cycle);
+
+ cpu_timer_start(&tstart_cpu);
+
+ for (int nburst = ncycle % outputInterval; nburst < outputInterval && ncycle < endcycle; nburst++, ncycle++) {
+
+#ifdef _OPENMP
+#pragma omp parallel
+ {
+#endif
+ // Calculate the real time step for the current discrete time step.
+ double mydeltaT = state->set_timestep(g, sigma); // Private variable to avoid write conflict
+#ifdef _OPENMP
+#pragma omp barrier
+#pragma omp master
+ {
+#endif
+ deltaT = mydeltaT;
+ simTime += deltaT;
+#ifdef _OPENMP
+ }
+#endif
+
+ mesh->calc_neighbors(ncells);
+
+ cpu_timer_start(&tstart_partmeas);
+ mesh->partition_measure();
+
+#ifdef _OPENMP
+#pragma omp master
+#endif
+ cpu_time_partmeas += cpu_timer_stop(tstart_partmeas);
+
+ // Currently not working -- may need to be earlier?
+ //if (do_cpu_calc && ! mesh->have_boundary) {
+ // state->add_boundary_cells(mesh);
+ //}
+
+ // Apply BCs is currently done as first part of gpu_finite_difference and so comparison won't work here
+
+ mesh->set_bounds(ncells);
+
+ // Execute main kernel
+ if (face_based) {
+ state->calc_finite_difference_via_faces(deltaT);
+ } else {
+ state->calc_finite_difference(deltaT);
+ }
+
+ // Size of arrays gets reduced to just the real cells in this call for have_boundary = 0
+ state->remove_boundary_cells();
+#ifdef _OPENMP
+ } // end parallel region
+#endif
+
+ mpot.resize(ncells);
+ new_ncells = state->calc_refine_potential(mpot, icount, jcount);
+
+ // Resize the mesh, inserting cells where refinement is necessary.
+
+#ifdef _OPENMP
+#pragma omp parallel
+ {
+#endif
+ state->rezone_all(icount, jcount, mpot);
+
+ // Clear does not delete mpot, so have to swap with an empty vector to get
+ // it to delete the mpot memory. This is all to avoid valgrind from showing
+ // it as a reachable memory leak
+#ifdef _OPENMP
+#pragma omp master
+ {
+#endif
+ //mpot.clear();
+ vector<int>().swap(mpot);
+
+ mesh->ncells = new_ncells;
+ ncells = new_ncells;
+#ifdef _OPENMP
+ }
+#pragma omp barrier
+#endif
+ mesh->set_bounds(ncells);
+
+#ifdef _OPENMP
+#pragma omp master
+ {
+#endif
+ //cpu_timer_start(&tstart_check);
+ mesh->proc.resize(ncells);
+ if (icount)
+ { vector<int> index(ncells);
+ mesh->partition_cells(numpe, index, cycle_reorder);
+ state->state_reorder(index);
+ state->memory_reset_ptrs();
+ }
+ //cpu_time_check += cpu_timer_stop(tstart_check);
+#ifdef _OPENMP
+ }
+#pragma omp barrier
+#endif
+
+#ifdef _OPENMP
+ } // end parallel region
+#endif
+
+ } // End burst loop
+
+ cpu_time_calcs += cpu_timer_stop(tstart_cpu);
+
+ H_sum = state->mass_sum(enhanced_precision_sum);
+
+ int error_status = STATUS_OK;
+
+ if (isnan(H_sum)) {
+ printf("Got a NAN on cycle %d\n",ncycle);
+ error_status = STATUS_NAN;
+ }
+
+ double percent_mass_diff = fabs(H_sum - H_sum_initial)/H_sum_initial * 100.0;
+ if (percent_mass_diff >= upper_mass_diff_percentage) {
+ printf("Mass difference outside of acceptable range on cycle %d percent_mass_diff %lg upper limit %lg\n",ncycle,percent_mass_diff, upper_mass_diff_percentage);
+ error_status = STATUS_MASS_LOSS;
+ }
+
+ if (error_status != STATUS_OK){
+ if (crux_type != CRUX_NONE) {
+
+ rollback_attempt++;
+ if (rollback_attempt > num_of_rollback_states) {
+ printf("Can not recover from error from back up files. Killing program...\n");
+ total_program_time = cpu_timer_stop(total_exec);
+ FILE *fp = fopen(total_sim_time_log,"w");
+ fprintf(fp,"The total execution time of the program before failure was %g seconds\n", total_program_time);
+ fclose(fp);
+ state->print_failure_log(ncycle, simTime, H_sum_initial, H_sum, percent_mass_diff, true);
+ exit(-1);
+ }
+
+ if (graphic_outputInterval <= niter){
+ mesh->calc_spatial_coordinates(0);
+ set_graphics_mysize(ncells);
+ set_graphics_viewmode(view_mode);
+ set_graphics_cell_coordinates(&mesh->x[0], &mesh->dx[0], &mesh->y[0], &mesh->dy[0]);
+ set_graphics_cell_data(&state->H[0]);
+ set_graphics_cell_proc(&mesh->proc[0]);
+ write_graphics_info(ncycle/graphic_outputInterval,ncycle,simTime,1,rollback_attempt);
+ }
+
+ if((ncycle - (rollback_attempt)*checkpoint_outputInterval) < 0){
+ printf("Rolling simulation back to to ncycle 0\n");
+ }
+ else{
+ printf("Rolling simulation back to to ncycle %d\n", ncycle - (rollback_attempt*checkpoint_outputInterval));
+ }
+
+ state->print_rollback_log(ncycle, simTime, H_sum_initial, H_sum, percent_mass_diff, rollback_attempt, num_of_rollback_states, error_status);
+
+ int rollback_num = crux->get_rollback_number();
+
+ restore_crux_data_bootstrap(crux, NULL, rollback_num);
+ mesh->terminate();
+ state->terminate();
+ restore_crux_data(crux);
+
+
+ } else {
+ printf("failure.log has been created\n");
+ state->print_failure_log(ncycle, simTime, H_sum_initial, H_sum, percent_mass_diff, true);
+ exit(-1);
+ }
+ }
+
+ if (mype == 0 && ncycle % outputInterval == 0) {
+ printf("Iteration %3d timestep %lf Sim Time %lf cells %ld Mass Sum %14.12lg Mass Change %12.6lg\n",
+ ncycle, deltaT, simTime, ncells, H_sum, H_sum - H_sum_initial);
+ }
+
+ if (ncycle == next_cp_cycle) store_crux_data(crux, ncycle);
+
+ cpu_timer_start(&tstart_cpu);
+
+ if(do_display_graphics || ncycle == next_graphics_cycle ||
+ (ncycle >= niter && graphic_outputInterval < niter) ){
+
+ mesh->calc_spatial_coordinates(0);
+ }
+
+ if(ncycle == next_graphics_cycle){
+ set_graphics_mysize(ncells);
+ set_graphics_viewmode(view_mode);
+ set_graphics_cell_coordinates(&mesh->x[0], &mesh->dx[0], &mesh->y[0], &mesh->dy[0]);
+ set_graphics_cell_data(&state->H[0]);
+ set_graphics_cell_proc(&mesh->proc[0]);
+
+ write_graphics_info(ncycle/graphic_outputInterval,ncycle,simTime,0,0);
+ next_graphics_cycle += graphic_outputInterval;
+ }
+
+#ifdef HAVE_GRAPHICS
+ if(ncycle % outputInterval == 0){
+ if(ncycle != next_graphics_cycle){
+ set_display_mysize(ncells);
+ set_display_viewmode(view_mode);
+ set_display_cell_coordinates(&mesh->x[0], &mesh->dx[0], &mesh->y[0], &mesh->dy[0]);
+ set_display_cell_data(&state->H[0]);
+ set_display_cell_proc(NULL);
+ }
+ set_display_circle_radius(circle_radius);
+ draw_scene();
+ }
+
+#endif
+
+ cpu_time_graphics += cpu_timer_stop(tstart_cpu);
+
+ // Output final results and timing information.
+ if (ncycle >= niter) {
+ //free_display();
+
+ if(graphic_outputInterval < niter){
+ cpu_timer_start(&tstart_cpu);
+
+#ifdef HAVE_GRAPHICS
+ set_display_viewmode(view_mode);
+ set_display_mysize(ncells);
+ set_display_cell_coordinates(&mesh->x[0], &mesh->dx[0], &mesh->y[0], &mesh->dy[0]);
+ set_display_cell_data(&state->H[0]);
+ set_display_cell_proc(NULL);
+#endif
+
+ if (mype == 0) {
+ write_graphics_info(ncycle/graphic_outputInterval,ncycle,simTime,0,0);
+ }
+ next_graphics_cycle += graphic_outputInterval;
+
+ cpu_time_graphics += cpu_timer_stop(tstart_cpu);
+ }
+
+ // Get overall program timing.
+ double elapsed_time = cpu_timer_stop(tstart);
+
+ long long mem_used = memstats_memused();
+ #ifdef MEMORY
+ if (mem_used > 0) {
+ printf("Memory used %lld kB\n",mem_used);
+ printf("Memory peak %lld kB\n",memstats_mempeak());
+ printf("Memory free %lld kB\n",memstats_memfree());
+ printf("Memory available %lld kB\n",memstats_memtotal());
+ }
+ #endif
+ state->output_timing_info(do_cpu_calc, do_gpu_calc, elapsed_time);
+ #ifdef TIMING
+ mesh->parallel_output("CPU: calc incl part meas time was",cpu_time_calcs, 0, "s");
+ mesh->parallel_output("CPU: calculation only time was",cpu_time_calcs-cpu_time_partmeas, 0, "s");
+ mesh->parallel_output("CPU: partition measure time was",cpu_time_partmeas, 0, "s");
+ mesh->parallel_output("CPU: graphics time was",cpu_time_graphics, 0, "s");
+ //mesh->parallel_output("CPU: check time was",cpu_time_check, 0, "s");
+ #endif
+
+ mesh->print_partition_measure();
+ mesh->print_calc_neighbor_type();
+ mesh->print_partition_type();
+
+ printf("CPU: rezone frequency \t %8.4f\tpercent\n", (double)mesh->get_cpu_counter(MESH_COUNTER_REZONE)/(double)ncycle*100.0 );
+ printf("CPU: calc neigh frequency \t %8.4f\tpercent\n", (double)mesh->get_cpu_counter(MESH_COUNTER_CALC_NEIGH)/(double)ncycle*100.0 );
+ printf("CPU: refine_smooth_iter per rezone \t %8.4f\t\n", (double)mesh->get_cpu_counter(MESH_COUNTER_REFINE_SMOOTH)/(double)mesh->get_cpu_counter(MESH_COUNTER_REZONE) );
+
+ mesh->terminate();
+ state->terminate();
+
+ terminate_graphics_output();
+
+ delete mesh;
+ delete state;
+ delete crux;
+ delete parse;
+
+ total_program_time = cpu_timer_stop(total_exec);
+ FILE *fp = fopen(total_sim_time_log,"w");
+ fprintf(fp,"The total execution time of the program was %g seconds\n", total_program_time);
+ fclose(fp);
+ exit(0);
+ } // Complete final output.
+
+} // end do_calc
+
+const int CRUX_CLAMR_VERSION = 101;
+const int num_int_vals = 15;
+const int num_double_vals = 5;
+
+MallocPlus clamr_bootstrap_memory;
+
+void store_crux_data(Crux *crux, int ncycle)
+{
+ size_t nsize = num_int_vals*sizeof(int) +
+ num_double_vals*sizeof(double);
+ nsize += state->get_checkpoint_size();
+
+ next_cp_cycle += checkpoint_outputInterval;
+
+ int int_vals[num_int_vals];
+
+ int_vals[ 0] = CRUX_CLAMR_VERSION; // Version number
+ int_vals[ 1] = nx;
+ int_vals[ 2] = ny;
+ int_vals[ 3] = levmx;
+ int_vals[ 4] = ndim;
+ int_vals[ 5] = outputInterval;
+ int_vals[ 6] = enhanced_precision_sum;
+ int_vals[ 7] = niter;
+ int_vals[ 8] = it;
+ int_vals[ 9] = ncycle;
+ int_vals[10] = crux_type;
+ int_vals[11] = graphic_outputInterval;
+ int_vals[12] = checkpoint_outputInterval;
+ int_vals[13] = next_cp_cycle;
+ int_vals[14] = next_graphics_cycle;
+
+ double double_vals[num_double_vals];
+ double_vals[ 0] = circ_radius;
+ double_vals[ 1] = H_sum_initial;
+ double_vals[ 2] = simTime;
+ double_vals[ 3] = deltaT;
+ double_vals[ 4] = upper_mass_diff_percentage;
+
+ clamr_bootstrap_memory.memory_add(int_vals, size_t(num_int_vals), 4, "bootstrap_int_vals", RESTART_DATA);
+ clamr_bootstrap_memory.memory_add(double_vals, size_t(num_double_vals), 8, "bootstrap_double_vals", RESTART_DATA);
+
+ crux->store_begin(nsize, ncycle);
+
+ crux->store_MallocPlus(clamr_bootstrap_memory);
+
+ state->store_checkpoint(crux);
+
+ crux->store_end();
+
+ clamr_bootstrap_memory.memory_remove(int_vals);
+ clamr_bootstrap_memory.memory_remove(double_vals);
+}
+
+void restore_crux_data_bootstrap(Crux *crux, char *restart_file, int rollback_counter)
+{
+ crux->restore_begin(restart_file, rollback_counter);
+
+ int int_vals[num_int_vals];
+
+ double double_vals[num_double_vals];
+
+ clamr_bootstrap_memory.memory_add(int_vals, size_t(num_int_vals), 4, "bootstrap_int_vals", RESTART_DATA);
+ clamr_bootstrap_memory.memory_add(double_vals, size_t(num_double_vals), 8, "bootstrap_double_vals", RESTART_DATA);
+
+ crux->restore_MallocPlus(clamr_bootstrap_memory);
+
+ if (int_vals[ 0] != CRUX_CLAMR_VERSION) {
+ printf("CRUX version mismatch for clamr data, version on file is %d, version in code is %d\n",
+ int_vals[0], CRUX_CLAMR_VERSION);
+ exit(0);
+ }
+
+ nx = int_vals[ 1];
+ ny = int_vals[ 2];
+ levmx = int_vals[ 3];
+ ndim = int_vals[ 4];
+ outputInterval = int_vals[ 5];
+ enhanced_precision_sum = int_vals[ 6];
+ niter = int_vals[ 7];
+ it = int_vals[ 8];
+ ncycle = int_vals[ 9];
+ crux_type = int_vals[10];
+ graphic_outputInterval = int_vals[11];
+ checkpoint_outputInterval = int_vals[12];
+ next_cp_cycle = int_vals[13];
+ next_graphics_cycle = int_vals[14];
+
+ circ_radius = double_vals[ 0];
+ H_sum_initial = double_vals[ 1];
+ simTime = double_vals[ 2];
+ deltaT = double_vals[ 3];
+ upper_mass_diff_percentage = double_vals[ 4];
+
+ // need to reset crux type, because initialize to none
+ // before checkpoint is read
+ crux->set_crux_type(crux_type);
+
+ clamr_bootstrap_memory.memory_remove(int_vals);
+ clamr_bootstrap_memory.memory_remove(double_vals);
+
+#ifdef DEBUG_RESTORE_VALS
+ if (DEBUG_RESTORE_VALS) {
+ const char *int_vals_descriptor[num_int_vals] = {
+ "CRUX_CLAMR_VERSION",
+ "nx",
+ "ny",
+ "levmx",
+ "ndim",
+ "outputInterval",
+ "enhanced_precision_sum",
+ "niter",
+ "it",
+ "ncycle",
+ "crux_type",
+ "graphic_outputInterval",
+ "checkpoint_outputInterval",
+ "next_cp_cycle",
+ "next_graphics_cycle"
+ };
+ printf("\n");
+ printf(" === Restored bootstrap int_vals ===\n");
+ for (int i = 0; i < num_int_vals; i++){
+ printf(" %-30s %d\n",int_vals_descriptor[i], int_vals[i]);
+ }
+ printf(" === Restored bootstrap int_vals ===\n");
+ printf("\n");
+ }
+#endif
+
+#ifdef DEBUG_RESTORE_VALS
+ if (DEBUG_RESTORE_VALS) {
+ const char *double_vals_descriptor[num_double_vals] = {
+ "circ_radius",
+ "H_sum_initial",
+ "simTime",
+ "deltaT",
+ "upper_mass_diff_percentage"
+ };
+ printf("\n");
+ printf(" === Restored bootstrap double_vals ===\n");
+ for (int i = 0; i < num_double_vals; i++){
+ printf(" %-30s %lg\n",double_vals_descriptor[i], double_vals[i]);
+ }
+ printf(" === Restored bootstrap double_vals ===\n");
+ printf("\n");
+ }
+#endif
+}
+
+void restore_crux_data(Crux *crux)
+{
+ state->restore_checkpoint(crux);
+
+ crux->restore_end();
+}
+
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/crux.cpp
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/crux.cpp?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/crux.cpp (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/crux.cpp Sun Sep 3 20:10:18 2017
@@ -0,0 +1,1054 @@
+/*
+ * Copyright (c) 2014, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ *
+ * Authors: Brian Atkinson bwa at g.clemson.edu
+ Bob Robey XCP-2 brobey at lanl.gov
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <algorithm>
+#include <assert.h>
+#include "PowerParser.hh"
+
+#include "crux.h"
+#include "timer.h"
+#include "fmemopen.h"
+
+#ifdef HAVE_HDF5
+#include "hdf5.h"
+#endif
+#ifdef HAVE_MPI
+#include "mpi.h"
+#endif
+
+const bool CRUX_TIMING = true;
+bool do_crux_timing = false;
+
+#define RESTORE_NONE 0
+#define RESTORE_RESTART 1
+#define RESTORE_ROLLBACK 2
+
+#ifndef DEBUG
+#define DEBUG 0
+#endif
+#define DEBUG_RESTORE_VALS 1
+
+using namespace std;
+using PP::PowerParser;
+// Pointers to the various objects.
+PowerParser *parse;
+
+char checkpoint_directory[] = "checkpoint_output";
+int cp_num, rs_num;
+int *backup;
+void **crux_data;
+size_t *crux_data_size;
+#ifdef HAVE_HDF5
+bool USE_HDF5 = true; //MSB
+hid_t h5_fid;
+herr_t h5err;
+bool is_restart = false;
+
+hid_t create_hdf5_parallel_file_plist();
+
+void map_name_to_hdf5 (const char*, int, char*, char*);
+
+void access_named_hdf5_values (const char *name, int name_size,
+ hsize_t rank, hsize_t *cur_size,
+ void *values, hid_t datatype,
+ bool store);
+#endif
+
+
+FILE *crux_time_fp;
+struct timeval tcheckpoint_time;
+struct timeval trestore_time;
+int checkpoint_timing_count = 0;
+float checkpoint_timing_sum = 0.0f;
+float checkpoint_timing_size = 0.0f;
+int rollback_attempt = 0;
+FILE *store_fp, *restore_fp;
+#ifdef HAVE_MPI
+static MPI_File mpi_store_fp, mpi_restore_fp;
+#endif
+static int mype = 0, npes = 1;
+
+Crux::Crux(int crux_type_in, int num_of_rollback_states_in, bool restart)
+{
+#ifdef HAVE_MPI
+ MPI_Comm_rank(MPI_COMM_WORLD,&mype);
+ MPI_Comm_size(MPI_COMM_WORLD,&npes);
+#endif
+
+ num_of_rollback_states = num_of_rollback_states_in;
+ crux_type = crux_type_in;
+ checkpoint_counter = 0;
+
+ if (crux_type != CRUX_NONE || restart){
+ do_crux_timing = CRUX_TIMING;
+ struct stat stat_descriptor;
+ if (stat(checkpoint_directory,&stat_descriptor) == -1){
+ mkdir(checkpoint_directory,0777);
+ }
+ }
+
+ crux_data = (void **)malloc(num_of_rollback_states*sizeof(void *));
+ for (int i = 0; i < num_of_rollback_states; i++){
+ crux_data[i] = NULL;
+ }
+ crux_data_size = (size_t *)malloc(num_of_rollback_states*sizeof(size_t));
+
+
+ if (do_crux_timing){
+ char checkpointtimelog[60];
+ sprintf(checkpointtimelog,"%s/crux_timing.log",checkpoint_directory);
+ crux_time_fp = fopen(checkpointtimelog,"w");
+ }
+}
+
+Crux::~Crux()
+{
+ for (int i = 0; i < num_of_rollback_states; i++){
+ free(crux_data[i]);
+ }
+ free(crux_data);
+ free(crux_data_size);
+
+ if (do_crux_timing){
+ if (checkpoint_timing_count > 0) {
+ printf("CRUX checkpointing time averaged %f msec, bandwidth %f Mbytes/sec\n",
+ checkpoint_timing_sum/(float)checkpoint_timing_count*1.0e3,
+ checkpoint_timing_size/checkpoint_timing_sum*1.0e-6);
+
+ fprintf(crux_time_fp,"CRUX checkpointing time averaged %f msec, bandwidth %f Mbytes/sec\n",
+ checkpoint_timing_sum/(float)checkpoint_timing_count*1.0e3,
+ checkpoint_timing_size/checkpoint_timing_sum*1.0e-6);
+
+ fclose(crux_time_fp);
+ }
+ }
+}
+
+void Crux::store_MallocPlus(MallocPlus memory){
+
+ malloc_plus_memory_entry *memory_item;
+
+ for (memory_item = memory.memory_entry_by_name_begin();
+ memory_item != memory.memory_entry_by_name_end();
+ memory_item = memory.memory_entry_by_name_next() ){
+
+ void *mem_ptr = memory_item->mem_ptr;
+ if ((memory_item->mem_flags & RESTART_DATA) == 0) continue;
+
+
+
+ if (DEBUG) {
+ printf("MallocPlus ptr %p: name %10s ptr %p dims %lu nelem (",
+ mem_ptr,memory_item->mem_name,memory_item->mem_ptr,memory_item->mem_ndims);
+
+ char nelemstring[80];
+ char *str_ptr = nelemstring;
+ str_ptr += sprintf(str_ptr,"%lu", memory_item->mem_nelem[0]);
+ for (uint i = 1; i < memory_item->mem_ndims; i++){
+ str_ptr += sprintf(str_ptr,", %lu", memory_item->mem_nelem[i]);
+ }
+ printf("%12s",nelemstring);
+
+ printf(") elsize %lu flags %d capacity %lu\n",
+ memory_item->mem_elsize,memory_item->mem_flags,memory_item->mem_capacity);
+ }
+
+#ifdef HAVE_HDF5
+ if(USE_HDF5) {
+ access_named_hdf5_values (memory_item->mem_name,
+ strlen (memory_item->mem_name),
+ (hsize_t) memory_item->mem_ndims,
+ (hsize_t *) memory_item->mem_nelem,
+ mem_ptr,
+ memory_item->mem_elsize == 4 ?
+ H5T_NATIVE_INT : H5T_NATIVE_DOUBLE,
+ true);
+ } else {
+#endif
+ int num_elements = 1;
+ for (uint i = 0; i < memory_item->mem_ndims; i++){
+ num_elements *= memory_item->mem_nelem[i];
+ }
+ store_field_header(memory_item->mem_name,30);
+ if (memory_item->mem_flags & REPLICATED_DATA) {
+ if (memory_item->mem_elsize == 4){
+ store_replicated_int_array((int *)mem_ptr, num_elements);
+ } else {
+ store_replicated_double_array((double *)mem_ptr, num_elements);
+ }
+ } else {
+ if (memory_item->mem_elsize == 4){
+ store_int_array((int *)mem_ptr, num_elements);
+ } else {
+ store_double_array((double *)mem_ptr, num_elements);
+ }
+ }
+ }
+#ifdef HAVE_HDF5
+ }
+#endif
+}
+
+void Crux::store_begin(size_t nsize, int ncycle)
+{
+
+ int mype = 0;
+
+#ifdef HAVE_MPI
+ MPI_Comm_rank(MPI_COMM_WORLD,&mype);
+#endif
+
+ cp_num = checkpoint_counter % num_of_rollback_states;
+ cpu_timer_start(&tcheckpoint_time);
+
+ if(crux_type == CRUX_IN_MEMORY) {
+ if (crux_data[cp_num] != NULL) free(crux_data[cp_num]);
+ crux_data[cp_num] = (int *)malloc(nsize);
+ crux_data_size[cp_num] = nsize;
+ store_fp = fmemopen(crux_data[cp_num], nsize, "w");
+ } else if(crux_type == CRUX_DISK) {
+ char backup_file_w_dir[60];
+ char backup_file[40];
+#ifdef HAVE_HDF5
+ if(USE_HDF5) {
+
+ hid_t plist_id = create_hdf5_parallel_file_plist();
+
+#ifdef HDF5_FF
+ if(is_restart)
+ sprintf(backup_file_w_dir,"rbackup%05d.h5",ncycle);
+ else
+ sprintf(backup_file_w_dir,"backup%05d.h5",ncycle);
+#else
+ sprintf(backup_file_w_dir,"%s/backup%05d.h5",checkpoint_directory,ncycle);
+ sprintf(backup_file,"backup%05d.h5",ncycle);
+#endif
+ if(!(h5_fid = H5Fcreate(backup_file_w_dir, H5F_ACC_TRUNC, H5P_DEFAULT, plist_id))) {
+ printf("HDF5: Could not write HDF5 %s at iteration %d\n",backup_file_w_dir,ncycle);
+ }
+ H5Pclose(plist_id);
+ } else {
+#endif
+ sprintf(backup_file_w_dir,"%s/backup%05d.crx",checkpoint_directory,ncycle);
+ sprintf(backup_file,"backup%05d.crx",ncycle);
+#ifdef HAVE_MPI
+ int iret = MPI_File_open(MPI_COMM_WORLD, backup_file_w_dir, MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &mpi_store_fp);
+ if(iret != MPI_SUCCESS) {
+ printf("Could not write %s at iteration %d\n",backup_file_w_dir,ncycle);
+ }
+#else
+ store_fp = fopen(backup_file_w_dir,"w");
+ if(!store_fp){
+ printf("Could not write %s at iteration %d\n",backup_file_w_dir,ncycle);
+ }
+#endif
+ if (mype == 0) {
+ char symlink_file[60];
+ sprintf(symlink_file,"%s/backup%1d.crx",checkpoint_directory,cp_num);
+ unlink(symlink_file);
+ symlink(backup_file, symlink_file);
+ // int ireturn = symlink(backup_file, symlink_file);
+ // if (ireturn == -1) {
+ // printf("Warning: error returned with symlink call for file %s and symlink %s\n",
+ // backup_file,symlink_file);
+ // }
+ }
+ }
+#ifdef HAVE_HDF5
+ }
+#endif
+ if (do_crux_timing) {
+ checkpoint_timing_size += nsize;
+ }
+}
+
+void Crux::store_field_header(const char *name, int name_size){
+#ifdef HAVE_MPI
+ assert(name != NULL);
+ MPI_Status status;
+ MPI_File_write_shared(mpi_store_fp, (void *)name, name_size, MPI_CHAR, &status);
+ MPI_Barrier(MPI_COMM_WORLD);
+#ifdef DEBUG_RESTORE_VALS
+ int count;
+ MPI_Get_count(&status, MPI_CHAR, &count);
+ printf("%d:Wrote %d characters at line %d in file %s\n",mype,count,__LINE__,__FILE__);
+#endif
+
+#else
+ assert(name != NULL && store_fp != NULL);
+ fwrite(name,sizeof(char),name_size,store_fp);
+#endif
+}
+
+#ifdef HAVE_HDF5
+hid_t create_hdf5_parallel_file_plist()
+{
+ hid_t plist_id = H5P_DEFAULT;
+
+ if( (plist_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
+ printf("HDF5: Could not create property list \n");
+
+#ifdef HAVE_MPI
+ if( H5Pset_libver_bounds(plist_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
+ printf("HDF5: Could set libver bounds \n");
+# ifdef HDF5_FF
+ H5Pset_fapl_daosm(plist_id, MPI_COMM_WORLD, MPI_INFO_NULL);
+ if(H5Pset_all_coll_metadata_ops(plist_id, true) < 0)
+ printf("HDF5: Could not set collective metadata \n");
+# else
+ H5Pset_fapl_mpio(plist_id, MPI_COMM_WORLD, MPI_INFO_NULL);
+#endif
+#endif
+ return plist_id;
+}
+
+void map_name_to_hdf5 (const char *name, int name_size,
+ char *group,
+ char *label)
+{
+ static const char * default_group = "default";
+ int i, j;
+ group[0] = '/';
+ for (i=0; i<name_size; i++)
+ if (name[i] == '_') break;
+ if (i < name_size) {
+ for (j=0; j<i; j++)
+ group[1+j] = name[j];
+ ++i;
+ } else {
+ for (j=0; default_group[j]; j++)
+ group[1+j] = default_group[j];
+ i=0;
+ }
+ group[1+j] = '\0';
+ for (j=i; name[j]; j++)
+ label[j-i] = name[j];
+ label[j-i] = '\0';
+}
+
+void access_named_hdf5_values (const char *name, int name_size,
+ hsize_t rank, hsize_t *sizes,
+ void *values, hid_t datatype,
+ bool store)
+{
+ size_t length = 0, count = 1, offset = 0;
+ char groupname[512], fieldname[512];
+ hid_t hid_group, hid_space, hid_mem, hid_dataset, hid_plist = H5P_DEFAULT;
+
+ map_name_to_hdf5(name, name_size, groupname, fieldname);
+ for (hsize_t i=0; i<rank; i++)
+ count *= sizes[i];
+#ifdef HAVE_MPI
+ hid_plist = H5Pcreate(H5P_DATASET_XFER);
+# ifndef HDF5_FF
+ H5Pset_dxpl_mpio(hid_plist, H5FD_MPIO_COLLECTIVE);
+# endif
+ if (npes > 1) {
+ size_t *counts = new size_t[npes];
+ MPI_Allgather (&count, sizeof(count), MPI_BYTE,
+ counts, sizeof *counts, MPI_BYTE,
+ MPI_COMM_WORLD);
+ for (int i=0; i<npes; i++) {
+ if (i == mype)
+ offset = length;
+ length += counts[i];
+ }
+ delete[] counts;
+ } else {
+#endif
+ length = count;
+#ifdef HAVE_MPI
+ }
+#endif
+
+#ifndef HDF5_FF
+ if (!store || H5Lexists(h5_fid, groupname, H5P_DEFAULT))
+ hid_group = H5Gopen (h5_fid, groupname, H5P_DEFAULT);
+ else
+ hid_group = H5Gcreate (h5_fid, groupname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+#else
+ int mpi_rank;
+ MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
+
+ if(store) {
+ hbool_t ret;
+
+ if(mpi_rank == 0)
+ ret = H5Lexists(h5_fid, groupname, H5P_DEFAULT);
+
+ MPI_Bcast(&ret, sizeof(hbool_t), MPI_BYTE, 0, MPI_COMM_WORLD);
+ if(!ret)
+ hid_group = H5Gcreate (h5_fid, groupname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ else
+ hid_group = H5Gopen (h5_fid, groupname, H5P_DEFAULT);
+ }
+ if (!store) {
+ hid_group = H5Gopen (h5_fid, groupname, H5P_DEFAULT);
+ }
+#endif
+ if (hid_group == -1) {
+ fprintf(stderr, "Unable to create group: %30s\n", groupname);
+ exit(1);
+ }
+ hid_mem = H5Screate_simple (1, (hsize_t *) &count, NULL);
+ hid_space = H5Screate_simple (1, (hsize_t *) &length, NULL);
+ if (hid_space == -1) {
+ fprintf(stderr, "Unable to create space\n");
+ exit(1);
+ }
+ if (store) {
+ hid_dataset = H5Dcreate (hid_group, fieldname, datatype, hid_space,
+ H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ } else
+ hid_dataset = H5Dopen (hid_group, fieldname, H5P_DEFAULT);
+
+ if(hid_dataset == -1) {
+ fprintf(stderr, "Unable to access dataset %s\n", fieldname);
+ exit(1);
+ }
+
+ if (!hid_dataset) {
+ fprintf(stderr, "Unable to create/open dataset: %30s\n", fieldname);
+ exit(1);
+ }
+
+ herr_t status;
+ status = H5Sselect_hyperslab (hid_space, H5S_SELECT_SET,
+ (hsize_t *) &offset, NULL,
+ (hsize_t *) &count, NULL);
+ if(status < 0) {
+ fprintf(stderr, "Unable to select correct hyperslab\n");
+ exit(1);
+ }
+ if (store)
+ status = H5Dwrite (hid_dataset, datatype, hid_mem, hid_space, hid_plist, values);
+ else
+ status = H5Dread (hid_dataset, datatype, hid_mem, hid_space, hid_plist, values);
+
+ H5Dclose (hid_dataset);
+ H5Gclose (hid_group);
+ H5Sclose (hid_space);
+ H5Sclose (hid_mem);
+#ifdef HAVE_MPI
+ H5Pclose (hid_plist);
+#endif
+}
+#endif
+
+void Crux::store_named_ints(const char *name, int name_size, int *int_vals, size_t nelem)
+{
+#ifdef HAVE_HDF5
+ if (USE_HDF5) {
+ access_named_hdf5_values (name, name_size, 1, (hsize_t *) &nelem,
+ int_vals, H5T_NATIVE_INT, true);
+
+ } else {
+#endif
+ store_field_header (name, name_size);
+ store_int_array (int_vals, nelem);
+#ifdef HAVE_HDF5
+ }
+#endif
+}
+
+void Crux::restore_named_ints(const char *name, int name_size, int *int_vals, size_t nelem)
+{
+#ifdef HAVE_HDF5
+ if (USE_HDF5) {
+ access_named_hdf5_values (name, name_size, 1, (hsize_t *) &nelem,
+ int_vals, H5T_NATIVE_INT, false);
+
+ } else {
+#endif
+ char fname[512];
+ restore_field_header (fname, name_size);
+ restore_int_array (int_vals, nelem);
+#ifdef HAVE_HDF5
+ }
+#endif
+}
+
+void Crux::store_bools(bool *bool_vals, size_t nelem)
+{
+ assert(bool_vals != NULL && store_fp != NULL);
+ fwrite(bool_vals,sizeof(bool),nelem,store_fp);
+}
+
+void Crux::store_ints(int *int_vals, size_t nelem)
+{
+ assert(int_vals != NULL && store_fp != NULL);
+ fwrite(int_vals,sizeof(int),nelem,store_fp);
+}
+
+void Crux::store_longs(long long *long_vals, size_t nelem)
+{
+ assert(long_vals != NULL && store_fp != NULL);
+ fwrite(long_vals,sizeof(long long),nelem,store_fp);
+}
+
+void Crux::store_sizets(size_t *size_t_vals, size_t nelem)
+{
+ assert(size_t_vals != NULL && store_fp != NULL);
+ fwrite(size_t_vals,sizeof(size_t),nelem,store_fp);
+}
+
+void Crux::store_doubles(double *double_vals, size_t nelem)
+{
+ assert(double_vals != NULL && store_fp != NULL);
+ fwrite(double_vals,sizeof(double),nelem,store_fp);
+}
+
+void Crux::store_int_array(int *int_array, size_t nelem)
+{
+#ifdef HAVE_MPI
+ assert(int_array != NULL);
+ MPI_Status status;
+ MPI_File_write_shared(mpi_store_fp, int_array, (int)nelem, MPI_INT, &status);
+ MPI_Barrier(MPI_COMM_WORLD);
+#ifdef DEBUG_RESTORE_VALS
+ int count;
+ MPI_Get_count(&status, MPI_INT, &count);
+ printf("%d:Wrote %d integers at line %d in file %s\n",mype,count,__LINE__,__FILE__);
+#endif
+
+#else
+ assert(int_array != NULL && store_fp != NULL);
+ fwrite(int_array,sizeof(int),nelem,store_fp);
+#endif
+}
+
+void Crux::store_long_array(long long *long_array, size_t nelem)
+{
+ assert(long_array != NULL && store_fp != NULL);
+ fwrite(long_array,sizeof(long long),nelem,store_fp);
+}
+
+void Crux::store_float_array(float *float_array, size_t nelem)
+{
+ assert(float_array != NULL && store_fp != NULL);
+ fwrite(float_array,sizeof(float),nelem,store_fp);
+}
+
+void Crux::store_double_array(double *double_array, size_t nelem)
+{
+#ifdef HAVE_MPI
+ assert(double_array != NULL);
+ MPI_Status status;
+ MPI_File_write_shared(mpi_store_fp, double_array, (int)nelem, MPI_DOUBLE, &status);
+ MPI_Barrier(MPI_COMM_WORLD);
+#ifdef DEBUG_RESTORE_VALS
+ int count;
+ MPI_Get_count(&status, MPI_DOUBLE, &count);
+ printf("%d:Wrote %d doubles at line %d in file %s\n",mype,count,__LINE__,__FILE__);
+#endif
+
+#else
+ assert(double_array != NULL && store_fp != NULL);
+ fwrite(double_array,sizeof(double),nelem,store_fp);
+#endif
+}
+
+void Crux::store_replicated_int_array(int *int_array, size_t nelem)
+{
+#ifdef HAVE_MPI
+ assert(int_array != NULL);
+ MPI_Status status;
+ MPI_File_write_shared(mpi_store_fp, int_array, (int)nelem, MPI_INT, &status);
+ MPI_Barrier(MPI_COMM_WORLD);
+#ifdef DEBUG_RESTORE_VALS
+ int count;
+ MPI_Get_count(&status, MPI_INT, &count);
+ printf("%d:Wrote %d integers at line %d in file %s\n",mype,count,__LINE__,__FILE__);
+#endif
+
+#else
+ assert(int_array != NULL && store_fp != NULL);
+ fwrite(int_array,sizeof(int),nelem,store_fp);
+#endif
+}
+
+void Crux::store_replicated_double_array(double *double_array, size_t nelem)
+{
+#ifdef HAVE_MPI
+ assert(double_array != NULL);
+ MPI_Status status;
+ MPI_File_write_shared(mpi_store_fp, double_array, (int)nelem, MPI_DOUBLE, &status);
+ MPI_Barrier(MPI_COMM_WORLD);
+#ifdef DEBUG_RESTORE_VALS
+ int count;
+ MPI_Get_count(&status, MPI_DOUBLE, &count);
+ printf("%d:Wrote %d doubles at line %d in file %s\n",mype,count,__LINE__,__FILE__);
+#endif
+
+#else
+ assert(double_array != NULL && store_fp != NULL);
+ fwrite(double_array,sizeof(double),nelem,store_fp);
+#endif
+}
+
+#ifdef HAVE_MPI
+void Crux::store_distributed_int_array(int *int_array, size_t nelem, int flags)
+{
+ assert(int_array != NULL);
+ //MPI_Datatype datatype = get_crux_datatype(DISTRIBUTED_INT_DATA);
+ MPI_Status status;
+ //MPI_File_write_shared(mpi_store_fp, int_array, nelem, MPI_INT, &status);
+ printf("writing crux data type 8\n");
+ //MPI_File_write_shared(mpi_store_fp, int_array, 1, crux_datatype[8], &status);
+#ifdef DEBUG_RESTORE_VALS
+ int count;
+ MPI_Get_count(&status, MPI_INT, &count);
+ printf("%d:Wrote %d integers at line %d in file %s\n",mype,count,__LINE__,__FILE__);
+#endif
+}
+void Crux::store_distributed_double_array(double *double_array, size_t nelem, int flags)
+{
+ assert(double_array != NULL);
+ //MPI_Datatype datatype = get_crux_datatype(DISTRIBUTED_DOUBLE_DATA);
+ MPI_Status status;
+ //MPI_File_write_shared(mpi_store_fp, double_array, nelem, datatype, &status);
+#ifdef DEBUG_RESTORE_VALS
+ int count;
+ MPI_Get_count(&status, MPI_DOUBLE_PRECISION, &count);
+ printf("%d:Wrote %d doubles at line %d in file %s\n",mype,count,__LINE__,__FILE__);
+#endif
+}
+#endif
+
+void Crux::store_end(void)
+{
+#ifdef HAVE_HDF5
+ if(USE_HDF5) {
+ if(H5Fclose(h5_fid) != 0)
+ printf("HDF5: Could not close HDF5 file \n");
+ } else {
+#endif
+#ifdef HAVE_MPI
+ MPI_File_close(&mpi_store_fp);
+#else
+ assert(store_fp != NULL);
+ fclose(store_fp);
+#endif
+#ifdef HAVE_HDF5
+ }
+#endif
+
+ double checkpoint_total_time = cpu_timer_stop(tcheckpoint_time);
+
+ if (do_crux_timing){
+ fprintf(crux_time_fp, "Total time for checkpointing was %g seconds\n", checkpoint_total_time);
+ checkpoint_timing_count++;
+ checkpoint_timing_sum += checkpoint_total_time;
+ }
+
+ checkpoint_counter++;
+}
+
+int restore_type = RESTORE_NONE;
+
+void Crux::restore_MallocPlus(MallocPlus memory){
+ char test_name[34];
+ malloc_plus_memory_entry *memory_item;
+ for (memory_item = memory.memory_entry_by_name_begin();
+ memory_item != memory.memory_entry_by_name_end();
+ memory_item = memory.memory_entry_by_name_next() ){
+ void *mem_ptr = memory_item->mem_ptr;
+ if ((memory_item->mem_flags & RESTART_DATA) == 0) continue;
+
+ if (DEBUG) {
+ printf("MallocPlus ptr %p: name %10s ptr %p dims %lu nelem (",
+ mem_ptr,memory_item->mem_name,memory_item->mem_ptr,memory_item->mem_ndims);
+
+ char nelemstring[80];
+ char *str_ptr = nelemstring;
+ str_ptr += sprintf(str_ptr,"%lu", memory_item->mem_nelem[0]);
+ for (uint i = 1; i < memory_item->mem_ndims; i++){
+ str_ptr += sprintf(str_ptr,", %lu", memory_item->mem_nelem[i]);
+ }
+ printf("%12s",nelemstring);
+
+ printf(") elsize %lu flags %d capacity %lu\n",
+ memory_item->mem_elsize,memory_item->mem_flags,memory_item->mem_capacity);
+ }
+#ifdef HAVE_HDF5
+ if(USE_HDF5) {
+ access_named_hdf5_values (memory_item->mem_name,
+ strlen (memory_item->mem_name),
+ (hsize_t) memory_item->mem_ndims,
+ (hsize_t *) memory_item->mem_nelem,
+ mem_ptr,
+ memory_item->mem_elsize == 4 ?
+ H5T_NATIVE_INT : H5T_NATIVE_DOUBLE, false);
+ } else {
+#endif
+ int num_elements = 1;
+ for (uint i = 0; i < memory_item->mem_ndims; i++){
+ num_elements *= memory_item->mem_nelem[i];
+ }
+ restore_field_header(test_name,30);
+ if (strcmp(test_name,memory_item->mem_name) != 0) {
+ printf("ERROR in restore checkpoint for %s %s\n",test_name,memory_item->mem_name);
+#ifdef HAVE_MPI
+ MPI_Finalize();
+#endif
+ exit(-1);
+ }
+ if (memory_item->mem_flags & REPLICATED_DATA) {
+ if (memory_item->mem_elsize == 4){
+ restore_replicated_int_array((int *)mem_ptr, num_elements);
+ } else {
+ restore_replicated_double_array((double *)mem_ptr, num_elements);
+ }
+ } else {
+ if (memory_item->mem_elsize == 4){
+ restore_int_array((int *)mem_ptr, num_elements);
+ } else {
+ restore_double_array((double *)mem_ptr, num_elements);
+ }
+ }
+ }
+#ifdef HAVE_HDF5
+ }
+#endif
+}
+
+void Crux::restore_begin(char *restart_file, int rollback_counter)
+{
+ rs_num = rollback_counter % num_of_rollback_states;
+
+ cpu_timer_start(&trestore_time);
+
+ if (restart_file != NULL){
+ if (mype == 0) {
+ printf("\n ================================================================\n");
+ printf( " Restoring state from disk file %s\n",restart_file);
+ printf( " ================================================================\n\n");
+ }
+#ifdef HAVE_HDF5
+ is_restart = true;
+ if (USE_HDF5) {
+ hid_t plist_id = create_hdf5_parallel_file_plist();
+
+ if(!(h5_fid = H5Fopen(restart_file, H5F_ACC_RDWR, plist_id)))
+ printf("HDF5: Could not restart from HDF5 file: %s\n", restart_file);
+ H5Pclose(plist_id);
+ } else {
+#endif
+#ifdef HAVE_MPI
+ int iret = MPI_File_open(MPI_COMM_WORLD, restart_file, MPI_MODE_RDONLY | MPI_MODE_UNIQUE_OPEN, MPI_INFO_NULL, &mpi_restore_fp);
+ if(iret != MPI_SUCCESS){
+ //printf("Could not write %s at iteration %d\n",restart_file,crux_int_vals[8]);
+ printf("Could not open restart file %s\n",restart_file);
+ }
+#else
+ restore_fp = fopen(restart_file,"r");
+ if(!restore_fp){
+ //printf("Could not write %s at iteration %d\n",restart_file,crux_int_vals[8]);
+ printf("Could not open restart file %s\n",restart_file);
+ }
+#endif
+#ifdef HAVE_HDF5
+ }
+#endif
+ restore_type = RESTORE_RESTART;
+ } else if(crux_type == CRUX_IN_MEMORY){
+ printf("Restoring state from memory rollback number %d rollback_counter %d\n",rs_num,rollback_counter);
+ restore_fp = fmemopen(crux_data[rs_num], crux_data_size[rs_num], "r");
+ restore_type = RESTORE_ROLLBACK;
+ } else if(crux_type == CRUX_DISK){
+ char backup_file_w_dir[60];
+
+ sprintf(backup_file_w_dir,"%s/backup%d.crx",checkpoint_directory,rs_num);
+ printf("Restoring state from disk file %s rollback_counter %d\n",backup_file_w_dir,rollback_counter);
+ restore_fp = fopen(backup_file_w_dir,"r");
+ if(!restore_fp){
+ //printf("Could not write %s at iteration %d\n",backup_file_w_dir,crux_int_vals[8]);
+ printf("Could not open restore file %s\n",backup_file_w_dir);
+ }
+ restore_type = RESTORE_ROLLBACK;
+ }
+}
+
+void Crux::restore_field_header(char *name, int name_size)
+{
+#ifdef HAVE_MPI
+ assert(name != NULL);
+ MPI_Status status;
+ MPI_File_read_shared(mpi_restore_fp, name, name_size, MPI_CHAR, &status);
+ MPI_Barrier(MPI_COMM_WORLD);
+#ifdef DEBUG_RESTORE_VALS
+ int count;
+ MPI_Get_count(&status, MPI_CHAR, &count);
+ printf("%d:Read %d characters at line %d in file %s\n",mype,count,__LINE__,__FILE__);
+#endif
+
+#else
+ int name_read = fread(name,sizeof(char),name_size,restore_fp);
+ if (name_read != name_size){
+ printf("Warning: number of elements read %d is not equal to request %d\n",name_read,name_size);
+ }
+#endif
+}
+
+void Crux::restore_bools(bool *bool_vals, size_t nelem)
+{
+ size_t nelem_read = fread(bool_vals,sizeof(bool),nelem,restore_fp);
+ if (nelem_read != nelem){
+ printf("Warning: number of elements read %lu is not equal to request %lu\n",nelem_read,nelem);
+ }
+}
+
+void Crux::restore_ints(int *int_vals, size_t nelem)
+{
+ size_t nelem_read = fread(int_vals,sizeof(int),nelem,restore_fp);
+ if (nelem_read != nelem){
+ printf("Warning: number of elements read %lu is not equal to request %lu\n",nelem_read,nelem);
+ }
+}
+
+void Crux::restore_longs(long long *long_vals, size_t nelem)
+{
+ size_t nelem_read = fread(long_vals,sizeof(long),nelem,restore_fp);
+ if (nelem_read != nelem){
+ printf("Warning: number of elements read %lu is not equal to request %lu\n",nelem_read,nelem);
+ }
+}
+
+void Crux::restore_sizets(size_t *size_t_vals, size_t nelem)
+{
+ size_t nelem_read = fread(size_t_vals,sizeof(size_t),nelem,restore_fp);
+ if (nelem_read != nelem){
+ printf("Warning: number of elements read %lu is not equal to request %lu\n",nelem_read,nelem);
+ }
+}
+
+void Crux::restore_doubles(double *double_vals, size_t nelem)
+{
+ size_t nelem_read = fread(double_vals,sizeof(double),nelem,restore_fp);
+ if (nelem_read != nelem){
+ printf("Warning: number of elements read %lu is not equal to request %lu\n",nelem_read,nelem);
+ }
+}
+
+int *Crux::restore_int_array(int *int_array, size_t nelem)
+{
+#ifdef HAVE_MPI
+ assert(int_array != NULL);
+ MPI_Status status;
+ MPI_File_read_shared(mpi_restore_fp, int_array, (int)nelem, MPI_INT, &status);
+ MPI_Barrier(MPI_COMM_WORLD);
+#ifdef DEBUG_RESTORE_VALS
+ int count;
+ MPI_Get_count(&status, MPI_INT, &count);
+ printf("%d:Read %d integers at line %d in file %s\n",mype,count,__LINE__,__FILE__);
+#endif
+
+#else
+ size_t nelem_read = fread(int_array,sizeof(int),nelem,restore_fp);
+ if (nelem_read != nelem){
+ printf("Warning: number of elements read %lu is not equal to request %lu\n",nelem_read,nelem);
+ }
+#endif
+ return(int_array);
+}
+
+long long *Crux::restore_long_array(long long *long_array, size_t nelem)
+{
+ size_t nelem_read = fread(long_array,sizeof(long long),nelem,restore_fp);
+ if (nelem_read != nelem){
+ printf("Warning: number of elements read %lu is not equal to request %lu\n",nelem_read,nelem);
+ }
+ return(long_array);
+}
+
+float *Crux::restore_float_array(float *float_array, size_t nelem)
+{
+ size_t nelem_read = fread(float_array,sizeof(float),nelem,restore_fp);
+ if (nelem_read != nelem){
+ printf("Warning: number of elements read %lu is not equal to request %lu\n",nelem_read,nelem);
+ }
+ return(float_array);
+}
+
+double *Crux::restore_double_array(double *double_array, size_t nelem)
+{
+#ifdef HAVE_MPI
+ MPI_Status status;
+ MPI_File_read_shared(mpi_restore_fp, double_array, (int)nelem, MPI_DOUBLE, &status);
+ MPI_Barrier(MPI_COMM_WORLD);
+#ifdef DEBUG_RESTORE_VALS
+ int count;
+ MPI_Get_count(&status, MPI_DOUBLE, &count);
+ printf("%d:Read %d doubles at line %d in file %s\n",mype,count,__LINE__,__FILE__);
+#endif
+
+#else
+ size_t nelem_read = fread(double_array,sizeof(double),nelem,restore_fp);
+ if (nelem_read != nelem){
+ printf("Warning: number of elements read %lu is not equal to request %lu\n",nelem_read,nelem);
+ }
+#endif
+ return(double_array);
+}
+
+int *Crux::restore_replicated_int_array(int *int_array, size_t nelem)
+{
+#ifdef HAVE_MPI
+ assert(int_array != NULL);
+ MPI_Status status;
+ MPI_File_read_shared(mpi_restore_fp, int_array, (int)nelem, MPI_INT, &status);
+ MPI_Barrier(MPI_COMM_WORLD);
+#ifdef DEBUG_RESTORE_VALS
+ int count;
+ MPI_Get_count(&status, MPI_INT, &count);
+ printf("%d:Read %d integers at line %d in file %s\n",mype,count,__LINE__,__FILE__);
+#endif
+
+#else
+ size_t nelem_read = fread(int_array,sizeof(int),nelem,restore_fp);
+ if (nelem_read != nelem){
+ printf("Warning: number of elements read %lu is not equal to request %lu\n",nelem_read,nelem);
+ }
+#endif
+ return(int_array);
+}
+
+double *Crux::restore_replicated_double_array(double *double_array, size_t nelem)
+{
+#ifdef HAVE_MPI
+ MPI_Status status;
+ MPI_File_read_shared(mpi_restore_fp, double_array, (int)nelem, MPI_DOUBLE, &status);
+ MPI_Barrier(MPI_COMM_WORLD);
+#ifdef DEBUG_RESTORE_VALS
+ int count;
+ MPI_Get_count(&status, MPI_DOUBLE, &count);
+ printf("%d:Read %d doubles at line %d in file %s\n",mype,count,__LINE__,__FILE__);
+#endif
+
+#else
+ size_t nelem_read = fread(double_array,sizeof(double),nelem,restore_fp);
+ if (nelem_read != nelem){
+ printf("Warning: number of elements read %lu is not equal to request %lu\n",nelem_read,nelem);
+ }
+#endif
+ return(double_array);
+}
+
+#ifdef HAVE_MPI
+int *Crux::restore_distributed_int_array(int *int_array, size_t nelem, int flags)
+{
+ assert(int_array != NULL);
+ //MPI_Datatype datatype = get_crux_datatype(DISTRIBUTED_INT_DATA);
+ MPI_Status status;
+ //MPI_File_read_shared(mpi_restore_fp, int_array, (int)nelem, datatype, &status);
+ MPI_Barrier(MPI_COMM_WORLD);
+#ifdef DEBUG_RESTORE_VALS
+ int count;
+ MPI_Get_count(&status, MPI_INT, &count);
+ printf("%d:Read %d integers at line %d in file %s\n",mype,count,__LINE__,__FILE__);
+#endif
+
+ return(int_array);
+}
+
+double *Crux::restore_distributed_double_array(double *double_array, size_t nelem, int flags)
+{
+ //MPI_Datatype datatype = get_crux_datatype(DISTRIBUTED_DOUBLE_DATA);
+ MPI_Status status;
+ //MPI_File_read_shared(mpi_restore_fp, double_array, (int)nelem, datatype, &status);
+ MPI_Barrier(MPI_COMM_WORLD);
+#ifdef DEBUG_RESTORE_VALS
+ int count;
+ MPI_Get_count(&status, MPI_DOUBLE, &count);
+ printf("%d:Read %d doubles at line %d in file %s\n",mype,count,__LINE__,__FILE__);
+#endif
+
+ return(double_array);
+}
+#endif
+
+void Crux::restore_end(void)
+{
+ double restore_total_time = cpu_timer_stop(trestore_time);
+
+ if (do_crux_timing){
+ if (restore_type == RESTORE_RESTART) {
+ fprintf(crux_time_fp, "Total time for restore was %g seconds\n", restore_total_time);
+ } else if (restore_type == RESTORE_ROLLBACK){
+ fprintf(crux_time_fp, "Total time for rollback %d was %g seconds\n", rollback_attempt, restore_total_time);
+ }
+ }
+#ifdef HAVE_HDF5
+ if(USE_HDF5) {
+ if(H5Fclose(h5_fid) != 0) {
+ printf("HDF5: Could not close HDF5 file!!\n");
+ }
+ } else {
+#endif
+#ifdef HAVE_MPI
+ MPI_File_close(&mpi_store_fp);
+#else
+ assert(restore_fp != NULL);
+ fclose(restore_fp);
+#endif
+#ifdef HAVE_HDF5
+ }
+#endif
+}
+
+int Crux::get_rollback_number()
+{
+ rollback_attempt++;
+ return(checkpoint_counter % num_of_rollback_states);
+}
+
+void Crux::set_crux_type(int crux_type_in)
+{
+ crux_type = crux_type_in;
+}
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/crux.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/crux.h?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/crux.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/crux.h Sun Sep 3 20:10:18 2017
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2014, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ *
+ * Authors: Brian Atkinson bwa at g.clemson.edu
+ Bob Robey XCP-2 brobey at lanl.gov
+ */
+
+#ifndef CRUX_H_
+#define CRUX_H_
+
+#include <stdio.h>
+#include "MallocPlus.h"
+
+enum crux_types{
+ CRUX_NONE,
+ CRUX_DISK,
+ CRUX_IN_MEMORY
+};
+
+class Crux
+{
+ int num_of_rollback_states;
+ int crux_type;
+ int checkpoint_counter;
+
+public:
+
+ Crux(int crux_type_in, int num_of_rollback_states_in, bool restart);
+ ~Crux();
+
+ void store_MallocPlus(MallocPlus memory);
+ void store_begin(size_t nsize, int ncycle);
+ void store_field_header(const char *name, int name_size);
+ void store_bools(bool *bool_vals, size_t nelem);
+ void store_ints(int *int_vals, size_t nelem);
+ void store_longs(long long *long_vals, size_t nelem);
+ void store_sizets(size_t *size_t_vals, size_t nelem);
+ void store_doubles(double *double_vals, size_t nelem);
+ void store_int_array(int *int_array, size_t nelem);
+ void store_long_array(long long *long_array, size_t nelem);
+ void store_float_array(float *float_array, size_t nelem);
+ void store_double_array(double *double_array, size_t nelem);
+ void store_replicated_int_array(int *int_array, size_t nelem);
+ void store_replicated_double_array(double *double_array, size_t nelem);
+ void store_named_ints(const char *name, int name_size, int *int_vals, size_t nelem);
+#ifdef HAVE_MPI
+ void store_distributed_int_array(int *int_array, size_t nelem, int flags);
+ void store_distributed_double_array(double *double_array, size_t nelem, int flags);
+#endif
+ void store_end(void);
+
+ void restore_MallocPlus(MallocPlus memory);
+ void restore_begin(char *restart_file, int rollback_counter);
+ void restore_field_header(char *name, int name_size);
+ void restore_bools(bool *bool_vals, size_t nelem);
+ void restore_ints(int *int_vals, size_t nelem);
+ void restore_longs(long long *long_vals, size_t nelem);
+ void restore_sizets(size_t *size_t_vals, size_t nelem);
+ void restore_doubles(double *double_vals, size_t nelem);
+ int *restore_int_array(int *int_array, size_t nsize);
+ long long *restore_long_array(long long *long_array, size_t nsize);
+ float *restore_float_array(float *float_array, size_t nsize);
+ double *restore_double_array(double *double_array, size_t nsize);
+ int *restore_replicated_int_array(int *int_array, size_t nsize);
+ double *restore_replicated_double_array(double *double_array, size_t nsize);
+ void restore_named_ints(const char *name, int name_size, int *int_vals, size_t nelem);
+#ifdef HAVE_MPI
+ int *restore_distributed_int_array(int *int_array, size_t nsize, int flags);
+ double *restore_distributed_double_array(double *double_array, size_t nsize, int flags);
+#endif
+ void restore_end(void);
+
+ int get_rollback_number();
+ void set_crux_type(int crux_type_in);
+
+};
+#endif // CRUX_H_
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/fmemopen.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/fmemopen.h?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/fmemopen.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/fmemopen.h Sun Sep 3 20:10:18 2017
@@ -0,0 +1,35 @@
+#ifndef FMEMOPEN_H_
+#define FMEMOPEN_H_
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A BSD port of the fmemopen Linux method using funopen.
+ *
+ * man docs for fmemopen:
+ * http://linux.die.net/man/3/fmemopen
+ *
+ * man docs for funopen:
+ * https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/funopen.3.html
+ *
+ * This method is ported from ingenuitas' python-tesseract project.
+ *
+ * You must call fclose on the returned file pointer or memory will be leaked.
+ *
+ * @param buf The data that will be used to back the FILE* methods. Must be at least
+ * @c size bytes.
+ * @param size The size of the @c buf data.
+ * @param mode The permitted stream operation modes.
+ * @return A pointer that can be used in the fread/fwrite/fseek/fclose family of methods.
+ * If a failure occurred NULL will be returned.
+ * @ingroup NimbusMemoryMappping
+ */
+FILE *fmemopen(void *buf, size_t size, const char *mode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef FMEMOPEN_H_
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/genmalloc.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/genmalloc.c?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/genmalloc.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/genmalloc.c Sun Sep 3 20:10:18 2017
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2011-2012, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ * This research code is being developed as part of the
+ * 2011 X Division Summer Workshop for the express purpose
+ * of a collaborative code for development of ideas in
+ * the implementation of AMR codes for Exascale platforms
+ *
+ * AMR implementation of the Wave code previously developed
+ * as a demonstration code for regular grids on Exascale platforms
+ * as part of the Supercomputing Challenge and Los Alamos
+ * National Laboratory
+ *
+ * Authors: Bob Robey XCP-2 brobey at lanl.gov
+ * Neal Davis davis68 at lanl.gov, davis68 at illinois.edu
+ * David Nicholaeff dnic at lanl.gov, mtrxknight at aol.com
+ * Dennis Trujillo dptrujillo at lanl.gov, dptru10 at gmail.com
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "genmalloc.h"
+
+#ifndef DEBUG
+#define DEBUG 0
+#endif
+
+double ***gentrimatrix_double_p(int knum, int jnum, int inum, const char *file, const int line);
+int ***gentrimatrix_int_p(int knum, int jnum, int inum, const char *file, const int line);
+
+SLIST_HEAD(slist_genmalloc_memory_head, genmalloc_memory_entry) genmalloc_memory_head = SLIST_HEAD_INITIALIZER(genmalloc_memory_head);
+struct slist_genmalloc_memory_head *genmalloc_memory_headp;
+struct genmalloc_memory_entry {
+ void *mem_ptr;
+ size_t mem_size;
+ SLIST_ENTRY(genmalloc_memory_entry) genmalloc_memory_entries;
+} *genmalloc_memory_item;
+
+void *genvector_p(int inum, size_t elsize, const char *file, const int line)
+{
+ // Just to get rid of warning
+ if (1 == 2) printf("Warning file %s line %d\n", file, line);
+
+ void *out;
+ size_t mem_size;
+
+ mem_size = inum*elsize;
+ out = (void *)calloc((size_t)inum, elsize);
+ genmalloc_memory_add(out, mem_size);
+
+ return (out);
+}
+
+void genvectorfree_p(void *var, const char *file, const int line)
+{
+ // Just to get rid of warning
+ if (1 == 2) printf("Warning file %s line %d\n", file, line);
+
+ genmalloc_memory_remove(var);
+}
+
+void **genmatrix_p(int jnum, int inum, size_t elsize, const char *file, const int line)
+{
+ // Just to get rid of warning
+ if (1 == 2) printf("Warning file %s line %d\n", file, line);
+
+ void **out;
+ size_t mem_size;
+
+ mem_size = jnum*sizeof(void *);
+ out = (void **)malloc(mem_size);
+ genmalloc_memory_add(out, mem_size);
+
+ mem_size = jnum*inum*elsize;
+ out[0] = (void *)calloc((size_t)jnum*(size_t)inum, elsize);
+ genmalloc_memory_add(out[0], mem_size);
+
+ for (int i = 1; i < jnum; i++) {
+ out[i] = out[i-1] + inum*elsize;
+ }
+
+ return (out);
+}
+
+void genmatrixfree_p(void **var, const char *file, const int line)
+{
+ // Just to get rid of warning
+ if (1 == 2) printf("Warning file %s line %d\n", file, line);
+
+ genmalloc_memory_remove(var[0]);
+ genmalloc_memory_remove(var);
+}
+
+void ***gentrimatrix_p(int knum, int jnum, int inum, size_t elsize, const char *file, const int line)
+{
+ // Just to get rid of warning
+ if (1 == 2) printf("Warning file %s line %d\n", file, line);
+
+ void ***out = NULL;
+ if (elsize == 8) {
+ out = (void ***)gentrimatrix_double_p(knum, jnum, inum, file, line);
+ } else if (elsize == 4) {
+ out = (void ***)gentrimatrix_int_p(knum, jnum, inum, file, line);
+ } else {
+ printf("Error -- element size not supported in genmalloc for call at %s line %d\n",file,line);
+ }
+
+ return(out);
+}
+
+double ***gentrimatrix_double_p(int knum, int jnum, int inum, const char *file, const int line)
+{
+ // Just to get rid of warning
+ if (1 == 2) printf("Warning file %s line %d\n", file, line);
+
+ double ***out;
+ size_t mem_size;
+ const size_t elsize = 8;
+
+ mem_size = knum*sizeof(void **);
+ out = (double ***)malloc(mem_size);
+ genmalloc_memory_add(out, mem_size);
+
+ mem_size = knum*jnum*sizeof(void *);
+ out[0] = (double **) malloc(mem_size);
+ genmalloc_memory_add(out[0], mem_size);
+
+ size_t nelems = knum*jnum*inum;
+ mem_size = nelems*elsize;
+ out[0][0] = (void *)calloc(nelems, elsize);
+ genmalloc_memory_add(out[0][0], mem_size);
+
+ for (int k = 0; k < knum; k++)
+ {
+ if (k > 0)
+ {
+ out[k] = out[k-1] + jnum;
+ out[k][0] = out[k-1][0] + (jnum*inum);
+ }
+
+ for (int j = 1; j < jnum; j++)
+ {
+ out[k][j] = out[k][j-1] + inum;
+ }
+ }
+
+ return (out);
+}
+
+int ***gentrimatrix_int_p(int knum, int jnum, int inum, const char *file, const int line)
+{
+ // Just to get rid of warning
+ if (1 == 2) printf("Warning file %s line %d\n", file, line);
+
+ int ***out;
+ size_t mem_size;
+ const size_t elsize = 4;
+
+ mem_size = knum*sizeof(void **);
+ out = (int ***)malloc(mem_size);
+ genmalloc_memory_add(out, mem_size);
+
+ mem_size = knum*jnum*sizeof(void *);
+ out[0] = (int **) malloc(mem_size);
+ genmalloc_memory_add(out[0], mem_size);
+
+ size_t nelems = knum*jnum*inum;
+ mem_size = nelems*elsize;
+ out[0][0] = (void *)calloc(nelems, elsize);
+ genmalloc_memory_add(out[0][0], mem_size);
+
+ for (int k = 0; k < knum; k++)
+ {
+ if (k > 0)
+ {
+ out[k] = out[k-1] + jnum;
+ out[k][0] = out[k-1][0] + (jnum*inum);
+ }
+
+ for (int j = 1; j < jnum; j++)
+ {
+ out[k][j] = out[k][j-1] + inum;
+ }
+ }
+
+ return (out);
+}
+
+void gentrimatrixfree_p(void ***var, const char *file, const int line)
+{
+ // Just to get rid of warning
+ if (1 == 2) printf("Warning file %s line %d\n", file, line);
+
+ genmalloc_memory_remove(var[0][0]);
+ genmalloc_memory_remove(var[0]);
+ genmalloc_memory_remove(var);
+}
+
+void *genmalloc_memory_add_p(void *malloc_mem_ptr, size_t size, const char *file, const int line){
+ // Just to get rid of warning
+ if (1 == 2) printf("Warning file %s line %d\n", file, line);
+
+ if (SLIST_EMPTY(&genmalloc_memory_head)) SLIST_INIT(&genmalloc_memory_head);
+
+ genmalloc_memory_item = malloc(sizeof(struct genmalloc_memory_entry));
+ genmalloc_memory_item->mem_ptr = malloc_mem_ptr;
+ genmalloc_memory_item->mem_size = size;
+ if (DEBUG) printf("GENMALLOC_MEMORY_ADD: DEBUG -- malloc memory pointer is %p called from file %s line %d\n",malloc_mem_ptr,file,line);
+
+ SLIST_INSERT_HEAD(&genmalloc_memory_head, genmalloc_memory_item, genmalloc_memory_entries);
+
+ return(malloc_mem_ptr);
+}
+
+void genmalloc_memory_remove_p(void *malloc_mem_ptr, const char *file, const int line){
+ // Just to get rid of warning
+ if (1 == 2) printf("Warning file %s line %d\n", file, line);
+
+ SLIST_FOREACH(genmalloc_memory_item, &genmalloc_memory_head, genmalloc_memory_entries){
+ if (genmalloc_memory_item->mem_ptr == malloc_mem_ptr) {
+ if (DEBUG) printf("GENMALLOC_MEMORY_REMOVE: DEBUG -- freeing malloc memory pointer %p called from file %s line %d\n",malloc_mem_ptr,file,line);
+ free(malloc_mem_ptr);
+ SLIST_REMOVE(&genmalloc_memory_head, genmalloc_memory_item, genmalloc_memory_entry, genmalloc_memory_entries);
+ free(genmalloc_memory_item);
+ break;
+ }
+ }
+}
+
+void genmem_free_all_p(const char *file, const int line){
+ // Just to get rid of warning
+ if (1 == 2) printf("Warning file %s line %d\n", file, line);
+
+ while (!SLIST_EMPTY(&genmalloc_memory_head)) {
+ genmalloc_memory_item = SLIST_FIRST(&genmalloc_memory_head);
+ if (DEBUG) printf("GENMEM_FREE_ALL: DEBUG -- freeing genmalloc memory %p called from file %s line %d\n",genmalloc_memory_item->mem_ptr,file,line);
+ free(genmalloc_memory_item->mem_ptr);
+ SLIST_REMOVE_HEAD(&genmalloc_memory_head, genmalloc_memory_entries);
+ free(genmalloc_memory_item);
+ }
+}
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/genmalloc.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/genmalloc.h?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/genmalloc.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/genmalloc.h Sun Sep 3 20:10:18 2017
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2011-2012, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ * This research code is being developed as part of the
+ * 2011 X Division Summer Workshop for the express purpose
+ * of a collaborative code for development of ideas in
+ * the implementation of AMR codes for Exascale platforms
+ *
+ * AMR implementation of the Wave code previously developed
+ * as a demonstration code for regular grids on Exascale platforms
+ * as part of the Supercomputing Challenge and Los Alamos
+ * National Laboratory
+ *
+ * Authors: Bob Robey XCP-2 brobey at lanl.gov
+ * Neal Davis davis68 at lanl.gov, davis68 at illinois.edu
+ * David Nicholaeff dnic at lanl.gov, mtrxknight at aol.com
+ * Dennis Trujillo dptrujillo at lanl.gov, dptru10 at gmail.com
+ *
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* memory routines */
+#define genvector( inum, elsize) \
+ ( genvector_p(inum, elsize, __FILE__, __LINE__) )
+#define genvectorfree( var) \
+ ( genvectorfree_p(var, __FILE__, __LINE__) )
+#define genmatrix( jnum, inum, elsize) \
+ ( genmatrix_p(jnum, inum, elsize, __FILE__, __LINE__) )
+#define gentrimatrix( knum, jnum, inum, elsize) \
+ ( gentrimatrix_p(knum, jnum, inum, elsize, __FILE__, __LINE__) )
+#define genmatrixfree( var) \
+ ( genmatrixfree_p(var, __FILE__, __LINE__) )
+#define gentrimatrixfree( var) \
+ ( gentrimatrixfree_p(var, __FILE__, __LINE__) )
+
+#define genmalloc_memory_add( malloc_mem_ptr, size) \
+ ( genmalloc_memory_add_p(malloc_mem_ptr, size, __FILE__, __LINE__) )
+#define genmalloc_memory_remove( malloc_mem_ptr) \
+ ( genmalloc_memory_remove_p(malloc_mem_ptr, __FILE__, __LINE__) )
+#define genmem_free_all() \
+ ( genmem_free_all_p(__FILE__, __LINE__) )
+
+
+void *genvector_p(int inum, size_t elsize, const char *file, const int line);
+void genvectorfree_p(void *var, const char *file, const int line);
+void **genmatrix_p(int jnum, int inum, size_t elsize, const char *file, const int line);
+void ***gentrimatrix_p(int knum, int jnum, int inum, size_t elsize, const char *file, const int line);
+void genmatrixfree_p(void **var, const char *file, const int line);
+void gentrimatrixfree_p(void ***var, const char *file, const int line);
+
+void *genmalloc_memory_add_p(void *malloc_mem_ptr, size_t size, const char *file, const int line);
+void genmalloc_memory_remove_p(void *malloc_mem_ptr, const char *file, const int line);
+void genmem_free_all_p(const char *file, const int line);
+
+#ifdef __cplusplus
+}
+#endif
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/glibc_compat_rand.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/glibc_compat_rand.c?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/glibc_compat_rand.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/glibc_compat_rand.c Sun Sep 3 20:10:18 2017
@@ -0,0 +1,60 @@
+/*===------------ glibc_compat_rand.c - glibc rand emulation --------------===*\
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+\*===----------------------------------------------------------------------===*/
+
+#include "glibc_compat_rand.h"
+
+/**
+ * This rand implementation is designed to emulate the implementation of
+ * rand/srand in recent versions of glibc. This is used for programs which
+ * require this specific rand implementation in order to pass verification
+ * tests.
+ *
+ * For more information, see: http://www.mathstat.dal.ca/~selinger/random/
+ **/
+
+#define TABLE_SIZE 344
+static unsigned int table[TABLE_SIZE];
+static int next;
+
+int glibc_compat_rand(void) {
+ /* Calculate the indices i-3 and i-31 in the circular vector. */
+ int i3 = (next < 3) ? (TABLE_SIZE + next - 3) : (next - 3);
+ int i31 = (next < 31) ? (TABLE_SIZE + next - 31) : (next - 31);
+
+ table[next] = table[i3] + table[i31];
+ unsigned int r = table[next] >> 1;
+
+ ++next;
+ if (next >= TABLE_SIZE)
+ next = 0;
+
+ return r;
+}
+
+void glibc_compat_srand(unsigned int seed) {
+ if (seed == 0)
+ seed = 1;
+
+ table[0] = seed;
+
+ for (int i = 1; i < 31; i++) {
+ int r = (16807ll * table[i - 1]) % 2147483647;
+ if (r < 0)
+ r += 2147483647;
+
+ table[i] = r;
+ }
+
+ for (int i = 31; i < 34; i++)
+ table[i] = table[i - 31];
+ for (int i = 34; i < TABLE_SIZE; i++)
+ table[i] = table[i - 31] + table[i - 3];
+
+ next = 0;
+}
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/glibc_compat_rand.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/glibc_compat_rand.h?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/glibc_compat_rand.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/glibc_compat_rand.h Sun Sep 3 20:10:18 2017
@@ -0,0 +1,16 @@
+/*===------------- glibc_compat_rand.h- glibc rand emulation --------------===*\
+|*
+|* The LLVM Compiler Infrastructure
+|*
+|* This file is distributed under the University of Illinois Open Source
+|* License. See LICENSE.TXT for details.
+|*
+\*===----------------------------------------------------------------------===*/
+
+#ifndef GLIBC_COMPAT_RAND_H
+#define GLIBC_COMPAT_RAND_H
+
+int glibc_compat_rand(void);
+void glibc_compat_srand(unsigned int seed);
+
+#endif /* GLIBC_COMPAT_RAND_H */
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/graphics.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/graphics.c?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/graphics.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/graphics.c Sun Sep 3 20:10:18 2017
@@ -0,0 +1,706 @@
+/*
+ * Copyright (c) 2011, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ * This research code is being developed as part of the
+ * 2011 X Division Summer Workshop for the express purpose
+ * of a collaborative code for development of ideas in
+ * the implementation of AMR codes for Exascale platforms
+ *
+ * AMR implementation of the Wave code previously developed
+ * as a demonstration code for regular grids on Exascale platforms
+ * as part of the Supercomputing Challenge and Los Alamos
+ * National Laboratory
+ *
+ * Authors: Bob Robey XCP-2 brobey at lanl.gov
+ * Neal Davis davis68 at lanl.gov, davis68 at illinois.edu
+ * David Nicholaeff dnic at lanl.gov, mtrxknight at aol.com
+ * Dennis Trujillo dptrujillo at lanl.gov, dptru10 at gmail.com
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include "graphics.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+static int magick_on = 0;
+
+#ifdef HAVE_MAGICKWAND
+#include <wand/MagickWand.h>
+
+#define MAGICK_NCOLORS 1280
+
+void Magick_Scale();
+
+//static int graphics_movie = 0;
+static MagickWand *magick_wand = NULL;
+static DrawingWand *draw_wand = NULL;
+static PixelWand *pixel_wand = NULL;
+
+struct MagickColorTable {
+ int Red;
+ int Blue;
+ int Green;
+};
+
+static struct MagickColorTable MagickRainbow[MAGICK_NCOLORS];
+#endif
+
+
+#define WINSIZE 800
+
+void DrawSquaresToFile(int graph_num, int ncycle, double simTime, int rollback_img, int rollback_num);
+
+/*
+ * Variables that I added to make everything work for getting graphics
+ * data output to files while running no graphics with CLAMR
+ * Brian Atkinson
+*/
+static int autoscale = 0;
+static double xconversion = 0.0;
+static double yconversion = 0.0;
+static int Ncolors = 256;
+static int iteration = 0;
+
+char *graphics_directory = "graphics_output";
+enum graphics_file_type graphics_type; // type of graphics output
+
+//static int mode = MOVE;
+
+static int width;
+static float graphics_xmin=0.0, graphics_xmax=0.0, graphics_ymin=0.0, graphics_ymax=0.0;
+
+static int graphics_outline = 0;
+static int graphics_view_mode = 0;
+static int graphics_mysize = 0;
+
+enum spatial_data_type {SPATIAL_DOUBLE, SPATIAL_FLOAT};
+static int spatial_type = SPATIAL_FLOAT;
+
+static double *x_double=NULL, *y_double=NULL, *dx_double=NULL, *dy_double=NULL;
+static float *x_float=NULL, *y_float=NULL, *dx_float=NULL, *dy_float=NULL;
+
+enum plot_data_type {DATA_DOUBLE, DATA_FLOAT};
+static int data_type = DATA_FLOAT;
+static double *data_double=NULL;
+static float *data_float=NULL;
+static int *graphics_proc=NULL;
+
+void init_graphics_output(void){
+ width = (WINSIZE / (graphics_ymax - graphics_ymin)) * (graphics_xmax - graphics_xmin);
+ xconversion = (double)WINSIZE/ (graphics_xmax - graphics_xmin);
+ yconversion = (double)WINSIZE/(graphics_ymax - graphics_ymin);
+
+ struct stat stat_descriptor;
+ if (stat(graphics_directory,&stat_descriptor) == -1){
+ mkdir(graphics_directory,0777);
+ }
+
+ if (graphics_type != GRAPHICS_DATA && graphics_type != GRAPHICS_NONE) magick_on = 1;
+
+#ifdef HAVE_MAGICKWAND
+ if (magick_on){
+ //MagickWandGenesis();
+ // Create wand
+ magick_wand = NewMagickWand();
+
+ Magick_Scale();
+ }
+#endif
+}
+
+void terminate_graphics_output(void){
+#ifdef HAVE_MAGICKWAND
+ if (magick_on){
+ magick_wand = DestroyMagickWand(magick_wand);
+ MagickWandTerminus();
+ }
+#endif
+}
+
+void set_graphics_window(float graphics_xmin_in, float graphics_xmax_in, float graphics_ymin_in, float graphics_ymax_in){
+ graphics_xmin = graphics_xmin_in;
+ graphics_xmax = graphics_xmax_in;
+ graphics_ymin = graphics_ymin_in;
+ graphics_ymax = graphics_ymax_in;
+}
+void set_graphics_cell_data_double(double *data_in){
+ data_type = DATA_DOUBLE;
+ data_double = data_in;
+}
+void set_graphics_cell_data_float(float *data_in){
+ data_type = DATA_FLOAT;
+ data_float = data_in;
+}
+void set_graphics_cell_proc(int *graphics_proc_in){
+ graphics_proc = graphics_proc_in;
+}
+void set_graphics_cell_coordinates_double(double *x_in, double *dx_in, double *y_in, double *dy_in){
+ spatial_type = SPATIAL_DOUBLE;
+ x_double = x_in;
+ dx_double = dx_in;
+ y_double = y_in;
+ dy_double = dy_in;
+}
+void set_graphics_cell_coordinates_float(float *x_in, float *dx_in, float *y_in, float *dy_in){
+ spatial_type = SPATIAL_FLOAT;
+ x_float = x_in;
+ dx_float = dx_in;
+ y_float = y_in;
+ dy_float = dy_in;
+}
+void set_graphics_viewmode(int graphics_view_mode_in){
+ graphics_view_mode = graphics_view_mode_in;
+}
+void set_graphics_mysize(int graphics_mysize_in){
+ graphics_mysize = graphics_mysize_in;
+}
+void set_graphics_outline(int graphics_outline_in){
+ graphics_outline = graphics_outline_in;
+}
+
+/*
+ * Created this function get graphics data while running
+ * the no graphic version of CLAMR. The output for the main
+ * cell data is written out to graph#.data files and the gridline
+ * data is writeen out to outline#.lin files.
+ * Brian Atkinson
+*/
+void DrawSquaresToFile(int graph_num, int ncycle, double simTime, int rollback_img, int rollback_num){
+#ifdef HAVE_MAGICKWAND
+ if (magick_on) {
+ draw_wand = NewDrawingWand();
+ pixel_wand = NewPixelWand();
+
+ MagickSetSize(magick_wand,WINSIZE,WINSIZE);
+ MagickSetColorspace(magick_wand,sRGBColorspace);
+ MagickReadImage(magick_wand,"xc:white");
+
+ DrawSetViewbox(draw_wand, 0, 0, WINSIZE, WINSIZE);
+ DrawScale(draw_wand, xconversion, -yconversion);
+ DrawTranslate(draw_wand, -graphics_xmin, graphics_ymin);
+
+ int npart = graphics_mysize/16;
+ for (int i=0; i<graphics_mysize; i++){
+ graphics_proc[i] = i/npart;
+ }
+
+ int magick_step = MAGICK_NCOLORS/(graphics_proc[graphics_mysize-1]+1);
+
+ if (graphics_outline) {
+ PixelGetBlack(pixel_wand);
+
+ DrawSetStrokeColor(draw_wand,pixel_wand);
+ DrawSetStrokeWidth(draw_wand,0.01);
+ DrawSetStrokeAntialias(draw_wand,1);
+ DrawSetStrokeOpacity(draw_wand,1);
+ }
+
+ if (data_type == DATA_DOUBLE){
+
+ for(int i = 0; i < graphics_mysize; i++) {
+ int magick_color = graphics_proc[i]*magick_step;
+ char cstring[40];
+ sprintf(cstring,"rgba(%d,%d,%d,%d)",MagickRainbow[magick_color].Red,
+ MagickRainbow[magick_color].Green,
+ MagickRainbow[magick_color].Blue,120);
+ PixelSetColor(pixel_wand, cstring);
+
+
+ DrawSetFillColor(draw_wand, pixel_wand);
+
+ DrawRectangle(draw_wand, x_double[i], y_double[i],
+ x_double[i]+dx_double[i], y_double[i]+dy_double[i]);
+/*
+ printf("DEBUG -- i %d magick_color %d magick_step %d graphics_proc %d cstring %s corners %lg %lg %lg %lg\n",
+ i,magick_color,magick_step,graphics_proc[i],cstring,
+ x_double[i], y_double[i],
+ x_double[i]+dx_double[i], y_double[i]+dy_double[i]);
+*/
+ }
+
+ if (graphics_outline) {
+ PixelSetColor(pixel_wand,"black");
+ DrawSetStrokeColor(draw_wand,pixel_wand);
+ DrawSetStrokeWidth(draw_wand,0.01);
+
+ double xold = x_double[0]+0.5*dx_double[0];
+ double yold = y_double[0]+0.5*dy_double[0];
+
+ for(int i = 0; i < graphics_mysize; i++) {
+ char cstring[40];
+ sprintf(cstring,"%d",i);
+
+ double xnew = x_double[i]+0.5*dx_double[i];
+ double ynew = y_double[i]+0.5*dy_double[i];
+
+ DrawLine(draw_wand, xold, yold, xnew, ynew);
+
+ xold = xnew;
+ yold = ynew;
+ }
+ }
+
+/*
+ // Set up a 12 point black font
+ PixelSetColor(pixel_wand,"black");
+ DrawSetFillColor(draw_wand,pixel_wand);
+ DrawSetFont (draw_wand, "Courier" ) ;
+ DrawSetFontSize(draw_wand,0.01);
+ DrawSetStrokeColor(draw_wand,pixel_wand);
+ DrawSetStrokeWidth(draw_wand,0.01);
+ DrawSetTextDirection(draw_wand, RightToLeftDirection);
+ DrawSetTextAlignment(draw_wand, CenterAlign);
+ DrawSetTextAntialias(draw_wand,MagickTrue);
+
+ for(int i = 1; i < graphics_mysize; i++) {
+ char cstring[40];
+ sprintf(cstring,"%d",i);
+
+
+ DrawAnnotation(draw_wand, x_double[i]+0.5*dx_double[i], y_double[i]+0.5*dy_double[i], cstring);
+ }
+*/
+
+ } else {
+
+ for(int i = 0; i < graphics_mysize; i++) {
+ int magick_color = graphics_proc[i]*magick_step;
+ char cstring[40];
+ sprintf(cstring,"rgba(%d,%d,%d,%d)",MagickRainbow[magick_color].Red,
+ MagickRainbow[magick_color].Green,
+ MagickRainbow[magick_color].Blue,120);
+ PixelSetColor(pixel_wand, cstring);
+
+ DrawSetFillColor(draw_wand, pixel_wand);
+
+ DrawRectangle(draw_wand, x_float[i], y_float[i],
+ x_float[i]+dx_float[i], y_float[i]+dy_float[i]);
+ }
+
+ if (graphics_outline) {
+ PixelSetColor(pixel_wand,"black");
+ DrawSetStrokeColor(draw_wand,pixel_wand);
+ DrawSetStrokeWidth(draw_wand,0.01);
+
+ float xold = x_float[0]+0.5*dx_float[0];
+ float yold = y_float[0]+0.5*dy_float[0];
+
+ for(int i = 0; i < graphics_mysize; i++) {
+ char cstring[40];
+ sprintf(cstring,"%d",i);
+
+ float xnew = x_float[i]+0.5*dx_float[i];
+ float ynew = y_float[i]+0.5*dy_float[i];
+
+ DrawLine(draw_wand, xold, yold, xnew, ynew);
+
+ xold = xnew;
+ yold = ynew;
+ }
+ }
+
+ }
+
+ MagickDrawImage(magick_wand, draw_wand);
+
+ char filename[50];
+ char graphics_file_extension[10];
+ if (graphics_type == GRAPHICS_BMP) strcpy(graphics_file_extension,".bmp");
+ if (graphics_type == GRAPHICS_GIF) strcpy(graphics_file_extension,".gif");
+ if (graphics_type == GRAPHICS_JPEG) strcpy(graphics_file_extension,".jpeg");
+ if (graphics_type == GRAPHICS_MPEG) strcpy(graphics_file_extension,".mpeg");
+ if (graphics_type == GRAPHICS_PDF) strcpy(graphics_file_extension,".pdf");
+ if (graphics_type == GRAPHICS_PNG) strcpy(graphics_file_extension,".png");
+ if (graphics_type == GRAPHICS_SVG) strcpy(graphics_file_extension,".svg");
+ sprintf(filename,"%s/graph%05d%s", graphics_directory, graph_num, graphics_file_extension);
+ MagickWriteImage(magick_wand, filename);
+ //MagickDisplayImage(magick_wand, "x:");
+
+ draw_wand = DestroyDrawingWand(draw_wand);
+ pixel_wand = DestroyPixelWand(pixel_wand);
+ }
+#endif
+
+ if (graphics_type == GRAPHICS_DATA){
+ int i, color;
+ int step = Ncolors/(graphics_proc[graphics_mysize-1]+1);
+ int xloc, xwid, yloc, ywid;
+ int xloc1, xloc2, yloc1, yloc2;
+ char filename[50], filename2[50];
+
+ if(rollback_img){
+ sprintf(filename,"%s/graph%dcp%05d.data", graphics_directory, graph_num, rollback_num);
+ sprintf(filename2,"%s/outline%dcp%05d.lin",graphics_directory, graph_num, rollback_num);
+ }
+ else{
+ sprintf(filename,"%s/graph%05d.data", graphics_directory, graph_num);
+ sprintf(filename2,"%s/outline%05d.lin",graphics_directory, graph_num);
+ }
+ FILE *fp = fopen(filename,"w");
+ FILE *fp2 = fopen(filename2,"w");
+ if(fp && fp2){
+ fprintf(fp,"%d,%lf\n",ncycle,simTime);
+ if (data_type == DATA_DOUBLE){
+ for(i = 0; i < graphics_mysize; i++) {
+ xloc = (int)((x_double[i]-graphics_xmin)*xconversion);
+ xwid = (int)((x_double[i]+dx_double[i]-graphics_xmin)*xconversion-xloc);
+ yloc = (int)((graphics_ymax-(y_double[i]+dy_double[i]))*yconversion);
+ ywid = (int)((graphics_ymax-y_double[i])*yconversion);
+ ywid -= yloc;
+ color = graphics_proc[i]*step;
+ //fprintf(fp,"%d,%d,%d,%d,%f\n",xloc,yloc,xwid,ywid,data[i]);
+ fprintf(fp,"%d,%d,%d,%d,%d\n",xloc,yloc,xwid,ywid,color);
+
+ xloc1 = (int)((x_double[i]-graphics_xmin)*xconversion);
+ xloc2 = (int)((x_double[i]+dx_double[i]-graphics_xmin)*xconversion);
+ yloc1 = (int)((graphics_ymax-y_double[i])*yconversion);
+ yloc2 = (int)((graphics_ymax-(y_double[i]+dy_double[i]))*yconversion);
+ fprintf(fp2,"%d,%d,%d,%d\n",xloc1,yloc2,xloc2,yloc2);
+ fprintf(fp2,"%d,%d,%d,%d\n",xloc1,yloc1,xloc2,yloc1);
+ fprintf(fp2,"%d,%d,%d,%d\n",xloc1,yloc1,xloc1,yloc2);
+ fprintf(fp2,"%d,%d,%d,%d\n",xloc2,yloc1,xloc2,yloc2);
+ }
+ } else {
+ for(i = 0; i < graphics_mysize; i++) {
+ xloc = (int)((x_float[i]-graphics_xmin)*xconversion);
+ xwid = (int)((x_float[i]+dx_float[i]-graphics_xmin)*xconversion-xloc);
+ yloc = (int)((graphics_ymax-(y_float[i]+dy_float[i]))*yconversion);
+ ywid = (int)((graphics_ymax-y_float[i])*yconversion);
+ ywid -= yloc;
+ color = graphics_proc[i]*step;
+ //fprintf(fp,"%d,%d,%d,%d,%f\n",xloc,yloc,xwid,ywid,data[i]);
+ fprintf(fp,"%d,%d,%d,%d,%d\n",xloc,yloc,xwid,ywid,color);
+
+ xloc1 = (int)((x_float[i]-graphics_xmin)*xconversion);
+ xloc2 = (int)((x_float[i]+dx_float[i]-graphics_xmin)*xconversion);
+ yloc1 = (int)((graphics_ymax-y_float[i])*yconversion);
+ yloc2 = (int)((graphics_ymax-(y_float[i]+dy_float[i]))*yconversion);
+ fprintf(fp2,"%d,%d,%d,%d\n",xloc1,yloc2,xloc2,yloc2);
+ fprintf(fp2,"%d,%d,%d,%d\n",xloc1,yloc1,xloc2,yloc1);
+ fprintf(fp2,"%d,%d,%d,%d\n",xloc1,yloc1,xloc1,yloc2);
+ fprintf(fp2,"%d,%d,%d,%d\n",xloc2,yloc1,xloc2,yloc2);
+ }
+ }
+ fclose(fp);
+ fclose(fp2);
+ iteration++;
+ }
+ else{
+ if(fp == NULL){
+ printf("Could not create %s in DrawSqaures\n", filename);
+ }
+ else{
+ printf("Could not create %s in DrawSqaures\n", filename2);
+ }
+ }
+ }
+}
+
+/*
+ * Created this function get graphics data while running
+ * the no graphic version of CLAMR. The output for the main
+ * cell data is written out to graph#.data files and the gridline
+ * data is writeen out to outline#.lin files.
+ * Brian Atkinson
+*/
+void DisplayStateToFile(int graph_num, int ncycle, double simTime, int rollback_img, int rollback_num){
+#ifdef HAVE_MAGICKWAND
+ if (magick_on) {
+ double scaleMax = 25.0, scaleMin = 0.0;
+
+ draw_wand = NewDrawingWand();
+ pixel_wand = NewPixelWand();
+
+ MagickSetSize(magick_wand,WINSIZE,WINSIZE);
+ MagickSetColorspace(magick_wand,sRGBColorspace);
+ MagickReadImage(magick_wand,"xc:white");
+
+ DrawSetViewbox(draw_wand, 0, 0, WINSIZE, WINSIZE);
+ DrawScale(draw_wand, xconversion, -yconversion);
+ DrawTranslate(draw_wand, -graphics_xmin, graphics_ymin);
+
+ if (autoscale) {
+ scaleMax=-1.0e30;
+ scaleMin=1.0e30;
+ if (data_type == DATA_DOUBLE){
+ for(int i = 0; i<graphics_mysize; i++) {
+ if (data_double[i] > scaleMax) scaleMax = data_double[i];
+ if (data_double[i] < scaleMin) scaleMin = data_double[i];
+ }
+ } else {
+ for(int i = 0; i<graphics_mysize; i++) {
+ if (data_float[i] > scaleMax) scaleMax = data_float[i];
+ if (data_float[i] < scaleMin) scaleMin = data_float[i];
+ }
+ }
+ }
+
+ int magick_step = MAGICK_NCOLORS/(scaleMax - scaleMin);
+
+ if (graphics_outline) {
+ PixelGetBlack(pixel_wand);
+
+ DrawSetStrokeColor(draw_wand,pixel_wand);
+ DrawSetStrokeWidth(draw_wand,0.01);
+ DrawSetStrokeAntialias(draw_wand,1);
+ DrawSetStrokeOpacity(draw_wand,1);
+ }
+
+ if (data_type == DATA_DOUBLE){
+
+ for(int i = 0; i < graphics_mysize; i++) {
+ int magick_color;
+ if (data_type == DATA_DOUBLE){
+ magick_color = (int)(data_double[i]-scaleMin)*magick_step;
+ } else {
+ magick_color = (int)(data_float[i]-scaleMin)*magick_step;
+ }
+ magick_color = MAGICK_NCOLORS-magick_color;
+ if (magick_color < 0) {
+ magick_color=0;
+ }
+ if (magick_color >= MAGICK_NCOLORS) magick_color = MAGICK_NCOLORS-1;
+
+ char cstring[40];
+ sprintf(cstring,"rgba(%d,%d,%d,%d)",MagickRainbow[magick_color].Red,
+ MagickRainbow[magick_color].Green,
+ MagickRainbow[magick_color].Blue,120);
+ PixelSetColor(pixel_wand, cstring);
+
+ DrawSetFillColor(draw_wand, pixel_wand);
+
+ DrawRectangle(draw_wand, x_double[i], y_double[i],
+ x_double[i]+dx_double[i], y_double[i]+dy_double[i]);
+/*
+ printf("DEBUG -- i %d magick_color %d magick_step %d graphics_proc %d cstring %s corners %lg %lg %lg %lg\n",
+ i,magick_color,magick_step,graphics_proc[i],cstring,
+ x_double[i], y_double[i],
+ x_double[i]+dx_double[i], y_double[i]+dy_double[i]);
+*/
+ }
+ } else {
+
+ for(int i = 0; i < graphics_mysize; i++) {
+ int magick_color;
+ if (data_type == DATA_DOUBLE){
+ magick_color = (int)(data_double[i]-scaleMin)*magick_step;
+ } else {
+ magick_color = (int)(data_float[i]-scaleMin)*magick_step;
+ }
+ magick_color = MAGICK_NCOLORS-magick_color;
+ if (magick_color < 0) {
+ magick_color=0;
+ }
+ if (magick_color >= MAGICK_NCOLORS) magick_color = MAGICK_NCOLORS-1;
+
+ char cstring[40];
+ sprintf(cstring,"rgba(%d,%d,%d,%d)",MagickRainbow[magick_color].Red,
+ MagickRainbow[magick_color].Green,
+ MagickRainbow[magick_color].Blue,120);
+ PixelSetColor(pixel_wand, cstring);
+
+ DrawSetFillColor(draw_wand, pixel_wand);
+
+ DrawRectangle(draw_wand, x_float[i], y_float[i],
+ x_float[i]+dx_float[i], y_float[i]+dy_float[i]);
+ }
+ }
+
+ MagickDrawImage(magick_wand, draw_wand);
+
+ char filename[50];
+ char graphics_file_extension[10];
+ if (graphics_type == GRAPHICS_BMP) strcpy(graphics_file_extension,".bmp");
+ if (graphics_type == GRAPHICS_GIF) strcpy(graphics_file_extension,".gif");
+ if (graphics_type == GRAPHICS_JPEG) strcpy(graphics_file_extension,".jpeg");
+ if (graphics_type == GRAPHICS_MPEG) strcpy(graphics_file_extension,".mpeg");
+ if (graphics_type == GRAPHICS_PDF) strcpy(graphics_file_extension,".pdf");
+ if (graphics_type == GRAPHICS_PNG) strcpy(graphics_file_extension,".png");
+ if (graphics_type == GRAPHICS_SVG) strcpy(graphics_file_extension,".svg");
+ sprintf(filename,"%s/graph%05d%s", graphics_directory, graph_num, graphics_file_extension);
+ MagickWriteImage(magick_wand, filename);
+ //MagickDisplayImage(magick_wand, "x:");
+
+ draw_wand = DestroyDrawingWand(draw_wand);
+ pixel_wand = DestroyPixelWand(pixel_wand);
+ }
+#endif
+ if (graphics_type == GRAPHICS_DATA){
+ double scaleMax = 25.0, scaleMin = 0.0;
+ int i;
+ int color;
+ char filename[50], filename2[50];
+
+ if(rollback_img){
+ sprintf(filename,"%s/graph%dcp%05d.data", graphics_directory, graph_num, rollback_num);
+ sprintf(filename2,"%s/outline%dcp%05d.lin",graphics_directory, graph_num, rollback_num);
+ }
+ else{
+ sprintf(filename,"%s/graph%05d.data", graphics_directory, graph_num);
+ sprintf(filename2,"%s/outline%05d.lin",graphics_directory, graph_num);
+ }
+ FILE *fp = fopen(filename,"w");
+ FILE *fp2 = fopen(filename2,"w");
+ if(fp && fp2){
+ fprintf(fp,"%d,%lf\n",ncycle,simTime);
+ if (autoscale) {
+ scaleMax=-1.0e30;
+ scaleMin=1.0e30;
+ if (data_type == DATA_DOUBLE){
+ for(i = 0; i<graphics_mysize; i++) {
+ if (data_double[i] > scaleMax) scaleMax = data_double[i];
+ if (data_double[i] < scaleMin) scaleMin = data_double[i];
+ }
+ } else {
+ for(i = 0; i<graphics_mysize; i++) {
+ if (data_float[i] > scaleMax) scaleMax = data_float[i];
+ if (data_float[i] < scaleMin) scaleMin = data_float[i];
+ }
+ }
+ }
+
+ double step = Ncolors/(scaleMax - scaleMin);
+ int xloc, xwid, yloc, ywid;
+ int xloc1, xloc2, yloc1, yloc2;
+ for(i = 0; i < graphics_mysize; i++) {
+ if (data_type == DATA_DOUBLE){
+ color = (int)(data_double[i]-scaleMin)*step;
+ } else {
+ color = (int)(data_float[i]-scaleMin)*step;
+ }
+ color = Ncolors-color;
+ if (color < 0) {
+ color=0;
+ }
+ if (color >= Ncolors) color = Ncolors-1;
+
+ if (data_type == DATA_DOUBLE){
+ xloc = (int)((x_double[i]-graphics_xmin)*xconversion);
+ xwid = (int)((x_double[i]+dx_double[i]-graphics_xmin)*xconversion-xloc);
+ yloc = (int)((graphics_ymax-(y_double[i]+dy_double[i]))*yconversion);
+ ywid = (int)((graphics_ymax-y_double[i])*yconversion);
+ ywid -= yloc;
+ //fprintf(fp,"%d,%d,%d,%d,%f\n",xloc,yloc,xwid,ywid,data[i]);
+ fprintf(fp,"%d,%d,%d,%d,%d\n",xloc,yloc,xwid,ywid,color);
+
+ xloc1 = (int)((x_double[i]-graphics_xmin)*xconversion);
+ xloc2 = (int)((x_double[i]+dx_double[i]-graphics_xmin)*xconversion);
+ yloc1 = (int)((graphics_ymax-y_double[i])*yconversion);
+ yloc2 = (int)((graphics_ymax-(y_double[i]+dy_double[i]))*yconversion);
+ fprintf(fp2,"%d,%d,%d,%d\n",xloc1,yloc2,xloc2,yloc2);
+ fprintf(fp2,"%d,%d,%d,%d\n",xloc1,yloc1,xloc2,yloc1);
+ fprintf(fp2,"%d,%d,%d,%d\n",xloc1,yloc1,xloc1,yloc2);
+ fprintf(fp2,"%d,%d,%d,%d\n",xloc2,yloc1,xloc2,yloc2);
+ } else {
+ xloc = (int)((x_float[i]-graphics_xmin)*xconversion);
+ xwid = (int)((x_float[i]+dx_float[i]-graphics_xmin)*xconversion-xloc);
+ yloc = (int)((graphics_ymax-(y_float[i]+dy_float[i]))*yconversion);
+ ywid = (int)((graphics_ymax-y_float[i])*yconversion);
+ ywid -= yloc;
+ //fprintf(fp,"%d,%d,%d,%d,%f\n",xloc,yloc,xwid,ywid,data[i]);
+ fprintf(fp,"%d,%d,%d,%d,%d\n",xloc,yloc,xwid,ywid,color);
+
+ xloc1 = (int)((x_float[i]-graphics_xmin)*xconversion);
+ xloc2 = (int)((x_float[i]+dx_float[i]-graphics_xmin)*xconversion);
+ yloc1 = (int)((graphics_ymax-y_float[i])*yconversion);
+ yloc2 = (int)((graphics_ymax-(y_float[i]+dy_float[i]))*yconversion);
+ fprintf(fp2,"%d,%d,%d,%d\n",xloc1,yloc2,xloc2,yloc2);
+ fprintf(fp2,"%d,%d,%d,%d\n",xloc1,yloc1,xloc2,yloc1);
+ fprintf(fp2,"%d,%d,%d,%d\n",xloc1,yloc1,xloc1,yloc2);
+ fprintf(fp2,"%d,%d,%d,%d\n",xloc2,yloc1,xloc2,yloc2);
+ }
+ }
+ fclose(fp);
+ fclose(fp2);
+ iteration++;
+ }
+ else{
+ if(fp == NULL){
+ printf("Could not open %s in DisplayStateToFile\n", filename);
+ }
+ else{
+ printf("Could not open %s in DisplayStateToFile\n", filename2);
+ }
+ }
+ }
+}
+
+void write_graphics_info(int graph_num, int ncycle, double simTime, int rollback_img, int rollback_num){
+ if (graphics_view_mode == 0) {
+ DrawSquaresToFile(graph_num, ncycle, simTime, rollback_img, rollback_num);
+ } else {
+ DisplayStateToFile(graph_num, ncycle, simTime, rollback_img, rollback_num);
+ }
+}
+
+#ifdef HAVE_MAGICKWAND
+void Magick_Scale() {
+ int i, r;
+ for (i=0, r=0; i<256; i++, r++) {
+ MagickRainbow[ i].Red = 0;
+ MagickRainbow[ i].Green = r;
+ MagickRainbow[ i].Blue = 255;
+ }
+ for (i=0, r=255; i<256; i++, r--) {
+ MagickRainbow[ 256+i].Red = 0;
+ MagickRainbow[ 256+i].Green = 255;
+ MagickRainbow[ 256+i].Blue = r;
+ }
+ for (i=0, r=0; i<256; i++, r++) {
+ MagickRainbow[ 512+i].Red = r;
+ MagickRainbow[ 512+i].Green = 255;
+ MagickRainbow[ 512+i].Blue = 0;
+ }
+ for (i=0, r=255; i<256; i++, r--) {
+ MagickRainbow[ 768+i].Red = 255;
+ MagickRainbow[ 768+i].Green = r;
+ MagickRainbow[ 768+i].Blue = 0;
+ }
+ for (i=0, r=0; i<256; i++, r++) {
+ MagickRainbow[1024+i].Red = 255;
+ MagickRainbow[1024+i].Green = 0;
+ MagickRainbow[1024+i].Blue = r;
+ }
+}
+#endif
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/graphics.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/graphics.h?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/graphics.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/graphics.h Sun Sep 3 20:10:18 2017
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2011-2012, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ * This research code is being developed as part of the
+ * 2011 X Division Summer Workshop for the express purpose
+ * of a collaborative code for development of ideas in
+ * the implementation of AMR codes for Exascale platforms
+ *
+ * AMR implementation of the Wave code previously developed
+ * as a demonstration code for regular grids on Exascale platforms
+ * as part of the Supercomputing Challenge and Los Alamos
+ * National Laboratory
+ *
+ * Authors: Bob Robey XCP-2 brobey at lanl.gov
+ * Neal Davis davis68 at lanl.gov, davis68 at illinois.edu
+ * David Nicholaeff dnic at lanl.gov, mtrxknight at aol.com
+ * Dennis Trujillo dptrujillo at lanl.gov, dptru10 at gmail.com
+ *
+ */
+#ifndef _GRAPHICS_H_
+#define _GRAPHICS_H_
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+enum graphics_file_type{
+ GRAPHICS_NONE,
+ GRAPHICS_DATA,
+ GRAPHICS_BMP,
+ GRAPHICS_GIF,
+ GRAPHICS_JPEG,
+ GRAPHICS_MPEG,
+ GRAPHICS_PDF,
+ GRAPHICS_PNG,
+ GRAPHICS_SVG
+};
+
+void set_graphics_window(float graphics_xmin_in, float graphics_xmax_in,
+ float graphics_ymin_in, float graphics_ymax_in);
+void init_graphics_output(void);
+void terminate_graphics_output(void);
+void set_graphics_viewmode(int graphics_view_mode_in);
+void set_graphics_mysize(int graphics_mysize_in);
+void set_graphics_outline(int graphics_outline_in);
+void set_graphics_cell_data_double(double *data_in);
+void set_graphics_cell_data_float(float *data_in);
+void set_graphics_cell_proc(int *graphics_proc_in);
+void set_graphics_cell_coordinates_double(double *x_in, double *dx_in,
+ double *y_in, double *dy_in);
+void set_graphics_cell_coordinates_float(float *x_in, float *dx_in,
+ float *y_in, float *dy_in);
+void write_graphics_info(int graph_num, int ncycle, double simTime,
+ int rollback_img, int rollback_num);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hash.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/hash.c?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hash.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hash.c Sun Sep 3 20:10:18 2017
@@ -0,0 +1,1277 @@
+//#if defined __INTEL_COMPILER
+
+#include <stdio.h>
+#define __USE_XOPEN
+#include <stdlib.h>
+#include "hash.h"
+#include "genmalloc.h"
+#ifdef HAVE_OPENCL
+#include "hashlib_kern.inc"
+#include "hashlib_source_kern.inc"
+#endif
+
+#ifndef NO_GLIBC_COMPAT_RAND
+#include "glibc_compat_rand.h"
+#define rand glibc_compat_rand
+#define srand glibc_compat_srand
+#define drand48() (1.0 * rand() / RAND_MAX)
+#define srand48(x) srand(x)
+#endif
+
+static ulong AA;
+static ulong BB;
+static ulong prime=4294967291;
+static uint hashtablesize;
+static uint hash_stride;
+static uint hash_ncells;
+static uint write_hash_collisions;
+static uint read_hash_collisions;
+static double write_hash_collisions_runsum = 0.0;
+static double read_hash_collisions_runsum = 0.0;
+static uint write_hash_collisions_count = 0;
+static uint read_hash_collisions_count = 0;
+static uint hash_report_level = 2;
+static uint hash_queries;
+static int hash_method = METHOD_UNSET;
+static uint hash_jump_prime = 41;
+static double hash_mult = 3.0;
+
+size_t hash_header_size = 16;
+
+#ifdef HAVE_OPENCL
+cl_mem dev_hash_header = NULL;
+#endif
+
+float mem_opt_factor;
+
+int choose_hash_method = METHOD_UNSET;
+
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+int (*read_hash)(ulong, int *);
+void (*write_hash)(uint, ulong, int *);
+
+int get_hash_method(void) {
+ return(hash_method);
+}
+
+long long get_hashtablesize(void) {
+ return(hashtablesize);
+}
+
+int *compact_hash_init(int ncells, uint isize, uint jsize, uint report_level){
+ hash_ncells = 0;
+ write_hash_collisions = 0;
+ read_hash_collisions = 0;
+ hash_queries = 0;
+ hash_report_level = report_level;
+ hash_stride = isize;
+ int *hash = NULL;
+
+ if (choose_hash_method != METHOD_UNSET) hash_method = choose_hash_method;
+
+ uint compact_hash_size = (uint)((double)ncells*hash_mult);
+ uint perfect_hash_size = (uint)(isize*jsize);
+
+ if (hash_method == METHOD_UNSET){
+ float hash_mem_factor = 20.0;
+ float hash_mem_ratio = (double)perfect_hash_size/(double)compact_hash_size;
+ if (mem_opt_factor != 1.0) hash_mem_factor /= (mem_opt_factor*0.2);
+ hash_method = (hash_mem_ratio < hash_mem_factor) ? PERFECT_HASH : QUADRATIC;
+
+ if (hash_report_level >= 2) printf("DEBUG hash_method %d hash_mem_ratio %f hash_mem_factor %f mem_opt_factor %f perfect_hash_size %u compact_hash_size %u\n",
+ hash_method,hash_mem_ratio,hash_mem_factor,mem_opt_factor,perfect_hash_size,compact_hash_size);
+ }
+
+ int do_compact_hash = (hash_method == PERFECT_HASH) ? 0 : 1;
+
+ if (hash_report_level >= 2) printf("DEBUG do_compact_hash %d hash_method %d perfect_hash_size %u compact_hash_size %u\n",
+ do_compact_hash,hash_method,perfect_hash_size,compact_hash_size);
+
+ if (do_compact_hash) {
+ hashtablesize = compact_hash_size;
+ AA = (ulong)(1.0+(double)(prime-1)*drand48());
+ BB = (ulong)(0.0+(double)(prime-1)*drand48());
+ if (AA > prime-1 || BB > prime-1) exit(0);
+ if (hash_report_level > 1) printf("Factors AA %lu BB %lu\n",AA,BB);
+
+ hash = (int *)genvector(2*hashtablesize,sizeof(int));
+ for (uint ii = 0; ii<2*hashtablesize; ii+=2){
+ hash[ii] = -1;
+ }
+
+ if (hash_method == LINEAR){
+ if (hash_report_level == 0){
+ read_hash = read_hash_linear;
+ write_hash = write_hash_linear;
+ } else if (hash_report_level == 1){
+ read_hash = read_hash_linear_report_level_1;
+ write_hash = write_hash_linear_report_level_1;
+ } else if (hash_report_level == 2){
+ read_hash = read_hash_linear_report_level_2;
+ write_hash = write_hash_linear_report_level_2;
+ } else if (hash_report_level == 3){
+ read_hash = read_hash_linear_report_level_3;
+ write_hash = write_hash_linear_report_level_3;
+ }
+ } else if (hash_method == QUADRATIC) {
+ if (hash_report_level == 0){
+ read_hash = read_hash_quadratic;
+ write_hash = write_hash_quadratic;
+ } else if (hash_report_level == 1){
+ read_hash = read_hash_quadratic_report_level_1;
+ write_hash = write_hash_quadratic_report_level_1;
+ } else if (hash_report_level == 2){
+ read_hash = read_hash_quadratic_report_level_2;
+ write_hash = write_hash_quadratic_report_level_2;
+ } else if (hash_report_level == 3){
+ read_hash = read_hash_quadratic_report_level_3;
+ write_hash = write_hash_quadratic_report_level_3;
+ }
+ } else if (hash_method == PRIME_JUMP) {
+ if (hash_report_level == 0){
+ read_hash = read_hash_primejump;
+ write_hash = write_hash_primejump;
+ } else if (hash_report_level == 1){
+ read_hash = read_hash_primejump_report_level_1;
+ write_hash = write_hash_primejump_report_level_1;
+ } else if (hash_report_level == 2){
+ read_hash = read_hash_primejump_report_level_2;
+ write_hash = write_hash_primejump_report_level_2;
+ } else if (hash_report_level == 3){
+ read_hash = read_hash_primejump_report_level_3;
+ write_hash = write_hash_primejump_report_level_3;
+ }
+ }
+ } else {
+ hashtablesize = perfect_hash_size;
+
+ hash = (int *)genvector(hashtablesize,sizeof(int));
+ for (uint ii = 0; ii<hashtablesize; ii++){
+ hash[ii] = -1;
+ }
+
+ read_hash = read_hash_perfect;
+ write_hash = write_hash_perfect;
+ }
+
+ if (hash_report_level >= 2) {
+ printf("Hash table size %u perfect hash table size %u memory savings %d by percentage %lf\n",
+ hashtablesize,isize*jsize,(int)isize*(int)jsize-(int)hashtablesize,
+ (double)hashtablesize/(double)(isize*jsize) * 100.0);
+ }
+
+ return(hash);
+}
+
+#ifdef _OPENMP
+int *compact_hash_init_openmp(int ncells, uint isize, uint jsize, uint report_level){
+ static int *hash = NULL;
+
+ static float hash_mem_factor;
+ static float hash_mem_ratio;
+ static int do_compact_hash;
+ static uint compact_hash_size;
+ static uint perfect_hash_size;
+
+#pragma omp barrier
+#pragma omp master
+ {
+
+ hash_ncells = 0;
+ write_hash_collisions = 0;
+ read_hash_collisions = 0;
+ hash_queries = 0;
+ hash_report_level = report_level;
+ hash_stride = isize;
+
+ if (choose_hash_method != METHOD_UNSET) hash_method = choose_hash_method;
+
+ compact_hash_size = (uint)((double)ncells*hash_mult);
+ perfect_hash_size = (uint)(isize*jsize);
+
+ if (hash_method == METHOD_UNSET){
+ hash_mem_factor = 20.0;
+ hash_mem_ratio = (double)perfect_hash_size/(double)compact_hash_size;
+ if (mem_opt_factor != 1.0) hash_mem_factor /= (mem_opt_factor*0.2);
+ hash_method = (hash_mem_ratio < hash_mem_factor) ? PERFECT_HASH : QUADRATIC;
+ //hash_method = QUADRATIC;
+
+ if (hash_report_level >= 2) printf("DEBUG hash_method %d hash_mem_ratio %f hash_mem_factor %f mem_opt_factor %f perfect_hash_size %u compact_hash_size %u\n",
+ hash_method,hash_mem_ratio,hash_mem_factor,mem_opt_factor,perfect_hash_size,compact_hash_size);
+ }
+
+ do_compact_hash = (hash_method == PERFECT_HASH) ? 0 : 1;
+
+ if (hash_report_level >= 2) printf("DEBUG do_compact_hash %d hash_method %d perfect_hash_size %u compact_hash_size %u\n",
+ do_compact_hash,hash_method,perfect_hash_size,compact_hash_size);
+
+ } // end omp master
+#pragma omp barrier
+
+ if (do_compact_hash) {
+#pragma omp master
+ {
+ hashtablesize = compact_hash_size;
+ //srand48(0);
+ AA = (ulong)(1.0+(double)(prime-1)*drand48());
+ BB = (ulong)(0.0+(double)(prime-1)*drand48());
+ if (AA > prime-1 || BB > prime-1) exit(0);
+ if (hash_report_level > 1) printf("Factors AA %lu BB %lu\n",AA,BB);
+
+ hash = (int *)genvector(2*hashtablesize,sizeof(int));
+ } // end omp master
+#pragma omp barrier
+
+#pragma omp for
+ for (uint ii = 0; ii<hashtablesize; ii++){
+ hash[2*ii] = -1;
+ }
+
+#pragma omp master
+ {
+ if (hash_method == LINEAR){
+ if (hash_report_level == 0){
+ read_hash = read_hash_linear;
+ write_hash = write_hash_linear_openmp;
+ } else if (hash_report_level == 1){
+ read_hash = read_hash_linear_report_level_1;
+ write_hash = write_hash_linear_openmp_report_level_1;
+ } else if (hash_report_level == 2){
+ read_hash = read_hash_linear_report_level_2;
+ write_hash = write_hash_linear_openmp_report_level_2;
+ } else if (hash_report_level == 3){
+ read_hash = read_hash_linear_report_level_3;
+ write_hash = write_hash_linear_openmp_report_level_3;
+ }
+ } else if (hash_method == QUADRATIC) {
+ if (hash_report_level == 0){
+ read_hash = read_hash_quadratic;
+ write_hash = write_hash_quadratic_openmp;
+ } else if (hash_report_level == 1){
+ read_hash = read_hash_quadratic_report_level_1;
+ write_hash = write_hash_quadratic_openmp_report_level_1;
+ } else if (hash_report_level == 2){
+ read_hash = read_hash_quadratic_report_level_2;
+ write_hash = write_hash_quadratic_openmp_report_level_2;
+ } else if (hash_report_level == 3){
+ read_hash = read_hash_quadratic_report_level_3;
+ write_hash = write_hash_quadratic_openmp_report_level_3;
+ }
+ } else if (hash_method == PRIME_JUMP) {
+ if (hash_report_level == 0){
+ read_hash = read_hash_primejump;
+ write_hash = write_hash_primejump_openmp;
+ } else if (hash_report_level == 1){
+ read_hash = read_hash_primejump_report_level_1;
+ write_hash = write_hash_primejump_openmp_report_level_1;
+ } else if (hash_report_level == 2){
+ read_hash = read_hash_primejump_report_level_2;
+ write_hash = write_hash_primejump_openmp_report_level_2;
+ } else if (hash_report_level == 3){
+ read_hash = read_hash_primejump_report_level_3;
+ write_hash = write_hash_primejump_openmp_report_level_3;
+ }
+ }
+ } // end omp master
+#pragma omp barrier
+
+ } else {
+
+#pragma omp master
+ {
+ hashtablesize = perfect_hash_size;
+
+ hash = (int *)genvector(hashtablesize,sizeof(int));
+ } // end omp master
+#pragma omp barrier
+
+#pragma omp for
+ for (uint ii = 0; ii<hashtablesize; ii++){
+ hash[ii] = -1;
+ }
+
+#pragma omp master
+ {
+ read_hash = read_hash_perfect;
+ write_hash = write_hash_perfect;
+ } // end omp master
+#pragma omp barrier
+ }
+
+#pragma omp master
+ {
+ if (hash_report_level >= 2) {
+ printf("Hash table size %u perfect hash table size %u memory savings %u by percentage %lf\n",
+ hashtablesize,isize*jsize,isize*jsize-hashtablesize,
+ (double)hashtablesize/(double)(isize*jsize));
+ }
+ }
+#pragma omp barrier
+
+ return(hash);
+}
+#endif
+
+void write_hash_perfect(uint ic, ulong hashkey, int *hash){
+ hash[hashkey] = ic;
+}
+
+void write_hash_linear(uint ic, ulong hashkey, int *hash){
+ uint hashloc;
+
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc++,hashloc = hashloc%hashtablesize);
+
+ hash[2*hashloc] = hashkey;
+ hash[2*hashloc+1] = ic;
+}
+
+void write_hash_linear_report_level_1(uint ic, ulong hashkey, int *hash){
+ uint hashloc;
+
+ hash_ncells++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc++,hashloc = hashloc%hashtablesize){
+ write_hash_collisions++;
+ }
+
+ hash[2*hashloc] = hashkey;
+ hash[2*hashloc+1] = ic;
+}
+
+void write_hash_linear_report_level_2(uint ic, ulong hashkey, int *hash){
+ uint hashloc;
+
+ hash_ncells++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc++,hashloc = hashloc%hashtablesize){
+ write_hash_collisions++;
+ }
+
+ hash[2*hashloc] = hashkey;
+ hash[2*hashloc+1] = ic;
+}
+
+void write_hash_linear_report_level_3(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint hashloc;
+
+ hash_ncells++;
+ hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+ printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc++,hashloc = hashloc%hashtablesize){
+ int hashloctmp = hashloc+1;
+ hashloctmp = hashloctmp%hashtablesize;
+ printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ icount++;
+ }
+ write_hash_collisions += icount;
+
+ hash[2*hashloc] = hashkey;
+ hash[2*hashloc+1] = ic;
+}
+
+void write_hash_quadratic(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint hashloc;
+
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize) {
+ icount++;
+ }
+
+ hash[2*hashloc] = hashkey;
+ hash[2*hashloc+1] = ic;
+}
+
+void write_hash_quadratic_report_level_1(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint hashloc;
+
+ hash_ncells++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
+ icount++;
+ }
+ write_hash_collisions += icount;
+
+ hash[2*hashloc] = hashkey;
+ hash[2*hashloc+1] = ic;
+}
+
+void write_hash_quadratic_report_level_2(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint hashloc;
+
+ hash_ncells++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
+ icount++;
+ }
+ write_hash_collisions += icount;
+
+ hash[2*hashloc] = hashkey;
+ hash[2*hashloc+1] = ic;
+}
+
+void write_hash_quadratic_report_level_3(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint hashloc;
+
+ hash_ncells++;
+ hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+ printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
+ icount++;
+ int hashloctmp = hashloc+icount*icount;
+ hashloctmp = hashloctmp%hashtablesize;
+ printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ }
+ write_hash_collisions += icount;
+
+ hash[2*hashloc] = hashkey;
+ hash[2*hashloc+1] = ic;
+}
+
+void write_hash_primejump(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint hashloc;
+
+ uint jump = 1+hashkey%hash_jump_prime;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize) {
+ icount++;
+ }
+
+ hash[2*hashloc] = hashkey;
+ hash[2*hashloc+1] = ic;
+}
+
+void write_hash_primejump_report_level_1(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint hashloc;
+
+ uint jump = 1+hashkey%hash_jump_prime;
+ hash_ncells++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
+ icount++;
+ }
+ write_hash_collisions += icount;
+
+ hash[2*hashloc] = hashkey;
+ hash[2*hashloc+1] = ic;
+}
+
+void write_hash_primejump_report_level_2(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint hashloc;
+
+ uint jump = 1+hashkey%hash_jump_prime;
+ hash_ncells++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
+ icount++;
+ }
+ write_hash_collisions += icount;
+
+ hash[2*hashloc] = hashkey;
+ hash[2*hashloc+1] = ic;
+}
+
+void write_hash_primejump_report_level_3(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint hashloc;
+
+ uint jump = 1+hashkey%hash_jump_prime;
+ hash_ncells++;
+ hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+ printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != -1 && hash[2*hashloc]!= (int)hashkey; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
+ icount++;
+ int hashloctmp = hashloc+1;
+ hashloctmp = hashloctmp%hashtablesize;
+ printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ }
+ write_hash_collisions += icount;
+
+ hash[2*hashloc] = hashkey;
+ hash[2*hashloc+1] = ic;
+}
+
+#ifdef _OPENMP
+void write_hash_linear_openmp(uint ic, ulong hashkey, int *hash){
+ int icount;
+ uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;;
+
+ int MaxTries = 1000;
+
+ int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ //printf("old_key is %d\n",old_key);
+
+ for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
+ hashloc++;
+ hashloc %= hashtablesize;
+
+ old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ }
+
+ if (icount < MaxTries) hash[2*hashloc+1] = ic;
+}
+
+void write_hash_linear_openmp_report_level_1(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;;
+
+ int MaxTries = 1000;
+
+ int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ //printf("old_key is %d\n",old_key);
+
+ for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
+ hashloc++;
+ hashloc %= hashtablesize;
+
+ old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ icount++;
+ }
+
+ if (icount < MaxTries) hash[2*hashloc+1] = ic;
+
+#pragma omp atomic
+ write_hash_collisions += icount;;
+#pragma omp atomic
+ hash_ncells++;
+}
+
+void write_hash_linear_openmp_report_level_2(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;;
+
+ int MaxTries = 1000;
+
+ int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ //printf("old_key is %d\n",old_key);
+
+ for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
+ hashloc++;
+ hashloc %= hashtablesize;
+
+ old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ icount++;
+ }
+
+ if (icount < MaxTries) hash[2*hashloc+1] = ic;
+
+#pragma omp atomic
+ write_hash_collisions += icount;;
+#pragma omp atomic
+ hash_ncells++;
+}
+
+void write_hash_linear_openmp_report_level_3(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;;
+ printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+
+ int MaxTries = 1000;
+
+ int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ //printf("old_key is %d\n",old_key);
+
+ for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
+ hashloc++;
+ hashloc %= hashtablesize;
+ printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+
+ old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ icount++;
+ }
+
+ if (icount < MaxTries) hash[2*hashloc+1] = ic;
+
+#pragma omp atomic
+ write_hash_collisions += icount;;
+#pragma omp atomic
+ hash_ncells++;
+}
+
+void write_hash_quadratic_openmp(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+
+ int MaxTries = 1000;
+
+ int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ //printf("old_key is %d\n",old_key);
+
+ for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
+ hashloc+=(icount*icount);
+ hashloc %= hashtablesize;
+
+ old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ }
+
+ if (icount < MaxTries) hash[2*hashloc+1] = ic;
+}
+
+void write_hash_quadratic_openmp_report_level_1(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+
+ int MaxTries = 1000;
+
+ int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ //printf("old_key is %d\n",old_key);
+
+ for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
+ hashloc+=(icount*icount);
+ hashloc %= hashtablesize;
+
+ old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ }
+
+ if (icount < MaxTries) hash[2*hashloc+1] = ic;
+
+#pragma omp atomic
+ write_hash_collisions += icount;;
+#pragma omp atomic
+ hash_ncells++;
+}
+
+void write_hash_quadratic_openmp_report_level_2(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+
+ int MaxTries = 1000;
+
+ int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ //printf("old_key is %d\n",old_key);
+
+ for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
+ hashloc+=(icount*icount);
+ hashloc %= hashtablesize;
+
+ old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ }
+
+ if (icount < MaxTries) hash[2*hashloc+1] = ic;
+
+#pragma omp atomic
+ write_hash_collisions += icount;;
+#pragma omp atomic
+ hash_ncells++;
+}
+
+void write_hash_quadratic_openmp_report_level_3(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+ printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+
+ int MaxTries = 1000;
+
+ int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ //printf("old_key is %d\n",old_key);
+
+ for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
+ hashloc+=(icount*icount);
+ hashloc %= hashtablesize;
+ printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+
+ old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ }
+
+ if (icount < MaxTries) hash[2*hashloc+1] = ic;
+
+#pragma omp atomic
+ write_hash_collisions += icount;;
+#pragma omp atomic
+ hash_ncells++;
+}
+
+void write_hash_primejump_openmp(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint jump = 1+hashkey%hash_jump_prime;
+ uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+
+ int MaxTries = 1000;
+
+ int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ //printf("old_key is %d\n",old_key);
+
+ for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
+ hashloc+=(icount*jump);
+ hashloc %= hashtablesize;
+
+ old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ }
+
+ if (icount < MaxTries) hash[2*hashloc+1] = ic;
+}
+
+void write_hash_primejump_openmp_report_level_1(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint jump = 1+hashkey%hash_jump_prime;
+ uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+
+ int MaxTries = 1000;
+
+ int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ //printf("old_key is %d\n",old_key);
+
+ for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
+ hashloc+=(icount*jump);
+ hashloc %= hashtablesize;
+
+ old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ }
+
+ if (icount < MaxTries) hash[2*hashloc+1] = ic;
+
+#pragma omp atomic
+ write_hash_collisions += icount;;
+#pragma omp atomic
+ hash_ncells++;
+}
+
+void write_hash_primejump_openmp_report_level_2(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint jump = 1+hashkey%hash_jump_prime;
+ uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+
+ int MaxTries = 1000;
+
+ int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ //printf("old_key is %d\n",old_key);
+
+ for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
+ hashloc+=(icount*jump);
+ hashloc %= hashtablesize;
+
+ old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ }
+
+ if (icount < MaxTries) hash[2*hashloc+1] = ic;
+
+#pragma omp atomic
+ write_hash_collisions += icount;;
+#pragma omp atomic
+ hash_ncells++;
+}
+
+void write_hash_primejump_openmp_report_level_3(uint ic, ulong hashkey, int *hash){
+ int icount = 0;
+ uint jump = 1+hashkey%hash_jump_prime;
+ uint hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+ printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+
+ int MaxTries = 1000;
+
+ int old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ //printf("old_key is %d\n",old_key);
+
+ for (icount = 1; old_key != hashkey && old_key != -1 && icount < MaxTries; icount++){
+ hashloc+=(icount*jump);
+ hashloc %= hashtablesize;
+ printf("%d: cell %d hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,ic,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+
+ old_key = __sync_val_compare_and_swap(&hash[2*hashloc], -1, hashkey);
+ }
+
+ if (icount < MaxTries) hash[2*hashloc+1] = ic;
+
+#pragma omp atomic
+ write_hash_collisions += icount;;
+#pragma omp atomic
+ hash_ncells++;
+}
+#endif
+
+int read_hash_perfect(ulong hashkey, int *hash){
+ return(hash[hashkey]);
+}
+
+int read_hash_linear(ulong hashkey, int *hash){
+ int hashval = -1;
+ uint hashloc;
+ int icount=0;
+
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc++,hashloc = hashloc%hashtablesize){
+ icount++;
+ }
+
+ if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
+ return(hashval);
+}
+
+int read_hash_linear_report_level_1(ulong hashkey, int *hash){
+ int hashval = -1;
+ uint hashloc;
+ int icount=0;
+
+ hash_queries++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc++,hashloc = hashloc%hashtablesize){
+ icount++;
+ }
+ read_hash_collisions += icount;
+
+ if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
+ return(hashval);
+}
+
+int read_hash_linear_report_level_2(ulong hashkey, int *hash){
+ int max_collisions_allowed = 1000;
+ int hashval = -1;
+ uint hashloc;
+ int icount=0;
+
+ hash_queries++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc++,hashloc = hashloc%hashtablesize){
+ icount++;
+ if (icount > max_collisions_allowed) {
+ printf("Error -- too many read hash collisions\n");
+ exit(0);
+ }
+ }
+ read_hash_collisions += icount;
+
+ if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
+ return(hashval);
+}
+
+int read_hash_linear_report_level_3(ulong hashkey, int *hash){
+ int max_collisions_allowed = 1000;
+ int hashval = -1;
+ uint hashloc;
+ int icount=0;
+
+ hash_queries++;
+ hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+ printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc++,hashloc = hashloc%hashtablesize){
+ icount++;
+ uint hashloctmp = hashloc+1;
+ hashloctmp = hashloctmp%hashtablesize;
+ printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ if (icount > max_collisions_allowed) {
+ printf("Error -- too many read hash collisions\n");
+ exit(0);
+ }
+ }
+ read_hash_collisions += icount;
+
+ if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
+ return(hashval);
+}
+
+int read_hash_quadratic(ulong hashkey, int *hash){
+ int hashval = -1;
+ uint hashloc;
+ int icount=0;
+
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
+ icount++;
+ }
+
+ if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
+ return(hashval);
+}
+
+int read_hash_quadratic_report_level_1(ulong hashkey, int *hash){
+ int hashval = -1;
+ uint hashloc;
+ int icount=0;
+
+ hash_queries++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
+ icount++;
+ }
+ read_hash_collisions += icount;
+
+ if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
+ return(hashval);
+}
+
+int read_hash_quadratic_report_level_2(ulong hashkey, int *hash){
+ int max_collisions_allowed = 1000;
+ int hashval = -1;
+ uint hashloc;
+ int icount=0;
+
+ hash_queries++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
+ icount++;
+ if (icount > max_collisions_allowed) {
+ printf("Error -- too many read hash collisions\n");
+ exit(0);
+ }
+ }
+ read_hash_collisions += icount;
+
+ if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
+ return(hashval);
+}
+
+int read_hash_quadratic_report_level_3(ulong hashkey, int *hash){
+ int max_collisions_allowed = 1000;
+ int hashval = -1;
+ uint hashloc;
+ int icount=0;
+
+ hash_queries++;
+ hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+ printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
+ icount++;
+ uint hashloctmp = hashloc+1;
+ hashloctmp = hashloctmp%hashtablesize;
+ printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ if (icount > max_collisions_allowed) {
+ printf("Error -- too many read hash collisions\n");
+ exit(0);
+ }
+ }
+ read_hash_collisions += icount;
+
+ if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
+ return(hashval);
+}
+
+int read_hash_primejump(ulong hashkey, int *hash){
+ int hashval = -1;
+ uint hashloc;
+ int icount=0;
+
+ uint jump = 1+hashkey%hash_jump_prime;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
+ icount++;
+ }
+
+ if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
+ return(hashval);
+}
+
+int read_hash_primejump_report_level_1(ulong hashkey, int *hash){
+ int hashval = -1;
+ uint hashloc;
+ int icount=0;
+
+ uint jump = 1+hashkey%hash_jump_prime;
+ hash_queries++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
+ icount++;
+ }
+ read_hash_collisions += icount;
+
+ if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
+ return(hashval);
+}
+
+int read_hash_primejump_report_level_2(ulong hashkey, int *hash){
+ int max_collisions_allowed = 1000;
+ int hashval = -1;
+ uint hashloc;
+ int icount=0;
+
+ uint jump = 1+hashkey%hash_jump_prime;
+ hash_queries++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
+ icount++;
+ if (icount > max_collisions_allowed) {
+ printf("Error -- too many read hash collisions\n");
+ exit(0);
+ }
+ }
+ read_hash_collisions += icount;
+
+ if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
+ return(hashval);
+}
+
+int read_hash_primejump_report_level_3(ulong hashkey, int *hash){
+ int max_collisions_allowed = 1000;
+ int hashval = -1;
+ uint hashloc;
+ int icount=0;
+
+ uint jump = 1+hashkey%hash_jump_prime;
+ hash_queries++;
+ hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+ printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
+ icount++;
+ uint hashloctmp = hashloc+1;
+ hashloctmp = hashloctmp%hashtablesize;
+ printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ if (icount > max_collisions_allowed) {
+ printf("Error -- too many read hash collisions\n");
+ exit(0);
+ }
+ }
+ read_hash_collisions += icount;
+
+ if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
+ return(hashval);
+}
+
+void compact_hash_delete(int *hash){
+ read_hash = NULL;
+ genvectorfree((void *)hash);
+ hash_method = METHOD_UNSET;
+}
+
+void write_hash_collision_report(void){
+ if (hash_method == PERFECT_HASH) return;
+ if (hash_report_level == 1) {
+ write_hash_collisions_runsum += (double)write_hash_collisions/(double)hash_ncells;
+ write_hash_collisions_count++;
+ } else if (hash_report_level >= 2) {
+ printf("Write hash collision report -- collisions per cell %lf, collisions %d cells %d\n",(double)write_hash_collisions/(double)hash_ncells,write_hash_collisions,hash_ncells);
+ }
+}
+
+void read_hash_collision_report(void){
+ //printf("hash table size bytes %ld\n",hashtablesize*sizeof(int));
+ if (hash_method == PERFECT_HASH) return;
+ if (hash_report_level == 1) {
+ read_hash_collisions_runsum += (double)read_hash_collisions/(double)hash_queries;
+ read_hash_collisions_count++;
+ } else if (hash_report_level >= 2) {
+ printf("Read hash collision report -- collisions per cell %lf, collisions %d cells %d\n",(double)read_hash_collisions/(double)hash_queries,read_hash_collisions,hash_queries);
+ hash_queries = 0;
+ read_hash_collisions = 0;
+ }
+}
+
+void final_hash_collision_report(void){
+ printf("hash table size bytes %ld\n",hashtablesize*sizeof(int));
+ if (hash_report_level >= 1 && read_hash_collisions_count > 0) {
+ printf("Final hash collision report -- write/read collisions per cell %lf/%lf\n",write_hash_collisions_runsum/(double)write_hash_collisions_count,read_hash_collisions_runsum/(double)read_hash_collisions_count);
+ }
+}
+
+#ifdef HAVE_OPENCL
+const char *get_hash_kernel_source_string(void)
+{
+ return(hashlib_source_kern_source);
+}
+#endif
+
+#ifdef HAVE_OPENCL
+static cl_kernel kernel_hash_init;
+void hash_lib_init(void){
+ cl_context context = ezcl_get_context();
+
+ const char *defines = NULL;
+ cl_program program = ezcl_create_program_wsource(context, defines, hashlib_kern_source);
+
+ kernel_hash_init = ezcl_create_kernel_wprogram(program, "hash_init_cl");
+
+ ezcl_program_release(program);
+}
+
+void hash_lib_terminate(void){
+ ezcl_kernel_release(kernel_hash_init);
+}
+
+cl_mem gpu_compact_hash_init(ulong ncells, int imaxsize, int jmaxsize, int gpu_hash_method, uint hash_report_level_in,
+ ulong *gpu_hashtablesize, ulong *hashsize, cl_mem *dev_hash_header_in)
+{
+ hash_report_level = hash_report_level_in;
+
+ uint gpu_compact_hash_size = (uint)((double)ncells*hash_mult);
+ uint gpu_perfect_hash_size = (uint)(imaxsize*jmaxsize);
+
+ if (gpu_hash_method == METHOD_UNSET) {
+ float gpu_hash_mem_factor = 20.0;
+ float gpu_hash_mem_ratio = (double)gpu_perfect_hash_size/(double)gpu_compact_hash_size;
+ if (mem_opt_factor != 1.0) gpu_hash_mem_factor /= (mem_opt_factor*0.2);
+ gpu_hash_method = (gpu_hash_mem_ratio < gpu_hash_mem_factor) ? PERFECT_HASH : QUADRATIC;
+ }
+
+ int gpu_do_compact_hash = (gpu_hash_method == PERFECT_HASH) ? 0 : 1;
+
+ ulong gpu_AA = 1;
+ ulong gpu_BB = 0;
+ if (gpu_do_compact_hash){
+ (*gpu_hashtablesize) = gpu_compact_hash_size;
+ gpu_AA = (ulong)(1.0+(double)(prime-1)*drand48());
+ gpu_BB = (ulong)(0.0+(double)(prime-1)*drand48());
+ //if ( gpu_AA > prime-1 || gpu_BB > prime-1) exit(0);
+ (*hashsize) = 2*gpu_compact_hash_size;
+ } else {
+ (*gpu_hashtablesize) = gpu_perfect_hash_size;
+ (*hashsize) = gpu_perfect_hash_size;
+ }
+
+ hashtablesize = (*hashsize);
+
+ const uint TILE_SIZE = 128;
+
+ cl_command_queue command_queue = ezcl_get_command_queue();
+
+ cl_mem dev_hash = ezcl_malloc(NULL, "dev_hash", hashsize, sizeof(cl_int), CL_MEM_READ_WRITE, 0);
+ ulong *gpu_hash_header = (ulong *)genvector(hash_header_size, sizeof(ulong));
+ gpu_hash_header[0] = (ulong)gpu_hash_method;
+ gpu_hash_header[1] = (*gpu_hashtablesize);
+ gpu_hash_header[2] = gpu_AA;
+ gpu_hash_header[3] = gpu_BB;
+ dev_hash_header = ezcl_malloc(NULL, "dev_hash_header", &hash_header_size, sizeof(cl_ulong), CL_MEM_READ_WRITE, 0);
+ ezcl_enqueue_write_buffer(command_queue, dev_hash_header, CL_TRUE, 0, hash_header_size*sizeof(cl_ulong), &gpu_hash_header[0], NULL);
+
+ genvectorfree(gpu_hash_header);
+
+ (*dev_hash_header_in) = dev_hash_header;
+
+ size_t hash_local_work_size = MIN((*hashsize), TILE_SIZE);
+ size_t hash_global_work_size = (((*hashsize)+hash_local_work_size - 1) /hash_local_work_size) * hash_local_work_size;
+
+ ezcl_set_kernel_arg(kernel_hash_init, 0, sizeof(cl_int), (void *)hashsize);
+ ezcl_set_kernel_arg(kernel_hash_init, 1, sizeof(cl_mem), (void *)&dev_hash);
+ ezcl_enqueue_ndrange_kernel(command_queue, kernel_hash_init, 1, NULL, &hash_global_work_size, &hash_local_work_size, NULL);
+
+ return(dev_hash);
+}
+
+void gpu_compact_hash_delete(cl_mem dev_hash, cl_mem dev_hash_header){
+ ezcl_device_memory_delete(dev_hash);
+ ezcl_device_memory_delete(dev_hash_header);
+ hash_method = METHOD_UNSET;
+}
+
+cl_mem gpu_get_hash_header(void){
+ return(dev_hash_header);
+}
+#endif
+
+int read_dev_hash(int hash_method, ulong hashtablesize, ulong AA, ulong BB, ulong hashkey, int *hash){
+ //int hash_report_level = 3;
+ int max_collisions_allowed = 1000;
+ int hashval = -1;
+ uint hashloc;
+ int icount=0;
+ if (hash_method == PERFECT_HASH) {
+ return(hash[hashkey]);
+ }
+ if (hash_method == LINEAR) {
+ if (hash_report_level == 0) {
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc++,hashloc = hashloc%hashtablesize){
+ icount++;
+ }
+ } else if (hash_report_level == 1) {
+ hash_queries++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc++,hashloc = hashloc%hashtablesize){
+ icount++;
+ }
+ read_hash_collisions += icount;
+ } else if (hash_report_level == 2) {
+ hash_queries++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc++,hashloc = hashloc%hashtablesize){
+ icount++;
+ if (icount > max_collisions_allowed) {
+ printf("Error -- too many read hash collisions\n");
+ exit(0);
+ }
+ }
+ read_hash_collisions += icount;
+ } else if (hash_report_level == 3) {
+ hash_queries++;
+ hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+ printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc++,hashloc = hashloc%hashtablesize){
+ icount++;
+ uint hashloctmp = hashloc+1;
+ hashloctmp = hashloctmp%hashtablesize;
+ printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ if (icount > max_collisions_allowed) {
+ printf("Error -- too many read hash collisions\n");
+ exit(0);
+ }
+ }
+ read_hash_collisions += icount;
+ } else {
+ printf("Error -- Illegal value of hash_report_level %d\n",hash_report_level);
+ exit(1);
+ }
+ } else if (hash_method == QUADRATIC) {
+ if (hash_report_level == 0) {
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
+ icount++;
+ }
+ } else if (hash_report_level == 1) {
+ hash_queries++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
+ icount++;
+ }
+ read_hash_collisions += icount;
+ } else if (hash_report_level == 2) {
+ hash_queries++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
+ icount++;
+ if (icount > max_collisions_allowed) {
+ printf("Error -- too many read hash collisions\n");
+ exit(0);
+ }
+ }
+ read_hash_collisions += icount;
+ } else if (hash_report_level == 3) {
+ hash_queries++;
+ hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+ printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*icount),hashloc = hashloc%hashtablesize){
+ icount++;
+ uint hashloctmp = hashloc+1;
+ hashloctmp = hashloctmp%hashtablesize;
+ printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ if (icount > max_collisions_allowed) {
+ printf("Error -- too many read hash collisions\n");
+ exit(0);
+ }
+ }
+ read_hash_collisions += icount;
+ } else {
+ printf("Error -- Illegal value of hash_report_level %d\n",hash_report_level);
+ exit(1);
+ }
+ } else if (hash_method == PRIME_JUMP) {
+ uint jump = 1+hashkey%hash_jump_prime;
+ if (hash_report_level == 0) {
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
+ icount++;
+ }
+ } else if (hash_report_level == 1) {
+ hash_queries++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
+ icount++;
+ }
+ read_hash_collisions += icount;
+ } else if (hash_report_level == 2) {
+ hash_queries++;
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
+ icount++;
+ if (icount > max_collisions_allowed) {
+ printf("Error -- too many read hash collisions\n");
+ exit(0);
+ }
+ }
+ read_hash_collisions += icount;
+ } else if (hash_report_level == 3) {
+ hash_queries++;
+ hashloc = (hashkey*AA+BB)%prime%hashtablesize;
+ printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloc,hash[2*hashloc],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ for (hashloc = (hashkey*AA+BB)%prime%hashtablesize; hash[2*hashloc] != (int)hashkey && hash[2*hashloc] != -1; hashloc+=(icount*jump),hashloc = hashloc%hashtablesize){
+ icount++;
+ uint hashloctmp = hashloc+1;
+ hashloctmp = hashloctmp%hashtablesize;
+ printf("%d: hashloc is %d hash[2*hashloc] = %d hashkey %lu ii %lu jj %lu\n",icount,hashloctmp,hash[2*hashloctmp],hashkey,hashkey%hash_stride,hashkey/hash_stride);
+ if (icount > max_collisions_allowed) {
+ printf("Error -- too many read hash collisions\n");
+ exit(0);
+ }
+ }
+ read_hash_collisions += icount;
+ } else {
+ printf("Error -- Illegal value of hash_report_level %d\n",hash_report_level);
+ exit(1);
+ }
+ } else {
+ printf("Error -- Illegal value of hash_method %d\n",hash_method);
+ exit(1);
+ }
+
+ if (hash[2*hashloc] != -1) hashval = hash[2*hashloc+1];
+ return(hashval);
+}
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hash.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/hash.h?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hash.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hash.h Sun Sep 3 20:10:18 2017
@@ -0,0 +1,108 @@
+// Uses LANL Copyright Disclosure C14043/LA-CC-14-003
+
+#ifndef _HASH_H
+#define _HASH_H
+
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+
+#ifdef HAVE_OPENCL
+#include "ezcl/ezcl.h"
+#endif
+
+enum choose_hash_method
+{ METHOD_UNSET = 0, // use 0 for no method set
+ PERFECT_HASH, // perfect hash 1
+ LINEAR, // linear hash 2
+ QUADRATIC, // quadratic hash 3
+ PRIME_JUMP }; // prime_jump hash 4
+
+typedef unsigned int uint;
+typedef unsigned long ulong;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+int *compact_hash_init(int ncells, uint isize, uint jsize, uint report_level);
+
+#ifdef _OPENMP
+ int *compact_hash_init_openmp(int ncells, uint isize, uint jsize, uint report_level);
+#endif
+
+int get_hash_method(void);
+long long get_hash_table_size(void);
+
+void write_hash_perfect(uint ic, ulong hashkey, int *hash);
+void write_hash_linear(uint ic, ulong hashkey, int *hash);
+void write_hash_linear_report_level_1(uint ic, ulong hashkey, int *hash);
+void write_hash_linear_report_level_2(uint ic, ulong hashkey, int *hash);
+void write_hash_linear_report_level_3(uint ic, ulong hashkey, int *hash);
+void write_hash_quadratic(uint ic, ulong hashkey, int *hash);
+void write_hash_quadratic_report_level_1(uint ic, ulong hashkey, int *hash);
+void write_hash_quadratic_report_level_2(uint ic, ulong hashkey, int *hash);
+void write_hash_quadratic_report_level_3(uint ic, ulong hashkey, int *hash);
+void write_hash_primejump(uint ic, ulong hashkey, int *hash);
+void write_hash_primejump_report_level_1(uint ic, ulong hashkey, int *hash);
+void write_hash_primejump_report_level_2(uint ic, ulong hashkey, int *hash);
+void write_hash_primejump_report_level_3(uint ic, ulong hashkey, int *hash);
+extern void (*write_hash)(uint ic, ulong hashkey, int *hash); // declared in hash.c
+
+#ifdef _OPENMP
+ void write_hash_linear_openmp(uint ic, ulong hashkey, int *hash);
+ void write_hash_linear_openmp_report_level_1(uint ic, ulong hashkey, int *hash);
+ void write_hash_linear_openmp_report_level_2(uint ic, ulong hashkey, int *hash);
+ void write_hash_linear_openmp_report_level_3(uint ic, ulong hashkey, int *hash);
+ void write_hash_quadratic_openmp(uint ic, ulong hashkey, int *hash);
+ void write_hash_quadratic_openmp_report_level_1(uint ic, ulong hashkey, int *hash);
+ void write_hash_quadratic_openmp_report_level_2(uint ic, ulong hashkey, int *hash);
+ void write_hash_quadratic_openmp_report_level_3(uint ic, ulong hashkey, int *hash);
+ void write_hash_primejump_openmp(uint ic, ulong hashkey, int *hash);
+ void write_hash_primejump_openmp_report_level_1(uint ic, ulong hashkey, int *hash);
+ void write_hash_primejump_openmp_report_level_2(uint ic, ulong hashkey, int *hash);
+ void write_hash_primejump_openmp_report_level_3(uint ic, ulong hashkey, int *hash);
+ extern void (*write_hash)(uint ic, ulong hashkey, int *hash); // declared in hash.c
+#endif
+
+int read_hash_perfect(ulong hashkey, int *hash);
+int read_hash_linear(ulong hashkey, int *hash);
+int read_hash_linear_report_level_1(ulong hashkey, int *hash);
+int read_hash_linear_report_level_2(ulong hashkey, int *hash);
+int read_hash_linear_report_level_3(ulong hashkey, int *hash);
+int read_hash_quadratic(ulong hashkey, int *hash);
+int read_hash_quadratic_report_level_1(ulong hashkey, int *hash);
+int read_hash_quadratic_report_level_2(ulong hashkey, int *hash);
+int read_hash_quadratic_report_level_3(ulong hashkey, int *hash);
+int read_hash_primejump(ulong hashkey, int *hash);
+int read_hash_primejump_report_level_1(ulong hashkey, int *hash);
+int read_hash_primejump_report_level_2(ulong hashkey, int *hash);
+int read_hash_primejump_report_level_3(ulong hashkey, int *hash);
+extern int (*read_hash)(ulong hashkey, int *hash); // declared in hash.c
+
+void compact_hash_delete(int *hash);
+
+void write_hash_collision_report(void);
+void read_hash_collision_report(void);
+void final_hash_collision_report(void);
+
+const char *get_hash_kernel_source_string(void);
+void hash_lib_init(void);
+void hash_lib_terminate(void);
+
+#ifdef HAVE_OPENCL
+cl_mem gpu_compact_hash_init(ulong ncells, int imaxsize, int jmaxsize, int gpu_hash_method, uint hash_report_level_in,
+ ulong *gpu_hash_table_size, ulong *hashsize, cl_mem *dev_hash_header_in);
+cl_mem gpu_get_hash_header(void);
+void gpu_compact_hash_delete(cl_mem dev_hash, cl_mem dev_hash_header);
+#endif
+int read_dev_hash(int hash_method, ulong hash_table_size, ulong AA, ulong BB, ulong hashkey, int *hash);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // _HASH_H
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hsfc.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/hsfc.c?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hsfc.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hsfc.c Sun Sep 3 20:10:18 2017
@@ -0,0 +1,279 @@
+/* ---------------------------------------------------------------------
+Author: H. Carter Edwards
+ hcedwar at sandia.gov
+
+Copyright: Copyright (C) 1997 H. Carter Edwards
+ Graduate Student
+ University of Texas
+
+Re-release: Copyright (C) 2011-2012 H. Carter Edwards
+
+Purpose: Domain paritioning based upon Hilbert Space-Filling Curve
+ ordering.
+
+License: Re-release under the less-restrictive CLAMR software terms.
+ Permitted by email with H. Carter Edwards on 9/13/2011
+
+Disclaimer:
+
+ These routines comes with ABSOLUTELY NO WARRANTY;
+ This is free software, and you are welcome to redistribute it
+ under certain conditions. See License terms in file 'LICENSE'.
+--------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------
+Description:
+ Inverse of the Hilbert Space-Filling Curve Map from a 2D or 3D
+domain to the 1D domain. Two different 2D and 3D domains are
+supported.
+
+For the routines 'hsfc2d' and 'hsfc3d' the 2D and 3D domains are
+defined as follows.
+Note that
+ * 0 is the minimum value of an unsigned integer
+ * ~(0u) is the maximum value of an unsigned integer - all bits set
+thus the 2D and 3D domains are
+ * [0,~(0u)] x [0,~(0u)]
+ * [0,~(0u)] x [0,~(0u)] x [0,~(0u)]
+respectively.
+
+For the routines 'fhsfc2d' and 'fhsfc3d' the 2D and 3D domains are
+defines as:
+ * [0.0,1.0] x [0.0,1.0]
+ * [0.0,1.0] x [0.0,1.0] x [0.0,1.0]
+respectively.
+
+The 1D domain is a multiword (array of unsigned integers) key.
+This key is essentially an unsigned integer of an arbitrary
+number of bits. The most significant bit is the leading bit
+of the first (0th) word of the key. The least significant
+bit is the trailing bit of the last word.
+
+----------------------------------------------------------------------*/
+
+#include <stdlib.h>
+#include <limits.h>
+
+/* Bits per unsigned word */
+
+#define MaxBits ( sizeof(unsigned) * CHAR_BIT )
+
+/*--------------------------------------------------------------------*/
+/* 2D Hilbert Space-filling curve */
+
+void hsfc2d(
+ unsigned coord[] , /* IN: Normalized integer coordinates */
+ unsigned nkey , /* IN: Word length of key */
+ unsigned key[] ) /* OUT: space-filling curve key */
+{
+ static int init = 0 ;
+ static unsigned char gray_inv[ 2 * 2 ] ;
+
+ const unsigned NKey = ( 2 < nkey ) ? 2 : (nkey) ;
+ const unsigned NBits = ( MaxBits * NKey ) / 2 ;
+
+ unsigned i ;
+ unsigned char order[2+2] ;
+ unsigned char reflect ;
+
+ /* GRAY coding */
+
+ if ( ! init ) {
+ unsigned char gray[ 2 * 2 ] ;
+ register unsigned k ;
+ register unsigned j ;
+
+ gray[0] = 0 ;
+ for ( k = 1 ; k < sizeof(gray) ; k <<= 1 ) {
+ for ( j = 0 ; j < k ; j++ ) gray[k+j] = k | gray[k-(j+1)] ;
+ }
+ for ( k = 0 ; k < sizeof(gray) ; k++ ) gray_inv[ gray[k] ] = k ;
+ init = 1 ;
+ }
+
+ /* Zero out the key */
+
+ for ( i = 0 ; i < NKey ; ++i ) key[i] = 0 ;
+
+ order[0] = 0 ;
+ order[1] = 1 ;
+ reflect = ( 0 << 0 ) | ( 0 );
+
+ for ( i = 1 ; i <= NBits ; i++ ) {
+ const unsigned s = MaxBits - i ;
+ const unsigned c = gray_inv[ reflect ^ (
+ ( ( ( coord[0] >> s ) & 01 ) << order[0] ) |
+ ( ( ( coord[1] >> s ) & 01 ) << order[1] ) ) ];
+
+ const unsigned off = 2 * i ; /* Bit offset */
+ const unsigned which = off / MaxBits ; /* Which word to update */
+ const unsigned shift = MaxBits - off % MaxBits ; /* Which bits to update */
+
+ /* Set the two bits */
+
+ if ( shift == MaxBits ) { /* Word boundary */
+ key[ which - 1 ] |= c ;
+ }
+ else {
+ key[ which ] |= c << shift ;
+ }
+
+ /* Determine the recursive quadrant */
+
+ switch( c ) {
+ case 3:
+ reflect ^= 03 ;
+ case 0:
+ order[2+0] = order[0] ;
+ order[2+1] = order[1] ;
+ order[0] = order[2+1] ;
+ order[1] = order[2+0] ;
+ break ;
+ }
+ }
+}
+
+/*--------------------------------------------------------------------*/
+/* 3D Hilbert Space-filling curve */
+
+void hsfc3d(
+ unsigned coord[] , /* IN: Normalized integer coordinates */
+ unsigned nkey , /* IN: Word length of 'key' */
+ unsigned key[] ) /* OUT: space-filling curve key */
+{
+ static int init = 0 ;
+ static unsigned char gray_inv[ 2*2*2 ] ;
+
+ const unsigned NKey = ( 3 < nkey ) ? 3 : (nkey) ;
+ const unsigned NBits = ( MaxBits * NKey ) / 3 ;
+
+ unsigned i ;
+ unsigned char axis[3+3] ;
+
+ /* GRAY coding */
+
+ if ( ! init ) {
+ unsigned char gray[ 2*2*2 ] ;
+ register unsigned k ;
+ register unsigned j ;
+
+ gray[0] = 0 ;
+ for ( k = 1 ; k < sizeof(gray) ; k <<= 1 ) {
+ for ( j = 0 ; j < k ; j++ ) gray[k+j] = k | gray[k-(j+1)] ;
+ }
+ for ( k = 0 ; k < sizeof(gray) ; k++ ) gray_inv[ gray[k] ] = k ;
+ init = 1 ;
+ }
+
+ /* Zero out the key */
+
+ for ( i = 0 ; i < NKey ; ++i ) key[i] = 0 ;
+
+ axis[0] = 0 << 1 ;
+ axis[1] = 1 << 1 ;
+ axis[2] = 2 << 1 ;
+
+ for ( i = 1 ; i <= NBits ; i++ ) {
+ const unsigned s = MaxBits - i ;
+ const unsigned c = gray_inv[
+ (((( coord[ axis[0] >> 1 ] >> s ) ^ axis[0] ) & 01 ) << 0 ) |
+ (((( coord[ axis[1] >> 1 ] >> s ) ^ axis[1] ) & 01 ) << 1 ) |
+ (((( coord[ axis[2] >> 1 ] >> s ) ^ axis[2] ) & 01 ) << 2 ) ];
+ unsigned n ;
+
+ /* Set the 3bits */
+
+ for ( n = 0 ; n < 3 ; ++n ) {
+ const unsigned bit = 01 & ( c >> ( 2 - n ) ); /* Bit value */
+ const unsigned off = 3 * i + n ; /* Bit offset */
+ const unsigned which = off / MaxBits ; /* Which word */
+ const unsigned shift = MaxBits - off % MaxBits ; /* Which bits */
+
+ if ( MaxBits == shift ) { /* Word boundary */
+ key[ which - 1 ] |= bit ;
+ }
+ else {
+ key[ which ] |= bit << shift ;
+ }
+ }
+
+ /* Determine the recursive quadrant */
+
+ axis[3+0] = axis[0] ;
+ axis[3+1] = axis[1] ;
+ axis[3+2] = axis[2] ;
+
+ switch( c ) {
+ case 0:
+ axis[0] = axis[3+2];
+ axis[1] = axis[3+1];
+ axis[2] = axis[3+0];
+ break ;
+ case 1:
+ axis[0] = axis[3+0];
+ axis[1] = axis[3+2];
+ axis[2] = axis[3+1];
+ break ;
+ case 2:
+ axis[0] = axis[3+0];
+ axis[1] = axis[3+1];
+ axis[2] = axis[3+2];
+ break ;
+ case 3:
+ axis[0] = axis[3+2] ^ 01 ;
+ axis[1] = axis[3+0] ^ 01 ;
+ axis[2] = axis[3+1];
+ break ;
+ case 4:
+ axis[0] = axis[3+2];
+ axis[1] = axis[3+0] ^ 01 ;
+ axis[2] = axis[3+1] ^ 01 ;
+ break ;
+ case 5:
+ axis[0] = axis[3+0];
+ axis[1] = axis[3+1];
+ axis[2] = axis[3+2];
+ break ;
+ case 6:
+ axis[0] = axis[3+0];
+ axis[1] = axis[3+2] ^ 01 ;
+ axis[2] = axis[3+1] ^ 01 ;
+ break ;
+ case 7:
+ axis[0] = axis[3+2] ^ 01 ;
+ axis[1] = axis[3+1];
+ axis[2] = axis[3+0] ^ 01 ;
+ break ;
+ default:
+ exit(-1);
+ }
+ }
+}
+
+/*--------------------------------------------------------------------*/
+
+void fhsfc2d(
+ double coord[] , /* IN: Normalized floating point coordinates */
+ unsigned nkey , /* IN: Word length of key */
+ unsigned key[] ) /* OUT: space-filling curve key */
+{
+ const double imax = ~(0u);
+ unsigned c[2] ;
+ c[0] = coord[0] * imax ;
+ c[1] = coord[1] * imax ;
+ hsfc2d( c , nkey , key );
+}
+
+void fhsfc3d(
+ double coord[] , /* IN: Normalized floating point coordinates */
+ unsigned nkey , /* IN: Word length of key */
+ unsigned key[] ) /* OUT: space-filling curve key */
+{
+ const double imax = ~(0u);
+ unsigned c[3] ;
+ c[0] = coord[0] * imax ;
+ c[1] = coord[1] * imax ;
+ c[2] = coord[2] * imax ;
+ hsfc3d( c , nkey , key );
+}
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hsfc.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/hsfc.h?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hsfc.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hsfc.h Sun Sep 3 20:10:18 2017
@@ -0,0 +1,86 @@
+/* ---------------------------------------------------------------------
+Author: H. Carter Edwards
+ hcedwar at sandia.gov
+
+Copyright: Copyright (C) 1997 H. Carter Edwards
+ Graduate Student
+ University of Texas
+
+Re-release: Copyright (C) 2011-2012 H. Carter Edwards
+
+Purpose: Domain paritioning based upon Hilbert Space-Filling Curve
+ ordering.
+
+License: Re-release under the less-restrictive CLAMR software terms.
+ Permitted by email with H. Carter Edwards on 9/13/2011
+
+Disclaimer:
+
+ These routines comes with ABSOLUTELY NO WARRANTY;
+ This is free software, and you are welcome to redistribute it
+ under certain conditions. See License terms in file 'LICENSE'.
+--------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------
+Description:
+ Inverse of the Hilbert Space-Filling Curve Map from a 2D or 3D
+domain to the 1D domain. Two different 2D and 3D domains are
+supported.
+
+For the routines 'hsfc2d' and 'hsfc3d' the 2D and 3D domains are
+defined as follows.
+Note that
+ * 0 is the minimum value of an unsigned integer
+ * ~(0u) is the maximum value of an unsigned integer - all bits set
+thus the 2D and 3D domains are
+ * [0,~(0u)] x [0,~(0u)]
+ * [0,~(0u)] x [0,~(0u)] x [0,~(0u)]
+respectively.
+
+For the routines 'fhsfc2d' and 'fhsfc3d' the 2D and 3D domains are
+defines as:
+ * [0.0,1.0] x [0.0,1.0]
+ * [0.0,1.0] x [0.0,1.0] x [0.0,1.0]
+respectively.
+
+The 1D domain is a multiword (array of unsigned integers) key.
+This key is essentially an unsigned integer of an arbitrary
+number of bits. The most significant bit is the leading bit
+of the first (0th) word of the key. The least significant
+bit is the trailing bit of the last word.
+
+----------------------------------------------------------------------*/
+
+#ifndef __HILBERT_SPACE_FILLING_CURVE_MAPPING__
+#define __HILBERT_SPACE_FILLING_CURVE_MAPPING__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void hsfc2d(
+ unsigned coord[] , /* IN: Normalized integer 2D coordinate */
+ unsigned nkey , /* IN: Word length of key */
+ unsigned key[] ); /* OUT: space-filling curve key */
+
+extern void hsfc3d(
+ unsigned coord[] , /* IN: Normalized integer 3D coordinate */
+ unsigned nkey , /* IN: Word length of 'key' */
+ unsigned key[] ); /* OUT: space-filling curve key */
+
+extern void fhsfc2d(
+ double coord[] , /* IN: Normalized floating point 2D coordinate */
+ unsigned nkey , /* IN: Word length of key */
+ unsigned key[] ); /* OUT: space-filling curve key */
+
+extern void fhsfc3d(
+ double coord[] , /* IN: Normalized floating point 3D coordinate */
+ unsigned nkey , /* IN: Word length of key */
+ unsigned key[] ); /* OUT: space-filling curve key */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hsfcsort.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/hsfcsort.c?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hsfcsort.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/hsfcsort.c Sun Sep 3 20:10:18 2017
@@ -0,0 +1,268 @@
+/* ---------------------------------------------------------------------
+Author: H. Carter Edwards
+ hcedwar at sandia.gov
+
+Copyright: Copyright (C) 1997 H. Carter Edwards
+ Graduate Student
+ University of Texas
+
+Re-release: Copyright (C) 2011-2012 H. Carter Edwards
+
+Purpose: Domain paritioning based upon Hilbert Space-Filling Curve
+ ordering.
+
+License: Re-release under the less-restrictive CLAMR software terms.
+ Permitted by email with H. Carter Edwards on 9/13/2011
+
+Disclaimer:
+
+ These routines comes with ABSOLUTELY NO WARRANTY;
+ This is free software, and you are welcome to redistribute it
+ under certain conditions. See License terms in file 'LICENSE'.
+--------------------------------------------------------------------- */
+
+#include <limits.h>
+#include <stdlib.h>
+
+#include "hsfc.h"
+
+/*--------------------------------------------------------------------*/
+/* Make it callable from FORTRAN:
+ * Interface types: INTEGER and REAL*8
+ */
+
+void hsfc2sort(
+ const int N , /* IN: Number of points */
+ const double * X , /* IN: array of X-Coordinates */
+ const double * Y , /* IN: array of Y-Coordinates */
+ const int ibase, /* 0 for C and 1 for Fortran */
+ int * Info , /* OUT: (1 <= LDInfo) [ HSFC ordering ]
+ (2 <= LDInfo) [ HSFC index, #1 ]
+ (3 <= LDInfo) [ HSFC index, #2 ] */
+ int LDInfo /* IN: Leading dimension of Info */
+ );
+
+/*--------------------------------------------------------------------*/
+
+#define MaxBits ( sizeof(unsigned) * CHAR_BIT )
+
+#define NBITC (32) /* 32 Bits per coordinate, resolve data at 2^31 */
+#define NKEY(ND) ((NBITC * ND + MaxBits - 1) / MaxBits)
+
+/*--------------------------------------------------------------------*/
+
+static int ui1comp( const void * const I1 , const void * const I2 )
+{
+ return (
+ ( ((const unsigned *)I1)[0] != ((const unsigned *)I2)[0] ) ? (
+ ( ((const unsigned *)I1)[0] < ((const unsigned *)I2)[0] ) ? -1 : 1 ) : (
+ 0 ));
+}
+
+static int ui2comp( const void * const I1 , const void * const I2 )
+{
+ return (
+ ( ((const unsigned *)I1)[0] != ((const unsigned *)I2)[0] ) ? (
+ ( ((const unsigned *)I1)[0] < ((const unsigned *)I2)[0] ) ? -1 : 1 ) : (
+ ( ((const unsigned *)I1)[1] != ((const unsigned *)I2)[1] ) ? (
+ ( ((const unsigned *)I1)[1] < ((const unsigned *)I2)[1] ) ? -1 : 1 ) : (
+ 0 )));
+}
+
+/*--------------------------------------------------------------------*/
+
+static int ui3comp( const void * const I1 , const void * const I2 )
+{
+ return (
+ ( ((const unsigned *)I1)[0] != ((const unsigned *)I2)[0] ) ? (
+ ( ((const unsigned *)I1)[0] < ((const unsigned *)I2)[0] ) ? -1 : 1 ) : (
+ ( ((const unsigned *)I1)[1] != ((const unsigned *)I2)[1] ) ? (
+ ( ((const unsigned *)I1)[1] < ((const unsigned *)I2)[1] ) ? -1 : 1 ) : (
+ ( ((const unsigned *)I1)[2] != ((const unsigned *)I2)[2] ) ? (
+ ( ((const unsigned *)I1)[2] < ((const unsigned *)I2)[2] ) ? -1 : 1 ) : (
+ 0 ))));
+}
+
+static int N_uiNcomp = 0 ;
+
+static int uiNcomp( const void * const I1 , const void * const I2 )
+{
+ const int N = N_uiNcomp ;
+ register int i ;
+
+ for ( i = 0 ; i < N &&
+ ((const unsigned *)I1)[i] != ((const unsigned *)I2)[i] ; ++i );
+
+ return ( i < N ) ? (
+ ( ((const unsigned *)I1)[i] < ((const unsigned *)I2)[i] ) ? -1 : 1 ) : 0 ;
+}
+
+/*--------------------------------------------------------------------*/
+
+void hsfc2sort(
+ const int N , /* IN: Number of points */
+ const double * X , /* IN: array of X-Coordinates */
+ const double * Y , /* IN: array of Y-Coordinates */
+ const int ibase, /* 0 for C and 1 for Fortran */
+ int * Info , /* OUT: (1 <= LDInfo) [ HSFC ordering ]
+ (2 <= LDInfo) [ HSFC index, #1 ]
+ (3 <= LDInfo) [ HSFC index, #2 ] */
+ int LDInfo )/* IN: Leading dimension of Info */
+{
+ /*------------------------------------------------------------------*/
+
+ const double imax = ((double) ~(0u)) ;
+
+ const unsigned ldinfo = LDInfo ;
+ const unsigned long long npt = N ;
+ const unsigned nkey = NKEY(2) ;
+ const unsigned ldT = nkey + 1 ;
+
+ unsigned * const T = (unsigned *) malloc( sizeof(unsigned) * ldT * npt );
+
+ int i , ix , iy , ii , it ;
+
+ /* Fill SFC table */
+
+ for ( i = it = ix = iy = 0 ; (unsigned long long)i < npt ;
+ ++i , ix++ , iy++ , it += ldT ) {
+ double xy[2] ;
+ unsigned coord[2] ;
+
+ xy[0] = X[ix] ;
+ xy[1] = Y[iy] ;
+
+ coord[0] = xy[0] * imax ;
+ coord[1] = xy[1] * imax ;
+
+ hsfc2d( coord , nkey , T + it );
+ T[it+nkey] = i ;
+ }
+
+ /* SFC Key output */
+
+ if ( 2 < ldinfo && 1 < nkey ) {
+ for ( ii = 1, it = 0, i = 0 ; (unsigned long long)i < npt ; ++i, ii += ldinfo, it += ldT ) {
+ Info[ii] = T[it];
+ Info[ii+1] = T[it+1];
+ }
+ }
+ else if ( 1 < ldinfo ) {
+ for ( ii = 1, it = 0 ,i = 0 ; (unsigned long long)i < npt ; ++i, ii += ldinfo, it += ldT ) {
+ Info[ii] = T[it] ;
+ }
+ }
+
+ /* Sort */
+
+ switch ( nkey ) {
+ case 0: break ;
+ case 1: qsort( T , npt , sizeof(unsigned) * ldT , ui1comp ); break ;
+ case 2: qsort( T , npt , sizeof(unsigned) * ldT , ui2comp ); break ;
+ case 3: qsort( T , npt , sizeof(unsigned) * ldT , ui3comp ); break ;
+ default:
+ N_uiNcomp = nkey ;
+ qsort( T , npt , sizeof(unsigned) * ldT , uiNcomp );
+ N_uiNcomp = 0 ;
+ break ;
+ }
+
+ for (ii = 0, i = 0, it = nkey ; (unsigned long long)i < npt ; ++i, ii += ldinfo, it += ldT) {
+ Info[ii] = T[it] + ibase; /* 1 -- FORTRAN convention, 0 -- C */
+ }
+
+ free( (void *) T );
+
+ return ;
+}
+
+/*--------------------------------------------------------------------*/
+
+void hsfc3sort(
+ const int N , /* IN: Number of points */
+ const double * X , /* IN: array of X-Coordinates */
+ const double * Y , /* IN: array of Y-Coordinates */
+ const double * Z , /* IN: array of Y-Coordinates */
+ const int ibase , /* IN: Stride for Y array */
+ int * Info , /* OUT: (1 <= LDInfo) [ HSFC ordering ]
+ (2 <= LDInfo) [ HSFC index, #1 ]
+ (3 <= LDInfo) [ HSFC index, #2 ]
+ (4 <= LDInfo) [ HSFC index, #3 ] */
+ int LDInfo )/* IN: Leading dimension of Info */
+{
+ /*------------------------------------------------------------------*/
+
+ const double imax = ((double) ~(0u)) ;
+
+ const unsigned ldinfo = LDInfo ;
+ const unsigned long long npt = N ;
+ const unsigned nkey = NKEY(3) ;
+ const unsigned ldT = nkey + 1 ;
+
+ unsigned * const T = (unsigned *) malloc( sizeof(unsigned) * ldT * npt );
+
+ int i , ix , iy , iz , ii , it ;
+
+ /* Fill SFC table */
+
+ for ( i = it = ix = iy = iz = 0 ; (unsigned long long)i < npt ;
+ ++i , ix++ , iy++ , iz++ , it += ldT ) {
+ double xyz[3] ;
+ unsigned coord[3] ;
+
+ xyz[0] = X[ix] ;
+ xyz[1] = Y[iy] ;
+ xyz[2] = Z[iz] ;
+
+ coord[0] = xyz[0] * imax ;
+ coord[1] = xyz[1] * imax ;
+ coord[2] = xyz[2] * imax ;
+
+ hsfc3d( coord , nkey , T + it );
+ T[it+nkey] = i ;
+ }
+
+ /* SFC Key output */
+
+ if ( 3 < ldinfo && 2 < nkey ) {
+ for ( ii = 1, it = 0, i = 0 ; (unsigned long long)i < npt ; ++i, ii += ldinfo, it += ldT ) {
+ Info[ii] = T[it];
+ Info[ii+1] = T[it+1];
+ Info[ii+2] = T[it+2];
+ }
+ }
+ else if ( 2 < ldinfo && 1 < nkey ) {
+ for ( ii = 1, it = 0, i = 0 ; (unsigned long long)i < npt ; ++i, ii += ldinfo, it += ldT ) {
+ Info[ii] = T[it];
+ Info[ii+1] = T[it+1];
+ }
+ }
+ else if ( 1 < ldinfo ) {
+ for ( ii = 1, it = 0 ,i = 0 ; (unsigned long long)i < npt ; ++i, ii += ldinfo, it += ldT ) {
+ Info[ii] = T[it] ;
+ }
+ }
+
+ /* Sort */
+
+ switch ( nkey ) {
+ case 0: break ;
+ case 1: qsort( T , npt , sizeof(unsigned) * ldT , ui1comp ); break ;
+ case 2: qsort( T , npt , sizeof(unsigned) * ldT , ui2comp ); break ;
+ case 3: qsort( T , npt , sizeof(unsigned) * ldT , ui3comp ); break ;
+ default:
+ N_uiNcomp = nkey ;
+ qsort( T , npt , sizeof(unsigned) * ldT , uiNcomp );
+ N_uiNcomp = 0 ;
+ break ;
+ }
+
+ for (ii = 0, i = 0, it = nkey ; (unsigned long long)i < npt ; ++i, ii += ldinfo, it += ldT) {
+ Info[ii] = T[it] + ibase ; /* FORTRAN convention */
+ }
+
+ free( (void *) T );
+
+ return ;
+}
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/input.cpp
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/input.cpp?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/input.cpp (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/input.cpp Sun Sep 3 20:10:18 2017
@@ -0,0 +1,513 @@
+/*
+ * Copyright (c) 2011-2012, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ * This research code is being developed as part of the
+ * 2011 X Division Summer Workshop for the express purpose
+ * of a collaborative code for development of ideas in
+ * the implementation of AMR codes for Exascale platforms
+ *
+ * AMR implementation of the Wave code previously developed
+ * as a demonstration code for regular grids on Exascale platforms
+ * as part of the Supercomputing Challenge and Los Alamos
+ * National Laboratory
+ *
+ * Authors: Bob Robey XCP-2 brobey at lanl.gov
+ * Neal Davis davis68 at lanl.gov, davis68 at illinois.edu
+ * David Nicholaeff dnic at lanl.gov, mtrxknight at aol.com
+ * Dennis Trujillo dptrujillo at lanl.gov, dptru10 at gmail.com
+ *
+ *
+ * This file and the associated header is based on a file from the capablanca
+ * project available under the MIT open-source license. As author of that code,
+ * I, Neal Davis, permit repurposing and redistribution for CLAMR under the New
+ * BSD License used above.
+ * http://code.google.com/p/capablanca/
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "state.h"
+#include "partition.h"
+#include "mesh.h"
+#include "hash.h"
+#include "crux.h"
+//#include "graphics/display.h"
+#include "graphics.h"
+
+#include <fstream>
+#include <iostream>
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <sys/stat.h>
+#include <limits.h>
+
+#define OUTPUT_INTERVAL 100
+#define COARSE_GRID_RES 128
+#define MAX_TIME_STEP 3000
+
+using namespace std;
+
+// Global variables.
+char progName[12]; // Program name.
+char progVers[8]; // Program version.
+
+// External global variables.
+extern bool verbose,
+ localStencil,
+ outline,
+ face_based,
+ dynamic_load_balance_on,
+ h5_spoutput,
+ restart;
+extern int outputInterval,
+ crux_type,
+ enhanced_precision_sum,
+ tmax,
+ levmx,
+ nx,
+ ny,
+ niter,
+ measure_type,
+ lttrace_on,
+ do_quo_setup,
+ calc_neighbor_type,
+ choose_hash_method,
+ initial_order,
+ graphic_outputInterval,
+ graphics_type,
+ checkpoint_outputInterval,
+ neighbor_remap,
+ num_of_rollback_states,
+ cycle_reorder;
+extern float
+ mem_opt_factor;
+extern double
+ upper_mass_diff_percentage;
+
+extern char* restart_file;
+
+void outputHelp()
+{ cout << "CLAMR is an experimental adaptive mesh refinement code for the GPU." << endl
+ #ifdef PACKAGE_VERSION
+ << "Version is " << PACKAGE_VERSION << endl << endl
+ #endif
+ << "Usage: " << progName << " [options]..." << endl
+ << " -b <B> Number of rollback images, disk or in memory (default 2);" << endl
+ << " -c <C> Checkpoint to disk at interval specified;" << endl
+ << " -C <C> Checkpoint to memory at interval specified;" << endl
+ << " -d turn on LTTRACE;" << endl
+ << " -D turn on dynamic load balancing using LTTRACE;" << endl
+ << " -e <E> force hash_method, ie linear, quadratic..." <<endl
+ << " \"perfect\"" << endl
+ << " \"linear\"" << endl
+ << " \"quadratic\"" << endl
+ << " \"prime_jump\"" << endl
+ << " -f face-based finite difference;" << endl
+ << " -g <g> specify I step between saving graphics information for post processing;" << endl
+ << " -G <G> specify graphics file type for post processing;" << endl
+ << " \"bmp\"" << endl
+ << " \"gif\"" << endl
+ << " \"jpeg\"" << endl
+ << " \"mpeg\"" << endl
+ << " \"pdf\"" << endl
+ << " \"png\"" << endl
+ << " \"svg\"" << endl
+ << " \"data\"" << endl
+ << " -h display this help message;" << endl
+ << " -i <I> specify I steps between output files;" << endl
+ << " -l <l> max number of levels;" << endl
+ << " -M <M> memory optimization factor 1.0 <= M <=100.0 (default 1.0 -- represents 1/20 perfect hash);" << endl
+ << " -m <m> specify partition measure type;" << endl
+ << " \"with_duplicates\"" << endl
+ << " \"without_duplicates\"" << endl
+ << " -N <n> specify calc neighbor type;" << endl
+ << " \"hash_table\"" << endl
+ << " \"kdtree\"" << endl
+ << " -n <N> specify coarse grid resolution of NxN;" << endl
+ << " -o turn off outlines;" << endl
+ << " -P <P> specify initial order P;" << endl
+ << " \"original_order\"" << endl
+ << " \"hilbert_sort\"" << endl
+ << " \"hilbert_partition\"" << endl
+ << " \"z_order\"" << endl
+ << " -p <p> specify ordering P every cycle;" << endl
+ << " \"original_order\"" << endl
+ << " \"hilbert_sort\"" << endl
+ << " \"hilbert_partition\"" << endl
+ << " \"local_hilbert\"" << endl
+ << " \"local_fixed\"" << endl
+ << " \"z_order\"" << endl
+ << " -q turn on quo;" << endl
+ << " -r regular sum instead of enhanced precision sum (Kahan sum);" << endl
+ << " -R restart simulation from the backup file specified;" << endl
+ << " -s <s> specify space-filling curve method S;" << endl
+ << " -S write out double precision data as single precision;" << endl
+ << " -T execute with TVD;" << endl
+ << " -t <t> specify T time steps to run;" << endl
+ << " -u allowed percentage of difference between total mass between iterations." << endl
+ << " the default value for this parameter is 2.6e-13;" << endl
+ << " -V use verbose output;" << endl
+ << " -v display version information." << endl
+ << " -z force recalculation of neighbors." << endl; }
+
+void outputVersion()
+{ cout << progName << " " << progVers << endl; }
+
+/* parseInput(const int argc, char** argv)
+ *
+ * Interpret the command line input.
+ */
+void parseInput(const int argc, char** argv)
+{ strcpy(progName, "clamr");
+ #ifdef PACKAGE_VERSION
+ strcpy(progVers, PACKAGE_VERSION);
+ #endif
+ // Reconstruct command line argument as a string.
+ char progCL[256]; // Complete program command line.
+ strcpy(progCL, argv[0]);
+ for (int i = 1; i < argc; i++)
+ { strcat(progCL, " ");
+ strcat(progCL, argv[i]); }
+
+ // Set variables to defaults, which may be overridden by CLI.
+ verbose = false;
+ localStencil = true;
+ outline = true;
+#ifdef HAVE_LTTRACE
+ lttrace_on = 0;
+#endif
+#ifdef HAVE_QUO
+ do_quo_setup = 0;
+#endif
+ dynamic_load_balance_on = false;
+ crux_type = CRUX_NONE;
+ face_based = false;
+ restart = false;
+ restart_file = NULL;
+ outputInterval = OUTPUT_INTERVAL;
+ nx = COARSE_GRID_RES;
+ ny = COARSE_GRID_RES;
+ niter = MAX_TIME_STEP;
+ neighbor_remap = true;
+ //measure_type = CSTARVALUE;
+ measure_type = NO_PARTITION_MEASURE;
+ calc_neighbor_type = HASH_TABLE;
+ choose_hash_method = METHOD_UNSET;
+ initial_order = HILBERT_SORT;
+ cycle_reorder = ORIGINAL_ORDER;
+ graphic_outputInterval = INT_MAX;
+ graphics_type = GRAPHICS_NONE;
+ checkpoint_outputInterval = INT_MAX;
+ num_of_rollback_states = 2;
+ levmx = 1;
+ mem_opt_factor = 1.0;
+ upper_mass_diff_percentage = -1.0;
+ enhanced_precision_sum = SUM_KAHAN;
+
+ char *val;
+ if (argc > 1)
+ { int i = 1;
+ val = strtok(argv[i++], " ,.-");
+ while (val != NULL){
+ switch (val[0]){
+ case 'b': // Number of rollback images, disk or in memory (default 2)
+ sprintf(val,"0");
+ if (i < argc) val = strtok(argv[i++], " ,");
+ if(atoi(val) < 1){
+ printf("backup number must be at least 1, setting to default value 2\n");
+ }
+ else{
+ num_of_rollback_states = atoi(val);
+ }
+ break;
+ case 'c': // Checkpoint to disk at interval specified
+ val = strtok(argv[i++], " ,.-");
+ checkpoint_outputInterval = atoi(val);
+ crux_type = CRUX_DISK;
+ break;
+
+ case 'C': // Checkpoint to memory at interval specified
+ val = strtok(argv[i++], " ,.-");
+ checkpoint_outputInterval = atoi(val);
+ crux_type = CRUX_IN_MEMORY;
+ break;
+
+ case 'd': // Turn on lttrace.
+ // This is provided as a separate option to measure
+ // the overhead of having lttrace on.
+#ifdef HAVE_LTTRACE
+ lttrace_on = 1;
+#endif
+ break;
+
+ case 'D': // Turn on dynamic load balancing.
+ // This forces on lttrace.
+#ifdef HAVE_LTTRACE
+ lttrace_on = true;
+ dynamic_load_balance_on = true;
+#endif
+ break;
+
+ case 'e': // hash method specified.
+ val = strtok(argv[i++], " ,");
+ if (! strcmp(val,"perfect") ) {
+ choose_hash_method = PERFECT_HASH;
+ } else if (! strcmp(val,"linear") ) {
+ choose_hash_method = LINEAR;
+ } else if (! strcmp(val,"quadratic") ) {
+ choose_hash_method = QUADRATIC;
+ } else if (! strcmp(val,"prime_jump") ) {
+ choose_hash_method = PRIME_JUMP;
+ }
+ break;
+
+ case 'f': // Use face-based finite difference
+ face_based = true;
+ break;
+
+ case 'g': // Save graphics data to files during simulation.
+ val = strtok(argv[i++], " ,.-");
+ graphic_outputInterval = atoi(val);
+ if (graphics_type == GRAPHICS_NONE) graphics_type = GRAPHICS_DATA;
+ break;
+
+ case 'G': // Graphics data file type.
+ val = strtok(argv[i++], " ,.-");
+ if (! strcmp(val,"none") ) {
+ graphics_type = GRAPHICS_NONE;
+ graphic_outputInterval = INT_MAX;
+ } else if (! strcmp(val,"data") ) {
+ graphics_type = GRAPHICS_DATA;
+#ifdef HAVE_MAGICKWAND
+ } else if (! strcmp(val,"bmp") ) {
+ graphics_type = GRAPHICS_BMP;
+ } else if (! strcmp(val,"gif") ) {
+ graphics_type = GRAPHICS_GIF;
+ } else if (! strcmp(val,"jpeg") ) {
+ graphics_type = GRAPHICS_JPEG;
+ } else if (! strcmp(val,"mpeg") ) {
+ graphics_type = GRAPHICS_MPEG;
+ } else if (! strcmp(val,"pdf") ) {
+ graphics_type = GRAPHICS_PDF;
+ } else if (! strcmp(val,"png") ) {
+ graphics_type = GRAPHICS_PNG;
+ } else if (! strcmp(val,"svg") ) {
+ graphics_type = GRAPHICS_SVG;
+#endif
+ } else {
+ printf("Unrecognized option for graphics file type %s\n",val);
+ exit(-1);
+ }
+ break;
+
+ case 'h': // Output help.
+ outputHelp();
+ cout.flush();
+ exit(EXIT_SUCCESS);
+ break;
+
+ case 'i': // Output interval specified.
+ val = strtok(argv[i++], " ,.-");
+ outputInterval = atoi(val);
+ break;
+
+ case 'l': // max level specified.
+ val = strtok(argv[i++], " ,");
+ levmx = atoi(val);
+ break;
+
+ case 'M': // memory optimization factor
+ val = strtok(argv[i++], " ,");
+ mem_opt_factor = atof(val);
+ break;
+
+ case 'm': // partition measure specified.
+ val = strtok(argv[i++], " ,");
+ if (! strcmp(val,"no_partition_measure") ) {
+ measure_type = NO_PARTITION_MEASURE;
+ } else if (! strcmp(val,"with_duplicates") ) {
+ measure_type = WITH_DUPLICATES;
+ } else if (! strcmp(val,"without_duplicates") ) {
+ measure_type = WITHOUT_DUPLICATES;
+ } else if (! strcmp(val,"cvalue") ) {
+ measure_type = CVALUE;
+ } else if (! strcmp(val,"cstarvalue") ) {
+ measure_type = CSTARVALUE;
+ }
+ break;
+
+ case 'N': // calc neighbor type specified.
+ val = strtok(argv[i++], " ,");
+ if (! strcmp(val,"hash_table") ) {
+ calc_neighbor_type = HASH_TABLE;
+ } else if (! strcmp(val,"kdtree") ) {
+ calc_neighbor_type = KDTREE;
+ }
+ break;
+
+ case 'n': // Domain grid resolution specified.
+ val = strtok(argv[i++], " ,");
+ nx = atoi(val);
+ ny = nx;
+ break;
+
+ case 'o': // Turn off outlines on mesh drawing.
+ outline = false;
+ break;
+
+ case 'P': // Initial order specified.
+ val = strtok(argv[i++], " ,");
+ if (! strcmp(val,"original_order") ) {
+ initial_order = ORIGINAL_ORDER;
+ } else if (! strcmp(val,"hilbert_sort") ) {
+ initial_order = HILBERT_SORT;
+ } else if (! strcmp(val,"hilbert_partition") ) {
+ initial_order = HILBERT_PARTITION;
+ } else if (! strcmp(val,"z_order") ) {
+ initial_order = ZORDER;
+ }
+ break;
+
+ case 'p': // Initial order specified.
+ val = strtok(argv[i++], " ,");
+ if (! strcmp(val,"original_order") ) {
+ cycle_reorder = ORIGINAL_ORDER;
+ localStencil = false;
+ } else if (! strcmp(val,"hilbert_sort") ) {
+ cycle_reorder = HILBERT_SORT;
+ localStencil = false;
+ } else if (! strcmp(val,"hilbert_partition") ) {
+ cycle_reorder = HILBERT_PARTITION;
+ localStencil = false;
+ } else if (! strcmp(val,"local_hilbert") ) {
+ cycle_reorder = ORIGINAL_ORDER;
+ localStencil = true;
+ } else if (! strcmp(val,"local_fixed") ) {
+ cycle_reorder = ORIGINAL_ORDER;
+ localStencil = false;
+ } else if (! strcmp(val,"z_order") ) {
+ cycle_reorder = ZORDER;
+ localStencil = false;
+ }
+ break;
+
+ case 'q': // turn on quo package.
+#ifdef HAVE_QUO
+ do_quo_setup = 1;
+#endif
+ break;
+
+ case 'r': // Regular sum instead of enhanced precision sum.
+ val = strtok(argv[i++], " ,");
+ if (! strcmp(val,"regular_sum") ) {
+ enhanced_precision_sum = SUM_REGULAR;
+ } else if (! strcmp(val,"kahan_sum") ) {
+ enhanced_precision_sum = SUM_KAHAN;
+ } else {
+ printf("Error with sum argument %s\n",val);
+ exit(0);
+ }
+ break;
+
+ case 'R': // Restart application from last checkpoint
+ restart = true;
+ restart_file = strtok(argv[i++], " ,");
+
+#ifndef HDF5_FF
+ struct stat stat_descriptor;
+ if (stat(restart_file,&stat_descriptor) == -1){
+ printf("Error -- restart file %s does not exist\n",restart_file);
+ exit(0);
+ }
+#endif
+ break;
+
+ case 's': // Space-filling curve method specified (default HILBERT_SORT).
+ // Add different problem setups such as sloped wave in x, y and diagonal directions to help check algorithm
+ // HILBERT_SORT
+ break;
+
+ case 'T': // TVD inclusion specified.
+ break;
+
+ case 't': // Number of time steps specified.
+ val = strtok(argv[i++], " ,.-");
+ niter = atoi(val);
+ break;
+
+ case 'u': // Allowed percentage of difference in mass per iteration
+ val = strtok(argv[i++], " ,");
+ upper_mass_diff_percentage = atof(val);
+ break;
+
+ case 'V': // Verbose output desired.
+ verbose = true;
+ break;
+
+ case 'v': // Version.
+ outputVersion();
+ cout.flush();
+ exit(EXIT_SUCCESS);
+ break;
+
+ case 'z': // Neighbor remap -- default is true, -z sets to false
+ neighbor_remap = false;
+ break;
+
+ default: // Unknown parameter encountered.
+ cout << "â Unknown input parameter " << val << endl;
+ outputHelp();
+ cout.flush();
+ exit(EXIT_FAILURE);
+ break; }
+
+ val = strtok(argv[i++], " ,.-");
+ }
+ }
+
+/*
+ if(upper_mass_diff_percentage < 0){
+ upper_mass_diff_percentage = 1.0e-12;
+ }
+*/
+}
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/input.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/input.h?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/input.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/input.h Sun Sep 3 20:10:18 2017
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2011-2012, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ * This research code is being developed as part of the
+ * 2011 X Division Summer Workshop for the express purpose
+ * of a collaborative code for development of ideas in
+ * the implementation of AMR codes for Exascale platforms
+ *
+ * AMR implementation of the Wave code previously developed
+ * as a demonstration code for regular grids on Exascale platforms
+ * as part of the Supercomputing Challenge and Los Alamos
+ * National Laboratory
+ *
+ * Authors: Bob Robey XCP-2 brobey at lanl.gov
+ * Neal Davis davis68 at lanl.gov, davis68 at illinois.edu
+ * David Nicholaeff dnic at lanl.gov, mtrxknight at aol.com
+ * Dennis Trujillo dptrujillo at lanl.gov, dptru10 at gmail.com
+ *
+ *
+ * This file and the associated header is based on a file from the capablanca
+ * project available under the MIT open-source license. As author of that code,
+ * I, Neal Davis, permit repurposing and redistribution for CLAMR under the New
+ * BSD License used above.
+ * http://code.google.com/p/capablanca/
+ */
+#ifndef _INPUT_H
+#define _INPUT_H
+
+void outputHelp();
+void outputVersion();
+void parseInput(const int argc, char** argv);
+
+#endif /* _INPUT_H */
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/memstats.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/memstats.c?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/memstats.c (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/memstats.c Sun Sep 3 20:10:18 2017
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2011-2012, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ * This research code is being developed as part of the
+ * 2011 X Division Summer Workshop for the express purpose
+ * of a collaborative code for development of ideas in
+ * the implementation of AMR codes for Exascale platforms
+ *
+ * AMR implementation of the Wave code previously developed
+ * as a demonstration code for regular grids on Exascale platforms
+ * as part of the Supercomputing Challenge and Los Alamos
+ * National Laboratory
+ *
+ * Authors: Bob Robey XCP-2 brobey at lanl.gov
+ * Neal Davis davis68 at lanl.gov, davis68 at illinois.edu
+ * David Nicholaeff dnic at lanl.gov, mtrxknight at aol.com
+ * Dennis Trujillo dptrujillo at lanl.gov, dptru10 at gmail.com
+ *
+ */
+#include <sys/time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <unistd.h>
+#include <string.h>
+
+#ifdef __APPLE_CC__
+#include <mach/mach_host.h>
+#include <mach/task.h>
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "memstats.h"
+
+pid_t pid;
+FILE *stat_fp = NULL, *meminfo_fp = NULL;
+
+long long memstats_memused(){
+ long long mem_current=0;
+#ifdef __APPLE_CC__
+/* This is all memory used and we want the memory for only our process -- do alternate
+ vm_size_t page_size;
+ mach_port_t mach_port;
+ mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
+
+ host_page_size(mach_port, &page_size);
+ vm_statistics_data_t vmstat;
+ host_statistics (mach_host_self (), HOST_VM_INFO, (host_info_t) &vmstat, &count);
+
+ mem_current = (vmstat.wire_count + vmstat.active_count + vmstat.inactive_count)*page_size/1024;
+*/
+
+ struct task_basic_info t_info;
+ mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
+ task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count);
+
+ mem_current = t_info.resident_size;
+#else
+ char proc_stat_file[50];
+ char *p;
+ int err;
+ int memdebug = 0;
+ //long long page_size = 1; //4096
+
+ if (!stat_fp){
+ pid = getpid();
+ sprintf(proc_stat_file, "/proc/%d/status", pid);
+ stat_fp = fopen(proc_stat_file, "r");
+ if (!stat_fp){
+ //printf("fopen %s failed: \n", proc_stat_file);
+ return(-1);
+ }
+ }
+
+ err = fflush(stat_fp);
+ if (err) {
+ printf("fflush %s failed: %s\n", proc_stat_file, strerror(err));
+ return(-1);
+ }
+ err = fseek(stat_fp, 0L, 0);
+ if (err) {
+ printf("fseek %s failed: %s\n", proc_stat_file, strerror(err));
+ return(-1);
+ }
+
+ char *str = (char *)malloc(140*sizeof(char));
+ while (!feof(stat_fp)){
+ str = fgets(str, 132, stat_fp);
+ if (str == NULL){
+ printf("Warning: Error in reading %s for memory stats\n",proc_stat_file);
+ }
+ p = strtok(str,":");
+ //printf("p is |%s|\n",p);
+ if (!strcmp(p, "VmRSS")) {
+ p = strtok('\0'," ");
+ p = strtok('\0'," ");
+ //mem_current = atoll(p)*1024; // Size is in kB
+ mem_current = atoll(p); // Size is in kB
+ if (memdebug) {
+ printf("VmRSS %lld\n",mem_current);
+ }
+ break;
+ }
+ }
+ free(str);
+
+ fclose(stat_fp);
+ stat_fp = NULL;
+#endif
+
+ return(mem_current);
+}
+
+long long memstats_mempeak(){
+ char proc_stat_file[50];
+ char *p;
+ int err;
+ int memdebug = 0;
+ long long mem_current=0;
+ //long long page_size = 1; //4096
+
+ if (!stat_fp){
+ pid = getpid();
+ sprintf(proc_stat_file, "/proc/%d/status", pid);
+ stat_fp = fopen(proc_stat_file, "r");
+ if (!stat_fp){
+ //printf("fopen %s failed: \n", proc_stat_file);
+ return(-1);
+ }
+ }
+
+ err = fflush(stat_fp);
+ if (err) {
+ printf("fflush %s failed: %s\n", proc_stat_file, strerror(err));
+ return(-1);
+ }
+ err = fseek(stat_fp, 0L, 0);
+ if (err) {
+ printf("fseek %s failed: %s\n", proc_stat_file, strerror(err));
+ return(-1);
+ }
+
+ char *str = (char *)malloc(140*sizeof(char));
+ while (!feof(stat_fp)){
+ str = fgets(str, 132, stat_fp);
+ if (str == NULL){
+ printf("Warning: Error in reading %s for memory stats\n",proc_stat_file);
+ }
+ p = strtok(str,":");
+ //printf("p is |%s|\n",p);
+ if (!strcmp(p, "VmHWM")) {
+ p = strtok('\0'," ");
+ p = strtok('\0'," ");
+ //mem_current = atoll(p)*1024; // Size is in kB
+ mem_current = atoll(p); // Size is in kB
+ if (memdebug) {
+ printf("VmRSS %lld\n",mem_current);
+ }
+ break;
+ }
+ }
+
+ fclose(stat_fp);
+ stat_fp = NULL;
+ free(str);
+
+ return(mem_current);
+}
+
+#define TIMER_ONEK 1024
+long long memstats_memfree(){
+ long long freemem;
+#ifdef __APPLE_CC__
+ vm_size_t page_size;
+ mach_port_t mach_port;
+ mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
+
+ mach_port = mach_host_self();
+ host_page_size(mach_port, &page_size);
+ vm_statistics64_data_t vmstat;
+ host_statistics64 (mach_port, HOST_VM_INFO, (host_info_t) &vmstat, &count);
+
+ freemem = vmstat.free_count*page_size/1024;
+#else
+ int err;
+ int memdebug = 0;
+ char buf[260];
+ char *p;
+
+ freemem = -1;
+
+ if (!meminfo_fp){
+ meminfo_fp = fopen("/proc/meminfo", "r");
+ if (!meminfo_fp){
+ printf("fopen failed: \n");
+ return(-1);
+ }
+ }
+
+ err = fflush(meminfo_fp);
+ if (err) {
+ printf("fflush failed: %s\n", strerror(err));
+ return(-1);
+ }
+ err = fseek(meminfo_fp, 0L, 0);
+ if (err) {
+ printf("fseek failed: %s\n", strerror(err));
+ return(-1);
+ }
+
+ while (!feof(meminfo_fp)) {
+ if (fgets(buf, 255, meminfo_fp)) { /* read header */
+ //printf("buf is %s\n",buf);
+ p = strtok(buf, ":");
+ if (memdebug){
+ printf("p: |%s|\n",p);
+ }
+ if (!strcmp(p, "MemFree")) {
+ p = strtok('\0', " ");
+ //printf("p is %s\n",p);
+ freemem = atoll(p); // in kB
+ break;
+ }
+ }
+ }
+
+ //return(freemem+cachedmem);
+
+ fclose(meminfo_fp);
+ meminfo_fp = NULL;
+#endif
+
+ return(freemem);
+}
+
+long long memstats_memtotal(){
+ long long totalmem;
+#ifdef __APPLE_CC__
+/*
+ vm_size_t page_size;
+ mach_port_t mach_port;
+ mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
+
+ host_page_size(mach_port, &page_size);
+ vm_statistics_data_t vmstat;
+ host_statistics (mach_host_self (), HOST_VM_INFO, (host_info_t) &vmstat, &count);
+
+ totalmem = (vmstat.wire_count + vmstat.active_count + vmstat.inactive_count + vmstat.free_count)
+ *page_size/1024;
+*/
+// alternate
+ int mib[2];
+ mib[0] = CTL_HW;
+ mib[1] = HW_MEMSIZE;
+ size_t length = sizeof(long long);
+ sysctl(mib, 2, &totalmem, &length, NULL, 0);
+ totalmem /= 1024;
+#else
+ int err;
+ int memdebug = 0;
+ char buf[260];
+ char *p;
+
+ totalmem = -1;
+
+ if (!meminfo_fp){
+ meminfo_fp = fopen("/proc/meminfo", "r");
+ if (!meminfo_fp){
+ printf("fopen failed: \n");
+ return(-1);
+ }
+ }
+
+ err = fflush(meminfo_fp);
+ if (err) {
+ printf("fflush failed: %s\n", strerror(err));
+ return(-1);
+ }
+ err = fseek(meminfo_fp, 0L, 0);
+ if (err) {
+ printf("fseek failed: %s\n", strerror(err));
+ return(-1);
+ }
+
+ while (!feof(meminfo_fp)) {
+ if (fgets(buf, 255, meminfo_fp)) { /* read header */
+ //printf("buf is %s\n",buf);
+ p = strtok(buf, ":");
+ if (memdebug){
+ printf("p: |%s|\n",p);
+ }
+ if (!strcmp(p, "MemTotal")) {
+ p = strtok('\0', " ");
+ //printf("p is %s\n",p);
+ totalmem = atoll(p); // in kB
+ break;
+ }
+ }
+ }
+
+ fclose(meminfo_fp);
+ meminfo_fp = NULL;
+#endif
+
+ return(totalmem);
+}
+
Added: test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/memstats.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C%2B%2B/CLAMR/memstats.h?rev=312463&view=auto
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/memstats.h (added)
+++ test-suite/trunk/MultiSource/Benchmarks/DOE-ProxyApps-C++/CLAMR/memstats.h Sun Sep 3 20:10:18 2017
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2011-2012, Los Alamos National Security, LLC.
+ * All rights Reserved.
+ *
+ * Copyright 2011-2012. Los Alamos National Security, LLC. This software was produced
+ * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
+ * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
+ * for the U.S. Department of Energy. The U.S. Government has rights to use,
+ * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
+ * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
+ * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
+ * to produce derivative works, such modified software should be clearly marked,
+ * so as not to confuse it with the version available from LANL.
+ *
+ * Additionally, redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Los Alamos National Security, LLC, Los Alamos
+ * National Laboratory, LANL, the U.S. Government, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE LOS ALAMOS NATIONAL SECURITY, LLC AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL
+ * SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CLAMR -- LA-CC-11-094
+ * This research code is being developed as part of the
+ * 2011 X Division Summer Workshop for the express purpose
+ * of a collaborative code for development of ideas in
+ * the implementation of AMR codes for Exascale platforms
+ *
+ * AMR implementation of the Wave code previously developed
+ * as a demonstration code for regular grids on Exascale platforms
+ * as part of the Supercomputing Challenge and Los Alamos
+ * National Laboratory
+ *
+ * Authors: Bob Robey XCP-2 brobey at lanl.gov
+ * Neal Davis davis68 at lanl.gov, davis68 at illinois.edu
+ * David Nicholaeff dnic at lanl.gov, mtrxknight at aol.com
+ * Dennis Trujillo dptrujillo at lanl.gov, dptru10 at gmail.com
+ *
+ */
+#ifndef _MEMSTATS_H
+#define _MEMSTATS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+long long memstats_memused();
+long long memstats_mempeak();
+long long memstats_memfree();
+long long memstats_memtotal();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MEMSTATS_H */
+
More information about the llvm-commits
mailing list