From 07aa334d8d445c3e44a1922791c2f16e3aea84e1 Mon Sep 17 00:00:00 2001 From: Quentin Bourgerie Date: Wed, 7 Dec 2022 09:58:52 +0100 Subject: [PATCH] chore(benchmarks): Refactor the benchmark tools --- .github/workflows/benchmark.yml | 33 ++-- compiler/Makefile | 51 +++-- .../concretelang/Support/CompilerEngine.h | 22 +++ .../end_to_end_benchmark.cpp | 186 ++++++++++-------- .../end_to_end_fixture/EndToEndFixture.h | 5 + .../tests/end_to_end_tests/end_to_end_test.cc | 71 +------ .../tests/end_to_end_tests/end_to_end_test.h | 102 +++++++++- 7 files changed, 293 insertions(+), 177 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index cd30f29b5..0479a6083 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -112,17 +112,20 @@ jobs: run: | echo "HOME=/home/ubuntu" >> "${GITHUB_ENV}" - - name: Export CUDA variables + - name: Export specific variables (CPU) + if: ${{ inputs.backend == 'cpu' }} + run: | + echo "CUDA_SUPPORT=OFF" >> "${GITHUB_ENV}" + echo "BENCHMARK_TARGET=run-cpu-benchmarks" >> "${GITHUB_ENV}" + + - name: Export specific variables (GPU) if: ${{ inputs.backend == 'gpu' }} run: | + echo "CUDA_SUPPORT=ON" >> "${GITHUB_ENV}" + echo "BENCHMARK_TARGET=run-gpu-benchmarks" >> "${GITHUB_ENV}" echo "CUDA_PATH=$CUDA_PATH" >> "${GITHUB_ENV}" echo "$CUDA_PATH/bin" >> "${GITHUB_PATH}" echo "LD_LIBRARY_PATH=$CUDA_PATH/lib:$LD_LIBRARY_PATH" >> "${GITHUB_ENV}" - - # Specify the correct host compilers - - name: Export gcc and g++ variables - if: ${{ inputs.backend == 'gpu' }} - run: | echo "CC=/usr/bin/gcc-${{ env.GCC_VERSION }}" >> "${GITHUB_ENV}" echo "CXX=/usr/bin/g++-${{ env.GCC_VERSION }}" >> "${GITHUB_ENV}" echo "CUDAHOSTCXX=/usr/bin/g++-${{ env.GCC_VERSION }}" >> "${GITHUB_ENV}" @@ -134,19 +137,11 @@ jobs: toolchain: stable override: true - - name: Build compiler and end-to-end benchmarks (CPU) - if: ${{ inputs.backend == 'cpu' }} + - name: Build compiler benchmarks run: | set -e cd compiler - make BINDINGS_PYTHON_ENABLED=OFF build-benchmarks generate-cpu-benchmarks - - - name: Build compiler and end-to-end benchmarks (GPU) - if: ${{ inputs.backend == 'gpu' }} - run: | - set -e - cd compiler - make BINDINGS_PYTHON_ENABLED=OFF CUDA_SUPPORT=ON build-benchmarks generate-gpu-benchmarks + make BINDINGS_PYTHON_ENABLED=OFF CUDA_SUPPORT=${{ env.CUDA_SUPPORT }} build-benchmarks - name: Download KeySetCache if: ${{ !contains(github.head_ref, 'newkeysetcache') }} @@ -155,15 +150,11 @@ jobs: cd compiler GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} make keysetcache_ci_populated - - name: Mark KeySetCache - run: | - touch keysetcache.timestamp - - name: Run end-to-end benchmarks run: | set -e cd compiler - make BINDINGS_PYTHON_ENABLED=OFF run-benchmarks + make ${{ env.BENCHMARK_TARGET }} - name: Upload raw results artifact uses: actions/upload-artifact@v3 diff --git a/compiler/Makefile b/compiler/Makefile index c9d91c697..9cd6a7ce1 100644 --- a/compiler/Makefile +++ b/compiler/Makefile @@ -265,7 +265,8 @@ run-end-to-end-tests: build-end-to-end-tests generate-cpu-tests $(BUILD_DIR)/tools/concretelang/tests/end_to_end_tests/end_to_end_jit_encrypted_tensor $(BUILD_DIR)/tools/concretelang/tests/end_to_end_tests/end_to_end_jit_fhelinalg $(BUILD_DIR)/tools/concretelang/tests/end_to_end_tests/end_to_end_jit_lambda - $(BUILD_DIR)/tools/concretelang/tests/end_to_end_tests/end_to_end_test --loop-parallelize --jit $(FIXTURE_CPU_DIR)/*.yaml + $(BUILD_DIR)/tools/concretelang/tests/end_to_end_tests/end_to_end_test \ + --backend=cpu --jit $(FIXTURE_CPU_DIR)/*.yaml ### end-to-end-tests GPU @@ -284,10 +285,9 @@ generate-gpu-tests: $(FIXTURE_GPU_DIR) $(FIXTURE_GPU_DIR)/end_to_end_apply_looku run-end-to-end-tests-gpu: build-end-to-end-test generate-gpu-tests $(BUILD_DIR)/tools/concretelang/tests/end_to_end_tests/end_to_end_test \ - --emit-gpu-ops --batch-concrete-ops --library /tmp/concrete_compiler/gpu_tests/ \ + --backend=gpu --library /tmp/concrete_compiler/gpu_tests/ \ $(FIXTURE_GPU_DIR)/*.yaml - ## end-to-end-dataflow-tests build-end-to-end-dataflow-tests: build-initialized @@ -301,30 +301,51 @@ run-end-to-end-dataflow-tests: build-end-to-end-dataflow-tests # benchmark +build-benchmarks: build-initialized + cmake --build $(BUILD_DIR) --target end_to_end_benchmark + +## benchmark CPU + BENCHMARK_CPU_DIR=tests/end_to_end_fixture/benchmarks_cpu +$(BENCHMARK_CPU_DIR): + mkdir -p $@ + $(BENCHMARK_CPU_DIR)/end_to_end_linalg_apply_lookup_table.yaml: tests/end_to_end_fixture/end_to_end_linalg_apply_lookup_table_gen.py $(Python3_EXECUTABLE) $< --n-ct 64 128 1024 > $@ $(BENCHMARK_CPU_DIR)/%.yaml: tests/end_to_end_fixture/%_gen.py - mkdir -p $(FIXTURE_CPU_DIR) $(Python3_EXECUTABLE) $< > $@ -$(BENCHMARK_CPU_DIR): - mkdir -p $@ - generate-cpu-benchmarks: $(BENCHMARK_CPU_DIR) $(BENCHMARK_CPU_DIR)/end_to_end_linalg_apply_lookup_table.yaml $(BENCHMARK_CPU_DIR)/end_to_end_apply_lookup_table.yaml $(BENCHMARK_CPU_DIR)/end_to_end_leveled.yaml -generate-gpu-benchmarks: - $(Python3_EXECUTABLE) ./tests/end_to_end_fixture/end_to_end_linalg_apply_lookup_table_gen.py \ - --min_bitwidth 1 --max_bitwidth 7 --n_ct 1 128 1024 2048 8192 \ - > tests/end_to_end_fixture/end_to_end_linalg_apply_lookup_table.yaml +run-cpu-benchmarks: build-benchmarks generate-cpu-benchmarks + $(BUILD_DIR)/bin/end_to_end_benchmark \ + --backend=cpu \ + --benchmark_out=benchmarks_results.json --benchmark_out_format=json \ + $(BENCHMARK_CPU_DIR)/*.yaml + +## benchmark GPU + +BENCHMARK_GPU_DIR=tests/end_to_end_fixture/benchmarks_gpu + +$(BENCHMARK_GPU_DIR): + mkdir -p $@ + +$(BENCHMARK_GPU_DIR)/end_to_end_linalg_apply_lookup_table.yaml: tests/end_to_end_fixture/end_to_end_linalg_apply_lookup_table_gen.py + $(Python3_EXECUTABLE) $< \ + --bitwidth 1 2 3 4 5 6 7 --n-ct 1 128 1024 2048 8192 + + +generate-gpu-benchmarks: $(BENCHMARK_GPU_DIR) $(BENCHMARK_GPU_DIR)/end_to_end_linalg_apply_lookup_table.yaml + +run-gpu-benchmarks: build-benchmarks generate-cpu-benchmarks + $(BUILD_DIR)/bin/end_to_end_benchmark \ + --backend=gpu \ + --benchmark_out=benchmarks_results.json --benchmark_out_format=json \ + $(BENCHMARK_CPU_DIR)/*.yaml -build-benchmarks: build-initialized - cmake --build $(BUILD_DIR) --target end_to_end_benchmark -run-benchmarks: build-benchmarks generate-cpu-benchmarks - $(BUILD_DIR)/bin/end_to_end_benchmark --benchmark_out=benchmarks_results.json --benchmark_out_format=json build-mlbench: build-initialized cmake --build $(BUILD_DIR) --target end_to_end_mlbench diff --git a/compiler/include/concretelang/Support/CompilerEngine.h b/compiler/include/concretelang/Support/CompilerEngine.h index 04038b1e6..c8d0eda9a 100644 --- a/compiler/include/concretelang/Support/CompilerEngine.h +++ b/compiler/include/concretelang/Support/CompilerEngine.h @@ -38,6 +38,11 @@ protected: llvm::LLVMContext *llvmContext; }; +enum Backend { + CPU, + GPU, +}; + /// Compilation options allows to configure the compilation pipeline. struct CompilationOptions { llvm::Optional v0FHEConstraints; @@ -75,6 +80,23 @@ struct CompilationOptions { CompilationOptions(std::string funcname) : CompilationOptions() { clientParametersFuncName = funcname; } + + /// @brief Constructor for CompilationOptions with default parameters for a + /// specific backend. + /// @param funcname The name of the function to compile. + /// @param backend The backend to target. + CompilationOptions(std::string funcname, enum Backend backend) + : CompilationOptions(funcname) { + switch (backend) { + case Backend::CPU: + loopParallelize = true; + break; + case Backend::GPU: + batchConcreteOps = true; + emitGPUOps = true; + break; + } + } }; class CompilerEngine { diff --git a/compiler/tests/end_to_end_benchmarks/end_to_end_benchmark.cpp b/compiler/tests/end_to_end_benchmarks/end_to_end_benchmark.cpp index abb6bf896..d4f791c48 100644 --- a/compiler/tests/end_to_end_benchmarks/end_to_end_benchmark.cpp +++ b/compiler/tests/end_to_end_benchmarks/end_to_end_benchmark.cpp @@ -1,7 +1,9 @@ -#include "end_to_end_fixture/EndToEndFixture.h" +#include "../end_to_end_tests/end_to_end_test.h" + +#include + #define BENCHMARK_HAS_CXX11 #include "llvm/Support/Path.h" -#include #include "tests_tools/StackSize.h" #include "tests_tools/keySetCache.h" @@ -100,82 +102,112 @@ static void BM_Evaluate(benchmark::State &state, EndToEndDesc description, } } -static int registerEndToEndTestFromFile(std::string prefix, std::string path, - size_t stackSizeRequirement = 0, - bool only_evaluate = false) { - auto registe = [&](std::string optionsName, - mlir::concretelang::CompilationOptions options) { - llvm::for_each(loadEndToEndDesc(path), [&](EndToEndDesc &description) { - options.clientParametersFuncName = "main"; - mlir::concretelang::JITSupport support; - auto benchName = [&](std::string name) { - std::ostringstream s; - s << prefix << "/" << name << "/" << optionsName << "/" - << description.description; - return s.str(); - }; - benchmark::RegisterBenchmark( - benchName("Evaluate").c_str(), [=](::benchmark::State &st) { - BM_Evaluate(st, description, support, options); - }); - if (!only_evaluate) { - benchmark::RegisterBenchmark( - benchName("Compile").c_str(), [=](::benchmark::State &st) { - BM_Compile(st, description, support, options); - }); - benchmark::RegisterBenchmark( - benchName("KeyGen").c_str(), [=](::benchmark::State &st) { - BM_KeyGen(st, description, support, options); - }); - benchmark::RegisterBenchmark( - benchName("ExportArguments").c_str(), [=](::benchmark::State &st) { - BM_ExportArguments(st, description, support, options); - }); - } - return; - }); - }; - setCurrentStackLimit(stackSizeRequirement); - -#ifndef CONCRETELANG_CUDA_SUPPORT - // Run only parallelized benchmarks to take advantage of hardware with lots of - // CPU cores. - mlir::concretelang::CompilationOptions cpu; - registe("cpu", cpu); - cpu.loopParallelize = true; -#else - mlir::concretelang::CompilationOptions gpu; - gpu.batchConcreteOps = true; - gpu.emitGPUOps = true; - gpu.loopParallelize = true; - registe("gpu", gpu); -#endif - - return 1; +std::string getOptionsName(mlir::concretelang::CompilationOptions options) { + std::ostringstream os; + if (options.loopParallelize) + os << "_loop"; + if (options.dataflowParallelize) + os << "_dataflow"; + if (options.emitGPUOps) + os << "_gpu"; + auto ostr = os.str(); + if (ostr.size() == 0) { + os << "_default"; + } + return os.str().substr(1); } -auto stackSizeRequirement = 0; -auto _ = { - registerEndToEndTestFromFile("FHELinalgLeveled", - "tests/end_to_end_fixture/benchmarks_cpu/" - "end_to_end_leveled.yaml", - stackSizeRequirement, - /* only_evaluate = */ false), - // For lookup table bench we only bench the keygen time on simple lookup - // table bench, to avoid - // bench the same keygen several times as it take times - registerEndToEndTestFromFile("FHELinalg", - "tests/end_to_end_fixture/benchmarks_cpu/" - "end_to_end_apply_lookup_table.yaml", - stackSizeRequirement, - /* only_evaluate = */ false), - // So for the other lookup table benchmarks we only test the evaluataion - // times - registerEndToEndTestFromFile("FHELinalgTLU", - "tests/end_to_end_fixture/benchmarks_cpu/" - "end_to_end_linalg_apply_lookup_table.yaml", - stackSizeRequirement, - /* only_evaluate = */ true), +enum Action { + COMPILE, + KEYGEN, + ENCRYPT, + EVALUATE, }; -BENCHMARK_MAIN(); +void registerEndToEndBenchmark(std::string suiteName, + std::vector descriptions, + mlir::concretelang::CompilationOptions options, + std::vector actions, + size_t stackSizeRequirement = 0) { + auto optionsName = getOptionsName(options); + for (auto description : descriptions) { + options.clientParametersFuncName = "main"; + mlir::concretelang::JITSupport support; + auto benchName = [&](std::string name) { + std::ostringstream s; + s << suiteName << "/" << name << "/" << optionsName << "/" + << description.description; + return s.str(); + }; + for (auto action : actions) { + switch (action) { + case Action::COMPILE: + benchmark::RegisterBenchmark( + benchName("compile").c_str(), [=](::benchmark::State &st) { + BM_Compile(st, description, support, options); + }); + break; + case Action::KEYGEN: + benchmark::RegisterBenchmark( + benchName("keygen").c_str(), [=](::benchmark::State &st) { + BM_KeyGen(st, description, support, options); + }); + break; + case Action::ENCRYPT: + benchmark::RegisterBenchmark( + benchName("encrypt").c_str(), [=](::benchmark::State &st) { + BM_ExportArguments(st, description, support, options); + }); + break; + case Action::EVALUATE: + benchmark::RegisterBenchmark( + benchName("evaluate").c_str(), [=](::benchmark::State &st) { + BM_Evaluate(st, description, support, options); + }); + break; + } + } + } + setCurrentStackLimit(stackSizeRequirement); +} + +int main(int argc, char **argv) { + // Parse google benchmark options + ::benchmark::Initialize(&argc, argv); + + llvm::cl::list clActions( + "b", "bench", + llvm::cl::desc("Specify benchmark cases to run, if no benchmarks speci"), + llvm::cl::values( + clEnumValN(Action::COMPILE, "compile", "Run compile benchmark")), + llvm::cl::values( + clEnumValN(Action::KEYGEN, "keygen", "Run keygen benchmark")), + llvm::cl::values( + clEnumValN(Action::ENCRYPT, "encrypt", "Run encrypt benchmark")), + llvm::cl::values( + clEnumValN(Action::EVALUATE, "evaluate", "Run evaluate benchmark"))); + + // parse end to end test compiler options + auto options = parseEndToEndCommandLine(argc, argv); + + auto compilationOptions = std::get<0>(options); + auto libpath = std::get<1>(options); + auto descriptionFiles = std::get<2>(options); + + std::vector actions = clActions; + if (actions.empty()) { + actions = {Action::COMPILE, Action::KEYGEN, Action::ENCRYPT, + Action::EVALUATE}; + } + + auto stackSizeRequirement = 0; + for (auto descFile : descriptionFiles) { + auto suiteName = llvm::sys::path::stem(descFile.path).str(); + registerEndToEndBenchmark(suiteName, descFile.descriptions, + compilationOptions, actions, + stackSizeRequirement); + } + ::benchmark::RunSpecifiedBenchmarks(); + ::benchmark::Shutdown(); + return 0; +} diff --git a/compiler/tests/end_to_end_fixture/EndToEndFixture.h b/compiler/tests/end_to_end_fixture/EndToEndFixture.h index 0a3dad856..362d39667 100644 --- a/compiler/tests/end_to_end_fixture/EndToEndFixture.h +++ b/compiler/tests/end_to_end_fixture/EndToEndFixture.h @@ -56,6 +56,11 @@ struct EndToEndDesc { std::vector test_error_rates; }; +struct EndToEndDescFile { + std::string path; + std::vector descriptions; +}; + llvm::Error checkResult(ValueDescription &desc, mlir::concretelang::LambdaArgument &res); diff --git a/compiler/tests/end_to_end_tests/end_to_end_test.cc b/compiler/tests/end_to_end_tests/end_to_end_test.cc index a3f68775e..6885df7fa 100644 --- a/compiler/tests/end_to_end_tests/end_to_end_test.cc +++ b/compiler/tests/end_to_end_tests/end_to_end_test.cc @@ -226,78 +226,23 @@ int main(int argc, char **argv) { // Parse google test options, update argc and argv by removing gtest options ::testing::InitGoogleTest(&argc, argv); - // Main command line options - llvm::cl::ResetCommandLineParser(); + // parse end to end test compiler options - llvm::cl::list descriptionFiles( - llvm::cl::Positional, llvm::cl::desc(""), - llvm::cl::OneOrMore); + auto options = parseEndToEndCommandLine(argc, argv); - // Compilation options - llvm::cl::opt loopParallelize( - "loop-parallelize", - llvm::cl::desc( - "Set the loopParallelize compilation options to run the tests"), - llvm::cl::init(false)); - llvm::cl::opt dataflowParallelize( - "dataflow-parallelize", - llvm::cl::desc( - "Set the loopParallelize compilation options to run the tests"), - llvm::cl::init(false)); - llvm::cl::opt emitGPUOps( - "emit-gpu-ops", - llvm::cl::desc("Set the emitGPUOps compilation options to run the tests"), - llvm::cl::init(false)); - llvm::cl::opt batchConcreteOps( - "batch-concrete-ops", - llvm::cl::desc( - "Set the batchConcreteOps compilation options to run the tests"), - llvm::cl::init(false)); - - // Optimizer options - llvm::cl::opt optimizerDisplay( - "optimizer-display", - llvm::cl::desc("Set the optimizerConfig.display compilation options to " - "run the tests"), - llvm::cl::init(false)); - - // JIT or Library support - llvm::cl::opt jit( - "jit", - llvm::cl::desc("Use JIT support to run the tests (default, overwritten " - "if --library is set"), - llvm::cl::init(true)); - llvm::cl::opt library( - "library", - llvm::cl::desc("Use library support to run the tests and specify the " - "prefix for compilation artifacts"), - llvm::cl::init("")); - - llvm::cl::ParseCommandLineOptions(argc, argv); - - // Build compilation options - mlir::concretelang::CompilationOptions compilationOptions("main"); - compilationOptions.loopParallelize = loopParallelize.getValue(); - compilationOptions.dataflowParallelize = dataflowParallelize.getValue(); - compilationOptions.emitGPUOps = emitGPUOps.getValue(); - compilationOptions.batchConcreteOps = - compilationOptions.optimizerConfig.display = optimizerDisplay.getValue(); + auto compilationOptions = std::get<0>(options); + auto libpath = std::get<1>(options); + auto descriptionFiles = std::get<2>(options); for (auto descFile : descriptionFiles) { - auto desc = loadEndToEndDesc(descFile); - auto suiteName = path::stem(descFile).str(); - auto libpath = library.getValue(); - if (libpath.empty() && !jit.getValue()) { - llvm::errs() - << "You must specify the library path or use jit to run the test"; - return 1; - } + auto suiteName = path::stem(descFile.path).str(); if (libpath.empty()) { suiteName = suiteName + ".jit"; } else { suiteName = suiteName + ".library"; } - registerEndToEndSuite(suiteName, libpath, desc, compilationOptions); + registerEndToEndSuite(suiteName, libpath, descFile.descriptions, + compilationOptions); } return RUN_ALL_TESTS(); } diff --git a/compiler/tests/end_to_end_tests/end_to_end_test.h b/compiler/tests/end_to_end_tests/end_to_end_test.h index 29bd5bfff..04d7e3935 100644 --- a/compiler/tests/end_to_end_tests/end_to_end_test.h +++ b/compiler/tests/end_to_end_tests/end_to_end_test.h @@ -1,7 +1,10 @@ #ifndef END_TO_END_TEST_H #define END_TO_END_TEST_H -#include +#include "concretelang/Support/CompilerEngine.h" +#include "llvm/Support/CommandLine.h" + +#include "end_to_end_fixture/EndToEndFixture.h" // Shorthands to create integer literals of a specific type static inline uint8_t operator"" _u8(unsigned long long int v) { return v; } @@ -13,4 +16,101 @@ static inline uint64_t operator"" _u64(unsigned long long int v) { return v; } // array #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) +/// @brief Parse the command line and return a tuple contains the compilation +/// options, the library path if the --library options has been specified and +/// the parsed description files +std::tuple> +parseEndToEndCommandLine(int argc, char **argv) { + + // TODO - Well reset other llvm command line options registered but assert on + // --help + // llvm::cl::ResetCommandLineParser(); + + llvm::cl::list descriptionFiles( + llvm::cl::Positional, llvm::cl::desc(""), + llvm::cl::OneOrMore); + + // Compilation options + llvm::cl::opt backend( + "backend", + llvm::cl::desc("Specify benchmark cases to run, if no benchmarks speci"), + llvm::cl::values(clEnumValN(mlir::concretelang::Backend::CPU, "cpu", + "Target a CPU backend")), + llvm::cl::values(clEnumValN(mlir::concretelang::Backend::GPU, "gpu", + "Target a GPU backend")), + llvm::cl::init(mlir::concretelang::Backend::CPU)); + + llvm::cl::opt> loopParallelize( + "loop-parallelize", + llvm::cl::desc( + "Set the loopParallelize compilation options to run the tests"), + llvm::cl::init(llvm::None)); + llvm::cl::opt> dataflowParallelize( + "dataflow-parallelize", + llvm::cl::desc( + "Set the loopParallelize compilation options to run the tests"), + llvm::cl::init(llvm::None)); + llvm::cl::opt> emitGPUOps( + "emit-gpu-ops", + llvm::cl::desc("Set the emitGPUOps compilation options to run the tests"), + llvm::cl::init(llvm::None)); + llvm::cl::opt> batchConcreteOps( + "batch-concrete-ops", + llvm::cl::desc( + "Set the batchConcreteOps compilation options to run the tests"), + llvm::cl::init(llvm::None)); + + // Optimizer options + llvm::cl::opt optimizerDisplay( + "optimizer-display", + llvm::cl::desc("Set the optimizerConfig.display compilation options to " + "run the tests"), + llvm::cl::init(false)); + + // JIT or Library support + llvm::cl::opt jit( + "jit", + llvm::cl::desc("Use JIT support to run the tests (default, overwritten " + "if --library is set"), + llvm::cl::init(true)); + llvm::cl::opt library( + "library", + llvm::cl::desc("Use library support to run the tests and specify the " + "prefix for compilation artifacts"), + llvm::cl::init("")); + + llvm::cl::ParseCommandLineOptions(argc, argv); + + // Build compilation options + mlir::concretelang::CompilationOptions compilationOptions("main", + backend.getValue()); + if (loopParallelize.hasValue()) + compilationOptions.loopParallelize = loopParallelize.getValue().getValue(); + if (dataflowParallelize.hasValue()) + compilationOptions.dataflowParallelize = + dataflowParallelize.getValue().getValue(); + if (emitGPUOps.hasValue()) + compilationOptions.emitGPUOps = emitGPUOps.getValue().getValue(); + if (batchConcreteOps.hasValue()) + compilationOptions.batchConcreteOps = + batchConcreteOps.getValue().getValue(); + compilationOptions.optimizerConfig.display = optimizerDisplay.getValue(); + + std::vector parsedDescriptionFiles; + for (auto descFile : descriptionFiles) { + EndToEndDescFile f; + f.path = descFile; + f.descriptions = loadEndToEndDesc(descFile); + parsedDescriptionFiles.push_back(f); + } + auto libpath = library.getValue(); + if (libpath.empty() && !jit.getValue()) { + llvm::errs() + << "You must specify the library path or use jit to run the test"; + exit(1); + } + return std::make_tuple(compilationOptions, libpath, parsedDescriptionFiles); +} + #endif