LIBINT  2.6.0
uncontract.h
1 /*
2  * Copyright (C) 2004-2019 Edward F. Valeev
3  *
4  * This file is part of Libint.
5  *
6  * Libint is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Libint is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Libint. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #ifndef _libint2_src_bin_libint_uncontract_h_
22 #define _libint2_src_bin_libint_uncontract_h_
23 
24 #include <iostream>
25 #include <string>
26 #include <vector>
27 #include <stdexcept>
28 #include <cassert>
29 #include <rr.h>
30 #include <integral.h>
31 #include <iter.h>
32 #include <algebra.h>
33 #include <context.h>
34 #include <dims.h>
35 #include <bfset.h>
36 
37 using namespace std;
38 
39 
40 namespace libint2 {
41 
45  protected:
46  virtual ~Uncontract_Integral_base() {}
47  };
48 
52  template <class I>
55  public:
56  typedef I TargetType;
57  typedef TargetType ChildType;
58  typedef typename I::BasisFunctionType BFSet;
61 
62  Uncontract_Integral(const SafePtr<I>&);
63  virtual ~Uncontract_Integral() {}
64 
66  unsigned int num_children() const { return children_.size(); };
68  SafePtr<TargetType> target() const { return target_; };
70  SafePtr<ChildType> child(unsigned int i) const;
72  SafePtr<DGVertex> rr_target() const { return static_pointer_cast<DGVertex,TargetType>(target()); }
74  SafePtr<DGVertex> rr_child(unsigned int i) const { return static_pointer_cast<DGVertex,ChildType>(child(i)); }
77  bool is_simple() const {
78  return false;
79  }
80 
81  private:
82  SafePtr<TargetType> target_;
83  vector< SafePtr<ChildType> > children_;
84 
85  // contracting integrals only depends on the number of integrals in a set
86  // can simplify this to only refer to that number
87  std::string generate_label() const {
88  ostringstream os;
89  os << "Generic Contract";
90  return os.str();
91  }
92 
93  //
94  std::string spfunction_call(const SafePtr<CodeContext>& context,
95  const SafePtr<ImplicitDimensions>& dims) const;
96 
97  };
98 
99 
100  template <class I>
101  Uncontract_Integral<I>::Uncontract_Integral(const SafePtr<I>& Tint) :
102  target_(Tint)
103  {
104  target_ = Tint;
105 
106  // create the uncontracted version
107  typedef typename I::BraType bratype;
108  typedef typename I::KetType kettype;
109  typedef typename I::OperType opertype;
110  bratype bra_unc = target_->bra();
111  kettype ket_unc = target_->ket();
112  // is it even contracted?
113  bool target_is_contracted = false;
114  {
115  const unsigned int np = bra_unc.num_part();
116  for(unsigned int p=0; p<np; ++p) {
117  const unsigned int nf = bra_unc.num_members(p);
118  for(unsigned int f=0; f<nf; ++f) {
119  target_is_contracted |= bra_unc.member(p,f).contracted();
120  bra_unc.member(p,f).uncontract();
121  }
122  }
123  }
124  {
125  const unsigned int np = ket_unc.num_part();
126  for(unsigned int p=0; p<np; ++p) {
127  const unsigned int nf = ket_unc.num_members(p);
128  for(unsigned int f=0; f<nf; ++f) {
129  target_is_contracted |= ket_unc.member(p,f).contracted();
130  ket_unc.member(p,f).uncontract();
131  }
132  }
133  }
134  opertype oper_unc = target_->oper();
135  const bool oper_contracted = oper_unc.descr().contracted();
136  target_is_contracted |= oper_contracted;
137  oper_unc.descr().uncontract();
138 
139  if (target_is_contracted) {
140 #if DEBUG
141  std::cout << "Uncontract_Integral: " << target_->description() << " is contracted" << std::endl;
142 #endif
143  SafePtr<ChildType> c = ChildType::Instance(bra_unc, ket_unc,
144  target_->aux(),
145  oper_unc);
146  children_.push_back(c);
147  }
148  };
149 
150  template <class I>
151  SafePtr<typename Uncontract_Integral<I>::ChildType>
152  Uncontract_Integral<I>::child(unsigned int i) const
153  {
154  return children_.at(i);
155  };
156 
157  template <class I>
158  std::string
159  Uncontract_Integral<I>::spfunction_call(const SafePtr<CodeContext>& context,
160  const SafePtr<ImplicitDimensions>& dims) const {
161 
162  const unsigned int s = target_->size();
163  SafePtr<CTimeEntity<int> > bdim(new CTimeEntity<int>(s));
164  SafePtr<Entity> bvecdim;
165  bool vectorize = false;
166  if (!dims->vecdim_is_static()) {
167  vectorize = true;
168  SafePtr< RTimeEntity<EntityTypes::Int> > vecdim = dynamic_pointer_cast<RTimeEntity<EntityTypes::Int>,Entity>(dims->vecdim());
169  bvecdim = vecdim * bdim;
170  }
171  else {
172  SafePtr< CTimeEntity<int> > vecdim = dynamic_pointer_cast<CTimeEntity<int>,Entity>(dims->vecdim());
173  vectorize = vecdim->value() == 1 ? false : true;
174  bvecdim = vecdim * bdim;
175  }
176 
177  ostringstream os;
178  // contraction = reduction
179  if (vectorize == false || !TrivialBFSet<BFSet>::result || context->cparams()->vectorize_by_line()) {
180  os << "_libint2_static_api_inc1_short_("
181  << context->value_to_pointer(rr_target()->symbol()) << ","
182  << context->value_to_pointer(rr_child(0)->symbol()) << ","
183  << bvecdim->id()
184  << ")" << context->end_of_stat() << endl;
185  }
186  else { // blockwise vectorize for a single integral
187  os << "_libint2_static_api_inc1_short_("
188  << context->value_to_pointer(rr_target()->symbol()) << "+vi,"
189  << context->value_to_pointer(rr_child(0)->symbol()) << ",1)" << context->end_of_stat() << endl;
190  }
191  unsigned int& nflops_ref = const_cast<unsigned int&>(nflops_);
192  nflops_ref += target_->size();
193 
194  return os.str();
195  }
196 
198  struct DecontractedIntegralSet : public std::unary_function<const SafePtr<DGVertex>&,bool> {
199  bool operator()(const SafePtr<DGVertex>& V) {
200  const unsigned int outdegree = V->num_exit_arcs();
201  if (outdegree == 0) return false;
202 
203  const SafePtr<DGArc> arc0 = *(V->first_exit_arc());
204  // Is this DGArcRR?
205  const SafePtr<DGArcRR> arcrr = dynamic_pointer_cast<DGArcRR,DGArc>(arc0);
206  if (arcrr == 0) return false;
207  const SafePtr<Uncontract_Integral_base> uib_ptr = dynamic_pointer_cast<Uncontract_Integral_base,RecurrenceRelation>(arcrr->rr());
208  return uib_ptr != 0;
209  }
210  };
211 
212 };
213 
214 #endif
215 
SafePtr< DGVertex > rr_child(unsigned int i) const
Implementation of RecurrenceRelation's child()
Definition: uncontract.h:74
CTimeEntity is an Entity of type T that exists at compile-time of the generated code (hence has a val...
Definition: entity.h:186
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:24
bool is_simple() const
to inline this would require a unary operator (+=).
Definition: uncontract.h:77
Uncontract_Integral_base is dummy class used for dynamic casts only.
Definition: uncontract.h:44
RTimeEntity is an Entity of type T that exists at runtime of the generated code (hence has no value k...
Definition: entity.h:102
Entity is a base class for all objects that exist at compile or runtime of the generated code.
Definition: entity.h:81
AlgebraicOperator is an algebraic operator that acts on objects of type T.
Definition: algebra.h:48
return true if V is a decontracted IntegralSet
Definition: uncontract.h:198
RecurrenceRelation::ExprType ExprType
The type of expressions in which RecurrenceRelations result.
Definition: uncontract.h:60
unsigned int num_children() const
Implementation of RecurrenceRelation::num_children()
Definition: uncontract.h:66
SafePtr< TargetType > target() const
target() returns pointer to target
Definition: uncontract.h:68
RecurrenceRelation describes all recurrence relations.
Definition: rr.h:101
Uncontract_Integral converts (a set of) contracted integral(s) to its uncontracted counterpart.
Definition: uncontract.h:53
SafePtr< ChildType > child(unsigned int i) const
child(i) returns pointer i-th child
Definition: uncontract.h:152
const std::string & id() const
Return id string.
Definition: entity.h:86
SafePtr< DGVertex > rr_target() const
Implementation of RecurrenceRelation's target()
Definition: uncontract.h:72