diff options
author | Geir Storli <geirst@yahoo-inc.com> | 2016-10-24 14:28:00 +0200 |
---|---|---|
committer | Geir Storli <geirst@yahoo-inc.com> | 2016-10-24 14:28:00 +0200 |
commit | 292817945280d84896d3b137d3c2c2385d7b15b4 (patch) | |
tree | 3f457c1630a9e6070eab59edc9b1e2bf2fe99d7e /vespalib/src/tests/dotproduct | |
parent | b73bd2dded336d472a67c53539500160d6d28796 (diff) |
Move hwaccelrated library from staging_vespalib to vespalib (for usage in tensor code).
Diffstat (limited to 'vespalib/src/tests/dotproduct')
-rw-r--r-- | vespalib/src/tests/dotproduct/.gitignore | 2 | ||||
-rw-r--r-- | vespalib/src/tests/dotproduct/CMakeLists.txt | 21 | ||||
-rw-r--r-- | vespalib/src/tests/dotproduct/dotproductbenchmark.cpp | 179 |
3 files changed, 202 insertions, 0 deletions
diff --git a/vespalib/src/tests/dotproduct/.gitignore b/vespalib/src/tests/dotproduct/.gitignore new file mode 100644 index 00000000000..5d9432fbd08 --- /dev/null +++ b/vespalib/src/tests/dotproduct/.gitignore @@ -0,0 +1,2 @@ +dotproductbenchmark +staging_vespalib_dotproductbenchmark_app diff --git a/vespalib/src/tests/dotproduct/CMakeLists.txt b/vespalib/src/tests/dotproduct/CMakeLists.txt new file mode 100644 index 00000000000..4887f74088c --- /dev/null +++ b/vespalib/src/tests/dotproduct/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(vespalib_dotproductbenchmark_app + SOURCES + dotproductbenchmark.cpp + DEPENDS + vespalib +) +vespa_add_test(NAME vespalib_dotproductbenchmark_app_sparse-ordered COMMAND vespalib_dotproductbenchmark_app 10 10 1000 1000 BENCHMARK) +vespa_add_test(NAME vespalib_dotproductbenchmark_app_sparse-unordered COMMAND vespalib_dotproductbenchmark_app 10 10 1000 1000 BENCHMARK) +vespa_add_test(NAME vespalib_dotproductbenchmark_app_full COMMAND vespalib_dotproductbenchmark_app 10 10 1000 1000 BENCHMARK) + +# benchmark: dotproductbenchmark +# $(HIDE)$(LDL) time $(VALGRIND) ./dotproductbenchmark sparse-ordered 1000 1000 1000 1000 +# $(HIDE)$(LDL) time $(VALGRIND) ./dotproductbenchmark sparse-unordered 1000 1000 1000 1000 +# $(HIDE)$(LDL) time $(VALGRIND) ./dotproductbenchmark full 1000 1000 1000 1000 +# $(HIDE)$(LDL) time $(VALGRIND) ./dotproductbenchmark sparse-ordered 1000 1000 100 1000 +# $(HIDE)$(LDL) time $(VALGRIND) ./dotproductbenchmark sparse-unordered 1000 1000 100 1000 +# $(HIDE)$(LDL) time $(VALGRIND) ./dotproductbenchmark full 1000 1000 100 1000 +# $(HIDE)$(LDL) time $(VALGRIND) ./dotproductbenchmark sparse-ordered 1000 1000 1000 100 +# $(HIDE)$(LDL) time $(VALGRIND) ./dotproductbenchmark sparse-unordered 1000 1000 1000 100 +# $(HIDE)$(LDL) time $(VALGRIND) ./dotproductbenchmark full 1000 1000 1000 100 diff --git a/vespalib/src/tests/dotproduct/dotproductbenchmark.cpp b/vespalib/src/tests/dotproduct/dotproductbenchmark.cpp new file mode 100644 index 00000000000..9ef3d959f3b --- /dev/null +++ b/vespalib/src/tests/dotproduct/dotproductbenchmark.cpp @@ -0,0 +1,179 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <vespa/fastos/fastos.h> +#include <vespa/vespalib/hwaccelrated/iaccelrated.h> +#include <vespa/vespalib/stllike/string.h> +#include <vespa/vespalib/stllike/hash_map.h> +#include <iostream> + +using namespace vespalib; +using vespalib::hwaccelrated::IAccelrated; + +class Benchmark { +public: + virtual ~Benchmark() { } + virtual void compute(size_t docId) const = 0; +}; + +void +runBenchmark(size_t count, size_t docs, const Benchmark & benchmark) +{ + for (size_t i(0); i < count; i++) { + for (size_t docId(0); docId < docs; docId++) { + benchmark.compute(docId); + } + } +} + +template <typename T> +class FullBenchmark : public Benchmark +{ +public: + FullBenchmark(size_t numDocs, size_t numValues) : + _values(numDocs*numValues), + _query(numValues), + _dp(IAccelrated::getAccelrator()) + { + for (size_t i(0); i < numDocs; i++) { + for (size_t j(0); j < numValues; j++) { + _values[i*numValues + j] = j; + } + } + for (size_t j(0); j < numValues; j++) { + _query[j] = j; + } + } + virtual void compute(size_t docId) const { + _dp->dotProduct(&_query[0], &_values[docId * _query.size()], _query.size()); + } +private: + std::vector<T> _values; + std::vector<T> _query; + IAccelrated::UP _dp; +}; + +class SparseBenchmark : public Benchmark +{ +public: + SparseBenchmark(size_t numDocs, size_t numValues, size_t numQueryValues) : + _numValues(numValues), + _values(numDocs*numValues) + { + for (size_t i(0); i < numDocs; i++) { + for (size_t j(0); j < numValues; j++) { + size_t k(numValues < numQueryValues ? (j*numQueryValues)/numValues : j); + _values[i*numValues + j] = P(k, k); + } + } + } +protected: + struct P { + P(uint32_t key=0, int32_t value=0) : + _key(key), + _value(value) + { } + uint32_t _key; + int32_t _value; + }; + size_t _numValues; + std::vector<P> _values; +}; + +class UnorderedSparseBenchmark : public SparseBenchmark +{ +private: + typedef hash_map<uint32_t, int32_t> map; +public: + UnorderedSparseBenchmark(size_t numDocs, size_t numValues, size_t numQueryValues) : + SparseBenchmark(numDocs, numValues, numQueryValues) + { + for (size_t j(0); j < numQueryValues; j++) { + _query[j] = j; + } + } +private: + virtual void compute(size_t docId) const { + int64_t sum(0); + size_t offset(docId*_numValues); + const auto e(_query.end()); + for (size_t i(0); i < _numValues; i++) { + auto it = _query.find(_values[offset + i]._key); + if (it != e) { + sum += static_cast<int64_t>(_values[offset + i]._value) * it->second; + } + } + } + map _query; +}; + +class OrderedSparseBenchmark : public SparseBenchmark +{ +private: +public: + OrderedSparseBenchmark(size_t numDocs, size_t numValues, size_t numQueryValues) : + SparseBenchmark(numDocs, numValues, numQueryValues), + _query(numQueryValues) + { + for (size_t j(0); j < numQueryValues; j++) { + size_t k(numValues > numQueryValues ? j*numValues/numQueryValues : j); + _query[j] = P(k, k); + } + } +private: + virtual void compute(size_t docId) const { + int64_t sum(0); + size_t offset(docId*_numValues); + + for (size_t a(0), b(0); a < _query.size() && b < _numValues; b++) { + for (; a < _query.size() && (_query[a]._key <= _values[offset + b]._key); a++); + if (_query[a]._key == _values[offset + b]._key) { + sum += static_cast<int64_t>(_values[offset + b]._value) * _query[a]._value; + } + } + } + std::vector<P> _query; +}; + +int main(int argc, char *argv[]) +{ + size_t numDocs(1); + size_t numValues(1000); + size_t numQueryValues(1000); + size_t numQueries(1000000); + string type("full"); + if ( argc > 1) { + type = argv[1]; + } + if ( argc > 2) { + numQueries = strtoul(argv[2], NULL, 0); + } + if ( argc > 3) { + numDocs = strtoul(argv[3], NULL, 0); + } + if ( argc > 4) { + numValues = strtoul(argv[4], NULL, 0); + } + if ( argc > 5) { + numQueryValues = strtoul(argv[5], NULL, 0); + } + + std::cout << "type = " << type << std::endl; + std::cout << "numQueries = " << numQueries << std::endl; + std::cout << "numDocs = " << numDocs << std::endl; + std::cout << "numValues = " << numValues << std::endl; + std::cout << "numQueryValues = " << numQueryValues << std::endl; + if (type == "full") { + FullBenchmark<int32_t> bm(numDocs, numValues); + runBenchmark(numQueries, numDocs, bm); + } else if (type == "sparse-ordered") { + OrderedSparseBenchmark bm(numDocs, numValues, numQueryValues); + runBenchmark(numQueries, numDocs, bm); + } else if (type == "sparse-unordered") { + UnorderedSparseBenchmark bm(numDocs, numValues, numQueryValues); + runBenchmark(numQueries, numDocs, bm); + } else { + std::cerr << "type '" << type << "' is unknown." << std::endl; + } + + return 0; +} + |