Skip to content

Commit

Permalink
[Feature](mlu-ops): add lite-kernels config files. (#1197)
Browse files Browse the repository at this point in the history
  • Loading branch information
PetrelYy authored Jan 17, 2025
1 parent c14b817 commit b2f930a
Show file tree
Hide file tree
Showing 10 changed files with 308 additions and 36 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
test/mlu_op_gtest/pb_gtest/src/gtest/case_list.cpp
test/mlu_op_gtest/pb_gtest/src/gtest/op_register.h
bangc_kernels_collection.h
daily.software.cambricon.com/
dep_libs_extract
dependency.txt
test/mlu_op_gtest/pb_gtest/src/gtest/case_list.cpp
test/mlu_op_gtest/pb_gtest/src/gtest/op_register.h

# Swap
[._]*.s[a-v][a-z]
Expand Down
6 changes: 5 additions & 1 deletion bangc_helper_dtype.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*************************************************************************/
#pragma once

#ifndef BANGC_HELPER_DTYPE_H_
#define BANGC_HELPER_DTYPE_H_

/**
* Provides `BANG_WRAP_T(ptr_arg)` for .cc and `BANG_UNWRAP_T(ptr_arg)` for .mlu
Expand Down Expand Up @@ -111,3 +113,5 @@ using bang_unwrap_data_t = typename bang_unwrap_data<T>::type;
#define BANG_UNWRAP_T(a) reinterpret_cast<bang_unwrap_data_t<decltype(a)>>(a)

#endif // __BANG__

#endif // BANGC_HELPER_DTYPE_H_
10 changes: 9 additions & 1 deletion independent_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ SCRIPT_DIR=`dirname $0`
BUILD_PATH=${SCRIPT_DIR}/build
CMAKE=cmake
MLUOP_TARGET_CPU_ARCH=`uname -m`

GEN_SYMBOL_VIS_FILE_PY="./scripts/gen_symbol_visibility_map.py"
GEN_BANGC_KERNELS_COLLECTION_H_PY="./scripts/bangc_kernels_path_config/bangc_kernels_gen_header_file_for_mlu_ops.py"
BANGC_KERNEL_PATH_CHECK="./scripts/bangc_kernels_path_config/bangc_kernels_path_check.py"
MLUOP_SYMBOL_VIS_FILE="symbol_visibility.map"
TARGET_SYMBOL_FILE="mlu_op.h"
TARGET_SYMBOL_FILE_LITE_COLLECTION="test/mlu_op_gtest/pb_gtest/include/bangc_kernels_collection.h"
TARGET_SYMBOL_FILE_LITE_COLLECTION="bangc_kernels_collection.h"
PACKAGE_EXTRACT_DIR="dep_libs_extract"

PROG_NAME=$(basename $0) # current script filename, DO NOT EDIT
Expand Down Expand Up @@ -459,6 +462,11 @@ fi
export PATH=${NEUWARE_HOME}/bin:$PATH
export LD_LIBRARY_PATH=${NEUWARE_HOME}/lib64:$LD_LIBRARY_PATH

# GEN_BANGC_KERNELS_COLLECTION_H_PY="scripts/bangc_kernels_path_config/bangc_kernels_gen_header_file_for_mlu_ops.py"
# BANGC_KERNEL_PATH_CHECK="scripts/bangc_kernels_path_config/bangc_kernels_path_check.py"
python3 ${BANGC_KERNEL_PATH_CHECK}
python3 ${GEN_BANGC_KERNELS_COLLECTION_H_PY}

prog_log_info "generate ${MLUOP_SYMBOL_VIS_FILE} file."
prog_log_info "python3 ${GEN_SYMBOL_VIS_FILE_PY} ${BUILD_PATH}/${MLUOP_SYMBOL_VIS_FILE} ${TARGET_SYMBOL_FILE} ${TARGET_SYMBOL_FILE_LITE_COLLECTION}"
python3 ${GEN_SYMBOL_VIS_FILE_PY} ${BUILD_PATH}/${MLUOP_SYMBOL_VIS_FILE} ${TARGET_SYMBOL_FILE} ${TARGET_SYMBOL_FILE_LITE_COLLECTION}
Expand Down
5 changes: 5 additions & 0 deletions kernels/adam_w/adam_w_lite.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*************************************************************************/

#ifndef KERNELS_ADAM_W_LITE_ADAM_W_LITE_H_
#define KERNELS_ADAM_W_LITE_ADAM_W_LITE_H_

#include "bangc_helper_dtype.h"
#include "bangc_kernels.h"

Expand Down Expand Up @@ -116,3 +119,5 @@ bangcKernelsStatus_t BANGC_KERNELS_WIN_API mluAdamW(const cnrtQueue_t queue,
float *velocity);

NAMESPACE_BANGC_KERNELS_END

#endif // KERNELS_ADAM_W_LITE_ADAM_W_LITE_H_
5 changes: 5 additions & 0 deletions kernels/adam_w/adam_w_union1.mluh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*************************************************************************/

#ifndef KERNELS_ADAM_W_LITE_UNION1_ADAM_W_LITE_UNION1_MLUH_
#define KERNELS_ADAM_W_LITE_UNION1_ADAM_W_LITE_UNION1_MLUH_

#include <mlu.h>

#include "kernels/debug.h"
Expand Down Expand Up @@ -220,3 +223,5 @@ __mlu_global__ void unionApplyAdamW(T *param_h, T *grad, float *param,
}
PERF_TIME_END();
}

