T["einst"]
This project is an effort to standardize the usage of Tensor Frameworks (TF) by defining a common application programming interface (API). One of the main goals is to ease the creation of bindings for diverse programming languages. Most TF are written in C++ and make extensive use of generic programming through C++ templates. This in turn makes creating bindings burdensome.
This projects aims to define a common API in the C programming language which can access most basic functionality of these libraries. We choose to focus on C since most programming languages provide a well supported infrastructure for interfacing with C data structures. This standard strives to be as general as possible, but a trade-off must be waged. Therefore, not all features of TF can be made to fit in.
This section should be a compilation of use cases that should motivate the definition of the API. The goal is to define a series of general examples and implement them using the API of different TF.
In this example we will consider the calculation of the simple coupled cluster energy.
\begin{equation} E_\mathrm{CC} = \frac{1}{4} ∑a, b, i, j Tabij Vijab \end{equation}
In this example we will illustrate how one uses the library Cyclops Tensor Framework (CTF).
#include <mpi.h>
#include <ctf.hpp>
template <typename F> using T = CTF::Tensor<F>;
template <typename F> using S = CTF::Scalar<F>;
template <typename F>
F ccEnergy(T<F> &t, T<F> &vhhpp) {
S<F> energy;
energy[""] = (0.25)
* t["abij"]
* vijab["ijab"]
;
return energy.get_val();
}
int main() {
int no(20)
, nv(200)
, order(4)
, symmetries[] = {NS, NS, NS, NS}
, lensT[] = {nv, nv, no, no}
, lensV[] = {no, no, nv, nv}
;
auto T<double>(order, symmetries, lensT, MPI_COMM_WORLD)
, V<double>(order, symmetries, lensV, MPI_COMM_WORLD)
;
double e(ccEnergy(T, V));
std::cout << "Energy " << e << std::endl;
}
- [X] Write a makefile file to download and compile
CTF
. - [ ] Write a makefile file to download and compile
libtensor
. - [ ] Write a makefile file to download and compile
tiledarray
. - [ ] Write a makefile target to compile and run examples.
- [X] Define an example to do basic full contraction.
- [ ] Define an example to do slicing.
- [ ] Define an example to apply map function to values of a tensor.
- [ ] Define an example to define sparse tensors.
- Prefix library functions by
teinst_
- Use
s
,d
, andz
forreal
,double
andcomplex
types - Use a marker in the name to indicate if an operation is in-place. I think the default should be to have one output-only parameter and multiple const input-only parameters to functions.
- Dimensioning variables should always be given as int64
- Use only the C native types in the API. If a struct is needed, return a pointer and provide functions to interact with the struct
- Return a return code
TEINST_SUCCESS
orTEINST_FAILURE
for every function call - Do not allocate temporary memory, let the user pass some pointers to allocated memory
- Test preconditions and post-conditions with asserts in all functions.
For example, test if dimensions are compatible and if the tensors
point to allocated memory. We can also provide unsafe versions which
don’t do the checks, such that the safe version
- tests the pre-conditions
- call the unsafe function
- tests the post-conditions
- Provide a test for each function
- All operations are deep (copies, allocations, etc)
- If we have some data structures, we should make it impossible to have them incompletely filled
- Use
const
whenever possible - All functions should be independent of the context
- Convert scalars and arrays to tensors, and backwards (copy)
- Allocate and return a pointer
- Free the tensor
- Test if a pointer points on an allocated tensor
- Contractions
- Add, subtract, multiply and divide element-wise along selected directions
- Slicing
- Map function
return_code = teinst_dcontr(E, "", T, "abij", V, "ijab", 0.25);