Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
597e42d
Native Windows port (Phase 1 scaffolding): serial PW build on MinGW-w64
ErjieWu Jun 2, 2026
bd6371b
Native Windows port (Phase 1): serial PW build compiles, links, runs
ErjieWu Jun 2, 2026
4f2e62e
Fix all-zero seeded random wavefunctions in serial (non-MPI) PW build
ErjieWu Jun 2, 2026
f86fd99
Windows: use the existing toolchain + serial test harness, drop bespo…
ErjieWu Jun 2, 2026
b6ebfd6
Windows test: run the whole 01_PW suite, drop the curated case list
ErjieWu Jun 2, 2026
255513a
Windows toolchain: provide a generic `abacus` command after build
ErjieWu Jun 2, 2026
a32e103
Fix Binstream binary file I/O on Windows (force binary fopen mode)
ErjieWu Jun 2, 2026
32f6ab0
Fix uninitialized structure factor in serial bspline_sf (wrong energy)
ErjieWu Jun 2, 2026
77150d2
docs(windows): note pw_seed cross-platform non-reproducibility (078 i…
ErjieWu Jun 2, 2026
fe0f93b
toolchain(windows): clarify to run abacus_env.sh inside a mingw bash
ErjieWu Jun 2, 2026
1d0575d
fix(lcao): guard null deref of DeePKS overlap_orb_alpha when DeePKS i…
ErjieWu Jun 2, 2026
cb60705
Windows toolchain: add LCAO + MPI (MS-MPI + ScaLAPACK) build
ErjieWu Jun 2, 2026
2ed5a8c
toolchain(windows): make the unmodified test harness drive MS-MPI
ErjieWu Jun 3, 2026
763f788
toolchain(windows): add MS-MPI Bin (MSMPI_BIN) to PATH in abacus_env.sh
ErjieWu Jun 3, 2026
3acecd9
fix: restore Linux link of FFT_CPU<float> and harden parse_expression
ErjieWu Jun 3, 2026
5cfa159
fft: make the weak-vtable trick Windows-safe without touching Linux code
ErjieWu Jun 3, 2026
fa7b577
toolchain(windows): cap default build parallelism by available RAM
ErjieWu Jun 4, 2026
35262de
docs(windows): remove install_windows_native.md
ErjieWu Jun 4, 2026
1e88467
Merge branch 'develop' into windows
ErjieWu Jun 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# Shell scripts and the bash-parsed integration-test case lists must keep LF
# endings so they run under bash, including MSYS2/Git-Bash on Windows where
# core.autocrlf may rewrite them to CRLF (which breaks `#!/bin/bash` and adds
# stray \r to parsed lines such as the case names in CASES_*.txt).
*.sh text eol=lf
CASES_*.txt text eol=lf

.gitattributes export-ignore
.gitignore export-ignore
.gitmodules export-ignore
Expand Down
32 changes: 26 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ if(ENABLE_ASAN)
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
endif()

if(NOT CMAKE_BUILD_TYPE)
if(NOT CMAKE_BUILD_TYPE AND NOT MSVC)
add_compile_options(-O3 -g)
endif()

Expand All @@ -289,6 +289,14 @@ if(ENABLE_NATIVE_OPTIMIZATION)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mtune=native")
endif()

# Windows (native build, e.g. MinGW-w64 or MSVC) portability defines:
# _USE_MATH_DEFINES - expose M_PI and friends from <cmath>
# NOMINMAX - stop <windows.h> defining min()/max() macros
# _CRT_SECURE_NO_WARNINGS - silence CRT "use _s function" deprecations
if(WIN32)
add_compile_definitions(_USE_MATH_DEFINES NOMINMAX _CRT_SECURE_NO_WARNINGS)
endif()

if(ENABLE_LCAO)
find_package(Cereal REQUIRED)
include_directories(${CEREAL_INCLUDE_DIR})
Expand Down Expand Up @@ -610,8 +618,13 @@ elseif(NOT USE_SW)
find_package(Lapack REQUIRED)
include_directories(${FFTW3_INCLUDE_DIRS})
list(APPEND math_libs FFTW3::FFTW3 LAPACK::LAPACK BLAS::BLAS)
find_package(ScaLAPACK REQUIRED)
list(APPEND math_libs ScaLAPACK::ScaLAPACK)
# ScaLAPACK is a distributed-memory library and is only needed for the
# MPI build. A serial build (e.g. the native Windows serial version)
# must not require it.
if(ENABLE_MPI)
find_package(ScaLAPACK REQUIRED)
list(APPEND math_libs ScaLAPACK::ScaLAPACK)
endif()
if(USE_OPENMP)
list(APPEND math_libs FFTW3::FFTW3_OMP)
endif()
Expand Down Expand Up @@ -869,16 +882,23 @@ if (USE_SW)
list(APPEND math_libs gfortran)
endif()

list(APPEND math_libs m)
# libm exists on Linux and MinGW-w64 but not in the MSVC CRT.
if(NOT MSVC)
list(APPEND math_libs m)
endif()
target_link_libraries(${ABACUS_BIN_NAME} ${math_libs})

install(PROGRAMS ${ABACUS_BIN_PATH}
TYPE BIN
# DESTINATION ${CMAKE_INSTALL_BINDIR}
)

# Create a symbolic link 'abacus' pointing to the actual executable
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${ABACUS_BIN_NAME} ${CMAKE_INSTALL_PREFIX}/bin/abacus WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin)")
# Create a symbolic link 'abacus' pointing to the actual executable.
# Skipped on Windows: symlink creation needs elevated/developer-mode
# privileges there and the executable carries an .exe suffix anyway.
if(NOT WIN32)
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${ABACUS_BIN_NAME} ${CMAKE_INSTALL_PREFIX}/bin/abacus WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin)")
endif()

