Compare commits

...

5 Commits

Author SHA1 Message Date
Giulio Eulisse
2f416c9c1e
Merge 602807e6f9 into dcea48fcee 2025-06-13 10:59:26 +02:00
Dennis Klein
dcea48fcee
fix: parse errors
```
/test/memory_resources/_memory_resources.cxx: In member function ‘virtual void {anonymous}::MemoryResources_allocator_Test::TestBody()’:
/test/memory_resources/_memory_resources.cxx:104:12: error: parse error in template argument list
  104 |     config.SetProperty<string>("session", to_string(session));
      |            ^~~~~~~~~~~~~~~~~~~
/test/memory_resources/_memory_resources.cxx:104:31: error: no matching function for call to ‘fair::mq::ProgOptions::SetProperty<<expression error> >(const char [8], std::string)’
  104 |     config.SetProperty<string>("session", to_string(session));
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/dklein/projects/FairMQ2/test/memory_resources/_memory_resources.cxx:11:
/fairmq/ProgOptions.h:269:6: note: candidate: ‘template<class T> void fair::mq::ProgOptions::SetProperty(const std::string&, T)’
  269 | void fair::mq::ProgOptions::SetProperty(const std::string& key, T val)
      |      ^~~~
/fairmq/ProgOptions.h:269:6: note:   template argument deduction/substitution failed:
/test/memory_resources/_memory_resources.cxx:104:31: error: template argument 1 is invalid
  104 |     config.SetProperty<string>("session", to_string(session));
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/test/memory_resources/_memory_resources.cxx: In member function ‘virtual void {anonymous}::MemoryResources_getMessage_Test::TestBody()’:
/test/memory_resources/_memory_resources.cxx:132:12: error: parse error in template argument list
  132 |     config.SetProperty<string>("session", to_string(session));
      |            ^~~~~~~~~~~~~~~~~~~
/test/memory_resources/_memory_resources.cxx:132:31: error: no matching function for call to ‘fair::mq::ProgOptions::SetProperty<<expression error> >(const char [8], std::string)’
  132 |     config.SetProperty<string>("session", to_string(session));
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/fairmq/ProgOptions.h:269:6: note: candidate: ‘template<class T> void fair::mq::ProgOptions::SetProperty(const std::string&, T)’
  269 | void fair::mq::ProgOptions::SetProperty(const std::string& key, T val)
      |      ^~~~
/fairmq/ProgOptions.h:269:6: note:   template argument deduction/substitution failed:
/test/memory_resources/_memory_resources.cxx:132:31: error: template argument 1 is invalid
  132 |     config.SetProperty<string>("session", to_string(session));
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
2025-06-13 08:17:53 +02:00
Giulio Eulisse
67dcf77a7f De-boostify: use std::pmr from C++17 2025-06-13 08:02:06 +02:00
Giulio Eulisse
602807e6f9 Introduce a SmallVector Container 2024-05-23 15:10:06 +02:00
Giulio Eulisse
a461bd0ae7 Hide actual container from the API 2024-05-23 15:10:06 +02:00
6 changed files with 1487 additions and 10 deletions

View File

@ -55,6 +55,7 @@ if(BUILD_FAIRMQ)
ProgOptionsFwd.h
Properties.h
PropertyOutput.h
SmallVector.h
Socket.h
StateMachine.h
States.h
@ -127,6 +128,7 @@ if(BUILD_FAIRMQ)
PluginServices.cxx
ProgOptions.cxx
Properties.cxx
SmallVector.cxx
StateMachine.cxx
States.cxx
SuboptParser.cxx

View File

@ -17,7 +17,7 @@
#include <boost/container/container_fwd.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/container/pmr/memory_resource.hpp>
#include <memory_resource>
#include <cstring>
#include <fairmq/Message.h>
#include <stdexcept>
@ -27,7 +27,7 @@ namespace fair::mq {
class TransportFactory;
using byte = unsigned char;
namespace pmr = boost::container::pmr;
namespace pmr = std::pmr;
/// All FairMQ related memory resources need to inherit from this interface
/// class for the

View File

@ -11,6 +11,7 @@
#include <algorithm> // std::move
#include <fairmq/Message.h> // fair::mq::MessagePtr
#include <fairmq/SmallVector.h>
#include <iterator> // std::back_inserter
#include <utility> // std::move, std::forward
#include <vector> // std::vector
@ -21,7 +22,7 @@ namespace fair::mq {
/// Message, used for sending multi-part messages
struct Parts
{
using container = std::vector<MessagePtr>;
using container = fair::llvm_copy::SmallVector<MessagePtr, 8>;
using size_type = container::size_type;
using reference = container::reference;
using const_reference = container::const_reference;
@ -71,9 +72,9 @@ struct Parts
// const_reference operator[](size_type index) const { return fParts[index]; }
[[deprecated("Redundant, dereference at call site e.g. '*(parts.At(index))' instead.")]]
Message& AtRef(size_type index) { return *(fParts.at(index)); }
reference At(size_type index) { return fParts.at(index); }
const_reference At(size_type index) const { return fParts.at(index); }
Message& AtRef(size_type index) { return *(fParts[index]); }
reference At(size_type index) { return fParts[index]; }
const_reference At(size_type index) const { return fParts[index]; }
size_type Size() const noexcept { return fParts.size(); }
bool Empty() const noexcept { return fParts.empty(); }
@ -82,10 +83,10 @@ struct Parts
// range access
iterator begin() noexcept { return fParts.begin(); }
const_iterator begin() const noexcept { return fParts.begin(); }
const_iterator cbegin() const noexcept { return fParts.cbegin(); }
const_iterator cbegin() const noexcept { return fParts.begin(); }
iterator end() noexcept { return fParts.end(); }
const_iterator end() const noexcept { return fParts.end(); }
const_iterator cend() const noexcept { return fParts.cend(); }
const_iterator cend() const noexcept { return fParts.end(); }
container fParts{};
};

120
fairmq/SmallVector.cxx Normal file
View File

@ -0,0 +1,120 @@
//===- llvm/ADT/SmallVector.cpp - 'Normally small' vectors ----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the SmallVector class.
//
//===----------------------------------------------------------------------===//
#include <SmallVector.h>
//#include "llvm/Support/MemAlloc.h"
#include <cstdint>
using namespace fair::llvm_copy;
// Check that no bytes are wasted and everything is well-aligned.
namespace {
struct Struct16B {
alignas(16) void *X;
};
struct Struct32B {
alignas(32) void *X;
};
}
static_assert(sizeof(SmallVector<void *, 0>) ==
sizeof(unsigned) * 2 + sizeof(void *),
"wasted space in SmallVector size 0");
static_assert(alignof(SmallVector<Struct16B, 0>) >= alignof(Struct16B),
"wrong alignment for 16-byte aligned T");
static_assert(alignof(SmallVector<Struct32B, 0>) >= alignof(Struct32B),
"wrong alignment for 32-byte aligned T");
static_assert(sizeof(SmallVector<Struct16B, 0>) >= alignof(Struct16B),
"missing padding for 16-byte aligned T");
static_assert(sizeof(SmallVector<Struct32B, 0>) >= alignof(Struct32B),
"missing padding for 32-byte aligned T");
static_assert(sizeof(SmallVector<void *, 1>) ==
sizeof(unsigned) * 2 + sizeof(void *) * 2,
"wasted space in SmallVector size 1");
static_assert(sizeof(SmallVector<char, 0>) ==
sizeof(void *) * 2 + sizeof(void *),
"1 byte elements have word-sized type for size and capacity");
// Note: Moving this function into the header may cause performance regression.
template <class Size_T>
static size_t getNewCapacity(size_t MinSize, size_t , size_t OldCapacity) {
constexpr size_t MaxSize = std::numeric_limits<Size_T>::max();
// In theory 2*capacity can overflow if the capacity is 64 bit, but the
// original capacity would never be large enough for this to be a problem.
size_t NewCapacity = 2 * OldCapacity + 1; // Always grow.
return std::clamp(NewCapacity, MinSize, MaxSize);
}
template <class Size_T>
void *SmallVectorBase<Size_T>::replaceAllocation(void *NewElts, size_t TSize,
size_t NewCapacity,
size_t VSize) {
void *NewEltsReplace = malloc(NewCapacity * TSize);
if (VSize)
memcpy(NewEltsReplace, NewElts, VSize * TSize);
free(NewElts);
return NewEltsReplace;
}
// Note: Moving this function into the header may cause performance regression.
template <class Size_T>
void *SmallVectorBase<Size_T>::mallocForGrow(void *FirstEl, size_t MinSize,
size_t TSize,
size_t &NewCapacity) {
NewCapacity = getNewCapacity<Size_T>(MinSize, TSize, this->capacity());
// Even if capacity is not 0 now, if the vector was originally created with
// capacity 0, it's possible for the malloc to return FirstEl.
void *NewElts = malloc(NewCapacity * TSize);
if (NewElts == FirstEl)
NewElts = replaceAllocation(NewElts, TSize, NewCapacity);
return NewElts;
}
// Note: Moving this function into the header may cause performance regression.
template <class Size_T>
void SmallVectorBase<Size_T>::grow_pod(void *FirstEl, size_t MinSize,
size_t TSize) {
size_t NewCapacity = getNewCapacity<Size_T>(MinSize, TSize, this->capacity());
void *NewElts;
if (BeginX == FirstEl) {
NewElts = malloc(NewCapacity * TSize);
if (NewElts == FirstEl)
NewElts = replaceAllocation(NewElts, TSize, NewCapacity);
// Copy the elements over. No need to run dtors on PODs.
memcpy(NewElts, this->BeginX, size() * TSize);
} else {
// If this wasn't grown from the inline copy, grow the allocated space.
NewElts = realloc(this->BeginX, NewCapacity * TSize);
if (NewElts == FirstEl)
NewElts = replaceAllocation(NewElts, TSize, NewCapacity, size());
}
this->set_allocation_range(NewElts, NewCapacity);
}
template class fair::llvm_copy::SmallVectorBase<uint32_t>;
// Disable the uint64_t instantiation for 32-bit builds.
// Both uint32_t and uint64_t instantiations are needed for 64-bit builds.
// This instantiation will never be used in 32-bit builds, and will cause
// warnings when sizeof(Size_T) > sizeof(size_t).
#if SIZE_MAX > UINT32_MAX
template class fair::llvm_copy::SmallVectorBase<uint64_t>;
// Assertions to ensure this #if stays in sync with SmallVectorSizeType.
static_assert(sizeof(SmallVectorSizeType<char>) == sizeof(uint64_t),
"Expected SmallVectorBase<uint64_t> variant to be in use.");
#else
static_assert(sizeof(SmallVectorSizeType<char>) == sizeof(uint32_t),
"Expected SmallVectorBase<uint32_t> variant to be in use.");
#endif

1353
fairmq/SmallVector.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,7 @@
#include <gtest/gtest.h>
#include <cstring>
#include <string>
#include <vector>
namespace
@ -101,7 +102,7 @@ TEST(MemoryResources, allocator)
size_t session{tools::UuidHash()};
ProgOptions config;
config.SetProperty<string>("session", to_string(session));
config.SetProperty<std::string>("session", to_string(session));
FactoryType factoryZMQ = TransportFactory::CreateTransportFactory("zeromq", fair::mq::tools::Uuid(), &config);
@ -129,7 +130,7 @@ TEST(MemoryResources, getMessage)
size_t session{tools::UuidHash()};
ProgOptions config;
config.SetProperty<string>("session", to_string(session));
config.SetProperty<std::string>("session", to_string(session));
config.SetProperty<bool>("shm-monitor", true);
FactoryType factoryZMQ = TransportFactory::CreateTransportFactory("zeromq", fair::mq::tools::Uuid(), &config);