Skip to content

Commit b4dc8ad

Browse files
Fix mfc.bat run for MS Windows (#533)
Co-authored-by: ChrisZYJ <[email protected]>
1 parent a0781f8 commit b4dc8ad

File tree

8 files changed

+208
-124
lines changed

8 files changed

+208
-124
lines changed

docs/documentation/getting-started.md

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Please select your desired configuration from the list bellow:
2323
. ./mfc.sh load
2424
```
2525

26+
<a id="via-aptitude"></a>
2627
- **Via [Aptitude](https://wiki.debian.org/Aptitude):**
2728

2829
```shell
@@ -59,29 +60,52 @@ On Windows, you can either use Intel Compilers with the standard Microsoft toolc
5960
[Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/) for a Linux experience.
6061

6162
<details>
62-
<summary><h3>Windows + Intel (Native)</h3></summary>
6363

64-
Install the latest version of:
65-
- [Microsoft Visual Studio Community](https://visualstudio.microsoft.com/)
66-
- [Intel® oneAPI Base Toolkit](https://www.intel.com/content/www/us/en/developer/tools/oneapi/base-toolkit-download.html)
67-
- [Intel® oneAPI HPC Toolkit](https://www.intel.com/content/www/us/en/developer/tools/oneapi/hpc-toolkit-download.html)
64+
<summary><h3>Windows + WSL (Recommended)</h3></summary>
6865

69-
Then, in order to initialize your development environment, open a terminal window and run:
66+
Install [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/) on Windows 11:
67+
Either
68+
1. Open a terminal with administrator privileges and run the following command:
7069
```shell
71-
"C:\Program Files (x86)\Intel\oneAPI\setvars.bat"
70+
wsl --install
7271
```
72+
Or
73+
1. Open the Start menu, search for "Windows Features", and select "Turn Windows features on or off". Enable "Windows Subsystem for Linux" by checking the corresponding box.
74+
2. Open the Microsoft Store, search for "Linux", and install your preferred distribution (e.g., [Ubuntu](https://apps.microsoft.com/store/detail/ubuntu/9PDXGNCFSCZV))
7375

74-
To follow this guide, please replace `./mfc.sh` with `mfc.bat` when running any commands. `./mfc.sh` is intended Unix-like systems.
75-
You will also have access to the `.sln` Microsoft Visual Studio solution files for an IDE (Integrated Development Environment).
76+
Useful software to install for using WSL on Windows:
77+
- [Windows Terminal](https://apps.microsoft.com/store/detail/windows-terminal/9N0DX20HK701)
78+
- [Visual Studio Code](https://code.visualstudio.com/) and the [Remote - WSL](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl) extension
79+
80+
Once you have WSL installed, you can follow the instructions for *nix systems above (for Ubuntu, see [Via Aptitude](#via-aptitude)).
7681

7782
</details>
7883

7984
<details>
80-
<summary><h3>Windows + WSL</h3></summary>
8185

82-
Install the latest version of the [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/) as well as a distribution such as Ubuntu which can be found [here](https://apps.microsoft.com/store/detail/ubuntu/9PDXGNCFSCZV). Acquiring an interactive session is as simple as typing `wsl` in your command prompt, or alternatively, selecting the distribution from the dropdown menu available in the [Microsoft Terminal](https://apps.microsoft.com/store/detail/windows-terminal/9N0DX20HK701).
86+
<summary><h3>Native Windows (Intel)</h3></summary>
87+
88+
Install the latest version of:
89+
- [Microsoft Visual Studio Community](https://visualstudio.microsoft.com/)
90+
- [Intel® oneAPI Base Toolkit](https://www.intel.com/content/www/us/en/developer/tools/oneapi/base-toolkit-download.html)
91+
- [Intel® oneAPI HPC Toolkit](https://www.intel.com/content/www/us/en/developer/tools/oneapi/hpc-toolkit-download.html)
92+
- [Strawberry Perl](https://strawberryperl.com/) (Install and add `C:\strawberry\perl\bin\perl.exe` or your installation path to your [PATH](https://www.architectryan.com/2018/03/17/add-to-the-path-on-windows-10/))
93+
Please note that Visual Studio must be installed first, and the oneAPI Toolkits need to be configured with the installed Visual Studio, even if you plan to use a different IDE.
94+
95+
Then, in order to initialize your development environment, run the following command (or your installation path) in command prompt:
96+
```shell
97+
"C:\Program Files (x86)\Intel\oneAPI\setvars.bat"
98+
```
99+
Alternatively, you can run the following command in Powershell:
100+
```shell
101+
cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell'
102+
```
103+
You could verify the initialization by typing `where mpiexec` in the command prompt terminal (does not work in Powershell), which should return the path to the Intel MPI executable.
104+
To continue following this guide, please stay in the initialized terminal window. Replace `./mfc.sh` with `.\mfc.bat` for all commands.
105+
106+
If `.\mfc.bat build` produces errors, please run the command again. Repeating this process three times should resolve all errors (once each for pre_process, simulation, and post_process). If the same error persists after each attempt, please verify that you have installed all required software and properly initialized the development environment. If uncertain, you could try deleting the build directory and starting over.
83107

84-
You can now follow the appropriate instructions for your distribution.
108+
You will also have access to the `.sln` Microsoft Visual Studio solution files for an IDE (Integrated Development Environment).
85109

86110
</details>
87111

mfc.bat

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ goto label_windows
66

77
:label_windows
88

9-
if not exist "%cd%\toolchain\mfc.py" (
9+
if not exist "%cd%\toolchain\main.py" (
1010
echo.
1111
echo ^[mfc.bat^] You must call this script from within MFC's root folder
1212
echo.
@@ -16,7 +16,7 @@ if not exist "%cd%\toolchain\mfc.py" (
1616
mkdir "%cd%\build" 2> NUL
1717

1818
if not exist "%cd%\build\venv" (
19-
python3 -m venv "%cd%\build\venv"
19+
python -m venv "%cd%\build\venv"
2020
if %errorlevel% neq 0 (
2121
echo.
2222
echo ^[mfc.bat^] Failed to create the Python virtual environment. Delete the build/venv folder and try again.
@@ -40,7 +40,7 @@ if %errorlevel% neq 0 (
4040
copy "%cd%\toolchain\requirements.txt" "%cd%\build" 2> NUL
4141
)
4242

43-
python3 "%cd%\toolchain\mfc.py" %*
43+
python "%cd%\toolchain\main.py" %*
4444
set main_py_err=%errorlevel%
4545

4646
call "%cd%\build\venv\Scripts\deactivate.bat"

mfc.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ code=$?
5454
echo
5555

5656
if [ $code -ne 0 ]; then
57-
error "mfc.py finished with a $code exit code."
57+
error "main.py finished with a $code exit code."
5858
fi
5959

6060
# Deactivate the Python virtualenv in case the user "source"'d this script

toolchain/mfc/run/queues.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import typing, dataclasses
1+
import os, typing, dataclasses
22

33
from mfc import common
44
from ..state import ARG
@@ -26,6 +26,9 @@ def is_active(self) -> bool:
2626
return True
2727

2828
def gen_submit_cmd(self, filepath: str) -> typing.List[str]:
29+
if os.name == 'nt':
30+
return [filepath]
31+
2932
return ["/bin/bash", filepath]
3033

3134

toolchain/mfc/run/run.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def get_baked_templates() -> dict:
7070
def __job_script_filepath() -> str:
7171
return os.path.abspath(os.sep.join([
7272
os.path.dirname(ARG("input")),
73-
f"{ARG('name')}.sh"
73+
f"{ARG('name')}.{'bat' if os.name == 'nt' else 'sh'}"
7474
]))
7575

7676

toolchain/mfc/test/case.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,10 @@ def get_dirpath(self):
138138
return os.path.join(common.MFC_TESTDIR, self.get_uuid())
139139

140140
def get_filepath(self):
141-
return os.path.join(self.get_dirpath(), "case.py")
141+
filepath = os.path.join(self.get_dirpath(), "case.py")
142+
if os.name == 'nt':
143+
return filepath.replace('\\', '\\\\')
144+
return filepath
142145

143146
def delete_output(self):
144147
dirpath = self.get_dirpath()

toolchain/templates/default.mako

Lines changed: 72 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,89 @@
1+
<%!
2+
import os
3+
from mako.exceptions import RuntimeException
4+
%>
5+
% if os.name == 'nt':
6+
@echo off
7+
% else:
18
#!/usr/bin/env bash
9+
% endif
210

311
<%namespace name="helpers" file="helpers.mako"/>
412

513
${helpers.template_prologue()}
614

7-
% if engine == 'batch':
8-
error "The$MAGENTA default$COLOR_RESET template does not support batch jobs. Please use a different template via the $MAGENTA--computer$COLOR_RESET option.\n"
9-
exit 1
10-
% endif
15+
<%
16+
if engine == 'batch':
17+
raise RuntimeException("The default template does not support batch jobs. Please use a different template via the --computer option.")
18+
%>
1119

12-
warn "This is the$MAGENTA default$COLOR_RESET template."
13-
warn "It is not intended to support all systems and execution engines."
14-
warn "Consider using a different template via the $MAGENTA--computer$COLOR_RESET option if you encounter problems."
20+
% if os.name != 'nt':
21+
warn "This is the$MAGENTA default$COLOR_RESET template."
22+
warn "It is not intended to support all systems and execution engines."
23+
warn "Consider using a different template via the $MAGENTA--computer$COLOR_RESET option if you encounter problems."
1524

16-
% if mpi:
17-
# Find a suitable MPI launcher and store it in the variable "binary".
18-
for binary in ${binary or ''} jsrun srun mpirun mpiexec; do
19-
if command -v $binary > /dev/null; then
20-
break
21-
fi
22-
done
25+
% if mpi:
26+
# Find a suitable MPI launcher and store it in the variable "binary".
27+
for binary in ${binary or ''} jsrun srun mpirun mpiexec; do
28+
if command -v $binary > /dev/null; then
29+
break
30+
fi
31+
done
2332

24-
if ! command -v $binary > /dev/null; then
25-
error ":( Could not find a suitable MPI launcher.\n"
26-
exit 1
27-
else
28-
ok ":) Selected MPI launcher $MAGENTA$binary$COLOR_RESET. Use$MAGENTA --binary$COLOR_RESET to override."
29-
fi
30-
% endif
33+
if ! command -v $binary > /dev/null; then
34+
error ":( Could not find a suitable MPI launcher.\n"
35+
exit 1
36+
else
37+
ok ":) Selected MPI launcher $MAGENTA$binary$COLOR_RESET. Use$MAGENTA --binary$COLOR_RESET to override."
38+
fi
39+
% endif
3140

32-
% for target in targets:
33-
${helpers.run_prologue(target)}
41+
% for target in targets:
42+
${helpers.run_prologue(target)}
3443

35-
% if not mpi:
36-
(set -x; ${profiler} "${target.get_install_binpath(case)}")
37-
% else:
38-
if [ "$binary" == "jsrun" ]; then
39-
(set -x; ${profiler} \
40-
jsrun --nrs ${tasks_per_node*nodes} \
41-
--cpu_per_rs 1 \
42-
--gpu_per_rs ${1 if gpu else 0} \
43-
--tasks_per_rs 1 \
44-
"${target.get_install_binpath(case)}")
45-
elif [ "$binary" == "srun" ]; then
46-
(set -x; ${profiler} \
47-
srun --ntasks ${nodes*tasks_per_node} \
48-
"${target.get_install_binpath(case)}")
49-
elif [ "$binary" == "mpirun" ]; then
50-
(set -x; ${profiler} \
51-
$binary -np ${nodes*tasks_per_node} \
44+
% if not mpi:
45+
(set -x; ${profiler} "${target.get_install_binpath(case)}")
46+
% else:
47+
if [ "$binary" == "jsrun" ]; then
48+
(set -x; ${profiler} \
49+
jsrun --nrs ${tasks_per_node*nodes} \
50+
--cpu_per_rs 1 \
51+
--gpu_per_rs ${1 if gpu else 0} \
52+
--tasks_per_rs 1 \
5253
"${target.get_install_binpath(case)}")
53-
elif [ "$binary" == "mpiexec" ]; then
54-
(set -x; ${profiler} \
55-
$binary --ntasks ${nodes*tasks_per_node} \
54+
elif [ "$binary" == "srun" ]; then
55+
(set -x; ${profiler} \
56+
srun --ntasks ${nodes*tasks_per_node} \
5657
"${target.get_install_binpath(case)}")
57-
fi
58-
% endif
58+
elif [ "$binary" == "mpirun" ]; then
59+
(set -x; ${profiler} \
60+
$binary -np ${nodes*tasks_per_node} \
61+
"${target.get_install_binpath(case)}")
62+
elif [ "$binary" == "mpiexec" ]; then
63+
(set -x; ${profiler} \
64+
$binary --ntasks ${nodes*tasks_per_node} \
65+
"${target.get_install_binpath(case)}")
66+
fi
67+
% endif
68+
69+
${helpers.run_epilogue(target)}
5970

60-
${helpers.run_epilogue(target)}
71+
echo
72+
% endfor
73+
% else:
74+
% for target in targets:
75+
${helpers.run_prologue(target)}
6176

62-
echo
63-
% endfor
77+
% if not mpi:
78+
${profiler} "${target.get_install_binpath(case)}.exe"
79+
% else:
80+
${profiler} \
81+
mpiexec -n ${nodes*tasks_per_node} \
82+
"${target.get_install_binpath(case)}.exe"
83+
% endif
84+
85+
${helpers.run_epilogue(target)}
86+
% endfor
87+
% endif
6488

6589
${helpers.template_epilogue()}

0 commit comments

Comments
 (0)