runJit a model with multiple results

Hello,
I’m trying to runJit with llvm backend from llvm dialect.
My model has no input and two outputs, 1x1x1x2xf32, 1x1x1x2xf32.

My code to invoke the execution engine is as follows, but it didn’t work.

mlir::OwningMemRef<float, 4> res1(*(vec_res_shape[0]), {}, res_init);
mlir::OwningMemRef<float, 4> res2(*(vec_res_shape[1]), {}, res_init);
auto invocationResult = engine->invoke("%self.1", &*res1, &*res2);

I also tried the following code, but it also didn’t work.

mlir::OwningMemRef<float, 4> res1(*(vec_res_shape[0]), {}, res_init);
mlir::OwningMemRef<float, 4> res2(*(vec_res_shape[1]), {}, res_init);

llvm::SmallVector<void *> res_argsArray;
res_argsArray.push_back(&res1);
res_argsArray.push_back(&res2);
auto invocationResult = engine->invoke("%self.1", res_argsArray);

LLVM dialects are as follows.

  llvm.func @"_mlir_ciface_%self.1"(%arg0: !llvm.ptr<struct<(struct<(ptr<f32>, ptr<f32>, i64, array<4 x i64>, array<4 x i64>)>, struct<(ptr<f32>, ptr<f32>, i64, array<4 x i64>, array<4 x i64>)>)>>) attributes {llvm.emit_c_interface} {
    %0 = llvm.call @"%self.1"() : () -> !llvm.struct<(struct<(ptr<f32>, ptr<f32>, i64, array<4 x i64>, array<4 x i64>)>, struct<(ptr<f32>, ptr<f32>, i64, array<4 x i64>, array<4 x i64>)>)>
    llvm.store %0, %arg0 : !llvm.ptr<struct<(struct<(ptr<f32>, ptr<f32>, i64, array<4 x i64>, array<4 x i64>)>, struct<(ptr<f32>, ptr<f32>, i64, array<4 x i64>, array<4 x i64>)>)>>
    llvm.return
  }

How can I pass containers for the two results?
Thank you so much.

Given the signature, you need to pass a pointer to a struct containing the two results as elements. Something like

struct Result {
  mlir::OwningMemRef<float, 4> first;
  mlir::OwningMemRef<float, 4> second;
};
Result result;
engine->invoke("name", &result);

Note that LLVM does not support multi-result function, so there are two conversions happening here:

  1. multiple results get packed into a struct,
  2. then the single-struct result is transformed into a trailing pointer argument because you requested a C-friendly interface.

It works!
Thank you so much, @ftynse!