mirror of
https://github.com/CHN-beta/nixos.git
synced 2026-01-11 22:49:56 +08:00
Compare commits
10 Commits
d92b202b8e
...
6efc29a7a4
| Author | SHA1 | Date | |
|---|---|---|---|
| 6efc29a7a4 | |||
| c0c8bc3704 | |||
| 73a1490fed | |||
| 1bb6e550d8 | |||
| c9bd7b48d7 | |||
| d1d27ce194 | |||
| 3f46eb23de | |||
| 4cb983ce32 | |||
| 87c6d0fab4 | |||
| e5f7e1650e |
@@ -115,10 +115,17 @@ inputs:
|
|||||||
services.colord.enable = true;
|
services.colord.enable = true;
|
||||||
services.udev.extraRules =
|
services.udev.extraRules =
|
||||||
''
|
''
|
||||||
|
# 禁止鼠标等在睡眠时唤醒
|
||||||
|
ACTION=="add", ATTR{power/wakeup}="disabled"
|
||||||
# CPU降压
|
# CPU降压
|
||||||
SUBSYSTEM=="power_supply", KERNEL=="BAT0", ACTION=="*", RUN+="${inputs.pkgs.ryzenadj}/bin/ryzenadj --set-coall=0x0fff40"
|
SUBSYSTEM=="power_supply", KERNEL=="BAT0", ACTION=="*", RUN+="${inputs.pkgs.ryzenadj}/bin/ryzenadj --set-coall=0x0fff40"
|
||||||
'';
|
'';
|
||||||
# 解决有时蓝牙不能使用的问题
|
boot.kernelParams =
|
||||||
boot.kernelParams = [ "mt7925e.disable_aspm=1" ];
|
[
|
||||||
|
# 解决有时蓝牙不能使用的问题
|
||||||
|
"mt7925e.disable_aspm=1"
|
||||||
|
# 插拔电源和扩展坞不要唤醒电脑
|
||||||
|
"acpi.ec_no_wakeup=1"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
9
devices/wlin/bsub.nix
Normal file
9
devices/wlin/bsub.nix
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
normal = [ 4 4 20 ];
|
||||||
|
normal_1day = [ 4 7 28 ];
|
||||||
|
normal_1week = [ 4 7 28 ];
|
||||||
|
normal_2week = [ 6 8 48 ];
|
||||||
|
normal_1day_new = [ 4 6 24 ];
|
||||||
|
ocean_530_1day = [ 4 6 24 ];
|
||||||
|
ocean6226R_1day = [ 4 8 32 ];
|
||||||
|
}
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# sudo nix build --store 'local?store=/data/gpfs01/wlin/.nix/store&state=/data/gpfs01/wlin/.nix/state&log=/data/gpfs01/wlin/.nix/log' .#wlin
|
||||||
|
# sudo nix-store --store 'local?store=/data/gpfs01/wlin/.nix/store&state=/data/gpfs01/wlin/.nix/state&log=/data/gpfs01/wlin/.nix/log' -qR ./result | grep -Fxv -f <(ssh wlin find .nix/store -maxdepth 1 -exec realpath '{}' '\;') | sudo xargs nix-store --store 'local?store=/data/gpfs01/wlin/.nix/store&state=/data/gpfs01/wlin/.nix/state&log=/data/gpfs01/wlin/.nix/log' --export | pv > wlin.nar
|
||||||
|
# cat wlin.nar | nix-store --import
|
||||||
{ inputs, localLib }:
|
{ inputs, localLib }:
|
||||||
let
|
let
|
||||||
pkgs = import inputs.nixpkgs (localLib.buildNixpkgsConfig
|
pkgs = import inputs.nixpkgs (localLib.buildNixpkgsConfig
|
||||||
@@ -5,10 +8,17 @@ let
|
|||||||
inputs = { inherit (inputs.nixpkgs) lib; topInputs = inputs; };
|
inputs = { inherit (inputs.nixpkgs) lib; topInputs = inputs; };
|
||||||
nixpkgs = { march = "haswell"; nixRoot = "/data/gpfs01/wlin/.nix"; nixos = false; };
|
nixpkgs = { march = "haswell"; nixRoot = "/data/gpfs01/wlin/.nix"; nixos = false; };
|
||||||
});
|
});
|
||||||
|
python = pkgs.python3.withPackages (ps: with ps; [ phonopy ]);
|
||||||
|
chn-bsub = pkgs.localPackages.chn-bsub.overrideAttrs
|
||||||
|
(prev: { bsubConfig = builtins.toFile "bsub.yaml" (builtins.toJSON (import ./bsub.nix)); });
|
||||||
wlin = pkgs.symlinkJoin
|
wlin = pkgs.symlinkJoin
|
||||||
{
|
{
|
||||||
name = "wlin";
|
name = "wlin";
|
||||||
paths = with pkgs; [ gnuplot localPackages.vaspkit pv ];
|
paths = with pkgs;
|
||||||
|
[
|
||||||
|
gnuplot localPackages.vaspkit pv python localPackages.vasp.intel chn-bsub hwloc
|
||||||
|
lsd
|
||||||
|
];
|
||||||
postBuild = "echo ${inputs.self.rev or "dirty"} > $out/.version";
|
postBuild = "echo ${inputs.self.rev or "dirty"} > $out/.version";
|
||||||
passthru = { inherit pkgs; archive = pkgs.closureInfo { rootPaths = [ wlin.drvPath ]; }; };
|
passthru = { inherit pkgs; archive = pkgs.closureInfo { rootPaths = [ wlin.drvPath ]; }; };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,7 +6,5 @@ if [ -f ~/.bashrc ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# User specific environment and startup programs
|
# User specific environment and startup programs
|
||||||
|
export PATH=/data/gpfs01/wlin/.nix/state/gcroots/current/bin:$HOME/bin:$PATH
|
||||||
PATH=$PATH:$HOME/bin
|
ulimit -s unlimited
|
||||||
|
|
||||||
export PATH
|
|
||||||
|
|||||||
@@ -4,40 +4,4 @@
|
|||||||
if [ -f /etc/bashrc ]; then
|
if [ -f /etc/bashrc ]; then
|
||||||
. /etc/bashrc
|
. /etc/bashrc
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export PATH=$PATH:/data/gpfs01/wlin/bin
|
|
||||||
|
|
||||||
# User specific aliases and functions
|
|
||||||
export PATH=/data/gpfs01/wlin/bin/vaspkit.1.4.1/bin:${PATH}
|
|
||||||
#export PATH=~/bin:/data/gpfs01/wlin/opt/mpich_ifort/bin:$PATH
|
|
||||||
#export LD_LIBRARY_PATH=/data/gpfs01/wlin/opt/mpich_ifort/lib:$LD_LIBRARY_PATH
|
|
||||||
#export PATH=~/bin:/data/gpfs01/wlin/opt/mpich/bin:$PATH
|
|
||||||
#export LD_LIBRARY_PATH=/data/gpfs01/wlin/opt/mpich/lib:$LD_LIBRARY_PATH
|
|
||||||
export P4_RSHCOMMAND=ssh
|
|
||||||
shopt -s cdspell
|
|
||||||
export HISTCONTROL=ignoredups
|
|
||||||
#shopt -s histappend
|
|
||||||
PROMPT_COMMAND='history -a'
|
|
||||||
export C3_RSH="ssh -x"
|
|
||||||
export OMP_NUM_THREADS=1
|
|
||||||
export MKL_NUM_THREADS=1
|
|
||||||
alias grep='grep --color'
|
|
||||||
USER_IP=`who -u am i 2>/dev/null| awk '{print $NF}'|sed -e 's/[()]//g'`
|
|
||||||
|
|
||||||
export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S `whoami`@${USER_IP}: "
|
|
||||||
export HISTFILESIZE=1000000
|
export HISTFILESIZE=1000000
|
||||||
export PROMPT_COMMAND="history -a; history -r; $PROMPT_COMMAND"
|
|
||||||
shopt -s histappend
|
|
||||||
# Auto add env parameter $PROMPT_COMMAND when use non-Linux tty login by ssh.
|
|
||||||
if [ "$SSH_CONNECTION" != '' -a "$TERM" != 'linux' ]; then
|
|
||||||
declare -a HOSTIP
|
|
||||||
HOSTIP=`echo $SSH_CONNECTION |awk '{print $3}'`
|
|
||||||
export PROMPT_COMMAND='echo -ne "\033]0;${USER}@$HOSTIP:[${HOSTNAME%%.*}]:${PWD/#$HOME/~} \007"'
|
|
||||||
fi
|
|
||||||
ulimit -s unlimited
|
|
||||||
export PYTHONPATH=/data/gpfs01/wlin/bin/VaspBandUnfolding-master:${PYTHONPATH}
|
|
||||||
|
|
||||||
# vsts, see https://theory.cm.utexas.edu/vtsttools/scripts.html
|
|
||||||
export PATH=$PATH:/data/gpfs01/wlin/yjj/vtstscripts-1022
|
|
||||||
export PERL5LIB=/data/gpfs01/wlin/yjj/vtstscripts-1022
|
|
||||||
|
|
||||||
|
|||||||
2
devices/wlin/files/.config/nix/nix.conf
Normal file
2
devices/wlin/files/.config/nix/nix.conf
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
store = local?store=/data/gpfs01/wlin/.nix/store&state=/data/gpfs01/wlin/.nix/state&log=/data/gpfs01/wlin/.nix/log
|
||||||
|
experimental-features = flakes nix-command
|
||||||
@@ -47,7 +47,6 @@ inputs:
|
|||||||
host = host;
|
host = host;
|
||||||
hostname = "hpc.xmu.edu.cn";
|
hostname = "hpc.xmu.edu.cn";
|
||||||
user = host;
|
user = host;
|
||||||
setEnv.TERM = "chn_unset_ls_colors:xterm-256color";
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
[ "wlin" "hwang" ])
|
[ "wlin" "hwang" ])
|
||||||
|
|||||||
@@ -92,7 +92,13 @@ inputs:
|
|||||||
mode = { width = 3840; height = 2160; refresh = 160.; };
|
mode = { width = 3840; height = 2160; refresh = 160.; };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
input = { touchpad.dwt = true; keyboard.numlock = true; };
|
input =
|
||||||
|
{
|
||||||
|
touchpad.dwt = true;
|
||||||
|
keyboard.numlock = true;
|
||||||
|
power-key-handling.enable = false;
|
||||||
|
focus-follows-mouse.enable = true;
|
||||||
|
};
|
||||||
layout =
|
layout =
|
||||||
{
|
{
|
||||||
default-column-width.proportion = 0.5;
|
default-column-width.proportion = 0.5;
|
||||||
|
|||||||
@@ -3,7 +3,11 @@ inputs:
|
|||||||
config =
|
config =
|
||||||
{
|
{
|
||||||
# only preserve the last 7 days of logs
|
# only preserve the last 7 days of logs
|
||||||
services.journald.extraConfig = "MaxRetentionSec=7d";
|
services =
|
||||||
|
{
|
||||||
|
journald.extraConfig = "MaxRetentionSec=7d";
|
||||||
|
logind.settings.Login.HandleLidSwitch = "ignore";
|
||||||
|
};
|
||||||
systemd =
|
systemd =
|
||||||
{
|
{
|
||||||
settings.Manager =
|
settings.Manager =
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ inputs:
|
|||||||
xmuhk = { host = "xmuhk"; hostname = "10.26.14.64"; user = "xmuhk"; };
|
xmuhk = { host = "xmuhk"; hostname = "10.26.14.64"; user = "xmuhk"; };
|
||||||
xmuhk2 = { host = "xmuhk2"; hostname = "183.233.219.132"; user = "xmuhk"; port = 62022; };
|
xmuhk2 = { host = "xmuhk2"; hostname = "183.233.219.132"; user = "xmuhk"; port = 62022; };
|
||||||
jykang.setEnv.TERM = "chn_unset_ls_colors:chn_cd:linwei/chn:xterm-256color";
|
jykang.setEnv.TERM = "chn_unset_ls_colors:chn_cd:linwei/chn:xterm-256color";
|
||||||
|
wlin.setEnv.TERM = "xterm-256color";
|
||||||
"tinc0.jykang" = jykang;
|
"tinc0.jykang" = jykang;
|
||||||
};
|
};
|
||||||
extraConfig = inputs.lib.mkIf inputs.config.nixos.model.private
|
extraConfig = inputs.lib.mkIf inputs.config.nixos.model.private
|
||||||
|
|||||||
1
packages/chn-bsub/.envrc
Normal file
1
packages/chn-bsub/.envrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
use flake .#chn-bsub
|
||||||
@@ -10,14 +10,14 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(ftxui REQUIRED)
|
find_package(ftxui REQUIRED)
|
||||||
find_package(Boost REQUIRED COMPONENTS filesystem iostreams)
|
|
||||||
find_package(range-v3 REQUIRED)
|
|
||||||
find_package(biu REQUIRED)
|
find_package(biu REQUIRED)
|
||||||
|
|
||||||
add_executable(chn-bsub src/main.cpp)
|
add_executable(chn-bsub src/main.cpp)
|
||||||
target_compile_features(chn-bsub PUBLIC cxx_std_23)
|
target_compile_features(chn-bsub PUBLIC cxx_std_23)
|
||||||
target_link_libraries(chn-bsub PRIVATE fmt::fmt ftxui::screen ftxui::dom ftxui::component Boost::filesystem
|
target_link_libraries(chn-bsub PRIVATE ftxui::screen ftxui::dom ftxui::component biu::biu)
|
||||||
range-v3::range-v3 biu::biu)
|
if(BSUB_CONFIG)
|
||||||
|
target_compile_definitions(chn-bsub PRIVATE BSUB_CONFIG="${BSUB_CONFIG}")
|
||||||
|
endif()
|
||||||
|
|
||||||
install(TARGETS chn-bsub RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
install(TARGETS chn-bsub RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
|
||||||
|
|||||||
4
packages/chn-bsub/bsub.yaml
Normal file
4
packages/chn-bsub/bsub.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
Queues:
|
||||||
|
normal: [ 4, 4, 20 ]
|
||||||
|
normal_1day: [ 4, 7, 28 ]
|
||||||
|
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
{ stdenv, lib, cmake, pkg-config, ftxui, biu }: stdenv.mkDerivation
|
{ stdenv, cmake, pkg-config, ftxui, biu, bsubConfig ? null, lib }: stdenv.mkDerivation
|
||||||
{
|
{
|
||||||
name = "chn-bsub";
|
name = "chn-bsub";
|
||||||
src = ./.;
|
src = ./.;
|
||||||
buildInputs = [ ftxui biu ];
|
buildInputs = [ ftxui biu ];
|
||||||
nativeBuildInputs = [ cmake pkg-config ];
|
nativeBuildInputs = [ cmake pkg-config ];
|
||||||
postInstall = "ln -s chn-bsub $out/bin/chn_bsub";
|
postInstall = "ln -s chn-bsub $out/bin/chn_bsub";
|
||||||
|
cmakeFlags = lib.optional (bsubConfig != null) [ "-DBSUB_CONFIG=${bsubConfig}" ];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,202 +1,177 @@
|
|||||||
# include <map>
|
# include <biu.hpp>
|
||||||
# include <filesystem>
|
|
||||||
# include <ftxui/component/component.hpp>
|
# include <ftxui/component/component.hpp>
|
||||||
# include <ftxui/component/component_options.hpp>
|
# include <ftxui/component/component_options.hpp>
|
||||||
# include <ftxui/component/screen_interactive.hpp>
|
# include <ftxui/component/screen_interactive.hpp>
|
||||||
# include <boost/process.hpp>
|
# include <boost/process.hpp>
|
||||||
# include <boost/algorithm/string.hpp>
|
# include <boost/algorithm/string.hpp>
|
||||||
# include <biu.hpp>
|
|
||||||
|
# ifndef BSUB_CONFIG
|
||||||
|
# define BSUB_CONFIG "./bsub.yaml"
|
||||||
|
# endif
|
||||||
|
|
||||||
using namespace biu::literals;
|
using namespace biu::literals;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// 需要绑定到界面上的变量
|
biu::Logger::Guard log;
|
||||||
struct
|
enum class UserCommandType { Continue, Back, Quit };
|
||||||
{
|
enum class InterfaceType { Request, Confirm };
|
||||||
std::array<int, 3> vasp_version_selected = {0, 0, 0};
|
struct
|
||||||
std::vector<std::string> vasp_version_entries_level1 = {"640", "631"};
|
{
|
||||||
std::map<std::string, std::vector<std::string>> vasp_version_entries_level2 =
|
std::optional<UserCommandType> UserCommand;
|
||||||
|
std::string SubmitCommand;
|
||||||
|
InterfaceType CurrentInterface = InterfaceType::Request;
|
||||||
|
int VaspSelected = 0;
|
||||||
|
std::vector<std::string> VaspEntries = { "std", "gam", "ncl" };
|
||||||
|
int QueueSelected = 0;
|
||||||
|
std::vector<std::string> QueueEntries;
|
||||||
|
std::string JobName = []
|
||||||
{
|
{
|
||||||
{"640", {"(default)", "fixc", "optcell_vtst_wannier90", "shmem", "vtst"}},
|
// /data/gpfs01/wlin/chn/lammps-SiC
|
||||||
{"631", {"shmem"}}
|
|
||||||
};
|
|
||||||
std::vector<std::string> vasp_version_entries_level3 = {"std", "gam", "ncl"};
|
|
||||||
|
|
||||||
int queue_selected = 0;
|
|
||||||
std::vector<std::string> queue_entries =
|
|
||||||
{
|
|
||||||
"normal_1day", "normal_1week", "normal",
|
|
||||||
"normal_1day_new", "ocean_530_1day", "ocean6226R_1day"
|
|
||||||
};
|
|
||||||
std::map<std::string, std::size_t> max_cores =
|
|
||||||
{
|
|
||||||
{"normal_1day", 28}, {"normal_1week", 28}, {"normal", 20},
|
|
||||||
{"normal_1day_new", 24}, {"ocean_530_1day", 24}, {"ocean6226R_1day", 32}
|
|
||||||
};
|
|
||||||
std::string ncores = "";
|
|
||||||
std::string job_name = []
|
|
||||||
{
|
|
||||||
// /data/gpfs01/jykang/linwei/chn/lammps-SiC
|
|
||||||
std::vector<std::string> paths;
|
std::vector<std::string> paths;
|
||||||
boost::split(paths, std::filesystem::current_path().string(),
|
boost::split(paths, std::filesystem::current_path().string(), boost::is_any_of("/"));
|
||||||
boost::is_any_of("/"));
|
if (paths.size() < 6) return "my-great-job"s;
|
||||||
if (paths.size() < 7)
|
else return paths[4] + "_" + paths.back();
|
||||||
return "my-great-job"s;
|
|
||||||
else
|
|
||||||
return paths[5] + "_" + paths.back();
|
|
||||||
}();
|
}();
|
||||||
std::string bsub = "";
|
std::string OutputFile = "output.txt";
|
||||||
std::string user_command = "";
|
} State;
|
||||||
} state;
|
struct { std::map<std::string, std::array<int, 3>> Queues; } QueueConfig =
|
||||||
|
YAML::LoadFile(BSUB_CONFIG).as<decltype(QueueConfig)>();
|
||||||
|
State.QueueEntries = QueueConfig.Queues
|
||||||
|
| ranges::views::transform([](auto const& item) { return item.first; })
|
||||||
|
| ranges::to_vector;
|
||||||
|
|
||||||
// 为组件增加标题栏
|
// 为组件增加标题栏
|
||||||
auto component_with_title = [](std::string title, ftxui::Component component)
|
auto with_title = [](std::string title, ftxui::Color bgcolor = ftxui::Color::Blue)
|
||||||
{
|
{
|
||||||
return ftxui::Renderer(component, [title, component]
|
return [=](ftxui::Element element)
|
||||||
{
|
{ return ftxui::vbox(ftxui::text(title) | ftxui::bgcolor(bgcolor), element); };
|
||||||
return ftxui::vbox
|
};
|
||||||
({
|
// 为组件增加下边框
|
||||||
ftxui::text(title) | ftxui::bgcolor(ftxui::Color::Blue),
|
auto with_bottom = [](ftxui::Element element)
|
||||||
component->Render(),
|
{ return ftxui::vbox(element, ftxui::separatorLight()); };
|
||||||
ftxui::separator()
|
// 为组件增加比较粗的下边框
|
||||||
});
|
auto with_bottom_heavy = [](ftxui::Element element)
|
||||||
});
|
{ return ftxui::vbox(element, ftxui::separatorHeavy()); };
|
||||||
};
|
// 在组件左边增加小标题
|
||||||
|
auto with_subtitle = [](std::string title)
|
||||||
|
{ return [title](ftxui::Element element) { return ftxui::hbox(ftxui::text(title), element); }; };
|
||||||
|
// 带标题的文本输入框
|
||||||
|
auto input = [with_subtitle](std::string* content, std::string title)
|
||||||
|
{
|
||||||
|
return ftxui::Input(content) | ftxui::underlined
|
||||||
|
| ftxui::size(ftxui::WIDTH, ftxui::GREATER_THAN, 3)
|
||||||
|
| ftxui::size(ftxui::HEIGHT, ftxui::EQUAL, 1)
|
||||||
|
| with_subtitle(title);
|
||||||
|
};
|
||||||
|
// 在组件左边增加分割线
|
||||||
|
auto with_separator = [](ftxui::Element element)
|
||||||
|
{ return ftxui::hbox(ftxui::separatorLight(), element); };
|
||||||
|
// 为组件增加空白以填充界面
|
||||||
|
auto with_padding = [](ftxui::Element element)
|
||||||
|
{
|
||||||
|
auto empty = ftxui::emptyElement() | ftxui::flex_grow;
|
||||||
|
return ftxui::vbox(empty, ftxui::hbox(empty, element | ftxui::center, empty), empty);
|
||||||
|
};
|
||||||
|
// 转义字符
|
||||||
|
auto escape = [](std::string str)
|
||||||
|
{
|
||||||
|
return str | ranges::views::transform([](char c)
|
||||||
|
{
|
||||||
|
// only the following characters need to be escaped: $ ` \ " newline * @ space tab
|
||||||
|
if (std::set{'$', '`', '\\', '\"', '\n', '*', '@', ' ', '\t'}.contains(c))
|
||||||
|
return '\\' + std::string(1, c);
|
||||||
|
else return std::string(1, c);
|
||||||
|
}) | ranges::views::join("") | ranges::to<std::string>;
|
||||||
|
};
|
||||||
|
|
||||||
// 构建界面, 需要至少 25 行 47 列
|
// 构建界面
|
||||||
auto screen = ftxui::ScreenInteractive::Fullscreen();
|
auto Screen = ftxui::ScreenInteractive::Fullscreen();
|
||||||
auto request_interface = [&state, &screen, &component_with_title]
|
auto key_event_handler = [&](ftxui::Event event)
|
||||||
{
|
{
|
||||||
auto vasp_version_level1 = ftxui::Menu
|
if (event == ftxui::Event::Return)
|
||||||
(&state.vasp_version_entries_level1, &state.vasp_version_selected[0])
|
{ State.UserCommand = UserCommandType::Continue; Screen.ExitLoopClosure()(); return true; }
|
||||||
| ftxui::size(ftxui::WIDTH, ftxui::EQUAL, 8);
|
else return false;
|
||||||
std::vector<ftxui::Component> vasp_version_level2_children;
|
};
|
||||||
for (auto& i : state.vasp_version_entries_level1)
|
auto InterfaceRequest = ftxui::Container::Vertical
|
||||||
vasp_version_level2_children.push_back(ftxui::Menu
|
({
|
||||||
(
|
ftxui::Container::Horizontal
|
||||||
&state.vasp_version_entries_level2[i],
|
|
||||||
&state.vasp_version_selected[1]
|
|
||||||
));
|
|
||||||
auto vasp_version_level2 = ftxui::Container::Tab
|
|
||||||
(
|
|
||||||
vasp_version_level2_children,
|
|
||||||
&state.vasp_version_selected[0]
|
|
||||||
) | ftxui::size(ftxui::WIDTH, ftxui::EQUAL, 27);
|
|
||||||
auto vasp_version_level3 = ftxui::Menu
|
|
||||||
(&state.vasp_version_entries_level3, &state.vasp_version_selected[2])
|
|
||||||
| ftxui::size(ftxui::WIDTH, ftxui::EQUAL, 8);
|
|
||||||
auto vasp_version = component_with_title("Select vasp version:",
|
|
||||||
ftxui::Container::Horizontal
|
|
||||||
({vasp_version_level1, vasp_version_level2, vasp_version_level3})
|
|
||||||
| ftxui::size(ftxui::HEIGHT, ftxui::EQUAL, 5));
|
|
||||||
auto queue = component_with_title("Select queue:",
|
|
||||||
ftxui::Menu(&state.queue_entries, &state.queue_selected)
|
|
||||||
| ftxui::size(ftxui::HEIGHT, ftxui::EQUAL, 6));
|
|
||||||
auto ncores = component_with_title("Input cores you want to use:",
|
|
||||||
ftxui::Input(&state.ncores, "(leave blank to use all cores)"))
|
|
||||||
| ftxui::size(ftxui::HEIGHT, ftxui::EQUAL, 3);
|
|
||||||
auto job_name = component_with_title("Job name:",
|
|
||||||
ftxui::Input(&state.job_name, ""))
|
|
||||||
| ftxui::size(ftxui::HEIGHT, ftxui::EQUAL, 3);
|
|
||||||
auto continue_button = ftxui::Button("Continue",
|
|
||||||
[&]{state.user_command = "continue"; screen.ExitLoopClosure()();});
|
|
||||||
auto quit_button = ftxui::Button("Quit",
|
|
||||||
[&]{state.user_command = "quit"; screen.ExitLoopClosure()();});
|
|
||||||
return ftxui::Container::Vertical
|
|
||||||
({
|
({
|
||||||
vasp_version, queue, ncores, job_name,
|
ftxui::Menu(&State.VaspEntries, &State.VaspSelected) | with_title("VASP variant:"),
|
||||||
ftxui::Container::Horizontal({continue_button, quit_button})
|
ftxui::Menu(&State.QueueEntries, &State.QueueSelected)
|
||||||
}) | ftxui::borderHeavy
|
| with_title("Queue:") | with_separator
|
||||||
| ftxui::size(ftxui::WIDTH, ftxui::EQUAL, 47)
|
}) | with_bottom_heavy,
|
||||||
| ftxui::size(ftxui::HEIGHT, ftxui::EQUAL, 24);
|
input(&State.JobName, "Job name: "),
|
||||||
}();
|
input(&State.OutputFile, "Output file: "),
|
||||||
auto confirm_interface = [&state, &screen, &component_with_title]
|
// 操作按钮
|
||||||
{
|
ftxui::Container::Horizontal
|
||||||
ftxui::InputOption input_option;
|
|
||||||
input_option.multiline = true;
|
|
||||||
return ftxui::Container::Vertical
|
|
||||||
({
|
({
|
||||||
component_with_title
|
ftxui::Button("Continue (Enter)",
|
||||||
(
|
[&]{ State.UserCommand = UserCommandType::Continue; Screen.ExitLoopClosure()(); }),
|
||||||
"Double check & modify submit command:",
|
ftxui::Button("Quit",
|
||||||
ftxui::Input(&state.bsub, "", input_option)
|
[&]{ State.UserCommand = UserCommandType::Quit; Screen.ExitLoopClosure()(); })
|
||||||
)
|
}),
|
||||||
| ftxui::size(ftxui::HEIGHT, ftxui::EQUAL, 7),
|
}) | ftxui::borderHeavy | with_padding | ftxui::CatchEvent(key_event_handler);
|
||||||
ftxui::Container::Horizontal
|
auto InterfaceConfirm = ftxui::Container::Vertical
|
||||||
({
|
({
|
||||||
ftxui::Button("Submit",
|
ftxui::Input(&State.SubmitCommand, "", ftxui::InputOption{.multiline = true})
|
||||||
[&]{state.user_command = "submit"; screen.ExitLoopClosure()();}),
|
| with_title("Double check & modify submit command:") | with_bottom_heavy,
|
||||||
ftxui::Button("Quit",
|
ftxui::Container::Horizontal
|
||||||
[&]{state.user_command = "quit"; screen.ExitLoopClosure()();}),
|
({
|
||||||
ftxui::Button("Back",
|
ftxui::Button("Submit (Enter)",
|
||||||
[&]{state.user_command = "back"; screen.ExitLoopClosure()();})
|
[&]{State.UserCommand = UserCommandType::Continue; Screen.ExitLoopClosure()();}),
|
||||||
}),
|
ftxui::Button("Back",
|
||||||
ftxui::Renderer([]{return ftxui::vbox
|
[&]{State.UserCommand = UserCommandType::Back; Screen.ExitLoopClosure()();}),
|
||||||
({
|
ftxui::Button("Quit",
|
||||||
ftxui::separator(),
|
[&]{State.UserCommand = UserCommandType::Quit; Screen.ExitLoopClosure()();})
|
||||||
ftxui::text("Source code:"),
|
})
|
||||||
ftxui::text("https://github.com/CHN-beta/chn_bsub.git"),
|
}) | ftxui::borderHeavy | with_padding | ftxui::CatchEvent(key_event_handler);
|
||||||
ftxui::text("Star & PR are welcome!"),
|
|
||||||
});})
|
|
||||||
}) | ftxui::borderHeavy
|
|
||||||
| ftxui::size(ftxui::WIDTH, ftxui::EQUAL, 47)
|
|
||||||
| ftxui::size(ftxui::HEIGHT, ftxui::EQUAL, 14);
|
|
||||||
}();
|
|
||||||
|
|
||||||
// 实际投递任务
|
// 进入事件循环
|
||||||
auto submit = [](std::string bsub)
|
while (true)
|
||||||
{
|
{
|
||||||
// replace \n with space
|
if (State.CurrentInterface == InterfaceType::Request)
|
||||||
boost::replace_all(bsub, "\n", " ");
|
{
|
||||||
auto process = boost::process::child
|
State.UserCommand.reset();
|
||||||
(
|
Screen.Loop(InterfaceRequest);
|
||||||
boost::process::search_path("sh"), "-c", bsub,
|
if (State.UserCommand == UserCommandType::Quit) return 0;
|
||||||
boost::process::std_in.close(),
|
else if (State.UserCommand == UserCommandType::Continue)
|
||||||
boost::process::std_out > stdout,
|
{
|
||||||
boost::process::std_err > stderr
|
State.CurrentInterface = InterfaceType::Confirm;
|
||||||
);
|
State.SubmitCommand = [&]
|
||||||
process.wait();
|
{
|
||||||
};
|
auto [nproc, nthr, ncpu] = QueueConfig.Queues.at(State.QueueEntries[State.QueueSelected]);
|
||||||
|
auto args = std::vector<std::string>
|
||||||
// 进入事件循环
|
{
|
||||||
while (true)
|
"bsub",
|
||||||
{
|
"-J {} -o {}"_f(escape(State.JobName), escape(State.OutputFile)),
|
||||||
screen.Loop(request_interface);
|
"-q {} -n {} -R 'span[hosts=1]'"_f(escape(State.QueueEntries[State.QueueSelected]), ncpu),
|
||||||
if (state.user_command == "quit")
|
"vasp-intel mpirun -n {} -x OMP_NUM_THREADS={} vasp-{}"_f
|
||||||
return EXIT_FAILURE;
|
(nproc, nthr, State.VaspEntries[State.VaspSelected])
|
||||||
else if (state.user_command != "continue")
|
};
|
||||||
throw std::runtime_error("user_command is not recognized");
|
return args | ranges::views::join(" \\\n ") | ranges::to<std::string>;
|
||||||
state.bsub = fmt::format
|
}();
|
||||||
(
|
}
|
||||||
"bsub -J '{}'\n-q {}\n-n {}\n-R 'span[hosts=1]'\n-o 'output.txt'\nchn_vasp.sh {}",
|
else if (!State.UserCommand) return EXIT_FAILURE;
|
||||||
state.job_name,
|
else std::unreachable();
|
||||||
state.queue_entries[state.queue_selected],
|
}
|
||||||
state.ncores.empty() ? state.max_cores[state.queue_entries[state.queue_selected]] :
|
else if (State.CurrentInterface == InterfaceType::Confirm)
|
||||||
std::stoi(state.ncores),
|
{
|
||||||
[&]
|
State.UserCommand.reset();
|
||||||
{
|
Screen.Loop(InterfaceConfirm);
|
||||||
auto version_level1 = state.vasp_version_entries_level1[state.vasp_version_selected[0]];
|
if (State.UserCommand == UserCommandType::Quit) return 0;
|
||||||
auto version_level2 = state.vasp_version_entries_level2[version_level1]
|
else if (State.UserCommand == UserCommandType::Back) { State.CurrentInterface = InterfaceType::Request; }
|
||||||
[state.vasp_version_selected[1]];
|
else if (State.UserCommand == UserCommandType::Continue)
|
||||||
auto version_level3 = state.vasp_version_entries_level3[state.vasp_version_selected[2]];
|
{
|
||||||
return fmt::format
|
// 提交任务
|
||||||
(
|
log.debug("submit command: {}"_f(State.SubmitCommand));
|
||||||
"{}{}_{}",
|
// -c 对 \\n 的处理与通常情况下不同,我们需要用 -s 然后将命令通过标准输入传入
|
||||||
version_level1,
|
biu::exec<{.SearchPath = true, .Stdin = biu::IoType::String}>
|
||||||
version_level2 == "(default)" ? ""s : "_" + version_level2,
|
({.Program = "sh", .Args = { "-s"}, .Stdin = State.SubmitCommand});
|
||||||
version_level3
|
break;
|
||||||
);
|
}
|
||||||
}()
|
else if (!State.UserCommand) return EXIT_FAILURE;
|
||||||
);
|
else std::unreachable();
|
||||||
screen.Loop(confirm_interface);
|
}
|
||||||
if (state.user_command == "quit")
|
}
|
||||||
return EXIT_FAILURE;
|
|
||||||
else if (state.user_command == "back")
|
|
||||||
continue;
|
|
||||||
else if (state.user_command != "submit")
|
|
||||||
throw std::runtime_error("user_command is not recognized");
|
|
||||||
submit(state.bsub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user