if(ENABLE_COVERAGE)
coverage_evaluate()
Expand Down
9 changes: 9 additions & 0 deletions cmake/FindBlas.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,16 @@ if(DEFINED BLAS_LIBRARY)
set(BLAS_LIBRARIES ${BLAS_LIBRARY})
endif()

# Delegate to CMake's builtin FindBLAS module. On case-insensitive
# filesystems (Windows, macOS) this file "FindBlas.cmake" and the builtin
# "FindBLAS.cmake" resolve to the same name, so a plain find_package(BLAS)
# recurses into this very file. Temporarily remove our module directory
# from CMAKE_MODULE_PATH so the builtin module is used instead. Harmless
# no-op on case-sensitive filesystems.
set(_abacus_blas_saved_module_path "${CMAKE_MODULE_PATH}")
list(REMOVE_ITEM CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
find_package(BLAS REQUIRED)
set(CMAKE_MODULE_PATH "${_abacus_blas_saved_module_path}")

if(NOT TARGET BLAS::BLAS)
add_library(BLAS::BLAS UNKNOWN IMPORTED)
Expand Down
10 changes: 10 additions & 0 deletions cmake/FindLapack.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,18 @@ if(DEFINED LAPACK_LIBRARY)
set(LAPACK_LIBRARIES ${LAPACK_LIBRARY})
endif()

# find_package(Blas) must resolve to our cmake/FindBlas.cmake wrapper, so
# leave CMAKE_MODULE_PATH intact for it.
find_package(Blas REQUIRED)

# Delegate to CMake's builtin FindLAPACK module. As with FindBlas, the names
# "FindLapack.cmake" and builtin "FindLAPACK.cmake" collide on
# case-insensitive filesystems, so drop our module directory from
# CMAKE_MODULE_PATH around the call to avoid infinite recursion.
set(_abacus_lapack_saved_module_path "${CMAKE_MODULE_PATH}")
list(REMOVE_ITEM CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
find_package(LAPACK REQUIRED)
set(CMAKE_MODULE_PATH "${_abacus_lapack_saved_module_path}")

if(NOT TARGET LAPACK::LAPACK)
add_library(LAPACK::LAPACK UNKNOWN IMPORTED)
Expand Down
48 changes: 48 additions & 0 deletions source/source_base/fs_compat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#ifndef MODULEBASE_FS_COMPAT_H
#define MODULEBASE_FS_COMPAT_H

//==========================================================
// Small filesystem-portability helpers.
//
// The POSIX `mkdir(path, mode)` takes a permission-mode argument that
// does not exist in the Windows CRT (`_mkdir`/MinGW `mkdir` take only a
// path). This header provides a single cross-platform directory-creation
// helper so call sites stay identical on every platform.
//==========================================================

#include <cerrno>
#include <string>

#ifdef _WIN32
#include <direct.h> // _mkdir
#else
#include <sys/stat.h> // mkdir
#include <sys/types.h>
#endif

namespace ModuleBase
{

/**
* @brief Create a single directory, portably.
*
* @param path directory path to create
* @return 0 on success; -1 on failure with `errno` set (e.g. EEXIST when
* the directory already exists), matching POSIX `mkdir` semantics.
*
* On Windows the permission mode is not applicable and is ignored; on
* POSIX systems the directory is created with mode 0755 (subject to umask),
* preserving the previous behaviour of the call sites.
*/
inline int make_directory(const std::string& path)
{
#ifdef _WIN32
return _mkdir(path.c_str());
#else
return mkdir(path.c_str(), 0755);
#endif
}

} // namespace ModuleBase

#endif // MODULEBASE_FS_COMPAT_H
16 changes: 7 additions & 9 deletions source/source_base/global_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@
#ifdef __MPI
#include <mpi.h>
#endif
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <cerrno>
#include <sstream>
#include "source_base/fs_compat.h"
#include "global_function.h"
#include "global_variable.h"
#include "source_base/parallel_common.h"
Expand Down Expand Up @@ -57,7 +55,7 @@ void ModuleBase::Global_File::make_dir_out(
{
if(rank==times)
{
int ret = mkdir(global_out_dir.c_str(), 0755);
int ret = ModuleBase::make_directory(global_out_dir);
if ( ret == 0 || errno == EEXIST )
{
std::cout << " MAKE THE DIR : " << global_out_dir << std::endl;
Expand Down Expand Up @@ -95,7 +93,7 @@ void ModuleBase::Global_File::make_dir_out(
{
if(rank==times)
{
int ret = mkdir(global_stru_dir.c_str(), 0755);
int ret = ModuleBase::make_directory(global_stru_dir);
if ( ret == 0 || errno == EEXIST )
{
std::cout << " MAKE THE STRU DIR : " << global_stru_dir << std::endl;
Expand Down Expand Up @@ -135,7 +133,7 @@ void ModuleBase::Global_File::make_dir_out(
{
if(rank==times)
{
int ret = mkdir(global_matrix_dir.c_str(), 0755);
int ret = ModuleBase::make_directory(global_matrix_dir);
if ( ret == 0 || errno == EEXIST )
{
std::cout << " MAKE THE MATRIX DIR : " << global_matrix_dir << std::endl;
Expand Down Expand Up @@ -174,7 +172,7 @@ void ModuleBase::Global_File::make_dir_out(
{
if(rank==times)
{
int ret = mkdir(global_wfc_dir.c_str(), 0755);
int ret = ModuleBase::make_directory(global_wfc_dir);
if ( ret == 0 || errno == EEXIST )
{
std::cout << " MAKE THE WFC DIR : " << global_wfc_dir << std::endl;
Expand Down Expand Up @@ -213,7 +211,7 @@ void ModuleBase::Global_File::make_dir_out(
{
if(rank==times)
{
int ret = mkdir(global_mlkedf_descriptor_dir.c_str(), 0755);
int ret = ModuleBase::make_directory(global_mlkedf_descriptor_dir);
if ( ret == 0 || errno == EEXIST )
{
std::cout << " MAKE THE MLKEDF DESCRIPTOR DIR : " << global_mlkedf_descriptor_dir << std::endl;
Expand Down Expand Up @@ -254,7 +252,7 @@ void ModuleBase::Global_File::make_dir_out(
{
if(rank==times)
{
int ret = mkdir(global_deepks_label_elec_dir.c_str(), 0755);
int ret = ModuleBase::make_directory(global_deepks_label_elec_dir);
if ( ret == 0 || errno == EEXIST )
{
std::cout << " MAKE THE DEEPKS LABELS (ELEC) DIR : " << global_deepks_label_elec_dir << std::endl;
Expand Down
6 changes: 2 additions & 4 deletions source/source_base/global_function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@
#include <fstream>
#include <iostream>
#include <string>
#include <sys/stat.h>
#include <sys/types.h>
#include <cerrno>
#include <unistd.h>
#include "source_base/fs_compat.h"

namespace ModuleBase
{
Expand Down Expand Up @@ -68,7 +66,7 @@ void MAKE_DIR(const std::string &fn)
// ModuleBase::TITLE("global_function","MAKE_DIR");
if (GlobalV::MY_RANK == 0)
{
int ret = mkdir(fn.c_str(), 0755);
int ret = ModuleBase::make_directory(fn);
if (ret != 0 && errno != EEXIST)
{
ModuleBase::WARNING_QUIT("MAKE_DIR", fn);
Expand Down
20 changes: 20 additions & 0 deletions source/source_base/module_container/base/core/cpu_allocator.cpp
Original file line number Diff line number Diff line change
@@ -1,28 +1,48 @@
#include <base/core/cpu_allocator.h>

#include <cstddef>
#ifdef _WIN32
#include <malloc.h> // _aligned_malloc / _aligned_free
#endif

namespace base {
namespace core {

// Allocate a block of CPU memory with the given size and default alignment.
// On Windows the aligned allocator family is used consistently so that every
// pointer handed out by this class can be released through free() below
// (_aligned_malloc memory must not be released with ::operator delete).
void *CPUAllocator::allocate(size_t size) {
this->allocated_size_ = size;
#ifdef _WIN32
return _aligned_malloc(size, alignof(std::max_align_t));
#else
return ::operator new(size);
#endif
}

// Allocate a block of CPU memory with the given size and alignment.
void *CPUAllocator::allocate(size_t size, size_t alignment) {
this->allocated_size_ = size;
void *ptr = nullptr;
#ifdef _WIN32
ptr = _aligned_malloc(size, alignment); // posix_memalign has no Windows CRT equivalent
#else
if (posix_memalign(&ptr, alignment, size) != 0) {
ptr = nullptr;
}
#endif
Comment thread
ErjieWu marked this conversation as resolved.
return ptr;
}

// Free a block of CPU memory that was previously allocated by this allocator.
void CPUAllocator::free(void *ptr) {
this->allocated_size_ = 0;
#ifdef _WIN32
_aligned_free(ptr);
#else
::operator delete(ptr);
#endif
}

// Get the type of device used by the TensorBuffer.
Expand Down
Loading
Loading