LIBINT 2.9.0
uncontract.h
1/*
2 * Copyright (C) 2004-2024 Edward F. Valeev
3 *
4 * This file is part of Libint compiler.
5 *
6 * Libint compiler 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 compiler 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 compiler. 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 <algebra.h>
25#include <bfset.h>
26#include <context.h>
27#include <dims.h>
28#include <integral.h>
29#include <iter.h>
30#include <rr.h>
31
32#include <cassert>
33#include <iostream>
34#include <stdexcept>
35#include <string>
36#include <vector>
37
38namespace libint2 {
39
43 protected:
44 virtual ~Uncontract_Integral_base() {}
45};
46
51template <class I>
54 public:
55 typedef I TargetType;
56 typedef TargetType ChildType;
57 typedef typename I::BasisFunctionType BFSet;
60
61 Uncontract_Integral(const std::shared_ptr<I>&);
62 virtual ~Uncontract_Integral() {}
63
65 unsigned int num_children() const override { return children_.size(); }
67 std::shared_ptr<TargetType> target() const { return target_; };
69 std::shared_ptr<ChildType> child(unsigned int i) const;
71 std::shared_ptr<DGVertex> rr_target() const override {
72 return std::static_pointer_cast<DGVertex, TargetType>(target());
73 }
75 std::shared_ptr<DGVertex> rr_child(unsigned int i) const override {
76 return std::static_pointer_cast<DGVertex, ChildType>(child(i));
77 }
80 bool is_simple() const override { return false; }
81
82 private:
83 std::shared_ptr<TargetType> target_;
84 std::vector<std::shared_ptr<ChildType> > children_;
85
86 // contracting integrals only depends on the number of integrals in a set
87 // can simplify this to only refer to that number
88 std::string generate_label() const override {
89 std::ostringstream os;
90 os << "Generic Contract";
91 return os.str();
92 }
93
94 //
95 std::string spfunction_call(
96 const std::shared_ptr<CodeContext>& context,
97 const std::shared_ptr<ImplicitDimensions>& dims) const override;
98};
99
100template <class I>
101Uncontract_Integral<I>::Uncontract_Integral(const std::shared_ptr<I>& Tint)
102 : target_(Tint) {
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()
141 << " is contracted" << std::endl;
142#endif
143 std::shared_ptr<ChildType> c =
144 ChildType::Instance(bra_unc, ket_unc, target_->aux(), oper_unc);
145 children_.push_back(c);
146 }
147};
148
149template <class I>
150std::shared_ptr<typename Uncontract_Integral<I>::ChildType>
151Uncontract_Integral<I>::child(unsigned int i) const {
152 return children_.at(i);
153};
154
155template <class I>
157 const std::shared_ptr<CodeContext>& context,
158 const std::shared_ptr<ImplicitDimensions>& dims) const {
159 const unsigned int s = target_->size();
160 std::shared_ptr<CTimeEntity<int> > bdim(new CTimeEntity<int>(s));
161 std::shared_ptr<Entity> bvecdim;
162 bool vectorize = false;
163 if (!dims->vecdim_is_static()) {
164 vectorize = true;
165 std::shared_ptr<RTimeEntity<EntityTypes::Int> > vecdim =
166 std::dynamic_pointer_cast<RTimeEntity<EntityTypes::Int>, Entity>(
167 dims->vecdim());
168 bvecdim = vecdim * bdim;
169 } else {
170 std::shared_ptr<CTimeEntity<int> > vecdim =
171 std::dynamic_pointer_cast<CTimeEntity<int>, Entity>(dims->vecdim());
172 vectorize = vecdim->value() == 1 ? false : true;
173 bvecdim = vecdim * bdim;
174 }
175
176 std::ostringstream os;
177 // contraction = reduction
178 if (!vectorize || !TrivialBFSet<BFSet>::result ||
179 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() << ")" << context->end_of_stat() << std::endl;
184 } else { // blockwise vectorize for a single integral
185 os << "_libint2_static_api_inc1_short_("
186 << context->value_to_pointer(rr_target()->symbol()) << "+vi,"
187 << context->value_to_pointer(rr_child(0)->symbol()) << ",1)"
188 << context->end_of_stat() << std::endl;
189 }
190 unsigned int& nflops_ref = const_cast<unsigned int&>(nflops_);
191 nflops_ref += target_->size();
192
193 return os.str();
194}
195
198 bool operator()(const std::shared_ptr<DGVertex>& V) {
199 const unsigned int outdegree = V->num_exit_arcs();
200 if (outdegree == 0) return false;
201
202 const std::shared_ptr<DGArc> arc0 = *(V->first_exit_arc());
203 // Is this DGArcRR?
204 const std::shared_ptr<DGArcRR> arcrr =
205 std::dynamic_pointer_cast<DGArcRR, DGArc>(arc0);
206 if (arcrr == 0) return false;
207 const std::shared_ptr<Uncontract_Integral_base> uib_ptr =
208 std::dynamic_pointer_cast<Uncontract_Integral_base, RecurrenceRelation>(
209 arcrr->rr());
210 return uib_ptr != 0;
211 }
212};
213
214}; // namespace libint2
215
216#endif
AlgebraicOperator is an algebraic operator that acts on objects of type T.
Definition algebra.h:47
CTimeEntity is an Entity of type T that exists at compile-time of the generated code (hence has a val...
Definition entity.h:220
Entity is a base class for all objects that exist at compile or runtime of the generated code.
Definition entity.h:132
const std::string & id() const
Return id string.
Definition entity.h:136
RecurrenceRelation describes all recurrence relations.
Definition rr.h:97
Uncontract_Integral_base is dummy class used for dynamic casts only.
Definition uncontract.h:42
Uncontract_Integral converts (a set of) contracted integral(s) to its uncontracted counterpart.
Definition uncontract.h:53
std::shared_ptr< TargetType > target() const
target() returns pointer to target
Definition uncontract.h:67
bool is_simple() const override
to inline this would require a unary operator (+=).
Definition uncontract.h:80
unsigned int num_children() const override
Implementation of RecurrenceRelation::num_children()
Definition uncontract.h:65
std::shared_ptr< DGVertex > rr_child(unsigned int i) const override
Implementation of RecurrenceRelation's child()
Definition uncontract.h:75
RecurrenceRelation::ExprType ExprType
The type of expressions in which RecurrenceRelations result.
Definition uncontract.h:59
std::shared_ptr< ChildType > child(unsigned int i) const
child(i) returns pointer i-th child
Definition uncontract.h:151
std::shared_ptr< DGVertex > rr_target() const override
Implementation of RecurrenceRelation's target()
Definition uncontract.h:71
Defaults definitions for various parameters assumed by Libint.
Definition algebra.cc:24
return true if V is a decontracted IntegralSet
Definition uncontract.h:197