diff --git a/benchmarks/config.h b/benchmarks/config.h index 9a01df5c0..53f00c55f 100644 --- a/benchmarks/config.h +++ b/benchmarks/config.h @@ -1,6 +1,6 @@ /* * Apache License, Version 2.0 - * Copyright 2020 NVIDIA Corporation + * Copyright 2020-2021 NVIDIA Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,8 @@ struct AppConfig { - std::string input_file = "test_data/private/generic_tiff_000.tif"; + std::string test_folder; + std::string test_file; bool discard_cache = false; int random_seed = 0; bool random_start_location = false; @@ -42,6 +43,38 @@ struct AppConfig std::string benchmark_color; // {auto|true|false} std::string benchmark_counters_tabular; std::string v; // + + std::string get_input_path(const std::string default_value = "generated/tiff_stripe_4096x4096_256.tif") const + { + // If `test_file` is absolute path + if (!test_folder.empty() && test_file.substr(0, 1) == "/") + { + return test_file; + } + else + { + std::string test_data_folder = test_folder; + if (test_data_folder.empty()) + { + if (const char* env_p = std::getenv("CUCIM_TESTDATA_FOLDER")) + { + test_data_folder = env_p; + } + else + { + test_data_folder = "test_data"; + } + } + if (test_file.empty()) + { + return test_data_folder + "/" + default_value; + } + else + { + return test_data_folder + "/" + test_file; + } + } + } }; #endif // CUCIM_CONFIG_H diff --git a/benchmarks/main.cpp b/benchmarks/main.cpp index e3e920436..d33516bd6 100644 --- a/benchmarks/main.cpp +++ b/benchmarks/main.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. + * Copyright (c) 2020-2021, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,8 @@ static AppConfig g_config; static void test_cucim(benchmark::State& state) { + std::string input_path = g_config.get_input_path(); + int arg = -1; for (auto state_item : state) { @@ -46,7 +48,7 @@ static void test_cucim(benchmark::State& state) if (g_config.discard_cache) { - int fd = open(g_config.input_file.c_str(), O_RDONLY); + int fd = open(input_path.c_str(), O_RDONLY); fdatasync(fd); posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED); close(fd); @@ -61,7 +63,7 @@ static void test_cucim(benchmark::State& state) request_location[1] = rand() % (g_config.image_height - state.range(0)); } - cucim::CuImage image = cucim::CuImage(g_config.input_file.c_str()); + cucim::CuImage image = cucim::CuImage(input_path.c_str()); cucim::CuImage region = image.read_region({ request_location[0], request_location[1] }, { state.range(0), state.range(0) }, 0, cucim::DimIndices{}, "cpu", nullptr, ""); @@ -70,6 +72,8 @@ static void test_cucim(benchmark::State& state) static void test_openslide(benchmark::State& state) { + std::string input_path = g_config.get_input_path(); + int arg = -1; for (auto _ : state) { @@ -84,7 +88,7 @@ static void test_openslide(benchmark::State& state) if (g_config.discard_cache) { - int fd = open(g_config.input_file.c_str(), O_RDONLY); + int fd = open(input_path.c_str(), O_RDONLY); fdatasync(fd); posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED); close(fd); @@ -92,7 +96,7 @@ static void test_openslide(benchmark::State& state) } state.ResumeTiming(); - openslide_t* slide = openslide_open(g_config.input_file.c_str()); + openslide_t* slide = openslide_open(input_path.c_str()); uint32_t* buf = static_cast(cucim_malloc(state.range(0) * state.range(0) * 4)); int64_t request_location[2] = { 0, 0 }; if (g_config.random_start_location) @@ -131,10 +135,12 @@ static bool remove_help_option(int* argc, char** argv) static bool setup_configuration() { - openslide_t* slide = openslide_open(g_config.input_file.c_str()); + std::string input_path = g_config.get_input_path(); + + openslide_t* slide = openslide_open(input_path.c_str()); if (slide == nullptr) { - fmt::print("[Error] Cannot load {}!\n", g_config.input_file); + fmt::print("[Error] Cannot load {}!\n", input_path); return false; } int64_t w, h; @@ -159,7 +165,8 @@ int main(int argc, char** argv) // return 1; CLI::App app{ "cuCIM Benchmark" }; - app.add_option("--test_file", g_config.input_file, "An input .tif/.svs file path"); + app.add_option("--test_folder", g_config.test_folder, "An input test folder path"); + app.add_option("--test_file", g_config.test_file, "An input test image file path"); app.add_option("--discard_cache", g_config.discard_cache, "Discard page cache for the input file for each iteration"); app.add_option("--random_seed", g_config.random_seed, "A random seed number"); app.add_option( diff --git a/cpp/plugins/cucim.kit.cuslide/benchmarks/config.h b/cpp/plugins/cucim.kit.cuslide/benchmarks/config.h index e82cb685e..6aaa99f67 100644 --- a/cpp/plugins/cucim.kit.cuslide/benchmarks/config.h +++ b/cpp/plugins/cucim.kit.cuslide/benchmarks/config.h @@ -1,6 +1,6 @@ /* * Apache License, Version 2.0 - * Copyright 2020 NVIDIA Corporation + * Copyright 2020-2021 NVIDIA Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,8 @@ struct AppConfig { - std::string input_file = "test_data/private/generic_tiff_000.tif"; + std::string test_folder; + std::string test_file; bool discard_cache = false; int random_seed = 0; bool random_start_location = false; @@ -42,6 +43,38 @@ struct AppConfig std::string benchmark_color; // {auto|true|false} std::string benchmark_counters_tabular; std::string v; // + + std::string get_input_path(const std::string default_value = "generated/tiff_stripe_4096x4096_256.tif") const + { + // If `test_file` is absolute path + if (!test_folder.empty() && test_file.substr(0, 1) == "/") + { + return test_file; + } + else + { + std::string test_data_folder = test_folder; + if (test_data_folder.empty()) + { + if (const char* env_p = std::getenv("CUCIM_TESTDATA_FOLDER")) + { + test_data_folder = env_p; + } + else + { + test_data_folder = "test_data"; + } + } + if (test_file.empty()) + { + return test_data_folder + "/" + default_value; + } + else + { + return test_data_folder + "/" + test_file; + } + } + } }; #endif // CUSLIDE_CONFIG_H diff --git a/cpp/plugins/cucim.kit.cuslide/benchmarks/main.cpp b/cpp/plugins/cucim.kit.cuslide/benchmarks/main.cpp index faa8372cb..d4da518a4 100644 --- a/cpp/plugins/cucim.kit.cuslide/benchmarks/main.cpp +++ b/cpp/plugins/cucim.kit.cuslide/benchmarks/main.cpp @@ -43,6 +43,8 @@ static AppConfig g_config; static void test_basic(benchmark::State& state) { + std::string input_path = g_config.get_input_path(); + int arg = -1; for (auto state_item : state) { @@ -57,7 +59,7 @@ static void test_basic(benchmark::State& state) if (g_config.discard_cache) { - int fd = open(g_config.input_file.c_str(), O_RDONLY); + int fd = open(input_path.c_str(), O_RDONLY); fdatasync(fd); posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED); close(fd); @@ -83,7 +85,7 @@ static void test_basic(benchmark::State& state) return; } - auto handle = image_format->formats[0].image_parser.open(g_config.input_file.c_str()); + auto handle = image_format->formats[0].image_parser.open(input_path.c_str()); cucim::io::format::ImageMetadata metadata{}; image_format->formats[0].image_parser.parse(&handle, &metadata.desc()); @@ -118,6 +120,8 @@ static void test_basic(benchmark::State& state) static void test_openslide(benchmark::State& state) { + std::string input_path = g_config.get_input_path(); + int arg = -1; for (auto _ : state) { @@ -132,7 +136,7 @@ static void test_openslide(benchmark::State& state) if (g_config.discard_cache) { - int fd = open(g_config.input_file.c_str(), O_RDONLY); + int fd = open(input_path.c_str(), O_RDONLY); fdatasync(fd); posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED); close(fd); @@ -140,7 +144,7 @@ static void test_openslide(benchmark::State& state) } state.ResumeTiming(); - openslide_t* slide = openslide_open(g_config.input_file.c_str()); + openslide_t* slide = openslide_open(input_path.c_str()); uint32_t* buf = static_cast(cucim_malloc(state.range(0) * state.range(0) * 4)); int64_t request_location[2] = { 0, 0 }; if (g_config.random_start_location) @@ -177,10 +181,11 @@ static bool remove_help_option(int* argc, char** argv) static bool setup_configuration() { - openslide_t* slide = openslide_open(g_config.input_file.c_str()); + std::string input_path = g_config.get_input_path(); + openslide_t* slide = openslide_open(input_path.c_str()); if (slide == nullptr) { - fmt::print("[Error] Cannot load {}!\n", g_config.input_file); + fmt::print("[Error] Cannot load {}!\n", input_path); return false; } @@ -205,7 +210,8 @@ int main(int argc, char** argv) // if (::benchmark::ReportUnrecognizedArguments(argc, argv)) // return 1; CLI::App app{ "benchmark: cuSlide" }; - app.add_option("--test_file", g_config.input_file, "An input .tif/.svs file path"); + app.add_option("--test_folder", g_config.test_folder, "An input test folder path"); + app.add_option("--test_file", g_config.test_file, "An input test image file path"); app.add_option("--discard_cache", g_config.discard_cache, "Discard page cache for the input file for each iteration"); app.add_option("--random_seed", g_config.random_seed, "A random seed number"); app.add_option( diff --git a/cpp/plugins/cucim.kit.cuslide/tests/config.h b/cpp/plugins/cucim.kit.cuslide/tests/config.h index e44a5df73..49a860e77 100644 --- a/cpp/plugins/cucim.kit.cuslide/tests/config.h +++ b/cpp/plugins/cucim.kit.cuslide/tests/config.h @@ -1,6 +1,6 @@ /* * Apache License, Version 2.0 - * Copyright 2020 NVIDIA Corporation + * Copyright 2020-2021 NVIDIA Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ struct AppConfig std::string test_folder; std::string test_file; std::string temp_folder = "/tmp"; - std::string get_input_path(const char* default_value = "private/generic_tiff_000.tif") const + std::string get_input_path(const std::string default_value = "generated/tiff_stripe_4096x4096_256.tif") const { // If `test_file` is absolute path if (!test_folder.empty() && test_file.substr(0, 1) == "/") diff --git a/cpp/tests/config.h b/cpp/tests/config.h index 1baba463f..518548ab8 100644 --- a/cpp/tests/config.h +++ b/cpp/tests/config.h @@ -20,12 +20,15 @@ #include #include +#define XSTR(x) STR(x) +#define STR(x) #x + struct AppConfig { std::string test_folder; std::string test_file; std::string temp_folder = "/tmp"; - std::string get_input_path(const char* default_value = "private/generic_tiff_000.tif") const + std::string get_input_path(const std::string default_value = "generated/tiff_stripe_4096x4096_256.tif") const { // If `test_file` is absolute path if (!test_folder.empty() && test_file.substr(0, 1) == "/") @@ -56,7 +59,7 @@ struct AppConfig } } } - std::string get_plugin_path(const char* default_value = "cucim.kit.cuslide@0.0.0.so") + std::string get_plugin_path(const char* default_value = "cucim.kit.cuslide@" XSTR(CUCIM_VERSION) ".so") { std::string plugin_path = default_value; if (const char* env_p = std::getenv("CUCIM_TEST_PLUGIN_PATH")) diff --git a/cpp/tests/test_read_region.cpp b/cpp/tests/test_read_region.cpp index 691933fe1..3f8f87b41 100644 --- a/cpp/tests/test_read_region.cpp +++ b/cpp/tests/test_read_region.cpp @@ -110,6 +110,21 @@ SCENARIO("Verify read_region()", "[test_read_region.cpp]") // } printf("\ncucim count: %d\n", hash); cucim_free(image_data.container.data); + if (image_data.container.shape) + { + cucim_free(image_data.container.shape); + image_data.container.shape = nullptr; + } + if (image_data.container.strides) + { + cucim_free(image_data.container.strides); + image_data.container.strides = nullptr; + } + if (image_data.shm_name) + { + cucim_free(image_data.shm_name); + image_data.shm_name = nullptr; + } image_format->formats[0].image_parser.close(&handle); auto end = std::chrono::high_resolution_clock::now(); diff --git a/cucim.code-workspace b/cucim.code-workspace index 5c46d19c3..bfb1be839 100644 --- a/cucim.code-workspace +++ b/cucim.code-workspace @@ -161,7 +161,7 @@ "cwd": "${workspaceFolder}", "env": { // Workaround the environment variable issue: https://github.com/microsoft/vscode/issues/121470 - "PATH": "${env:PATH}" + "PATH": "${env:HOME}/.local/bin:${env:PATH}" } }, "presentation": { diff --git a/python/cucim/tests/util/gen_image.py b/python/cucim/tests/util/gen_image.py index 9f49a3a7f..8eea5dc81 100644 --- a/python/cucim/tests/util/gen_image.py +++ b/python/cucim/tests/util/gen_image.py @@ -82,6 +82,7 @@ def gen(self): image_size=image_size, tile_size=tile_size, compression=compression) + self.logger.info(' Generated %s...', image_path) results.append(image_path) self.logger.info('[Finished] Dataset generation') diff --git a/test_data/README.md b/test_data/README.md index 575398bea..dc230fadf 100644 --- a/test_data/README.md +++ b/test_data/README.md @@ -2,12 +2,19 @@ Symbolic links for for this folder is available under the following subfolders: -- `cpp/plugins/cucim.kit.cuslide +- `cpp/plugins/cucim.kit.cuslide` - `python/cucim` +## Generated Test Data (`test_data/generated` folder) + +Generated by executing `gen_images.sh`. + +- tiff_stripe_32x32_16.tif +- tiff_stripe_4096x4096_256.tif + ## Private Test Data (`test_data/private` folder) - `generic_tiff_000.tif` : 256x256 multi-resolution/tiled TIF conversion of `TUPAC-TR-467.svs` from the dataset of [Tumor Proliferation Assessment Challenge 2016](http://tupac.tue-image.nl/node/3) (TUPAC16 | MICCAI Grand Challenge) which are publicly available through [The Cancer Genome Atlas (TCGA)](https://www.cancer.gov/about-nci/organization/ccg/research/structural-genomics/tcga) under [CC BY 3.0 License](https://creativecommons.org/licenses/by/3.0/) -- `philips_tiff_000.tif` : `patient_100_node_0.tif` from the [Camelyon16 challenge data](https://drive.google.com/drive/folders/0BzsdkU4jWx9BUzVXeUg0dUNOR1U) (another [link](https://camelyon17.grand-challenge.org/Data/)) which is under [CC0 License](https://choosealicense.com/licenses/cc0-1.0/) +- `philips_tiff_000.tif` : `normal_042.tif` from the [Camelyon16 challenge data](ftp://parrot.genomics.cn/gigadb/pub/10.5524/100001_101000/100439/CAMELYON16/training/normal/normal_042.tif) (another [link](https://camelyon17.grand-challenge.org/Data/)) which is under [CC0 License](https://choosealicense.com/licenses/cc0-1.0/) diff --git a/test_data/gen_images.sh b/test_data/gen_images.sh new file mode 100755 index 000000000..c6c06d628 --- /dev/null +++ b/test_data/gen_images.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") +TOP="$(git rev-parse --show-toplevel 2> /dev/null || echo "${SCRIPT_DIR}")" + +[ -z "${TOP}" ] && >&2 echo "Repository root is not available!" && exit 1 + +DEST_FOLDER=${TOP}/test_data/generated +mkdir -p ${DEST_FOLDER} + +generate_image() { + local recipe="${1:-tiff}" + local check_file="${2:-}" + + [ -n "${check_file}" ] && [ -f "${DEST_FOLDER}/${check_file}" ] && return + + python3 ${TOP}/python/cucim/tests/util/gen_image.py ${recipe} --dest ${DEST_FOLDER} +} + +generate_image tiff::stripe:32x32:16 tiff_stripe_32x32_16.tif +generate_image tiff::stripe:4096x4096:256:deflate tiff_stripe_4096x4096_256.tif