From 36bfad2be8b69b6c4b0793b639c203e530fc1209 Mon Sep 17 00:00:00 2001
From: ralfulrich <ralf.ulrich@kit.edu>
Date: Wed, 8 Aug 2018 01:14:20 +0200
Subject: [PATCH] added static process sequence

---
 Documentation/Examples/CMakeLists.txt         |   4 +
 .../Examples/staticsequence_example.cc        |  99 ++++++++++++++
 Framework/CMakeLists.txt                      |   1 +
 Framework/ProcessSequence/CMakeLists.txt      |  10 ++
 Framework/ProcessSequence/ProcessSequence.h   | 128 ++++++++++++++++++
 Framework/ProcessSequence/StaticSequence.h    | 128 ++++++++++++++++++
 Framework/Units/CMakeLists.txt                |   2 -
 7 files changed, 370 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/Examples/staticsequence_example.cc
 create mode 100644 Framework/ProcessSequence/CMakeLists.txt
 create mode 100644 Framework/ProcessSequence/ProcessSequence.h
 create mode 100644 Framework/ProcessSequence/StaticSequence.h

diff --git a/Documentation/Examples/CMakeLists.txt b/Documentation/Examples/CMakeLists.txt
index b7b574f4f..00a152fff 100644
--- a/Documentation/Examples/CMakeLists.txt
+++ b/Documentation/Examples/CMakeLists.txt
@@ -11,3 +11,7 @@ add_executable (stack_example stack_example.cc)
 target_link_libraries (stack_example CORSIKAstack CORSIKAunits CORSIKAlogging)
 install (TARGETS stack_example DESTINATION share/examples)
 
+add_executable (staticsequence_example staticsequence_example.cc)
+target_link_libraries (staticsequence_example CORSIKAstack CORSIKAprocesssequence CORSIKAunits CORSIKAlogging)
+install (TARGETS staticsequence_example DESTINATION share/examples)
+
diff --git a/Documentation/Examples/staticsequence_example.cc b/Documentation/Examples/staticsequence_example.cc
new file mode 100644
index 000000000..26d27d10b
--- /dev/null
+++ b/Documentation/Examples/staticsequence_example.cc
@@ -0,0 +1,99 @@
+#include <iostream>
+#include <iomanip>
+
+#include <ProcessSequence/ProcessSequence.h>
+
+using namespace std;
+
+
+class Process1 : public processes::Base <Process1>
+{
+public:
+  Process1() {}
+  template<typename D> void Call(D& d) const {
+    for (int i=0; i<10; ++i) d.p[i] += 1;
+  }
+};
+
+class Process2 : public processes::Base <Process2>
+{
+public:
+  Process2() {}
+   
+  template<typename D> inline void Call(D& d) const {
+    //for (int i=0; i<10; ++i) d.p[i] *= 2;
+  }
+};
+
+class Process3 : public processes::Base <Process3>
+{
+public:
+  //Process3(const int v) :fV(v) {}
+  Process3() {}
+
+  template<typename D> inline void Call(D& d) const {
+    //for (int i=0; i<10; ++i) d.p[i] += fV;
+  }
+
+private:
+  //int fV;
+};
+
+class Process4 : public processes::Base <Process4>
+{
+public:
+  //Process4(const int v) : fV(v) {}
+  Process4() {}  
+  template<typename D> inline void Call(D& d) const {
+    //for (int i=0; i<10; ++i) d.p[i] /= fV;
+  }
+
+private:
+  //int fV;
+};
+
+
+class data {
+public:
+  double p[10];
+  data() {for (int i=0; i<10; ++i) p[i] = 0; }
+};
+
+
+
+void
+modular()
+{
+  data d0;
+
+  Process1 m1;
+  Process2 m2;
+  Process3 m3;
+  Process4 m4;
+  
+  const auto sequence  = m1 + m2 + m3 + m4; 
+  
+  const int n = 100000000;
+  for (int i=0; i<n; ++i) {
+    sequence.Call(d0);    
+  }
+
+  double s = 0;
+  for (int i=0; i<10; ++i) {
+    s += d0.p[i];
+  }
+
+  cout << scientific << " v=" << s << " n=" << n << endl;
+}
+
+
+
+
+int
+main()
+{
+  modular();
+  return 0;
+}
+
+
diff --git a/Framework/CMakeLists.txt b/Framework/CMakeLists.txt
index 57e388294..bb0b41f62 100644
--- a/Framework/CMakeLists.txt
+++ b/Framework/CMakeLists.txt
@@ -4,3 +4,4 @@ add_subdirectory (Geometry)
 add_subdirectory (Logging)
 add_subdirectory (StackInterface)
 add_subdirectory (ParticleStack)
