GitOrigin-RevId: bd964ed505
release-1.7
@@ -1,84 +0,0 @@ | |||||
# This code is licensed under the MIT License. See the FindBANG.cmake script | |||||
# for the text of the license. | |||||
# The MIT License | |||||
# | |||||
# License for the specific language governing rights and limitations under | |||||
# 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. | |||||
# | |||||
####################################################################### | |||||
# This converts a file written in makefile syntax into one that can be included | |||||
# by CMake. | |||||
file(READ ${input_file} depend_text) | |||||
if (NOT "${depend_text}" STREQUAL "") | |||||
# message("FOUND DEPENDS") | |||||
string(REPLACE "\\ " " " depend_text ${depend_text}) | |||||
# This works for the cncc -M generated dependency files. | |||||
string(REGEX REPLACE "^.* : " "" depend_text ${depend_text}) | |||||
string(REGEX REPLACE "[ \\\\]*\n" ";" depend_text ${depend_text}) | |||||
set(dependency_list "") | |||||
foreach(file ${depend_text}) | |||||
string(REGEX REPLACE "^ +" "" file ${file}) | |||||
# OK, now if we had a UNC path, cncc has a tendency to only output the first '/' | |||||
# instead of '//'. Here we will test to see if the file exists, if it doesn't then | |||||
# try to prepend another '/' to the path and test again. If it still fails remove the | |||||
# path. | |||||
if(NOT EXISTS "${file}") | |||||
if (EXISTS "/${file}") | |||||
set(file "/${file}") | |||||
else() | |||||
message(WARNING " Removing non-existent dependency file: ${file}") | |||||
set(file "") | |||||
endif() | |||||
endif() | |||||
if(NOT IS_DIRECTORY "${file}") | |||||
# If softlinks start to matter, we should change this to REALPATH. For now we need | |||||
# to flatten paths, because cncc can generate stuff like /bin/../include instead of | |||||
# just /include. | |||||
get_filename_component(file_absolute "${file}" ABSOLUTE) | |||||
list(APPEND dependency_list "${file_absolute}") | |||||
endif() | |||||
endforeach() | |||||
else() | |||||
# message("FOUND NO DEPENDS") | |||||
endif() | |||||
# Remove the duplicate entries and sort them. | |||||
list(REMOVE_DUPLICATES dependency_list) | |||||
list(SORT dependency_list) | |||||
foreach(file ${dependency_list}) | |||||
set(bang_cncc_depend "${bang_cncc_depend} \"${file}\"\n") | |||||
endforeach() | |||||
file(WRITE ${output_file} "# Generated by: make2cmake.cmake\nSET(BANG_CNCC_DEPEND\n ${bang_cncc_depend})\n\n") |
@@ -1,103 +0,0 @@ | |||||
# This code is licensed under the MIT License. See the FindBANG.cmake script | |||||
# for the text of the license. | |||||
# The MIT License | |||||
# | |||||
# License for the specific language governing rights and limitations under | |||||
# 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. | |||||
# | |||||
####################################################################### | |||||
# Parses a .cnbin file produced by cncc and reports statistics about the file. | |||||
file(READ ${input_file} file_text) | |||||
if (NOT "${file_text}" STREQUAL "") | |||||
string(REPLACE ";" "\\;" file_text ${file_text}) | |||||
string(REPLACE "\ncode" ";code" file_text ${file_text}) | |||||
list(LENGTH file_text len) | |||||
foreach(line ${file_text}) | |||||
# Only look at "code { }" blocks. | |||||
if(line MATCHES "^code") | |||||
# Break into individual lines. | |||||
string(REGEX REPLACE "\n" ";" line ${line}) | |||||
foreach(entry ${line}) | |||||
# Extract kernel names. | |||||
if (${entry} MATCHES "[^g]name = ([^ ]+)") | |||||
set(entry "${CMAKE_MATCH_1}") | |||||
# Check to see if the kernel name starts with "_" | |||||
set(skip FALSE) | |||||
# if (${entry} MATCHES "^_") | |||||
# Skip the rest of this block. | |||||
# message("Skipping ${entry}") | |||||
# set(skip TRUE) | |||||
# else () | |||||
message("Kernel: ${entry}") | |||||
# endif () | |||||
endif() | |||||
# Skip the rest of the block if necessary | |||||
if(NOT skip) | |||||
# Registers | |||||
if (${entry} MATCHES "reg([ ]+)=([ ]+)([^ ]+)") | |||||
set(entry "${CMAKE_MATCH_3}") | |||||
message("Registers: ${entry}") | |||||
endif() | |||||
# Local memory | |||||
if (${entry} MATCHES "lmem([ ]+)=([ ]+)([^ ]+)") | |||||
set(entry "${CMAKE_MATCH_3}") | |||||
message("Local: ${entry}") | |||||
endif() | |||||
# Shared memory | |||||
if (${entry} MATCHES "smem([ ]+)=([ ]+)([^ ]+)") | |||||
set(entry "${CMAKE_MATCH_3}") | |||||
message("Shared: ${entry}") | |||||
endif() | |||||
if (${entry} MATCHES "^}") | |||||
message("") | |||||
endif() | |||||
endif() | |||||
endforeach() | |||||
endif() | |||||
endforeach() | |||||
else() | |||||
# message("FOUND NO DEPENDS") | |||||
endif() | |||||
@@ -1,200 +0,0 @@ | |||||
# This code is licensed under the MIT License. See the FindBANG.cmake script | |||||
# for the text of the license. | |||||
# The MIT License | |||||
# | |||||
# License for the specific language governing rights and limitations under | |||||
# 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. | |||||
########################################################################## | |||||
# This file runs the cncc commands to produce the desired output file along with | |||||
# the dependency file needed by CMake to compute dependencies. In addition the | |||||
# file checks the output of each command and if the command fails it deletes the | |||||
# output files. | |||||
# Input variables | |||||
# | |||||
# verbose:BOOL=<> OFF: Be as quiet as possible (default) | |||||
# ON : Describe each step | |||||
# | |||||
# build_configuration:STRING=<> Typically one of Debug, MinSizeRel, Release, or | |||||
# RelWithDebInfo, but it should match one of the | |||||
# entries in BANG_HOST_FLAGS. This is the build | |||||
# configuration used when compiling the code. If | |||||
# blank or unspecified Debug is assumed as this is | |||||
# what CMake does. | |||||
# | |||||
# generated_file:STRING=<> File to generate. This argument must be passed in. | |||||
# | |||||
# generated_cnbin_file:STRING=<> File to generate. This argument must be passed | |||||
# in if build_cnbin is true. | |||||
if(NOT generated_file) | |||||
message(FATAL_ERROR "You must specify generated_file on the command line") | |||||
endif() | |||||
# Set these up as variables to make reading the generated file easier | |||||
set(CMAKE_COMMAND "@CMAKE_COMMAND@") # path | |||||
set(source_file "@source_file@") # path | |||||
set(CNCC_generated_dependency_file "@CNCC_generated_dependency_file@") # path | |||||
set(cmake_dependency_file "@cmake_dependency_file@") # path | |||||
set(BANG_make2cmake "@BANG_make2cmake@") # path | |||||
set(BANG_parse_cnbin "@BANG_parse_cnbin@") # path | |||||
set(build_cnbin @build_cnbin@) # bool | |||||
set(BANG_HOST_COMPILER "@BANG_HOST_COMPILER@") # path | |||||
# We won't actually use these variables for now, but we need to set this, in | |||||
# order to force this file to be run again if it changes. | |||||
set(generated_file_path "@generated_file_path@") # path | |||||
set(generated_file_internal "@generated_file@") # path | |||||
set(generated_cnbin_file_internal "@generated_cnbin_file@") # path | |||||
set(BANG_CNCC_EXECUTABLE "@BANG_CNCC_EXECUTABLE@") # path | |||||
set(BANG_CNCC_FLAGS @BANG_CNCC_FLAGS@ ;; @BANG_WRAP_OPTION_CNCC_FLAGS@) # list | |||||
@BANG_CNCC_FLAGS_CONFIG@ | |||||
set(cncc_flags @cncc_flags@) # list | |||||
set(BANG_CNCC_INCLUDE_ARGS "@BANG_CNCC_INCLUDE_ARGS@") # list (needs to be in quotes to handle spaces properly). | |||||
set(format_flag "@format_flag@") # string | |||||
set(bang_language_flag @bang_language_flag@) # list | |||||
if(build_cnbin AND NOT generated_cnbin_file) | |||||
message(FATAL_ERROR "You must specify generated_cnbin_file on the command line") | |||||
endif() | |||||
# This is the list of host compilation flags. It C or CXX should already have | |||||
# been chosen by FindBANG.cmake. | |||||
@BANG_HOST_FLAGS@ | |||||
# Take the compiler flags and package them up to be sent to the compiler via -Xcompiler | |||||
set(cncc_host_compiler_flags "") | |||||
# If we weren't given a build_configuration, use Debug. | |||||
if(NOT build_configuration) | |||||
set(build_configuration Debug) | |||||
endif() | |||||
string(TOUPPER "${build_configuration}" build_configuration) | |||||
#message("BANG_CNCC_HOST_COMPILER_FLAGS = ${BANG_CNCC_HOST_COMPILER_FLAGS}") | |||||
foreach(flag ${CMAKE_HOST_FLAGS} ${CMAKE_HOST_FLAGS_${build_configuration}}) | |||||
# Extra quotes are added around each flag to help cncc parse out flags with spaces. | |||||
set(cncc_host_compiler_flags ${cncc_host_compiler_flags} ${flag}) | |||||
endforeach() | |||||
# message("cncc_host_compiler_flags = ${cncc_host_compiler_flags}") | |||||
# Add the build specific configuration flags | |||||
list(APPEND BANG_CNCC_FLAGS ${BANG_CNCC_FLAGS_${build_configuration}}) | |||||
# Remove the duplicated flags and including | |||||
list(REMOVE_DUPLICATES BANG_CNCC_FLAGS) | |||||
list(REMOVE_DUPLICATES BANG_CNCC_INCLUDE_ARGS) | |||||
# bang_execute_process - Executes a command with optional command echo and status message. | |||||
# | |||||
# status - Status message to print if verbose is true | |||||
# command - COMMAND argument from the usual execute_process argument structure | |||||
# ARGN - Remaining arguments are the command with arguments | |||||
# | |||||
# BANG_result - return value from running the command | |||||
# | |||||
# Make this a macro instead of a function, so that things like RESULT_VARIABLE | |||||
# and other return variables are present after executing the process. | |||||
macro(bang_execute_process status command) | |||||
set(_command ${command}) | |||||
if(NOT "x${_command}" STREQUAL "xCOMMAND") | |||||
message(FATAL_ERROR "Malformed call to bang_execute_process. Missing COMMAND as second argument. (command = ${command})") | |||||
endif() | |||||
if(verbose) | |||||
execute_process(COMMAND "${CMAKE_COMMAND}" -E echo -- ${status}) | |||||
# Now we need to build up our command string. We are accounting for quotes | |||||
# and spaces, anything else is left up to the user to fix if they want to | |||||
# copy and paste a runnable command line. | |||||
set(bang_execute_process_string) | |||||
foreach(arg ${ARGN}) | |||||
# If there are quotes, excape them, so they come through. | |||||
string(REPLACE "\"" "\\\"" arg ${arg}) | |||||
# Args with spaces need quotes around them to get them to be parsed as a single argument. | |||||
if(arg MATCHES " ") | |||||
list(APPEND bang_execute_process_string "\"${arg}\"") | |||||
else() | |||||
list(APPEND bang_execute_process_string ${arg}) | |||||
endif() | |||||
endforeach() | |||||
# Echo the command | |||||
execute_process(COMMAND ${CMAKE_COMMAND} -E echo ${bang_execute_process_string}) | |||||
endif() | |||||
# Run the command | |||||
execute_process(COMMAND ${ARGN} RESULT_VARIABLE BANG_result ) | |||||
endmacro() | |||||
# Delete the target file | |||||
bang_execute_process( | |||||
"Removing ${generated_file}" | |||||
COMMAND "${CMAKE_COMMAND}" -E remove "${generated_file}" | |||||
) | |||||
# cncc ignore host flags | |||||
set(cncc_host_compiler_flags "") | |||||
# Generate the code | |||||
bang_execute_process( | |||||
"Generating ${generated_file}" | |||||
COMMAND "${BANG_CNCC_EXECUTABLE}" | |||||
"${source_file}" | |||||
${bang_language_flag} | |||||
${format_flag} -o "${generated_file}" | |||||
${cncc_flags} | |||||
${cncc_host_compiler_flags} | |||||
${BANG_CNCC_FLAGS} | |||||
-DCNCC | |||||
${BANG_CNCC_INCLUDE_ARGS} | |||||
) | |||||
if(BANG_result) | |||||
# Since cncc can sometimes leave half done files make sure that we delete the output file. | |||||
bang_execute_process( | |||||
"Removing ${generated_file}" | |||||
COMMAND "${CMAKE_COMMAND}" -E remove "${generated_file}" | |||||
) | |||||
message(FATAL_ERROR "Error generating file ${generated_file}") | |||||
else() | |||||
message(VERBOSE "Generated ${generated_file} successfully.") | |||||
endif() | |||||
# Cnbin resource report commands. | |||||
if( build_cnbin ) | |||||
# Run with -cnbin to produce resource usage report. | |||||
bang_execute_process( | |||||
"Generating ${generated_cnbin_file}" | |||||
COMMAND "${BANG_CNCC_EXECUTABLE}" | |||||
"${source_file}" | |||||
${BANG_CNCC_FLAGS} | |||||
${cncc_flags} | |||||
${cncc_host_compiler_flags} | |||||
-DCNCC | |||||
-cnbin | |||||
-o "${generated_cnbin_file}" | |||||
${BANG_CNCC_INCLUDE_ARGS} | |||||
) | |||||
# Execute the parser script. | |||||
bang_execute_process( | |||||
"Executing the parser script" | |||||
COMMAND "${CMAKE_COMMAND}" | |||||
-D "input_file:STRING=${generated_cnbin_file}" | |||||
-P "${BANG_parse_cnbin}" | |||||
) | |||||
endif() |
@@ -1,60 +0,0 @@ | |||||
/** | |||||
* \file include/megcore_cambricon.h | |||||
* | |||||
* This file is part of MegDNN, a deep neural network run-time library | |||||
* developed by Megvii. | |||||
* | |||||
* \copyright Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
*/ | |||||
#pragma once | |||||
#include "megcore.h" | |||||
#include <cndev.h> | |||||
#include <cnml.h> | |||||
#include <cnrt.h> | |||||
#include "megdnn/internal/visibility_prologue.h" | |||||
namespace megcore { | |||||
megcoreStatus_t createDeviceHandleWithGlobalInitStatus( | |||||
megcoreDeviceHandle_t* devHandle, int deviceID, unsigned int flags, | |||||
bool global_initialized); | |||||
struct CambriconContext { | |||||
cnrtQueue_t queue = nullptr; | |||||
CambriconContext() = default; | |||||
CambriconContext(cnrtQueue_t q) : queue{q} {} | |||||
}; | |||||
megcoreStatus_t createComputingHandleWithCambriconContext( | |||||
megcoreComputingHandle_t* compHandle, megcoreDeviceHandle_t devHandle, | |||||
unsigned int flags, const CambriconContext& ctx); | |||||
megcoreStatus_t getCambriconContext( | |||||
megcoreComputingHandle_t handle, CambriconContext* ctx); | |||||
} // namespace megcore | |||||
static inline megcoreStatus_t megcoreCreateComputingHandleWithCNRTQueue( | |||||
megcoreComputingHandle_t* compHandle, megcoreDeviceHandle_t devHandle, | |||||
unsigned int flags, cnrtQueue_t queue) { | |||||
megcore::CambriconContext ctx{queue}; | |||||
return megcore::createComputingHandleWithCambriconContext( | |||||
compHandle, devHandle, flags, ctx); | |||||
} | |||||
static inline megcoreStatus_t megcoreGetCNRTQueue( | |||||
megcoreComputingHandle_t handle, cnrtQueue_t* queue) { | |||||
megcore::CambriconContext ctx; | |||||
auto ret = megcore::getCambriconContext(handle, &ctx); | |||||
*queue = ctx.queue; | |||||
return ret; | |||||
} | |||||
#include "megdnn/internal/visibility_epilogue.h" | |||||
// vim: syntax=cpp.doxygen |
@@ -1,32 +0,0 @@ | |||||
load("//brain/megbrain/dnn:flags.bzl", "megdnn_opts") | |||||
load("@megvii3//tools/build_rules:bangc.bzl", "bangc_library") | |||||
package(default_visibility = ["//brain/megbrain/dnn:__subpackages__"]) | |||||
bangc_library( | |||||
name = "bangc_kernels", | |||||
srcs = glob([ | |||||
"**/*.mlu", | |||||
]) + [ | |||||
"//brain/megbrain/dnn:src/common/utils.cuh", | |||||
], | |||||
hdrs = glob([ | |||||
"**/*.mlu.h", | |||||
]), | |||||
deps = [ | |||||
"//brain/megbrain/dnn:public_headers", | |||||
"//brain/megbrain/sdk/build_config", | |||||
], | |||||
copts = megdnn_opts + [ | |||||
"-Ibrain/megbrain/dnn", | |||||
], | |||||
) | |||||
filegroup( | |||||
name = "cambricon_backend_files", | |||||
srcs = glob([ | |||||
"**/*.cpp", | |||||
"**/*.h", | |||||
"**/*.hpp", | |||||
]), | |||||
) |
@@ -1,25 +0,0 @@ | |||||
/** | |||||
* \file dnn/src/cambricon/checksum/checksum.mlu.h | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#pragma once | |||||
#include "src/cambricon/utils.mlu.h" | |||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
void checksum_kernel_union1(uint32_t* dst, const uint32_t* src, int num_elems); | |||||
void checksum_kernel_union4(uint32_t* dst, const uint32_t* src, int num_elems); | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif | |||||
// vim: ft=cpp syntax=cpp.doxygen |
@@ -1,61 +0,0 @@ | |||||
/** | |||||
* \file dnn/src/cambricon/checksum/checksum_kernel_union1.mlu | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#include "checksum.mlu.h" | |||||
#include "cnsccl.h" | |||||
#include "mlu.h" | |||||
#define CLUSTER_DIM 1 | |||||
#define CORE_DIM 4 | |||||
#define STRIDE 1024 | |||||
__mlu_entry__ void checksum_kernel_union1(uint32_t* dst, uint32_t* src, | |||||
int nr_elems) { | |||||
__nram__ uint32_t sum = 0; | |||||
__nram__ uint32_t val[STRIDE]; | |||||
const uint32_t TASK_DIM = CLUSTER_DIM * CORE_DIM; | |||||
__mlu_shared__ uint32_t partial_sum[TASK_DIM]; | |||||
int task_stride = STRIDE; | |||||
int start_offset = taskId * task_stride; | |||||
int global_stride = taskDim * task_stride; | |||||
for (int task_offset = start_offset; task_offset < nr_elems; | |||||
task_offset += global_stride) { | |||||
int end_offset = task_offset + task_stride; | |||||
end_offset = end_offset > nr_elems ? nr_elems : end_offset; | |||||
int copy_elems = end_offset - task_offset; | |||||
__memcpy(val, src + task_offset, copy_elems * sizeof(uint32_t), | |||||
GDRAM2NRAM); | |||||
for (int i = 0; i < copy_elems; i++) { | |||||
sum = sum + val[i] * (task_offset + i + 1); | |||||
} | |||||
} | |||||
partial_sum[taskId] = sum; | |||||
__sync_cluster(); | |||||
if (taskId == 0) { | |||||
uint32_t res = 0; | |||||
for (int i = 0; i < taskDim; i++) { | |||||
res += partial_sum[i]; | |||||
} | |||||
dst[0] = res; | |||||
} | |||||
} | |||||
#undef CLUSTER_DIM | |||||
#undef CORE_DIM | |||||
#undef STRIDE | |||||
// vim: ft=cpp syntax=cpp.doxygen | |||||
@@ -1,71 +0,0 @@ | |||||
/** | |||||
* \file dnn/src/cambricon/checksum/checksum_kernel_union4.mlu | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#include "checksum.mlu.h" | |||||
#include "cnsccl.h" | |||||
#include "mlu.h" | |||||
#define CLUSTER_DIM 4 | |||||
#define CORE_DIM 4 | |||||
#define STRIDE 1024 | |||||
__mlu_entry__ void checksum_kernel_union4(uint32_t* dst, uint32_t* src, | |||||
int nr_elems) { | |||||
__nram__ uint32_t sum = 0; | |||||
__nram__ uint32_t val[STRIDE]; | |||||
__mlu_shared__ uint32_t partial_sum_send[CORE_DIM]; | |||||
__mlu_shared__ uint32_t partial_sum_recv[CLUSTER_DIM]; | |||||
int task_stride = STRIDE; | |||||
int start_offset = taskId * task_stride; | |||||
int global_stride = taskDim * task_stride; | |||||
for (int task_offset = start_offset; task_offset < nr_elems; | |||||
task_offset += global_stride) { | |||||
int end_offset = task_offset + task_stride; | |||||
end_offset = end_offset > nr_elems ? nr_elems : end_offset; | |||||
int copy_elems = end_offset - task_offset; | |||||
__memcpy(val, src + task_offset, copy_elems * sizeof(uint32_t), | |||||
GDRAM2NRAM); | |||||
for (int i = 0; i < copy_elems; i++) { | |||||
sum = sum + val[i] * (task_offset + i + 1); | |||||
} | |||||
} | |||||
partial_sum_send[coreId] = sum; | |||||
__sync_cluster(); | |||||
if (coreId == 0) { | |||||
for (int i = 1; i < CORE_DIM; ++i) { | |||||
partial_sum_send[0] += partial_sum_send[i]; | |||||
} | |||||
} | |||||
__sync_all(); | |||||
cnscclGather((void*)&partial_sum_send, (void*)&partial_sum_recv, 1, | |||||
cnscclInt, 0); | |||||
__sync_all(); | |||||
if (clusterId == 0 && coreId == 0) { | |||||
uint32_t res = 0; | |||||
for (int i = 0; i < CLUSTER_DIM; ++i) { | |||||
res += partial_sum_recv[i]; | |||||
} | |||||
dst[0] = res; | |||||
} | |||||
} | |||||
#undef CLUSTER_DIM | |||||
#undef CORE_DIM | |||||
#undef STRIDE | |||||
// vim: ft=cpp syntax=cpp.doxygen | |||||
@@ -1,85 +0,0 @@ | |||||
/** | |||||
* \file dnn/src/cambricon/checksum/opr_impl.cpp | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#include "src/cambricon/checksum/opr_impl.h" | |||||
#include "src/cambricon/checksum/checksum.mlu.h" | |||||
#include "src/cambricon/utils.h" | |||||
#include <algorithm> | |||||
using namespace megdnn; | |||||
using namespace cambricon; | |||||
namespace { | |||||
void bang_c_wrapper( | |||||
uint32_t* dst, const uint32_t* src, int nr_elems, cnrtQueue_t queue, | |||||
cnrtCoreVersion_t core_version) { | |||||
cnrtKernelParamsBuffer_t params; | |||||
cnrt_check(cnrtGetKernelParamsBuffer(¶ms)); | |||||
cnrt_check(cnrtKernelParamsBufferAddParam(params, &dst, sizeof(uint32_t*))); | |||||
cnrt_check(cnrtKernelParamsBufferAddParam(params, &src, sizeof(uint32_t*))); | |||||
cnrt_check(cnrtKernelParamsBufferAddParam(params, &nr_elems, sizeof(int))); | |||||
if (core_version == CNRT_MLU270) { | |||||
cnrtDim3_t dim; | |||||
dim.x = 16; | |||||
dim.y = 1; | |||||
dim.z = 1; | |||||
cnrtFunctionType_t c = CNRT_FUNC_TYPE_UNION4; | |||||
cnrt_check(cnrtInvokeKernel_V2( | |||||
(void*)&checksum_kernel_union4, dim, params, c, queue)); | |||||
} else if (core_version == CNRT_MLU220) { | |||||
cnrtDim3_t dim; | |||||
dim.x = 4; | |||||
dim.y = 1; | |||||
dim.z = 1; | |||||
cnrtFunctionType_t c = CNRT_FUNC_TYPE_UNION1; | |||||
cnrt_check(cnrtInvokeKernel_V2( | |||||
(void*)&checksum_kernel_union1, dim, params, c, queue)); | |||||
} | |||||
after_kernel_launch(); | |||||
cnrt_check(cnrtDestroyKernelParamsBuffer(params)); | |||||
} | |||||
} // namespace | |||||
size_t ChecksumForwardImpl::get_workspace_in_bytes(const TensorLayout& /* data */) { | |||||
size_t ws_size = sizeof(ChecksumForward::Result::checksum); | |||||
return ws_size; | |||||
} | |||||
ChecksumForward::Result ChecksumForwardImpl::exec( | |||||
_megdnn_tensor_in data, _megdnn_workspace workspace) { | |||||
Result result; | |||||
memset(&result, 0, sizeof(result)); | |||||
check_exec(data.layout, workspace.size); | |||||
auto queue = cnrt_queue(handle()); | |||||
auto ptr = static_cast<uint8_t*>(data.raw_ptr()); | |||||
size_t size_all = data.layout.shape[0], size_ints = size_all / sizeof(uint32_t); | |||||
auto last_val_size = std::min<size_t>(size_all, 4); | |||||
cnrt_check(cnrtMemcpyAsync( | |||||
&result.last_val, ptr + size_all - last_val_size, last_val_size, queue, | |||||
CNRT_MEM_TRANS_DIR_DEV2HOST)); | |||||
if (size_ints) { | |||||
auto&& device_info = current_device_info(); | |||||
bang_c_wrapper( | |||||
reinterpret_cast<uint32_t*>(workspace.raw_ptr), | |||||
static_cast<uint32_t*>(data.raw_ptr()), size_ints, queue, | |||||
device_info.core_version); | |||||
cnrt_check(cnrtMemcpyAsync( | |||||
&result.checksum, workspace.raw_ptr, sizeof(result.checksum), queue, | |||||
CNRT_MEM_TRANS_DIR_DEV2HOST)); | |||||
} | |||||
cnrt_check(cnrtSyncQueue(queue)); | |||||
return result; | |||||
} | |||||
// vim: syntax=cpp.doxygen |
@@ -1,34 +0,0 @@ | |||||
/** | |||||
* \file dnn/src/cambricon/checksum/opr_impl.h | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#pragma once | |||||
#include "megdnn/oprs.h" | |||||
#include "src/cambricon/utils.h" | |||||
namespace megdnn { | |||||
namespace cambricon { | |||||
class ChecksumForwardImpl final : public ChecksumForward { | |||||
public: | |||||
using ChecksumForward::ChecksumForward; | |||||
size_t get_workspace_in_bytes(const TensorLayout&) override; | |||||
bool is_thread_safe() const override { return true; } | |||||
Result exec(_megdnn_tensor_in data, _megdnn_workspace workspace) override; | |||||
}; | |||||
} // namespace cambricon | |||||
} // namespace megdnn | |||||
// vim: syntax=cpp.doxygen |
@@ -1,67 +0,0 @@ | |||||
/** | |||||
* \file dnn/src/cambricon/handle.cpp | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#include "src/common/handle_impl.h" | |||||
#include "src/common/version_symbol.h" | |||||
#include "src/cambricon/handle.h" | |||||
#include "src/cambricon/utils.h" | |||||
#include <cnrt.h> | |||||
#include "src/cambricon/checksum/opr_impl.h" | |||||
namespace megdnn { | |||||
namespace cambricon { | |||||
HandleImpl::HandleImpl(megcoreComputingHandle_t comp_handle) | |||||
: HandleImplHelper(comp_handle, HandleType::CAMBRICON) { | |||||
// Get megcore device handle | |||||
megcoreDeviceHandle_t dev_handle; | |||||
megcoreGetDeviceHandle(comp_handle, &dev_handle); | |||||
int dev_id; | |||||
megcoreGetDeviceID(dev_handle, &dev_id); | |||||
unsigned int dev_num; | |||||
cnrt_check(cnrtGetDeviceCount(&dev_num)); | |||||
MEGDNN_MARK_USED_VAR(dev_num); | |||||
// check validity of device_id | |||||
megdnn_assert(dev_id >= 0 && static_cast<unsigned int>(dev_id) < dev_num); | |||||
m_device_id = dev_id; | |||||
cnrt_check(cnrtGetDeviceInfo(&m_device_info, dev_id)); | |||||
megcore::getCambriconContext(comp_handle, &m_megcore_context); | |||||
} | |||||
HandleImpl::~HandleImpl() noexcept = default; | |||||
template <typename Opr> | |||||
std::unique_ptr<Opr> HandleImpl::create_operator() { | |||||
megdnn_throw("unsupported cambricon opr"); | |||||
return nullptr; | |||||
} | |||||
size_t HandleImpl::alignment_requirement() const { | |||||
return 1; | |||||
} | |||||
MEGDNN_SPECIALIZE_CREATE_OPERATOR(ChecksumForward); | |||||
#pragma GCC diagnostic push | |||||
#pragma GCC diagnostic ignored "-Wpragmas" | |||||
#pragma GCC diagnostic ignored "-Winstantiation-after-specialization" | |||||
MEGDNN_FOREACH_OPR_CLASS(MEGDNN_INST_CREATE_OPERATOR) | |||||
#pragma GCC diagnostic pop | |||||
} // namespace cambricon | |||||
} // namespace megdnn | |||||
MEGDNN_VERSION_SYMBOL3( | |||||
CNRT, CNRT_MAJOR_VERSION, CNRT_MINOR_VERSION, CNRT_PATCH_VERSION); | |||||
// vim: syntax=cpp.doxygen |
@@ -1,64 +0,0 @@ | |||||
/** | |||||
* \file dnn/src/cambricon/handle.h | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#pragma once | |||||
#include "megcore_cambricon.h" | |||||
#include "megdnn/basic_types.h" | |||||
#include "megdnn/handle.h" | |||||
#include "megdnn/oprs/general.h" | |||||
#include "src/common/handle_impl.h" | |||||
#include "src/common/utils.h" | |||||
#include <atomic> | |||||
#include <mutex> | |||||
#include <cnrt.h> | |||||
namespace megdnn { | |||||
namespace cambricon { | |||||
class HandleImpl : public HandleImplHelper { | |||||
public: | |||||
HandleImpl(megcoreComputingHandle_t computing_handle); | |||||
~HandleImpl() noexcept; | |||||
size_t alignment_requirement() const override; | |||||
const cnrtDeviceInfo_t& device_info() const { return m_device_info; } | |||||
template <typename Opr> | |||||
std::unique_ptr<Opr> create_operator(); | |||||
const megcore::CambriconContext& megcore_context() const { | |||||
return m_megcore_context; | |||||
} | |||||
int device_id() const { return m_device_id; } | |||||
cnrtQueue_t queue() const { return megcore_context().queue; } | |||||
//! global matmul opr | |||||
Checksum* checksum_opr() override final { | |||||
return get_helper_opr<Checksum, 0>(this); | |||||
} | |||||
private: | |||||
int m_device_id; | |||||
//! MegDNN handle does not manage the lifetime of cnrt queue. | |||||
megcore::CambriconContext m_megcore_context; | |||||
cnrtDeviceInfo_t m_device_info; | |||||
}; | |||||
} // namespace cambricon | |||||
} // namespace megdnn | |||||
// vim: syntax=cpp.doxygen |
@@ -1,75 +0,0 @@ | |||||
/** | |||||
* \file dnn/src/cambricon/megcore/cambricon_computing_context.cpp | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#include "megcore.h" | |||||
#include "src/cambricon/utils.h" | |||||
#include "src/common/utils.h" | |||||
#include "src/cambricon/megcore/cambricon_computing_context.hpp" | |||||
using namespace megcore; | |||||
using namespace megcore::cambricon; | |||||
CambriconComputingContext::CambriconComputingContext( | |||||
megcoreDeviceHandle_t dev_handle, unsigned int flags, | |||||
const CambriconContext& ctx) | |||||
: ComputingContext(dev_handle, flags), | |||||
own_queue{ctx.queue == nullptr}, | |||||
context_{ctx} { | |||||
megcorePlatform_t platform; | |||||
megcoreGetPlatform(dev_handle, &platform); | |||||
megdnn_assert(platform == megcorePlatformCambricon); | |||||
if (own_queue) { | |||||
cnrt_check(cnrtCreateQueue(&context_.queue)); | |||||
} | |||||
} | |||||
CambriconComputingContext::~CambriconComputingContext() { | |||||
if (own_queue) { | |||||
cnrt_check(cnrtDestroyQueue(context_.queue)); | |||||
} | |||||
} | |||||
void CambriconComputingContext::memcpy( | |||||
void* dst, const void* src, size_t size_in_bytes, megcoreMemcpyKind_t kind) { | |||||
cnrtMemTransDir_t dir; | |||||
switch (kind) { | |||||
case megcoreMemcpyDeviceToHost: | |||||
dir = CNRT_MEM_TRANS_DIR_DEV2HOST; | |||||
break; | |||||
case megcoreMemcpyHostToDevice: | |||||
dir = CNRT_MEM_TRANS_DIR_HOST2DEV; | |||||
break; | |||||
case megcoreMemcpyDeviceToDevice: | |||||
dir = CNRT_MEM_TRANS_DIR_DEV2DEV; | |||||
break; | |||||
default: | |||||
megdnn_throw("bad cnrt mem trans dir"); | |||||
} | |||||
if (kind == megcoreMemcpyDeviceToDevice) { | |||||
cnrt_check(cnrtSyncQueue(context_.queue)); | |||||
cnrt_check(cnrtMemcpy(dst, const_cast<void*>(src), size_in_bytes, dir)); | |||||
return; | |||||
} | |||||
cnrt_check(cnrtMemcpyAsync( | |||||
dst, const_cast<void*>(src), size_in_bytes, context_.queue, dir)); | |||||
} | |||||
void CambriconComputingContext::memset(void* dst, int value, size_t size_in_bytes) { | |||||
cnrt_check(cnrtSyncQueue(context_.queue)); | |||||
cnrt_check(cnrtMemset(dst, value, size_in_bytes)); | |||||
} | |||||
void CambriconComputingContext::synchronize() { | |||||
cnrt_check(cnrtSyncQueue(context_.queue)); | |||||
} | |||||
// vim: syntax=cpp.doxygen |
@@ -1,44 +0,0 @@ | |||||
/** | |||||
* \file dnn/src/cambricon/megcore/cambricon_computing_context.hpp | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#pragma once | |||||
#include "megcore_cambricon.h" | |||||
#include "src/common/megcore/common/computing_context.hpp" | |||||
namespace megcore { | |||||
namespace cambricon { | |||||
class CambriconComputingContext final : public ComputingContext { | |||||
public: | |||||
CambriconComputingContext(megcoreDeviceHandle_t dev_handle, | |||||
unsigned int flags, | |||||
const CambriconContext& ctx = {}); | |||||
~CambriconComputingContext(); | |||||
void memcpy(void* dst, const void* src, size_t size_in_bytes, | |||||
megcoreMemcpyKind_t kind) override; | |||||
void memset(void* dst, int value, size_t size_in_bytes) override; | |||||
void synchronize() override; | |||||
const CambriconContext& context() const { return context_; } | |||||
cnrtQueue_t queue() const { return context().queue; } | |||||
private: | |||||
bool own_queue; | |||||
CambriconContext context_; | |||||
}; | |||||
} // namespace cambricon | |||||
} // namespace megcore | |||||
// vim: syntax=cpp.doxygen | |||||
@@ -1,77 +0,0 @@ | |||||
/** | |||||
* \file dnn/src/cambricon/megcore/cambricon_device_context.cpp | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#include "megcore.h" | |||||
#include "src/cambricon/utils.h" | |||||
#include "src/common/utils.h" | |||||
#include "src/cambricon/megcore/cambricon_device_context.hpp" | |||||
#define STR_HELPER(x) #x | |||||
#define STR(x) STR_HELPER(x) | |||||
#define CNRT_VERSION_STR \ | |||||
STR(CNRT_MAJOR_VERSION) \ | |||||
"." STR(CNRT_MINOR_VERSION) "." STR(CNRT_PATCH_VERSION) | |||||
#pragma message "compile with cnrt " CNRT_VERSION_STR " " | |||||
#undef STR_HELPER | |||||
#undef STR | |||||
using namespace megcore; | |||||
using namespace cambricon; | |||||
CambriconDeviceContext::CambriconDeviceContext( | |||||
int device_id, unsigned int flags, bool global_initialized) | |||||
: DeviceContext(megcorePlatformCambricon, device_id, flags) { | |||||
if (!global_initialized) | |||||
init_status.init(); | |||||
unsigned int version; | |||||
cnrt_check(cnrtGetVersion(&version)); | |||||
megdnn_assert( | |||||
version == CNRT_VERSION, "megcore compiled with cnrt %d, get %d at runtime", | |||||
CNRT_VERSION, version); | |||||
unsigned int dev_num; | |||||
cnrt_check(cnrtGetDeviceCount(&dev_num)); | |||||
MEGDNN_MARK_USED_VAR(dev_num); | |||||
// check validity of device_id | |||||
megdnn_assert(device_id >= 0 && static_cast<unsigned int>(device_id) < dev_num); | |||||
cnrt_check(cnrtGetDeviceInfo(&device_info, device_id)); | |||||
} | |||||
CambriconDeviceContext::~CambriconDeviceContext() noexcept = default; | |||||
size_t CambriconDeviceContext::mem_alignment_in_bytes() const noexcept { | |||||
return 1; | |||||
} | |||||
void CambriconDeviceContext::activate() { | |||||
int id = device_id(); | |||||
cnrtDev_t dev; | |||||
cnrt_check(cnrtGetDeviceHandle(&dev, id)); | |||||
cnrt_check(cnrtSetCurrentDevice(dev)); | |||||
} | |||||
void* CambriconDeviceContext::malloc(size_t size_in_bytes) { | |||||
void* ptr; | |||||
cnrt_check(cnrtMalloc(&ptr, size_in_bytes)); | |||||
return ptr; | |||||
} | |||||
void CambriconDeviceContext::free(void* ptr) { | |||||
cnrt_check(cnrtFree(ptr)); | |||||
} | |||||
CambriconDeviceContext::InitStatus CambriconDeviceContext::init_status; | |||||
// vim: syntax=cpp.doxygen |
@@ -1,63 +0,0 @@ | |||||
/** | |||||
* \file dnn/src/cambricon/megcore/cambricon_device_context.hpp | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#pragma once | |||||
#include <mutex> | |||||
#include "megcore_cambricon.h" | |||||
#include "src/common/megcore/common/device_context.hpp" | |||||
#include "src/common/utils.h" | |||||
namespace megcore { | |||||
namespace cambricon { | |||||
class CambriconDeviceContext : public DeviceContext { | |||||
public: | |||||
CambriconDeviceContext(int device_id, unsigned int flags, | |||||
bool global_initialized = false); | |||||
~CambriconDeviceContext() noexcept; | |||||
size_t mem_alignment_in_bytes() const noexcept override; | |||||
void activate() override; | |||||
void* malloc(size_t size_in_bytes) override; | |||||
void free(void* ptr) override; | |||||
struct InitStatus { | |||||
bool initialized; | |||||
std::mutex mtx; | |||||
InitStatus() : initialized{false} {} | |||||
void init() { | |||||
std::lock_guard<std::mutex> guard{mtx}; | |||||
if (!initialized) { | |||||
auto cnrt_err = cnrtInit(0); | |||||
initialized = cnrt_err == CNRT_RET_SUCCESS; | |||||
megdnn_assert(initialized, "cnrt initialize failed: (cnrt:%d)", | |||||
static_cast<int>(cnrt_err)); | |||||
} | |||||
} | |||||
~InitStatus() { | |||||
if (initialized) { | |||||
cnrtDestroy(); | |||||
initialized = false; | |||||
} | |||||
} | |||||
}; | |||||
static InitStatus init_status; | |||||
private: | |||||
cnrtDeviceInfo_t device_info; | |||||
}; | |||||
} // namespace cambricon | |||||
} // namespace megcore | |||||
// vim: syntax=cpp.doxygen | |||||
@@ -1,57 +0,0 @@ | |||||
/** | |||||
* \file dnn/src/cambricon/megcore/public_api/computing.cpp | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#include "megcore_cambricon.h" | |||||
#include "src/cambricon/megcore/cambricon_computing_context.hpp" | |||||
#include "src/cambricon/megcore/cambricon_device_context.hpp" | |||||
#include "src/common/megcore/public_api/computing.hpp" | |||||
#include "src/common/megcore/public_api/device.hpp" | |||||
#include "src/common/utils.h" | |||||
using namespace megcore; | |||||
megcoreStatus_t megcore::createDeviceHandleWithGlobalInitStatus( | |||||
megcoreDeviceHandle_t* devHandle, int deviceID, unsigned int flags, | |||||
bool global_initialized) { | |||||
auto content = megdnn::make_unique<cambricon::CambriconDeviceContext>( | |||||
deviceID, flags, global_initialized); | |||||
auto& ctx = *devHandle; | |||||
ctx = new megcoreDeviceContext; | |||||
ctx->content = std::move(content); | |||||
return megcoreSuccess; | |||||
} | |||||
megcoreStatus_t megcore::createComputingHandleWithCambriconContext( | |||||
megcoreComputingHandle_t* compHandle, megcoreDeviceHandle_t devHandle, | |||||
unsigned int flags, const CambriconContext& ctx) { | |||||
auto content = megdnn::make_unique<cambricon::CambriconComputingContext>( | |||||
devHandle, flags, ctx); | |||||
auto& H = *compHandle; | |||||
H = new megcoreComputingContext; | |||||
H->content = std::move(content); | |||||
return megcoreSuccess; | |||||
} | |||||
megcoreStatus_t megcore::getCambriconContext( | |||||
megcoreComputingHandle_t handle, CambriconContext* ctx) { | |||||
auto&& H = handle; | |||||
megdnn_assert(H); | |||||
megcoreDeviceHandle_t dev_handle = H->content->dev_handle(); | |||||
megcorePlatform_t platform; | |||||
megcoreGetPlatform(dev_handle, &platform); | |||||
megdnn_assert(platform == megcorePlatformCambricon); | |||||
auto context = static_cast<megcore::cambricon::CambriconComputingContext*>( | |||||
H->content.get()); | |||||
*ctx = context->context(); | |||||
return megcoreSuccess; | |||||
} | |||||
// vim: syntax=cpp.doxygen |
@@ -1,75 +0,0 @@ | |||||
/** | |||||
* \file dnn/src/cambricon/utils.cpp | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#include "src/cambricon/utils.h" | |||||
#include "src/cambricon/utils.mlu.h" | |||||
#include "src/cambricon/handle.h" | |||||
#include "src/common/utils.h" | |||||
#include <mutex> | |||||
#include <unordered_map> | |||||
using namespace megdnn; | |||||
using namespace cambricon; | |||||
namespace { | |||||
struct DeviceInfoRecord { | |||||
bool init = false; | |||||
cnrtDeviceInfo_t device_info; | |||||
std::mutex mtx; | |||||
}; | |||||
std::unordered_map<cnrtDev_t, int> dev2device_id; | |||||
std::mutex dev2device_id_mtx; | |||||
constexpr int MAX_NR_DEVICE = 64; | |||||
DeviceInfoRecord device_info_rec[MAX_NR_DEVICE]; | |||||
} // namespace | |||||
void cambricon::__throw_cnrt_error__(cnrtRet_t err, const char* msg) { | |||||
auto s = ssprintf( | |||||
"cnrt return %s(%d) occurred; expr: %s", cnrtGetErrorStr(err), int(err), | |||||
msg); | |||||
megdnn_throw(s.c_str()); | |||||
} | |||||
cnrtDeviceInfo_t cambricon::current_device_info() { | |||||
static bool dev2device_id_init = false; | |||||
{ | |||||
std::lock_guard<std::mutex> lock(dev2device_id_mtx); | |||||
if (!dev2device_id_init) { | |||||
unsigned int dev_num = 0; | |||||
cnrt_check(cnrtGetDeviceCount(&dev_num)); | |||||
for (unsigned int dev_id = 0; dev_id < dev_num; ++dev_id) { | |||||
cnrtDev_t dev; | |||||
cnrt_check(cnrtGetDeviceHandle(&dev, dev_id)); | |||||
dev2device_id[dev] = dev_id; | |||||
} | |||||
dev2device_id_init = true; | |||||
} | |||||
} | |||||
cnrtDev_t dev; | |||||
cnrt_check(cnrtGetCurrentDevice(&dev)); | |||||
{ | |||||
std::lock_guard<std::mutex> lock(dev2device_id_mtx); | |||||
int dev_id = dev2device_id.at(dev); | |||||
auto& rec = device_info_rec[dev_id]; | |||||
{ | |||||
std::lock_guard<std::mutex> lock(rec.mtx); | |||||
if (!rec.init) { | |||||
cnrt_check(cnrtGetDeviceInfo(&rec.device_info, dev_id)); | |||||
rec.init = true; | |||||
} | |||||
} | |||||
return rec.device_info; | |||||
} | |||||
} | |||||
// vim: syntax=cpp.doxygen |
@@ -1,39 +0,0 @@ | |||||
/** | |||||
* \file dnn/src/cambricon/utils.h | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#pragma once | |||||
#include "megcore_cdefs.h" | |||||
#include "megdnn/handle.h" | |||||
#include "src/cambricon/utils.mlu.h" | |||||
#include "src/common/utils.h" | |||||
#include "src/cambricon/handle.h" | |||||
#include <cnrt.h> | |||||
namespace megdnn { | |||||
namespace cambricon { | |||||
static inline HandleImpl* concrete_handle(Handle* handle) { | |||||
return static_cast<cambricon::HandleImpl*>(handle); | |||||
} | |||||
static inline cnrtQueue_t cnrt_queue(Handle* handle) { | |||||
return concrete_handle(handle)->queue(); | |||||
} | |||||
//! get device info of current active device | |||||
cnrtDeviceInfo_t current_device_info(); | |||||
} // namespace cambricon | |||||
} // namespace megdnn | |||||
// vim: syntax=cpp.doxygen |
@@ -1,41 +0,0 @@ | |||||
/** | |||||
* \file dnn/src/cambricon/utils.mlu.h | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#pragma once | |||||
#include "src/common/utils.cuh" | |||||
#include <stdint.h> | |||||
#include <cnrt.h> | |||||
#define cnrt_check(_x) \ | |||||
do { \ | |||||
cnrtRet_t _ret = (_x); \ | |||||
if (_ret != CNRT_RET_SUCCESS) { \ | |||||
::megdnn::cambricon::__throw_cnrt_error__(_ret, #_x); \ | |||||
} \ | |||||
} while (0) | |||||
#define after_kernel_launch() \ | |||||
do { \ | |||||
cnrt_check(cnrtGetLastErr()); \ | |||||
} while (0) | |||||
namespace megdnn { | |||||
namespace cambricon { | |||||
//! Error handling funcions | |||||
MEGDNN_NORETURN void __throw_cnrt_error__(cnrtRet_t err, const char* msg); | |||||
} // namespace cambricon | |||||
} // namespace megdnn | |||||
// vim: syntax=cpp.doxygen |
@@ -1,70 +0,0 @@ | |||||
/** | |||||
* \file dnn/test/cambricon/checksum.cpp | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#include "megdnn/oprs.h" | |||||
#include "test/cambricon/fixture.h" | |||||
#include "test/common/checker.h" | |||||
using namespace megdnn; | |||||
using namespace test; | |||||
TEST_F(CAMBRICON, CHECKSUM_FORWARD) { | |||||
auto cambricon_opr = handle_cambricon()->create_operator<megdnn::Checksum>(), | |||||
naive_opr = handle_naive()->create_operator<megdnn::Checksum>(); | |||||
std::mt19937 rng(std::random_device{}()); | |||||
for (size_t size : {3, 8, 4 * 4 * 1024, 12345, 1024 * 1024, 1024 * 1024 * 10}) { | |||||
auto aligned_size = size + ((512 - size % 512) % 512); | |||||
auto run = [&](megdnn::Checksum* opr, void* ptr, bool log_size) { | |||||
TensorND tensor; | |||||
tensor.reset_ptr(ptr); | |||||
tensor.layout.init_contiguous_stride({size}); | |||||
tensor.layout.dtype = dtype::Byte(); | |||||
WorkspaceWrapper workspace( | |||||
handle_cambricon(), opr->get_workspace_in_bytes(tensor.layout)); | |||||
if (log_size) { | |||||
printf("checksum(%zu): workspace=%zu\n", size, | |||||
workspace.workspace().size); | |||||
} | |||||
return opr->exec(tensor, workspace.workspace()); | |||||
}; | |||||
std::vector<uint8_t> buf(aligned_size); | |||||
for (size_t i = 0; i < size; ++i) | |||||
buf[i] = 1; | |||||
auto run_offsset = [&](size_t offset) { | |||||
void* dev_ptr = megdnn_malloc(handle_cambricon(), buf.size() + offset); | |||||
void* dev_buf = static_cast<char*>(dev_ptr) + offset; | |||||
Checksum::Result res_cambricon[2], res_naive[2]; | |||||
for (int change_last = 0; change_last < 2; ++change_last) { | |||||
if (change_last) | |||||
++buf[size - 1]; | |||||
megdnn_memcpy_H2D(handle_cambricon(), dev_buf, buf.data(), size); | |||||
res_cambricon[change_last] = | |||||
run(cambricon_opr.get(), dev_buf, !change_last); | |||||
res_naive[change_last] = run(naive_opr.get(), buf.data(), false); | |||||
} | |||||
megdnn_free(handle_cambricon(), dev_ptr); | |||||
ASSERT_EQ(res_naive[0], res_cambricon[0]) << "failed for size " << size; | |||||
ASSERT_EQ(res_naive[1], res_cambricon[1]); | |||||
ASSERT_NE(res_cambricon[0], res_cambricon[1]); | |||||
}; | |||||
for (size_t i = 0; i < 8; ++i) { | |||||
run_offsset(i); | |||||
} | |||||
} | |||||
} | |||||
// vim: syntax=cpp.doxygen |
@@ -1,49 +0,0 @@ | |||||
/** | |||||
* \file dnn/test/cambricon/fixture.cpp | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#include "test/cambricon/fixture.h" | |||||
#include "src/cambricon/handle.h" | |||||
#include "src/cambricon/utils.h" | |||||
#include "test/common/memory_manager.h" | |||||
#include "test/common/random_state.h" | |||||
#include "test/common/utils.h" | |||||
#include <cnrt.h> | |||||
#include <cstdlib> | |||||
using namespace megdnn; | |||||
using namespace test; | |||||
void CAMBRICON::SetUp() { | |||||
RandomState::reset(); | |||||
megcoreDeviceHandle_t dev_handle; | |||||
// use card 0 | |||||
megcore_check(megcoreCreateDeviceHandle(&dev_handle, megcorePlatformCambricon, 0)); | |||||
megcoreComputingHandle_t comp_handle; | |||||
megcore_check(megcoreCreateComputingHandle(&comp_handle, dev_handle)); | |||||
m_handle_cambricon = Handle::make(comp_handle); | |||||
megdnn_assert(m_handle_cambricon); | |||||
} | |||||
Handle* CAMBRICON::handle_naive() { | |||||
if (!m_handle_naive) | |||||
m_handle_naive = create_cpu_handle(2); | |||||
return m_handle_naive.get(); | |||||
} | |||||
void CAMBRICON::TearDown() { | |||||
m_handle_naive.reset(); | |||||
m_handle_cambricon.reset(); | |||||
MemoryManagerHolder::instance()->clear(); | |||||
} | |||||
// vim: syntax=cpp.doxygen |
@@ -1,39 +0,0 @@ | |||||
/** | |||||
* \file dnn/test/cambricon/fixture.h | |||||
* MegEngine is Licensed under the Apache License, Version 2.0 (the "License") | |||||
* | |||||
* Copyright (c) 2014-2021 Megvii Inc. All rights reserved. | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, | |||||
* software distributed under the License is distributed on an | |||||
* "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
*/ | |||||
#pragma once | |||||
#include <gtest/gtest.h> | |||||
#include "test/common/fix_gtest_on_platforms_without_exception.inl" | |||||
#include "megcore_cdefs.h" | |||||
#include "megdnn/handle.h" | |||||
#include <memory> | |||||
namespace megdnn { | |||||
namespace test { | |||||
class CAMBRICON : public ::testing::Test { | |||||
public: | |||||
void SetUp() override; | |||||
void TearDown() override; | |||||
Handle* handle_cambricon() { return m_handle_cambricon.get(); } | |||||
Handle* handle_naive(); | |||||
private: | |||||
std::unique_ptr<Handle> m_handle_naive; | |||||
std::unique_ptr<Handle> m_handle_cambricon; | |||||
}; | |||||
} // namespace test | |||||
} // namespace megdnn | |||||
// vim: syntax=cpp.doxygen |