Skip to content

Commit

Permalink
Merge pull request #7 from UniStuttgart-VISUS/collector
Browse files Browse the repository at this point in the history
Collector fix
  • Loading branch information
crowbar27 authored Mar 11, 2023
2 parents f9cf6fb + 559822b commit 98f4cbb
Show file tree
Hide file tree
Showing 9 changed files with 359 additions and 71 deletions.
93 changes: 60 additions & 33 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,63 @@ schedules:
- master
always: true

pool:
vmImage: 'windows-2022'

variables:
buildPlatform: 'x64'
buildConfiguration: 'Release'
generator: 'Visual Studio 17 2022'

steps:
- task: NuGetToolInstaller@0

- task: CMake@1
displayName: 'CMake'
inputs:
workingDirectory: '_build'
cmakeArgs: .. -G"$(generator)" -A"$(buildPlatform)"

#- task: NuGetCommand@2
# inputs:
# restoreSolution: '$(solution)'

- task: VSBuild@1
displayName: 'Build'
inputs:
solution: '_build/*.sln'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'

- task: VSTest@2
displayName: 'Tests'
inputs:
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'

jobs:
- job: Windows

variables:
buildPlatform: 'x64'
buildConfiguration: 'Release'
generator: 'Visual Studio 17 2022'

pool:
vmImage: 'windows-2022'

steps:
- task: NuGetToolInstaller@0

- task: CMake@1
displayName: 'Configure'
inputs:
workingDirectory: '_build'
cmakeArgs: '.. -G"$(generator)" -A"$(buildPlatform)"'

#- task: NuGetCommand@2
# inputs:
# restoreSolution: '$(solution)'

- task: VSBuild@1
displayName: 'Build'
inputs:
solution: '_build/*.sln'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'

- task: VSTest@2
displayName: 'Tests'
inputs:
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'


- job: Linux

variables:
buildConfiguration: 'Release'
generator: 'Unix Makefiles'

pool:
vmImage: 'ubuntu-22.04'

steps:
- task: CMake@1
displayName: 'Configure'
inputs:
workingDirectory: '_build'
cmakeArgs: '.. -G"$(generator)" -DCMAKE_BUILD_TYPE="$(buildConfiguration)"'

- task: CMake@1
displayName: 'Build'
inputs:
workingDirectory: '_build'
cmakeArgs: '--build .'
42 changes: 32 additions & 10 deletions power_overwhelming/include/power_overwhelming/collector.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include <type_traits>
#include <vector>

#include "power_overwhelming/sensor.h"
#include "power_overwhelming/collector_settings.h"


