xref: /llvm-project/flang/unittests/Evaluate/reshape.cpp (revision ffc67bb3602a6a9a4f886af362e1f2d7c9821570)
1 #include "testing.h"
2 #include "flang/Runtime/descriptor.h"
3 #include "flang/Runtime/transformational.h"
4 #include <cinttypes>
5 
6 using namespace Fortran::common;
7 using namespace Fortran::runtime;
8 
main()9 int main() {
10   static const SubscriptValue sourceExtent[]{2, 3, 4};
11   auto source{Descriptor::Create(TypeCategory::Integer, sizeof(std::int32_t),
12       nullptr, 3, sourceExtent, CFI_attribute_allocatable)};
13   source->Check();
14   MATCH(3, source->rank());
15   MATCH(sizeof(std::int32_t), source->ElementBytes());
16   TEST(source->IsAllocatable());
17   TEST(!source->IsPointer());
18   for (int j{0}; j < 3; ++j) {
19     source->GetDimension(j).SetBounds(1, sourceExtent[j]);
20   }
21   TEST(source->Allocate() == CFI_SUCCESS);
22   TEST(source->IsAllocated());
23   MATCH(2, source->GetDimension(0).Extent());
24   MATCH(3, source->GetDimension(1).Extent());
25   MATCH(4, source->GetDimension(2).Extent());
26   MATCH(24, source->Elements());
27   for (std::size_t j{0}; j < 24; ++j) {
28     *source->OffsetElement<std::int32_t>(j * sizeof(std::int32_t)) = j;
29   }
30 
31   static const std::int16_t shapeData[]{8, 4};
32   static const SubscriptValue shapeExtent{2};
33   auto shape{Descriptor::Create(TypeCategory::Integer,
34       static_cast<int>(sizeof shapeData[0]),
35       const_cast<void *>(reinterpret_cast<const void *>(shapeData)), 1,
36       &shapeExtent, CFI_attribute_pointer)};
37   shape->Check();
38   MATCH(1, shape->rank());
39   MATCH(2, shape->GetDimension(0).Extent());
40   TEST(shape->IsPointer());
41   TEST(!shape->IsAllocatable());
42 
43   StaticDescriptor<3> padDescriptor;
44   Descriptor &pad{padDescriptor.descriptor()};
45   static const std::int32_t padData[]{24, 25, 26, 27, 28, 29, 30, 31};
46   static const SubscriptValue padExtent[]{2, 2, 3};
47   pad.Establish(TypeCategory::Integer, static_cast<int>(sizeof padData[0]),
48       const_cast<void *>(reinterpret_cast<const void *>(padData)), 3, padExtent,
49       CFI_attribute_pointer);
50   padDescriptor.Check();
51   pad.Check();
52   MATCH(3, pad.rank());
53   MATCH(2, pad.GetDimension(0).Extent());
54   MATCH(2, pad.GetDimension(1).Extent());
55   MATCH(3, pad.GetDimension(2).Extent());
56   StaticDescriptor<1> orderDescriptor;
57   Descriptor &order{orderDescriptor.descriptor()};
58   static const std::int32_t orderData[]{1, 2};
59   static const SubscriptValue orderExtent[]{2};
60   order.Establish(TypeCategory::Integer, static_cast<int>(sizeof orderData[0]),
61       const_cast<void *>(reinterpret_cast<const void *>(orderData)), 1,
62       orderExtent, CFI_attribute_pointer);
63   orderDescriptor.Check();
64   order.Check();
65   MATCH(1, order.rank());
66   MATCH(2, order.GetDimension(0).Extent());
67 
68   auto result{Descriptor::Create(TypeCategory::Integer, sizeof(std::int32_t),
69       nullptr, 2, nullptr, CFI_attribute_allocatable)};
70   TEST(result.get() != nullptr);
71   RTNAME(Reshape)(*result, *source, *shape, &pad, &order, __FILE__, __LINE__);
72   result->Check();
73   MATCH(sizeof(std::int32_t), result->ElementBytes());
74   MATCH(2, result->rank());
75   TEST(result->type().IsInteger());
76   for (std::int32_t j{0}; j < 32; ++j) {
77     MATCH(j, *result->OffsetElement<std::int32_t>(j * sizeof(std::int32_t)));
78   }
79   for (std::int32_t j{0}; j < 32; ++j) {
80     SubscriptValue ss[2]{1 + (j % 8), 1 + (j / 8)};
81     MATCH(j, *result->Element<std::int32_t>(ss));
82   }
83 
84   return testing::Complete();
85 }
86