mirror of
https://github.com/vosen/ZLUDA.git
synced 2025-04-28 21:47:57 +03:00
zoc: Improve error messages
This commit is contained in:
parent
e6e9a79fe7
commit
69080d2abc
6 changed files with 107 additions and 56 deletions
27
Cargo.lock
generated
27
Cargo.lock
generated
|
@ -820,8 +820,8 @@ dependencies = [
|
||||||
"ptx_parser",
|
"ptx_parser",
|
||||||
"quick-error",
|
"quick-error",
|
||||||
"rustc-hash 2.0.0",
|
"rustc-hash 2.0.0",
|
||||||
"strum",
|
"strum 0.26.3",
|
||||||
"strum_macros",
|
"strum_macros 0.26.4",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror 1.0.64",
|
"thiserror 1.0.64",
|
||||||
"unwrap_or",
|
"unwrap_or",
|
||||||
|
@ -836,6 +836,7 @@ dependencies = [
|
||||||
"logos",
|
"logos",
|
||||||
"ptx_parser_macros",
|
"ptx_parser_macros",
|
||||||
"rustc-hash 2.0.0",
|
"rustc-hash 2.0.0",
|
||||||
|
"strum 0.27.1",
|
||||||
"thiserror 1.0.64",
|
"thiserror 1.0.64",
|
||||||
"winnow",
|
"winnow",
|
||||||
]
|
]
|
||||||
|
@ -1047,6 +1048,15 @@ version = "0.26.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
|
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum"
|
||||||
|
version = "0.27.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32"
|
||||||
|
dependencies = [
|
||||||
|
"strum_macros 0.27.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum_macros"
|
name = "strum_macros"
|
||||||
version = "0.26.4"
|
version = "0.26.4"
|
||||||
|
@ -1060,6 +1070,19 @@ dependencies = [
|
||||||
"syn 2.0.89",
|
"syn 2.0.89",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum_macros"
|
||||||
|
version = "0.27.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustversion",
|
||||||
|
"syn 2.0.89",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.109"
|
version = "1.0.109"
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use std::ffi::FromBytesUntilNulError;
|
use std::ffi::FromBytesUntilNulError;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::str::Utf8Error;
|
use std::str::Utf8Error;
|
||||||
|
|
||||||
use amd_comgr_sys::amd_comgr_status_s;
|
use amd_comgr_sys::amd_comgr_status_s;
|
||||||
|
@ -10,22 +9,20 @@ use ptx_parser::PtxError;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum CompilerError {
|
pub enum CompilerError {
|
||||||
#[error("HIP error: {0:?}")]
|
#[error("HIP error code: {0:?}")]
|
||||||
HipError(hipErrorCode_t),
|
HipError(hipErrorCode_t),
|
||||||
#[error("amd_comgr error: {0:?}")]
|
#[error("amd_comgr status code: {0:?}")]
|
||||||
ComgrError(amd_comgr_status_s),
|
ComgrError(amd_comgr_status_s),
|
||||||
#[error("Not a regular file: {0}")]
|
#[error(transparent)]
|
||||||
CheckPathError(PathBuf),
|
IoError(#[from] io::Error),
|
||||||
#[error("Invalid output type: {0}")]
|
#[error(transparent)]
|
||||||
ParseOutputTypeError(String),
|
Utf8Error(#[from] Utf8Error),
|
||||||
#[error("Error translating PTX: {0:?}")]
|
#[error("{message}")]
|
||||||
PtxTranslateError(TranslateError),
|
GenericError {
|
||||||
#[error("IO error: {0:?}")]
|
#[source]
|
||||||
IoError(io::Error),
|
cause: Option<Box<dyn std::error::Error>>,
|
||||||
#[error("Error parsing file: {0:?}")]
|
message: String,
|
||||||
ParseFileError(Utf8Error),
|
},
|
||||||
#[error("Error: {0}")]
|
|
||||||
GenericError(String)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<hipErrorCode_t> for CompilerError {
|
impl From<hipErrorCode_t> for CompilerError {
|
||||||
|
@ -42,32 +39,37 @@ impl From<amd_comgr_status_s> for CompilerError {
|
||||||
|
|
||||||
impl From<Vec<PtxError<'_>>> for CompilerError {
|
impl From<Vec<PtxError<'_>>> for CompilerError {
|
||||||
fn from(causes: Vec<PtxError>) -> Self {
|
fn from(causes: Vec<PtxError>) -> Self {
|
||||||
let errors: Vec<String> = causes.iter().map(PtxError::to_string).collect();
|
let errors: Vec<String> = causes
|
||||||
let msg = errors.join("\n");
|
.iter()
|
||||||
CompilerError::GenericError(msg)
|
.map(|e| {
|
||||||
}
|
let msg = match e {
|
||||||
}
|
PtxError::UnrecognizedStatement(value)
|
||||||
|
| PtxError::UnrecognizedDirective(value) => value.unwrap_or("").to_string(),
|
||||||
impl From<io::Error> for CompilerError {
|
other => other.to_string(),
|
||||||
fn from(cause: io::Error) -> Self {
|
};
|
||||||
CompilerError::IoError(cause)
|
format!("PtxError::{}: {}", e.as_ref(), msg)
|
||||||
}
|
})
|
||||||
}
|
.collect();
|
||||||
|
let message = errors.join("\n");
|
||||||
impl From<Utf8Error> for CompilerError {
|
CompilerError::GenericError {
|
||||||
fn from(cause: Utf8Error) -> Self {
|
cause: None,
|
||||||
CompilerError::ParseFileError(cause)
|
message,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TranslateError> for CompilerError {
|
impl From<TranslateError> for CompilerError {
|
||||||
fn from(cause: TranslateError) -> Self {
|
fn from(cause: TranslateError) -> Self {
|
||||||
CompilerError::PtxTranslateError(cause)
|
let message = format!("PTX TranslateError::{}", cause.as_ref());
|
||||||
|
let cause = Some(Box::new(cause) as Box<dyn std::error::Error>);
|
||||||
|
CompilerError::GenericError { cause, message }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<FromBytesUntilNulError> for CompilerError {
|
impl From<FromBytesUntilNulError> for CompilerError {
|
||||||
fn from(cause: FromBytesUntilNulError) -> Self {
|
fn from(cause: FromBytesUntilNulError) -> Self {
|
||||||
CompilerError::GenericError(format!("{}", cause))
|
let message = format!("{}", cause);
|
||||||
|
let cause = Some(Box::new(cause) as Box<dyn std::error::Error>);
|
||||||
|
CompilerError::GenericError { cause, message }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::error::Error;
|
||||||
use std::ffi::{CStr, CString, OsStr};
|
use std::ffi::{CStr, CString, OsStr};
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::ExitCode;
|
||||||
use std::str::{self, FromStr};
|
use std::str::{self, FromStr};
|
||||||
|
|
||||||
use bpaf::Bpaf;
|
use bpaf::Bpaf;
|
||||||
|
@ -26,7 +28,17 @@ pub struct Options {
|
||||||
ptx_path: String,
|
ptx_path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), CompilerError> {
|
fn main() -> ExitCode {
|
||||||
|
main_core().map_or_else(
|
||||||
|
|e| {
|
||||||
|
eprintln!("Error: {}", e);
|
||||||
|
ExitCode::FAILURE
|
||||||
|
},
|
||||||
|
|_| ExitCode::SUCCESS,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main_core() -> Result<(), CompilerError> {
|
||||||
let opts = options().run();
|
let opts = options().run();
|
||||||
|
|
||||||
let output_type = opts.output_type.unwrap_or_default();
|
let output_type = opts.output_type.unwrap_or_default();
|
||||||
|
@ -36,7 +48,7 @@ fn main() -> Result<(), CompilerError> {
|
||||||
|
|
||||||
let output_path = match opts.output_path {
|
let output_path = match opts.output_path {
|
||||||
Some(value) => value,
|
Some(value) => value,
|
||||||
None => get_output_path(&ptx_path, &output_type)?
|
None => get_output_path(&ptx_path, &output_type)?,
|
||||||
};
|
};
|
||||||
check_path(&output_path)?;
|
check_path(&output_path)?;
|
||||||
|
|
||||||
|
@ -48,7 +60,7 @@ fn main() -> Result<(), CompilerError> {
|
||||||
OutputType::LlvmIrPreLinked => llvm.llvm_ir,
|
OutputType::LlvmIrPreLinked => llvm.llvm_ir,
|
||||||
OutputType::LlvmIrLinked => get_linked_bitcode(&llvm)?,
|
OutputType::LlvmIrLinked => get_linked_bitcode(&llvm)?,
|
||||||
OutputType::Elf => get_elf(&llvm)?,
|
OutputType::Elf => get_elf(&llvm)?,
|
||||||
OutputType::Assembly => get_assembly(&llvm)?
|
OutputType::Assembly => get_assembly(&llvm)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
write_to_file(&output, &output_path).map_err(CompilerError::from)?;
|
write_to_file(&output, &output_path).map_err(CompilerError::from)?;
|
||||||
|
@ -56,7 +68,7 @@ fn main() -> Result<(), CompilerError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ptx_to_llvm(ptx: &str) -> Result<LLVMArtifacts, CompilerError> {
|
fn ptx_to_llvm(ptx: &str) -> Result<LLVMArtifacts, CompilerError> {
|
||||||
let ast = ptx_parser::parse_module_checked(ptx).map_err(CompilerError::from).map_err(CompilerError::from)?;
|
let ast = ptx_parser::parse_module_checked(ptx).map_err(CompilerError::from)?;
|
||||||
let module = ptx::to_llvm_module(ast).map_err(CompilerError::from)?;
|
let module = ptx::to_llvm_module(ast).map_err(CompilerError::from)?;
|
||||||
let bitcode = module.llvm_ir.write_bitcode_to_memory().to_vec();
|
let bitcode = module.llvm_ir.write_bitcode_to_memory().to_vec();
|
||||||
let linked_bitcode = module.linked_bitcode().to_vec();
|
let linked_bitcode = module.linked_bitcode().to_vec();
|
||||||
|
@ -82,7 +94,11 @@ fn get_arch() -> Result<CString, CompilerError> {
|
||||||
unsafe { hipGetDevicePropertiesR0600(dev_props.as_mut_ptr(), 0) }?;
|
unsafe { hipGetDevicePropertiesR0600(dev_props.as_mut_ptr(), 0) }?;
|
||||||
let dev_props = unsafe { dev_props.assume_init() };
|
let dev_props = unsafe { dev_props.assume_init() };
|
||||||
let arch = dev_props.gcnArchName;
|
let arch = dev_props.gcnArchName;
|
||||||
let arch: Vec<u8> = arch.to_vec().iter().map(|&v| i8::to_ne_bytes(v)[0]).collect();
|
let arch: Vec<u8> = arch
|
||||||
|
.to_vec()
|
||||||
|
.iter()
|
||||||
|
.map(|&v| i8::to_ne_bytes(v)[0])
|
||||||
|
.collect();
|
||||||
let arch = CStr::from_bytes_until_nul(arch.as_slice())?;
|
let arch = CStr::from_bytes_until_nul(arch.as_slice())?;
|
||||||
Ok(CString::from(arch))
|
Ok(CString::from(arch))
|
||||||
}
|
}
|
||||||
|
@ -94,26 +110,29 @@ fn get_linked_bitcode(llvm: &LLVMArtifacts) -> Result<Vec<u8>, CompilerError> {
|
||||||
|
|
||||||
fn get_elf(llvm: &LLVMArtifacts) -> Result<Vec<u8>, CompilerError> {
|
fn get_elf(llvm: &LLVMArtifacts) -> Result<Vec<u8>, CompilerError> {
|
||||||
let arch = get_arch()?;
|
let arch = get_arch()?;
|
||||||
comgr::get_executable_as_bytes(&arch, &llvm.bitcode, &llvm.linked_bitcode).map_err(CompilerError::from)
|
comgr::get_executable_as_bytes(&arch, &llvm.bitcode, &llvm.linked_bitcode)
|
||||||
|
.map_err(CompilerError::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_assembly(llvm: &LLVMArtifacts) -> Result<Vec<u8>, CompilerError> {
|
fn get_assembly(llvm: &LLVMArtifacts) -> Result<Vec<u8>, CompilerError> {
|
||||||
let arch = get_arch()?;
|
let arch = get_arch()?;
|
||||||
comgr::get_assembly_as_bytes(&arch, &llvm.bitcode, &llvm.linked_bitcode).map_err(CompilerError::from)
|
comgr::get_assembly_as_bytes(&arch, &llvm.bitcode, &llvm.linked_bitcode)
|
||||||
|
.map_err(CompilerError::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_path(path: &Path) -> Result<(), CompilerError> {
|
fn check_path(path: &Path) -> Result<(), CompilerError> {
|
||||||
if path.try_exists().map_err(CompilerError::from)? && !path.is_file() {
|
if path.try_exists().map_err(CompilerError::from)? && !path.is_file() {
|
||||||
let error = CompilerError::CheckPathError(path.to_path_buf());
|
let message = format!("Not a regular file: {:?}", path.to_path_buf());
|
||||||
|
let error = CompilerError::GenericError {
|
||||||
|
cause: None,
|
||||||
|
message,
|
||||||
|
};
|
||||||
return Err(error);
|
return Err(error);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_output_path(
|
fn get_output_path(ptx_path: &PathBuf, output_type: &OutputType) -> Result<PathBuf, CompilerError> {
|
||||||
ptx_path: &PathBuf,
|
|
||||||
output_type: &OutputType,
|
|
||||||
) -> Result<PathBuf, CompilerError> {
|
|
||||||
let current_dir = env::current_dir().map_err(CompilerError::from)?;
|
let current_dir = env::current_dir().map_err(CompilerError::from)?;
|
||||||
let output_path = current_dir.join(
|
let output_path = current_dir.join(
|
||||||
ptx_path
|
ptx_path
|
||||||
|
@ -169,7 +188,13 @@ impl FromStr for OutputType {
|
||||||
"ll_linked" => Ok(Self::LlvmIrLinked),
|
"ll_linked" => Ok(Self::LlvmIrLinked),
|
||||||
"elf" => Ok(Self::Elf),
|
"elf" => Ok(Self::Elf),
|
||||||
"asm" => Ok(Self::Assembly),
|
"asm" => Ok(Self::Assembly),
|
||||||
_ => Err(CompilerError::ParseOutputTypeError(s.into())),
|
_ => {
|
||||||
|
let message = format!("Not a valid output type: {}", s);
|
||||||
|
Err(CompilerError::GenericError {
|
||||||
|
cause: None,
|
||||||
|
message,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,8 @@ mod expand_operands;
|
||||||
mod fix_special_registers2;
|
mod fix_special_registers2;
|
||||||
mod hoist_globals;
|
mod hoist_globals;
|
||||||
mod insert_explicit_load_store;
|
mod insert_explicit_load_store;
|
||||||
mod instruction_mode_to_global_mode;
|
|
||||||
mod insert_implicit_conversions2;
|
mod insert_implicit_conversions2;
|
||||||
|
mod instruction_mode_to_global_mode;
|
||||||
mod normalize_basic_blocks;
|
mod normalize_basic_blocks;
|
||||||
mod normalize_identifiers2;
|
mod normalize_identifiers2;
|
||||||
mod normalize_predicates2;
|
mod normalize_predicates2;
|
||||||
|
@ -31,7 +31,7 @@ static ZLUDA_PTX_IMPL: &'static [u8] = include_bytes!("../../lib/zluda_ptx_impl.
|
||||||
const ZLUDA_PTX_PREFIX: &'static str = "__zluda_ptx_impl_";
|
const ZLUDA_PTX_PREFIX: &'static str = "__zluda_ptx_impl_";
|
||||||
|
|
||||||
quick_error! {
|
quick_error! {
|
||||||
#[derive(Debug)]
|
#[derive(Debug, strum_macros::AsRefStr)]
|
||||||
pub enum TranslateError {
|
pub enum TranslateError {
|
||||||
UnknownSymbol {}
|
UnknownSymbol {}
|
||||||
UntypedSymbol {}
|
UntypedSymbol {}
|
||||||
|
|
|
@ -7,11 +7,12 @@ edition = "2021"
|
||||||
[lib]
|
[lib]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
bitflags = "1.2"
|
||||||
|
derive_more = { version = "1", features = ["display"] }
|
||||||
logos = "0.14"
|
logos = "0.14"
|
||||||
|
ptx_parser_macros = { path = "../ptx_parser_macros" }
|
||||||
|
rustc-hash = "2.0.0"
|
||||||
|
strum = { version = "0.27.1", features = ["derive"] }
|
||||||
|
thiserror = "1.0"
|
||||||
winnow = { version = "0.6.18" }
|
winnow = { version = "0.6.18" }
|
||||||
#winnow = { version = "0.6.18", features = ["debug"] }
|
#winnow = { version = "0.6.18", features = ["debug"] }
|
||||||
ptx_parser_macros = { path = "../ptx_parser_macros" }
|
|
||||||
thiserror = "1.0"
|
|
||||||
bitflags = "1.2"
|
|
||||||
rustc-hash = "2.0.0"
|
|
||||||
derive_more = { version = "1", features = ["display"] }
|
|
||||||
|
|
|
@ -1240,7 +1240,7 @@ impl<Ident> ast::ParsedOperand<Ident> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, strum::AsRefStr)]
|
||||||
pub enum PtxError<'input> {
|
pub enum PtxError<'input> {
|
||||||
#[error("{source}")]
|
#[error("{source}")]
|
||||||
ParseInt {
|
ParseInt {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue