Skip to content

Commit

Permalink
Merge pull request #305 from electronic-structure/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
toxa81 authored Nov 6, 2018
2 parents 7d0c882 + 221b1c1 commit c9ae51d
Show file tree
Hide file tree
Showing 33 changed files with 730 additions and 656 deletions.
75 changes: 49 additions & 26 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ if (NOT CMAKE_BUILD_TYPE)
endif()

if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -DNDEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -ggdb")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -ggdb -DDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-ftree-vectorize -O3 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -ggdb -O2")
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNDEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g -O2")
endif()
Expand Down Expand Up @@ -74,7 +74,7 @@ find_package(LibSPG REQUIRED)
find_package(HDF5 REQUIRED C HL)

# cmake assumes spglib installed
add_compile_options(-D__SPGLIB_STD_INCLUDE_PATH)
#add_compile_options(-D__SPGLIB_STD_INCLUDE_PATH)

if(USE_ELPA)
find_package(Elpa REQUIRED)
Expand Down Expand Up @@ -131,34 +131,57 @@ include_directories(${MPI_INCLUDE_DIR})
include_directories(BEFORE src)
include_directories(BEFORE src/SDDK)

# configure version header
exec_program("git" ${CMAKE_CURRENT_SOURCE_DIR}
ARGS "rev-parse HEAD"
OUTPUT_VARIABLE GIT_VERSION_SHA1
RETURN_VALUE exit_code)
if(exit_code)
set(GIT_VERSION_SHA1 "")
endif()
exec_program("date"
ARGS "+\"%a, %e %b %Y %H:%M:%S\""
OUTPUT_VARIABLE BUILD_DATE)
exec_program(
"git"
${CMAKE_CURRENT_SOURCE_DIR}
ARGS "describe --all"
OUTPUT_VARIABLE GIT_BRANCHNAME
RETURN_VALUE exit_code)
if(exit_code)
set(GIT_BRANCHNAME "")
endif()
configure_file("${PROJECT_SOURCE_DIR}/src/version.hpp.in" "${PROJECT_BINARY_DIR}/src/version.hpp")
# configure generation of the version header
add_custom_command(
OUTPUT _always_rebuild
COMMAND true
)
add_custom_command(
OUTPUT version.hpp-test
DEPENDS _always_rebuild
COMMAND python ${CMAKE_SOURCE_DIR}/make_version_hpp.py ${CMAKE_SOURCE_DIR}/VERSION > version.hpp-test
)

set(version_hpp_path src/version.hpp)
add_custom_command(
OUTPUT ${version_hpp_path}
DEPENDS version.hpp-test
COMMAND ${CMAKE_COMMAND} -E copy_if_different version.hpp-test ${version_hpp_path}
)

add_custom_target(generate_version_hpp DEPENDS ${version_hpp_path})


## configure version header
#exec_program("git" ${CMAKE_CURRENT_SOURCE_DIR}
# ARGS "rev-parse HEAD"
# OUTPUT_VARIABLE GIT_VERSION_SHA1
# RETURN_VALUE exit_code)
#if(exit_code)
# set(GIT_VERSION_SHA1 "")
#endif()
#exec_program("date"
# ARGS "+\"%a, %e %b %Y %H:%M:%S\""
# OUTPUT_VARIABLE BUILD_DATE)
#exec_program(
# "git"
# ${CMAKE_CURRENT_SOURCE_DIR}
# ARGS "describe --all"
# OUTPUT_VARIABLE GIT_BRANCHNAME
# RETURN_VALUE exit_code)
#if(exit_code)
# set(GIT_BRANCHNAME "")
#endif()
#configure_file("${PROJECT_SOURCE_DIR}/src/version.hpp.in" "${PROJECT_BINARY_DIR}/src/version.hpp")
include_directories(BEFORE ${PROJECT_BINARY_DIR}/src)

MACRO(SIRIUS_SETUP_TARGET _target)
if(USE_CUDA)
add_dependencies(${_target} sirius_cu)
endif()

add_dependencies(${_target} generate_version_hpp)

