-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Calculating cubes for visualization using the C interface #12
Comments
That is effectively the operation that something like Psi4 uses so we have very similar use cases. Let see the operation you want to complete is
With a gaussian in the form of In Psi4 to build out a full G we use the following:
A few questions:
|
We do not, but I have thought about the best way of building this in to accelerate.
Usually just one, but in the future I would like to look at 2-5 (around HOMO/LUMO).
No, I think I would need to read up on this :-) I think what we do is on the basic side.
I entirely agree on keeping the threading in the calling code, and generally look to use a read-only input with all basis sets, MO matrix, etc. Then assign subgrids to threads, and use embarrassingly parallel approaches to keep things simple. |
If you only doing 2-5 MO's it probably doesn't make sense to use DGEMM. What if we looked at an example use case where this would compute the orbital values size_t npoints = 500000;
const double *C = (nbf, nmo);
const double *x = (npoints, );
const double *y = (npoints, );
const double *z = (npoints, );
double *output = (nmo, npoints);
bool spherical = true;
size_t block_size = 500;
size_t nblocks = npoints / block_size size_t nmo_shift = 0;
// Loop over chunks of the grid
for (size_t i = 0; i < nblocks; i++) {
// Loop over
size_t block_start = block_size * i;
size_t nmo_shift = 0;
// Loop over shells
#pragma omp parallel for public(nmo_shift)
for (size_t j = 0; j < nshell; j++) {
shell = shells[j];
int nQ = shell.nfunction();
int L = shell.am();
int nprim = shell.nprimitive();
const double *center = shell.center();
const double *alpha = shell.exps();
const double *norm = shell.coefs();
// Evaluate the data
gg_evaluate_orbitals_grid(
// AM, how large the grid is, xyz information
L, block_size, x + block_start, y + block_start, z + block_start,
// basis information
nprim, norm, alpha, center, spherical,
// orbital information. Shift down the current basis functions
C + (nmo_shift * nmo), nmo,
// Output data and the stride of that data as we need to write out multiple rows.
output + block_start, npoints);
nmo_shift += nQ;
}
} |
@cryos Released 1.3 which contains these changes, let me know how it works and we can keep moving. |
I would like to integrate this into Avogadro, and make use of it in a desktop application. In addition, this is wrapped, and used on a server to deliver to web clients using a RESTful API. We effectively load up Gaussian basis sets, and an MO coefficient matrix.
I currently map each basis function to an atom, with a position in space, and then parallelise the code on the grid, effectively giving a smaller grid to each core, writing directly into it from all threads but ensuring only one thread will ever attempt to write to any given scalar. The code figures out which index to write to, its Cartesian position in space, and then iterates over all basis functions for the supplied molecular orbital.
I am open to reorganizing the code, but would like to maintain the high level interface. Load quantum output, then calculate the MO cube, which is then further processed before being visualized. It would be helpful to understand how I would map our basis sets, MO matrix, and atom positions in. Also what the most efficient method of passing in a subset of the cube, and whether we would need multiple copies of the data per thread, or could maintain the single copy that is only read across all threads.
The text was updated successfully, but these errors were encountered: