diff options
25 files changed, 131 insertions, 44 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/systemflags/FlagsClient.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/systemflags/FlagsClient.java index 992d0754cc5..5cd6b32d572 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/systemflags/FlagsClient.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/systemflags/FlagsClient.java @@ -1,7 +1,6 @@ // Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.controller.restapi.systemflags; -import ai.vespa.util.http.retry.DelayedHttpRequestRetryHandler; import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.vespa.athenz.api.AthenzIdentity; import com.yahoo.vespa.athenz.identity.ServiceIdentityProvider; @@ -85,9 +84,6 @@ class FlagsClient { private static CloseableHttpClient createClient(ServiceIdentityProvider identityProvider, Set<FlagsTarget> targets) { - DelayedHttpRequestRetryHandler retryHandler = DelayedHttpRequestRetryHandler.Builder - .withExponentialBackoff(Duration.ofSeconds(1), Duration.ofSeconds(20), 5) - .build(); return HttpClientBuilder.create() .setUserAgent("controller-flags-v1-client") .setRetryHandler(new DefaultHttpRequestRetryHandler(5, /*retry on non-idempotent requests*/true)) @@ -100,7 +96,6 @@ class FlagsClient { .build()) .setMaxConnPerRoute(2) .setMaxConnTotal(100) - .setRetryHandler(retryHandler) .build(); } diff --git a/document/src/vespa/document/fieldvalue/structfieldvalue.cpp b/document/src/vespa/document/fieldvalue/structfieldvalue.cpp index 793f6918bd1..b448b2b33bc 100644 --- a/document/src/vespa/document/fieldvalue/structfieldvalue.cpp +++ b/document/src/vespa/document/fieldvalue/structfieldvalue.cpp @@ -43,7 +43,7 @@ StructFieldValue::StructFieldValue(const DataType &type) StructFieldValue::StructFieldValue(const StructFieldValue & rhs) = default; StructFieldValue & StructFieldValue::operator = (const StructFieldValue & rhs) = default; -StructFieldValue::~StructFieldValue() = default; +StructFieldValue::~StructFieldValue() noexcept = default; const StructDataType & StructFieldValue::getStructType() const { diff --git a/documentapi/src/vespa/documentapi/messagebus/documentprotocol.cpp b/documentapi/src/vespa/documentapi/messagebus/documentprotocol.cpp index e8cc7a03e94..a2e8219e916 100644 --- a/documentapi/src/vespa/documentapi/messagebus/documentprotocol.cpp +++ b/documentapi/src/vespa/documentapi/messagebus/documentprotocol.cpp @@ -48,7 +48,7 @@ DocumentProtocol::DocumentProtocol(const LoadTypeSet& loadTypes, std::vector<vespalib::VersionSpecification> from6 = { version6 }; // Add 6.x serialization - putRoutableFactory(MESSAGE_CREATEVISITOR, IRoutableFactory::SP(new RoutableFactories60::CreateVisitorMessageFactory(*_repo)), from6); + putRoutableFactory(MESSAGE_CREATEVISITOR, IRoutableFactory::SP(new RoutableFactories60::CreateVisitorMessageFactory()), from6); putRoutableFactory(MESSAGE_DESTROYVISITOR, IRoutableFactory::SP(new RoutableFactories60::DestroyVisitorMessageFactory()), from6); putRoutableFactory(MESSAGE_DOCUMENTLIST, IRoutableFactory::SP(new RoutableFactories60::DocumentListMessageFactory(*_repo)), from6); putRoutableFactory(MESSAGE_DOCUMENTSUMMARY, IRoutableFactory::SP(new RoutableFactories60::DocumentSummaryMessageFactory()), from6); @@ -56,7 +56,7 @@ DocumentProtocol::DocumentProtocol(const LoadTypeSet& loadTypes, putRoutableFactory(MESSAGE_GETBUCKETLIST, IRoutableFactory::SP(new RoutableFactories60::GetBucketListMessageFactory()), from6); putRoutableFactory(MESSAGE_GETBUCKETSTATE, IRoutableFactory::SP(new RoutableFactories60::GetBucketStateMessageFactory()), from6); putRoutableFactory(MESSAGE_GETDOCUMENT, IRoutableFactory::SP(new RoutableFactories60::GetDocumentMessageFactory()), from6); - putRoutableFactory(MESSAGE_MAPVISITOR, IRoutableFactory::SP(new RoutableFactories60::MapVisitorMessageFactory(*_repo)), from6); + putRoutableFactory(MESSAGE_MAPVISITOR, IRoutableFactory::SP(new RoutableFactories60::MapVisitorMessageFactory()), from6); putRoutableFactory(MESSAGE_PUTDOCUMENT, IRoutableFactory::SP(new RoutableFactories60::PutDocumentMessageFactory(*_repo)), from6); putRoutableFactory(MESSAGE_QUERYRESULT, IRoutableFactory::SP(new RoutableFactories60::QueryResultMessageFactory()), from6); putRoutableFactory(MESSAGE_REMOVEDOCUMENT, IRoutableFactory::SP(new RoutableFactories60::RemoveDocumentMessageFactory()), from6); diff --git a/documentapi/src/vespa/documentapi/messagebus/routablefactories60.h b/documentapi/src/vespa/documentapi/messagebus/routablefactories60.h index 75404f1dea1..0a997f3ffd9 100644 --- a/documentapi/src/vespa/documentapi/messagebus/routablefactories60.h +++ b/documentapi/src/vespa/documentapi/messagebus/routablefactories60.h @@ -130,7 +130,6 @@ public: // //////////////////////////////////////////////////////////////////////////////// class CreateVisitorMessageFactory : public DocumentMessageFactory { - const document::DocumentTypeRepo &_repo; protected: DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; @@ -138,7 +137,7 @@ public: virtual bool encodeBucketSpace(vespalib::stringref bucketSpace, vespalib::GrowableByteBuffer& buf) const; virtual string decodeBucketSpace(document::ByteBuffer&) const; public: - CreateVisitorMessageFactory(const document::DocumentTypeRepo &r) : _repo(r) {} + CreateVisitorMessageFactory() : DocumentMessageFactory() {} }; class CreateVisitorReplyFactory : public DocumentReplyFactory { protected: @@ -228,12 +227,11 @@ public: GetDocumentReplyFactory(const document::DocumentTypeRepo &r) : _repo(r) {} }; class MapVisitorMessageFactory : public DocumentMessageFactory { - const document::DocumentTypeRepo &_repo; protected: DocumentMessage::UP doDecode(document::ByteBuffer &buf) const override; bool doEncode(const DocumentMessage &msg, vespalib::GrowableByteBuffer &buf) const override; public: - MapVisitorMessageFactory(const document::DocumentTypeRepo &r) : _repo(r) {} + MapVisitorMessageFactory() : DocumentMessageFactory() {} }; class MapVisitorReplyFactory : public DocumentReplyFactory { protected: diff --git a/eval/src/tests/ann/sift_benchmark.cpp b/eval/src/tests/ann/sift_benchmark.cpp index f37fd36652b..5ca505e5f1e 100644 --- a/eval/src/tests/ann/sift_benchmark.cpp +++ b/eval/src/tests/ann/sift_benchmark.cpp @@ -33,7 +33,7 @@ static PointVector *aligned_alloc(size_t num) { size_t val = (size_t)mem; size_t unalign = val % 512; mem -= unalign; - return (PointVector *)mem; + return reinterpret_cast<PointVector *>(mem); } static PointVector *generatedQueries = aligned_alloc(NUM_Q); diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java index 0d1ef3478ef..42e4bd9cd29 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java @@ -214,6 +214,13 @@ public class Flags { "Takes effect immediately", ZONE_ID, HOSTNAME); + public static final UnboundBooleanFlag GENERATE_ROUTING_CONFIG_FOR_TESTER_APPLICATIONS = defineFeatureFlag( + "generate-routing-config-for-tester-applications", true, + "Whether config server should generate routing config (lb-services) for tester applications", + "Takes effect immediately", + ZONE_ID); + + /** WARNING: public for testing: All flags should be defined in {@link Flags}. */ public static UnboundBooleanFlag defineFeatureFlag(String flagId, boolean defaultValue, String description, String modificationEffect, FetchVector.Dimension... dimensions) { diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeList.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeList.java index 37987f0512d..21bde5900eb 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeList.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeList.java @@ -9,6 +9,7 @@ import com.yahoo.config.provision.NodeType; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.EnumSet; import java.util.Iterator; import java.util.List; @@ -79,6 +80,16 @@ public class NodeList implements Iterable<Node> { return filter(node -> node.status().osVersion().changing()); } + /** Returns a copy of this sorted by current OS version (lowest to highest) */ + public NodeList byIncreasingOsVersion() { + return nodes.stream() + .sorted(Comparator.comparing(node -> node.status() + .osVersion() + .current() + .orElse(Version.emptyVersion))) + .collect(collectingAndThen(Collectors.toList(), NodeList::wrap)); + } + /** Returns the subset of nodes that are currently on the given OS version */ public NodeList onOsVersion(Version version) { return filter(node -> node.status().osVersion().matches(version)); diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsVersions.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsVersions.java index 106595fbd47..9b21d2aceba 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsVersions.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsVersions.java @@ -123,6 +123,7 @@ public class OsVersions { var numberToUpgrade = Math.max(0, maxActiveUpgrades - nodes.changingOsVersion().size()); var nodesToUpgrade = nodes.not().changingOsVersion() .not().onOsVersion(version) + .byIncreasingOsVersion() .first(numberToUpgrade); if (nodesToUpgrade.size() == 0) return; log.info("Upgrading " + nodesToUpgrade.size() + " nodes of type " + type + " to OS version " + version); diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java index ebb64d650f1..477319a8bbb 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java @@ -12,6 +12,7 @@ import java.util.Comparator; import java.util.List; import java.util.Optional; import java.util.function.Supplier; +import java.util.stream.Collectors; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -75,8 +76,11 @@ public class OsVersionsTest { tester.makeReadyNodes(totalNodes, "default", NodeType.host); Supplier<NodeList> hostNodes = () -> tester.nodeRepository().list().nodeType(NodeType.host); - // Some nodes have reported current version - setCurrentVersion(hostNodes.get().asList().subList(0, 2), Version.fromString("7.0")); + // 5 nodes have no version. The other 15 are spread across different versions + var hostNodesList = hostNodes.get().asList(); + for (int i = totalNodes - maxActiveUpgrades - 1; i >= 0; i--) { + setCurrentVersion(List.of(hostNodesList.get(i)), new Version(7, 0, i)); + } // Set target var version1 = Version.fromString("7.1"); @@ -86,20 +90,28 @@ public class OsVersionsTest { // Activate target for (int i = 0; i < totalNodes; i += maxActiveUpgrades) { versions.setActive(NodeType.host, true); - var nodesUpgrading = hostNodes.get().changingOsVersion(); + var nodes = hostNodes.get(); + var nodesUpgrading = nodes.changingOsVersion(); assertEquals("Target is changed for a subset of nodes", maxActiveUpgrades, nodesUpgrading.size()); assertEquals("Wanted version is set for nodes upgrading", version1, nodesUpgrading.stream() .map(node -> node.status().osVersion().wanted().get()) .min(Comparator.naturalOrder()).get()); + var nodesOnLowestVersion = nodes.asList().stream() + .sorted(Comparator.comparing(node -> node.status().osVersion().current().orElse(Version.emptyVersion))) + .collect(Collectors.toList()) + .subList(0, maxActiveUpgrades); + assertEquals("Nodes on lowest version are told to upgrade", + nodesUpgrading.asList(), nodesOnLowestVersion); completeUpgradeOf(nodesUpgrading.asList()); } // Activating again after all nodes have upgraded does nothing versions.setActive(NodeType.host, true); - assertEquals(version1, hostNodes.get().stream() - .map(n -> n.status().osVersion().current().get()) - .min(Comparator.naturalOrder()).get()); + assertEquals("All nodes upgraded", version1, + hostNodes.get().stream() + .map(n -> n.status().osVersion().current().get()) + .min(Comparator.naturalOrder()).get()); } private void setCurrentVersion(List<Node> nodes, Version currentVersion) { diff --git a/searchlib/src/vespa/searchlib/common/bitvector.cpp b/searchlib/src/vespa/searchlib/common/bitvector.cpp index bd6e677f8d4..e28ebe6682f 100644 --- a/searchlib/src/vespa/searchlib/common/bitvector.cpp +++ b/searchlib/src/vespa/searchlib/common/bitvector.cpp @@ -136,23 +136,6 @@ BitVector::count() const } BitVector::Index -BitVector::internalCount(const Word *tarr, size_t sz) -{ - Index count(0); - size_t i(0); - for (; (i + 3) < sz; i += 4) { - count += Optimized::popCount(tarr[i + 0]) + - Optimized::popCount(tarr[i + 1]) + - Optimized::popCount(tarr[i + 2]) + - Optimized::popCount(tarr[i + 3]); - } - for (; i < sz; i++) { - count += Optimized::popCount(tarr[i]); - } - return count; -} - -BitVector::Index BitVector::countInterval(Index start, Index end) const { if (start >= end) return 0; @@ -182,7 +165,7 @@ BitVector::countInterval(Index start, Index end) const ++endw; } if (startw < endw) { - res += internalCount(bitValues + startw, endw - startw); + res += IAccelrated::getAccelrator()->populationCount(bitValues + startw, endw - startw); } if (partialEnd) { res += Optimized::popCount(bitValues[endw] & ~endBits(last)); diff --git a/searchlib/src/vespa/searchlib/common/bitvector.h b/searchlib/src/vespa/searchlib/common/bitvector.h index e058f0d3f78..98e8c9adad3 100644 --- a/searchlib/src/vespa/searchlib/common/bitvector.h +++ b/searchlib/src/vespa/searchlib/common/bitvector.h @@ -297,7 +297,6 @@ private: } } VESPA_DLL_LOCAL void repairEnds(); - VESPA_DLL_LOCAL static Index internalCount(const Word *tarr, size_t sz); Index count() const; bool hasTrueBitsInternal() const; template <typename FunctionType, typename WordConverter> diff --git a/vespalib/src/vespa/vespalib/hwaccelrated/avx.cpp b/vespalib/src/vespa/vespalib/hwaccelrated/avx.cpp index 14abb93d8d0..39ea0d2d73b 100644 --- a/vespalib/src/vespa/vespalib/hwaccelrated/avx.cpp +++ b/vespalib/src/vespa/vespalib/hwaccelrated/avx.cpp @@ -17,4 +17,9 @@ AvxAccelrator::dotProduct(const double * af, const double * bf, size_t sz) const return avx::dotProductSelectAlignment<double, 32>(af, bf, sz); } +size_t +AvxAccelrator::populationCount(const uint64_t *a, size_t sz) const { + return helper::populationCount(a, sz); +} + } diff --git a/vespalib/src/vespa/vespalib/hwaccelrated/avx.h b/vespalib/src/vespa/vespalib/hwaccelrated/avx.h index ffbe0b8d27f..624531a9ca5 100644 --- a/vespalib/src/vespa/vespalib/hwaccelrated/avx.h +++ b/vespalib/src/vespa/vespalib/hwaccelrated/avx.h @@ -14,6 +14,7 @@ class AvxAccelrator : public Sse2Accelrator public: float dotProduct(const float * a, const float * b, size_t sz) const override; double dotProduct(const double * a, const double * b, size_t sz) const override; + size_t populationCount(const uint64_t *a, size_t sz) const override; }; } diff --git a/vespalib/src/vespa/vespalib/hwaccelrated/avx2.cpp b/vespalib/src/vespa/vespalib/hwaccelrated/avx2.cpp index 4c4e53e88db..ea8a3ead538 100644 --- a/vespalib/src/vespa/vespalib/hwaccelrated/avx2.cpp +++ b/vespalib/src/vespa/vespalib/hwaccelrated/avx2.cpp @@ -17,4 +17,9 @@ Avx2Accelrator::dotProduct(const double * af, const double * bf, size_t sz) cons return avx::dotProductSelectAlignment<double, 32>(af, bf, sz); } +size_t +Avx2Accelrator::populationCount(const uint64_t *a, size_t sz) const { + return helper::populationCount(a, sz); +} + } diff --git a/vespalib/src/vespa/vespalib/hwaccelrated/avx2.h b/vespalib/src/vespa/vespalib/hwaccelrated/avx2.h index f20068c6478..cf91bc81cfd 100644 --- a/vespalib/src/vespa/vespalib/hwaccelrated/avx2.h +++ b/vespalib/src/vespa/vespalib/hwaccelrated/avx2.h @@ -14,6 +14,7 @@ class Avx2Accelrator : public AvxAccelrator public: float dotProduct(const float * a, const float * b, size_t sz) const override; double dotProduct(const double * a, const double * b, size_t sz) const override; + size_t populationCount(const uint64_t *a, size_t sz) const override; }; } diff --git a/vespalib/src/vespa/vespalib/hwaccelrated/avx512.cpp b/vespalib/src/vespa/vespalib/hwaccelrated/avx512.cpp index 4d21c9358ec..1abf6b270cf 100644 --- a/vespalib/src/vespa/vespalib/hwaccelrated/avx512.cpp +++ b/vespalib/src/vespa/vespalib/hwaccelrated/avx512.cpp @@ -17,4 +17,9 @@ Avx512Accelrator::dotProduct(const double * af, const double * bf, size_t sz) co return avx::dotProductSelectAlignment<double, 64>(af, bf, sz); } +size_t +Avx512Accelrator::populationCount(const uint64_t *a, size_t sz) const { + return helper::populationCount(a, sz); +} + } diff --git a/vespalib/src/vespa/vespalib/hwaccelrated/avx512.h b/vespalib/src/vespa/vespalib/hwaccelrated/avx512.h index 5807aeeee57..eac8c96832b 100644 --- a/vespalib/src/vespa/vespalib/hwaccelrated/avx512.h +++ b/vespalib/src/vespa/vespalib/hwaccelrated/avx512.h @@ -14,6 +14,7 @@ class Avx512Accelrator : public Avx2Accelrator public: float dotProduct(const float * a, const float * b, size_t sz) const override; double dotProduct(const double * a, const double * b, size_t sz) const override; + size_t populationCount(const uint64_t *a, size_t sz) const override; }; } diff --git a/vespalib/src/vespa/vespalib/hwaccelrated/avxprivate.hpp b/vespalib/src/vespa/vespalib/hwaccelrated/avxprivate.hpp index 2db7ebfd8fd..9e6a6d8817f 100644 --- a/vespalib/src/vespa/vespalib/hwaccelrated/avxprivate.hpp +++ b/vespalib/src/vespa/vespalib/hwaccelrated/avxprivate.hpp @@ -2,6 +2,7 @@ #pragma once +#include "private_helpers.hpp" #include <vespa/fastos/dynamiclibrary.h> #include <cstring> diff --git a/vespalib/src/vespa/vespalib/hwaccelrated/generic.cpp b/vespalib/src/vespa/vespalib/hwaccelrated/generic.cpp index d70071525c6..b70ebb4051a 100644 --- a/vespalib/src/vespa/vespalib/hwaccelrated/generic.cpp +++ b/vespalib/src/vespa/vespalib/hwaccelrated/generic.cpp @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "generic.h" +#include "private_helpers.hpp" namespace vespalib::hwaccelrated { @@ -124,4 +125,9 @@ GenericAccelrator::notBit(void * aOrg, size_t bytes) const } } +size_t +GenericAccelrator::populationCount(const uint64_t *a, size_t sz) const { + return helper::populationCount(a, sz); +} + } diff --git a/vespalib/src/vespa/vespalib/hwaccelrated/generic.h b/vespalib/src/vespa/vespalib/hwaccelrated/generic.h index f9aab3ae845..d76d0728bdd 100644 --- a/vespalib/src/vespa/vespalib/hwaccelrated/generic.h +++ b/vespalib/src/vespa/vespalib/hwaccelrated/generic.h @@ -22,6 +22,7 @@ public: void andBit(void * a, const void * b, size_t bytes) const override; void andNotBit(void * a, const void * b, size_t bytes) const override; void notBit(void * a, size_t bytes) const override; + size_t populationCount(const uint64_t *a, size_t sz) const override; }; } diff --git a/vespalib/src/vespa/vespalib/hwaccelrated/iaccelrated.cpp b/vespalib/src/vespa/vespalib/hwaccelrated/iaccelrated.cpp index aae277b48d8..4006897dce5 100644 --- a/vespalib/src/vespa/vespalib/hwaccelrated/iaccelrated.cpp +++ b/vespalib/src/vespa/vespalib/hwaccelrated/iaccelrated.cpp @@ -6,6 +6,7 @@ #include "avx.h" #include "avx2.h" #include "avx512.h" +#include <vespa/vespalib/util/memory.h> #include <vespa/log/log.h> LOG_SETUP(".vespalib.hwaccelrated"); @@ -22,27 +23,27 @@ public: class GenericFactory :public Factory{ public: - IAccelrated::UP create() const override { return IAccelrated::UP(new GenericAccelrator()); } + IAccelrated::UP create() const override { return std::make_unique<GenericAccelrator>(); } }; class Sse2Factory :public Factory{ public: - IAccelrated::UP create() const override { return IAccelrated::UP(new Sse2Accelrator()); } + IAccelrated::UP create() const override { return std::make_unique<Sse2Accelrator>(); } }; class AvxFactory :public Factory{ public: - IAccelrated::UP create() const override { return IAccelrated::UP(new AvxAccelrator()); } + IAccelrated::UP create() const override { return std::make_unique<AvxAccelrator>(); } }; class Avx2Factory :public Factory{ public: - IAccelrated::UP create() const override { return IAccelrated::UP(new Avx2Accelrator()); } + IAccelrated::UP create() const override { return std::make_unique<Avx2Accelrator>(); } }; class Avx512Factory :public Factory{ public: - IAccelrated::UP create() const override { return IAccelrated::UP(new Avx512Accelrator()); } + IAccelrated::UP create() const override { return std::make_unique<Avx512Accelrator>(); } }; template<typename T> @@ -67,6 +68,23 @@ void verifyAccelrator(const IAccelrated & accel) delete [] b; } +void verifyPopulationCount(const IAccelrated & accel) +{ + const uint64_t words[7] = {0x123456789abcdef0L, // 32 + 0x0000000000000000L, // 0 + 0x8000000000000000L, // 1 + 0xdeadbeefbeefdeadUL, // 48 + 0x5555555555555555L, // 32 + 0x00000000000000001, // 1 + 0xffffffffffffffff}; // 64 + constexpr size_t expected = 32 + 0 + 1 + 48 + 32 + 1 + 64; + size_t hwComputedPopulationCount = accel.populationCount(words, VESPA_NELEMS(words)); + if (hwComputedPopulationCount != expected) { + fprintf(stderr, "Accelrator is not computing populationCount correctly.Expected %zu, computed %zu\n", expected, hwComputedPopulationCount); + LOG_ABORT("should not be reached"); + } +} + class RuntimeVerificator { public: @@ -79,7 +97,8 @@ RuntimeVerificator::RuntimeVerificator() verifyAccelrator<float>(generic); verifyAccelrator<double>(generic); verifyAccelrator<int32_t>(generic); - verifyAccelrator<int64_t>(generic); + verifyAccelrator<int64_t>(generic); + verifyPopulationCount(generic); IAccelrated::UP thisCpu(IAccelrated::getAccelrator()); verifyAccelrator<float>(*thisCpu); diff --git a/vespalib/src/vespa/vespalib/hwaccelrated/iaccelrated.h b/vespalib/src/vespa/vespalib/hwaccelrated/iaccelrated.h index aae60279d06..4031169c44d 100644 --- a/vespalib/src/vespa/vespalib/hwaccelrated/iaccelrated.h +++ b/vespalib/src/vespa/vespalib/hwaccelrated/iaccelrated.h @@ -26,6 +26,7 @@ public: virtual void andBit(void * a, const void * b, size_t bytes) const = 0; virtual void andNotBit(void * a, const void * b, size_t bytes) const = 0; virtual void notBit(void * a, size_t bytes) const = 0; + virtual size_t populationCount(const uint64_t *a, size_t sz) const = 0; static IAccelrated::UP getAccelrator() __attribute__((noinline)); }; diff --git a/vespalib/src/vespa/vespalib/hwaccelrated/private_helpers.hpp b/vespalib/src/vespa/vespalib/hwaccelrated/private_helpers.hpp new file mode 100644 index 00000000000..8eba313d5f1 --- /dev/null +++ b/vespalib/src/vespa/vespalib/hwaccelrated/private_helpers.hpp @@ -0,0 +1,27 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include <vespa/vespalib/util/optimized.h> + +namespace vespalib::hwaccelrated::helper { +namespace { + +inline size_t +populationCount(const uint64_t *a, size_t sz) { + size_t count(0); + size_t i(0); + for (; (i + 3) < sz; i += 4) { + count += Optimized::popCount(a[i + 0]) + + Optimized::popCount(a[i + 1]) + + Optimized::popCount(a[i + 2]) + + Optimized::popCount(a[i + 3]); + } + for (; i < sz; i++) { + count += Optimized::popCount(a[i]); + } + return count; +} + +} +}
\ No newline at end of file diff --git a/vespalib/src/vespa/vespalib/hwaccelrated/sse2.cpp b/vespalib/src/vespa/vespalib/hwaccelrated/sse2.cpp index f135de52e5a..a0f584f8a9f 100644 --- a/vespalib/src/vespa/vespalib/hwaccelrated/sse2.cpp +++ b/vespalib/src/vespa/vespalib/hwaccelrated/sse2.cpp @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "sse2.h" +#include "private_helpers.hpp" namespace vespalib::hwaccelrated { @@ -76,4 +77,9 @@ Sse2Accelrator::dotProduct(const double * af, const double * bf, size_t sz) cons return sum; } +size_t +Sse2Accelrator::populationCount(const uint64_t *a, size_t sz) const { + return helper::populationCount(a, sz); +} + } diff --git a/vespalib/src/vespa/vespalib/hwaccelrated/sse2.h b/vespalib/src/vespa/vespalib/hwaccelrated/sse2.h index a539aa44b03..d0fbefe5f03 100644 --- a/vespalib/src/vespa/vespalib/hwaccelrated/sse2.h +++ b/vespalib/src/vespa/vespalib/hwaccelrated/sse2.h @@ -14,6 +14,8 @@ class Sse2Accelrator : public GenericAccelrator public: float dotProduct(const float * a, const float * b, size_t sz) const override; double dotProduct(const double * a, const double * b, size_t sz) const override; + + size_t populationCount(const uint64_t *a, size_t sz) const override; }; } |