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