+add_subdirectory (ProcessSequence)
diff --git a/Framework/ProcessSequence/CMakeLists.txt b/Framework/ProcessSequence/CMakeLists.txt
new file mode 100644
index 000000000..966af8343
--- /dev/null
+++ b/Framework/ProcessSequence/CMakeLists.txt
@@ -0,0 +1,10 @@
+
+add_library (CORSIKAprocesssequence INTERFACE)
+
+target_include_directories (CORSIKAprocesssequence INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Framework>
+                                                   $<INSTALL_INTERFACE:include/Framework>
+                                                   )
+
+install (FILES ProcessSequence.h
+         DESTINATION include/ProcessSequence)
+
diff --git a/Framework/ProcessSequence/ProcessSequence.h b/Framework/ProcessSequence/ProcessSequence.h
new file mode 100644
index 000000000..bae3be1f8
--- /dev/null
+++ b/Framework/ProcessSequence/ProcessSequence.h
@@ -0,0 +1,128 @@
+#ifndef _include_ProcessSequence_h_
+#define _include_ProcessSequence_h_
+
+#include <iostream>
+#include <typeinfo>
+using namespace std;
+
+namespace processes {
+
+  template <typename derived>
+  struct Base 
+  {
+    const derived& GetRef() const
+    {
+      return static_cast<const derived&>(*this);
+    }
+  };
+
+
+
+  template <typename T1, typename T2>
+  class ProcessSequence : public Base <ProcessSequence<T1,T2> >
+  {
+  public:
+    const T1& A;
+    const T2& B;
+    
+    ProcessSequence(const T1& in_A, const T2& in_B)
+      : A(in_A)
+      , B(in_B)
+    { }
+    
+    template<typename D>
+      inline void Call(D& d) const { A.Call(d); B.Call(d); }
+    
+  };
+  
+
+  
+  template <typename T1, typename T2>
+  inline
+  const ProcessSequence<T1,T2>
+  operator+ (const Base<T1>& A, const Base<T2>& B)
+  {
+    return ProcessSequence<T1,T2>( A.GetRef(), B.GetRef() );
+  }
+  
+  
+  /*
+    template <typename T1>
+    struct depth_lhs
+    {
+    static const int num = 0;
+    };
+    
+
+
+    // terminating condition
+    template <typename T1, typename T2>
+    struct depth_lhs< Sequence<T1,T2> >
+    {
+    // try to expand the left node (T1) which might be a Sequence type
+    static const int num = 1 + depth_lhs<T1>::num;
+    };
+  */
+  
+
+
+
+  /*
+    template <typename T1>
+    struct mat_ptrs
+    {
+    static const int num = 0;
+    
+    inline static void
+    get_ptrs(const Process** ptrs, const T1& X)
+    {
+    ptrs[0] = reinterpret_cast<const Process*>(&X);
+    }
+    };
+    
+    
+    template <typename T1, typename T2>
+    struct mat_ptrs< Sequence<T1,T2> >
+    {
+    static const int num = 1 + mat_ptrs<T1>::num;
+    
+    inline static void
+    get_ptrs(const Process** in_ptrs, const Sequence<T1,T2>& X)
+    {
+    // traverse the left node
+    mat_ptrs<T1>::get_ptrs(in_ptrs, X.A);
+    // get address of the matrix on the right node
+    in_ptrs[num] = reinterpret_cast<const Process*>(&X.B);
+    }
+    };
+  */
+  
+  /*
+    template<typename T1, typename T2>
+    const Process&
+    Process::operator=(const Sequence<T1,T2>& X)
+    {
+    int N = 1 + depth_lhs< Sequence<T1,T2> >::num;
+    const Process* ptrs[N];
+    mat_ptrs< Sequence<T1,T2> >::get_ptrs(ptrs, X);
+    int r = ptrs[0]->rows;
+    int c = ptrs[0]->cols;
+    // ... check that all matrices have the same size ...
+    set_size(r, c);
+    for(int j=0; j<r*c; ++j)
+    {
+    double sum = ptrs[0]->data[j];
+    for(int i=1; i<N; ++i)
+    {
+    sum += ptrs[i]->data[j];
+    }
+    data[j] = sum;
+    }
+    return *this;
+    }
+  */
+
+} // end namespace
+  
+#endif
+
diff --git a/Framework/ProcessSequence/StaticSequence.h b/Framework/ProcessSequence/StaticSequence.h
new file mode 100644
index 000000000..093612cbf
--- /dev/null
+++ b/Framework/ProcessSequence/StaticSequence.h
@@ -0,0 +1,128 @@
+#ifndef _include_ProcessSequence_h_
+#define _include_ProcessSequence_h_
+
+#include <iostream>
+#include <typeinfo>
+using namespace std;
+
+namespace processes {
+
+  template <typename derived>
+  struct Base 
+  {
+    const derived& GetRef() const
+    {
+      return static_cast<const derived&>(*this);
+    }
+  };
+
+
+
+  template <typename T1, typename T2>
+  class ProcessSequence : public Base <Sequence<T1,T2>>
+  {
+  public:
+    const T1& A;
+    const T2& B;
+    
+    ProcessSequence(const T1& in_A, const T2& in_B)
+      : A(in_A)
+      , B(in_B)
+    { }
+    
+    template<class D>
+    inline void Call(D& d) const { A.Call<D>(d); B.Call<D>(d); }
+      
+  };
+  
+
+  
+  template <typename T1, typename T2>
+  inline
+  const ProcessSequence<T1,T2>
+  operator+ (const Base<T1>& A, const Base<T2>& B)
+  {
+    return ProcessSequence<T1,T2>( A.GetRef(), B.GetRef() );
+  }
+  
+  
+  /*
+    template <typename T1>
+    struct depth_lhs
+    {
+    static const int num = 0;
+    };
+    
+
+
+    // terminating condition
+    template <typename T1, typename T2>
+    struct depth_lhs< Sequence<T1,T2> >
+    {
+    // try to expand the left node (T1) which might be a Sequence type
+    static const int num = 1 + depth_lhs<T1>::num;
+    };
+  */
+  
+
+
+
+  /*
+    template <typename T1>
+    struct mat_ptrs
+    {
+    static const int num = 0;
+    
+    inline static void
+    get_ptrs(const Process** ptrs, const T1& X)
+    {
+    ptrs[0] = reinterpret_cast<const Process*>(&X);
+    }
+    };
+    
+    
+    template <typename T1, typename T2>
+    struct mat_ptrs< Sequence<T1,T2> >
+    {
+    static const int num = 1 + mat_ptrs<T1>::num;
+    
+    inline static void
+    get_ptrs(const Process** in_ptrs, const Sequence<T1,T2>& X)
+    {
+    // traverse the left node
+    mat_ptrs<T1>::get_ptrs(in_ptrs, X.A);
+    // get address of the matrix on the right node
+    in_ptrs[num] = reinterpret_cast<const Process*>(&X.B);
+    }
+    };
+  */
+  
+  /*
+    template<typename T1, typename T2>
+    const Process&
+    Process::operator=(const Sequence<T1,T2>& X)
+    {
+    int N = 1 + depth_lhs< Sequence<T1,T2> >::num;
+    const Process* ptrs[N];
+    mat_ptrs< Sequence<T1,T2> >::get_ptrs(ptrs, X);
+    int r = ptrs[0]->rows;
+    int c = ptrs[0]->cols;
+    // ... check that all matrices have the same size ...
+    set_size(r, c);
+    for(int j=0; j<r*c; ++j)
+    {
+    double sum = ptrs[0]->data[j];
+    for(int i=1; i<N; ++i)
+    {
+    sum += ptrs[i]->data[j];
+    }
+    data[j] = sum;
+    }
+    return *this;
+    }
+  */
+
+} // end namespace
+  
+#endif
+
diff --git a/Framework/Units/CMakeLists.txt b/Framework/Units/CMakeLists.txt
index f402dcb7d..16ce8b9b2 100644
--- a/Framework/Units/CMakeLists.txt
+++ b/Framework/Units/CMakeLists.txt
@@ -1,8 +1,6 @@
 
 add_library (CORSIKAunits INTERFACE)
 
-target_include_directories (CORSIKAunits INTERFACE ${PROJECT_SOURCE_DIR}/Framework)
-
 target_include_directories (CORSIKAunits INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Framework>
                                                    $<INSTALL_INTERFACE:include/Framework>
                                                    )
-- 
GitLab