if(USE_MKL)
# TODO: handle -lpthread properly
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
Expand Down
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
<p align="center">
<img src="doc/images/sirius_logo.png" width="500">
</p>
SIRIUS is a domain specific library for electronic structure calculations. It is designed to work with codes such as Exciting, Elk and Quantum ESPRESSO. SIRIUS is written in C++11 with MPI, OpenMP and CUDA programming models. Up-to-date source code documantation is available here: https://electronic-structure.github.io/SIRIUS-doc.

## How to compile
SIRIUS depends on the following libraries: MPI, BLAS, LAPACK, GSL, LibXC, HDF5, spglib, FFTW and optionally on ScaLAPACK, ELPA, MAGMA and CUDA. Some of the libraries (GSL, LibXC, HDF5, spglib, FFTW) can be downloaded and configured automatically by the helper Python script ``prerequisite.py``, other libraries must be provided by a system or a developer. We use CMake as a building tool. To compile and install SIRIUS (assuming that all the libraries are installed in the standard paths) run a cmake command from an empty directory followed by a make command:
[![GitHub Releases](https://img.shields.io/github/release/electronic-structure/sirius.svg)](https://github.com/electronic-structure/SIRIUS/releases)
[![Documentation](https://img.shields.io/badge/docs-doxygen-blue.svg)](https://electronic-structure.github.io/SIRIUS-doc)
[![Licence](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/electronic-structure/SIRIUS/master/LICENSE)

## Table of contents
1. [Introduction](#introduction)
2. [Installation](#installation)
3. [Examples](#examples)

## Introduction
SIRIUS is a domain specific library for electronic structure calculations. It is designed to work with codes such as Exciting, Elk and Quantum ESPRESSO. SIRIUS is written in C++11 with MPI, OpenMP and CUDA programming models.

## Installation
SIRIUS depends on the following libraries: MPI, BLAS, LAPACK, GSL, LibXC, HDF5, spglib, FFTW and optionally on ScaLAPACK, ELPA, MAGMA and CUDA. Some of the libraries (GSL, LibXC, HDF5, spglib, FFTW) can be downloaded and configured automatically by the helper Python script ``prerequisite.py``, other libraries must be provided by a system or a developer. We use CMake as a building tool. To compile and install SIRIUS (assuming that all the libraries are installed in the standard paths) run a cmake command from an empty directory followed by a make command:
```console
$ mkdir _build
$ cd _build
Expand All @@ -14,3 +24,9 @@ $ make
$ make install
```
This will compile SIRIUS in a most simple way: CPU-only mode without parallel linear algebra routines.



## Examples


1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
5.8.6
2 changes: 1 addition & 1 deletion apps/atoms/atom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ void generate_atom_file(Free_atom& a,
sirius::Atom_symmetry_class atom_class(0, a);
atom_class.set_spherical_potential(veff);
atom_class.generate_radial_functions(relativity_t::none);
runtime::pstdout pout(Communicator::self());
pstdout pout(Communicator::self());
atom_class.write_enu(pout);
pout.flush();

Expand Down
2 changes: 1 addition & 1 deletion apps/dft_loop/sirius.scf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ enum class task_t : int
void json_output_common(json& dict__)
{
dict__["git_hash"] = git_hash;
dict__["build_date"] = build_date;
//dict__["build_date"] = build_date;
dict__["comm_world_size"] = Communicator::world().size();
dict__["threads_per_rank"] = omp_get_max_threads();
}
Expand Down
2 changes: 1 addition & 1 deletion apps/tests/test_allgather.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void test_allgather()
}

{
runtime::pstdout pout(Communicator::world());
sddk::pstdout pout(Communicator::world());
if (Communicator::world().rank() == 0) pout.printf("before\n");
pout.printf("rank : %i array : ", Communicator::world().rank());
for (int i = 0; i < N; i++)
Expand Down
2 changes: 1 addition & 1 deletion apps/tests/test_mpi_grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ void test_grid(std::vector<int> grid__)
{
MPI_grid mpi_grid(grid__, Communicator::world());

runtime::pstdout pout(Communicator::world());
pstdout pout(Communicator::world());

if (Communicator::world().rank() == 0) {
pout.printf("dimensions: %i %i %i\n", mpi_grid.communicator(1 << 0).size(), mpi_grid.communicator(1 << 1).size(),
Expand Down
6 changes: 4 additions & 2 deletions cmake/modules/FindFFTW.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ include(FindPackageHandleStandardArgs)

find_path(FFTW_INCLUDE_DIR
NAMES fftw3.h
PATH_SUFFIXES include/fftw
PATH_SUFFIXES include include/fftw
HINTS ENV MKLROOT
HINTS ENV FFTWROOT
HINTS ENV FFTW_INC
)

find_library(FFTW_LIBRARIES NAMES fftw3
find_library(FFTW_LIBRARIES
NAMES fftw3
PATH_SUFFIXES lib
HINTS ENV MKLROOT
HINTS ENV FFTW_DIR
HINTS ENV FFTWROOT
Expand Down
87 changes: 87 additions & 0 deletions make_version_hpp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import sys
import subprocess
import datetime
import json

# Use github REST API to query the tags
request_str = 'https://api.github.com/repos/electronic-structure/SIRIUS/tags'

def to_string(s):
"""
Convert to ASCII sring.
"""
if isinstance(s, str):
return s
else:
return s.decode('utf-8')

def get_sha(vstr):
"""
Get SHA hash of the code.
Try to call git. If git command is not found or this is not a git repository, try to read
the file VERSION to get the tag name. If none found, return an empty string.
"""

sha_str = ""

try:
p = subprocess.Popen(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
sha_str = p.communicate()[0].strip()
if p.returncode != 0: raise
except:
# python2 and python3 handle URL requests differently
if sys.version_info < (3, 0):
import urllib2
data = json.load(urllib2.urlopen(request_str))
else:
import urllib.request
req = urllib.request.Request(request_str)
data = json.load(urllib.request.urlopen(req))
# serach for a version tag
for e in data:
if e['name'] == 'v' + vstr:
sha_str = e['commit']['sha']
break

return to_string(sha_str)

def get_branch(sha_str, vstr):
"""
Get name of the branch. If git command failed but SHA is found, this is a release version
"""
branch_name = ""
try:
p = subprocess.Popen(["git", "describe", "--all"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
branch_name = p.communicate()[0].strip()
if p.returncode != 0: raise
except:
if sha_str:
branch_name = 'release tag v%s'%vstr
return to_string(branch_name)

def main():
print("/** \\file version.hpp")
print(" * \\brief Auto-generated version file.")
print(" */\n")
print("#ifndef __VERSION_HPP__")
print("#define __VERSION_HPP__")

now = datetime.datetime.now()

version_str = ""
# get version string from the file
try:
with open(sys.argv[1]) as vf:
version_str = vf.readline().strip()
except:
pass
sha_str = get_sha(version_str)
branch_name = get_branch(sha_str, version_str)

print("const char* const git_hash = \"%s\";"%sha_str)
print("const char* const git_branchname = \"%s\";"%branch_name)
#print("const char* const build_date = \"%s\";"%(now.strftime("%a, %e %b %Y %H:%M:%S")))
print("#endif")

if __name__ == "__main__":
main()
37 changes: 19 additions & 18 deletions python_module/py_sirius.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,26 +338,27 @@ PYBIND11_MODULE(py_sirius, m)
.def("update", &DFT_ground_state::update);

py::class_<K_point>(m, "K_point")
.def("band_energy", py::overload_cast<int, int>(&K_point::band_energy))
.def("band_energy", py::overload_cast<int, int>(&K_point::band_energy, py::const_))
.def_property_readonly("vk", &K_point::vk, py::return_value_policy::copy)
.def("generate_fv_states", &K_point::generate_fv_states)
.def("set_band_energy", [](K_point& kpoint, int j, int ispn, double val) {
kpoint.band_energy(j, ispn) = val;
})
.def("band_energies", [](K_point const& kpoint, int ispn) {
std::vector<double> energies(kpoint.num_bands());
for (int i = 0; i < kpoint.num_bands(); ++i) {
energies[i] = kpoint.band_energy(i, ispn);
}
return energies;
}, py::return_value_policy::copy)
.def("band_occupancy", [](K_point const& kpoint, int ispn) {
std::vector<double> occ(kpoint.num_bands());
for (int i = 0; i < kpoint.num_bands(); ++i) {
occ[i] = kpoint.band_occupancy(i, ispn);
}
return occ;
})
.def("set_band_energy", [](K_point& kpoint, int j, int ispn, double val) { kpoint.band_energy(j, ispn, val); })
.def("band_energies",
[](K_point const& kpoint, int ispn) {
std::vector<double> energies(kpoint.num_bands());
for (int i = 0; i < kpoint.num_bands(); ++i) {
energies[i] = kpoint.band_energy(i, ispn);
}
return energies;
},
py::return_value_policy::copy)
.def("band_occupancy",
[](K_point const& kpoint, int ispn) {
std::vector<double> occ(kpoint.num_bands());
for (int i = 0; i < kpoint.num_bands(); ++i) {
occ[i] = kpoint.band_occupancy(i, ispn);
}
return occ;
})
.def("gkvec_partition", &K_point::gkvec_partition, py::return_value_policy::reference_internal)
.def("gkvec", &K_point::gkvec, py::return_value_policy::reference_internal)
.def("fv_states", &K_point::fv_states, py::return_value_policy::reference_internal)
Expand Down
2 changes: 1 addition & 1 deletion src/Band/diag_full_potential.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,7 @@ inline void Band::diag_full_potential_second_variation(K_point& kp__, Hamiltonia
#endif
for (int ispn = 0; ispn < ctx_.num_spin_dims(); ispn++) {
for (int j = 0; j < ctx_.num_bands(); j++) {
kp__.band_energy(j, ispn) = band_energies(j, ispn);
kp__.band_energy(j, ispn, band_energies(j, ispn));
}
}
}
Expand Down
18 changes: 13 additions & 5 deletions src/Band/diag_pseudo_potential.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ inline void Band::diag_pseudo_potential_exact(K_point* kp__,
}

for (int j = 0; j < ctx_.num_bands(); j++) {
kp__->band_energy(j, ispn__) = eval[j];
kp__->band_energy(j, ispn__, eval[j]);
}

kp__->spinor_wave_functions().pw_coeffs(ispn__).remap_from(evec, 0);
Expand Down Expand Up @@ -298,7 +298,15 @@ inline int Band::diag_pseudo_potential_davidson(K_point* kp__,
t1.stop();

utils::timer t2("sirius::Band::diag_pseudo_potential_davidson|alloc");
auto mem_type = (ctx_.std_evp_solver_type() == ev_solver_t::magma) ? memory_t::host_pinned : memory_t::host;
auto mem_type = memory_t::host;
/* MAGMA library requires a pinned memory allocation; however the matrices are relatively small and the
effect of pinned memory is canceled by the expensive pinned memory allocation; the lines below
are commented during the debug of performance on CUDA9.1 and MAGMA-2.4 */
//if (ctx_.processing_unit() == GPU &&
// (ctx_.std_evp_solver_type() == ev_solver_t::magma || ctx_.blacs_grid().comm().size() == 1)) {
// mem_type = memory_t::host_pinned;
//}
// TODO: add a control variable to switch between MAGMA and Lapack depending, for example, on the matrix size

const int bs = ctx_.cyclic_block_size();

Expand All @@ -310,7 +318,7 @@ inline int Band::diag_pseudo_potential_davidson(K_point* kp__,

kp__->beta_projectors().prepare();

#ifdef __GPU
#ifdef __GPU
if (ctx_.processing_unit() == GPU) {
if (!ctx_.control().keep_wf_on_device_) {
for (int ispn = 0; ispn < ctx_.num_spins(); ispn++) {
Expand All @@ -335,7 +343,7 @@ inline int Band::diag_pseudo_potential_davidson(K_point* kp__,
hmlt.allocate(memory_t::device);
}
}
#endif
#endif

if (kp__->comm().rank() == 0 && ctx_.control().print_memory_usage_) {
MEMORY_USAGE_INFO();
Expand Down Expand Up @@ -458,7 +466,7 @@ inline int Band::diag_pseudo_potential_davidson(K_point* kp__,
{&psi}, 0, num_bands);
/* update eigen-values */
for (int j = 0; j < num_bands; j++) {
kp__->band_energy(j, ispin_step) = eval[j];
kp__->band_energy(j, ispin_step, eval[j]);
}
} else {
if (ctx_.control().verbosity_ >= 2 && kp__->comm().rank() == 0) {
Expand Down
Loading

0 comments on commit c9ae51d

Please sign in to comment.