1 /* 2 * Copyright (c) Meta Platforms, Inc. and affiliates. 3 * All rights reserved. 4 * 5 * This source code is licensed under both the BSD-style license (found in the 6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found 7 * in the COPYING file in the root directory of this source tree). 8 */ 9 extern "C" { 10 #include "datagen.h" 11 } 12 #include "Options.h" 13 #include "test/RoundTrip.h" 14 #include "utils/ScopeGuard.h" 15 16 #include <cstddef> 17 #include <cstdio> 18 #include <cstdlib> 19 #include <memory> 20 #include <random> 21 22 using namespace std; 23 using namespace pzstd; 24 25 namespace { 26 string 27 writeData(size_t size, double matchProba, double litProba, unsigned seed) { 28 std::unique_ptr<uint8_t[]> buf(new uint8_t[size]); 29 RDG_genBuffer(buf.get(), size, matchProba, litProba, seed); 30 string file = tmpnam(nullptr); 31 auto fd = std::fopen(file.c_str(), "wb"); 32 auto guard = makeScopeGuard([&] { std::fclose(fd); }); 33 auto bytesWritten = std::fwrite(buf.get(), 1, size, fd); 34 if (bytesWritten != size) { 35 std::abort(); 36 } 37 return file; 38 } 39 40 template <typename Generator> 41 string generateInputFile(Generator& gen) { 42 // Use inputs ranging from 1 Byte to 2^16 Bytes 43 std::uniform_int_distribution<size_t> size{1, 1 << 16}; 44 std::uniform_real_distribution<> prob{0, 1}; 45 return writeData(size(gen), prob(gen), prob(gen), gen()); 46 } 47 48 template <typename Generator> 49 Options generateOptions(Generator& gen, const string& inputFile) { 50 Options options; 51 options.inputFiles = {inputFile}; 52 options.overwrite = true; 53 54 std::uniform_int_distribution<unsigned> numThreads{1, 32}; 55 std::uniform_int_distribution<unsigned> compressionLevel{1, 10}; 56 57 options.numThreads = numThreads(gen); 58 options.compressionLevel = compressionLevel(gen); 59 60 return options; 61 } 62 } 63 64 int main() { 65 std::mt19937 gen(std::random_device{}()); 66 67 auto newlineGuard = makeScopeGuard([] { std::fprintf(stderr, "\n"); }); 68 for (unsigned i = 0; i < 10000; ++i) { 69 if (i % 100 == 0) { 70 std::fprintf(stderr, "Progress: %u%%\r", i / 100); 71 } 72 auto inputFile = generateInputFile(gen); 73 auto inputGuard = makeScopeGuard([&] { std::remove(inputFile.c_str()); }); 74 for (unsigned i = 0; i < 10; ++i) { 75 auto options = generateOptions(gen, inputFile); 76 if (!roundTrip(options)) { 77 std::fprintf(stderr, "numThreads: %u\n", options.numThreads); 78 std::fprintf(stderr, "level: %u\n", options.compressionLevel); 79 std::fprintf(stderr, "decompress? %u\n", (unsigned)options.decompress); 80 std::fprintf(stderr, "file: %s\n", inputFile.c_str()); 81 return 1; 82 } 83 } 84 } 85 return 0; 86 } 87