File: pluto_test_alignment.cc

package info (click to toggle)
metview 5.26.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 614,356 kB
  • sloc: cpp: 560,586; ansic: 44,641; xml: 19,933; f90: 17,984; sh: 7,454; python: 5,565; yacc: 2,318; lex: 1,372; perl: 701; makefile: 88
file content (108 lines) | stat: -rw-r--r-- 3,650 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

/*
 * (C) Copyright 2024- ECMWF.
 *
 * This software is licensed under the terms of the Apache Licence Version 2.0
 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
 * In applying this licence, ECMWF does not waive the privileges and immunities
 * granted to it by virtue of its status as an intergovernmental organisation
 * nor does it submit to any jurisdiction.
 */

#include "pluto_testing.h"

#include <cstddef>
#include <iostream>
#include <string>
#include <limits>
#include <vector>

#include "pluto/pluto.h"

struct alignas(32) Vec3D_alignment32 {
    double x;
    double y;
    double z;


    static std::string type() { return "Vec3D_alignment32"; }
};

struct Vec3D {
    double x;
    double y;
    double z;

    static std::string type() { return "Vec3D"; }
};

std::size_t get_alignment(void* ptr) {
    for (std::size_t alignment : {2056,1024,512,256,128,64,32,16,8,4}) {
        if (pluto::is_aligned(ptr, alignment)) {
            return alignment;
        }
    }
    return 0;
}


template<typename T>
struct Allocated {
    Allocated(const pluto::allocator<T>& alloc): alloc_(alloc) {
        data = alloc_.allocate(1);
    }
    ~Allocated() {
        alloc_.deallocate(data, 1);
    }
    T* data;
    pluto::allocator<T> alloc_;
};

template<typename Vec>
void run_case() {
    std::cerr << "Case: vector<" << Vec::type() << ">" << std::endl;
    int N = 5;

    std::vector<Vec, pluto::host::allocator<Vec>> vec(N);

    // We expect the pluto::host::allocator to use pluto::host_resource, which aligns to pluto::default_alignment
    EXPECT( pluto::is_aligned(vec.data(), pluto::default_alignment()) );

    std::size_t alignment = std::numeric_limits<std::size_t>::max();
    for (auto& element: vec) {
        EXPECT( pluto::is_aligned(&element, alignof(Vec)) );
        alignment = std::min(alignment, get_alignment(&element));
        std::cerr << "  element alignment = " << get_alignment(&element) << std::endl;
    }
    std::cerr << "  minimum alignment = " << alignment << std::endl;
}

int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) {
    std::cerr << "TEST begin" << std::endl;

    static_assert(alignof(Vec3D_alignment32) == 32);
    run_case<Vec3D>();
    run_case<Vec3D_alignment32>();

    {
        auto test = [](const std::string& alloc_str, const pluto::allocator<int>& allocator, std::size_t expected_alignment) {
            std::cerr << "Case: alignment of " << alloc_str << std::endl;
            Allocated<int> allocated(allocator);
            EXPECT(pluto::is_aligned(allocated.data, expected_alignment));
        };
        #define TEST(allocator, expected_alignment) test(#allocator, allocator, expected_alignment);
        TEST(pluto::allocator<int>(),         alignof(int));               // by default uses pluto::new_delete_resource()
        TEST(pluto::host::allocator<int>(),   pluto::default_alignment()); // by default uses pluto::host_resource()
        TEST(pluto::device::allocator<int>(), pluto::default_alignment()); // by default uses pluto::device_resource()

        TEST(pluto::new_delete_resource(),      alignof(double));
        TEST(pluto::host_resource(),            pluto::default_alignment());
        TEST(pluto::device_resource(),          pluto::default_alignment());
        TEST(pluto::managed_resource(),         pluto::default_alignment());
        TEST(pluto::host_pool_resource(),       pluto::default_alignment());
        TEST(pluto::device_pool_resource(),     pluto::default_alignment());
        TEST(pluto::managed_pool_resource(),    pluto::default_alignment());
    }

    return pluto_testing_return();
}