1 //
2 // BAGEL - Brilliantly Advanced General Electronic Structure Library
3 // Filename: MRCI_tasks1.h
4 // Copyright (C) 2014 Toru Shiozaki
5 //
6 // Author: Toru Shiozaki <shiozaki@northwestern.edu>
7 // Maintainer: Shiozaki group
8 //
9 // This file is part of the BAGEL package.
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program 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 General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 //
24 
25 #include <bagel_config.h>
26 #ifdef COMPILE_SMITH
27 
28 #ifndef __SRC_SMITH_MRCI_TASKS1_H
29 #define __SRC_SMITH_MRCI_TASKS1_H
30 
31 #include <src/smith/indexrange.h>
32 #include <src/smith/tensor.h>
33 #include <src/smith/task.h>
34 #include <src/smith/subtask.h>
35 #include <src/smith/storage.h>
36 
37 namespace bagel {
38 namespace SMITH {
39 namespace MRCI{
40 
41 class Task0 : public Task {  // associated with gamma
42   protected:
43     std::shared_ptr<Tensor> out_;
44     std::array<std::shared_ptr<const Tensor>,3> in_;
45     class Task_local : public SubTask<4,3> {
46       protected:
47         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)48         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)49         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()50         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
51       public:
Task_local(const std::array<const Index,4> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)52         Task_local(const std::array<const Index,4>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
53                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
54           : SubTask<4,3>(block, in, out), range_(ran) { }
55         void compute() override;
56     };
57     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()58     void compute_() override {
59       if (!out_->allocated())
60         out_->allocate();
61       for (auto& i : subtasks_) i->compute();
62     }
63   public:
64     Task0(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task0()65     ~Task0() {}
66 };
67 
68 class Task1 : public Task {  // associated with gamma
69   protected:
70     std::shared_ptr<Tensor> out_;
71     std::array<std::shared_ptr<const Tensor>,3> in_;
72     class Task_local : public SubTask<6,3> {
73       protected:
74         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)75         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)76         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()77         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
78       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)79         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
80                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
81           : SubTask<6,3>(block, in, out), range_(ran) { }
82         void compute() override;
83     };
84     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()85     void compute_() override {
86       if (!out_->allocated())
87         out_->allocate();
88       for (auto& i : subtasks_) i->compute();
89     }
90   public:
91     Task1(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task1()92     ~Task1() {}
93 };
94 
95 class Task2 : public Task {  // associated with gamma
96   protected:
97     std::shared_ptr<Tensor> out_;
98     std::array<std::shared_ptr<const Tensor>,3> in_;
99     class Task_local : public SubTask<4,3> {
100       protected:
101         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)102         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)103         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()104         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
105       public:
Task_local(const std::array<const Index,4> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)106         Task_local(const std::array<const Index,4>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
107                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
108           : SubTask<4,3>(block, in, out), range_(ran) { }
109         void compute() override;
110     };
111     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()112     void compute_() override {
113       if (!out_->allocated())
114         out_->allocate();
115       for (auto& i : subtasks_) i->compute();
116     }
117   public:
118     Task2(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task2()119     ~Task2() {}
120 };
121 
122 class Task3 : public Task {  // associated with gamma
123   protected:
124     std::shared_ptr<Tensor> out_;
125     std::array<std::shared_ptr<const Tensor>,4> in_;
126     class Task_local : public SubTask<6,4> {
127       protected:
128         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)129         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)130         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()131         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
132       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)133         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
134                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
135           : SubTask<6,4>(block, in, out), range_(ran) { }
136         void compute() override;
137     };
138     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()139     void compute_() override {
140       if (!out_->allocated())
141         out_->allocate();
142       for (auto& i : subtasks_) i->compute();
143     }
144   public:
145     Task3(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task3()146     ~Task3() {}
147 };
148 
149 class Task4 : public Task {  // associated with gamma
150   protected:
151     std::shared_ptr<Tensor> out_;
152     std::array<std::shared_ptr<const Tensor>,4> in_;
153     class Task_local : public SubTask<6,4> {
154       protected:
155         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)156         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)157         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()158         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
159       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)160         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
161                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
162           : SubTask<6,4>(block, in, out), range_(ran) { }
163         void compute() override;
164     };
165     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()166     void compute_() override {
167       if (!out_->allocated())
168         out_->allocate();
169       for (auto& i : subtasks_) i->compute();
170     }
171   public:
172     Task4(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task4()173     ~Task4() {}
174 };
175 
176 class Task5 : public Task {  // associated with gamma
177   protected:
178     std::shared_ptr<Tensor> out_;
179     std::array<std::shared_ptr<const Tensor>,4> in_;
180     class Task_local : public SubTask<6,4> {
181       protected:
182         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)183         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)184         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()185         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
186       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)187         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
188                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
189           : SubTask<6,4>(block, in, out), range_(ran) { }
190         void compute() override;
191     };
192     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()193     void compute_() override {
194       if (!out_->allocated())
195         out_->allocate();
196       for (auto& i : subtasks_) i->compute();
197     }
198   public:
199     Task5(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task5()200     ~Task5() {}
201 };
202 
203 class Task6 : public Task {  // associated with gamma
204   protected:
205     std::shared_ptr<Tensor> out_;
206     std::array<std::shared_ptr<const Tensor>,4> in_;
207     class Task_local : public SubTask<8,4> {
208       protected:
209         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)210         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)211         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()212         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
213       public:
Task_local(const std::array<const Index,8> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)214         Task_local(const std::array<const Index,8>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
215                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
216           : SubTask<8,4>(block, in, out), range_(ran) { }
217         void compute() override;
218     };
219     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()220     void compute_() override {
221       if (!out_->allocated())
222         out_->allocate();
223       for (auto& i : subtasks_) i->compute();
224     }
225   public:
226     Task6(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task6()227     ~Task6() {}
228 };
229 
230 class Task7 : public Task {  // associated with gamma
231   protected:
232     std::shared_ptr<Tensor> out_;
233     std::array<std::shared_ptr<const Tensor>,4> in_;
234     class Task_local : public SubTask<8,4> {
235       protected:
236         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)237         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)238         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()239         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
240       public:
Task_local(const std::array<const Index,8> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)241         Task_local(const std::array<const Index,8>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
242                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
243           : SubTask<8,4>(block, in, out), range_(ran) { }
244         void compute() override;
245     };
246     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()247     void compute_() override {
248       if (!out_->allocated())
249         out_->allocate();
250       for (auto& i : subtasks_) i->compute();
251     }
252   public:
253     Task7(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task7()254     ~Task7() {}
255 };
256 
257 class Task8 : public Task {  // associated with gamma
258   protected:
259     std::shared_ptr<Tensor> out_;
260     std::array<std::shared_ptr<const Tensor>,3> in_;
261     class Task_local : public SubTask<6,3> {
262       protected:
263         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)264         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)265         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()266         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
267       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)268         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
269                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
270           : SubTask<6,3>(block, in, out), range_(ran) { }
271         void compute() override;
272     };
273     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()274     void compute_() override {
275       if (!out_->allocated())
276         out_->allocate();
277       for (auto& i : subtasks_) i->compute();
278     }
279   public:
280     Task8(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task8()281     ~Task8() {}
282 };
283 
284 class Task9 : public Task {  // associated with gamma
285   protected:
286     std::shared_ptr<Tensor> out_;
287     std::array<std::shared_ptr<const Tensor>,4> in_;
288     class Task_local : public SubTask<6,4> {
289       protected:
290         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)291         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)292         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()293         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
294       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)295         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
296                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
297           : SubTask<6,4>(block, in, out), range_(ran) { }
298         void compute() override;
299     };
300     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()301     void compute_() override {
302       if (!out_->allocated())
303         out_->allocate();
304       for (auto& i : subtasks_) i->compute();
305     }
306   public:
307     Task9(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task9()308     ~Task9() {}
309 };
310 
311 class Task10 : public Task {  // associated with gamma
312   protected:
313     std::shared_ptr<Tensor> out_;
314     std::array<std::shared_ptr<const Tensor>,4> in_;
315     class Task_local : public SubTask<6,4> {
316       protected:
317         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)318         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)319         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()320         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
321       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)322         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
323                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
324           : SubTask<6,4>(block, in, out), range_(ran) { }
325         void compute() override;
326     };
327     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()328     void compute_() override {
329       if (!out_->allocated())
330         out_->allocate();
331       for (auto& i : subtasks_) i->compute();
332     }
333   public:
334     Task10(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task10()335     ~Task10() {}
336 };
337 
338 class Task11 : public Task {  // associated with gamma
339   protected:
340     std::shared_ptr<Tensor> out_;
341     std::array<std::shared_ptr<const Tensor>,3> in_;
342     class Task_local : public SubTask<6,3> {
343       protected:
344         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)345         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)346         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()347         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
348       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)349         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
350                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
351           : SubTask<6,3>(block, in, out), range_(ran) { }
352         void compute() override;
353     };
354     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()355     void compute_() override {
356       if (!out_->allocated())
357         out_->allocate();
358       for (auto& i : subtasks_) i->compute();
359     }
360   public:
361     Task11(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task11()362     ~Task11() {}
363 };
364 
365 class Task12 : public Task {  // associated with gamma
366   protected:
367     std::shared_ptr<Tensor> out_;
368     std::array<std::shared_ptr<const Tensor>,3> in_;
369     class Task_local : public SubTask<6,3> {
370       protected:
371         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)372         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)373         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()374         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
375       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)376         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
377                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
378           : SubTask<6,3>(block, in, out), range_(ran) { }
379         void compute() override;
380     };
381     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()382     void compute_() override {
383       if (!out_->allocated())
384         out_->allocate();
385       for (auto& i : subtasks_) i->compute();
386     }
387   public:
388     Task12(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task12()389     ~Task12() {}
390 };
391 
392 class Task13 : public Task {  // associated with gamma
393   protected:
394     std::shared_ptr<Tensor> out_;
395     std::array<std::shared_ptr<const Tensor>,3> in_;
396     class Task_local : public SubTask<6,3> {
397       protected:
398         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)399         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)400         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()401         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
402       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)403         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
404                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
405           : SubTask<6,3>(block, in, out), range_(ran) { }
406         void compute() override;
407     };
408     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()409     void compute_() override {
410       if (!out_->allocated())
411         out_->allocate();
412       for (auto& i : subtasks_) i->compute();
413     }
414   public:
415     Task13(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task13()416     ~Task13() {}
417 };
418 
419 class Task14 : public Task {  // associated with gamma
420   protected:
421     std::shared_ptr<Tensor> out_;
422     std::array<std::shared_ptr<const Tensor>,2> in_;
423     class Task_local : public SubTask<4,2> {
424       protected:
425         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)426         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)427         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()428         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
429       public:
Task_local(const std::array<const Index,4> & block,const std::array<std::shared_ptr<const Tensor>,2> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)430         Task_local(const std::array<const Index,4>& block, const std::array<std::shared_ptr<const Tensor>,2>& in, std::shared_ptr<Tensor>& out,
431                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
432           : SubTask<4,2>(block, in, out), range_(ran) { }
433         void compute() override;
434     };
435     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()436     void compute_() override {
437       if (!out_->allocated())
438         out_->allocate();
439       for (auto& i : subtasks_) i->compute();
440     }
441   public:
442     Task14(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task14()443     ~Task14() {}
444 };
445 
446 class Task15 : public Task {  // associated with gamma
447   protected:
448     std::shared_ptr<Tensor> out_;
449     std::array<std::shared_ptr<const Tensor>,3> in_;
450     class Task_local : public SubTask<6,3> {
451       protected:
452         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)453         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)454         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()455         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
456       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)457         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
458                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
459           : SubTask<6,3>(block, in, out), range_(ran) { }
460         void compute() override;
461     };
462     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()463     void compute_() override {
464       if (!out_->allocated())
465         out_->allocate();
466       for (auto& i : subtasks_) i->compute();
467     }
468   public:
469     Task15(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task15()470     ~Task15() {}
471 };
472 
473 class Task16 : public Task {  // associated with gamma
474   protected:
475     std::shared_ptr<Tensor> out_;
476     std::array<std::shared_ptr<const Tensor>,4> in_;
477     class Task_local : public SubTask<8,4> {
478       protected:
479         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)480         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)481         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()482         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
483       public:
Task_local(const std::array<const Index,8> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)484         Task_local(const std::array<const Index,8>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
485                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
486           : SubTask<8,4>(block, in, out), range_(ran) { }
487         void compute() override;
488     };
489     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()490     void compute_() override {
491       if (!out_->allocated())
492         out_->allocate();
493       for (auto& i : subtasks_) i->compute();
494     }
495   public:
496     Task16(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task16()497     ~Task16() {}
498 };
499 
500 class Task17 : public Task {  // associated with gamma
501   protected:
502     std::shared_ptr<Tensor> out_;
503     std::array<std::shared_ptr<const Tensor>,4> in_;
504     class Task_local : public SubTask<8,4> {
505       protected:
506         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)507         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)508         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()509         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
510       public:
Task_local(const std::array<const Index,8> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)511         Task_local(const std::array<const Index,8>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
512                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
513           : SubTask<8,4>(block, in, out), range_(ran) { }
514         void compute() override;
515     };
516     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()517     void compute_() override {
518       if (!out_->allocated())
519         out_->allocate();
520       for (auto& i : subtasks_) i->compute();
521     }
522   public:
523     Task17(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task17()524     ~Task17() {}
525 };
526 
527 class Task18 : public Task {  // associated with gamma
528   protected:
529     std::shared_ptr<Tensor> out_;
530     std::array<std::shared_ptr<const Tensor>,4> in_;
531     class Task_local : public SubTask<8,4> {
532       protected:
533         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)534         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)535         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()536         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
537       public:
Task_local(const std::array<const Index,8> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)538         Task_local(const std::array<const Index,8>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
539                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
540           : SubTask<8,4>(block, in, out), range_(ran) { }
541         void compute() override;
542     };
543     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()544     void compute_() override {
545       if (!out_->allocated())
546         out_->allocate();
547       for (auto& i : subtasks_) i->compute();
548     }
549   public:
550     Task18(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task18()551     ~Task18() {}
552 };
553 
554 class Task19 : public Task {  // associated with gamma
555   protected:
556     std::shared_ptr<Tensor> out_;
557     std::array<std::shared_ptr<const Tensor>,4> in_;
558     class Task_local : public SubTask<8,4> {
559       protected:
560         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)561         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)562         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()563         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
564       public:
Task_local(const std::array<const Index,8> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)565         Task_local(const std::array<const Index,8>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
566                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
567           : SubTask<8,4>(block, in, out), range_(ran) { }
568         void compute() override;
569     };
570     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()571     void compute_() override {
572       if (!out_->allocated())
573         out_->allocate();
574       for (auto& i : subtasks_) i->compute();
575     }
576   public:
577     Task19(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task19()578     ~Task19() {}
579 };
580 
581 class Task20 : public Task {  // associated with gamma
582   protected:
583     std::shared_ptr<Tensor> out_;
584     std::array<std::shared_ptr<const Tensor>,4> in_;
585     class Task_local : public SubTask<8,4> {
586       protected:
587         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)588         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)589         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()590         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
591       public:
Task_local(const std::array<const Index,8> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)592         Task_local(const std::array<const Index,8>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
593                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
594           : SubTask<8,4>(block, in, out), range_(ran) { }
595         void compute() override;
596     };
597     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()598     void compute_() override {
599       if (!out_->allocated())
600         out_->allocate();
601       for (auto& i : subtasks_) i->compute();
602     }
603   public:
604     Task20(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task20()605     ~Task20() {}
606 };
607 
608 class Task21 : public Task {  // associated with gamma
609   protected:
610     std::shared_ptr<Tensor> out_;
611     std::array<std::shared_ptr<const Tensor>,3> in_;
612     class Task_local : public SubTask<6,3> {
613       protected:
614         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)615         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)616         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()617         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
618       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)619         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
620                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
621           : SubTask<6,3>(block, in, out), range_(ran) { }
622         void compute() override;
623     };
624     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()625     void compute_() override {
626       if (!out_->allocated())
627         out_->allocate();
628       for (auto& i : subtasks_) i->compute();
629     }
630   public:
631     Task21(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task21()632     ~Task21() {}
633 };
634 
635 class Task22 : public Task {  // associated with gamma
636   protected:
637     std::shared_ptr<Tensor> out_;
638     std::array<std::shared_ptr<const Tensor>,3> in_;
639     class Task_local : public SubTask<6,3> {
640       protected:
641         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)642         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)643         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()644         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
645       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)646         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
647                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
648           : SubTask<6,3>(block, in, out), range_(ran) { }
649         void compute() override;
650     };
651     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()652     void compute_() override {
653       if (!out_->allocated())
654         out_->allocate();
655       for (auto& i : subtasks_) i->compute();
656     }
657   public:
658     Task22(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task22()659     ~Task22() {}
660 };
661 
662 class Task23 : public Task {  // associated with gamma
663   protected:
664     std::shared_ptr<Tensor> out_;
665     std::array<std::shared_ptr<const Tensor>,3> in_;
666     class Task_local : public SubTask<6,3> {
667       protected:
668         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)669         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)670         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()671         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
672       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)673         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
674                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
675           : SubTask<6,3>(block, in, out), range_(ran) { }
676         void compute() override;
677     };
678     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()679     void compute_() override {
680       if (!out_->allocated())
681         out_->allocate();
682       for (auto& i : subtasks_) i->compute();
683     }
684   public:
685     Task23(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task23()686     ~Task23() {}
687 };
688 
689 class Task24 : public Task {  // associated with gamma
690   protected:
691     std::shared_ptr<Tensor> out_;
692     std::array<std::shared_ptr<const Tensor>,4> in_;
693     class Task_local : public SubTask<8,4> {
694       protected:
695         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)696         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)697         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()698         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
699       public:
Task_local(const std::array<const Index,8> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)700         Task_local(const std::array<const Index,8>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
701                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
702           : SubTask<8,4>(block, in, out), range_(ran) { }
703         void compute() override;
704     };
705     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()706     void compute_() override {
707       if (!out_->allocated())
708         out_->allocate();
709       for (auto& i : subtasks_) i->compute();
710     }
711   public:
712     Task24(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task24()713     ~Task24() {}
714 };
715 
716 class Task25 : public Task {  // associated with gamma
717   protected:
718     std::shared_ptr<Tensor> out_;
719     std::array<std::shared_ptr<const Tensor>,4> in_;
720     class Task_local : public SubTask<8,4> {
721       protected:
722         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)723         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)724         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()725         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
726       public:
Task_local(const std::array<const Index,8> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)727         Task_local(const std::array<const Index,8>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
728                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
729           : SubTask<8,4>(block, in, out), range_(ran) { }
730         void compute() override;
731     };
732     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()733     void compute_() override {
734       if (!out_->allocated())
735         out_->allocate();
736       for (auto& i : subtasks_) i->compute();
737     }
738   public:
739     Task25(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task25()740     ~Task25() {}
741 };
742 
743 class Task26 : public Task {  // associated with gamma
744   protected:
745     std::shared_ptr<Tensor> out_;
746     std::array<std::shared_ptr<const Tensor>,4> in_;
747     class Task_local : public SubTask<8,4> {
748       protected:
749         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)750         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)751         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()752         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
753       public:
Task_local(const std::array<const Index,8> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)754         Task_local(const std::array<const Index,8>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
755                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
756           : SubTask<8,4>(block, in, out), range_(ran) { }
757         void compute() override;
758     };
759     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()760     void compute_() override {
761       if (!out_->allocated())
762         out_->allocate();
763       for (auto& i : subtasks_) i->compute();
764     }
765   public:
766     Task26(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task26()767     ~Task26() {}
768 };
769 
770 class Task27 : public Task {  // associated with gamma
771   protected:
772     std::shared_ptr<Tensor> out_;
773     std::array<std::shared_ptr<const Tensor>,3> in_;
774     class Task_local : public SubTask<8,3> {
775       protected:
776         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)777         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)778         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()779         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
780       public:
Task_local(const std::array<const Index,8> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)781         Task_local(const std::array<const Index,8>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
782                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
783           : SubTask<8,3>(block, in, out), range_(ran) { }
784         void compute() override;
785     };
786     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()787     void compute_() override {
788       if (!out_->allocated())
789         out_->allocate();
790       for (auto& i : subtasks_) i->compute();
791     }
792   public:
793     Task27(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task27()794     ~Task27() {}
795 };
796 
797 class Task28 : public Task {  // associated with gamma
798   protected:
799     std::shared_ptr<Tensor> out_;
800     std::array<std::shared_ptr<const Tensor>,5> in_;
801     class Task_local : public SubTask<8,5> {
802       protected:
803         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)804         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)805         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()806         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
807       public:
Task_local(const std::array<const Index,8> & block,const std::array<std::shared_ptr<const Tensor>,5> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)808         Task_local(const std::array<const Index,8>& block, const std::array<std::shared_ptr<const Tensor>,5>& in, std::shared_ptr<Tensor>& out,
809                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
810           : SubTask<8,5>(block, in, out), range_(ran) { }
811         void compute() override;
812     };
813     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()814     void compute_() override {
815       if (!out_->allocated())
816         out_->allocate();
817       for (auto& i : subtasks_) i->compute();
818     }
819   public:
820     Task28(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task28()821     ~Task28() {}
822 };
823 
824 class Task29 : public Task {  // associated with gamma
825   protected:
826     std::shared_ptr<Tensor> out_;
827     std::array<std::shared_ptr<const Tensor>,5> in_;
828     class Task_local : public SubTask<10,5> {
829       protected:
830         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)831         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)832         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()833         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
834       public:
Task_local(const std::array<const Index,10> & block,const std::array<std::shared_ptr<const Tensor>,5> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)835         Task_local(const std::array<const Index,10>& block, const std::array<std::shared_ptr<const Tensor>,5>& in, std::shared_ptr<Tensor>& out,
836                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
837           : SubTask<10,5>(block, in, out), range_(ran) { }
838         void compute() override;
839     };
840     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()841     void compute_() override {
842       if (!out_->allocated())
843         out_->allocate();
844       for (auto& i : subtasks_) i->compute();
845     }
846   public:
847     Task29(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task29()848     ~Task29() {}
849 };
850 
851 class Task30 : public Task {  // associated with gamma
852   protected:
853     std::shared_ptr<Tensor> out_;
854     std::array<std::shared_ptr<const Tensor>,2> in_;
855     class Task_local : public SubTask<4,2> {
856       protected:
857         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)858         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)859         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()860         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
861       public:
Task_local(const std::array<const Index,4> & block,const std::array<std::shared_ptr<const Tensor>,2> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)862         Task_local(const std::array<const Index,4>& block, const std::array<std::shared_ptr<const Tensor>,2>& in, std::shared_ptr<Tensor>& out,
863                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
864           : SubTask<4,2>(block, in, out), range_(ran) { }
865         void compute() override;
866     };
867     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()868     void compute_() override {
869       if (!out_->allocated())
870         out_->allocate();
871       for (auto& i : subtasks_) i->compute();
872     }
873   public:
874     Task30(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task30()875     ~Task30() {}
876 };
877 
878 class Task31 : public Task {  // associated with gamma
879   protected:
880     std::shared_ptr<Tensor> out_;
881     std::array<std::shared_ptr<const Tensor>,2> in_;
882     class Task_local : public SubTask<2,2> {
883       protected:
884         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)885         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)886         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()887         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
888       public:
Task_local(const std::array<const Index,2> & block,const std::array<std::shared_ptr<const Tensor>,2> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)889         Task_local(const std::array<const Index,2>& block, const std::array<std::shared_ptr<const Tensor>,2>& in, std::shared_ptr<Tensor>& out,
890                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
891           : SubTask<2,2>(block, in, out), range_(ran) { }
892         void compute() override;
893     };
894     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()895     void compute_() override {
896       if (!out_->allocated())
897         out_->allocate();
898       for (auto& i : subtasks_) i->compute();
899     }
900   public:
901     Task31(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task31()902     ~Task31() {}
903 };
904 
905 class Task32 : public Task {  // associated with gamma
906   protected:
907     std::shared_ptr<Tensor> out_;
908     std::array<std::shared_ptr<const Tensor>,2> in_;
909     class Task_local : public SubTask<4,2> {
910       protected:
911         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)912         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)913         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()914         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
915       public:
Task_local(const std::array<const Index,4> & block,const std::array<std::shared_ptr<const Tensor>,2> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)916         Task_local(const std::array<const Index,4>& block, const std::array<std::shared_ptr<const Tensor>,2>& in, std::shared_ptr<Tensor>& out,
917                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
918           : SubTask<4,2>(block, in, out), range_(ran) { }
919         void compute() override;
920     };
921     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()922     void compute_() override {
923       if (!out_->allocated())
924         out_->allocate();
925       for (auto& i : subtasks_) i->compute();
926     }
927   public:
928     Task32(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task32()929     ~Task32() {}
930 };
931 
932 class Task33 : public Task {  // associated with gamma
933   protected:
934     std::shared_ptr<Tensor> out_;
935     std::array<std::shared_ptr<const Tensor>,3> in_;
936     class Task_local : public SubTask<4,3> {
937       protected:
938         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)939         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)940         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()941         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
942       public:
Task_local(const std::array<const Index,4> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)943         Task_local(const std::array<const Index,4>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
944                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
945           : SubTask<4,3>(block, in, out), range_(ran) { }
946         void compute() override;
947     };
948     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()949     void compute_() override {
950       if (!out_->allocated())
951         out_->allocate();
952       for (auto& i : subtasks_) i->compute();
953     }
954   public:
955     Task33(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task33()956     ~Task33() {}
957 };
958 
959 class Task34 : public Task {  // associated with gamma
960   protected:
961     std::shared_ptr<Tensor> out_;
962     std::array<std::shared_ptr<const Tensor>,4> in_;
963     class Task_local : public SubTask<6,4> {
964       protected:
965         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)966         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)967         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()968         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
969       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)970         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
971                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
972           : SubTask<6,4>(block, in, out), range_(ran) { }
973         void compute() override;
974     };
975     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()976     void compute_() override {
977       if (!out_->allocated())
978         out_->allocate();
979       for (auto& i : subtasks_) i->compute();
980     }
981   public:
982     Task34(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task34()983     ~Task34() {}
984 };
985 
986 class Task35 : public Task {  // associated with gamma
987   protected:
988     std::shared_ptr<Tensor> out_;
989     std::array<std::shared_ptr<const Tensor>,3> in_;
990     class Task_local : public SubTask<6,3> {
991       protected:
992         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)993         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)994         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()995         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
996       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)997         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
998                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
999           : SubTask<6,3>(block, in, out), range_(ran) { }
1000         void compute() override;
1001     };
1002     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()1003     void compute_() override {
1004       if (!out_->allocated())
1005         out_->allocate();
1006       for (auto& i : subtasks_) i->compute();
1007     }
1008   public:
1009     Task35(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task35()1010     ~Task35() {}
1011 };
1012 
1013 class Task36 : public Task {  // associated with gamma
1014   protected:
1015     std::shared_ptr<Tensor> out_;
1016     std::array<std::shared_ptr<const Tensor>,3> in_;
1017     class Task_local : public SubTask<6,3> {
1018       protected:
1019         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)1020         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)1021         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()1022         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
1023       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)1024         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
1025                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
1026           : SubTask<6,3>(block, in, out), range_(ran) { }
1027         void compute() override;
1028     };
1029     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()1030     void compute_() override {
1031       if (!out_->allocated())
1032         out_->allocate();
1033       for (auto& i : subtasks_) i->compute();
1034     }
1035   public:
1036     Task36(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task36()1037     ~Task36() {}
1038 };
1039 
1040 class Task37 : public Task {  // associated with gamma
1041   protected:
1042     std::shared_ptr<Tensor> out_;
1043     std::array<std::shared_ptr<const Tensor>,3> in_;
1044     class Task_local : public SubTask<4,3> {
1045       protected:
1046         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)1047         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)1048         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()1049         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
1050       public:
Task_local(const std::array<const Index,4> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)1051         Task_local(const std::array<const Index,4>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
1052                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
1053           : SubTask<4,3>(block, in, out), range_(ran) { }
1054         void compute() override;
1055     };
1056     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()1057     void compute_() override {
1058       if (!out_->allocated())
1059         out_->allocate();
1060       for (auto& i : subtasks_) i->compute();
1061     }
1062   public:
1063     Task37(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task37()1064     ~Task37() {}
1065 };
1066 
1067 class Task38 : public Task {  // associated with gamma
1068   protected:
1069     std::shared_ptr<Tensor> out_;
1070     std::array<std::shared_ptr<const Tensor>,3> in_;
1071     class Task_local : public SubTask<6,3> {
1072       protected:
1073         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)1074         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)1075         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()1076         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
1077       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)1078         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
1079                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
1080           : SubTask<6,3>(block, in, out), range_(ran) { }
1081         void compute() override;
1082     };
1083     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()1084     void compute_() override {
1085       if (!out_->allocated())
1086         out_->allocate();
1087       for (auto& i : subtasks_) i->compute();
1088     }
1089   public:
1090     Task38(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task38()1091     ~Task38() {}
1092 };
1093 
1094 class Task39 : public Task {  // associated with gamma
1095   protected:
1096     std::shared_ptr<Tensor> out_;
1097     std::array<std::shared_ptr<const Tensor>,3> in_;
1098     class Task_local : public SubTask<6,3> {
1099       protected:
1100         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)1101         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)1102         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()1103         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
1104       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)1105         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
1106                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
1107           : SubTask<6,3>(block, in, out), range_(ran) { }
1108         void compute() override;
1109     };
1110     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()1111     void compute_() override {
1112       if (!out_->allocated())
1113         out_->allocate();
1114       for (auto& i : subtasks_) i->compute();
1115     }
1116   public:
1117     Task39(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task39()1118     ~Task39() {}
1119 };
1120 
1121 class Task40 : public Task {  // associated with gamma
1122   protected:
1123     std::shared_ptr<Tensor> out_;
1124     std::array<std::shared_ptr<const Tensor>,3> in_;
1125     class Task_local : public SubTask<6,3> {
1126       protected:
1127         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)1128         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)1129         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()1130         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
1131       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)1132         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
1133                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
1134           : SubTask<6,3>(block, in, out), range_(ran) { }
1135         void compute() override;
1136     };
1137     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()1138     void compute_() override {
1139       if (!out_->allocated())
1140         out_->allocate();
1141       for (auto& i : subtasks_) i->compute();
1142     }
1143   public:
1144     Task40(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task40()1145     ~Task40() {}
1146 };
1147 
1148 class Task41 : public Task {  // associated with gamma
1149   protected:
1150     std::shared_ptr<Tensor> out_;
1151     std::array<std::shared_ptr<const Tensor>,2> in_;
1152     class Task_local : public SubTask<6,2> {
1153       protected:
1154         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)1155         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)1156         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()1157         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
1158       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,2> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)1159         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,2>& in, std::shared_ptr<Tensor>& out,
1160                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
1161           : SubTask<6,2>(block, in, out), range_(ran) { }
1162         void compute() override;
1163     };
1164     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()1165     void compute_() override {
1166       if (!out_->allocated())
1167         out_->allocate();
1168       for (auto& i : subtasks_) i->compute();
1169     }
1170   public:
1171     Task41(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task41()1172     ~Task41() {}
1173 };
1174 
1175 class Task42 : public Task {  // associated with gamma
1176   protected:
1177     std::shared_ptr<Tensor> out_;
1178     std::array<std::shared_ptr<const Tensor>,4> in_;
1179     class Task_local : public SubTask<4,4> {
1180       protected:
1181         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)1182         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)1183         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()1184         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
1185       public:
Task_local(const std::array<const Index,4> & block,const std::array<std::shared_ptr<const Tensor>,4> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)1186         Task_local(const std::array<const Index,4>& block, const std::array<std::shared_ptr<const Tensor>,4>& in, std::shared_ptr<Tensor>& out,
1187                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
1188           : SubTask<4,4>(block, in, out), range_(ran) { }
1189         void compute() override;
1190     };
1191     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()1192     void compute_() override {
1193       if (!out_->allocated())
1194         out_->allocate();
1195       for (auto& i : subtasks_) i->compute();
1196     }
1197   public:
1198     Task42(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task42()1199     ~Task42() {}
1200 };
1201 
1202 class Task43 : public Task {  // associated with gamma
1203   protected:
1204     std::shared_ptr<Tensor> out_;
1205     std::array<std::shared_ptr<const Tensor>,5> in_;
1206     class Task_local : public SubTask<6,5> {
1207       protected:
1208         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)1209         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)1210         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()1211         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
1212       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,5> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)1213         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,5>& in, std::shared_ptr<Tensor>& out,
1214                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
1215           : SubTask<6,5>(block, in, out), range_(ran) { }
1216         void compute() override;
1217     };
1218     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()1219     void compute_() override {
1220       if (!out_->allocated())
1221         out_->allocate();
1222       for (auto& i : subtasks_) i->compute();
1223     }
1224   public:
1225     Task43(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task43()1226     ~Task43() {}
1227 };
1228 
1229 class Task44 : public Task {  // associated with gamma
1230   protected:
1231     std::shared_ptr<Tensor> out_;
1232     std::array<std::shared_ptr<const Tensor>,3> in_;
1233     class Task_local : public SubTask<6,3> {
1234       protected:
1235         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)1236         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)1237         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()1238         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
1239       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,3> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)1240         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,3>& in, std::shared_ptr<Tensor>& out,
1241                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
1242           : SubTask<6,3>(block, in, out), range_(ran) { }
1243         void compute() override;
1244     };
1245     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()1246     void compute_() override {
1247       if (!out_->allocated())
1248         out_->allocate();
1249       for (auto& i : subtasks_) i->compute();
1250     }
1251   public:
1252     Task44(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task44()1253     ~Task44() {}
1254 };
1255 
1256 class Task45 : public Task {  // associated with gamma
1257   protected:
1258     std::shared_ptr<Tensor> out_;
1259     std::array<std::shared_ptr<const Tensor>,2> in_;
1260     class Task_local : public SubTask<4,2> {
1261       protected:
1262         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)1263         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)1264         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()1265         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
1266       public:
Task_local(const std::array<const Index,4> & block,const std::array<std::shared_ptr<const Tensor>,2> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)1267         Task_local(const std::array<const Index,4>& block, const std::array<std::shared_ptr<const Tensor>,2>& in, std::shared_ptr<Tensor>& out,
1268                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
1269           : SubTask<4,2>(block, in, out), range_(ran) { }
1270         void compute() override;
1271     };
1272     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()1273     void compute_() override {
1274       if (!out_->allocated())
1275         out_->allocate();
1276       for (auto& i : subtasks_) i->compute();
1277     }
1278   public:
1279     Task45(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task45()1280     ~Task45() {}
1281 };
1282 
1283 class Task46 : public Task {  // associated with gamma
1284   protected:
1285     std::shared_ptr<Tensor> out_;
1286     std::array<std::shared_ptr<const Tensor>,2> in_;
1287     class Task_local : public SubTask<4,2> {
1288       protected:
1289         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)1290         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)1291         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()1292         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
1293       public:
Task_local(const std::array<const Index,4> & block,const std::array<std::shared_ptr<const Tensor>,2> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)1294         Task_local(const std::array<const Index,4>& block, const std::array<std::shared_ptr<const Tensor>,2>& in, std::shared_ptr<Tensor>& out,
1295                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
1296           : SubTask<4,2>(block, in, out), range_(ran) { }
1297         void compute() override;
1298     };
1299     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()1300     void compute_() override {
1301       if (!out_->allocated())
1302         out_->allocate();
1303       for (auto& i : subtasks_) i->compute();
1304     }
1305   public:
1306     Task46(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task46()1307     ~Task46() {}
1308 };
1309 
1310 class Task47 : public Task {  // associated with gamma
1311   protected:
1312     std::shared_ptr<Tensor> out_;
1313     std::array<std::shared_ptr<const Tensor>,2> in_;
1314     class Task_local : public SubTask<4,2> {
1315       protected:
1316         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)1317         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)1318         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()1319         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
1320       public:
Task_local(const std::array<const Index,4> & block,const std::array<std::shared_ptr<const Tensor>,2> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)1321         Task_local(const std::array<const Index,4>& block, const std::array<std::shared_ptr<const Tensor>,2>& in, std::shared_ptr<Tensor>& out,
1322                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
1323           : SubTask<4,2>(block, in, out), range_(ran) { }
1324         void compute() override;
1325     };
1326     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()1327     void compute_() override {
1328       if (!out_->allocated())
1329         out_->allocate();
1330       for (auto& i : subtasks_) i->compute();
1331     }
1332   public:
1333     Task47(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task47()1334     ~Task47() {}
1335 };
1336 
1337 class Task48 : public Task {  // associated with gamma
1338   protected:
1339     std::shared_ptr<Tensor> out_;
1340     std::array<std::shared_ptr<const Tensor>,2> in_;
1341     class Task_local : public SubTask<6,2> {
1342       protected:
1343         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)1344         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)1345         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()1346         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
1347       public:
Task_local(const std::array<const Index,6> & block,const std::array<std::shared_ptr<const Tensor>,2> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)1348         Task_local(const std::array<const Index,6>& block, const std::array<std::shared_ptr<const Tensor>,2>& in, std::shared_ptr<Tensor>& out,
1349                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
1350           : SubTask<6,2>(block, in, out), range_(ran) { }
1351         void compute() override;
1352     };
1353     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()1354     void compute_() override {
1355       if (!out_->allocated())
1356         out_->allocate();
1357       for (auto& i : subtasks_) i->compute();
1358     }
1359   public:
1360     Task48(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task48()1361     ~Task48() {}
1362 };
1363 
1364 class Task49 : public Task {  // associated with gamma
1365   protected:
1366     std::shared_ptr<Tensor> out_;
1367     std::array<std::shared_ptr<const Tensor>,1> in_;
1368     class Task_local : public SubTask<2,1> {
1369       protected:
1370         const std::array<std::shared_ptr<const IndexRange>,3> range_;
b(const size_t & i)1371         const Index& b(const size_t& i) const { return this->block(i); }
in(const size_t & i)1372         std::shared_ptr<const Tensor> in(const size_t& i) const { return this->in_tensor(i); }
out()1373         std::shared_ptr<Tensor> out() { return this->out_tensor(); }
1374       public:
Task_local(const std::array<const Index,2> & block,const std::array<std::shared_ptr<const Tensor>,1> & in,std::shared_ptr<Tensor> & out,std::array<std::shared_ptr<const IndexRange>,3> & ran)1375         Task_local(const std::array<const Index,2>& block, const std::array<std::shared_ptr<const Tensor>,1>& in, std::shared_ptr<Tensor>& out,
1376                    std::array<std::shared_ptr<const IndexRange>,3>& ran)
1377           : SubTask<2,1>(block, in, out), range_(ran) { }
1378         void compute() override;
1379     };
1380     std::vector<std::shared_ptr<Task_local>> subtasks_;
compute_()1381     void compute_() override {
1382       if (!out_->allocated())
1383         out_->allocate();
1384       for (auto& i : subtasks_) i->compute();
1385     }
1386   public:
1387     Task49(std::vector<std::shared_ptr<Tensor>> t, std::array<std::shared_ptr<const IndexRange>,3> range);
~Task49()1388     ~Task49() {}
1389 };
1390 
1391 
1392 }
1393 }
1394 }
1395 #endif
1396 #endif
1397 
1398