summaryrefslogtreecommitdiff
path: root/simplex-glpk
diff options
context:
space:
mode:
Diffstat (limited to 'simplex-glpk')
-rw-r--r--simplex-glpk/.cproject52
-rw-r--r--simplex-glpk/.project27
-rwxr-xr-xsimplex-glpk/CMakeLists.txt21
-rwxr-xr-xsimplex-glpk/README.md268
-rw-r--r--simplex-glpk/build/binpacking.lp25
-rwxr-xr-xsimplex-glpk/sample.json41
-rwxr-xr-xsimplex-glpk/src/CMakeLists.txt95
-rw-r--r--simplex-glpk/src/glpsol.h950
-rw-r--r--simplex-glpk/src/host.cpp834
-rw-r--r--simplex-glpk/src/kernel.cpp263
-rwxr-xr-xsimplex-glpk/src/kernel.hpp13
-rw-r--r--simplex-glpk/src/note2
12 files changed, 2591 insertions, 0 deletions
diff --git a/simplex-glpk/.cproject b/simplex-glpk/.cproject
new file mode 100644
index 0000000..f98eedd
--- /dev/null
+++ b/simplex-glpk/.cproject
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+ <storageModule moduleId="org.eclipse.cdt.core.settings">
+ <cconfiguration id="0.1816735877">
+ <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.1816735877" moduleId="org.eclipse.cdt.core.settings" name="Default">
+ <externalSettings/>
+ <extensions>
+ <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ </extensions>
+ </storageModule>
+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+ <configuration buildProperties="" description="" id="0.1816735877" name="Default" parent="org.eclipse.cdt.build.core.prefbase.cfg">
+ <folderInfo id="0.1816735877." name="/" resourcePath="">
+ <toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.94912739" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
+ <targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.94912739.1919427232" name=""/>
+ <builder id="org.eclipse.cdt.build.core.settings.default.builder.1198697699" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
+ <tool id="org.eclipse.cdt.build.core.settings.holder.libs.1306355369" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
+ <tool id="org.eclipse.cdt.build.core.settings.holder.1882413059" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
+ <inputType id="org.eclipse.cdt.build.core.settings.holder.inType.256952332" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
+ </tool>
+ <tool id="org.eclipse.cdt.build.core.settings.holder.891915593" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
+ <inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1936190158" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
+ </tool>
+ <tool id="org.eclipse.cdt.build.core.settings.holder.1327351207" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
+ <inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1921794291" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
+ </tool>
+ </toolChain>
+ </folderInfo>
+ </configuration>
+ </storageModule>
+ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+ </cconfiguration>
+ </storageModule>
+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+ <project id="simplex-glpk.null.2076193173" name="simplex-glpk"/>
+ </storageModule>
+ <storageModule moduleId="scannerConfiguration">
+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+ <scannerConfigBuildInfo instanceId="0.1504268868">
+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+ </scannerConfigBuildInfo>
+ <scannerConfigBuildInfo instanceId="0.1816735877">
+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+ </scannerConfigBuildInfo>
+ </storageModule>
+ <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+</cproject> \ No newline at end of file
diff --git a/simplex-glpk/.project b/simplex-glpk/.project
new file mode 100644
index 0000000..99c2340
--- /dev/null
+++ b/simplex-glpk/.project
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>simplex-glpk</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+ <triggers>clean,full,incremental,</triggers>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+ <triggers>full,incremental,</triggers>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.cdt.core.cnature</nature>
+ <nature>org.eclipse.cdt.core.ccnature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+ </natures>
+</projectDescription>
diff --git a/simplex-glpk/CMakeLists.txt b/simplex-glpk/CMakeLists.txt
new file mode 100755
index 0000000..28485d3
--- /dev/null
+++ b/simplex-glpk/CMakeLists.txt
@@ -0,0 +1,21 @@
+if(UNIX)
+ # Direct CMake to use dpcpp rather than the default C++ compiler/linker
+ #set(CMAKE_CXX_COMPILER dpcpp)
+ set(CMAKE_CXX_COMPILER icpx -fsycl)
+else() # Windows
+ # Force CMake to use dpcpp rather than the default C++ compiler/linker
+ # (needed on Windows only)
+ include (CMakeForceCompiler)
+ CMAKE_FORCE_CXX_COMPILER (dpcpp IntelDPCPP)
+ include (Platform/Windows-Clang)
+endif()
+
+cmake_minimum_required (VERSION 3.4)
+
+project(FastRecompile CXX)
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+
+add_subdirectory (src)
diff --git a/simplex-glpk/README.md b/simplex-glpk/README.md
new file mode 100755
index 0000000..cec86e1
--- /dev/null
+++ b/simplex-glpk/README.md
@@ -0,0 +1,268 @@
+
+# Separating Host and Device Code Compilation
+This FPGA tutorial demonstrates how to separate the compilation of a program's host code and device code to save development time. It's recommended to read the 'fpga_compile' code sample before this one.
+
+| Optimized for | Description
+--- |---
+| OS | Linux* Ubuntu* 18.04/20.04 <br> RHEL*/CentOS* 8 <br> SUSE* 15 <br> Windows* 10
+| Hardware | Intel® Programmable Acceleration Card (PAC) with Intel Arria® 10 GX FPGA <br> Intel® FPGA Programmable Acceleration Card (PAC) D5005 (with Intel Stratix® 10 SX) <br> Intel® FPGA 3rd party / custom platforms with oneAPI support <br> *__Note__: Intel® FPGA PAC hardware is only compatible with Ubuntu 18.04*
+| Software | Intel® oneAPI DPC++ Compiler <br> Intel® FPGA Add-On for oneAPI Base Toolkit
+| What you will learn | Why to separate host and device code compilation in your FPGA project <br> How to use the `-reuse-exe` and device link methods <br> Which method to choose for your project
+| Time to complete | 15 minutes
+
+
+
+## Purpose
+Intel® oneAPI DPC++ Compiler only supports ahead-of-time (AoT) compilation for FPGA, which means that an FPGA device image is generated at compile time. The FPGA device image generation process can take hours to complete. Suppose you make a change that is exclusive to the host code. In that case, it is more efficient to recompile your host code only, re-using the existing FPGA device image and circumventing the time-consuming device compilation process.
+
+The compiler provides two different mechanisms to separate device code and host code compilation.
+* Passing the `-reuse-exe=<exe_name>` flag to `dpcpp` instructs the compiler to attempt to reuse the existing FPGA device image.
+* The more explicit "device link" method requires you to separate the host and device code into separate files. When a code change only applies to host-only files, an FPGA device image is not regenerated.
+
+This tutorial explains both mechanisms and the pros and cons of each. The included code sample demonstrates the device link method but does **not** demonstrate the use of the `-reuse-exe` flag.
+
+### Using the `-reuse-exe` flag
+
+If the device code and options affecting the device have not changed since the previous compilation, passing the `-reuse-exe=<exe_name>` flag to `dpcpp` instructs the compiler to extract the compiled FPGA binary from the existing executable and package it into the new executable, saving the device compilation time.
+
+**Sample usage:**
+
+```
+# Initial compilation
+dpcpp <files.cpp> -o out.fpga -Xshardware -fintelfpga
+```
+The initial compilation generates an FPGA device image, which takes several hours. Now, make some changes to the host code.
+```
+# Subsequent recompilation
+dpcpp <files.cpp> -o out.fpga -reuse-exe=out.fpga -Xshardware -fintelfpga
+```
+If `out.fpga` does not exist, `-reuse-exe` is ignored and the FPGA device image is regenerated. This will always be the case the first time a project is compiled.
+
+If `out.fpga` is found, the compiler checks whether any changes affecting the FPGA device code have been made since the last compilation. If no such changes are detected, the compiler reuses the existing FPGA binary, and only the host code is recompiled. The recompilation process takes a few minutes. Note that the device code is partially re-compiled (similar to a report flow compile) to check that the FPGA binary can safely be reused.
+
+If `out.fpga` is found but the compiler cannot prove that the FPGA device code will yield a result identical to the last compilation, a warning is printed and the FPGA device code is fully recompiled. Since the compiler checks must be conservative, spurious recompilations can sometimes occur when using `-reuse-exe`.
+
+### Using the device link method
+
+The program accompanying this tutorial is separated into two files, `host.cpp` and `kernel.cpp`. Only the `kernel. cpp` file contains device code.
+
+In the normal compilation process, FPGA device image generation happens at link time. As a result, any change to either `host.cpp` or `kernel.cpp` will trigger an FPGA device image's regeneration.
+
+```
+# normal compile command
+dpcpp -fintelfpga host.cpp kernel.cpp -Xshardware -o link.fpga
+```
+
+The following graph depicts this compilation process:
+
+![](normal_compile.png)
+
+
+If you want to iterate on the host code and avoid long compile time for your FPGA device, consider using a device link to separate device and host compilation:
+
+```
+# device link command
+dpcpp -fintelfpga -fsycl-link=image <input files> [options]
+```
+
+The compilation is a 3-step process:
+
+1. Compile the device code:
+
+ ```
+ dpcpp -fintelfpga -fsycl-link=image kernel.cpp -o dev_image.a -Xshardware
+ ```
+ Input files should include all source files that contain device code. This step may take several hours.
+
+
+2. Compile the host code:
+
+ ```
+ dpcpp -fintelfpga host.cpp -c -o host.o
+ ```
+ Input files should include all source files that only contain host code. This takes seconds.
+
+
+3. Create the device link:
+
+ ```
+ dpcpp -fintelfpga host.o dev_image.a -o fast_recompile.fpga
+ ```
+ The input should have N (N >= 0) host object files *(.o)* and one device image file *(.a)*. This takes seconds.
+
+**NOTE:** You only need to perform steps 2 and 3 when modifying host-only files.
+
+The following graph depicts the device link compilation process:
+
+![](device_link.png)
+
+### Which method to use?
+Of the two methods described, `-reuse-exe` is easier to use. It also allows you to keep your host and device code as single source, which is preferred for small programs.
+
+For larger and more complex projects, the device link method has the advantage of giving you complete control over the compiler's behavior.
+* When using `-reuse-exe`, the compiler must partially recompile and then analyze the device code to ensure that it is unchanged. This takes several minutes for larger designs. Compiling separate files does not incur this extra time.
+* When using `-reuse-exe`, you may occasionally encounter a "false positive" where the compiler wrongly believes that it must recompile your device code. In a single source file, the device and host code are coupled, so some changes to the host code _can_ change the compiler's view of the device code. The compiler will always behave conservatively and trigger a full recompilation if it cannot prove that reusing the previous FPGA binary is safe. Compiling separate files eliminates this possibility.
+
+### Additional Documentation
+- [Explore SYCL* Through Intel&reg; FPGA Code Samples](https://software.intel.com/content/www/us/en/develop/articles/explore-dpcpp-through-intel-fpga-code-samples.html) helps you to navigate the samples and build your knowledge of FPGAs and SYCL.
+- [FPGA Optimization Guide for Intel&reg; oneAPI Toolkits](https://software.intel.com/content/www/us/en/develop/documentation/oneapi-fpga-optimization-guide) helps you understand how to target FPGAs using SYCL and Intel&reg; oneAPI Toolkits.
+- [Intel&reg; oneAPI Programming Guide](https://software.intel.com/en-us/oneapi-programming-guide) helps you understand target-independent, SYCL-compliant programming using Intel&reg; oneAPI Toolkits.
+
+## Key Concepts
+* Why to separate host and device code compilation in your FPGA project
+* How to use the `-reuse-exe` and device link methods
+* Which method to choose for your project
+
+## Building the `fast_recompile` Tutorial
+> **Note**: If you have not already done so, set up your CLI
+> environment by sourcing the `setvars` script located in
+> the root of your oneAPI installation.
+>
+> Linux*:
+> - For system wide installations: `. /opt/intel/oneapi/setvars.sh`
+> - For private installations: `. ~/intel/oneapi/setvars.sh`
+>
+> Windows*:
+> - `C:\Program Files(x86)\Intel\oneAPI\setvars.bat`
+> - For PowerShell*, use the following command: `cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell'`
+>
+>For more information on environment variables, see **Use the setvars Script** for [Linux or macOS](https://www.intel.com/content/www/us/en/develop/documentation/oneapi-programming-guide/top/oneapi-development-environment-setup/use-the-setvars-script-with-linux-or-macos.html), or [Windows](https://www.intel.com/content/www/us/en/develop/documentation/oneapi-programming-guide/top/oneapi-development-environment-setup/use-the-setvars-script-with-windows.html).
+
+
+### Include Files
+The included header `dpc_common.hpp` is located at `%ONEAPI_ROOT%\dev-utilities\latest\include` on your development system.
+
+### Running Samples in Intel&reg; DevCloud
+If running a sample in the Intel&reg; DevCloud, remember that you must specify the type of compute node and whether to run in batch or interactive mode. Compiles to FPGA are only supported on fpga_compile nodes. Executing programs on FPGA hardware is only supported on fpga_runtime nodes of the appropriate type, such as fpga_runtime:arria10 or fpga_runtime:stratix10. Neither compiling nor executing programs on FPGA hardware are supported on the login nodes. For more information, see the Intel® oneAPI Base Toolkit Get Started Guide ([https://devcloud.intel.com/oneapi/documentation/base-toolkit/](https://devcloud.intel.com/oneapi/documentation/base-toolkit/)).
+
+When compiling for FPGA hardware, it is recommended to increase the job timeout to 12h.
+
+
+### Using Visual Studio Code* (Optional)
+
+You can use Visual Studio Code (VS Code) extensions to set your environment, create launch configurations,
+and browse and download samples.
+
+The basic steps to build and run a sample using VS Code include:
+ - Download a sample using the extension **Code Sample Browser for Intel&reg; oneAPI Toolkits**.
+ - Configure the oneAPI environment with the extension **Environment Configurator for Intel&reg; oneAPI Toolkits**.
+ - Open a Terminal in VS Code (**Terminal>New Terminal**).
+ - Run the sample in the VS Code terminal using the instructions below.
+ - (Linux only) Debug your GPU application with GDB for Intel® oneAPI toolkits using the **Generate Launch Configurations** extension.
+
+To learn more about the extensions, see the
+[Using Visual Studio Code with Intel® oneAPI Toolkits User Guide](https://www.intel.com/content/www/us/en/develop/documentation/using-vs-code-with-intel-oneapi/top.html).
+
+
+After learning how to use the extensions for Intel oneAPI Toolkits, return to this readme for instructions on how to build and run a sample.
+
+### On a Linux* System
+
+1. Generate the `Makefile` by running `cmake`.
+ ```
+ mkdir build
+ cd build
+ ```
+ To compile for the Intel® PAC with Intel Arria® 10 GX FPGA, run `cmake` using the command:
+ ```
+ cmake ..
+ ```
+ Alternatively, to compile for the Intel® FPGA PAC D5005 (with Intel Stratix® 10 SX), run `cmake` using the command:
+
+ ```
+ cmake .. -DFPGA_BOARD=intel_s10sx_pac:pac_s10
+ ```
+ You can also compile for a custom FPGA platform. Ensure that the board support package is installed on your system. Then run `cmake` using the command:
+ ```
+ cmake .. -DFPGA_BOARD=<board-support-package>:<board-variant>
+ ```
+
+ **NOTE:** For the FPGA emulator target and the FPGA target, the device link method is used.
+2. Compile the design through the generated `Makefile`. The following build targets are provided:
+
+ * Compile for emulation (fast compile time, targets emulated FPGA device):
+ ```
+ make fpga_emu
+ ```
+ * Compile for FPGA hardware (longer compile time, targets FPGA device):
+ ```
+ make fpga
+ ```
+3. (Optional) As the above hardware compile may take several hours to complete, FPGA precompiled binaries (compatible with Linux* Ubuntu* 18.04) can be downloaded <a href="https://iotdk.intel.com/fpga-precompiled-binaries/latest/fast_recompile.fpga.tar.gz" download>here</a>.
+
+### On a Windows* System
+
+1. Generate the `Makefile` by running `cmake`.
+ ```
+ mkdir build
+ cd build
+ ```
+ To compile for the Intel® PAC with Intel Arria® 10 GX FPGA, run `cmake` using the command:
+ ```
+ cmake -G "NMake Makefiles" ..
+ ```
+ Alternatively, to compile for the Intel® FPGA PAC D5005 (with Intel Stratix® 10 SX), run `cmake` using the command:
+
+ ```
+ cmake -G "NMake Makefiles" .. -DFPGA_BOARD=intel_s10sx_pac:pac_s10
+ ```
+ You can also compile for a custom FPGA platform. Ensure that the board support package is installed on your system. Then run `cmake` using the command:
+ ```
+ cmake -G "NMake Makefiles" .. -DFPGA_BOARD=<board-support-package>:<board-variant>
+ ```
+
+2. Compile the design through the generated `Makefile`. The following build targets are provided, matching the recommended development flow:
+
+ * Compile for emulation (fast compile time, targets emulated FPGA device):
+ ```
+ nmake fpga_emu
+ ```
+ * Compile for FPGA hardware (longer compile time, targets FPGA device):
+ ```
+ nmake fpga
+ ```
+
+> **Note**: The Intel® PAC with Intel Arria® 10 GX FPGA and Intel® FPGA PAC D5005 (with Intel Stratix® 10 SX) do not support Windows*. Compiling to FPGA hardware on Windows* requires a third-party or custom Board Support Package (BSP) with Windows* support.
+
+> **Note**: If you encounter any issues with long paths when compiling under Windows*, you may have to create your ‘build’ directory in a shorter path, for example c:\samples\build. You can then run cmake from that directory, and provide cmake with the full path to your sample directory.
+
+### Troubleshooting
+If an error occurs, you can get more details by running `make` with
+the `VERBOSE=1` argument:
+``make VERBOSE=1``
+For more comprehensive troubleshooting, use the Diagnostics Utility for
+Intel® oneAPI Toolkits, which provides system checks to find missing
+dependencies and permissions errors.
+[Learn more](https://www.intel.com/content/www/us/en/develop/documentation/diagnostic-utility-user-guide/top.html).
+
+
+### In Third-Party Integrated Development Environments (IDEs)
+
+You can compile and run this tutorial in the Eclipse* IDE (in Linux*) and the Visual Studio* IDE (in Windows*). For instructions, refer to the following link: [FPGA Workflows on Third-Party IDEs for Intel&reg; oneAPI Toolkits](https://www.intel.com/content/www/us/en/developer/articles/technical/intel-oneapi-dpcpp-fpga-workflow-on-ide.html).
+
+
+## Running the Sample
+
+ 1. Run the sample on the FPGA emulator (the kernel executes on the CPU):
+ ```
+ ./fast_recompile.fpga_emu (Linux)
+ fast_recompile.fpga_emu.exe (Windows)
+ ```
+2. Run the sample on the FPGA device:
+ ```
+ ./fast_recompile.fpga (Linux)
+ fast_recompile.fpga.exe (Windows)
+ ```
+
+### Example of Output
+```
+PASSED: results are correct
+```
+### Discussion of Results
+Try modifying `host.cpp` to produce a different output message. Then, perform a host-only recompile via the device link method to see how quickly the design is recompiled.
+
+## License
+Code samples are licensed under the MIT license. See
+[License.txt](https://github.com/oneapi-src/oneAPI-samples/blob/master/License.txt) for details.
+
+Third party program Licenses can be found here: [third-party-programs.txt](https://github.com/oneapi-src/oneAPI-samples/blob/master/third-party-programs.txt). \ No newline at end of file
diff --git a/simplex-glpk/build/binpacking.lp b/simplex-glpk/build/binpacking.lp
new file mode 100644
index 0000000..db06064
--- /dev/null
+++ b/simplex-glpk/build/binpacking.lp
@@ -0,0 +1,25 @@
+Minimize
+obj: y_1 + y_2 + y_3
+
+Subject To
+c1: y_1 + y_2 + y_3 >= 1
+c2: x_1_1 + 3 x_2_1 + x_3_1 - 5 y_1<= 0
+c3: x_1_2 + 3 x_2_2 + x_3_2 - 3 y_2 <= 0
+c4: x_1_3 + 3 x_2_3 + x_3_3 - 3 y_3 <= 0
+c5: x_1_1 + x_1_2 + x_1_3 = 1
+c6: x_2_1 + x_2_2 + x_2_3 = 1
+c7: x_3_1 + x_3_2 + x_3_3 = 1
+Bounds
+0 <= y_1 <= 1
+0 <= y_2 <= 1
+0 <= y_3 <= 1
+0 <= x_1_1 <= 1
+0 <= x_1_2 <= 1
+0 <= x_1_3 <= 1
+0 <= x_2_1 <= 1
+0 <= x_2_2 <= 1
+0 <= x_2_3 <= 1
+0 <= x_3_1 <= 1
+0 <= x_3_2 <= 1
+0 <= x_3_3 <= 1
+End
diff --git a/simplex-glpk/sample.json b/simplex-glpk/sample.json
new file mode 100755
index 0000000..a67feba
--- /dev/null
+++ b/simplex-glpk/sample.json
@@ -0,0 +1,41 @@
+{
+ "guid": "1457B49A-2CD3-48E5-B3A9-753EAD2D18F7",
+ "name": "Fast Recompile",
+ "categories": ["Toolkit/oneAPI Direct Programming/DPC++ FPGA/Getting Started Tutorials"],
+ "description": "An Intel® FPGA tutorial demonstrating how to separate the compilation of host and device code to save development time",
+ "toolchain": ["dpcpp"],
+ "os": ["linux", "windows"],
+ "targetDevice": ["FPGA"],
+ "builder": ["ide", "cmake"],
+ "languages": [{"cpp":{}}],
+ "ciTests": {
+ "linux": [
+ {
+ "id": "fpga_emu",
+ "steps": [
+ "dpcpp --version",
+ "mkdir build",
+ "cd build",
+ "cmake ..",
+ "make fpga_emu",
+ "./fast_recompile.fpga_emu"
+ ]
+ }
+ ],
+ "windows": [
+ {
+ "id": "fpga_emu",
+ "steps": [
+ "dpcpp --version",
+ "cd ../../..",
+ "mkdir build",
+ "cd build",
+ "cmake -G \"NMake Makefiles\" ../Tutorials/GettingStarted/fast_recompile",
+ "nmake fpga_emu",
+ "fast_recompile.fpga_emu.exe"
+ ]
+ }
+ ]
+ },
+ "expertise": "Getting Started"
+}
diff --git a/simplex-glpk/src/CMakeLists.txt b/simplex-glpk/src/CMakeLists.txt
new file mode 100755
index 0000000..043d5a0
--- /dev/null
+++ b/simplex-glpk/src/CMakeLists.txt
@@ -0,0 +1,95 @@
+set(DEVICE_SOURCE_FILE kernel.cpp)
+set(KERNEL_HEADER_FILE kernel.hpp)
+set(HOST_SOURCE_FILE host.cpp)
+set(TARGET_NAME simplexdev)
+set(EMULATOR_TARGET ${TARGET_NAME}.fpga_emu)
+set(FPGA_TARGET ${TARGET_NAME}.fpga)
+
+# FPGA board selection
+if(NOT DEFINED FPGA_BOARD)
+ set(FPGA_BOARD "intel_a10gx_pac:pac_a10")
+ message(STATUS "FPGA_BOARD was not specified.\
+ \nConfiguring the design to run on the default FPGA board ${FPGA_BOARD} (Intel(R) PAC with Intel Arria(R) 10 GX FPGA). \
+ \nPlease refer to the README for information on board selection.")
+else()
+ message(STATUS "Configuring the design to run on FPGA board ${FPGA_BOARD}")
+endif()
+
+# This is a Windows-specific flag that enables exception handling in host code
+if(WIN32)
+ set(WIN_FLAG "/EHsc")
+endif()
+
+# A DPC++ ahead-of-time (AoT) compile processes the device code in two stages.
+# 1. The "compile" stage compiles the device code to an intermediate representation (SPIR-V).
+# 2. The "link" stage invokes the compiler's FPGA backend before linking.
+# For this reason, FPGA backend flags must be passed as link flags in CMake.
+set(EMULATOR_COMPILE_FLAGS "-Wall ${WIN_FLAG} -fintelfpga -DFPGA_EMULATOR")
+set(EMULATOR_LINK_FLAGS "-fintelfpga -lglpk")
+set(HARDWARE_COMPILE_FLAGS "-Wall ${WIN_FLAG} -fintelfpga -lglpk -lm")
+set(HARDWARE_LINK_FLAGS "-fintelfpga -Xshardware -Xsboard=${FPGA_BOARD} ${USER_HARDWARE_FLAGS}")
+# use cmake -D USER_HARDWARE_FLAGS=<flags> to set extra flags for FPGA backend compilation
+
+###############################################################################
+### FPGA Emulator
+###############################################################################
+# To compile in a single command:
+# dpcpp -fintelfpga -DFPGA_EMULATOR host.cpp kernel.cpp -o fast_recompile.fpga_emu
+# CMake executes:
+# [compile] dpcpp -fintelfpga -DFPGA_EMULATOR -o host.cpp.o -c host.cpp
+# [compile] dpcpp -fintelfpga -DFPGA_EMULATOR -o kernel.cpp.o -c kernel.cpp
+# [link] dpcpp -fintelfpga host.cpp.o kernel.cpp.o -o fast_recompile.fpga_emu
+add_executable(${EMULATOR_TARGET} ${HOST_SOURCE_FILE} ${DEVICE_SOURCE_FILE})
+set_target_properties(${EMULATOR_TARGET} PROPERTIES COMPILE_FLAGS "${EMULATOR_COMPILE_FLAGS}")
+set_target_properties(${EMULATOR_TARGET} PROPERTIES LINK_FLAGS "${EMULATOR_LINK_FLAGS}")
+add_custom_target(fpga_emu DEPENDS ${EMULATOR_TARGET})
+
+###############################################################################
+### Generate Report
+###############################################################################
+# To compile manually:
+# dpcpp -fintelfpga -Xshardware -Xsboard=<FPGA_BOARD> -fsycl-link=early host.cpp kernel.cpp -o fast_compile_report.a
+set(FPGA_EARLY_IMAGE ${TARGET_NAME}_report.a)
+# The compile output is not an executable, but an intermediate compilation result unique to DPC++.
+add_executable(${FPGA_EARLY_IMAGE} ${HOST_SOURCE_FILE} ${DEVICE_SOURCE_FILE})
+add_custom_target(report DEPENDS ${FPGA_EARLY_IMAGE})
+set_target_properties(${FPGA_EARLY_IMAGE} PROPERTIES COMPILE_FLAGS ${HARDWARE_COMPILE_FLAGS})
+set_target_properties(${FPGA_EARLY_IMAGE} PROPERTIES LINK_FLAGS "${HARDWARE_LINK_FLAGS} -fsycl-link=early")
+# fsycl-link=early stops the compiler after RTL generation, before invoking Quartus®
+
+
+###############################################################################
+### FPGA Hardware
+###############################################################################
+# To compile manually:
+# dpcpp -fintelfpga -c host.cpp -o host.o
+# dpcpp -fintelfpga -Xshardware -Xsboard=<FPGA_BOARD> -fsycl-link=image kernel.cpp -o dev_image.a
+# dpcpp -fintelfpga host.o dev_image.a -o fast_recompile.fpga
+
+if(WIN32)
+ set(FPGA_TARGET ${FPGA_TARGET}.exe)
+endif()
+add_custom_target(fpga DEPENDS ${FPGA_TARGET})
+set(HOST_OBJ "host.o")
+set(DEVICE_OBJ "dev.o")
+set(DEVICE_IMAGE_OBJ "dev_image.a")
+
+set(CMAKE_CXX_FLAGS_LIST "${CMAKE_CXX_FLAGS}")
+separate_arguments(CMAKE_CXX_FLAGS_LIST)
+set(HARDWARE_COMPILE_FLAGS_LIST "${HARDWARE_COMPILE_FLAGS}")
+separate_arguments(HARDWARE_COMPILE_FLAGS_LIST)
+set(HARDWARE_LINK_FLAGS_LIST "${HARDWARE_LINK_FLAGS}")
+separate_arguments(HARDWARE_LINK_FLAGS_LIST)
+
+
+add_custom_command(OUTPUT ${HOST_OBJ}
+ COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS_LIST} ${HARDWARE_COMPILE_FLAGS_LIST} -c ${CMAKE_CURRENT_SOURCE_DIR}/${HOST_SOURCE_FILE} -o ${HOST_OBJ}
+ DEPENDS ${HOST_SOURCE_FILE} ${KERNEL_HEADER_FILE})
+
+add_custom_command(OUTPUT ${DEVICE_IMAGE_OBJ}
+ COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS_LIST} ${HARDWARE_LINK_FLAGS_LIST} -fsycl-link=image ${CMAKE_CURRENT_SOURCE_DIR}/${DEVICE_SOURCE_FILE} -o ${DEVICE_IMAGE_OBJ}
+ DEPENDS ${DEVICE_SOURCE_FILE} ${KERNEL_HEADER_FILE})
+
+add_custom_command(OUTPUT ${FPGA_TARGET}
+ COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS_LIST} -fintelfpga ${HOST_OBJ} ${DEVICE_IMAGE_OBJ} -o ${CMAKE_BINARY_DIR}/${FPGA_TARGET}
+ DEPENDS ${HOST_OBJ} ${DEVICE_IMAGE_OBJ})
diff --git a/simplex-glpk/src/glpsol.h b/simplex-glpk/src/glpsol.h
new file mode 100644
index 0000000..f0f79ae
--- /dev/null
+++ b/simplex-glpk/src/glpsol.h
@@ -0,0 +1,950 @@
+/* glpsol.c (stand-alone GLPK LP/MIP solver) */
+
+/***********************************************************************
+* This code is part of GLPK (GNU Linear Programming Kit).
+* Copyright (C) 2000-2020 Free Software Foundation, Inc.
+* Written by Andrew Makhorin <mao@gnu.org>.
+*
+* GLPK is free software: you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* GLPK is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+* License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with GLPK. If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+
+#include <ctype.h>
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glpk.h>
+
+
+
+#define xassert glp_assert
+#define xerror glp_error
+#define xprintf glp_printf
+
+struct csa
+{ /* common storage area */
+ glp_prob *prob;
+ /* LP/MIP problem object */
+ glp_bfcp bfcp;
+ /* basis factorization control parameters */
+ glp_smcp smcp;
+ /* simplex method control parameters */
+ glp_iptcp iptcp;
+ /* interior-point method control parameters */
+ glp_iocp iocp;
+ /* integer optimizer control parameters */
+ glp_tran *tran;
+ /* model translator workspace */
+ glp_graph *graph;
+ /* network problem object */
+ int format;
+ /* problem file format: */
+#define FMT_MPS_DECK 1 /* fixed MPS */
+#define FMT_MPS_FILE 2 /* free MPS */
+#define FMT_LP 3 /* CPLEX LP */
+#define FMT_GLP 4 /* GLPK LP/MIP */
+#define FMT_MATHPROG 5 /* MathProg */
+#define FMT_MIN_COST 6 /* DIMACS min-cost flow */
+#define FMT_MAX_FLOW 7 /* DIMACS maximum flow */
+#if 1 /* 06/VIII-2011 */
+#define FMT_CNF 8 /* DIMACS CNF-SAT */
+#endif
+ const char *in_file;
+ /* name of input problem file */
+#define DATA_MAX 10
+ /* maximal number of input data files */
+ int ndf;
+ /* number of input data files specified */
+ const char *in_data[1+DATA_MAX];
+ /* name(s) of input data file(s) */
+ const char *out_dpy;
+ /* name of output file to send display output; NULL means the
+ display output is sent to the terminal */
+ int seed;
+ /* seed value to be passed to the MathProg translator; initially
+ set to 1; 0x80000000 means the value is omitted */
+ int solution;
+ /* solution type flag: */
+#define SOL_BASIC 1 /* basic */
+#define SOL_INTERIOR 2 /* interior-point */
+#define SOL_INTEGER 3 /* mixed integer */
+ const char *in_res;
+ /* name of input solution file in raw format */
+ int dir;
+ /* optimization direction flag:
+ 0 - not specified
+ GLP_MIN - minimization
+ GLP_MAX - maximization */
+ int scale;
+ /* automatic problem scaling flag */
+ const char *out_sol;
+ /* name of output solution file in printable format */
+ const char *out_res;
+ /* name of output solution file in raw format */
+ const char *out_ranges;
+ /* name of output file to write sensitivity analysis report */
+ int check;
+ /* input data checking flag; no solution is performed */
+ const char *new_name;
+ /* new name to be assigned to the problem */
+#if 1 /* 18/I-2018 */
+ int hide;
+ /* clear all symbolic names in the problem object */
+#endif
+ const char *out_mps;
+ /* name of output problem file in fixed MPS format */
+ const char *out_freemps;
+ /* name of output problem file in free MPS format */
+ const char *out_cpxlp;
+ /* name of output problem file in CPLEX LP format */
+ const char *out_glp;
+ /* name of output problem file in GLPK format */
+#if 0
+ const char *out_pb;
+ /* name of output problem file in OPB format */
+ const char *out_npb;
+ /* name of output problem file in normalized OPB format */
+#endif
+#if 1 /* 06/VIII-2011 */
+ const char *out_cnf;
+ /* name of output problem file in DIMACS CNF-SAT format */
+#endif
+ const char *log_file;
+ /* name of output file to hardcopy terminal output */
+ int crash;
+ /* initial basis option: */
+#define USE_STD_BASIS 1 /* use standard basis */
+#define USE_ADV_BASIS 2 /* use advanced basis */
+#define USE_CPX_BASIS 3 /* use Bixby's basis */
+#define USE_INI_BASIS 4 /* use initial basis from ini_file */
+ const char *ini_file;
+ /* name of input file containing initial basis */
+ int exact;
+ /* flag to use glp_exact rather than glp_simplex */
+ int xcheck;
+ /* flag to check final basis with glp_exact */
+ int nomip;
+ /* flag to consider MIP as pure LP */
+#if 1 /* 15/VIII-2011 */
+ int minisat;
+ /* option to solve feasibility problem with MiniSat solver */
+ int use_bnd;
+ /* option to bound objective function */
+ int obj_bnd;
+ /* upper (minization) or lower (maximization) objective bound */
+#endif
+#if 1 /* 11/VII-2013 */
+ const char *use_sol;
+ /* name of input mip solution file in GLPK format */
+#endif
+};
+
+static int str2int(const char *s, int *x)
+{ /* convert string to integer */
+ long t;
+ char *endptr;
+ t = strtol(s, &endptr, 10);
+ if (*endptr != '\0')
+ return 2;
+ if (!(INT_MIN <= t && t <= INT_MAX))
+ return 1;
+ *x = t;
+#if 0
+ xprintf("str2int: x = %d\n", *x);
+#endif
+ return 0;
+}
+
+static int str2num(const char *s, double *x)
+{ /* convert string to floating point */
+ double t;
+ char *endptr;
+ t = strtod(s, &endptr);
+ if (*endptr != '\0')
+ return 2;
+ if (!(-DBL_MAX <= t && t <= +DBL_MAX))
+ return 1;
+ *x = t;
+#if 0
+ xprintf("str2num: x = %g\n", *x);
+#endif
+ return 0;
+}
+
+static void print_help(const char *my_name)
+{ /* print help information */
+ xprintf("Usage: %s [options...] filename\n", my_name);
+ xprintf("\n");
+ xprintf("General options:\n");
+ xprintf(" --mps read LP/MIP problem in fixed MPS fo"
+ "rmat\n");
+ xprintf(" --freemps read LP/MIP problem in free MPS for"
+ "mat (default)\n");
+ xprintf(" --lp read LP/MIP problem in CPLEX LP for"
+ "mat\n");
+ xprintf(" --glp read LP/MIP problem in GLPK format "
+ "\n");
+ xprintf(" --math read LP/MIP model written in GNU Ma"
+ "thProg modeling\n");
+ xprintf(" language\n");
+ xprintf(" -m filename, --model filename\n");
+ xprintf(" read model section and optional dat"
+ "a section from\n");
+ xprintf(" filename (same as --math)\n");
+ xprintf(" -d filename, --data filename\n");
+ xprintf(" read data section from filename (fo"
+ "r --math only);\n");
+ xprintf(" if model file also has data section"
+ ", it is ignored\n");
+ xprintf(" -y filename, --display filename\n");
+ xprintf(" send display output to filename (fo"
+ "r --math only);\n");
+ xprintf(" by default the output is sent to te"
+ "rminal\n");
+ xprintf(" --seed value initialize pseudo-random number gen"
+ "erator used in\n");
+ xprintf(" MathProg model with specified seed "
+ "(any integer);\n");
+ xprintf(" if seed value is ?, some random see"
+ "d will be used\n");
+ xprintf(" --mincost read min-cost flow problem in DIMAC"
+ "S format\n");
+ xprintf(" --maxflow read maximum flow problem in DIMACS"
+ " format\n");
+#if 1 /* 06/VIII-2011 */
+ xprintf(" --cnf read CNF-SAT problem in DIMACS form"
+ "at\n");
+#endif
+ xprintf(" --simplex use simplex method (default)\n");
+ xprintf(" --interior use interior point method (LP only)"
+ "\n");
+ xprintf(" -r filename, --read filename\n");
+ xprintf(" read solution from filename rather "
+ "to find it with\n");
+ xprintf(" the solver\n");
+ xprintf(" --min minimization\n");
+ xprintf(" --max maximization\n");
+ xprintf(" --scale scale problem (default)\n");
+ xprintf(" --noscale do not scale problem\n");
+ xprintf(" -o filename, --output filename\n");
+ xprintf(" write solution to filename in print"
+ "able format\n");
+ xprintf(" -w filename, --write filename\n");
+ xprintf(" write solution to filename in plain"
+ " text format\n");
+ xprintf(" --ranges filename\n");
+ xprintf(" write sensitivity analysis report t"
+ "o filename in\n");
+ xprintf(" printable format (simplex only)\n");
+ xprintf(" --tmlim nnn limit solution time to nnn seconds "
+ "\n");
+ xprintf(" --memlim nnn limit available memory to nnn megab"
+ "ytes\n");
+ xprintf(" --check do not solve problem, check input d"
+ "ata only\n");
+ xprintf(" --name probname change problem name to probname\n");
+#if 1 /* 18/I-2018 */
+ xprintf(" --hide remove all symbolic names from prob"
+ "lem object\n");
+#endif
+ xprintf(" --wmps filename write problem to filename in fixed "
+ "MPS format\n");
+ xprintf(" --wfreemps filename\n");
+ xprintf(" write problem to filename in free M"
+ "PS format\n");
+ xprintf(" --wlp filename write problem to filename in CPLEX "
+ "LP format\n");
+ xprintf(" --wglp filename write problem to filename in GLPK f"
+ "ormat\n");
+#if 0
+ xprintf(" --wpb filename write problem to filename in OPB fo"
+ "rmat\n");
+ xprintf(" --wnpb filename write problem to filename in normal"
+ "ized OPB format\n");
+#endif
+#if 1 /* 06/VIII-2011 */
+ xprintf(" --wcnf filename write problem to filename in DIMACS"
+ " CNF-SAT format\n");
+#endif
+ xprintf(" --log filename write copy of terminal output to fi"
+ "lename\n");
+ xprintf(" -h, --help display this help information and e"
+ "xit\n");
+ xprintf(" -v, --version display program version and exit\n")
+ ;
+ xprintf("\n");
+ xprintf("LP basis factorization options:\n");
+#if 0 /* 08/III-2014 */
+ xprintf(" --luf LU + Forrest-Tomlin update\n");
+ xprintf(" (faster, less stable; default)\n");
+ xprintf(" --cbg LU + Schur complement + Bartels-Gol"
+ "ub update\n");
+ xprintf(" (slower, more stable)\n");
+ xprintf(" --cgr LU + Schur complement + Givens rota"
+ "tion update\n");
+ xprintf(" (slower, more stable)\n");
+#else
+ xprintf(" --luf plain LU-factorization (default)\n")
+ ;
+ xprintf(" --btf block triangular LU-factorization\n"
+ );
+ xprintf(" --ft Forrest-Tomlin update (requires --l"
+ "uf; default)\n");
+ xprintf(" --cbg Schur complement + Bartels-Golub up"
+ "date\n");
+ xprintf(" --cgr Schur complement + Givens rotation "
+ "update\n");
+#endif
+ xprintf("\n");
+ xprintf("Options specific to simplex solver:\n");
+ xprintf(" --primal use primal simplex (default)\n");
+ xprintf(" --dual use dual simplex\n");
+ xprintf(" --std use standard initial basis of all s"
+ "lacks\n");
+ xprintf(" --adv use advanced initial basis (default"
+ ")\n");
+ xprintf(" --bib use Bixby's initial basis\n");
+ xprintf(" --ini filename use as initial basis previously sav"
+ "ed with -w\n");
+ xprintf(" (disables LP presolver)\n");
+ xprintf(" --steep use steepest edge technique (defaul"
+ "t)\n");
+ xprintf(" --nosteep use standard \"textbook\" pricing\n"
+ );
+ xprintf(" --relax use Harris' two-pass ratio test (de"
+ "fault)\n");
+ xprintf(" --norelax use standard \"textbook\" ratio tes"
+ "t\n");
+#if 0 /* 23/VI-2017 */
+#if 1 /* 28/III-2016 */
+ xprintf(" --flip use flip-flop ratio test (assumes -"
+ "-dual)\n");
+#endif
+#else
+ /* now this option is implemented in both primal and dual */
+ xprintf(" --flip use long-step ratio test\n");
+#endif
+ xprintf(" --presol use presolver (default; assumes --s"
+ "cale and --adv)\n");
+ xprintf(" --nopresol do not use presolver\n");
+ xprintf(" --exact use simplex method based on exact a"
+ "rithmetic\n");
+ xprintf(" --xcheck check final basis using exact arith"
+ "metic\n");
+ xprintf("\n");
+ xprintf("Options specific to interior-point solver:\n");
+ xprintf(" --nord use natural (original) ordering\n");
+ xprintf(" --qmd use quotient minimum degree orderin"
+ "g\n");
+ xprintf(" --amd use approximate minimum degree orde"
+ "ring (default)\n");
+ xprintf(" --symamd use approximate minimum degree orde"
+ "ring\n");
+ xprintf("\n");
+ xprintf("Options specific to MIP solver:\n");
+ xprintf(" --nomip consider all integer variables as c"
+ "ontinuous\n");
+ xprintf(" (allows solving MIP as pure LP)\n");
+ xprintf(" --first branch on first integer variable\n")
+ ;
+ xprintf(" --last branch on last integer variable\n");
+ xprintf(" --mostf branch on most fractional variable "
+ "\n");
+ xprintf(" --drtom branch using heuristic by Driebeck "
+ "and Tomlin\n");
+ xprintf(" (default)\n");
+ xprintf(" --pcost branch using hybrid pseudocost heur"
+ "istic (may be\n");
+ xprintf(" useful for hard instances)\n");
+ xprintf(" --dfs backtrack using depth first search "
+ "\n");
+ xprintf(" --bfs backtrack using breadth first searc"
+ "h\n");
+ xprintf(" --bestp backtrack using the best projection"
+ " heuristic\n");
+ xprintf(" --bestb backtrack using node with best loca"
+ "l bound\n");
+ xprintf(" (default)\n");
+ xprintf(" --intopt use MIP presolver (default)\n");
+ xprintf(" --nointopt do not use MIP presolver\n");
+ xprintf(" --binarize replace general integer variables b"
+ "y binary ones\n");
+ xprintf(" (assumes --intopt)\n");
+ xprintf(" --fpump apply feasibility pump heuristic\n")
+ ;
+#if 1 /* 29/VI-2013 */
+ xprintf(" --proxy [nnn] apply proximity search heuristic (n"
+ "nn is time limit\n");
+ xprintf(" in seconds; default is 60)\n");
+#endif
+ xprintf(" --gomory generate Gomory's mixed integer cut"
+ "s\n");
+ xprintf(" --mir generate MIR (mixed integer roundin"
+ "g) cuts\n");
+ xprintf(" --cover generate mixed cover cuts\n");
+ xprintf(" --clique generate clique cuts\n");
+ xprintf(" --cuts generate all cuts above\n");
+ xprintf(" --mipgap tol set relative mip gap tolerance to t"
+ "ol\n");
+#if 1 /* 15/VIII-2011 */
+ xprintf(" --minisat translate integer feasibility probl"
+ "em to CNF-SAT\n");
+ xprintf(" and solve it with MiniSat solver\n")
+ ;
+ xprintf(" --objbnd bound add inequality obj <= bound (minimi"
+ "zation) or\n");
+ xprintf(" obj >= bound (maximization) to inte"
+ "ger feasibility\n");
+ xprintf(" problem (assumes --minisat)\n");
+#endif
+ xprintf("\n");
+ xprintf("For description of the MPS and CPLEX LP formats see Refe"
+ "rence Manual.\n");
+ xprintf("For description of the modeling language see \"GLPK: Mod"
+ "eling Language\n");
+ xprintf("GNU MathProg\". Both documents are included in the GLPK "
+ "distribution.\n");
+ xprintf("\n");
+ xprintf("See GLPK web page at <http://www.gnu.org/software/glpk/g"
+ "lpk.html>.\n");
+ xprintf("\n");
+ xprintf("Please report bugs to <bug-glpk@gnu.org>.\n");
+ return;
+}
+
+static void print_version(int briefly)
+{ /* print version information */
+ xprintf("GLPSOL--GLPK LP/MIP Solver %s\n", glp_version());
+ if (briefly) goto done;
+ xprintf("Copyright (C) 2000-2020 Free Software Foundation, Inc.\n"
+ );
+ xprintf("\n");
+ xprintf("This program has ABSOLUTELY NO WARRANTY.\n");
+ xprintf("\n");
+ xprintf("This program is free software; you may re-distribute it "
+ "under the terms\n");
+ xprintf("of the GNU General Public License version 3 or later.\n")
+ ;
+done: return;
+}
+
+static int parse_cmdline(struct csa *csa, int argc, char *argv[])
+{ /* parse command-line parameters */
+ int k;
+#define p(str) (strcmp(argv[k], str) == 0)
+ for (k = 1; k < argc; k++)
+ { if (p("--mps"))
+ csa->format = FMT_MPS_DECK;
+ else if (p("--freemps"))
+ csa->format = FMT_MPS_FILE;
+ else if (p("--lp") || p("--cpxlp"))
+ csa->format = FMT_LP;
+ else if (p("--glp"))
+ csa->format = FMT_GLP;
+ else if (p("--math") || p("-m") || p("--model"))
+ csa->format = FMT_MATHPROG;
+ else if (p("-d") || p("--data"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No input data file specified\n");
+ return 1;
+ }
+ if (csa->ndf == DATA_MAX)
+ { xprintf("Too many input data files\n");
+ return 1;
+ }
+ csa->in_data[++(csa->ndf)] = argv[k];
+ }
+ else if (p("-y") || p("--display"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No display output file specified\n");
+ return 1;
+ }
+ if (csa->out_dpy != NULL)
+ { xprintf("Only one display output file allowed\n");
+ return 1;
+ }
+ csa->out_dpy = argv[k];
+ }
+ else if (p("--seed"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' ||
+ argv[k][0] == '-' && !isdigit((unsigned char)argv[k][1]))
+ { xprintf("No seed value specified\n");
+ return 1;
+ }
+ if (strcmp(argv[k], "?") == 0)
+ csa->seed = 0x80000000;
+ else if (str2int(argv[k], &csa->seed))
+ { xprintf("Invalid seed value '%s'\n", argv[k]);
+ return 1;
+ }
+ }
+ else if (p("--mincost"))
+ csa->format = FMT_MIN_COST;
+ else if (p("--maxflow"))
+ csa->format = FMT_MAX_FLOW;
+#if 1 /* 06/VIII-2011 */
+ else if (p("--cnf"))
+ csa->format = FMT_CNF;
+#endif
+ else if (p("--simplex"))
+ csa->solution = SOL_BASIC;
+ else if (p("--interior"))
+ csa->solution = SOL_INTERIOR;
+#if 1 /* 28/V-2010 */
+ else if (p("--alien"))
+ csa->iocp.alien = GLP_ON;
+#endif
+ else if (p("-r") || p("--read"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No input solution file specified\n");
+ return 1;
+ }
+ if (csa->in_res != NULL)
+ { xprintf("Only one input solution file allowed\n");
+ return 1;
+ }
+ csa->in_res = argv[k];
+ }
+ else if (p("--min"))
+ csa->dir = GLP_MIN;
+ else if (p("--max"))
+ csa->dir = GLP_MAX;
+ else if (p("--scale"))
+ csa->scale = 1;
+ else if (p("--noscale"))
+ csa->scale = 0;
+ else if (p("-o") || p("--output"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No output solution file specified\n");
+ return 1;
+ }
+ if (csa->out_sol != NULL)
+ { xprintf("Only one output solution file allowed\n");
+ return 1;
+ }
+ csa->out_sol = argv[k];
+ }
+ else if (p("-w") || p("--write"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No output solution file specified\n");
+ return 1;
+ }
+ if (csa->out_res != NULL)
+ { xprintf("Only one output solution file allowed\n");
+ return 1;
+ }
+ csa->out_res = argv[k];
+ }
+ else if (p("--ranges") || p("--bounds"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No output file specified to write sensitivity a"
+ "nalysis report\n");
+ return 1;
+ }
+ if (csa->out_ranges != NULL)
+ { xprintf("Only one output file allowed to write sensitivi"
+ "ty analysis report\n");
+ return 1;
+ }
+ csa->out_ranges = argv[k];
+ }
+ else if (p("--tmlim"))
+ { int tm_lim;
+ k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No time limit specified\n");
+ return 1;
+ }
+ if (str2int(argv[k], &tm_lim) || tm_lim < 0)
+ { xprintf("Invalid time limit '%s'\n", argv[k]);
+ return 1;
+ }
+ if (tm_lim <= INT_MAX / 1000)
+ csa->smcp.tm_lim = csa->iocp.tm_lim = 1000 * tm_lim;
+ else
+ csa->smcp.tm_lim = csa->iocp.tm_lim = INT_MAX;
+ }
+ else if (p("--memlim"))
+ { int mem_lim;
+ k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No memory limit specified\n");
+ return 1;
+ }
+ if (str2int(argv[k], &mem_lim) || mem_lim < 1)
+ { xprintf("Invalid memory limit '%s'\n", argv[k]);
+ return 1;
+ }
+ glp_mem_limit(mem_lim);
+ }
+ else if (p("--check"))
+ csa->check = 1;
+ else if (p("--name"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No problem name specified\n");
+ return 1;
+ }
+ if (csa->new_name != NULL)
+ { xprintf("Only one problem name allowed\n");
+ return 1;
+ }
+ csa->new_name = argv[k];
+ }
+#if 1 /* 18/I-2018 */
+ else if (p("--hide"))
+ csa->hide = 1;
+#endif
+ else if (p("--wmps"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No fixed MPS output file specified\n");
+ return 1;
+ }
+ if (csa->out_mps != NULL)
+ { xprintf("Only one fixed MPS output file allowed\n");
+ return 1;
+ }
+ csa->out_mps = argv[k];
+ }
+ else if (p("--wfreemps"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No free MPS output file specified\n");
+ return 1;
+ }
+ if (csa->out_freemps != NULL)
+ { xprintf("Only one free MPS output file allowed\n");
+ return 1;
+ }
+ csa->out_freemps = argv[k];
+ }
+ else if (p("--wlp") || p("--wcpxlp") || p("--wlpt"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No CPLEX LP output file specified\n");
+ return 1;
+ }
+ if (csa->out_cpxlp != NULL)
+ { xprintf("Only one CPLEX LP output file allowed\n");
+ return 1;
+ }
+ csa->out_cpxlp = argv[k];
+ }
+ else if (p("--wglp"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No GLPK LP/MIP output file specified\n");
+ return 1;
+ }
+ if (csa->out_glp != NULL)
+ { xprintf("Only one GLPK LP/MIP output file allowed\n");
+ return 1;
+ }
+ csa->out_glp = argv[k];
+ }
+#if 0
+ else if (p("--wpb"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No problem output file specified\n");
+ return 1;
+ }
+ if (csa->out_pb != NULL)
+ { xprintf("Only one OPB output file allowed\n");
+ return 1;
+ }
+ csa->out_pb = argv[k];
+ }
+ else if (p("--wnpb"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No problem output file specified\n");
+ return 1;
+ }
+ if (csa->out_npb != NULL)
+ { xprintf("Only one normalized OPB output file allowed\n");
+ return 1;
+ }
+ csa->out_npb = argv[k];
+ }
+#endif
+#if 1 /* 06/VIII-2011 */
+ else if (p("--wcnf"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No problem output file specified\n");
+ return 1;
+ }
+ if (csa->out_cnf != NULL)
+ { xprintf("Only one output DIMACS CNF-SAT file allowed\n");
+ return 1;
+ }
+ csa->out_cnf = argv[k];
+ }
+#endif
+ else if (p("--log"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No log file specified\n");
+ return 1;
+ }
+ if (csa->log_file != NULL)
+ { xprintf("Only one log file allowed\n");
+ return 1;
+ }
+ csa->log_file = argv[k];
+ }
+ else if (p("-h") || p("--help"))
+ { print_help(argv[0]);
+ return -1;
+ }
+ else if (p("-v") || p("--version"))
+ { print_version(0);
+ return -1;
+ }
+#if 0 /* 08/III-2014 */
+ else if (p("--luf"))
+ csa->bfcp.type = GLP_BF_FT;
+ else if (p("--cbg"))
+ csa->bfcp.type = GLP_BF_BG;
+ else if (p("--cgr"))
+ csa->bfcp.type = GLP_BF_GR;
+#else
+ else if (p("--luf"))
+ { csa->bfcp.type &= 0x0F;
+ csa->bfcp.type |= GLP_BF_LUF;
+ }
+ else if (p("--btf"))
+ { csa->bfcp.type &= 0x0F;
+ csa->bfcp.type |= GLP_BF_BTF;
+ }
+ else if (p("--ft"))
+ { csa->bfcp.type &= 0xF0;
+ csa->bfcp.type |= GLP_BF_FT;
+ }
+ else if (p("--cbg"))
+ { csa->bfcp.type &= 0xF0;
+ csa->bfcp.type |= GLP_BF_BG;
+ }
+ else if (p("--cgr"))
+ { csa->bfcp.type &= 0xF0;
+ csa->bfcp.type |= GLP_BF_GR;
+ }
+#endif
+ else if (p("--primal"))
+ csa->smcp.meth = GLP_PRIMAL;
+ else if (p("--dual"))
+ csa->smcp.meth = GLP_DUAL;
+ else if (p("--std"))
+ csa->crash = USE_STD_BASIS;
+ else if (p("--adv"))
+ csa->crash = USE_ADV_BASIS;
+ else if (p("--bib"))
+ csa->crash = USE_CPX_BASIS;
+ else if (p("--ini"))
+ { csa->crash = USE_INI_BASIS;
+ csa->smcp.presolve = GLP_OFF;
+ k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No initial basis file specified\n");
+ return 1;
+ }
+ if (csa->ini_file != NULL)
+ { xprintf("Only one initial basis file allowed\n");
+ return 1;
+ }
+ csa->ini_file = argv[k];
+ }
+ else if (p("--steep"))
+ csa->smcp.pricing = GLP_PT_PSE;
+ else if (p("--nosteep"))
+ csa->smcp.pricing = GLP_PT_STD;
+ else if (p("--relax"))
+ csa->smcp.r_test = GLP_RT_HAR;
+ else if (p("--norelax"))
+ csa->smcp.r_test = GLP_RT_STD;
+#if 1 /* 28/III-2016 */
+ else if (p("--flip"))
+#if 0 /* 23/VI-2017 */
+ { csa->smcp.meth = GLP_DUAL;
+#else
+ /* now this option is implemented in both primal and dual */
+ {
+#endif
+ csa->smcp.r_test = GLP_RT_FLIP;
+ csa->iocp.flip = GLP_ON;
+ }
+#endif
+ else if (p("--presol"))
+ csa->smcp.presolve = GLP_ON;
+ else if (p("--nopresol"))
+ csa->smcp.presolve = GLP_OFF;
+ else if (p("--exact"))
+ csa->exact = 1;
+ else if (p("--xcheck"))
+ csa->xcheck = 1;
+ else if (p("--nord"))
+ csa->iptcp.ord_alg = GLP_ORD_NONE;
+ else if (p("--qmd"))
+ csa->iptcp.ord_alg = GLP_ORD_QMD;
+ else if (p("--amd"))
+ csa->iptcp.ord_alg = GLP_ORD_AMD;
+ else if (p("--symamd"))
+ csa->iptcp.ord_alg = GLP_ORD_SYMAMD;
+ else if (p("--nomip"))
+ csa->nomip = 1;
+ else if (p("--first"))
+ csa->iocp.br_tech = GLP_BR_FFV;
+ else if (p("--last"))
+ csa->iocp.br_tech = GLP_BR_LFV;
+ else if (p("--drtom"))
+ csa->iocp.br_tech = GLP_BR_DTH;
+ else if (p("--mostf"))
+ csa->iocp.br_tech = GLP_BR_MFV;
+ else if (p("--pcost"))
+ csa->iocp.br_tech = GLP_BR_PCH;
+ else if (p("--dfs"))
+ csa->iocp.bt_tech = GLP_BT_DFS;
+ else if (p("--bfs"))
+ csa->iocp.bt_tech = GLP_BT_BFS;
+ else if (p("--bestp"))
+ csa->iocp.bt_tech = GLP_BT_BPH;
+ else if (p("--bestb"))
+ csa->iocp.bt_tech = GLP_BT_BLB;
+ else if (p("--intopt"))
+ csa->iocp.presolve = GLP_ON;
+ else if (p("--nointopt"))
+ csa->iocp.presolve = GLP_OFF;
+ else if (p("--binarize"))
+ csa->iocp.presolve = csa->iocp.binarize = GLP_ON;
+ else if (p("--fpump"))
+ csa->iocp.fp_heur = GLP_ON;
+#if 1 /* 29/VI-2013 */
+ else if (p("--proxy"))
+ { csa->iocp.ps_heur = GLP_ON;
+ if (argv[k+1] && isdigit((unsigned char)argv[k+1][0]))
+ { int nnn;
+ k++;
+ if (str2int(argv[k], &nnn) || nnn < 1)
+ { xprintf("Invalid proxy time limit '%s'\n", argv[k]);
+ return 1;
+ }
+ csa->iocp.ps_tm_lim = 1000 * nnn;
+ }
+ }
+#endif
+ else if (p("--gomory"))
+ csa->iocp.gmi_cuts = GLP_ON;
+ else if (p("--mir"))
+ csa->iocp.mir_cuts = GLP_ON;
+ else if (p("--cover"))
+ csa->iocp.cov_cuts = GLP_ON;
+ else if (p("--clique"))
+ csa->iocp.clq_cuts = GLP_ON;
+ else if (p("--cuts"))
+ csa->iocp.gmi_cuts = csa->iocp.mir_cuts =
+ csa->iocp.cov_cuts = csa->iocp.clq_cuts = GLP_ON;
+ else if (p("--mipgap"))
+ { double mip_gap;
+ k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No relative gap tolerance specified\n");
+ return 1;
+ }
+ if (str2num(argv[k], &mip_gap) || mip_gap < 0.0)
+ { xprintf("Invalid relative mip gap tolerance '%s'\n",
+ argv[k]);
+ return 1;
+ }
+ csa->iocp.mip_gap = mip_gap;
+ }
+#if 1 /* 15/VIII-2011 */
+ else if (p("--minisat"))
+ csa->minisat = 1;
+ else if (p("--objbnd"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' ||
+ argv[k][0] == '-' && !isdigit((unsigned char)argv[k][1]))
+ { xprintf("No objective bound specified\n");
+ return 1;
+ }
+ csa->minisat = 1;
+ csa->use_bnd = 1;
+ if (str2int(argv[k], &csa->obj_bnd))
+ { xprintf("Invalid objective bound '%s' (should be integer"
+ " value)\n", argv[k]);
+ return 1;
+ }
+ }
+#endif
+#if 1 /* 11/VII-2013 */
+ else if (p("--use"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No input MIP solution file specified\n");
+ return 1;
+ }
+ if (csa->use_sol != NULL)
+ { xprintf("Only one input MIP solution file allowed\n");
+ return 1;
+ }
+ csa->use_sol = argv[k];
+ }
+ else if (p("--save"))
+ { k++;
+ if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
+ { xprintf("No output MIP solution file specified\n");
+ return 1;
+ }
+ if (csa->iocp.save_sol != NULL)
+ { xprintf("Only one output MIP solution file allowed\n");
+ return 1;
+ }
+ csa->iocp.save_sol = argv[k];
+ }
+#endif
+ else if (argv[k][0] == '-' ||
+ (argv[k][0] == '-' && argv[k][1] == '-'))
+ { xprintf("Invalid option '%s'; try %s --help\n",
+ argv[k], argv[0]);
+ return 1;
+ }
+ else
+ { if (csa->in_file != NULL)
+ { xprintf("Only one input problem file allowed\n");
+ return 1;
+ }
+ csa->in_file = argv[k];
+ }
+ }
+#undef p
+ return 0;
+}
+
+typedef struct { double rhs, pi; } v_data;
+typedef struct { double low, cap, cost, x; } a_data;
+
+/* eof */
diff --git a/simplex-glpk/src/host.cpp b/simplex-glpk/src/host.cpp
new file mode 100644
index 0000000..617f8ca
--- /dev/null
+++ b/simplex-glpk/src/host.cpp
@@ -0,0 +1,834 @@
+//==============================================================
+// Copyright Intel Corporation
+//
+// SPDX-License-Identifier: MIT
+// =============================================================
+
+#include <iostream>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+#include <CL/sycl.hpp>
+#include <sycl/ext/intel/fpga_extensions.hpp>
+
+// dpc_common.hpp can be found in the dev-utilities include folder.
+// e.g., $ONEAPI_ROOT/dev-utilities//include/dpc_common.hpp
+#include "dpc_common.hpp"
+
+#include "glpsol.h"
+// This code sample demonstrates how to split the host and FPGA kernel code into
+// separate compilation units so that they can be separately recompiled.
+// Consult the README for a detailed discussion.
+// - host.cpp (this file) contains exclusively code that executes on the host.
+// - kernel.cpp contains almost exclusively code that executes on the device.
+// - kernel.hpp contains only the forward declaration of a function containing
+// the device code.
+#include "kernel.hpp"
+
+using namespace sycl;
+
+// Create an exception handler for asynchronous SYCL exceptions
+static auto exception_handler = [](sycl::exception_list e_list) {
+ for (std::exception_ptr const &e : e_list) {
+ try {
+ std::rethrow_exception(e);
+ }
+ catch (std::exception const &e) {
+#if _DEBUG
+ std::cout << "Failure" << std::endl;
+#endif
+ std::terminate();
+ }
+ }
+};
+
+template <typename K>
+void printMatrix(std::vector<K> &vec, int col, std::string msg) {
+ std::cout << msg << ":" << std::endl << "[" << std::endl;
+ for (size_t i=0; i<vec.size(); ++i) {
+ std::cout << vec.at(i);
+ if (i<vec.size()-1 && vec.size() > 1) {
+ std::cout << ",\t";
+ }
+ if (i%col == col-1) {
+ std::cout << std::endl;
+ }
+ }
+ std::cout << "]" << std::endl;
+}
+
+template <typename K>
+void printVec(std::vector<K> &vec, std::string msg) {
+ std::cout << msg << ": ";
+ std::cout << "[";
+
+ for (size_t i=0; i<vec.size(); ++i) {
+ std::cout << vec.at(i);
+ if (i<vec.size()-1 && vec.size() > 1) {
+ std::cout << ", ";
+ }
+ }
+ std::cout << "]" << std::endl;
+}
+
+int main2() {
+ std::vector<float> a = { 2, 1, 1, 1, 0, 0,
+ 1, 3, 2, 0, 1, 0,
+ 2, 1, 2, 0, 0, 1};
+
+ std::vector<float> c = {-6, -5, -4, 0, 0, 0};
+ std::vector<float> b = {180, 300, 240};
+
+ std::vector<int> resultFlags = {-1, -1, -1};
+
+
+
+ // Select either the FPGA emulator or FPGA device
+#if defined(FPGA_EMULATOR)
+ ext::intel::fpga_emulator_selector device_selector;
+#else
+ ext::intel::fpga_selector device_selector;
+#endif
+
+ try {
+ // Create a queue bound to the chosen device.
+ // If the device is unavailable, a SYCL runtime exception is thrown.
+ queue q(device_selector, exception_handler);
+
+ device d = q.get_device();
+ // Print out the device information used for the kernel code.
+ std::cout << "Running on device: "
+ << d.get_info<info::device::name>() << "\n";
+
+ // make sure the device supports USM device allocations
+ if (!d.get_info<info::device::usm_device_allocations>()) {
+ std::cerr << "ERROR: The selected device does not support USM device"
+ << " allocations\n";
+ return 1;
+ }
+
+ printMatrix(a, 6, "a");
+ printVec(resultFlags, "result flags");
+ // The definition of this function is in a different compilation unit,
+ // so host and device code can be separately compiled.
+ double timePassed = RunKernel(q, a, b, c, resultFlags);
+
+ std::cout << "------------------------" << std::endl;
+ printMatrix(a, 6, "a");
+ printVec(resultFlags, "result flags");
+
+ std::cout << std::endl << std::endl;
+ std::cout << "timePassed: " << timePassed << std::endl;
+
+
+ } catch (exception const &e) {
+ // Catches exceptions in the host code
+ std::cerr << "Caught a SYCL host exception:\n" << e.what() << "\n";
+
+ // Most likely the runtime couldn't find FPGA hardware!
+ if (e.code().value() == CL_DEVICE_NOT_FOUND) {
+ std::cerr << "If you are targeting an FPGA, please ensure that your "
+ "system has a correctly configured FPGA board.\n";
+ std::cerr << "Run sys_check in the oneAPI root directory to verify.\n";
+ std::cerr << "If you are targeting the FPGA emulator, compile with "
+ "-DFPGA_EMULATOR.\n";
+ }
+ std::terminate();
+ }
+
+
+ std::cout << "done\n";
+ return 0;
+}
+
+
+int runOnFPGA() {
+
+
+ // Select either the FPGA emulator or FPGA device
+#if defined(FPGA_EMULATOR)
+ ext::intel::fpga_emulator_selector device_selector;
+#else
+ ext::intel::fpga_selector device_selector;
+#endif
+
+ try {
+ // Create a queue bound to the chosen device.
+ // If the device is unavailable, a SYCL runtime exception is thrown.
+ queue q(device_selector, exception_handler);
+
+ device d = q.get_device();
+ // Print out the device information used for the kernel code.
+ std::cout << "Running on device: "
+ << d.get_info<info::device::name>() << "\n";
+
+ // make sure the device supports USM device allocations
+ if (!d.get_info<info::device::usm_device_allocations>()) {
+ std::cerr << "ERROR: The selected device does not support USM device"
+ << " allocations\n";
+ return 1;
+ }
+
+
+ int *parallel = malloc_shared<int>(1000, q);
+
+
+ double timePassed = 0; //RunKernel(q, a, b, c, resultFlags);
+
+ std::cout << std::endl;
+ std::cout << "timePassed: " << timePassed << std::endl;
+
+ } catch (exception const &e) {
+ // Catches exceptions in the host code
+ std::cerr << "Caught a SYCL host exception:\n" << e.what() << "\n";
+
+ // Most likely the runtime couldn't find FPGA hardware!
+ if (e.code().value() == CL_DEVICE_NOT_FOUND) {
+ std::cerr << "If you are targeting an FPGA, please ensure that your "
+ "system has a correctly configured FPGA board.\n";
+ std::cerr << "Run sys_check in the oneAPI root directory to verify.\n";
+ std::cerr << "If you are targeting the FPGA emulator, compile with "
+ "-DFPGA_EMULATOR.\n";
+ }
+ std::terminate();
+ }
+
+
+ std::cout << "done\n";
+ return 0;
+}
+
+
+void hellothere(void *tmpCSA) {
+ int *a = static_cast<int*>(tmpCSA);
+ std::cout << "callback from simplex..." << std::endl;
+ std::cout << "test output a:" << *a << " " << std::endl;
+ *a = 9999;
+}
+
+int main(int argc, char *argv[])
+{ /* stand-alone LP/MIP solver */
+ struct csa _csa, *csa = &_csa;
+ int ret;
+#if 0 /* 10/VI-2013 */
+ glp_long start;
+#else
+ double start;
+#endif
+ /* perform initialization */
+ csa->prob = glp_create_prob();
+ glp_get_bfcp(csa->prob, &csa->bfcp);
+ glp_init_smcp(&csa->smcp);
+ csa->smcp.presolve = GLP_ON;
+ glp_init_iptcp(&csa->iptcp);
+ glp_init_iocp(&csa->iocp);
+ csa->iocp.presolve = GLP_ON;
+ csa->tran = NULL;
+ csa->graph = NULL;
+ csa->format = FMT_MPS_FILE;
+ csa->in_file = NULL;
+ csa->ndf = 0;
+ csa->out_dpy = NULL;
+ csa->seed = 1;
+ csa->solution = SOL_BASIC;
+ csa->in_res = NULL;
+ csa->dir = 0;
+ csa->scale = 1;
+ csa->out_sol = NULL;
+ csa->out_res = NULL;
+ csa->out_ranges = NULL;
+ csa->check = 0;
+ csa->new_name = NULL;
+#if 1 /* 18/I-2018 */
+ csa->hide = 0;
+#endif
+ csa->out_mps = NULL;
+ csa->out_freemps = NULL;
+ csa->out_cpxlp = NULL;
+ csa->out_glp = NULL;
+#if 0
+ csa->out_pb = NULL;
+ csa->out_npb = NULL;
+#endif
+#if 1 /* 06/VIII-2011 */
+ csa->out_cnf = NULL;
+#endif
+ csa->log_file = NULL;
+ csa->crash = USE_ADV_BASIS;
+ csa->ini_file = NULL;
+ csa->exact = 0;
+ csa->xcheck = 0;
+ csa->nomip = 0;
+#if 1 /* 15/VIII-2011 */
+ csa->minisat = 0;
+ csa->use_bnd = 0;
+ csa->obj_bnd = 0;
+#endif
+#if 1 /* 11/VII-2013 */
+ csa->use_sol = NULL;
+#endif
+ /* parse command-line parameters */
+ ret = parse_cmdline(csa, argc, argv);
+ if (ret < 0)
+ { ret = EXIT_SUCCESS;
+ goto done;
+ }
+ if (ret > 0)
+ { ret = EXIT_FAILURE;
+ goto done;
+ }
+ /*--------------------------------------------------------------*/
+ /* remove all output files specified in the command line */
+ if (csa->out_dpy != NULL) remove(csa->out_dpy);
+ if (csa->out_sol != NULL) remove(csa->out_sol);
+ if (csa->out_res != NULL) remove(csa->out_res);
+ if (csa->out_ranges != NULL) remove(csa->out_ranges);
+ if (csa->out_mps != NULL) remove(csa->out_mps);
+ if (csa->out_freemps != NULL) remove(csa->out_freemps);
+ if (csa->out_cpxlp != NULL) remove(csa->out_cpxlp);
+ if (csa->out_glp != NULL) remove(csa->out_glp);
+#if 0
+ if (csa->out_pb != NULL) remove(csa->out_pb);
+ if (csa->out_npb != NULL) remove(csa->out_npb);
+#endif
+#if 1 /* 06/VIII-2011 */
+ if (csa->out_cnf != NULL) remove(csa->out_cnf);
+#endif
+ if (csa->log_file != NULL) remove(csa->log_file);
+ /*--------------------------------------------------------------*/
+ /* open log file, if required */
+ if (csa->log_file != NULL)
+ { if (glp_open_tee(csa->log_file))
+ { xprintf("Unable to create log file\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ }
+ /*--------------------------------------------------------------*/
+ /* print version information */
+ print_version(1);
+ /*--------------------------------------------------------------*/
+ /* print parameters specified in the command line */
+ if (argc > 1)
+ { int k, len = INT_MAX;
+ xprintf("Parameter(s) specified in the command line:");
+ for (k = 1; k < argc; k++)
+ { if (len > 72)
+ xprintf("\n"), len = 0;
+ xprintf(" %s", argv[k]);
+ len += 1 + strlen(argv[k]);
+ }
+ xprintf("\n");
+ }
+ /*--------------------------------------------------------------*/
+ /* read problem data from the input file */
+ if (csa->in_file == NULL)
+ { xprintf("No input problem file specified; try %s --help\n",
+ argv[0]);
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ if (csa->format == FMT_MPS_DECK)
+ { ret = glp_read_mps(csa->prob, GLP_MPS_DECK, NULL,
+ csa->in_file);
+ if (ret != 0)
+err1: { xprintf("MPS file processing error\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ }
+ else if (csa->format == FMT_MPS_FILE)
+ { ret = glp_read_mps(csa->prob, GLP_MPS_FILE, NULL,
+ csa->in_file);
+ if (ret != 0) goto err1;
+ }
+ else if (csa->format == FMT_LP)
+ { ret = glp_read_lp(csa->prob, NULL, csa->in_file);
+ if (ret != 0)
+ { xprintf("CPLEX LP file processing error\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ }
+ else if (csa->format == FMT_GLP)
+ { ret = glp_read_prob(csa->prob, 0, csa->in_file);
+ if (ret != 0)
+ { xprintf("GLPK LP/MIP file processing error\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ }
+ else if (csa->format == FMT_MATHPROG)
+ { int k;
+ /* allocate the translator workspace */
+ csa->tran = glp_mpl_alloc_wksp();
+ /* set seed value */
+ if (csa->seed == 0x80000000)
+#if 0 /* 10/VI-2013 */
+ { csa->seed = glp_time().lo;
+#else
+ { csa->seed = (int)fmod(glp_time(), 1000000000.0);
+#endif
+ xprintf("Seed value %d will be used\n", csa->seed);
+ }
+ glp_mpl_init_rand(csa->tran, csa->seed);
+ /* read model section and optional data section */
+ if (glp_mpl_read_model(csa->tran, csa->in_file, csa->ndf > 0))
+err2: { xprintf("MathProg model processing error\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ /* read optional data section(s), if necessary */
+ for (k = 1; k <= csa->ndf; k++)
+ { if (glp_mpl_read_data(csa->tran, csa->in_data[k]))
+ goto err2;
+ }
+ /* generate the model */
+ if (glp_mpl_generate(csa->tran, csa->out_dpy)) goto err2;
+ /* build the problem instance from the model */
+ glp_mpl_build_prob(csa->tran, csa->prob);
+ }
+ else if (csa->format == FMT_MIN_COST)
+ { csa->graph = glp_create_graph(sizeof(v_data), sizeof(a_data));
+ ret = glp_read_mincost(csa->graph, offsetof(v_data, rhs),
+ offsetof(a_data, low), offsetof(a_data, cap),
+ offsetof(a_data, cost), csa->in_file);
+ if (ret != 0)
+ { xprintf("DIMACS file processing error\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ glp_mincost_lp(csa->prob, csa->graph, GLP_ON,
+ offsetof(v_data, rhs), offsetof(a_data, low),
+ offsetof(a_data, cap), offsetof(a_data, cost));
+ glp_set_prob_name(csa->prob, csa->in_file);
+ }
+ else if (csa->format == FMT_MAX_FLOW)
+ { int s, t;
+ csa->graph = glp_create_graph(sizeof(v_data), sizeof(a_data));
+ ret = glp_read_maxflow(csa->graph, &s, &t,
+ offsetof(a_data, cap), csa->in_file);
+ if (ret != 0)
+ { xprintf("DIMACS file processing error\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ glp_maxflow_lp(csa->prob, csa->graph, GLP_ON, s, t,
+ offsetof(a_data, cap));
+ glp_set_prob_name(csa->prob, csa->in_file);
+ }
+#if 1 /* 06/VIII-2011 */
+ else if (csa->format == FMT_CNF)
+ { ret = glp_read_cnfsat(csa->prob, csa->in_file);
+ if (ret != 0)
+ { xprintf("DIMACS file processing error\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ glp_set_prob_name(csa->prob, csa->in_file);
+ }
+#endif
+ else
+ xassert(csa != csa);
+ /*--------------------------------------------------------------*/
+ /* change problem name, if required */
+ if (csa->new_name != NULL)
+ glp_set_prob_name(csa->prob, csa->new_name);
+ /* change optimization direction, if required */
+ if (csa->dir != 0)
+ glp_set_obj_dir(csa->prob, csa->dir);
+ /* sort elements of the constraint matrix */
+ glp_sort_matrix(csa->prob);
+#if 1 /* 18/I-2018 */
+ /*--------------------------------------------------------------*/
+ /* remove all symbolic names from problem object, if required */
+ if (csa->hide)
+ { int i, j;
+ glp_set_obj_name(csa->prob, NULL);
+ glp_delete_index(csa->prob);
+ for (i = glp_get_num_rows(csa->prob); i >= 1; i--)
+ glp_set_row_name(csa->prob, i, NULL);
+ for (j = glp_get_num_cols(csa->prob); j >= 1; j--)
+ glp_set_col_name(csa->prob, j, NULL);
+ }
+#endif
+ /*--------------------------------------------------------------*/
+ /* write problem data in fixed MPS format, if required */
+ if (csa->out_mps != NULL)
+ { ret = glp_write_mps(csa->prob, GLP_MPS_DECK, NULL,
+ csa->out_mps);
+ if (ret != 0)
+ { xprintf("Unable to write problem in fixed MPS format\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ }
+ /* write problem data in free MPS format, if required */
+ if (csa->out_freemps != NULL)
+ { ret = glp_write_mps(csa->prob, GLP_MPS_FILE, NULL,
+ csa->out_freemps);
+ if (ret != 0)
+ { xprintf("Unable to write problem in free MPS format\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ }
+ /* write problem data in CPLEX LP format, if required */
+ if (csa->out_cpxlp != NULL)
+ { ret = glp_write_lp(csa->prob, NULL, csa->out_cpxlp);
+ if (ret != 0)
+ { xprintf("Unable to write problem in CPLEX LP format\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ }
+ /* write problem data in GLPK format, if required */
+ if (csa->out_glp != NULL)
+ { ret = glp_write_prob(csa->prob, 0, csa->out_glp);
+ if (ret != 0)
+ { xprintf("Unable to write problem in GLPK format\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ }
+#if 0
+ /* write problem data in OPB format, if required */
+ if (csa->out_pb != NULL)
+ { ret = lpx_write_pb(csa->prob, csa->out_pb, 0, 0);
+ if (ret != 0)
+ { xprintf("Unable to write problem in OPB format\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ }
+ /* write problem data in normalized OPB format, if required */
+ if (csa->out_npb != NULL)
+ { ret = lpx_write_pb(csa->prob, csa->out_npb, 1, 1);
+ if (ret != 0)
+ { xprintf(
+ "Unable to write problem in normalized OPB format\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ }
+#endif
+#if 1 /* 06/VIII-2011 */
+ /* write problem data in DIMACS CNF-SAT format, if required */
+ if (csa->out_cnf != NULL)
+ { ret = glp_write_cnfsat(csa->prob, csa->out_cnf);
+ if (ret != 0)
+ { xprintf(
+ "Unable to write problem in DIMACS CNF-SAT format\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ }
+#endif
+ /*--------------------------------------------------------------*/
+ /* if only problem data check is required, skip computations */
+ if (csa->check)
+ {
+#if 1 /* 29/III-2016 */
+ /* report problem characteristics */
+ int j, cnt = 0;
+ xprintf("--- Problem Characteristics ---\n");
+ xprintf("Number of rows = %8d\n",
+ glp_get_num_rows(csa->prob));
+ xprintf("Number of columns = %8d\n",
+ glp_get_num_cols(csa->prob));
+ xprintf("Number of non-zeros (matrix) = %8d\n",
+ glp_get_num_nz(csa->prob));
+ for (j = glp_get_num_cols(csa->prob); j >= 1; j--)
+ { if (glp_get_obj_coef(csa->prob, j) != 0.0)
+ cnt++;
+ }
+ xprintf("Number of non-zeros (objrow) = %8d\n",
+ cnt);
+#endif
+ ret = EXIT_SUCCESS;
+ goto done;
+ }
+ /*--------------------------------------------------------------*/
+ /* determine the solution type */
+ if (!csa->nomip &&
+ glp_get_num_int(csa->prob) + glp_get_num_bin(csa->prob) > 0)
+ { if (csa->solution == SOL_INTERIOR)
+ { xprintf("Interior-point method is not able to solve MIP pro"
+ "blem; use --simplex\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ csa->solution = SOL_INTEGER;
+ }
+ /*--------------------------------------------------------------*/
+ /* if solution is provided, read it and skip computations */
+ if (csa->in_res != NULL)
+ { if (csa->solution == SOL_BASIC)
+ ret = glp_read_sol(csa->prob, csa->in_res);
+ else if (csa->solution == SOL_INTERIOR)
+ ret = glp_read_ipt(csa->prob, csa->in_res);
+ else if (csa->solution == SOL_INTEGER)
+ ret = glp_read_mip(csa->prob, csa->in_res);
+ else
+ xassert(csa != csa);
+ if (ret != 0)
+ { xprintf("Unable to read problem solution\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ goto skip;
+ }
+#if 1 /* 11/VII-2013 */
+ /*--------------------------------------------------------------*/
+ /* if initial MIP solution is provided, read it */
+ if (csa->solution == SOL_INTEGER && csa->use_sol != NULL)
+ { ret = glp_read_mip(csa->prob, csa->use_sol);
+ if (ret != 0)
+ { xprintf("Unable to read initial MIP solution\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ csa->iocp.use_sol = GLP_ON;
+ }
+#endif
+ /*--------------------------------------------------------------*/
+ /* scale the problem data, if required */
+ if (csa->scale)
+ { if (csa->solution == SOL_BASIC && !csa->smcp.presolve ||
+ csa->solution == SOL_INTERIOR ||
+ csa->solution == SOL_INTEGER && !csa->iocp.presolve)
+ glp_scale_prob(csa->prob, GLP_SF_AUTO);
+ }
+ /*--------------------------------------------------------------*/
+ /* construct starting LP basis */
+ if (csa->solution == SOL_BASIC && !csa->smcp.presolve ||
+ csa->solution == SOL_INTEGER && !csa->iocp.presolve)
+ { if (csa->crash == USE_STD_BASIS)
+ glp_std_basis(csa->prob);
+ else if (csa->crash == USE_ADV_BASIS)
+ glp_adv_basis(csa->prob, 0);
+ else if (csa->crash == USE_CPX_BASIS)
+ glp_cpx_basis(csa->prob);
+ else if (csa->crash == USE_INI_BASIS)
+ { ret = glp_read_sol(csa->prob, csa->ini_file);
+ if (ret != 0)
+ { xprintf("Unable to read initial basis\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ }
+ else
+ xassert(csa != csa);
+ }
+ /*--------------------------------------------------------------*/
+ /* solve the problem */
+ start = glp_time();
+ if (csa->solution == SOL_BASIC)
+ { if (!csa->exact)
+ { glp_set_bfcp(csa->prob, &csa->bfcp);
+
+ glp_simplex2(csa->prob, &csa->smcp, hellothere);
+ if (csa->xcheck)
+ { if (csa->smcp.presolve &&
+ glp_get_status(csa->prob) != GLP_OPT)
+ xprintf("If you need to check final basis for non-opt"
+ "imal solution, use --nopresol\n");
+ else
+ glp_exact(csa->prob, &csa->smcp);
+ }
+ if (csa->out_sol != NULL || csa->out_res != NULL)
+ { if (csa->smcp.presolve &&
+ glp_get_status(csa->prob) != GLP_OPT)
+ xprintf("If you need actual output for non-optimal solut"
+ "ion, use --nopresol\n");
+ }
+ }
+ else
+ glp_exact(csa->prob, &csa->smcp);
+ }
+ else if (csa->solution == SOL_INTERIOR)
+ glp_interior(csa->prob, &csa->iptcp);
+#if 1 /* 15/VIII-2011 */
+ else if (csa->solution == SOL_INTEGER && csa->minisat)
+ { if (glp_check_cnfsat(csa->prob) == 0)
+ glp_minisat1(csa->prob);
+ else
+ glp_intfeas1(csa->prob, csa->use_bnd, csa->obj_bnd);
+ }
+#endif
+ else if (csa->solution == SOL_INTEGER)
+ { glp_set_bfcp(csa->prob, &csa->bfcp);
+ if (!csa->iocp.presolve)
+ glp_simplex2(csa->prob, &csa->smcp, hellothere);
+#if 0
+ csa->iocp.msg_lev = GLP_MSG_DBG;
+ csa->iocp.pp_tech = GLP_PP_NONE;
+#endif
+#ifdef GLP_CB_FUNC /* 05/IV-2016 */
+ { extern void GLP_CB_FUNC(glp_tree *, void *);
+ csa->iocp.cb_func = GLP_CB_FUNC;
+ csa->iocp.cb_info = NULL;
+ }
+#endif
+ glp_intopt(csa->prob, &csa->iocp);
+ }
+ else
+ xassert(csa != csa);
+ /*--------------------------------------------------------------*/
+ /* display statistics */
+ xprintf("Time used: %.1f secs\n", glp_difftime(glp_time(),
+ start));
+#if 0 /* 16/II-2012 */
+ { glp_long tpeak;
+ char buf[50];
+ glp_mem_usage(NULL, NULL, NULL, &tpeak);
+ xprintf("Memory used: %.1f Mb (%s bytes)\n",
+ xltod(tpeak) / 1048576.0, xltoa(tpeak, buf));
+ }
+#else
+ { size_t tpeak;
+ glp_mem_usage(NULL, NULL, NULL, &tpeak);
+ xprintf("Memory used: %.1f Mb (%.0f bytes)\n",
+ (double)tpeak / 1048576.0, (double)tpeak);
+ }
+#endif
+ /*--------------------------------------------------------------*/
+skip: /* postsolve the model, if necessary */
+ if (csa->tran != NULL)
+ { if (csa->solution == SOL_BASIC)
+ { if (!(glp_get_status(csa->prob) == GLP_OPT ||
+ glp_get_status(csa->prob) == GLP_FEAS))
+ ret = -1;
+ else
+ ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_SOL);
+ }
+ else if (csa->solution == SOL_INTERIOR)
+ { if (!(glp_ipt_status(csa->prob) == GLP_OPT ||
+ glp_ipt_status(csa->prob) == GLP_FEAS))
+ ret = -1;
+ else
+ ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_IPT);
+ }
+ else if (csa->solution == SOL_INTEGER)
+ { if (!(glp_mip_status(csa->prob) == GLP_OPT ||
+ glp_mip_status(csa->prob) == GLP_FEAS))
+ ret = -1;
+ else
+ ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_MIP);
+ }
+ else
+ xassert(csa != csa);
+ if (ret > 0)
+ { xprintf("Model postsolving error\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ }
+ /*--------------------------------------------------------------*/
+ /* write problem solution in printable format, if required */
+ if (csa->out_sol != NULL)
+ { if (csa->solution == SOL_BASIC)
+ ret = glp_print_sol(csa->prob, csa->out_sol);
+ else if (csa->solution == SOL_INTERIOR)
+ ret = glp_print_ipt(csa->prob, csa->out_sol);
+ else if (csa->solution == SOL_INTEGER)
+ ret = glp_print_mip(csa->prob, csa->out_sol);
+ else
+ xassert(csa != csa);
+ if (ret != 0)
+ { xprintf("Unable to write problem solution\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ }
+ /* write problem solution in printable format, if required */
+ if (csa->out_res != NULL)
+ { if (csa->solution == SOL_BASIC)
+ ret = glp_write_sol(csa->prob, csa->out_res);
+ else if (csa->solution == SOL_INTERIOR)
+ ret = glp_write_ipt(csa->prob, csa->out_res);
+ else if (csa->solution == SOL_INTEGER)
+ ret = glp_write_mip(csa->prob, csa->out_res);
+ else
+ xassert(csa != csa);
+ if (ret != 0)
+ { xprintf("Unable to write problem solution\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ }
+ /* write sensitivity analysis report, if required */
+ if (csa->out_ranges != NULL)
+ { if (csa->solution == SOL_BASIC)
+ { if (glp_get_status(csa->prob) == GLP_OPT)
+ { if (glp_bf_exists(csa->prob))
+ranges: { ret = glp_print_ranges(csa->prob, 0, NULL, 0,
+ csa->out_ranges);
+ if (ret != 0)
+ { xprintf("Unable to write sensitivity analysis repo"
+ "rt\n");
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+ }
+ else
+ { ret = glp_factorize(csa->prob);
+ if (ret == 0) goto ranges;
+ xprintf("Cannot produce sensitivity analysis report d"
+ "ue to error in basis factorization (glp_factorize"
+ " returned %d); try --nopresol\n", ret);
+ }
+ }
+ else
+ xprintf("Cannot produce sensitivity analysis report for "
+ "non-optimal basic solution\n");
+ }
+ else
+ xprintf("Cannot produce sensitivity analysis report for int"
+ "erior-point or MIP solution\n");
+ }
+ /*--------------------------------------------------------------*/
+ /* all seems to be ok */
+ ret = EXIT_SUCCESS;
+ /*--------------------------------------------------------------*/
+done: /* delete the LP/MIP problem object */
+ if (csa->prob != NULL)
+ glp_delete_prob(csa->prob);
+ /* free the translator workspace, if necessary */
+ if (csa->tran != NULL)
+ glp_mpl_free_wksp(csa->tran);
+ /* delete the network problem object, if necessary */
+ if (csa->graph != NULL)
+ glp_delete_graph(csa->graph);
+#if 0 /* 23/XI-2015 */
+ xassert(gmp_pool_count() == 0);
+ gmp_free_mem();
+#endif
+ /* close log file, if necessary */
+ if (csa->log_file != NULL) glp_close_tee();
+ /* check that no memory blocks are still allocated */
+#if 0 /* 16/II-2012 */
+ { int count;
+ glp_long total;
+ glp_mem_usage(&count, NULL, &total, NULL);
+ if (count != 0)
+ xerror("Error: %d memory block(s) were lost\n", count);
+ xassert(count == 0);
+ xassert(total.lo == 0 && total.hi == 0);
+ }
+#else
+ { int count;
+ size_t total;
+ glp_mem_usage(&count, NULL, &total, NULL);
+ if (count != 0)
+ xerror("Error: %d memory block(s) were lost\n", count);
+ xassert(total == 0);
+ }
+#endif
+ /* free the GLPK environment */
+ glp_free_env();
+ /* return to the control program */
+ return ret;
+}
+
diff --git a/simplex-glpk/src/kernel.cpp b/simplex-glpk/src/kernel.cpp
new file mode 100644
index 0000000..27e743a
--- /dev/null
+++ b/simplex-glpk/src/kernel.cpp
@@ -0,0 +1,263 @@
+#include <sycl/ext/intel/fpga_extensions.hpp>
+#include <chrono>
+#include "kernel.hpp"
+
+/*
+template<typename T>
+SYCL_EXTERNAL bool checkOptimality(device_ptr<T> C, int size) {
+ bool isOptimal = false;
+ int positveValueCount = 0;
+ //check if the coefficients of the objective function are negative
+ for(int i=0; i<size;i++){
+ float value = C[i];
+ if(value >= 0){
+ positveValueCount++;
+ }
+ }
+ //if all the constraints are positive now,the table is optimal
+ if(positveValueCount == size){
+ isOptimal = true;
+ }
+ return isOptimal;
+}
+
+
+template<typename T>
+SYCL_EXTERNAL int findPivotColumn(device_ptr<T> C, int size) {
+ int location = 0;
+ float minimum = C[0];
+ for(int i=1; i<size; ++i) {
+ if(C[i]<minimum) {
+ minimum = C[i];
+ location = i;
+ }
+ }
+ return location;
+}
+
+
+//find the row with the pivot value.The least value item's row in the B array
+template<typename T>
+SYCL_EXTERNAL int findPivotRow(device_ptr<T> A, device_ptr<T> B, device_ptr<T> C, int pivotColumn, int rows, int cols, bool *isUnbounded) {
+ int negativeValueCount = 0;
+ for (int i = 0; i < rows; i++) {
+ // 2d to 1d array index mapping
+ int pivotColumnIndex = (i*cols)+pivotColumn;
+ if (A[pivotColumnIndex] <= 0) {
+ negativeValueCount += 1;
+ }
+ }
+ int location = 0;
+ //checking the unbound condition if all the values are negative ones
+ if (negativeValueCount == rows) {
+ *isUnbounded = true;
+ } else {
+ float minimum = 99999999.0;
+
+ for (int i = 0; i < rows; ++i) {
+ // 2d to 1d array index mapping
+ int pivotColumnIndex = (i*cols)+pivotColumn;
+ float tmpACols = A[pivotColumnIndex];
+ if (tmpACols > 0) {
+ float result = B[i] / tmpACols;
+ if (result > 0 && result < minimum) {
+ minimum = result;
+ location = i;
+ }
+ }
+ }
+ }
+ return location;
+}
+
+template<typename T>
+SYCL_EXTERNAL void doPivotting(device_ptr<T> A, device_ptr<T> B, device_ptr<T> C, int pivotRow, int pivotColumn, int rows, int cols) {
+ int columnIndex = (pivotRow*cols)+pivotColumn;
+ float pivetValue = A[columnIndex];
+
+ float pivotRowVals[6]; //the column with the pivot
+ float pivotColVals[3]; //the row with the pivot
+ float rowNew[6]; //the row after processing the pivot value
+
+ float maximum = 0;
+ maximum = maximum-(C[pivotColumn]*(B[pivotRow]/pivetValue)); //set the maximum step by step
+
+
+ //get the row that has the pivot value
+ for (int i = 0; i < cols; ++i) {
+ int pivotRowIndex = (pivotRow*cols)+i;
+ pivotRowVals[i] = A[pivotRowIndex];
+ }
+ //get the column that has the pivot value
+ for (int j = 0; j < rows; ++j) {
+ int pivotColIndex = (j*cols)+pivotColumn;
+ pivotColVals[j] = A[pivotColIndex];
+ }
+
+ //set the row values that has the pivot value divided by the pivot value and put into new row
+ for (int k = 0; k < cols; ++k) {
+ rowNew[k] = pivotRowVals[k]/pivetValue;
+ }
+
+ B[pivotRow] = B[pivotRow]/pivetValue;
+
+ //process the other coefficients in the A array by subtracting
+ for (int m=0; m < rows; ++m) {
+ //ignore the pivot row as we already calculated that
+ if (m != pivotRow) {
+ for (int p = 0; p<cols; ++p) {
+ float multiplyValue = pivotColVals[m];
+ int indexA_M_P = (m*cols)+p;
+ A[indexA_M_P] = A[indexA_M_P] - (multiplyValue * rowNew[p]);
+ //C[p] = C[p] - (multiplyValue*C[pivotRow]);
+ //B[i] = B[i] - (multiplyValue*B[pivotRow]);
+ }
+
+ }
+ }
+
+ //process the values of the B array
+ for (int i = 0; i<rows; ++i) { // rows = B.size()
+ if (i != pivotRow) {
+ float multiplyValue = pivotColVals[i];
+ B[i] = B[i]-(multiplyValue*B[pivotRow]);
+
+ }
+ }
+ //the least coefficient of the constraints of the objective function
+ float multiplyValue = C[pivotColumn];
+ //process the C array
+ for (int i = 0; i < C.size(); i++) {
+ C[i] = C[i]-(multiplyValue * rowNew[i]);
+
+ }
+
+ //replacing the pivot row in the new calculated A array
+ for (int i = 0; i<cols; ++i) {
+ int indexA_pivotRow_i = (pivotRow*cols)+i;
+ A[indexA_pivotRow_i] = rowNew[i];
+ }
+}
+
+// Forward declare the kernel names in the global scope. This FPGA best practice
+// reduces compiler name mangling in the optimization reports.
+class SimplexCalc;
+
+double RunKernel(queue &q, std::vector<T> &inAHost, std::vector<T> &inBHost,
+ std::vector<T> &inCHost, std::vector<int>& resultFlags) {
+
+ int rowSizeA = inBHost.size();
+ int colSizeA = inCHost.size();
+
+ T *inADevice = malloc_device<T> (inAHost.size(), q);
+ T *inBDevice = malloc_device<T> (inBHost.size(), q);
+ T *inCDevice = malloc_device<T> (inCHost.size(), q);
+ int *inResultFlagsDevice = malloc_device<int> (resultFlags.size(), q);
+
+ if (inADevice == nullptr) {
+ std::cerr << "ERROR: failed to allocate space for 'inADevice'\n";
+ std::terminate();
+ }
+ if (inBDevice == nullptr) {
+ std::cerr << "ERROR: failed to allocate space for 'inBDevice'\n";
+ std::terminate();
+ }
+ if (inCDevice == nullptr) {
+ std::cerr << "ERROR: failed to allocate space for 'inCDevice'\n";
+ std::terminate();
+ }
+
+ auto start = std::chrono::high_resolution_clock::now();
+
+ q.memcpy(inADevice, inAHost.data(), inAHost.size()*sizeof(T)).wait();
+ q.memcpy(inBDevice, inBHost.data(), inBHost.size() * sizeof(T)).wait();
+ q.memcpy(inCDevice, inCHost.data(), inCHost.size() * sizeof(T)).wait();
+ q.memcpy(inResultFlagsDevice, resultFlags.data(), resultFlags.size()*sizeof(int)).wait();
+
+ q.submit([&](handler &h) {
+ h.single_task < SimplexCalc > ([=]()[[intel::kernel_args_restrict]] {
+ device_ptr<T> inA(inADevice);
+ device_ptr<T> inB(inBDevice);
+ device_ptr<T> inC(inCDevice);
+ device_ptr<int> inResultFlags(inResultFlagsDevice);
+
+ bool tempIsOptimizal = checkOptimality(inC, colSizeA);
+ if (tempIsOptimizal) {
+ inResultFlags[0] = 1;
+ return;
+ } else {
+ inResultFlags[0] = 0;
+ }
+
+ int pivotColumn = findPivotColumn(inC, colSizeA);
+ inResultFlags[1] = pivotColumn;
+
+ inA[0] = 43.0; //test only
+ bool isUnbounded = true;
+ int pivotRow = findPivotRow(inA, inB, inC, pivotColumn, rowSizeA, colSizeA, &isUnbounded);
+ inResultFlags[2] = pivotRow;
+ });
+ }).wait();
+
+ q.memcpy(inAHost.data(), inADevice, inAHost.size()*sizeof(T)).wait();
+ q.memcpy(inBHost.data(), inBDevice, inBHost.size()*sizeof(T)).wait();
+ q.memcpy(inCHost.data(), inCDevice, inCHost.size()*sizeof(T)).wait();
+ q.memcpy(resultFlags.data(), inResultFlagsDevice, resultFlags.size()*sizeof(int)).wait();
+
+ auto end = std::chrono::high_resolution_clock::now();
+ std::chrono::duration<double, std::milli> diff = end - start;
+
+ sycl::free(inADevice, q);
+ sycl::free(inBDevice, q);
+ sycl::free(inCDevice, q);
+ sycl::free(inResultFlagsDevice, q);
+
+ return diff.count();
+}
+*/
+
+
+// Forward declare the kernel names in the global scope. This FPGA best practice
+// reduces compiler name mangling in the optimization reports.
+class SimplexCalc;
+
+double RunKernel(queue &q, std::vector<T> &inAHost, std::vector<T> &inBHost,
+ std::vector<T> &inCHost, std::vector<int>& resultFlags) {
+
+ constexpr int value = 100000;
+ size_t itemSize = 1000;
+ range numItems{itemSize};
+
+
+ int *parallel = malloc_shared<int>(itemSize, q);
+ if (parallel == nullptr) {
+ sycl::free(parallel, q);
+ std::cout << "Shared memory allocation failure.\n";
+ return -1;
+ }
+
+ auto start = std::chrono::high_resolution_clock::now();
+
+ // Use parallel_for to populate consecutive numbers starting with a specified
+ // value in parallel on device. This executes the kernel.
+ // 1st parameter is the number of work items to use.
+ // 2nd parameter is the kernel, a lambda that specifies what to do per
+ // work item. The parameter of the lambda is the work item id.
+ // SYCL supports unnamed lambda kernel by default.
+ auto e = q.parallel_for(numItems, [=](auto i) {
+ parallel[i] = value + i;
+ });
+
+ // q.parallel_for() is an asynchronous call. SYCL runtime enqueues and runs
+ // the kernel asynchronously. Wait for the asynchronous call to complete.
+ e.wait();
+
+
+ auto end = std::chrono::high_resolution_clock::now();
+ std::chrono::duration<double, std::milli> diff = end - start;
+
+ sycl::free(parallel, q);
+
+
+ return diff.count();
+}
diff --git a/simplex-glpk/src/kernel.hpp b/simplex-glpk/src/kernel.hpp
new file mode 100755
index 0000000..77b8ca7
--- /dev/null
+++ b/simplex-glpk/src/kernel.hpp
@@ -0,0 +1,13 @@
+//==============================================================
+// Copyright Intel Corporation
+//
+// SPDX-License-Identifier: MIT
+// =============================================================
+#include <CL/sycl.hpp>
+
+using namespace sycl;
+
+typedef float T;
+
+double RunKernel(queue &q, std::vector<T> &inAHost, std::vector<T> &inBHost,
+ std::vector<T> &inCHost, std::vector<int>& resultFlags);
diff --git a/simplex-glpk/src/note b/simplex-glpk/src/note
new file mode 100644
index 0000000..ea11799
--- /dev/null
+++ b/simplex-glpk/src/note
@@ -0,0 +1,2 @@
+gcc glpsol.c -lglpk -lm -o glpsol
+