#endif // KERNELS_ADAM_W_LITE_UNION1_ADAM_W_LITE_UNION1_MLUH_
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Copyright (C) [2025] by Cambricon, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall self.tcp included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS self.tcp LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# pylint: disable=invalid-name, missing-class-docstring, missing-function-docstring
# pylint: disable=attribute-defined-outside-init
#!/usr/bin/env python3

import os

from bangc_kernels_path_check import extract_headers,find_json_files

license_and_pragma_once = '''
/*************************************************************************
* Copyright (C) [2025] by Cambricon, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*************************************************************************/
#pragma once
'''

def write_string_to_file(long_string, filename):
try:
with open(filename, 'w') as file:
file.write(long_string)
print(f"Successfully wrote the license to {filename}")
except Exception as e:
print(f"Failed to write the license. Error: {e}")


def write_paths_to_file(path_list, filename):
try:
with open(filename, 'a') as file:
for path in path_list:
if "/" in path: file.write(f'\n')
file.write(f'#include "{path}"\n')
print(f"Successfully wrote the {path} to {filename}")
except Exception as e:
print(f"Failed to write the {path} . Error: {e}")


if __name__ == "__main__":
try:
# get header_files
header_files = []
json_paths = find_json_files(os.path.dirname(__file__))
for path in json_paths:
files_path,_ = extract_headers(path, False, True, False)
header_files.extend(files_path) if isinstance(files_path, list) else header_files.append(files_path)
header_files_unique = sorted(list(set(header_files)))

# gen bangc_kernels_collection.h
mlu_ops_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
filename = mlu_ops_path + "/bangc_kernels_collection.h"
write_string_to_file(license_and_pragma_once, filename)
write_paths_to_file(header_files_unique, filename)

except Exception as e:
print(f"[ERROR] The generation of file bangc_kernels_collection.h failed. : {e}")
20 changes: 20 additions & 0 deletions scripts/bangc_kernels_path_config/bangc_kernels_path.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"common": [
"bangc_helper_dtype.h",
"bangc_kernels.h",
"kernels/debug.h",
"kernels/device_check.h",
"kernels/kernel.h"
],

"operators": [
{
"name": "mluAdamW",
"header": "kernels/adam_w/adam_w_lite.h",
"sources": [
"kernels/adam_w/adam_w_union1.mluh",
"kernels/adam_w/adam_w_lite_union1.mlu"
]
}
]
}
143 changes: 143 additions & 0 deletions scripts/bangc_kernels_path_config/bangc_kernels_path_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# Copyright (C) [2025] by Cambricon, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall self.tcp included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS self.tcp LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# pylint: disable=invalid-name, missing-class-docstring, missing-function-docstring
# pylint: disable=attribute-defined-outside-init
#!/usr/bin/env python3
import json

import os
import logging

