The following project was done to provide an optimal way of solving the 0/1 Knapsack Problem. The implementation uses dynamic programming and parallel computations in the form of multiprocessing.
The project is written in C (for the best performance) and uses the Intel implementation of the MPI standard. Everything is documented in code with comments.
The 0/1 Knapsack Problem is a well-known weakly NP-hard (through a reduction from Partition Problem - section 10.5), while there exists an implementation that has pseudo-polynomial complexity. It stems from the magnitude of input data, not the number of inputs.
To solve this problem the recursive approach was implemented using the SPMD approach. At least 2 processes must be called to run the algorithm.
The root node (process with rank 0) distributes tasks which consist in determining a particular knapsack size (from 0 to n) and caches the results into a 1-dimensional array.
The other processes wait for a task from the root node. On a given request, each of them computes the result asynchronously. Each node has its own array of items that can be packed (their weights and values).
However, the results of the computed knapsacks are stored in the root node. Therefore, to find out the value of the previously cached result, a query to the root node is sent. If the result is already calculated, the return message contains the answer. Otherwise, the information returned delays the process because that particular result has not yet been computed.
Besides the main computations, some small things might be useful.
-
Error handling - if the user specifies wrong parameters, the code is designed to handle such situations and provides the potential fix.
-
Logging modes - the implementation contains two logging modes made for tracking the process of calculations. These are:
TRACE
- prints verbosely every action that has happened (who sent or received the message, its contents and response to them).DEBUG
- only prints the results of each iteration of the calculated knapsack size.
The reason why the debugging can be set only on the preprocessing stage is to avoid significant performance hit that exists by passing through unused ifs.
-
Custom types - the implementation does not force the user to use the hardcoded variable types (default is unsigned long). To do that, change the
VAR_TYPE
macro to the desired one, as well asMPI_VAR_TYPE
.WARNING: Keep in mind that this type has to be defined by MPI standard!
The provided tutorial was tested on Windows machines and it's dedicated purely to systems working on Intel CPUs. However, detailed steps on installation are on the Intel MPI Library site in the "Get Started" section.
- Systems based on the Intel® 64 architecture
- 2 GB RAM (1 GB of memory per core)
- 4 GB of free hard disk space
- Visual Studio (2019/2022 version recommended)
-
Go to the Intel® oneAPI Base Toolkit download site (link)
-
Install these Intel® OneAPI Base Toolkit tools (3.3 GB):
- Intel® DPC++ Compatibility Tool
- Intel® Distribution for GDB
- Intel® oneAPI DPC++ Library
- Intel® oneAPI Threading Building Blocks
- Intel® oneAPI DPC++/C++ Compiler
Disclaimer: It's highly recommended to install the tools in the default path. The custom one might lead to issues
-
Go to the Intel® oneAPI HPC Toolkit download site (link)
-
Install Intel® OneAPI HPC Toolkit tools (115 MB):
- Intel® MPI Library
- Intel® oneAPI DPC++/C++ Compiler & Intel® oneAPI C++ Compiler Classic
Disclaimer: The rest of the packages are made mostly for debugging and shorter compilation time. If you wish to install them then go ahead
-
Add bin directories to the PATH system variable:
- Path to MPI (by default,
C:\Program Files (x86)\Intel\oneAPI\mpi\<version>\bin
)
- Path to MPI (by default,
If the folder contains hydra_service.exe
then it's the right one!
- Path to compiler (by default,
C:\Program Files (x86)\Intel\oneAPI\compiler\<version>\windows\bin\intel64
)
If the folder contains icl.exe
then it's the right one!
-
Open Command Prompt as administrator (cmd)
-
Run the
setvars.bat
file located in the MPI installation directory (by default,C:\Program Files (x86)\Intel\oneAPI
) -
Install & run hydra service (used for network MPI communication)
hydra-service -install hydra-service -start
-
Register your device to identify it in the MPI network
mpiexec -register
-
(Optional step) It's highly recommended to restart the PC
Clone this repository by using your favourite client software 😉
-
Open Command Prompt as administrator (cmd)
-
Initialize the environment by running the
setvars.bat
script"%ONEAPI_ROOT%\setvars.bat"
-
In the same (it's very important) cmd session go to the project folder
-
Go to the
src
directory (the one containing themain.c
file) -
Compile the project by typing
mpiicc -o output.exe main.c
-
You've installed and compiled the project successfully 🎉!
The reason why this solution is unstable, is the high possibility of compilation failures. The most well-known reason is installing the project on the other drive than the MPI is installed.
-
Open the directory with the cloned project and double click on the
.sln
fileDisclaimer: The project has already configured settings. If you want to configure your very own project, here is the link to the instruction
-
Click Project > Intel Compiler > Use Intel oneAPI DPC++/C++ Compiler if it's not already in use. After that your project in the Solution Explorer will have the compiler name in curly brackets
-
(Optional step) Click Project > (...) Properties
-
(Optional step) Ensure that everything in the configuration is set properly (according to the documentation)
-
(Optional step) Save and close the settings
-
Change the Solution Platform to "x64"
-
Click Build > Build Solution or press F7
-
You've installed and compiled the project successfully 🎉!
-
In Command Prompt type:
mpiexec -n <number of processes> <path to the compiled project file> <args>
Protip: Without the
-n
parameter, mpiexec will automatically determine the amount of the installed core and use all of them -
You've launched the project successfully 🎉!
Typical, annoying with no explanations MPI error...
It's very common to encounter errors if You've installed the MPI environment on the other drive than the project files are located!
The code execution cannot proceed because impi.dll was not found.
The message implies that the executable was unable to locate the missing DLL. It is a well-known behaviour when it comes to the DLL files and the workaround is provided below.
There's a probability that it happens when the Intel® oneAPI toolkit and the project are installed on separated drives.
Copy the missing DLL files from the MPI directory.
-
Open Command Prompt as administrator and open open the folder with the
main.c
file -
Copy the missing DLL by typing:
copy "%I_MPI_ONEAPI_ROOT%\bin\release\impi.dll" .
-
The problem should be fixed now 👷♂️.
The reason why this error happens is the bad initialization of MPI environment variables. It's a very common error that pops right after pasting the DLL in the project directory.
-
In the same Command Prompt you have opened type:
"%ONEAPI_ROOT%\setvars.bat"
-
The problem should be fixed now 👷♂️.
Use the stable solution. This one always works and if it's not, then You either don't have an Intel CPU or you did something wrong during the installation process.
Disable the private firewall on each node. That's the simpliest solution.
- Hubert Lewandowski (RooTender)