Browse Source

Merge 611aa58325 into e207b3bd13

pull/5903/merge
nihui GitHub 10 months ago
parent
commit
b2434f4306
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
5 changed files with 238 additions and 1 deletions
  1. +1
    -0
      CMakeLists.txt
  2. +7
    -1
      src/CMakeLists.txt
  3. +1
    -0
      src/platform.h.in
  4. +179
    -0
      src/simplegcov.cpp
  5. +50
    -0
      src/simplegcov.h

+ 1
- 0
CMakeLists.txt View File

@@ -67,6 +67,7 @@ option(NCNN_SIMPLEOCV "minimal opencv structure emulation" OFF)
option(NCNN_SIMPLEOMP "minimal openmp runtime emulation" OFF)
option(NCNN_SIMPLESTL "minimal cpp stl structure emulation" OFF)
option(NCNN_SIMPLEMATH "minimal cmath" OFF)
option(NCNN_SIMPLEGCOV "minimal gcov emitting emulation" OFF)
option(NCNN_THREADS "build with threads" ON)
option(NCNN_BENCHMARK "print benchmark information for every layer" OFF)
option(NCNN_C_API "build with C api" ON)


+ 7
- 1
src/CMakeLists.txt View File

@@ -41,6 +41,7 @@ set(ncnn_SRCS
simpleomp.cpp
simplestl.cpp
simplemath.cpp
simplegcov.cpp
simplevk.cpp
)

@@ -704,7 +705,11 @@ endif()

if(NCNN_COVERAGE)
target_compile_options(ncnn PUBLIC -coverage -fprofile-arcs -ftest-coverage)
target_link_libraries(ncnn PUBLIC -coverage -lgcov)
if(NCNN_SIMPLEGCOV)
target_link_libraries(ncnn PUBLIC -coverage)
else()
target_link_libraries(ncnn PUBLIC -coverage -lgcov)
endif()
endif()

if(NCNN_ASAN)
@@ -753,6 +758,7 @@ if(NCNN_INSTALL_SDK)
simpleomp.h
simplestl.h
simplemath.h
simplegcov.h
simplevk.h
vulkan_header_fix.h
${CMAKE_CURRENT_BINARY_DIR}/ncnn_export.h


+ 1
- 0
src/platform.h.in View File

@@ -10,6 +10,7 @@
#cmakedefine01 NCNN_SIMPLEOMP
#cmakedefine01 NCNN_SIMPLESTL
#cmakedefine01 NCNN_SIMPLEMATH
#cmakedefine01 NCNN_SIMPLEGCOV
#cmakedefine01 NCNN_THREADS
#cmakedefine01 NCNN_BENCHMARK
#cmakedefine01 NCNN_C_API


+ 179
- 0
src/simplegcov.cpp View File

@@ -0,0 +1,179 @@
// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2025 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

#include "platform.h"

#if NCNN_SIMPLEGCOV

#include "simplegcov.h"

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>

struct gcda_function_arcs_info
{
// function
uint32_t ident;
uint32_t func_checksum;
uint32_t cfg_checksum;

// arcs
uint32_t num_counters;
uint64_t* counters;
};

struct gcda_info
{
const char* orig_filename;
uint32_t version;
uint32_t checksum;

std::vector<gcda_function_arcs_info> fas;
};

static void write_gcda_files();

struct gdata
{
std::vector<gcda_info> gcdas;

gdata()
{
atexit(write_gcda_files);
}
};

static struct gdata* g = 0;