namespace visus {
Expand All @@ -30,18 +30,32 @@ namespace power_overwhelming {

public:

/// <summary>
/// Creates a collector for all sensors that could be found and
/// instantiated on the machine.
/// </summary>
/// <param name="settings">The general settings for the collector,
/// including the sampling interval.</param>
/// <returns>A collector for all available sensors.</returns>
static collector for_all(const collector_settings& settings);

/// <summary>
/// Creates a collector for all sensors that could be found and
/// instantiated on the machne.
/// </summary>
/// <param name="output_path">The path where the collector should write
/// the output to.</param>
/// <param name="sampling_interval">The sampling interval for the sensors
/// in microseconds. This parameter defaults to 5000 microseconds.
/// </param>
/// in microseconds.</param>
/// <returns>A collector for all available sensors.</returns>
static collector for_all(const wchar_t *output_path,
const sensor::microseconds_type sampling_interval = 5000);
/// <exception std::invalid_argument">If <paramref name="output_path" />
/// is <c>nullptr</c>.</exception>
inline static collector for_all(const wchar_t *output_path,
const sensor::microseconds_type sampling_interval
= collector_settings::default_sampling_interval) {
return for_all(collector_settings().output_path(output_path)
.sampling_interval(sampling_interval));
}

/// <summary>
/// Create a collector for the configuration template generated by
Expand All @@ -65,23 +79,29 @@ namespace power_overwhelming {
/// <typeparam name="TSensorLists">The types of the lists of sensors,
/// which must be STL collection types (with <c>begin</c> and
/// <c>end</c>) or sensors.</typeparam>
/// <param name="settings">The general settings for the collector,
/// including the sampling interval.</param>
/// <param name="sensors">The lists of sensors.</param>
/// <returns></returns>
template<class... TSensorLists>
static collector from_sensor_lists(TSensorLists&&... sensors);
static collector from_sensor_lists(const collector_settings& settings,
TSensorLists&&... sensors);

/// <summary>
/// Initialise a new instance from the given compile-time list of
/// (possibly different kinds of) sensors.
/// </summary>
/// <typeparam name="TSensors>The types of the sensors to be used by
/// the collector.</typeparam>
/// <param name="settings">The general settings for the collector,
/// including the sampling interval.</param>
/// <param name="sensors">A compile-time list of sensors. The new
/// instance will take ownership of these sensors, ie they will be
/// disposed by moving them once the method returns.</param>
/// <returns>A new collector using the given sensors.</returns>
template<class... TSensors>
static collector from_sensors(TSensors&&... sensors);
static collector from_sensors(const collector_settings& settings,
TSensors&&... sensors);

/// <summary>
/// Creates a configuration file for all sensors currently attached to
Expand Down Expand Up @@ -183,12 +203,14 @@ namespace power_overwhelming {
TSensorList&& sensors);

/// <summary>
/// Creates a new collector that has no sensors, reserved space for the
/// given number of sensors.
/// Creates a new collector that has no sensors, but reserved space for
/// the given number of sensors.
/// </summary>
/// <param name="settings"></param>
/// <param name="capacity"></param>
/// <returns>A new collector without sensors.</returns>
static collector prepare(const std::size_t capacity);
static collector prepare(const collector_settings& settings,
const std::size_t capacity);

/// <summary>
/// Initialise a new instance.
Expand Down
16 changes: 9 additions & 7 deletions power_overwhelming/include/power_overwhelming/collector.inl
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@
template<class... TSensorLists>
visus::power_overwhelming::collector
visus::power_overwhelming::collector::from_sensor_lists(
TSensorLists&&... sensors) {
const collector_settings& settings, TSensorLists&&... sensors) {
std::array<std::vector<std::unique_ptr<sensor>>,
sizeof...(sensors)> instances = { move_to_heap(sensors)... };
typedef typename decltype(instances)::value_type sensor_type;

const auto cnt = std::accumulate(instances.begin(),
instances.end(), static_cast<std::size_t>(0),
[](const std::size_t s, const decltype(instances)::value_type& v) {
[](const std::size_t s, const sensor_type& v) {
return std::size(v) + s;
});

auto retval = collector::prepare(cnt);
auto retval = collector::prepare(settings, cnt);

for (auto& l : instances) {
for (auto& i : l) {
Expand All @@ -37,13 +38,14 @@ visus::power_overwhelming::collector::from_sensor_lists(
*/
template<class... TSensors>
visus::power_overwhelming::collector
visus::power_overwhelming::collector::from_sensors(TSensors&&... sensors) {
visus::power_overwhelming::collector::from_sensors(
const collector_settings& settings, TSensors&&... sensors) {
std::array<std::unique_ptr<sensor>, sizeof...(sensors)> instances = {
std::unique_ptr<sensor>(new typename std::decay<TSensors>::type(
std::move(sensors)))...
};

auto retval = collector::prepare(instances.size());
auto retval = collector::prepare(settings, instances.size());

for (auto& i : instances) {
// Note: We release this on purpose as the library and the calling code
Expand All @@ -69,8 +71,8 @@ visus::power_overwhelming::collector::move_to_heap(TSensorList&& sensors) {
retval.reserve(std::size(sensors));

std::transform(sensors.begin(), sensors.end(), std::back_inserter(retval),
[](typename sensor_type& s) {
return std::unique_ptr<sensor>(new typename sensor_type(std::move(s)));
[](sensor_type& s) {
return std::unique_ptr<sensor>(new sensor_type(std::move(s)));
});

return retval;
Expand Down
109 changes: 109 additions & 0 deletions power_overwhelming/include/power_overwhelming/collector_settings.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// <copyright file="collector_settings.h" company="Visualisierungsinstitut der Universität Stuttgart">
// Copyright © 2023 Visualisierungsinstitut der Universität Stuttgart. Alle Rechte vorbehalten.
// </copyright>
// <author>Christoph Müller</author>

#pragma once

#include <cinttypes>

#include "power_overwhelming/sensor.h"


namespace visus {
namespace power_overwhelming {

/// <summary>
/// Enapsulates the settings of a
/// <see cref="visus::power_overwhelming::collector" />.
/// </summary>
class POWER_OVERWHELMING_API collector_settings final {

public:

/// <summary>
/// The type used to specify sampling intervals in (microseconds).
/// </summary>
typedef sensor::microseconds_type sampling_interval_type;

/// <summary>
/// The default output path.
/// </summary>
static constexpr const wchar_t *default_output_path = L"output.csv";

/// <summary>
/// The default sampling interval of 5 milliseconds (or 5000
/// microseconds).
/// </summary>
static constexpr sampling_interval_type default_sampling_interval
= 5000;

/// <summary>
/// Initialises a new instance.
/// </summary>
/// <param name=""></param>
collector_settings(void);

/// <summary>
/// Clone <paramref name="rhs" />.
/// </summary>
/// <param name="rhs">The object to be cloned.</param>
collector_settings(const collector_settings& rhs);

/// <summary>
/// Finalises the instance.
/// </summary>
~collector_settings(void);

/// <summary>
/// Gets the path to the file where the collector should write its
/// output to.
/// </summary>
/// <returns>The path to the output file.</returns>
inline const wchar_t *output_path(void) const noexcept {
return this->_output_path;
}

/// <summary>
/// Sets the path to the file where the collector should write its
/// output to.
/// </summary>
/// <param name="path">The path to the output file.</param>
/// <returns><c>*this</c>.</returns>
/// <exception cref="std::invalid_argument">If
/// <paramref name="output_path" /> is <c>nullptr</c>.</exception>
collector_settings& output_path(const wchar_t *path);

/// <summary>
/// Gets the time interval in which the collector should sample the
/// sensors.
/// </summary>
/// <returns>The sampling interval.</returns>
inline sampling_interval_type sampling_interval(void) const noexcept {
return this->_sampling_interval;
}

/// <summary>
/// Sets the interval in which the collector should sample the sensors.
/// </summary>
/// <param name="interval">The sampling interval.</param>
/// <returns><c>*this</c>.</returns>
collector_settings& sampling_interval(
const sampling_interval_type interval);

/// <summary>
/// Assignment.
/// </summary>
/// <param name="rhs">The right hand side operand.</param>
/// <returns><c>*this</c>.</returns>
collector_settings& operator =(const collector_settings& rhs);

private:

wchar_t *_output_path;
sampling_interval_type _sampling_interval;

};

} /* namespace power_overwhelming */
} /* namespace visus */
23 changes: 6 additions & 17 deletions power_overwhelming/src/collector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,24 +78,11 @@ namespace detail {
* visus::power_overwhelming::collector::for_all
*/
visus::power_overwhelming::collector
visus::power_overwhelming::collector::for_all(const wchar_t *output_path,
const sensor::microseconds_type sampling_interval) {
if (output_path == nullptr) {
throw std::invalid_argument("The output path of a collector cannot be "
"null.");
}

visus::power_overwhelming::collector::for_all(
const collector_settings& settings) {
auto retval = collector(new detail::collector_impl());
retval._impl->apply(settings);
retval._impl->sensors = detail::get_all_sensors();
#if defined(_WIN32)
retval._impl->stream = std::wofstream(output_path, std::ofstream::trunc);
#else /* defined(_WIN32) */
auto p = convert_string<char>(output_path);
retval._impl->stream = std::wofstream(p, std::ofstream::trunc);
#endif /* defined(_WIN32) */
retval._impl->sampling_interval = std::chrono::microseconds(
sampling_interval);

return retval;
}

Expand Down Expand Up @@ -217,9 +204,11 @@ visus::power_overwhelming::collector::operator bool(void) const noexcept {
* visus::power_overwhelming::collector::prepare
*/
visus::power_overwhelming::collector
visus::power_overwhelming::collector::prepare(const std::size_t capacity) {
visus::power_overwhelming::collector::prepare(
const collector_settings& settings, const std::size_t capacity) {
auto retval = collector(new detail::collector_impl());
retval._impl->sensors.reserve(capacity);
retval._impl->apply(settings);
return retval;
}

Expand Down
Loading

0 comments on commit 98f4cbb

Please sign in to comment.