docs: Update README and compilation guides for clarity and consistency, including path corrections and improved formatting. Add copyright notices to source files and adjust file permissions for several scripts and directories.

This commit is contained in:
dian.yuan 2026-02-28 11:06:26 +08:00
parent f960c5030d
commit bd891a96dd
136 changed files with 14413 additions and 9399 deletions

0
examples/clip/cpp/.gitkeep Normal file → Executable file
View file

View file

@ -1,38 +1,38 @@
cmake_minimum_required(VERSION 3.10...3.27)
project(clip_demo)
set(CMAKE_CXX_STANDARD 17)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../../../../cmake")
find_package(AMLNN REQUIRED)
include_directories(${AMLNN_INCLUDE_DIR})
link_directories(${AMLNN_LIBRARY_DIR})
include_directories(${CMAKE_SOURCE_DIR}/../../../../common)
# Set 3rdparty path
set(3RDPARTY_DIR "${CMAKE_SOURCE_DIR}/../../../../dependency")
# Include directories for stb_image and json
# Note: code uses #include "stb_image.h" and #include "json.hpp"
include_directories(${3RDPARTY_DIR}/stb_image)
include_directories(${3RDPARTY_DIR}/json)
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
# Android needs log
link_libraries(log)
endif()
add_executable(${PROJECT_NAME}
main.cpp
model_invoke.cpp
pre_postprocess.cpp
clip_tokenizer.cpp
)
target_link_libraries(${PROJECT_NAME}
${AMLNN_LIBRARY}
dl
m
)
cmake_minimum_required(VERSION 3.10...3.27)
project(clip_demo)
set(CMAKE_CXX_STANDARD 17)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../../../../cmake")
find_package(AMLNN REQUIRED)
include_directories(${AMLNN_INCLUDE_DIR})
link_directories(${AMLNN_LIBRARY_DIR})
include_directories(${CMAKE_SOURCE_DIR}/../../../../common)
# Set 3rdparty path
set(3RDPARTY_DIR "${CMAKE_SOURCE_DIR}/../../../../dependency")
# Include directories for stb_image and json
# Note: code uses #include "stb_image.h" and #include "json.hpp"
include_directories(${3RDPARTY_DIR}/stb_image)
include_directories(${3RDPARTY_DIR}/json)
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
# Android needs log
link_libraries(log)
endif()
add_executable(${PROJECT_NAME}
main.cpp
model_invoke.cpp
pre_postprocess.cpp
clip_tokenizer.cpp
)
target_link_libraries(${PROJECT_NAME}
${AMLNN_LIBRARY}
dl
m
)

View file

@ -26,8 +26,8 @@
// Initialize network from file
void* init_network_file(const char *model_path);
// Run vision model inference
std::vector<float> run_vision_model(void* context, const std::vector<float>& input_data);
// Run image model inference
std::vector<float> run_image_model(void* context, const std::vector<float>& input_data);
// Run text model inference
std::vector<float> run_text_model(void* context, const std::vector<int64_t>& input_ids);

View file

@ -33,7 +33,7 @@ struct ProfilingTimer
{
uint64_t init_start, init_end;
uint64_t preprocess_start, preprocess_end;
uint64_t vision_infer_start, vision_infer_end;
uint64_t image_infer_start, image_infer_end;
uint64_t text_infer_start, text_infer_end;
};
@ -71,10 +71,10 @@ std::vector<std::string> parse_texts(const std::string& input)
void print_usage(const char* prog_name)
{
printf("Usage: %s <vision_model> <text_model> <tokenizer_dir> [--profiling]\n", prog_name);
printf("Usage: %s <image_model> <text_model> <tokenizer_dir> [--profiling]\n", prog_name);
printf("\n");
printf("Arguments:\n");
printf(" vision_model: Path to vision model (.adla)\n");
printf(" image_model: Path to image model (.adla)\n");
printf(" text_model: Path to text model (.adla)\n");
printf(" tokenizer_dir: Path to directory containing vocab.json and merges.txt\n");
printf(" --profiling: Enable performance profiling output (optional)\n");
@ -96,7 +96,7 @@ int main(int argc, char ** argv)
return -1;
}
const char* vision_model_path = argv[1];
const char* image_model_path = argv[1];
const char* text_model_path = argv[2];
const char* tokenizer_dir = argv[3];
@ -119,11 +119,11 @@ int main(int argc, char ** argv)
}
// Initialize models
printf("[Info] Initializing vision model: %s\n", vision_model_path);
printf("[Info] Initializing image model: %s\n", image_model_path);
timer.init_start = get_time_count();
void* vision_context = init_network_file(vision_model_path);
if (vision_context == NULL) {
printf("[Error] Failed to initialize vision model.\n");
void* image_context = init_network_file(image_model_path);
if (image_context == NULL) {
printf("[Error] Failed to initialize image model.\n");
return -1;
}
@ -131,7 +131,7 @@ int main(int argc, char ** argv)
void* text_context = init_network_file(text_model_path);
if (text_context == NULL) {
printf("[Error] Failed to initialize text model.\n");
destroy_network(vision_context);
destroy_network(image_context);
return -1;
}
timer.init_end = get_time_count();
@ -218,14 +218,14 @@ int main(int argc, char ** argv)
}
timer.preprocess_end = get_time_count();
// Run vision model
timer.vision_infer_start = get_time_count();
std::vector<float> image_embedding = run_vision_model(vision_context, image_input);
// Run image model
timer.image_infer_start = get_time_count();
std::vector<float> image_embedding = run_image_model(image_context, image_input);
if (image_embedding.empty()) {
printf("[Error] Vision model inference failed.\n");
printf("[Error] Image model inference failed.\n");
continue;
}
timer.vision_infer_end = get_time_count();
timer.image_infer_end = get_time_count();
// L2 normalize image embedding
image_embedding = l2_normalize(image_embedding);
@ -264,7 +264,8 @@ int main(int argc, char ** argv)
continue;
}
printf("[Info] Text embeddings size: %zu x %zu\n", text_embeddings.size(),
printf("[Info] Text embeddings size: %zu x %zu\n",
text_embeddings.size(),
text_embeddings.empty() ? 0 : text_embeddings[0].size());
// ==================== Compute Similarity ====================
@ -302,11 +303,11 @@ int main(int argc, char ** argv)
if (profiling) {
uint64_t preprocess_time = (timer.preprocess_end - timer.preprocess_start) / 1000000;
uint64_t vision_time = (timer.vision_infer_end - timer.vision_infer_start) / 1000000;
uint64_t image_time = (timer.image_infer_end - timer.image_infer_start) / 1000000;
uint64_t text_total_time = (timer.text_infer_end - timer.text_infer_start) / 1000000;
printf("\n[Profiling]\n");
printf(" Image preprocess: %lums\n", preprocess_time);
printf(" Vision inference: %lums\n", vision_time);
printf(" Image inference: %lums\n", image_time);
for (size_t i = 0; i < texts.size() && i < text_infer_times.size(); ++i) {
printf(" Text inference[%zu]: %lums '%s'\n", i, text_infer_times[i], texts[i].c_str());
}
@ -316,9 +317,9 @@ int main(int argc, char ** argv)
}
// Cleanup
ret = destroy_network(vision_context);
ret = destroy_network(image_context);
if (ret != 0) {
printf("[Error] Failed to destroy vision model.\n");
printf("[Error] Failed to destroy image model.\n");
}
ret = destroy_network(text_context);
@ -328,4 +329,4 @@ int main(int argc, char ** argv)
printf("[Info] Done.\n");
return 0;
}
}

View file

