-
Notifications
You must be signed in to change notification settings - Fork 320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Test the return value of omMMapBinaryFile function and terminate the main program elegantly #3002
Changes from 7 commits
afa4cff
03b00ca
79b9b95
7f8d1e0
c0b0a4d
8156452
9171ead
d0f8bcb
1d93a7d
0ae13e7
1042130
4f88c79
e9f794b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ | |
|
||
#include "onnx-mlir/Compiler/OMCompilerRuntimeTypes.h" | ||
#include "src/Conversion/KrnlToLLVM/KrnlToLLVMHelper.hpp" | ||
#include "src/Dialect/Krnl/DialectBuilder.hpp" | ||
#include "src/Dialect/Krnl/KrnlOps.hpp" | ||
#include "src/Dialect/Mlir/DialectBuilder.hpp" | ||
#include "src/Dialect/ONNX/ONNXOps/OpHelper.hpp" | ||
|
@@ -342,5 +343,48 @@ bool isZOS(ModuleOp module) { | |
return zOS; | ||
} | ||
|
||
void equalOrFailed(ModuleOp &module, OpBuilder &rewriter, Location loc, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would these calls also be potentially useful if we wanted to fail the inference, say after a NNPA severe failure call? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Totally yes. It will be used anywhere in the main inference when we want to fail the inference. We can introduce a krnl op for this. |
||
Value lhs, Value rhs, std::string errorMsg, bool appendRHS) { | ||
MLIRContext *context = rewriter.getContext(); | ||
MultiDialectBuilder<LLVMBuilder, KrnlBuilder> create(rewriter, loc); | ||
create.llvm.ifThenElse(/*cond=*/ | ||
[&](const LLVMBuilder &createLLVM) { | ||
return createLLVM.icmp(LLVM::ICmpPredicate::ne, lhs, rhs); | ||
}, /*then=*/ | ||
[&](const LLVMBuilder &createLLVM) { | ||
MultiDialectBuilder<LLVMBuilder, KrnlBuilder> create(createLLVM); | ||
// Print an error message. | ||
if (!errorMsg.empty()) { | ||
if (appendRHS) | ||
create.krnl.printf( | ||
StringRef(errorMsg), rhs, rewriter.getI64Type(), true); | ||
else | ||
create.krnl.printf(StringRef(errorMsg + "\n")); | ||
} | ||
// Set errno. | ||
emitErrNo(module, rewriter, loc, EINVAL); | ||
// Return NULL. | ||
create.llvm._return(create.llvm.null(getI8PointerType(context))); | ||
}); | ||
} | ||
|
||
void equalOrReturn(ModuleOp &module, OpBuilder &rewriter, Location loc, | ||
Value lhs, Value rhs, Value retVal, std::string errorMsg) { | ||
MLIRContext *context = rewriter.getContext(); | ||
MultiDialectBuilder<LLVMBuilder, KrnlBuilder> create(rewriter, loc); | ||
create.llvm.ifThenElse(/*cond=*/ | ||
[&](const LLVMBuilder &createLLVM) { | ||
return createLLVM.icmp(LLVM::ICmpPredicate::ne, lhs, rhs); | ||
}, /*then=*/ | ||
[&](const LLVMBuilder &createLLVM) { | ||
MultiDialectBuilder<LLVMBuilder, KrnlBuilder> create(createLLVM); | ||
// Print an error message. | ||
if (!errorMsg.empty()) | ||
create.krnl.printf(StringRef(errorMsg + "\n")); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we start to use the I had similar issue in the |
||
// Return retVal. | ||
create.llvm._return(retVal); | ||
}); | ||
} | ||
|
||
} // namespace krnl | ||
} // namespace onnx_mlir |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ typedef int make_iso_compilers_happy; | |
|
||
#include <errno.h> | ||
#include <inttypes.h> | ||
#include <stdbool.h> | ||
#include <stddef.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
@@ -42,7 +43,7 @@ const int i = 1; | |
void checkEndianness(const char constPackIsLE) { | ||
if (XOR(IS_SYSTEM_LE(), constPackIsLE)) { | ||
fprintf(stderr, "Constant pack is stored in a byte order that is not " | ||
"native to this current system."); | ||
"native to this current system: %s", strerror(errno)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry I probably didn't make it clear. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same thought. Will remove them. |
||
exit(1); | ||
} | ||
} | ||
|
@@ -58,24 +59,27 @@ void checkEndianness(const char constPackIsLE) { | |
/// | ||
/// This function is thread-safe. | ||
/// | ||
void omMMapBinaryFile( | ||
bool omMMapBinaryFile( | ||
void **constAddr, char *filename, int64_t size, int64_t isLE) { | ||
checkEndianness(isLE); | ||
char *fname = filename; | ||
#ifdef __MVS__ | ||
// Convert the file name to EBCDIC for the open call. | ||
char *tPath = strdup(fname); | ||
if (!tPath) { | ||
fprintf(stderr, "Error while strdup"); | ||
return; | ||
fprintf(stderr, "Error while strdup: %s", strerror(errno)); | ||
return false; | ||
} | ||
__a2e_s(tPath); | ||
fname = tPath; | ||
#endif | ||
|
||
if (constAddr == NULL) { | ||
perror("Error: null pointer"); | ||
return; | ||
fprintf(stderr, "Error: null pointer: %s", strerror(errno)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This |
||
#ifdef __MVS__ | ||
free(tPath); | ||
#endif | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not a big deal but a bit of an eye sore to see the
and then just use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gongsu832 all of these issues come from the fact that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK that makes things simpler. |
||
return false; | ||
} | ||
|
||
if (constAddr[0] == NULL) { | ||
|
@@ -85,23 +89,28 @@ void omMMapBinaryFile( | |
size_t baseLen = strlen(basePath); | ||
size_t fnameLen = strlen(fname); | ||
size_t sepLen = strlen(DIR_SEPARATOR); | ||
size_t filePathLen = baseLen + sepLen + fnameLen; | ||
size_t filePathLen = baseLen + sepLen + fnameLen + 1; | ||
filePath = (char *)malloc(filePathLen); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You probably want to +1 to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch! I updated this. |
||
if (!filePath) { | ||
fprintf(stderr, "Error while malloc"); | ||
return; | ||
fprintf(stderr, "Error while malloc: %s", strerror(errno)); | ||
#ifdef __MVS__ | ||
free(tPath); | ||
#endif | ||
return false; | ||
} | ||
memcpy(filePath, basePath, baseLen); | ||
memcpy(filePath + baseLen, DIR_SEPARATOR, sepLen); | ||
memcpy(filePath + baseLen + sepLen, fname, fnameLen); | ||
filePath[filePathLen] = '\0'; | ||
snprintf(filePath, filePathLen, "%s%s%s", basePath, DIR_SEPARATOR, fname); | ||
} else { | ||
filePath = (char *)fname; | ||
} | ||
int fd = open(filePath, O_RDONLY); | ||
if (fd < 0) { | ||
fprintf(stderr, "Error while opening %s\n", filePath); | ||
return; | ||
fprintf(stderr, "Error while opening %s: %s\n", filePath, strerror(errno)); | ||
if (basePath) | ||
free(filePath); | ||
#ifdef __MVS__ | ||
free(tPath); | ||
#endif | ||
return false; | ||
} | ||
|
||
#ifdef __MVS__ | ||
|
@@ -111,17 +120,22 @@ void omMMapBinaryFile( | |
#endif | ||
|
||
if (tempAddr == MAP_FAILED) { | ||
fprintf(stderr, "Error while mmapping %s\n", fname); | ||
fprintf(stderr, "Error while mmapping %s: %s\n", fname, strerror(errno)); | ||
close(fd); | ||
return; | ||
if (basePath) | ||
free(filePath); | ||
#ifdef __MVS__ | ||
free(tPath); | ||
#endif | ||
return false; | ||
} | ||
|
||
/* Prepare to compare-and-swap to setup the shared constAddr. | ||
* If we fail, another thread beat us so free our mmap. | ||
*/ | ||
#ifdef __MVS__ | ||
void *expected = NULL; | ||
if (cds((cds_t *)&expected, (cds_t *)&constAddr[0], *(cds_t *)tempAddr)) | ||
if (cds((cds_t *)&expected, (cds_t *)&constAddr[0], *(cds_t *)&tempAddr)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Include a fix for z/OS. |
||
munmap(tempAddr, size); | ||
#else | ||
if (!__sync_bool_compare_and_swap(&constAddr[0], NULL, tempAddr)) | ||
|
@@ -135,11 +149,24 @@ void omMMapBinaryFile( | |
close(fd); | ||
if (basePath) | ||
free(filePath); | ||
#ifdef __MVS__ | ||
free(tPath); | ||
#endif | ||
/* Make sure constAddr is the same as the mmap address. | ||
*/ | ||
if (constAddr[0] != tempAddr) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This check is wrong. Only the first thread that successfully performs the compare-and-swap will have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I explicitly set There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Not sure what you mean. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Not sure why you want to do that. A successful compare-and-swap guarantees that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, you are right. In the latest code, I set There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want to avoid the situation we encountered where There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. I removed the check. I was overthinking about having a check to debug, but since we found the issue, and There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes you can use |
||
fprintf(stderr, | ||
"Error while updating the buffer address for constants: %s\n", | ||
strerror(errno)); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
#ifdef __MVS__ | ||
free(tPath); | ||
#endif | ||
return true; | ||
} | ||
|
||
/// Return the address of a constant at a given offset. | ||
|
@@ -153,11 +180,11 @@ void omMMapBinaryFile( | |
void omGetExternalConstantAddr( | ||
void **outputAddr, void **baseAddr, int64_t offset) { | ||
if (outputAddr == NULL) { | ||
perror("Error: null pointer"); | ||
fprintf(stderr, "Error: null pointer: %s", strerror(errno)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
return; | ||
} | ||
if (baseAddr == NULL) { | ||
perror("Error: null pointer"); | ||
fprintf(stderr, "Error: null pointer: %s", strerror(errno)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
return; | ||
} | ||
// Constant is already loaded. Nothing to do. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this code into
KrnlToLLVMHelper.{hpp/cpp}
so that it can be reused.