Skip to content
This repository was archived by the owner on Apr 23, 2021. It is now read-only.

Commit 5ce428f

Browse files
committed
add vector memref support for mlir-cpu-runner func return
- allow mlir-cpu-runner to execute functions that return memrefs with vector of f32 in addition to just those with f32. - align memref's being allocated from mlir-cpu-runner (for input/output args of entry point function) to memref element size boundaries. Signed-off-by: Uday Bondhugula <[email protected]>
1 parent 4aa0a85 commit 5ce428f

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

lib/ExecutionEngine/MemRefUtils.cpp

+18-4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include "llvm/Support/Error.h"
2929
#include <numeric>
30+
#include <stdlib.h>
3031

3132
using namespace mlir;
3233

@@ -45,12 +46,14 @@ allocMemRefDescriptor(Type type, bool allocateData = true,
4546
return make_string_error("memref with dynamic shapes not supported");
4647

4748
auto elementType = memRefType.getElementType();
48-
if (!elementType.isF32())
49+
VectorType vectorType = elementType.dyn_cast<VectorType>();
50+
if (!elementType.isF32() &&
51+
!(vectorType && vectorType.getElementType().isF32()))
4952
return make_string_error(
50-
"memref with element other than f32 not supported");
53+
"memref with element other than f32 or vector of f32 not supported");
5154

5255
auto *descriptor =
53-
reinterpret_cast<StaticFloatMemRef *>(malloc(sizeof(StaticFloatMemRef)));
56+
static_cast<StaticFloatMemRef *>(malloc(sizeof(StaticFloatMemRef)));
5457
if (!allocateData) {
5558
descriptor->data = nullptr;
5659
return descriptor;
@@ -59,7 +62,18 @@ allocMemRefDescriptor(Type type, bool allocateData = true,
5962
auto shape = memRefType.getShape();
6063
int64_t size = std::accumulate(shape.begin(), shape.end(), 1,
6164
std::multiplies<int64_t>());
62-
descriptor->data = reinterpret_cast<float *>(malloc(sizeof(float) * size));
65+
// Align vector of f32 to the vector size boundary (to the closest greater
66+
// power of two if the former isn't a power of two).
67+
if (vectorType) {
68+
int64_t numElements = vectorType.getNumElements();
69+
size *= numElements;
70+
size_t alignment = llvm::PowerOf2Ceil(numElements * sizeof(float));
71+
posix_memalign(reinterpret_cast<void **>(&descriptor->data), alignment,
72+
size * sizeof(float));
73+
} else {
74+
descriptor->data = static_cast<float *>(malloc(sizeof(float) * size));
75+
}
76+
6377
for (int64_t i = 0; i < size; ++i) {
6478
descriptor->data[i] = initialValue;
6579
}

lib/Support/JitRunner.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ static void printOneMemRef(Type t, void *val) {
141141
auto shape = memRefType.getShape();
142142
int64_t size = std::accumulate(shape.begin(), shape.end(), 1,
143143
std::multiplies<int64_t>());
144+
if (auto vectorType = memRefType.getElementType().dyn_cast<VectorType>()) {
145+
size *= vectorType.getNumElements();
146+
}
147+
144148
for (int64_t i = 0; i < size; ++i) {
145149
llvm::outs() << reinterpret_cast<StaticFloatMemRef *>(val)->data[i] << ' ';
146150
}

test/mlir-cpu-runner/simple.mlir

+26
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// RUN: mlir-cpu-runner -e foo -init-value 1000 %s | FileCheck -check-prefix=NOMAIN %s
33
// RUN: mlir-cpu-runner %s -O3 | FileCheck %s
44
// RUN: mlir-cpu-runner -e affine -init-value 2.0 %s | FileCheck -check-prefix=AFFINE %s
5+
// RUN: mlir-cpu-runner -e bar -init-value 2.0 %s | FileCheck -check-prefix=BAR %s
6+
// RUN: mlir-cpu-runner -e large_vec_memref -init-value 2.0 %s | FileCheck -check-prefix=LARGE-VEC %s
57

68
// RUN: cp %s %t
79
// RUN: mlir-cpu-runner %t -dump-object-file | FileCheck %t
@@ -49,3 +51,27 @@ func @affine(%a : memref<32xf32>) -> memref<32xf32> {
4951
return %a : memref<32xf32>
5052
}
5153
// AFFINE: 4.2{{0+}}e+01
54+
55+
func @bar(%a : memref<16xvector<4xf32>>) -> memref<16xvector<4xf32>> {
56+
%c0 = constant 0 : index
57+
%c1 = constant 1 : index
58+
59+
%u = load %a[%c0] : memref<16xvector<4xf32>>
60+
%v = load %a[%c1] : memref<16xvector<4xf32>>
61+
%w = addf %u, %v : vector<4xf32>
62+
store %w, %a[%c0] : memref<16xvector<4xf32>>
63+
64+
return %a : memref<16xvector<4xf32>>
65+
}
66+
// BAR: 4.{{0+}}e+00 4.{{0+}}e+00 4.{{0+}}e+00 4.{{0+}}e+00 2.{{0+}}e+00
67+
// BAR-NEXT: 4.{{0+}}e+00 4.{{0+}}e+00 4.{{0+}}e+00 4.{{0+}}e+00 2.{{0+}}e+00
68+
69+
func @large_vec_memref(%arg2: memref<128x128xvector<8xf32>>) -> memref<128x128xvector<8xf32>> {
70+
%c0 = constant 0 : index
71+
%c127 = constant 127 : index
72+
%v = constant dense<42.0> : vector<8xf32>
73+
store %v, %arg2[%c0, %c0] : memref<128x128xvector<8xf32>>
74+
store %v, %arg2[%c127, %c127] : memref<128x128xvector<8xf32>>
75+
return %arg2 : memref<128x128xvector<8xf32>>
76+
}
77+
// LARGE-VEC: 4.200000e+01

0 commit comments

Comments
 (0)