MPQC 3.0.0-alpha
Loading...
Searching...
No Matches
taskintegrals.hpp
1//
2// taskintegrals.hpp
3//
4// Copyright (C) 2013 Drew Lewis
5//
6// Authors: Drew Lewis
7// Maintainer: Drew Lewis and Edward Valeev
8//
9// This file is part of the MPQC Toolkit.
10//
11// The MPQC Toolkit is free software; you can redistribute it and/or modify
12// it under the terms of the GNU Library General Public License as published by
13// the Free Software Foundation; either version 2, or (at your option)
14// any later version.
15//
16// The MPQC Toolkit is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU Library General Public License for more details.
20//
21// You should have received a copy of the GNU Library General Public License
22// along with the MPQC Toolkit; see the file COPYING.LIB. If not, write to
23// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24//
25// The U.S. Government is granted a limited license as per AL 91-7.
26//
27
28#ifndef MPQC_CHEMISTRY_QC_BASIS_TASKINTEGRALS_HPP_
29#define MPQC_CHEMISTRY_QC_BASIS_TASKINTEGRALS_HPP_
30
31#include <tiledarray.h>
32#include <memory>
33#include <chemistry/qc/basis/tiledbasisset.hpp>
34#include <mpqc/integrals/integrals.hpp>
35#include <chemistry/qc/basis/integral.h>
36
37namespace mpqc {
38 namespace TA {
39
42 template<typename T>
43 using PoolPtrType = typename std::pointer_traits<T>::element_type;
44
45#ifndef DOXYGEN
46// Helper class to get Integral Engine typetraits.
47 template<typename IntegralEngine>
48 struct EngineTypeTraits;
49 template<> struct EngineTypeTraits<sc::Ref<sc::TwoBodyInt> > {
50 static const size_t ncenters = 4u;
51 };
52 template<> struct EngineTypeTraits<sc::Ref<sc::TwoBodyThreeCenterInt> > {
53 static const size_t ncenters = 3u;
54 };
55 template<> struct EngineTypeTraits<sc::Ref<sc::TwoBodyTwoCenterInt> > {
56 static const size_t ncenters = 2u;
57 };
58 template<> struct EngineTypeTraits<sc::Ref<sc::OneBodyInt> > {
59 static const size_t ncenters = 2u;
60 };
61 template<> struct EngineTypeTraits<sc::Ref<sc::OneBodyOneCenterInt> > {
62 static const size_t ncenters = 1u;
63 };
64
65 /*
66 * Does the dirty work of getting integrals into TA::Tiles
67 */
68 namespace int_details {
69 typedef std::vector<int> shell_range;
70
71// Takes a shell_range, sc::Engine_Type, and a TensorRef map to a TA::Tile
72 template<typename RefEngine>
73 void get_integrals(const std::vector<shell_range> &s, RefEngine &engine,
74 TensorRef<double, 2, TensorRowMajor> &tile_map) {
75 mpqc::lcao::evaluate(engine, s[0], s[1], tile_map);
76 }
77
78 template<typename RefEngine>
79 void get_integrals(const std::vector<shell_range> &s, RefEngine &engine,
80 TensorRef<double, 3, TensorRowMajor> &tile_map) {
81 mpqc::lcao::evaluate(engine, s[0], s[1], s[2], tile_map);
82 }
83
84 template<typename RefEngine>
85 void get_integrals(const std::vector<shell_range> &s, RefEngine &engine,
86 TensorRef<double, 4, TensorRowMajor> &tile_map) {
87 mpqc::lcao::evaluate(engine, s[0], s[1], s[2], s[3], tile_map);
88 }
89
90 } // namespace int_details
91
92 /*
93 * Computes shell ranges to pass to a TensorRef for getting integrals
94 */
95 template<typename Tile, typename RefEngine>
96 void get_integrals(Tile &tile, RefEngine &engine) {
97
98 // Calculate the rank of our tiles
99 constexpr std::size_t rank = EngineTypeTraits<RefEngine>::ncenters;
100 typedef int_details::shell_range shell_range;
101
102 std::vector<shell_range> ranges(rank);
103
104 // Loop over each dimension of the tile.
105 for (std::size_t i = 0; i < rank; ++i) {
106
107 // Get the global indices of the first and last function in a tile
108 // This corresponds to basis functions.
109 const std::size_t first_func = tile.range().lobound()[i];
110 const std::size_t last_func = tile.range().upbound()[i] - 1;
111
112 // Compute the first and last shell for a given dimension of a tile
113 const std::size_t first_shell = engine->basis(i)->function_to_shell(
114 first_func);
115 const std::size_t last_shell = engine->basis(i)->function_to_shell(
116 last_func);
117
118 // fill a vector with the shell indices that belong to dimension i
119 for (auto j = first_shell; j < last_shell + 1; ++j) {
120 ranges[i].push_back(j);
121 }
122 }
123
124 // passes the TiledArray size into a fixed c-style array for Tensor class
125 const std::size_t (&dim)[rank] =
126 *reinterpret_cast<const std::size_t (*)[rank]>(tile.range().extent_data());
127
128 TensorRef<double, rank, TensorRowMajor> tile_map(tile.data(), dim);
129
130 int_details::get_integrals(ranges, engine, tile_map);
131
132 }
133
134 template<typename ShrPtrPool, typename It, class A>
135 void make_integral_task(It first, It last, const A &array, ShrPtrPool pool);
136
137 /*
138 * Splits work in into manageable chunks by creating tasks. And then fills
139 * each tile with integrals.
140 */
141 template<typename ShrPtrPool, typename It, class A>
142 void integral_task(It first, It last, A &array, ShrPtrPool &pool) {
143
144 // Divide work. If the distance between the first and last pointer
145 // is greater than some number then split the range in half and send
146 // half of the work to another task. Continue to do this until
147 // the distance between the pointers is small enough.
148 while (last - first > 10) {
149 It middle = first;
150 std::advance(middle, std::distance(first, last) / 2);
151 make_integral_task(middle, last, array, pool);
152 last = middle;
153 }
154
155 // Once the pointer range is small enough unwrap the engine type
156 // and get a local instance
157 typename PoolPtrType<ShrPtrPool>::engine_type engine = pool->instance();
158
159 // Loop over the iterator range and create tiles to populate the
160 // TiledArray. Fill the tiles with data in get_integrals
161 for (; first != last; ++first) {
162 typename A::value_type tile(array.trange().make_tile_range(*first));
163 get_integrals(tile, engine);
164
165 array.set(*first, tile);
166 }
167 }
168
169 /*
170 * Spawns tasks to fill tiles with integrals.
171 */
172 template<typename ShrPtrPool, typename It, class A>
173 void make_integral_task(It first, It last, const A &array, ShrPtrPool pool){
174 array.world().taskq.add(&integral_task<ShrPtrPool, It, A>, first, last,
175 array, pool);
176 }
177
178#endif //DOXYGEN
184 template<typename ShrPtrPool, class A>
185 void fill_tiles(A &array, const ShrPtrPool &pool) {
186
187 // get pointers
188 auto begin = array.pmap()->begin();
189 auto end = array.pmap()->end();
190
191 // Create tasks to fill tiles with data. Boost const reference is used
192 // because Integral Engine pool is not copyable, but when sent to the
193 // Madness task queue all objects are copied.
194 make_integral_task(begin, end, array, pool);
195 }
196
199
200 template<typename ShrPtrPool>
201 ::TiledArray::Array<double,
202 EngineTypeTraits<typename PoolPtrType<ShrPtrPool>::engine_type>::ncenters >
203 Integrals(
204 madness::World &world, const ShrPtrPool &pool,
205 const sc::Ref<mpqc::TA::TiledBasisSet> &tbasis) {
206
207 namespace TA = ::TiledArray;
208
209 // Get the the type of integral that we are computing.
210 typedef typename PoolPtrType<ShrPtrPool>::engine_type engine_type;
211 // Determine the dimensions of our integrals as well as our TiledArray
212 constexpr size_t rank = EngineTypeTraits<engine_type>::ncenters;
213
214 // Get the array to initialize the TiledArray::TiledRange using the
215 // TiledBasis
216 std::array<TiledArray::TiledRange1, rank> blocking;
217 for (auto i = 0; i < rank; ++i) {
218 blocking[i] = tbasis->trange1();
219 }
220
221 // Construct the TiledArray::TiledRange object
222 TA::TiledRange trange(blocking.begin(), blocking.end());
223
224 // Initialize the TiledArray
225 TA::Array<double, rank> array(world, trange);
226
227 // Fill the TiledArray with data by looping over tiles and sending
228 // each tile to a madness task to be filled in parallel.
229 fill_tiles(array, pool);
230
231 return array;
232 }
233
234 template<typename ShrPtrPool>
235 ::TiledArray::Array<double,
236 EngineTypeTraits<typename PoolPtrType<ShrPtrPool>::engine_type>::ncenters >
237 Integrals( madness::World &world, const ShrPtrPool &pool,
239 const sc::Ref<mpqc::TA::TiledBasisSet> &dftbasis) {
240
241 namespace TA = ::TiledArray;
242
243 // Get the the type of integral that we are computing.
244 typedef typename PoolPtrType<ShrPtrPool>::engine_type engine_type;
245 // Determine the dimensions of our integrals as well as our TiledArray
246 constexpr size_t rank = EngineTypeTraits<engine_type>::ncenters;
247
248 // Get the array to initialize the TiledArray::TiledRange using the
249 // TiledBasis
250 std::array<TiledArray::TiledRange1, rank> blocking;
251 for (auto i = 0; i < (rank - 1); ++i) {
252 blocking[i] = tbasis->trange1(); // Asign first 2 dims to regular basis
253 }
254 blocking.back() = dftbasis->trange1(); // Asign last dim to df basis
255
256 // Construct the TiledArray::TiledRange object
257 TA::TiledRange trange(blocking.begin(), blocking.end());
258
259 // Initialize the TiledArray
260 TA::Array<double, rank> array(world, trange);
261
262 // Fill the TiledArray with data by looping over tiles and sending
263 // each tile to a madness task to be filled in parallel.
264 fill_tiles(array, pool);
265
266 return array;
267 }
268
270
271 }// namespace TA
272} // namespace mpqc
273
274#endif /* MPQC_CHEMISTRY_QC_BASIS_TASKINTEGRALS_HPP_ */
A template class that maintains references counts.
Definition ref.h:361
Definition cadf_attic.h:330
void evaluate(sc::Ref< sc::OneBodyInt > &engine, const std::vector< int > &P, const std::vector< int > &Q, TensorRef< double, 2, TensorRowMajor > &ints)
Evaluate set of shell blocks of integrals (p|O|q)
Definition integrals.hpp:206
void fill_tiles(A &array, const ShrPtrPool &pool)
Initial function called to fill a TiledArray with integrals.
Definition taskintegrals.hpp:185
Contains new MPQC code since version 3.
Definition integralenginepool.hpp:37
Contains all MPQC code up to version 3.
Definition mpqcin.h:14

Generated at Wed Sep 25 2024 02:45:29 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.12.0.