Skip to content
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

Fix SDL warnings in CPU EP #9975

Merged
merged 53 commits into from
Dec 20, 2021
Merged

Fix SDL warnings in CPU EP #9975

merged 53 commits into from
Dec 20, 2021

Conversation

snnn
Copy link
Member

@snnn snnn commented Dec 8, 2021

Description:

  1. Solve some SDL warnings
  2. Refactor Training GPU Windows CI pipeline job, to make similar to the inference one. And I need to disable the static analysis for now. Fixing the warnings will need more changes, which will make this PR even bigger.
  3. Add a customized SDL ruleset file, which is based on the VC++ default one with a few additional enabled warnings. The list of warnings is picked up from https://docs.microsoft.com/en-us/cpp/code-quality/code-analysis-for-cpp-corecheck?view=msvc-170 . Some of the warnings enforce using unique_ptr/shared_ptr instead of raw pointer to meet our compliance requirement.

When this PR is checked in, if you have code like:

char *buffer = nullptr;
if (useCache)
    buffer = GetCache();
else
    buffer = new char[bufferSize];  // C26400

It will be rejected by static analyzer. Because 26400 is in our SDL.rules file. You may convert it to:

std::unique_ptr<char[]> buffer;
if (useCache)
    buffer = GetCache();
else
    buffer = std::make_unique<char[]>(bufferSize); 

We still have a lot C26451 warnings that I couldn't get them fixed this time. So I disabled them to make the CI pass. Next, I will add "C26406 DONT_ASSIGN_RAW_TO_OWNER" to the warning list.

To try the static analyzer locally, please open CMakeLists.txt and uncomment the following lines:

#if(WIN32 AND onnxruntime_ENABLE_STATIC_ANALYSIS)
  #  set_target_properties(${target_name} PROPERTIES VS_USER_PROPS ${PROJECT_SOURCE_DIR}/EnableVisualStudioCodeAnalysis.props)
#endif()

Then build it with "--extra_cmake_defines onnxruntime_ENABLE_STATIC_ANALYSIS=ON".
Motivation and Context

  • Why is this change required? What problem does it solve?

To meet compliance requirement and have better code quality. For example, C26478 is one of the warnings we will enable through this PR. And it helped me found a bug in conv_transpose_attributes.h

  • If it fixes an open issue, please link to the issue here.

@snnn snnn requested review from edgchen1 and pranavsharma December 8, 2021 20:41
@snnn snnn marked this pull request as draft December 9, 2021 20:04
@snnn snnn force-pushed the snnn/training_sdl branch 3 times, most recently from ed05fe4 to 02dfabb Compare December 14, 2021 03:12
@snnn snnn force-pushed the snnn/training_sdl branch from 9ad19d4 to 5ae6b24 Compare December 14, 2021 05:51
@@ -253,13 +254,6 @@ void LogRuntimeError(uint32_t session_id, const common::Status& status, const ch
} \
} while (0)

// C++ Core Guideline check suppression.
#if defined(_MSC_VER) && !defined(__NVCC__) && !defined(__clang__)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved it to a new file because onnxruntime::Status also wants to use this macro. But this file includes "core/common/status.h"

@@ -37,7 +37,7 @@ class KernelRegistry {
// TODO(Task:132) Make usage of unique_ptr/shared_ptr as out param consistent
Status TryCreateKernel(const Node& node, const IExecutionProvider& execution_provider,
const std::unordered_map<int, OrtValue>& constant_initialized_tensors,
const OrtValueNameIdxMap& mlvalue_name_idx_map, const FuncManager& funcs_mgr,
const OrtValueNameIdxMap& mlvalue_name_idx_map, FuncManager& funcs_mgr,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change funcs_mgr to non-const. Because this function may modify funcs_mgr's internal states. Previously we hided the fact.

using KernelCreateFn = std::function<OpKernel*(const OpKernelInfo& info)>;
using KernelCreatePtrFn = std::add_pointer<OpKernel*(const OpKernelInfo& info)>::type;
class FuncManager;
using KernelCreateFn = std::function<Status(FuncManager& func_mgr, const OpKernelInfo& info, std::unique_ptr<OpKernel>& out)>;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use unique_ptr to replace raw pointer. And make it be more obvious that it depends on a non-const FuncManager.

@@ -950,8 +950,14 @@ struct CustomOpBase : OrtCustomOp {
OrtCustomOp::GetOutputType = [](const OrtCustomOp* this_, size_t index) { return static_cast<const TOp*>(this_)->GetOutputType(index); };

OrtCustomOp::KernelCompute = [](void* op_kernel, OrtKernelContext* context) { static_cast<TKernel*>(op_kernel)->Compute(context); };
#if defined(_MSC_VER) && !defined(__clang__)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file can not use GSL macros. Because it is directly used by outside users.

pranavsharma
pranavsharma previously approved these changes Dec 18, 2021
include/onnxruntime/core/graph/graph.h Show resolved Hide resolved
@@ -50,7 +50,7 @@ struct ConvTransposeAttributes : public ConvAttributes {
const TensorShape& F_Shape = (filter_shape != nullptr) ? *filter_shape : F->Shape();
const Tensor* Pads = dynamic_padding ? context->Input<Tensor>(2) : nullptr;
const Tensor* B = has_bias ? (dynamic_padding ? context->Input<Tensor>(3) : context->Input<Tensor>(2)) : nullptr;
const TensorShape& input_shape = X->Shape().Slice(2);
TensorShape input_shape = X->Shape().Slice(2);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change fixed a bug.

The small program below reproduces the issue:

void BadCode(const std::string& s) {
    std::string p = std::move(s);
    std::cout << p << std::endl;
}

int _tmain(int argc, TCHAR* argv[])
{
    std::string s = "abc";
    std::cout << s << std::endl; //now it is empty.
    return 0;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the comment read - s "may" be empty after calling BadCode() ? I think the standard only expects that the source object is in a "valid" state after std::move is invoked (which may not necessarily be empty).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right.

@snnn snnn merged commit 4e9e01c into master Dec 20, 2021
@snnn snnn deleted the snnn/training_sdl branch December 20, 2021 04:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants