Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions mlir/include/mlir/Conversion/MathToEmitC/MathToEmitC.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===- MathToEmitC.h - Math to EmitCPatterns -------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_CONVERSION_MATHTOEMITC_MATHTOEMITC_H
#define MLIR_CONVERSION_MATHTOEMITC_MATHTOEMITC_H
#include "mlir/Dialect/EmitC/IR/EmitC.h"

namespace mlir {
class RewritePatternSet;

void populateConvertMathToEmitCPatterns(
RewritePatternSet &patterns,
emitc::MathToEmitCLanguageTarget languageTarget);
} // namespace mlir

#endif // MLIR_CONVERSION_MATHTOEMITC_MATHTOEMITC_H
21 changes: 21 additions & 0 deletions mlir/include/mlir/Conversion/MathToEmitC/MathToEmitCPass.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===- MathToEmitCPass.h - Math to EmitC Pass -------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_CONVERSION_MATHTOEMITC_MATHTOEMITCPASS_H
#define MLIR_CONVERSION_MATHTOEMITC_MATHTOEMITCPASS_H

#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include <memory>
namespace mlir {
class Pass;

#define GEN_PASS_DECL_CONVERTMATHTOEMITC
#include "mlir/Conversion/Passes.h.inc"
} // namespace mlir

#endif // MLIR_CONVERSION_MATHTOEMITC_MATHTOEMITCPASS_H
1 change: 1 addition & 0 deletions mlir/include/mlir/Conversion/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "mlir/Conversion/IndexToLLVM/IndexToLLVM.h"
#include "mlir/Conversion/IndexToSPIRV/IndexToSPIRV.h"
#include "mlir/Conversion/LinalgToStandard/LinalgToStandard.h"
#include "mlir/Conversion/MathToEmitC/MathToEmitCPass.h"
#include "mlir/Conversion/MathToFuncs/MathToFuncs.h"
#include "mlir/Conversion/MathToLLVM/MathToLLVM.h"
#include "mlir/Conversion/MathToLibm/MathToLibm.h"
Expand Down
22 changes: 22 additions & 0 deletions mlir/include/mlir/Conversion/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,28 @@ def ConvertMathToSPIRV : Pass<"convert-math-to-spirv"> {
let dependentDialects = ["spirv::SPIRVDialect"];
}

//===----------------------------------------------------------------------===//
// MathToEmitC
//===----------------------------------------------------------------------===//

def ConvertMathToEmitC : Pass<"convert-math-to-emitc"> {
let summary = "Convert some Math operations to EmitC Call_opaque";
let description = [{
This pass converts supported Math ops to `opaque_call` ops targeting libc/libm
functions. Unlike convert-math-to-funcs pass, converting to `call_opaque` ops
allows to overload the same function with different argument types.
}];
let dependentDialects = ["emitc::EmitCDialect"];
let options = [
Option<"languageTarget", "language-target", "::mlir::emitc::MathToEmitCLanguageTarget",
/*default=*/"::mlir::emitc::MathToEmitCLanguageTarget::CPP", "Select the language target for callees (C or CPP).",
[{::llvm::cl::values(
clEnumValN(::mlir::emitc::MathToEmitCLanguageTarget::C, "C", "C"),
clEnumValN(::mlir::emitc::MathToEmitCLanguageTarget::CPP, "CPP", "CPP")
)}]>
];
}