@ -27,9 +27,9 @@
#include "nn_sdk.h"
// Global DMA config for models
static aml_memory_config_t vision_mem_config;
static aml_memory_data_t vision_mem_data;
static void* vision_context_flag = nullptr;
static aml_memory_config_t image_mem_config;
static aml_memory_data_t image_mem_data;
static void* image_context_flag = nullptr;
static aml_memory_config_t text_mem_config;
static aml_memory_data_t text_mem_data;
@ -48,7 +48,7 @@ void* init_network_file(const char *model_path)
/* set omp, If you are considering high CPU usage during operation,
you can turn off this api, set_openmp_opt_flag = false */
aml_openmp_opt_t openmp_opt[] =
aml_openmp_opt_t openmp_opt[] =
{
{
.operator_type = AML_Unknown,
@ -62,7 +62,7 @@ void* init_network_file(const char *model_path)
config.forward_ctrl.softop_info.openmp_opt = openmp_opt;
/* set neon */
aml_neon_opt_t neon_opt[] =
aml_neon_opt_t neon_opt[] =
{
{
.operator_type = AML_Unknown,
@ -84,10 +84,11 @@ void* init_network_file(const char *model_path)
return qcontext;
}
std::vector<float> run_vision_model(void* qcontext, const std::vector<float>& input_data)
std::vector<float> run_image_model(void* qcontext, const std::vector<float>& input_data)
{
int ret = 0;
nn_input inData;
nn_output *outdata = NULL;
aml_output_config_t outconfig;
@ -96,19 +97,19 @@ std::vector<float> run_vision_model(void* qcontext, const std::vector<float>& in
inData.size = input_data.size() * sizeof(float);
// Use DMA
if (!vision_context_flag) {
vision_mem_config.cache_type = AML_WITH_CACHE;
vision_mem_config.memory_type = AML_VIRTUAL_ADDR;
vision_mem_config.direction = AML_MEM_DIRECTION_READ_WRITE;
vision_mem_config.index = 0;
vision_mem_config.mem_size = inData.size;
aml_util_mallocBuffer(qcontext, &vision_mem_config, &vision_mem_data);
aml_util_swapExternalInputBuffer(qcontext, &vision_mem_config, &vision_mem_data);
vision_context_flag = qcontext;
if (!image_context_flag) {
image_mem_config.cache_type = AML_WITH_CACHE;
image_mem_config.memory_type = AML_VIRTUAL_ADDR;
image_mem_config.direction = AML_MEM_DIRECTION_READ_WRITE;
image_mem_config.index = 0;
image_mem_config.mem_size = inData.size;
aml_util_mallocBuffer(qcontext, &image_mem_config, &image_mem_data);
aml_util_swapExternalInputBuffer(qcontext, &image_mem_config, &image_mem_data);
image_context_flag = qcontext;
}
inData.input_type = INPUT_DMA_DATA;
memcpy(vision_mem_data.viraddr, input_data.data(), vision_mem_config.mem_size);
memcpy(image_mem_data.viraddr, input_data.data(), image_mem_config.mem_size);
inData.input = NULL;
memset(&outconfig, 0, sizeof(aml_output_config_t));
@ -117,7 +118,7 @@ std::vector<float> run_vision_model(void* qcontext, const std::vector<float>& in
outdata = (nn_output*)aml_module_output_get(qcontext, outconfig);
if (outdata == NULL || outdata->out[0].buf == NULL) {
printf("Vision model inference failed.\n");
printf("Image model inference failed.\n");
return {};
}
@ -178,10 +179,10 @@ int destroy_network(void *qcontext)
{
int ret = 0;
if (vision_context_flag == qcontext) {
printf("Free vision model memory.\n");
aml_util_freeBuffer(qcontext, &vision_mem_config, &vision_mem_data);
vision_context_flag = nullptr;
if (image_context_flag == qcontext) {
printf("Free image model memory.\n");
aml_util_freeBuffer(qcontext, &image_mem_config, &image_mem_data);
image_context_flag = nullptr;
} else if (text_context_flag == qcontext) {
printf("Free text model memory.\n");
aml_util_freeBuffer(qcontext, &text_mem_config, &text_mem_data);
@ -199,4 +200,4 @@ int destroy_network(void *qcontext)
}
return ret;
}
}

View file

@ -1,13 +1,29 @@
#ifndef MODEL_INVOKE_H
#define MODEL_INVOKE_H
#include <string>
#include <vector>
#include <map>
void* init_network_file(const char *model_path);
std::vector<std::string> process_image_dir(void *context_model, const std::string& json_path, const std::string& base_dir = "", const std::string& json_filename = "");
int destroy_network(void *qcontext);
#endif // MODEL_INVOKE_H
/*
* Copyright (C) 2026 Amlogic, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 MODEL_INVOKE_H
#define MODEL_INVOKE_H
#include <string>
#include <vector>
#include <map>
void* init_network_file(const char *model_path);
std::vector<std::string> process_image_dir(void *context_model, const std::string& json_path, const std::string& base_dir = "", const std::string& json_filename = "");
int destroy_network(void *qcontext);
#endif // MODEL_INVOKE_H

View file

@ -102,7 +102,7 @@ std::vector<float> preprocess_image(const std::string& image_path) {
}
}
// Return NHWC format (batch dimension will be added in caller)
// get NHWC
return cropped;
}