static void write_gcda_files()
{
fprintf(stderr, "write_gcda_files\n");

// dump gcda
std::vector<gcda_info>& gcdas = g->gcdas;

for (size_t i = 0; i < gcdas.size(); i++)
{
const gcda_info& g = gcdas[i];

fprintf(stderr, "write %s\n", g.orig_filename);

FILE* fp = fopen(g.orig_filename, "wb");
if (!fp)
{
fprintf(stderr, "fopen %s failed %d\n", g.orig_filename, errno);
continue;
}

const uint32_t GCOV_DATA_MAGIC = 0x67636461;
fwrite(&GCOV_DATA_MAGIC, 1, sizeof(uint32_t), fp);
fwrite(&g.version, 1, sizeof(uint32_t), fp);
fwrite(&g.checksum, 1, sizeof(uint32_t), fp);

for (size_t j = 0; j < gcdas[i].fas.size(); j++)
{
const gcda_function_arcs_info& fa = gcdas[i].fas[j];

const uint32_t GCOV_TAG_FUNCTION = 0x01000000;
fwrite(&GCOV_TAG_FUNCTION, 1, sizeof(uint32_t), fp);
const uint32_t function_size = 3;
fwrite(&function_size, 1, sizeof(uint32_t), fp);
fwrite(&fa.ident, 1, sizeof(uint32_t), fp);
fwrite(&fa.func_checksum, 1, sizeof(uint32_t), fp);
fwrite(&fa.cfg_checksum, 1, sizeof(uint32_t), fp);

const uint32_t GCOV_TAG_COUNTER_BASE = 0x01a10000;
fwrite(&GCOV_TAG_COUNTER_BASE, 1, sizeof(uint32_t), fp);
const uint32_t arcs_size = fa.num_counters * 2;
fwrite(&arcs_size, 1, sizeof(uint32_t), fp);
for (uint32_t k = 0; k < fa.num_counters; k++)
{
fwrite(&fa.counters[k], 1, sizeof(uint64_t), fp);
}
}

fclose(fp);
}

delete g;
g = 0;
}

#ifdef __cplusplus
extern "C" {
#endif

void llvm_gcov_init(llvm_gcov_callback writeout, llvm_gcov_callback flush)
{
// fprintf(stderr, "llvm_gcov_init %p %p\n", writeout, flush);

if (g == 0)
{
g = new gdata;
}

writeout();
}

void llvm_gcda_start_file(const char* orig_filename, uint32_t version, uint32_t checksum)
{
// fprintf(stderr, "llvm_gcda_start_file %s %u %u\n", orig_filename, version, checksum);

std::vector<gcda_info>& gcdas = g->gcdas;

gcda_info g;
g.orig_filename = orig_filename;
g.version = version;
g.checksum = checksum;
gcdas.push_back(g);
}

void llvm_gcda_emit_function(uint32_t ident, uint32_t func_checksum, uint32_t cfg_checksum)
{
// fprintf(stderr, "llvm_gcda_emit_function %u %u %u\n", ident, func_checksum, cfg_checksum);

std::vector<gcda_info>& gcdas = g->gcdas;

gcda_function_arcs_info fa = {ident, func_checksum, cfg_checksum, 0, 0};
gcdas.back().fas.push_back(fa);
}

void llvm_gcda_emit_arcs(uint32_t num_counters, uint64_t* counters)
{
// fprintf(stderr, "llvm_gcda_emit_arcs %u %p\n", num_counters, counters);

std::vector<gcda_info>& gcdas = g->gcdas;

gcda_function_arcs_info& fa = gcdas.back().fas.back();
fa.num_counters = num_counters;
fa.counters = counters;
}

void llvm_gcda_summary_info()
{
// fprintf(stderr, "llvm_gcda_summary_info\n");
}

void llvm_gcda_end_file()
{
// fprintf(stderr, "llvm_gcda_end_file\n");
}

#ifdef __cplusplus
} // extern "C"
#endif

#endif // NCNN_SIMPLEGCOV

+ 50
- 0
src/simplegcov.h View File

@@ -0,0 +1,50 @@
// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2025 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

#ifndef NCNN_SIMPLEGCOV_H
#define NCNN_SIMPLEGCOV_H

#include "platform.h"

#if NCNN_SIMPLEGCOV

#include <stdint.h>

// This minimal gcov emitting implementation only supports the llvm abi

#ifdef __cplusplus
extern "C" {
#endif

typedef void (*llvm_gcov_callback)();

NCNN_EXPORT void llvm_gcov_init(llvm_gcov_callback writeout, llvm_gcov_callback flush);

NCNN_EXPORT void llvm_gcda_start_file(const char* orig_filename, uint32_t version, uint32_t checksum);

NCNN_EXPORT void llvm_gcda_emit_function(uint32_t ident, uint32_t func_checksum, uint32_t cfg_checksum);

NCNN_EXPORT void llvm_gcda_emit_arcs(uint32_t num_counters, uint64_t* counters);

NCNN_EXPORT void llvm_gcda_summary_info();

NCNN_EXPORT void llvm_gcda_end_file();

#ifdef __cplusplus
}
#endif

#endif // NCNN_SIMPLEGCOV

#endif // NCNN_SIMPLEGCOV_H

Loading…
Cancel
Save