//===----------------------------------------------------------------------===//
// MathToFuncs
//===----------------------------------------------------------------------===//
Expand Down
9 changes: 9 additions & 0 deletions mlir/include/mlir/Dialect/EmitC/IR/EmitCAttributes.td
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,13 @@ def EmitC_OpaqueAttr : EmitC_Attr<"Opaque", "opaque"> {

def EmitC_OpaqueOrTypedAttr : AnyAttrOf<[EmitC_OpaqueAttr, TypedAttrInterface]>;

def MathToEmitCLanguageTarget : I32EnumAttr<"MathToEmitCLanguageTarget",
"Specifies the language target for generating callees.", [
I32EnumAttrCase<"C", 0, "Use C-style function names">,
I32EnumAttrCase<"CPP", 1, "Use C++-style function names">
]> {
let cppNamespace = "::mlir::emitc";
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be placed in EmitCAttributes.td as it is not strictly belongs to the dialect itself. Scanning over upstream quickly it seems that ConvertSPIRVToLLVMPass relies on an Option which uses a custom attribute and not one of the standard types. As another example, include/mlir/Dialect/ArmSME/Transforms/Passes.td defines attributes in the passes file itself. I don't know the best solution for this but as mentioned EmitCAttributes.td feels like the wrong place.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we could take advantage of this use case to introduce a more general attribute attached to the module, e.g. EmitCTarget/EmitCTargetLanguage, to be used consistently by lowering passes and the translator where distinct C variants require different lowering, module-level verification or syntax, e.g.

  • Multiple return values are currently lowered to C++ has std::tuple, unavailable in other C variants.
  • OpenCL-C defines several address spaces, other C variants don't.
  • OpenCL-C has native vector types (to some extent), C doesn't.
  • C++ has templates, other C variants don't.
  • C/C++ support function pointers and recursion, OpenCL-C doesn't.

An alternative to such an attribute might be target-language module ops, e.g. EmitC::C99ModuleOp.

With the current PR we have "C" and "CPP" as possible targets (I actually would prefer lowercase here). What about >specifying language standard instead? While not having a demand myself right now, I think adding the option to add c23 to e.g. emit fabsd32 could be nice (?). Any (further) opinions on this?

+1
Would be good to enumerate all standard C/C++ versions and let each pass differentiate its lowering as needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback!
@marbre, I’m waiting to hear your opinion on @aniragil's suggestion to use a module-level attribute.
As for C23, since decimal types aren’t yet in the builtin types, lowering into them could be challenging. If C23 doesn’t add immediate benefits, maybe we can start with c99 and cpp11. Thoughts?"

Copy link
Member

@marbre marbre Nov 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to ass C23 from the start but I would prefer a naming (c99, cpp11, ...) that allows to extend if we want to (we would be a little stuck with just CPP and C).

Let me try to also pull in the other parallel discussion. With regards to @cferry-AMD's comment

How specific to Math functions do you see this pass? The second choice makes the lowering much more generic than I thought: it may apply to any op that could be lowered to opaque library calls, and not just Math dialect ops to math.h functions. I like this ability to lower anything to opaque calls with language filters, but this may not be what you intended.

and your response

Thank you for the feedback! I intended this pass to focus on lowering math functions specifically. I accepted the suggestion to use libraries like and am also considering the option to add custom math libraries, not just the standard ones, which motivated me to use a map. I can enforce that only math dialect ops will be converted to ensure it remains targeted.

I feel like shouldn't put to much into this single PR. We can still use what you have to iterate on it under the assumption that we don't land an approach that introduces drawbacks (for example ops, parameters, ..) that will break with the first refactoring commit and thus break users. Having something that can be consistently used in multiple conversions could be nice, but I currently don't have a concrete idea of how this could look like and lack time to spend much though on it. It would indeed be nice to solve some of the some of issues to which @aniragil pointed but I don't know if we can solve all these with this kind of the proposed attribute. Target module ops like EmitC::C99ModuleOp can be an alternative but are a different concept. Spontaneously, I would prefer to just go a different conversion route (which is what you're doing with the proposed patch) than introducing completely new ops.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marbre, thanks for the input.
I noticed that ConvertSPIRVToLLVMPass relies on a custom Option for ClientAPI defined in SPIRVBase.td, which is similar to what I’m aiming for here. Additionally, include/mlir/Dialect/ArmSME/Transforms/Passes.td defines attributes directly in its passes file but includes mlir/IR/EnumAttr.td, going beyond the usual Conversion/Passes.td convention to include only mlir/Pass/PassBase.td.

At this point, defining the attribute in EmitCBase.td or EmitCAttributes.td seems like the only alternative I can think of. What are your thoughts?

I also agree with your point on keeping this PR focused without adding too much at once. Further ideas we discussed can be part of future work.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this have to be an attribute right now? As we don't have a dedicated op we could attach this to yet, we could start with a LanguageTarget enum somewhere in Dialect/EmitC/Transforms. Once we introduce a module like op we can give it an inherent attribute to define the target.

Additionally I would strip the Math prefix from the name as I expect this to be used in more places in the future as @aniragil mentioned.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds about right to me. I've moved the LanguageTarget enum to Dialect/EmitC/Transforms/Passes.h as you suggested and removed the Math prefix to generalize the enum for broader use.



#endif // MLIR_DIALECT_EMITC_IR_EMITCATTRIBUTES
1 change: 1 addition & 0 deletions mlir/lib/Conversion/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ add_subdirectory(IndexToLLVM)
add_subdirectory(IndexToSPIRV)
add_subdirectory(LinalgToStandard)
add_subdirectory(LLVMCommon)
add_subdirectory(MathToEmitC)
add_subdirectory(MathToFuncs)
add_subdirectory(MathToLibm)
add_subdirectory(MathToLLVM)
Expand Down
19 changes: 19 additions & 0 deletions mlir/lib/Conversion/MathToEmitC/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
add_mlir_conversion_library(MLIRMathToEmitC
MathToEmitC.cpp
MathToEmitCPass.cpp

ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/MathToEmitC

DEPENDS
MLIRConversionPassIncGen

LINK_COMPONENTS
Core

LINK_LIBS PUBLIC
MLIREmitCDialect
MLIRMathDialect
MLIRPass
MLIRTransforms
)
83 changes: 83 additions & 0 deletions mlir/lib/Conversion/MathToEmitC/MathToEmitC.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//===- MathToEmitC.cpp - Math to EmitC Patterns ----------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "mlir/Conversion/MathToEmitC/MathToEmitC.h"

#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/Dialect/Math/IR/Math.h"
#include "mlir/Transforms/DialectConversion.h"

using namespace mlir;

namespace {
template <typename OpType>
class LowerToEmitCCallOpaque : public OpRewritePattern<OpType> {
std::string calleeStr;
emitc::MathToEmitCLanguageTarget languageTarget;

public:
LowerToEmitCCallOpaque(MLIRContext *context, std::string calleeStr,
emitc::MathToEmitCLanguageTarget languageTarget)
: OpRewritePattern<OpType>(context), calleeStr(std::move(calleeStr)),
languageTarget(languageTarget) {}

LogicalResult matchAndRewrite(OpType op,
PatternRewriter &rewriter) const override;
};

template <typename OpType>
LogicalResult LowerToEmitCCallOpaque<OpType>::matchAndRewrite(
OpType op, PatternRewriter &rewriter) const {
if (!llvm::all_of(op->getOperandTypes(), llvm::IsaPred<Float32Type, Float64Type>)||
!llvm::all_of(op->getResultTypes(),llvm::IsaPred<Float32Type, Float64Type>))
return rewriter.notifyMatchFailure(
op.getLoc(), "expected all operands and results to be of type f32");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
op.getLoc(), "expected all operands and results to be of type f32");
op.getLoc(), "expected all operands and results to be of type f32 or f64");

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right

std::string modifiedCalleeStr = calleeStr;
if (languageTarget == emitc::MathToEmitCLanguageTarget::CPP) {
modifiedCalleeStr = "std::" + calleeStr;
} else if (languageTarget == emitc::MathToEmitCLanguageTarget::C) {
auto operandType = op->getOperandTypes()[0];
if (operandType.isF32())
modifiedCalleeStr = calleeStr + "f";
}
rewriter.replaceOpWithNewOp<emitc::CallOpaqueOp>(
op, op.getType(), modifiedCalleeStr, op->getOperands());
return success();
}

} // namespace

// Populates patterns to replace `math` operations with `emitc.call_opaque`,
// using function names consistent with those in <math.h>.
void mlir::populateConvertMathToEmitCPatterns(
RewritePatternSet &patterns,
emitc::MathToEmitCLanguageTarget languageTarget) {
auto *context = patterns.getContext();
patterns.insert<LowerToEmitCCallOpaque<math::FloorOp>>(context, "floor",
languageTarget);
patterns.insert<LowerToEmitCCallOpaque<math::RoundOp>>(context, "round",
languageTarget);
patterns.insert<LowerToEmitCCallOpaque<math::ExpOp>>(context, "exp",
languageTarget);
patterns.insert<LowerToEmitCCallOpaque<math::CosOp>>(context, "cos",
languageTarget);
patterns.insert<LowerToEmitCCallOpaque<math::SinOp>>(context, "sin",
languageTarget);
patterns.insert<LowerToEmitCCallOpaque<math::AcosOp>>(context, "acos",
languageTarget);
patterns.insert<LowerToEmitCCallOpaque<math::AsinOp>>(context, "asin",
languageTarget);
patterns.insert<LowerToEmitCCallOpaque<math::Atan2Op>>(context, "atan2",
languageTarget);
patterns.insert<LowerToEmitCCallOpaque<math::CeilOp>>(context, "ceil",
languageTarget);
patterns.insert<LowerToEmitCCallOpaque<math::AbsFOp>>(context, "fabs",
languageTarget);
patterns.insert<LowerToEmitCCallOpaque<math::PowFOp>>(context, "pow",
languageTarget);
}
52 changes: 52 additions & 0 deletions mlir/lib/Conversion/MathToEmitC/MathToEmitCPass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//===- MathToEmitCPass.cpp - Math to EmitC Pass -----------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements a pass to convert the Math dialect to the EmitC dialect.
//
//===----------------------------------------------------------------------===//

#include "mlir/Conversion/MathToEmitC/MathToEmitCPass.h"
#include "mlir/Conversion/MathToEmitC/MathToEmitC.h"
#include "mlir/Dialect/EmitC/IR/EmitC.h"
#include "mlir/Dialect/Math/IR/Math.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Transforms/DialectConversion.h"

namespace mlir {
#define GEN_PASS_DEF_CONVERTMATHTOEMITC
#include "mlir/Conversion/Passes.h.inc"
} // namespace mlir

using namespace mlir;
namespace {

// Replaces Math operations with `emitc.call_opaque` operations.
struct ConvertMathToEmitC
: public impl::ConvertMathToEmitCBase<ConvertMathToEmitC> {
using ConvertMathToEmitCBase::ConvertMathToEmitCBase;

public:
void runOnOperation() final;
};

} // namespace

void ConvertMathToEmitC::runOnOperation() {
ConversionTarget target(getContext());
target.addLegalOp<emitc::CallOpaqueOp>();

target.addIllegalOp<math::FloorOp, math::ExpOp, math::RoundEvenOp,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
target.addIllegalOp<math::FloorOp, math::ExpOp, math::RoundEvenOp,
target.addIllegalOp<math::FloorOp, math::ExpOp, math::RoundOp,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

math::CosOp, math::SinOp, math::Atan2Op, math::CeilOp,
math::AcosOp, math::AsinOp, math::AbsFOp, math::PowFOp>();

RewritePatternSet patterns(&getContext());
populateConvertMathToEmitCPatterns(patterns, languageTarget);

if (failed(applyPartialConversion(getOperation(), target, std::move(patterns))))
signalPassFailure();
}
23 changes: 23 additions & 0 deletions mlir/test/Conversion/MathToEmitC/math-to-emitc-failed.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// RUN: mlir-opt -split-input-file -convert-math-to-emitc -verify-diagnostics %s

func.func @unsupported_tensor_type(%arg0 : tensor<4xf32>) -> tensor<4xf32> {
// expected-error @+1 {{failed to legalize operation 'math.absf' that was explicitly marked illegal}}
%0 = math.absf %arg0 : tensor<4xf32>
return %0 : tensor<4xf32>
}

// -----

func.func @unsupported_f16_type(%arg0 : f16) -> f16 {
// expected-error @+1 {{failed to legalize operation 'math.absf' that was explicitly marked illegal}}
%0 = math.absf %arg0 : f16
return %0 : f16
}

// -----

func.func @unsupported_f128_type(%arg0 : f128) -> f128 {
// expected-error @+1 {{failed to legalize operation 'math.absf' that was explicitly marked illegal}}
%0 = math.absf %arg0 : f128
return %0 : f128
}
65 changes: 65 additions & 0 deletions mlir/test/Conversion/MathToEmitC/math-to-emitc.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// RUN: mlir-opt -convert-math-to-emitc=language-target=C %s | FileCheck %s --check-prefix=C
// RUN: mlir-opt -convert-math-to-emitc=language-target=CPP %s | FileCheck %s --check-prefix=CPP

func.func @absf_to_call_opaque(%arg0: f32) {
// C: emitc.call_opaque "fabsf"
// CPP: emitc.call_opaque "std::fabs"
%1 = math.absf %arg0 : f32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the f64 variants for the tests please

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to support only float32 until I decide how to proceed with this thread. I would appreciate you opinion about it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a commit that support both f64 and f32, and updated the lit tests

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make the tests exhaustive, with something like this:

func.func @floor(%arg0: f32, %arg1: f64) {
    // C: emitc.call_opaque "floorf" (%arg0)
    // C-NEXT: emitc.call_opaque "floor" (%arg1)
    // CPP: emitc.call_opaque "std::floor" (%arg0)
    // CPP-NEXT: emitc.call_opaque "std::floor" (%arg1)
    %0 = math.floor %arg0 : f32
    %1 = math.floor %arg1 : f64
    return
}

Addiotionally a test for math.round is missing currently.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I changed the test accordingly and added one for math.round.

return
}
func.func @floor_to_call_opaque(%arg0: f32) {
// C: emitc.call_opaque "floorf"
// CPP: emitc.call_opaque "std::floor"
%1 = math.floor %arg0 : f32
return
}
func.func @sin_to_call_opaque(%arg0: f32) {
// C: emitc.call_opaque "sinf"
// CPP: emitc.call_opaque "std::sin"
%1 = math.sin %arg0 : f32
return
}
func.func @cos_to_call_opaque(%arg0: f32) {
// C: emitc.call_opaque "cosf"
// CPP: emitc.call_opaque "std::cos"
%1 = math.cos %arg0 : f32
return
}
func.func @asin_to_call_opaque(%arg0: f32) {
// C: emitc.call_opaque "asinf"
// CPP: emitc.call_opaque "std::asin"
%1 = math.asin %arg0 : f32
return
}
func.func @acos_to_call_opaque(%arg0: f64) {
// C: emitc.call_opaque "acos"
// CPP: emitc.call_opaque "std::acos"
%1 = math.acos %arg0 : f64
return
}
func.func @atan2_to_call_opaque(%arg0: f64, %arg1: f64) {
// C: emitc.call_opaque "atan2"
// CPP: emitc.call_opaque "std::atan2"
%1 = math.atan2 %arg0, %arg1 : f64
return
}
func.func @ceil_to_call_opaque(%arg0: f64) {
// C: emitc.call_opaque "ceil"
// CPP: emitc.call_opaque "std::ceil"
%1 = math.ceil %arg0 : f64
return
}
func.func @exp_to_call_opaque(%arg0: f64) {
// C: emitc.call_opaque "exp"
// CPP: emitc.call_opaque "std::exp"
%1 = math.exp %arg0 : f64
return
}
func.func @powf_to_call_opaque(%arg0: f64, %arg1: f64) {
// C: emitc.call_opaque "pow"
// CPP: emitc.call_opaque "std::pow"
%1 = math.powf %arg0, %arg1 : f64
return
}


22 changes: 22 additions & 0 deletions utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4201,6 +4201,7 @@ cc_library(
":IndexToLLVM",
":IndexToSPIRV",
":LinalgToStandard",
":MathToEmitC",
":MathToFuncs",
":MathToLLVM",
":MathToLibm",
Expand Down Expand Up @@ -8721,6 +8722,27 @@ cc_library(
],
)

cc_library(
name = "MathToEmitC",
srcs = glob([
"lib/Conversion/MathToEmitC/*.cpp",
]),
hdrs = glob([
"include/mlir/Conversion/MathToEmitC/*.h",
]),
includes = [
"include",
"lib/Conversion/MathToEmitC",
],
deps = [
":ConversionPassIncGen",
":EmitCDialect",
":MathDialect",
":Pass",
":TransformUtils",
],
)

cc_library(
name = "MathToFuncs",
srcs = glob(["lib/Conversion/MathToFuncs/*.cpp"]),
Expand Down
Loading