Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions tools/hls-fuzzer/ConjunctionTypeSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class ConjunctionTypeSystemBase
TypeSystem<std::tuple<typename SubTypeSystems::Context...>, Self>;
using Context = typename Base::Context;

ConjunctionTypeSystemBase() = default;

/// Constructs a conjunctive typesystem from the instances of the
/// sub-typesystems.
explicit ConjunctionTypeSystemBase(SubTypeSystems &&...subTypeSystems)
Expand Down
4 changes: 2 additions & 2 deletions tools/hls-fuzzer/LimitTypeSystem.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "LimitTypeSystem.h"

dynamatic::ProbabilityTable<dynamatic::gen::AbstractTypeSystem::ExpressionKey>
dynamatic::gen::LimitTypeSystem::getExpressionProbabilityTable(
const LimitTypingContext &context) {
dynamatic::gen::details::DepthTypeSystem::getExpressionProbabilityTable(
const DepthTypingContext &context) {
// Default probabilities for expressions.
// Most expressions are 100 times more likely to be generated than a
// constant.
Expand Down
127 changes: 101 additions & 26 deletions tools/hls-fuzzer/LimitTypeSystem.h
Original file line number Diff line number Diff line change
@@ -1,69 +1,72 @@
#ifndef DYNAMATIC_HLS_FUZZER_LIMITTYPESYSTEM
#define DYNAMATIC_HLS_FUZZER_LIMITTYPESYSTEM

#include "ConjunctionTypeSystem.h"
#include "TypeSystem.h"
#include "VisitorTypeSystem.h"
#include <cstddef>

namespace dynamatic::gen {
struct LimitTypingContext {

namespace details {

struct DepthTypingContext {
std::size_t expressionDepth{};
std::size_t totalNumberOfStatements{};
};

/// Typesystem used to enforce limits such as number of a specific AST nodes,
/// parameters, depth of expressions and so on.
class LimitTypeSystem : public TypeSystem<LimitTypingContext, LimitTypeSystem> {
class DepthTypeSystem : public TypeSystem<DepthTypingContext, DepthTypeSystem> {

/// Returns a transfer function which increments 'field' of the context of
/// 'from' before returning it.
template <typename ASTNode, std::size_t LimitTypingContext::*field,
template <typename ASTNode, std::size_t DepthTypingContext::*field,
std::size_t from = INPUT_DEPENDENCY>
static auto incrementDepth() {
return TransferFn<ASTNode, from>(
[](LimitTypingContext context, auto &&...) {
[](DepthTypingContext context, auto &&...) {
++(context.*field);
return context;
});
}

public:
explicit LimitTypeSystem(std::size_t maxExpressionDepth = 4,
explicit DepthTypeSystem(std::size_t maxExpressionDepth = 4,
std::size_t maxTotalStatements = 10)
: maxExpressionDepth(maxExpressionDepth),
maxTotalStatements(maxTotalStatements) {}

bool discardBinaryExpression(ast::BinaryExpression::Op,
const LimitTypingContext &context) const {
const DepthTypingContext &context) const {
return context.expressionDepth >= maxExpressionDepth;
}

TransferFnArray<ast::BinaryExpression>
getBinaryExpressionTransferFns(ast::BinaryExpression::Op op) override {
return {
/*lhs=*/incrementDepth<ast::BinaryExpression,
&LimitTypingContext::expressionDepth>(),
&DepthTypingContext::expressionDepth>(),
/*rhs=*/
incrementDepth<ast::BinaryExpression,
&LimitTypingContext::expressionDepth>(),
&DepthTypingContext::expressionDepth>(),
/*output=*/copyInputToOutput<ast::BinaryExpression>(),
};
}

bool discardUnaryExpression(ast::UnaryExpression::Op,
const LimitTypingContext &context) const {
const DepthTypingContext &context) const {
return context.expressionDepth >= maxExpressionDepth;
}

TransferFnArray<ast::UnaryExpression>
getUnaryExpressionTransferFns(ast::UnaryExpression::Op op) override {
return {
/*operand=*/incrementDepth<ast::UnaryExpression,
&LimitTypingContext::expressionDepth>(),
&DepthTypingContext::expressionDepth>(),
/*output=*/copyInputToOutput<ast::UnaryExpression>(),
};
}

bool discardCastExpression(const LimitTypingContext &context) const {
bool discardCastExpression(const DepthTypingContext &context) const {
return context.expressionDepth >= maxExpressionDepth;
}

Expand All @@ -72,12 +75,12 @@ class LimitTypeSystem : public TypeSystem<LimitTypingContext, LimitTypeSystem> {
/*target type=*/copyFromInput<ast::CastExpression>(),
/*operand=*/
incrementDepth<ast::CastExpression,
&LimitTypingContext::expressionDepth>(),
&DepthTypingContext::expressionDepth>(),
/*output=*/copyInputToOutput<ast::CastExpression>(),
};
}

bool discardConditionalExpression(const LimitTypingContext &context) const {
bool discardConditionalExpression(const DepthTypingContext &context) const {
return context.expressionDepth >= maxExpressionDepth;
}

Expand All @@ -87,18 +90,18 @@ class LimitTypeSystem : public TypeSystem<LimitTypingContext, LimitTypeSystem> {
// subelements.
return {
/*condition=*/incrementDepth<ast::ConditionalExpression,
&LimitTypingContext::expressionDepth>(),
&DepthTypingContext::expressionDepth>(),
/*true value=*/
incrementDepth<ast::ConditionalExpression,
&LimitTypingContext::expressionDepth>(),
&DepthTypingContext::expressionDepth>(),
/*false value=*/
incrementDepth<ast::ConditionalExpression,
&LimitTypingContext::expressionDepth>(),
&DepthTypingContext::expressionDepth>(),
/*output=*/copyInputToOutput<ast::ConditionalExpression>(),
};
}

bool discardArrayReadExpression(const LimitTypingContext &context) const {
bool discardArrayReadExpression(const DepthTypingContext &context) const {
return context.expressionDepth >= maxExpressionDepth;
}

Expand All @@ -108,7 +111,7 @@ class LimitTypeSystem : public TypeSystem<LimitTypingContext, LimitTypeSystem> {
/*array parameter=*/copyFromInput<ast::ArrayReadExpression>(),
/*index=*/
incrementDepth<ast::ArrayReadExpression,
&LimitTypingContext::expressionDepth>(),
&DepthTypingContext::expressionDepth>(),
/*output=*/copyInputToOutput<ast::ArrayReadExpression>(),
};
}
Expand All @@ -123,14 +126,14 @@ class LimitTypeSystem : public TypeSystem<LimitTypingContext, LimitTypeSystem> {
OutputTransferFn<ast::ArrayAssignmentStatement>(
std::index_sequence<INPUT_DEPENDENCY>{},
[](const ast::ArrayAssignmentStatement &,
LimitTypingContext context) {
DepthTypingContext context) {
context.totalNumberOfStatements++;
return context;
}),
};
}

bool discardStatementList(const LimitTypingContext &context) const {
bool discardStatementList(const DepthTypingContext &context) const {
return context.totalNumberOfStatements >= maxTotalStatements;
}

Expand All @@ -147,8 +150,8 @@ class LimitTypeSystem : public TypeSystem<LimitTypingContext, LimitTypeSystem> {
OutputTransferFn<ast::StatementList>(
std::index_sequence<ast::StatementList::STATEMENT,
ast::StatementList::STATEMENT_LIST>{},
[](const ast::StatementList &, LimitTypingContext statement,
const LimitTypingContext &statementList) {
[](const ast::StatementList &, DepthTypingContext statement,
const DepthTypingContext &statementList) {
// Regardless of which of the two was generated first, we can
// extract the total number of statements by taking their maximum.
statement.totalNumberOfStatements =
Expand All @@ -167,19 +170,91 @@ class LimitTypeSystem : public TypeSystem<LimitTypingContext, LimitTypeSystem> {
/*step=*/copyFromInput<ast::StructuredForStatement>(),
/*statements=*/
incrementDepth<ast::StructuredForStatement,
&LimitTypingContext::totalNumberOfStatements>(),
&DepthTypingContext::totalNumberOfStatements>(),
/*output=*/
copyToOutput<ast::StructuredForStatement,
ast::StructuredForStatement::BODY>(),
};
}

static ProbabilityTable<ExpressionKey>
getExpressionProbabilityTable(const LimitTypingContext &context);
getExpressionProbabilityTable(const DepthTypingContext &context);

std::size_t maxExpressionDepth{};
std::size_t maxTotalStatements{};
};

struct ParamTypingContext {
std::size_t numScalarParam{};
std::size_t numArrayParam{};

ParamTypingContext merge(const ParamTypingContext &rhs) const {
return {std::max(numScalarParam, rhs.numScalarParam),
std::max(numArrayParam, rhs.numArrayParam)};
}
};

/// Type system that caps the maximum amount of scalar parameters, array
/// parameters and parameters in general.
class ParamTypeSystem
: public VisitorTypeSystem<ParamTypingContext, ParamTypeSystem> {
public:
explicit ParamTypeSystem(std::size_t maxScalarParam = 16,
std::size_t maxArrayParam = 8,
std::size_t maxParams = 256)
: maxScalarParam(maxScalarParam), maxArrayParam(maxArrayParam),
maxParams(maxParams) {}

bool discardFreshScalarParameter(const ParamTypingContext &context) const {
return context.numScalarParam >= maxScalarParam ||
context.numScalarParam + context.numArrayParam >= maxParams;
}

TransferFnArray<ast::ScalarParameter>
getFreshScalarParameterTransferFns() override {
return {
copyFromInput<ast::ScalarParameter>(),
OutputTransferFn<ast::ScalarParameter>(
std::index_sequence<INPUT_DEPENDENCY>{},
[](const ast::ScalarParameter &, ParamTypingContext context) {
context.numScalarParam++;
return context;
}),
};
}

bool discardFreshArrayParameter(const ParamTypingContext &context) const {
return context.numArrayParam >= maxArrayParam ||
context.numScalarParam + context.numArrayParam >= maxParams;
}

TransferFnArray<ast::ArrayParameter>
getFreshArrayParameterTransferFns() override {
return {
copyFromInput<ast::ArrayParameter>(),
OutputTransferFn<ast::ArrayParameter>(
std::index_sequence<INPUT_DEPENDENCY>{},
[](const ast::ArrayParameter &, ParamTypingContext context) {
context.numArrayParam++;
return context;
}),
};
}

private:
std::size_t maxScalarParam{};
std::size_t maxArrayParam{};
std::size_t maxParams{};
};

} // namespace details

/// Typesystem used to enforce limits such as number of a specific AST nodes,
/// parameters, depth of expressions and so on.
class LimitTypeSystem final
: public ConjunctionTypeSystemBase<
LimitTypeSystem, details::DepthTypeSystem, details::ParamTypeSystem> {
};
} // namespace dynamatic::gen

#endif
Loading
Loading