"...targets/git@developer.sourcefind.cn:gaoqiong/migraphx.git" did not exist on "a2f8e035987c8c49b51c88d71f3b04e2a0bc8fda"
Commit c0563b9e authored by Artur Wojcik's avatar Artur Wojcik
Browse files

Merge branch 'develop' into uif2-initial

parents 01cf30d9 c58e7d89
...@@ -55,8 +55,11 @@ include(CTest) ...@@ -55,8 +55,11 @@ include(CTest)
find_package(ROCM REQUIRED) find_package(ROCM REQUIRED)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
include(CMakeDependentOption) if(WIN32)
cmake_dependent_option(MIGRAPHX_ENABLE_PYTHON "Enable python bindings" ON "WIN32" OFF) option(MIGRAPHX_ENABLE_PYTHON "Enable python bindings" OFF)
else()
option(MIGRAPHX_ENABLE_PYTHON "Enable python bindings" ON)
endif()
# By default build shared libraries # By default build shared libraries
option(BUILD_SHARED_LIBS "Create shared libraries" ON) option(BUILD_SHARED_LIBS "Create shared libraries" ON)
......
...@@ -32,6 +32,10 @@ migraphx_generate_export_header(migraphx_c DIRECTORY migraphx/api) ...@@ -32,6 +32,10 @@ migraphx_generate_export_header(migraphx_c DIRECTORY migraphx/api)
# bumped when binary compatibility is broken. # bumped when binary compatibility is broken.
rocm_set_soversion(migraphx_c 3.0) rocm_set_soversion(migraphx_c 3.0)
if(BUILD_TESTING)
target_compile_definitions(migraphx_c PRIVATE MIGRAPHX_BUILD_TESTING)
endif()
rocm_clang_tidy_check(migraphx_c) rocm_clang_tidy_check(migraphx_c)
target_link_libraries(migraphx_c PRIVATE migraphx migraphx_tf migraphx_onnx) target_link_libraries(migraphx_c PRIVATE migraphx migraphx_tf migraphx_onnx)
......
...@@ -53,6 +53,7 @@ target_link_libraries(driver migraphx_all_targets migraphx_onnx migraphx_tf) ...@@ -53,6 +53,7 @@ target_link_libraries(driver migraphx_all_targets migraphx_onnx migraphx_tf)
if(MIGRAPHX_ENABLE_PYTHON) if(MIGRAPHX_ENABLE_PYTHON)
target_link_libraries(driver migraphx_py) target_link_libraries(driver migraphx_py)
target_compile_definitions(driver PRIVATE MIGRAPHX_ENABLE_PYTHON)
endif() endif()
rocm_install_targets( rocm_install_targets(
......
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. * Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
...@@ -27,12 +27,42 @@ ...@@ -27,12 +27,42 @@
#include <list> #include <list>
#include <functional> #include <functional>
#include <migraphx/config.hpp> #include <migraphx/config.hpp>
#include <migraphx/requires.hpp>
namespace migraphx { namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS { inline namespace MIGRAPHX_INLINE_NS {
struct instruction; struct instruction;
#if defined(_WIN32) && !defined(NDEBUG)
struct instruction_ref : std::list<instruction>::iterator
{
using instruction_iter = std::list<instruction>::iterator;
using instruction_const_iter = std::list<instruction>::const_iterator;
instruction_ref() = default;
instruction_ref(const instruction_iter& other) : instruction_iter(other) {}
template <class T,
class U,
MIGRAPHX_REQUIRES(std::is_same<T, instruction_ref>{} or
std::is_same<U, instruction_ref>{})>
friend bool operator==(const T& x, const U& y)
{
return x._Unwrapped()._Ptr == y._Unwrapped()._Ptr;
}
template <class T,
class U,
MIGRAPHX_REQUIRES(std::is_same<T, instruction_ref>{} or
std::is_same<U, instruction_ref>{})>
friend bool operator!=(const T& x, const U& y)
{
return !(x == y);
}
};
#else
using instruction_ref = std::list<instruction>::iterator; using instruction_ref = std::list<instruction>::iterator;
#endif
MIGRAPHX_EXPORT migraphx::instruction* as_address(const instruction_ref& ins) noexcept; MIGRAPHX_EXPORT migraphx::instruction* as_address(const instruction_ref& ins) noexcept;
......
...@@ -87,8 +87,7 @@ struct parse_depthtospace : op_parser<parse_depthtospace> ...@@ -87,8 +87,7 @@ struct parse_depthtospace : op_parser<parse_depthtospace>
auto temp1 = info.add_instruction(make_op("reshape", {{"dims", lens1}}), args[0]); auto temp1 = info.add_instruction(make_op("reshape", {{"dims", lens1}}), args[0]);
auto temp2 = info.add_instruction(make_op("transpose", {{"permutation", perm}}), temp1); auto temp2 = info.add_instruction(make_op("transpose", {{"permutation", perm}}), temp1);
return info.add_instruction(make_op("reshape", {{"dims", lens2}}), return info.add_instruction(make_op("reshape", {{"dims", lens2}}), temp2);
info.make_contiguous(temp2));
} }
}; };
......
...@@ -53,8 +53,7 @@ struct parse_reshape : op_parser<parse_reshape> ...@@ -53,8 +53,7 @@ struct parse_reshape : op_parser<parse_reshape>
s.visit([&](auto v) { copy(v, std::back_inserter(dims)); }); s.visit([&](auto v) { copy(v, std::back_inserter(dims)); });
} }
auto cont = info.add_instruction(make_op("contiguous"), args[0]); return info.add_instruction(make_op("reshape", {{"dims", dims}}), args[0]);
return info.add_instruction(make_op("reshape", {{"dims", dims}}), cont);
} }
}; };
......
...@@ -73,8 +73,7 @@ struct parse_spacetodepth : op_parser<parse_spacetodepth> ...@@ -73,8 +73,7 @@ struct parse_spacetodepth : op_parser<parse_spacetodepth>
std::vector<int64_t> perm = {0, 3, 5, 1, 2, 4}; std::vector<int64_t> perm = {0, 3, 5, 1, 2, 4};
auto temp1 = info.add_instruction(make_op("reshape", {{"dims", trans_lens}}), args[0]); auto temp1 = info.add_instruction(make_op("reshape", {{"dims", trans_lens}}), args[0]);
auto temp2 = info.add_instruction(make_op("transpose", {{"permutation", perm}}), temp1); auto temp2 = info.add_instruction(make_op("transpose", {{"permutation", perm}}), temp1);
return info.add_instruction(make_op("reshape", {{"dims", res_lens}}), return info.add_instruction(make_op("reshape", {{"dims", res_lens}}), temp2);
info.make_contiguous(temp2));
} }
}; };
......
...@@ -105,7 +105,7 @@ class pipe ...@@ -105,7 +105,7 @@ class pipe
throw GetLastError(); throw GetLastError();
} }
pipe(const pipe&) = delete; pipe(const pipe&) = delete;
pipe& operator=(const pipe&) = delete; pipe& operator=(const pipe&) = delete;
pipe(pipe&&) = default; pipe(pipe&&) = default;
...@@ -206,7 +206,7 @@ int exec(const std::string& cmd) ...@@ -206,7 +206,7 @@ int exec(const std::string& cmd)
{ {
TCHAR buffer[MIGRAPHX_PROCESS_BUFSIZE]; TCHAR buffer[MIGRAPHX_PROCESS_BUFSIZE];
HANDLE std_out{GetStdHandle(STD_OUTPUT_HANDLE)}; HANDLE std_out{GetStdHandle(STD_OUTPUT_HANDLE)};
return (std_out == nullptr || std_out == INVALID_HANDLE_VALUE) return (std_out == nullptr or std_out == INVALID_HANDLE_VALUE)
? GetLastError() ? GetLastError()
: exec(cmd, [&](const pipe&, const pipe& out) { : exec(cmd, [&](const pipe&, const pipe& out) {
for(;;) for(;;)
...@@ -214,7 +214,7 @@ int exec(const std::string& cmd) ...@@ -214,7 +214,7 @@ int exec(const std::string& cmd)
if(auto result = out.read(buffer, MIGRAPHX_PROCESS_BUFSIZE)) if(auto result = out.read(buffer, MIGRAPHX_PROCESS_BUFSIZE))
{ {
auto [more_data, bytes_read] = *result; auto [more_data, bytes_read] = *result;
if(!more_data || bytes_read == 0) if(not more_data or bytes_read == 0)
break; break;
DWORD written; DWORD written;
if(WriteFile(std_out, buffer, bytes_read, &written, nullptr) == FALSE) if(WriteFile(std_out, buffer, bytes_read, &written, nullptr) == FALSE)
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
# THE SOFTWARE. # THE SOFTWARE.
##################################################################################### #####################################################################################
add_compile_definitions($<$<COMPILE_LANGUAGE:CXX,C>:MIGRAPHX_ENABLE_PYTHON>)
add_library(migraphx_py py_loader.cpp) add_library(migraphx_py py_loader.cpp)
migraphx_generate_export_header(migraphx_py) migraphx_generate_export_header(migraphx_py)
target_include_directories(migraphx_py PRIVATE include) target_include_directories(migraphx_py PRIVATE include)
......
...@@ -95,10 +95,7 @@ template <class F> ...@@ -95,10 +95,7 @@ template <class F>
struct execute_wrapper struct execute_wrapper
{ {
F f; F f;
argument operator()(context&, const std::vector<argument>& args) const argument operator()(context&, const std::vector<argument>& args) const { return f(args); }
{
return f(args);
}
}; };
template <class F> template <class F>
......
...@@ -45,8 +45,7 @@ struct parse_reshape : op_parser<parse_reshape> ...@@ -45,8 +45,7 @@ struct parse_reshape : op_parser<parse_reshape>
auto s = args[1]->eval(); auto s = args[1]->eval();
std::vector<int64_t> dims; std::vector<int64_t> dims;
s.visit([&](auto v) { copy(v, std::back_inserter(dims)); }); s.visit([&](auto v) { copy(v, std::back_inserter(dims)); });
return info.add_instruction(make_op("reshape", {{"dims", dims}}), return info.add_instruction(make_op("reshape", {{"dims", dims}}), args[0]);
info.make_contiguous(args[0]));
} }
}; };
......
...@@ -1772,8 +1772,7 @@ TEST_CASE(depthtospace_test) ...@@ -1772,8 +1772,7 @@ TEST_CASE(depthtospace_test)
mm->add_instruction(migraphx::make_op("reshape", {{"dims", {2, 2, 2, 2, 5, 5}}}), l0); mm->add_instruction(migraphx::make_op("reshape", {{"dims", {2, 2, 2, 2, 5, 5}}}), l0);
auto tmp2 = mm->add_instruction( auto tmp2 = mm->add_instruction(
migraphx::make_op("transpose", {{"permutation", {0, 3, 4, 1, 5, 2}}}), tmp1); migraphx::make_op("transpose", {{"permutation", {0, 3, 4, 1, 5, 2}}}), tmp1);
auto tmp3 = mm->add_instruction(migraphx::make_op("contiguous"), tmp2); mm->add_instruction(migraphx::make_op("reshape", {{"dims", {2, 2, 10, 10}}}), tmp2);
mm->add_instruction(migraphx::make_op("reshape", {{"dims", {2, 2, 10, 10}}}), tmp3);
auto prog = optimize_onnx("depthtospace_test.onnx"); auto prog = optimize_onnx("depthtospace_test.onnx");
EXPECT(p == prog); EXPECT(p == prog);
} }
...@@ -1787,8 +1786,7 @@ TEST_CASE(depthtospace_crd_test) ...@@ -1787,8 +1786,7 @@ TEST_CASE(depthtospace_crd_test)
mm->add_instruction(migraphx::make_op("reshape", {{"dims", {2, 2, 2, 2, 5, 5}}}), l0); mm->add_instruction(migraphx::make_op("reshape", {{"dims", {2, 2, 2, 2, 5, 5}}}), l0);
auto tmp2 = mm->add_instruction( auto tmp2 = mm->add_instruction(
migraphx::make_op("transpose", {{"permutation", {0, 1, 4, 2, 5, 3}}}), tmp1); migraphx::make_op("transpose", {{"permutation", {0, 1, 4, 2, 5, 3}}}), tmp1);
auto tmp3 = mm->add_instruction(migraphx::make_op("contiguous"), tmp2); mm->add_instruction(migraphx::make_op("reshape", {{"dims", {2, 2, 10, 10}}}), tmp2);
mm->add_instruction(migraphx::make_op("reshape", {{"dims", {2, 2, 10, 10}}}), tmp3);
auto prog = optimize_onnx("depthtospace_crd_test.onnx"); auto prog = optimize_onnx("depthtospace_crd_test.onnx");
EXPECT(p == prog); EXPECT(p == prog);
} }
...@@ -1802,8 +1800,7 @@ TEST_CASE(depthtospace_simple_test) ...@@ -1802,8 +1800,7 @@ TEST_CASE(depthtospace_simple_test)
mm->add_instruction(migraphx::make_op("reshape", {{"dims", {1, 2, 2, 2, 2, 3}}}), l0); mm->add_instruction(migraphx::make_op("reshape", {{"dims", {1, 2, 2, 2, 2, 3}}}), l0);
auto tmp2 = mm->add_instruction( auto tmp2 = mm->add_instruction(
migraphx::make_op("transpose", {{"permutation", {0, 3, 4, 1, 5, 2}}}), tmp1); migraphx::make_op("transpose", {{"permutation", {0, 3, 4, 1, 5, 2}}}), tmp1);
auto tmp3 = mm->add_instruction(migraphx::make_op("contiguous"), tmp2); mm->add_instruction(migraphx::make_op("reshape", {{"dims", {1, 2, 4, 6}}}), tmp2);
mm->add_instruction(migraphx::make_op("reshape", {{"dims", {1, 2, 4, 6}}}), tmp3);
auto prog = optimize_onnx("depthtospace_simple_test.onnx"); auto prog = optimize_onnx("depthtospace_simple_test.onnx");
EXPECT(p == prog); EXPECT(p == prog);
} }
...@@ -1817,8 +1814,7 @@ TEST_CASE(spacetodepth_test) ...@@ -1817,8 +1814,7 @@ TEST_CASE(spacetodepth_test)
mm->add_instruction(migraphx::make_op("reshape", {{"dims", {2, 2, 5, 2, 5, 2}}}), l0); mm->add_instruction(migraphx::make_op("reshape", {{"dims", {2, 2, 5, 2, 5, 2}}}), l0);
auto tmp2 = mm->add_instruction( auto tmp2 = mm->add_instruction(
migraphx::make_op("transpose", {{"permutation", {0, 3, 5, 1, 2, 4}}}), tmp1); migraphx::make_op("transpose", {{"permutation", {0, 3, 5, 1, 2, 4}}}), tmp1);
auto tmp3 = mm->add_instruction(migraphx::make_op("contiguous"), tmp2); mm->add_instruction(migraphx::make_op("reshape", {{"dims", {2, 8, 5, 5}}}), tmp2);
mm->add_instruction(migraphx::make_op("reshape", {{"dims", {2, 8, 5, 5}}}), tmp3);
auto prog = optimize_onnx("spacetodepth_test.onnx"); auto prog = optimize_onnx("spacetodepth_test.onnx");
EXPECT(p == prog); EXPECT(p == prog);
} }
...@@ -1832,8 +1828,7 @@ TEST_CASE(spacetodepth_simple_test) ...@@ -1832,8 +1828,7 @@ TEST_CASE(spacetodepth_simple_test)
mm->add_instruction(migraphx::make_op("reshape", {{"dims", {1, 2, 2, 2, 3, 2}}}), l0); mm->add_instruction(migraphx::make_op("reshape", {{"dims", {1, 2, 2, 2, 3, 2}}}), l0);
auto tmp2 = mm->add_instruction( auto tmp2 = mm->add_instruction(
migraphx::make_op("transpose", {{"permutation", {0, 3, 5, 1, 2, 4}}}), tmp1); migraphx::make_op("transpose", {{"permutation", {0, 3, 5, 1, 2, 4}}}), tmp1);
auto tmp3 = mm->add_instruction(migraphx::make_op("contiguous"), tmp2); mm->add_instruction(migraphx::make_op("reshape", {{"dims", {1, 8, 2, 3}}}), tmp2);
mm->add_instruction(migraphx::make_op("reshape", {{"dims", {1, 8, 2, 3}}}), tmp3);
auto prog = optimize_onnx("spacetodepth_simple_test.onnx"); auto prog = optimize_onnx("spacetodepth_simple_test.onnx");
EXPECT(p == prog); EXPECT(p == prog);
} }
...@@ -5491,12 +5486,9 @@ TEST_CASE(reshape_test) ...@@ -5491,12 +5486,9 @@ TEST_CASE(reshape_test)
migraphx::literal{migraphx::shape{migraphx::shape::int64_type, {2}}, reshape_dims}); migraphx::literal{migraphx::shape{migraphx::shape::int64_type, {2}}, reshape_dims});
auto l0 = mm->add_parameter("0", migraphx::shape{migraphx::shape::float_type, {4, 2, 3}}); auto l0 = mm->add_parameter("0", migraphx::shape{migraphx::shape::float_type, {4, 2, 3}});
op.dims = reshape_dims; op.dims = reshape_dims;
auto c0 = mm->add_instruction(migraphx::make_op("contiguous"), l0); mm->add_instruction(op, l0);
mm->add_instruction(op, c0); mm->add_instruction(op, l0);
auto c1 = mm->add_instruction(migraphx::make_op("contiguous"), l0);
mm->add_instruction(op, c1);
auto prog = optimize_onnx("reshape_test.onnx"); auto prog = optimize_onnx("reshape_test.onnx");
EXPECT(p == prog); EXPECT(p == prog);
} }
...@@ -5509,8 +5501,7 @@ TEST_CASE(reshape_non_standard_test) ...@@ -5509,8 +5501,7 @@ TEST_CASE(reshape_non_standard_test)
auto x = mm->add_parameter("x", s); auto x = mm->add_parameter("x", s);
auto tran_x = auto tran_x =
mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 2, 1}}}), x); mm->add_instruction(migraphx::make_op("transpose", {{"permutation", {0, 2, 1}}}), x);
auto cont_x = mm->add_instruction(migraphx::make_op("contiguous"), tran_x); mm->add_instruction(migraphx::make_op("reshape", {{"dims", {4, 3, 2}}}), tran_x);
mm->add_instruction(migraphx::make_op("reshape", {{"dims", {4, 3, 2}}}), cont_x);
auto prog = optimize_onnx("reshape_non_standard_test.onnx"); auto prog = optimize_onnx("reshape_non_standard_test.onnx");
EXPECT(p == prog); EXPECT(p == prog);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
##################################################################################### #####################################################################################
# The MIT License (MIT) # The MIT License (MIT)
# #
# Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. # Copyright (c) 2015-2023 Advanced Micro Devices, Inc. All rights reserved.
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal # of this software and associated documentation files (the "Software"), to deal
...@@ -27,11 +27,11 @@ import sys ...@@ -27,11 +27,11 @@ import sys
debug = False debug = False
# The filetypes we want to check for that are stamped # The filetypes we want to check for that are stamped
# LICENSE is included here as it SHOULD have a liscence in it otherwise flag it as unstamped # LICENSE is included here as it SHOULD have a license in it otherwise flag it as unstamped
supported_file_types = (".cpp", ".hpp", ".h", ".ipynb", ".py", ".txt", ".sh", supported_file_types = (".cpp", ".hpp", ".h", ".ipynb", ".py", ".txt", ".sh",
".bsh", "LICENSE", ".cmake") ".bsh", "LICENSE", ".cmake")
#add general stuff we shouldn't stamp and any exceptions here # add general stuff we shouldn't stamp and any exceptions here
unsupported_file_types = [ unsupported_file_types = [
".onnx", ".pb", ".rst", ".jpg", ".jpeg", ".proto", ".md", ".clang", ".onnx", ".pb", ".rst", ".jpg", ".jpeg", ".proto", ".md", ".clang",
".weight", ".ini", ".json", ".docker", ".git", ".rules", ".yml" ".weight", ".ini", ".json", ".docker", ".git", ".rules", ".yml"
...@@ -40,105 +40,89 @@ unsupported_file_types = [ ...@@ -40,105 +40,89 @@ unsupported_file_types = [
specificIgnores = ("digits.txt", "Dockerfile", "Jenkinsfile", "") specificIgnores = ("digits.txt", "Dockerfile", "Jenkinsfile", "")
def hasKeySequence(inputfile, key_message): def hasKeySequence(inputfile: str, key_message: str) -> bool:
result = False
if key_message in inputfile: if key_message in inputfile:
result = True return True
return result return False
#Simple just open and write stuff to each file with the license stamp # Simple just open and write stuff to each file with the license stamp
def openAndCheckFile(filename): def needStampCheck(filename: str) -> bool:
result = False # open save old contents and append things here
#open save old contents and append things here if debug: print("Open", filename, end=' ')
if debug is True:
print("Open", filename, end='')
try: try:
file = open(filename, 'r') file = open(filename, 'r')
except OSError as e: except OSError as e:
if debug is True: if debug: print(str(e) + "....Open Error: Skipping file ")
print(str(e) + "....Open Error: Skipping file ")
file.close() file.close()
return return False
else: else:
with file as contents: with file as contents:
try: try:
save = contents.read() save = contents.read()
hasAmdLic = hasKeySequence(
save, "Advanced Micro Devices, Inc. All rights reserved")
#Check if we have a licence stamp already # Check if we have a license stamp already
if hasAmdLic is True: if hasKeySequence(
if debug is True: save,
print("....Already Stamped: Skipping file ") "Advanced Micro Devices, Inc. All rights reserved"):
if debug: print("....Already Stamped: Skipping file ")
contents.close() contents.close()
result = True return False
except UnicodeDecodeError as eu: except UnicodeDecodeError as eu:
if debug is True: if debug: print(f"{str(eu)}...Skipping binary file ")
print(str(eu) + "...Skipping binary file ")
contents.close() contents.close()
result = True return False
return result return True
# Deterine if filename is desired in the fileTuple past in # Check if any element in fileTuple is in filename
def check_filename(filename, fileTuple): def check_filename(filename: str, fileTuple: tuple or list) -> bool:
supported = False if any([x in filename for x in fileTuple]):
for key in fileTuple: return True
if key in filename: return False
supported = True
break
return supported
def main(): def main() -> None:
unsupported_file_types.extend(specificIgnores) unsupported_file_types.extend(specificIgnores)
#Get a list of all the tracked files in our git repo # Get a list of all the tracked files in our git repo
proc = subprocess.run("git ls-files --exclude-standard", proc = subprocess.run("git ls-files --exclude-standard",
shell=True, shell=True,
stdout=subprocess.PIPE) stdout=subprocess.PIPE)
fileList = proc.stdout.decode().split('\n') fileList = proc.stdout.decode().split('\n')
if debug is True: if debug: print("Target file list:\n" + str(fileList))
print("Target file list:\n" + str(fileList))
unsupportedFiles = [] unsupportedFiles = []
unstampedFiles = [] unstampedFiles = []
unknownFiles = [] unknownFiles = []
for file in fileList: for file in fileList:
supported = check_filename(file, supported_file_types) if check_filename(file, supported_file_types):
if supported is True: if needStampCheck(file):
isStamped = openAndCheckFile(file)
if isStamped is False:
unstampedFiles.append(file) unstampedFiles.append(file)
elif check_filename(file, unsupported_file_types):
unsupportedFiles.append(file)
else: else:
unsupported = check_filename(file, unsupported_file_types) unknownFiles.append(file)
if unsupported is True:
unsupportedFiles.append(file)
else:
unknownFiles.append(file)
#Do a bunch of checks based on our file lists # Do a bunch of checks based on our file lists
if len(unstampedFiles) > 0: if len(unstampedFiles) > 0:
print("Error: The following " + str(len(unstampedFiles)) + print("\nError: The following " + str(len(unstampedFiles)) +
" files are currently without a license:") " files are currently without a license:")
print(str(unstampedFiles)) print(str(unstampedFiles))
sys.exit(1) sys.exit(1)
if len(unknownFiles) > 0: if len(unknownFiles) > 0:
print("Error: The following " + str(len(unknownFiles)) + print("\nError: The following " + str(len(unknownFiles)) +
" files not handled:") " files not handled:")
print(str(unknownFiles)) print(str(unknownFiles))
sys.exit(2) sys.exit(2)
sys.exit(0)
if __name__ == "__main__": if __name__ == "__main__":
main() main()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment