Skip to content

Instantly share code, notes, and snippets.

@cgmb
Last active March 31, 2023 16:39
Show Gist options
  • Save cgmb/f7b9012b9c1604646267ce8fc8d278cf to your computer and use it in GitHub Desktop.
Save cgmb/f7b9012b9c1604646267ce8fc8d278cf to your computer and use it in GitHub Desktop.
Example of C-style error handling
/* ************************************************************************
* Copyright (c) 2023 Advanced Micro Devices, Inc.
* ************************************************************************ */
#include <stdlib.h>
#include <rocblas/rocblas.h>
#include <rocsparse/rocsparse.h>
#include "rocsolver_rfinfo.hpp"
static rocblas_status to_rocsolver_status(rocblas_status status)
{
return status;
}
static rocblas_status to_rocsolver_status(rocsparse_status status)
{
switch(status)
{
case rocsparse_status_success: return rocblas_status_success;
case rocsparse_status_invalid_handle: return rocblas_status_invalid_handle;
case rocsparse_status_not_implemented: return rocblas_status_not_implemented;
case rocsparse_status_invalid_pointer: return rocblas_status_invalid_pointer;
case rocsparse_status_invalid_size: return rocblas_status_invalid_size;
case rocsparse_status_memory_error: return rocblas_status_memory_error;
case rocsparse_status_invalid_value: return rocblas_status_invalid_value;
default: return rocblas_status_internal_error;
}
}
#define GOTO_IF_ERROR(expr, result, error_label) \
do \
{ \
result = to_rocsolver_status(expr); \
if(result != rocblas_status_success) \
goto error_label; \
} while(0)
#define RETURN_IF_ERROR(expr) \
do \
{ \
rocblas_status _result = to_rocsolver_status(expr); \
if(_result != rocblas_status_success) \
return _result; \
} while(0)
extern "C" rocblas_status rocsolver_create_rfinfo(rocsolver_rfinfo* rfinfo, rocblas_handle handle)
{
#ifdef ROCSOLVER_WITH_ROCSPARSE
if(!handle)
return rocblas_status_invalid_handle;
if(!rfinfo)
return rocblas_status_invalid_pointer;
rocsolver_rfinfo_* impl = (rocsolver_rfinfo_*)malloc(sizeof(rocsolver_rfinfo_));
if(!impl)
return rocblas_status_memory_error;
memset(impl, 0, sizeof(rocsolver_rfinfo_));
rocblas_status result;
// create sparse handle
GOTO_IF_ERROR(rocsparse_create_handle(&impl->sphandle), result, cleanup);
// use handle->stream to sphandle->stream
hipStream_t stream;
GOTO_IF_ERROR(rocblas_get_stream(handle, &stream), result, cleanup);
GOTO_IF_ERROR(rocsparse_set_stream(sphandle, stream), result, cleanup);
// create and set matrix descriptors
GOTO_IF_ERROR(rocsparse_create_mat_descr(&impl->descrL), result, cleanup);
GOTO_IF_ERROR(rocsparse_set_mat_type(impl->descrL, rocsparse_matrix_type_general), result,
cleanup);
GOTO_IF_ERROR(rocsparse_set_mat_index_base(impl->descrL, rocsparse_index_base_zero), result,
cleanup);
GOTO_IF_ERROR(rocsparse_set_mat_fill_mode(impl->descrL, rocsparse_fill_mode_lower), result,
cleanup);
GOTO_IF_ERROR(rocsparse_set_mat_diag_type(impl->descrL, rocsparse_diag_type_unit), result,
cleanup);
GOTO_IF_ERROR(rocsparse_create_mat_descr(&impl->descrU), result, cleanup);
GOTO_IF_ERROR(rocsparse_set_mat_type(impl->descrU, rocsparse_matrix_type_general), result,
cleanup);
GOTO_IF_ERROR(rocsparse_set_mat_index_base(impl->descrU, rocsparse_index_base_zero), result,
cleanup);
GOTO_IF_ERROR(rocsparse_set_mat_fill_mode(impl->descrU, rocsparse_fill_mode_upper), result,
cleanup);
GOTO_IF_ERROR(rocsparse_set_mat_diag_type(impl->descrU, rocsparse_diag_type_non_unit), result,
cleanup);
GOTO_IF_ERROR(rocsparse_create_mat_descr(&impl->descrT), result, cleanup);
GOTO_IF_ERROR(rocsparse_set_mat_type(impl->descrT, rocsparse_matrix_type_general), result,
cleanup);
GOTO_IF_ERROR(rocsparse_set_mat_index_base(impl->descrT, rocsparse_index_base_zero), result,
cleanup);
// create info holders
GOTO_IF_ERROR(rocsparse_create_mat_info(&impl->infoL), result, cleanup);
GOTO_IF_ERROR(rocsparse_create_mat_info(&impl->infoU), result, cleanup);
GOTO_IF_ERROR(rocsparse_create_mat_info(&impl->infoT), result, cleanup);
impl->solve_policy = rocsparse_solve_policy_auto;
impl->analysis_policy = rocsparse_analysis_policy_reuse;
*rfinfo = impl;
return rocblas_status_success;
cleanup:
rocsparse_destroy_mat_info(impl->infoU);
rocsparse_destroy_mat_info(impl->infoL);
rocsparse_destroy_mat_descr(impl->descrT);
rocsparse_destroy_mat_descr(impl->descrU);
rocsparse_destroy_mat_descr(impl->descrL);
rocsparse_destroy_handle(impl->sphandle);
free(impl);
return result;
#else
return rocblas_status_not_implemented;
#endif
}
extern "C" rocblas_status rocsolver_destroy_rfinfo(rocsolver_rfinfo rfinfo)
{
#ifdef ROCSOLVER_WITH_ROCSPARSE
if(!rfinfo)
return rocblas_status_invalid_pointer;
RETURN_IF_ERROR(rocsparse_destroy_mat_info(rfinfo->infoT));
RETURN_IF_ERROR(rocsparse_destroy_mat_info(rfinfo->infoU));
RETURN_IF_ERROR(rocsparse_destroy_mat_info(rfinfo->infoL));
RETURN_IF_ERROR(rocsparse_destroy_mat_descr(rfinfo->descrT));
RETURN_IF_ERROR(rocsparse_destroy_mat_descr(rfinfo->descrU));
RETURN_IF_ERROR(rocsparse_destroy_mat_descr(rfinfo->descrL));
RETURN_IF_ERROR(rocsparse_destroy_handle(rfinfo->sphandle));
free(rfinfo);
return rocblas_status_success;
#else
return rocblas_status_not_implemented;
#endif
}
/* ************************************************************************
* Copyright (c) 2023 Advanced Micro Devices, Inc.
* ************************************************************************ */
#pragma once
#include "rocblas.hpp"
#include "rocsolver/rocsolver.h"
#include "rocsparse.hpp"
struct rocsolver_rfinfo_
{
rocsparse_handle sphandle;
rocsparse_mat_descr descrL;
rocsparse_mat_descr descrU;
rocsparse_mat_descr descrT;
rocsparse_mat_info infoL;
rocsparse_mat_info infoU;
rocsparse_mat_info infoT;
rocsparse_solve_policy solve_policy;
rocsparse_analysis_policy analysis_policy;
};
typedef struct rocsolver_rfinfo_* rocsolver_rfinfo;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment