Skip to content

Commit

Permalink
better code style for checking bits, signess, and delete the split in…
Browse files Browse the repository at this point in the history
…put file hack; add more docs; and change the test file accordingly
  • Loading branch information
jiahanxie353 committed Dec 3, 2024
1 parent a44ab09 commit be02332
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 65 deletions.
3 changes: 2 additions & 1 deletion include/circt/Dialect/Calyx/CalyxLoweringUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,8 @@ class ComponentLoweringStateInterface {
/// A mapping between the callee and the instance.
llvm::StringMap<calyx::InstanceOp> instanceMap;

/// A json file to store external global memory data
/// A json file to store external global memory data. See
/// https://docs.calyxir.org/lang/data-format.html?highlight=json#the-data-format
llvm::json::Value extMemData;
};

Expand Down
46 changes: 24 additions & 22 deletions lib/Conversion/SCFToCalyx/SCFToCalyx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "mlir/Support/LogicalResult.h"
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/Support/LogicalResult.h"
#include "llvm/Support/raw_os_ostream.h"
#include <filesystem>
#include <fstream>
Expand Down Expand Up @@ -320,24 +321,20 @@ class BuildOpGroups : public calyx::FuncOpPartialLoweringPattern {
if (!writeJson.empty()) {
if (auto fileLoc = dyn_cast<mlir::FileLineColLoc>(funcOp->getLoc())) {
std::string filename = fileLoc.getFilename().str();
// Hack: remove unwanted prefixes during testing
if (filename.rfind("within split at", 0) == 0)
filename = filename.substr(strlen("within split at "));
std::filesystem::path path(filename);
std::string jsonFileName = writeJson.append(".json");
auto outFileName = path.parent_path().append(jsonFileName);
std::ofstream outFile(outFileName);

if (outFile.is_open()) {
llvm::raw_os_ostream llvmOut(outFile);
llvm::json::OStream jsonOS(llvmOut, 2);
jsonOS.value(getState<ComponentLoweringState>().getExtMemData());
jsonOS.flush();
outFile.close();
} else {
if (!outFile.is_open()) {
llvm::errs() << "Unable to open file for writing\n";
return failure();
}
llvm::raw_os_ostream llvmOut(outFile);
llvm::json::OStream jsonOS(llvmOut, 2);
jsonOS.value(getState<ComponentLoweringState>().getExtMemData());
jsonOS.flush();
outFile.close();
}
}

Expand Down Expand Up @@ -1001,6 +998,8 @@ static LogicalResult buildAllocOp(ComponentLoweringState &componentState,
componentState.registerMemoryInterface(allocOp.getResult(),
calyx::MemoryInterface(memoryOp));

assert(memtype.getElementTypeBitWidth() <= 64 &&
"element bitwidth should not exceed 64");
bool isFloat = !memtype.getElementType().isInteger();

auto shape = allocOp.getType().getShape();
Expand All @@ -1010,8 +1009,10 @@ static LogicalResult buildAllocOp(ComponentLoweringState &componentState,
// https://github.com/llvm/circt/pull/2661 We should instead never pass
// multi-dimensional memories to Calyx, as discussed in:
// https://github.com/calyxir/calyx/issues/907
assert((shape.size() <= 1 || totalSize <= 1) &&
"dimension must be empty or one.");
if (!(shape.size() <= 1 || totalSize <= 1)) {
allocOp.emitError("input memory dimension must be empty or one.");
return failure();
}

std::vector<uint64_t> flattenedVals(totalSize, 0);

Expand All @@ -1026,10 +1027,13 @@ static LogicalResult buildAllocOp(ComponentLoweringState &componentState,
globalOp.getConstantInitValue());
int sizeCount = 0;
for (auto attr : cstAttr.template getValues<Attribute>()) {
assert((isa<mlir::FloatAttr>(attr) || isa<mlir::IntegerAttr>(attr)) &&
"memory attributes must be float or int");
if (auto fltAttr = dyn_cast<mlir::FloatAttr>(attr)) {
double value = fltAttr.getValueAsDouble();
std::memcpy(&flattenedVals[sizeCount++], &value, sizeof(double));
} else if (auto intAttr = dyn_cast<mlir::IntegerAttr>(attr)) {
} else {
auto intAttr = dyn_cast<mlir::IntegerAttr>(attr);
int64_t value = intAttr.getInt();
flattenedVals[sizeCount++] = static_cast<uint64_t>(value);
}
Expand All @@ -1048,9 +1052,13 @@ static LogicalResult buildAllocOp(ComponentLoweringState &componentState,
}
}

bool isSigned = false;
// Put the flattened values in the multi-dimensional structure
for (size_t i = 0; i < flattenedVals.size(); ++i) {
uint64_t bitValue = flattenedVals[i];
// checks whether the MSB of the `uint64_t` type `bitValue` is set
if (bitValue & (1ULL << 63))
isSigned = true;
llvm::json::Value value = 0;
if (isFloat) {
double floatValue;
Expand All @@ -1064,17 +1072,11 @@ static LogicalResult buildAllocOp(ComponentLoweringState &componentState,
}

componentState.setDataField(memoryOp.getName(), result);

auto width = memtype.getElementType().getIntOrFloatBitWidth();
std::string numType =
memtype.getElementType().isInteger() ? "bitnum" : "ieee754_float";

std::string numType;
bool isSigned;
if (memtype.getElementType().isInteger()) {
numType = "bitnum";
isSigned = false;
} else {
numType = "ieee754_float";
isSigned = true;
}
componentState.setFormat(memoryOp.getName(), numType, isSigned, width);

return success();
Expand Down
84 changes: 42 additions & 42 deletions test/Conversion/SCFToCalyx/write_memory.mlir
Original file line number Diff line number Diff line change
@@ -1,51 +1,51 @@
// RUN: circt-opt %s --lower-scf-to-calyx="write-json=data" -canonicalize -split-input-file>/dev/null && cat ./data.json | FileCheck %s
// RUN: circt-opt %s --lower-scf-to-calyx="write-json=data" -canonicalize>/dev/null && cat $(dirname %s)/data.json | FileCheck %s

// CHECK-LABEL: "mem_0": {
// CHECK: "data": [
// CHECK: 0,
// CHECK: 0,
// CHECK: 0,
// CHECK: 0
// CHECK: ],
// CHECK: "format": {
// CHECK: "is_signed": true,
// CHECK: "numeric_type": "ieee754_float",
// CHECK: "width": 32
// CHECK: }
// CHECK: },
// CHECK-DAG: "data": [
// CHECK-DAG: 0,
// CHECK-DAG: 0,
// CHECK-DAG: 0,
// CHECK-DAG: 0
// CHECK-DAG: ],
// CHECK-DAG: "format": {
// CHECK-DAG: "is_signed": false,
// CHECK-DAG: "numeric_type": "ieee754_float",
// CHECK-DAG: "width": 32
// CHECK-DAG: }
// CHECK-DAG: },

// CHECK-LABEL: "mem_1": {
// CHECK: "data": [
// CHECK: 43,
// CHECK: 8,
// CHECK: -39,
// CHECK: -19,
// CHECK: 70,
// CHECK: -64,
// CHECK: -7,
// CHECK: -27,
// CHECK: -57,
// CHECK: 5
// CHECK: ],
// CHECK: "format": {
// CHECK: "is_signed": false,
// CHECK: "numeric_type": "bitnum",
// CHECK: "width": 32
// CHECK: }
// CHECK: },
// CHECK-DAG: "data": [
// CHECK-DAG: 43,
// CHECK-DAG: 8,
// CHECK-DAG: -39,
// CHECK-DAG: -19,
// CHECK-DAG: 70,
// CHECK-DAG: -64,
// CHECK-DAG: -7,
// CHECK-DAG: -27,
// CHECK-DAG: -57,
// CHECK-DAG: 5
// CHECK-DAG: ],
// CHECK-DAG: "format": {
// CHECK-DAG: "is_signed": true,
// CHECK-DAG: "numeric_type": "bitnum",
// CHECK-DAG: "width": 32
// CHECK-DAG: }
// CHECK-DAG: },

// CHECK-LABEL: "mem_2": {
// CHECK: "data": [
// CHECK: 0.69999998807907104,
// CHECK: -4.1999998092651367,
// CHECK: 0
// CHECK: ],
// CHECK: "format": {
// CHECK: "is_signed": true,
// CHECK: "numeric_type": "ieee754_float",
// CHECK: "width": 32
// CHECK: }
// CHECK: }
// CHECK-DAG: "data": [
// CHECK-DAG: 0.69999998807907104,
// CHECK-DAG: -4.1999998092651367,
// CHECK-DAG: 0
// CHECK-DAG: ],
// CHECK-DAG: "format": {
// CHECK-DAG: "is_signed": true,
// CHECK-DAG: "numeric_type": "ieee754_float",
// CHECK-DAG: "width": 32
// CHECK-DAG: }
// CHECK-DAG: }

module {
memref.global "private" constant @constant_10xi32_0 : memref<10xi32> = dense<[43, 8, -39, -19, 70, -64, -7, -27, -57, 5]>
Expand Down

0 comments on commit be02332

Please sign in to comment.