# search cpp,h,mlu,mluh
def find_files_in_path(relative_path):
list_path = []
for root, dirs, files in os.walk(relative_path):
for file in files:
if file.endswith('.h') or file.endswith('.cpp') or file.endswith('.mlu') or file.endswith('.mluh'):
full_path = os.path.join(root, file)
list_path.append(full_path)
return list_path


# search JSON
def find_json_files(absolute_path):
json_files = []
for root, dirs, files in os.walk(absolute_path):
for file in files:
if file.endswith('.json'):
full_path = os.path.join(root, file)
json_files.append(full_path)
return json_files


def get_relative_paths(absolute_path):
relative_paths = []
# base_folder = os.path.basename(absolute_path)
base_folder = ""
for folder, dirs, files in os.walk(absolute_path):
# get relative_folder path
relative_folder = os.path.relpath(folder, start=absolute_path)

# concat path
for file in files:
if file.endswith('.h') or file.endswith('.cpp') or file.endswith('.mlu') or file.endswith('.mluh'):
if relative_folder == '.':
full_path = os.path.join(base_folder, file)
else:
full_path = os.path.join(base_folder, relative_folder, file)
relative_paths.append(full_path)
return relative_paths


# parsing JSON file
def extract_headers(json_file_path, common_flag=True, header_flag=True, sources_flag=True):
header_files = []
op_name = []
try:
with open(json_file_path, 'r') as file:
config = json.load(file)
except FileNotFoundError:
print(f"The JSON file at {json_file_path} was not found.")
return [], []
except json.JSONDecodeError:
print(f"Error decoding JSON from the file at {json_file_path}.")
return [], []

# JSON.common
if 'common' in config and common_flag:
header_files.extend(config['common'])

# JSON.operators {op_name, header, sources}
if 'operators' in config:
for operator in config['operators']:
if 'name' in operator:
if isinstance(operator['name'], list):
op_name.extend(operator['name'])
else:
op_name.append(operator['name'])

if 'header' in operator and header_flag:
if isinstance(operator['header'], list):
header_files.extend(operator['header'])
else:
header_files.append(operator['header'])

if 'sources' in operator and sources_flag:
if isinstance(operator['sources'], list):
header_files.extend(operator['sources'])
else:
header_files.append(operator['sources'])

return header_files, op_name


'''
params:
1. header_files_all: all .h/.mlu/.mluh/.cpp paths under "mlu-ops/"
2. header_files: all .h/.mlu/.mluh/.cpp paths form JSON
3. header_files_unique: Deduplicated header_files
'''
if __name__ == "__main__":
try:
# get header_files_all
mlu_ops_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
header_files_all = get_relative_paths(mlu_ops_path)

# get header_files, op_name
header_files = []
op_name_list = []
json_paths = find_json_files(os.path.dirname(__file__))
for path in json_paths:
files_path, op_name = extract_headers(path, True, True, True)
print(path)
header_files.extend(files_path) if isinstance(files_path, list) else header_files.append(files_path)
op_name_list.extend(op_name) if isinstance(op_name, list) else header_files.append(op_name)

# get header_files_unique
header_files_unique = list(set(header_files))
assert len(header_files_unique) is len(header_files), "There are duplicate paths in JSON files {}. ".format(json_paths)
assert len(list(set(op_name_list))) is len(op_name_list), "There are duplicate op-name in JSON files {}. ".format(json_paths)
for path in header_files_unique:
assert path in header_files_all, f"The file path({path}) is not in mlu-ops/. "
print("Bangc kernels path check success.")

except Exception as e:
print(f"[ERROR] Check failed. : {e}")
24 changes: 24 additions & 0 deletions scripts/gen_symbol_visibility_map.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
# Copyright (C) [2025] by Cambricon, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall self.tcp included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS self.tcp LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# pylint: disable=invalid-name, missing-class-docstring, missing-function-docstring
# pylint: disable=attribute-defined-outside-init

import re
import sys

Expand Down Expand Up @@ -54,6 +77,7 @@ def create_map_file(map_file,node_msg_cp_finished):
for path in kernels_header_map:
node_msg_cp_finished += get_mluops(path)
create_map_file(map_file, node_msg_cp_finished)
print("Gen symbol visibility map success.")

except Exception as e:
print(f"[scripts/gen_symbol_visibility_map.py] An error occurred: {e}")
Loading

0 comments on commit b2f930a

Please sign in to comment.