diff --git a/CMakeLists.txt b/CMakeLists.txt index dd451658a..d4033ca0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG=1") -set(CMAKE_CXX_FLAGS_RELEASE "{CMAKE_CXX_FLAGS_RELEASE} -DRELEASE=1") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DRELEASE=1") set(CMAKE_VERBOSE_MAKEFILE on) diff --git a/Makefile b/Makefile index 3655679f0..de52676e7 100755 --- a/Makefile +++ b/Makefile @@ -40,10 +40,12 @@ clean_cmake: ####### Visual studio build shortcut commands ####### +MK_BUILD_TYPE ?= "Release" + mk_cmake: cmake \ -Bbuild \ - -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_BUILD_TYPE=$(MK_BUILD_TYPE) \ -DKOMPUTE_OPT_BUILD_DOCS=0 \ -DCMAKE_TOOLCHAIN_FILE=$(VCPKG_UNIX_PATH) \ -DCMAKE_EXPORT_COMPILE_COMMANDS=1 \ @@ -70,6 +72,8 @@ mk_run_tests: mk_build_tests ####### Visual studio build shortcut commands ####### +VS_BUILD_TYPE ?= "Debug" + vs_cmake: $(CMAKE_BIN) \ -Bbuild \ @@ -79,22 +83,22 @@ vs_cmake: -G "Visual Studio 16 2019" vs_build_all: - $(MSBUILD_BIN) build/kompute.sln + $(MSBUILD_BIN) build/kompute.sln -p:Configuration$(VS_BUILD_TYPE) vs_build_docs: - $(MSBUILD_BIN) build/docs/gendocsall.vcxproj + $(MSBUILD_BIN) build/docs/gendocsall.vcxproj -p:Configuration=$(VS_BUILD_TYPE) vs_build_kompute: - $(MSBUILD_BIN) build/src/kompute.vcxproj + $(MSBUILD_BIN) build/src/kompute.vcxproj -p:Configuration=$(VS_BUILD_TYPE) vs_build_tests: - $(MSBUILD_BIN) build/test/test_kompute.vcxproj + $(MSBUILD_BIN) build/test/test_kompute.vcxproj -p:Configuration=$(VS_BUILD_TYPE) vs_run_docs: vs_build_docs (cd build/docs/sphinx && python2.7 -m SimpleHTTPServer) vs_run_tests: vs_build_tests - ./build/test/Debug/test_kompute.exe $(FILTER_TESTS) + ./build/test/$(VS_BUILD_TYPE)/test_kompute.exe $(FILTER_TESTS) ####### Create release ###### diff --git a/README.md b/README.md index 47ce93604..76660f1c6 100644 --- a/README.md +++ b/README.md @@ -257,6 +257,24 @@ To update the documentation will need to: * Run the gensphynx target in the buildsystem * Push to github pages with `make push_docs_to_ghpages` +##### Running tests + +To run tests you can use the helper top level Makefile + +For visual studio you can run + +``` +make vs_cmake +make vs_run_tests VS_BUILD_TYPE="Release" +``` + +For unix you can run + +``` +make mk_cmake MK_BUILD_TYPE="Release" +make mk_run_tests +``` + # The Komputer is waiting for instructions... diff --git a/shaders/glsl/opmult.comp b/shaders/glsl/opmult.comp index 213fd2643..d54865037 100644 --- a/shaders/glsl/opmult.comp +++ b/shaders/glsl/opmult.comp @@ -16,7 +16,6 @@ layout (constant_id = 0) const uint LEN_LHS = 0; layout (constant_id = 1) const uint LEN_RHS = 0; layout (constant_id = 2) const uint LEN_OUT = 0; -// TODO: Explore how to make layout inside shader dynamic layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in; void main() diff --git a/single_include/kompute/Kompute.hpp b/single_include/kompute/Kompute.hpp index 1016da63d..8d41f50cf 100755 --- a/single_include/kompute/Kompute.hpp +++ b/single_include/kompute/Kompute.hpp @@ -231,9 +231,18 @@ class Tensor * important to ensure that there is no out-of-sync data with the GPU * memory. * - * @return Vector of elements representing the data in the tensor. + * @return Reference to vector of elements representing the data in the tensor. */ - std::vector data(); + std::vector& data(); + /** + * Overrides the subscript operator to expose the underlying data's + * subscript operator which in this case would be its underlying + * vector's. + * + * @param i The index where the element will be returned from. + * @return Returns the element in the position requested. + */ + float& operator[] (int index); /** * Returns the size/magnitude of the Tensor, which will be the total number * of elements across all dimensions @@ -794,7 +803,6 @@ class Algorithm bool mFreeDescriptorSetLayout = false; std::shared_ptr mDescriptorPool; bool mFreeDescriptorPool = false; - // TODO: Explore design for multiple descriptor sets std::shared_ptr mDescriptorSet; bool mFreeDescriptorSet = false; std::shared_ptr mShaderModule; @@ -987,8 +995,6 @@ OpAlgoBase::OpAlgoBase(std::shared_ptr physicalD this->mY = tY > 0 ? tY : 1; this->mZ = tZ > 0 ? tZ : 1; } else { - // TODO: If tensor empty vector exception would be thrown - // TODO: Fully support the full size dispatch using size for the shape this->mX = tensors[0]->size(); this->mY = 1; this->mZ = 1; @@ -1298,7 +1304,6 @@ OpAlgoLhsRhsOut::init() this->mTensorRHS = this->mTensors[1]; this->mTensorOutput = this->mTensors[2]; - // TODO: Explore adding a validate function if (!(this->mTensorLHS->isInit() && this->mTensorRHS->isInit() && this->mTensorOutput->isInit())) { throw std::runtime_error( @@ -1308,8 +1313,6 @@ OpAlgoLhsRhsOut::init() " Output: " + std::to_string(this->mTensorOutput->isInit())); } - // TODO: Explore use-cases where tensors shouldn't be the same size, and how - // to deal with those situations if (!(this->mTensorLHS->size() == this->mTensorRHS->size() && this->mTensorRHS->size() == this->mTensorOutput->size())) { throw std::runtime_error( diff --git a/test/TestLogisticRegression.cpp b/test/TestLogisticRegression.cpp index f87edacd6..107f34509 100644 --- a/test/TestLogisticRegression.cpp +++ b/test/TestLogisticRegression.cpp @@ -42,35 +42,30 @@ TEST_CASE("test_logistic_regression") { sq->end(); sq->eval(); + // Record op algo base + sq->begin(); + + sq->record>( + params, + true, // Whether to copy output from device + "test/shaders/glsl/test_logistic_regression.comp"); + + sq->end(); + // Iterate across all expected iterations for (size_t i = 0; i < ITERATIONS; i++) { - sq->begin(); - - sq->record>( - params, - true, // Whether to copy output from device - "test/shaders/glsl/test_logistic_regression.comp"); - - sq->end(); sq->eval(); - // TODO: Reference of data instead of full value copy every time for(size_t j = 0; j < bOut->size(); j++) { - wInVec[0] -= wOutI->data()[j]; - wInVec[1] -= wOutJ->data()[j]; - bInVec[0] -= bOut->data()[j]; + wIn->data()[0] -= wOutI->data()[j]; + wIn->data()[1] -= wOutJ->data()[j]; + bIn->data()[0] -= bOut->data()[j]; } - wIn->setData(wInVec); - bIn->setData(bInVec); - wIn->mapDataIntoHostMemory(); bIn->mapDataIntoHostMemory(); } } - - wIn->mapDataFromHostMemory(); - bIn->mapDataFromHostMemory(); } diff --git a/test/TestManager.cpp b/test/TestManager.cpp index 7c67501e7..08c98e8af 100755 --- a/test/TestManager.cpp +++ b/test/TestManager.cpp @@ -5,60 +5,43 @@ #include -TEST_CASE("End to end OpMult Flow should execute correctly from manager") { - spdlog::info("TEST CASE STARTING"); +TEST_CASE("End to end OpMult Flow should execute correctly from manager") +{ + kp::Manager mgr; - spdlog::info("Creating manager"); - { - kp::Manager mgr; + std::shared_ptr tensorLHS{ new kp::Tensor({ 0, 1, 2 }) }; + mgr.evalOp({ tensorLHS }); - spdlog::info("Creating first tensor"); - std::shared_ptr tensorLHS{ new kp::Tensor({ 0, 1, 2 }) }; - mgr.evalOp({ tensorLHS }); + std::shared_ptr tensorRHS{ new kp::Tensor( + { 2, 4, 6 }) }; + mgr.evalOp({ tensorRHS }); - spdlog::info("Creating second tensor"); - std::shared_ptr tensorRHS{ new kp::Tensor( - { 2, 4, 6 }) }; - mgr.evalOp({ tensorRHS }); + std::shared_ptr tensorOutput{ new kp::Tensor( + { 0, 0, 0 }) }; + mgr.evalOp({ tensorOutput }); - // TODO: Add capabilities for just output tensor types - spdlog::info("Creating output tensor"); - std::shared_ptr tensorOutput{ new kp::Tensor( - { 0, 0, 0 }) }; - mgr.evalOp({ tensorOutput }); + spdlog::info("OpCreateTensor success for tensors"); + spdlog::info("Tensor one: {}", tensorLHS->data()); + spdlog::info("Tensor two: {}", tensorRHS->data()); + spdlog::info("Tensor output: {}", tensorOutput->data()); - spdlog::info("OpCreateTensor success for tensors"); - spdlog::info("Tensor one: {}", tensorLHS->data()); - spdlog::info("Tensor two: {}", tensorRHS->data()); - spdlog::info("Tensor output: {}", tensorOutput->data()); + spdlog::info("Calling op mult"); + mgr.evalOp>({ tensorLHS, tensorRHS, tensorOutput }); - spdlog::info("Calling op mult"); - mgr.evalOp>({ tensorLHS, tensorRHS, tensorOutput }); + spdlog::info("OpMult call success"); + spdlog::info("Tensor output: {}", tensorOutput->data()); - spdlog::info("OpMult call success"); - spdlog::info("Tensor output: {}", tensorOutput->data()); - - REQUIRE(tensorOutput->data() == std::vector{0, 4, 12}); - } - - spdlog::info("Called manager eval success END PROGRAM"); + REQUIRE(tensorOutput->data() == std::vector{0, 4, 12}); } TEST_CASE("End to end OpMult Flow should execute correctly from sequence") { - spdlog::info("TEST CASE STARTING"); - spdlog::info("Creating manager"); - - spdlog::info("Creating first tensor"); std::shared_ptr tensorLHS{ new kp::Tensor( { 0, 1, 2 }) }; - spdlog::info("Creating second tensor"); std::shared_ptr tensorRHS{ new kp::Tensor( { 2, 4, 6 }) }; - // TODO: Add capabilities for just output tensor types - spdlog::info("Creating output tensor"); std::shared_ptr tensorOutput{ new kp::Tensor( { 0, 0, 0 }) }; @@ -72,12 +55,6 @@ TEST_CASE("End to end OpMult Flow should execute correctly from sequence") { sq->record({ tensorRHS }); sq->record({ tensorOutput }); - spdlog::info("OpCreateTensor success for tensors"); - spdlog::info("Tensor one: {}", tensorLHS->data()); - spdlog::info("Tensor two: {}", tensorRHS->data()); - spdlog::info("Tensor output: {}", tensorOutput->data()); - - spdlog::info("Calling op mult"); sq->record>({ tensorLHS, tensorRHS, tensorOutput }); sq->end(); @@ -85,12 +62,7 @@ TEST_CASE("End to end OpMult Flow should execute correctly from sequence") { } sqWeakPtr.reset(); - spdlog::info("OpMult call success"); - spdlog::info("Tensor output: {}", tensorOutput->data()); - REQUIRE(tensorOutput->data() == std::vector{0, 4, 12}); - - spdlog::info("Called manager eval success END PROGRAM"); } TEST_CASE("Test manager get create functionality for sequences") { @@ -115,20 +87,13 @@ TEST_CASE("Test manager get create functionality for sequences") { } TEST_CASE("End to end OpMult Flow with OpCreateTensor called with multiple tensors") { - spdlog::info("TEST CASE STARTING"); - spdlog::info("Creating manager"); - - spdlog::info("Creating first tensor"); std::shared_ptr tensorLHS{ new kp::Tensor( { 0, 1, 2 }) }; - spdlog::info("Creating second tensor"); std::shared_ptr tensorRHS{ new kp::Tensor( { 2, 4, 6 }) }; - // TODO: Add capabilities for just output tensor types - spdlog::info("Creating output tensor"); std::shared_ptr tensorOutput{ new kp::Tensor( { 0, 0, 0 }) }; @@ -140,15 +105,10 @@ TEST_CASE("End to end OpMult Flow with OpCreateTensor called with multiple tenso sq->record({ tensorLHS, tensorRHS, tensorOutput }); - spdlog::info("OpCreateTensor success for tensors"); - spdlog::info("Tensor one: {}", tensorLHS->data()); - spdlog::info("Tensor two: {}", tensorRHS->data()); - spdlog::info("Tensor output: {}", tensorOutput->data()); REQUIRE(tensorLHS->isInit()); REQUIRE(tensorRHS->isInit()); REQUIRE(tensorOutput->isInit()); - spdlog::info("Calling op mult"); sq->record>({ tensorLHS, tensorRHS, tensorOutput }); sq->end(); @@ -156,10 +116,5 @@ TEST_CASE("End to end OpMult Flow with OpCreateTensor called with multiple tenso } sqWeakPtr.reset(); - spdlog::info("OpMult call success"); - spdlog::info("Tensor output: {}", tensorOutput->data()); - REQUIRE(tensorOutput->data() == std::vector{0, 4, 12}); - - spdlog::info("Called manager eval success END PROGRAM"); }