diff --git a/.teamcity/Dockerfile b/.teamcity/Dockerfile index c3d1c209eb04bf7379969a28d0be4ce1bfe10c0d..e16d09d6f56adfc6ba9bd9a3305e3d8210117146 100644 --- a/.teamcity/Dockerfile +++ b/.teamcity/Dockerfile @@ -18,3 +18,11 @@ FROM parl/parl-test:cuda9.0-cudnn7-v2 COPY ./requirements.txt /root/ + +RUN apt-get install -y libgflags-dev libgoogle-glog-dev libomp-dev unzip +RUN apt-get install -y libgtest-dev && cd /usr/src/gtest && mkdir build \ + && cd build && cmake .. && make && cp libgtest*.a /usr/local/lib + +RUN wget https://github.com/google/protobuf/releases/download/v2.4.1/protobuf-2.4.1.tar.gz \ + && tar -zxvf protobuf-2.4.1.tar.gz \ + && cd protobuf-2.4.1 && ./configure && make && make install diff --git a/.teamcity/build.sh b/.teamcity/build.sh index 6a33424797690bcd088381bd8173ae7d881c2dbc..2f6cec0c6976797572bb9f139e0cd42cde3e5d5e 100755 --- a/.teamcity/build.sh +++ b/.teamcity/build.sh @@ -134,6 +134,19 @@ EOF rm -rf ${REPO_ROOT}/build } +function run_deepes_test { + cd ${REPO_ROOT}/deepes + + cat < noisy_rewards(ITER, 0.0f); noisy_keys.resize(ITER); - for (int epoch = 0; epoch < 1000; ++epoch) { + for (int epoch = 0; epoch < 100; ++epoch) { #pragma omp parallel for schedule(dynamic, 1) for (int i = 0; i < ITER; ++i) { auto sampling_agent = sampling_agents[i]; diff --git a/deepes/include/utils.h b/deepes/include/utils.h index 6733e7ccb765194f4df65bfcdbd470f4a09fbb0c..843f7c45ab073835c9eb4ebc67b7fa1993f347d4 100644 --- a/deepes/include/utils.h +++ b/deepes/include/utils.h @@ -27,7 +27,7 @@ namespace DeepES{ Args: reward: an array of rewards */ -void compute_centered_ranks(std::vector &reward) ; +bool compute_centered_ranks(std::vector &reward); /* Load a protobuf-based configuration from the file. * Args: diff --git a/deepes/scripts/build.sh b/deepes/scripts/build.sh index 4dc8d518072509d5c4fd4cf7a020e41567531017..c1a40671ae2b344a4e908684a15e261cebe55750 100644 --- a/deepes/scripts/build.sh +++ b/deepes/scripts/build.sh @@ -23,8 +23,11 @@ elif [ $1 = "torch" ]; then #---------------libtorch-------------# if [ ! -d "./libtorch" ];then echo "Cannot find the torch library: ./libtorch" - echo "Please put the torch libraray to current folder according the instruction in README" - exit 1 + echo "Downloading Torch library" + wget -q https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-1.4.0%2Bcpu.zip + unzip -q libtorch-cxx11-abi-shared-with-deps-1.4.0+cpu.zip + rm -rf libtorch-cxx11-abi-shared-with-deps-1.4.0+cpu.zip + echo "Torch library Downloaded" fi FLAGS=" -DWITH_TORCH=ON" else @@ -32,7 +35,7 @@ else exit 0 fi -#export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH +export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH #----------------protobuf-------------# cp ./src/proto/deepes.proto ./ diff --git a/deepes/src/optimizer_factory.cc b/deepes/src/optimizer_factory.cc index 55dff6bc76ad7fbcac2f2d22ac4adb7ef90a4dad..08419045267cfbcdbad4a8d083f529af2e047db7 100644 --- a/deepes/src/optimizer_factory.cc +++ b/deepes/src/optimizer_factory.cc @@ -16,6 +16,7 @@ namespace DeepES{ + std::shared_ptr create_optimizer(const OptimizerConfig& optimizer_config) { std::shared_ptr optimizer; std::string opt_type = optimizer_config.type(); diff --git a/deepes/src/utils.cc b/deepes/src/utils.cc index 5a2e8c37fd2967bd378230858e941d1b8a684b89..726da6606592e311d903de0ecc6d62ad239a48a2 100644 --- a/deepes/src/utils.cc +++ b/deepes/src/utils.cc @@ -16,7 +16,7 @@ namespace DeepES { -void compute_centered_ranks(std::vector &reward) { +bool compute_centered_ranks(std::vector &reward) { std::vector> reward_index; float gap = 1.0 / (reward.size() - 1); float normlized_rank = -0.5; @@ -31,6 +31,7 @@ void compute_centered_ranks(std::vector &reward) { reward[id] = normlized_rank; normlized_rank += gap; } + return true; } }//namespace diff --git a/deepes/test/CMakeLists.txt b/deepes/test/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..86b91214b47f5ec1a257e98204371a9ab9e79fa9 --- /dev/null +++ b/deepes/test/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required (VERSION 2.6) +project (DeepES) +set(TARGET unit_test_main) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +find_package(GTest REQUIRED) +find_package(OpenMP) +if (OPENMP_FOUND) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") +endif() + +file(GLOB core_src "../src/*.cc" "../src/*.cpp" "../benchmark/*.cc") +file(GLOB test_src "../test/src/*.cc") + + +include_directories("../include") +include_directories("../benchmark") +include_directories("../test/include") + +add_executable(${TARGET} "unit_test.cc" ${core_src} ${test_src} ${lib_src}) # ${demo_src} +target_link_libraries(${TARGET} gflags protobuf pthread glog gtest) # "${TORCH_LIBRARIES}" diff --git a/deepes/test/run_test.sh b/deepes/test/run_test.sh new file mode 100644 index 0000000000000000000000000000000000000000..82d805935702e6fc95bc905d87bc1de10a22cc65 --- /dev/null +++ b/deepes/test/run_test.sh @@ -0,0 +1,16 @@ +#!/bin/bash +export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH + +#----------------protobuf-------------# +cp ./src/proto/deepes.proto ./ +protoc deepes.proto --cpp_out ./ +mv deepes.pb.h ./include +mv deepes.pb.cc ./src + +#----------------build---------------# +rm -rf build +mkdir build +cd build +cmake ../test # -DWITH_TORCH=ON +make -j10 +./unit_test_main diff --git a/deepes/test/src/optimizers_test.cc b/deepes/test/src/optimizers_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..6d7116941d76322caecdd4517a61736b6760d280 --- /dev/null +++ b/deepes/test/src/optimizers_test.cc @@ -0,0 +1,59 @@ +// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "gtest/gtest.h" +#include +#include "optimizer_factory.h" +#include + +namespace DeepES { + +TEST(SGDOptimizersTest, Method_update) { + std::shared_ptr config = std::make_shared(); + auto optimizer_config = config->mutable_optimizer(); + optimizer_config->set_base_lr(1.0); + optimizer_config->set_type("sgd"); + std::shared_ptr optimizer = create_optimizer(config->optimizer()); + float sgd_wei[10] = { 0.0 , 0.0 , 0.04216444, 0.0511456 , 0.04231584, 0.01089015, 0.06569759, 0.00127421,-0.00092832, 0.01128081}; + float sgd_grad[10] = {-0.11992419,-0.0 , 0.07681337,-0.06616384, 0.00249889, 0.01158612,-0.3067452 , 0.36048946,-0.15820622,-0.20014143}; + float sgd_new[10] = { 0.01199242, 0.0 , 0.0344831 , 0.05776198, 0.04206595, 0.00973154, 0.09637211,-0.03477474, 0.014892306, 0.03129495}; + + EXPECT_TRUE(optimizer->update(sgd_wei, sgd_grad, 10, "test")); + for (int i = 0; i < 10; ++i) { + EXPECT_FLOAT_EQ(sgd_new[i], sgd_wei[i]) << " i: " << i ; + } + EXPECT_TRUE(optimizer->update(sgd_wei, sgd_grad, 10, "test")); + EXPECT_FALSE(optimizer->update(sgd_wei, sgd_grad, 9, "test")); +} + +TEST(AdamOptimizersTest, Method_update) { + std::shared_ptr config = std::make_shared(); + auto optimizer_config = config->mutable_optimizer(); + optimizer_config->set_base_lr(1.0); + optimizer_config->set_type("adam"); + std::shared_ptr optimizer = create_optimizer(config->optimizer()); + float adam_wei[10] = { 0.0 , 0.0 , 0.04216444, 0.0511456 , 0.04231584, 0.01089015, 0.06569759, 0.00127421,-0.00092832, 0.01128081}; + float adam_grad[10] = {-0.11992419,-0.0 , 0.07681337,-0.06616384, 0.00249889, 0.01158612,-0.3067452 , 0.36048946,-0.15820622,-0.20014143}; + float adam_new[10] = { 0.99999736, 0. ,-0.95783144, 1.05114082,-0.95755763,-0.98908256, 1.06569656,-0.99872491, 0.99906968, 1.01127923}; + + EXPECT_TRUE(optimizer->update(adam_wei, adam_grad, 10, "test")); + for (int i = 0; i < 10; ++i) { + EXPECT_FLOAT_EQ(adam_new[i], adam_wei[i]) << " i: " << i ; + } + EXPECT_TRUE(optimizer->update(adam_wei, adam_grad, 10, "test")); + EXPECT_FALSE(optimizer->update(adam_wei, adam_grad, 9, "test")); +} + +} + diff --git a/deepes/test/src/utils_test.cc b/deepes/test/src/utils_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..eda386504ca5773d71dc4d66a6c426e80d048441 --- /dev/null +++ b/deepes/test/src/utils_test.cc @@ -0,0 +1,30 @@ +// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "gtest/gtest.h" +#include +#include "utils.h" + +namespace DeepES { + +// Tests that the Utils::compute_centered_rank() method. +TEST(UtilsTest, Method_compute_centered_ranks) { + float a[5] = {9.0, 8.0, 7.0, 6.0, 5.0}; + std::vector reward_vec(a, a+5); + EXPECT_EQ(compute_centered_ranks(reward_vec), true); +} + + +} + diff --git a/deepes/test/unit_test.cc b/deepes/test/unit_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..3bbc21f4cdfb8e7709173a258f66560a7f7e27a1 --- /dev/null +++ b/deepes/test/unit_test.cc @@ -0,0 +1,20 @@ +// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "gtest/gtest.h" + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +}