mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Merge pull request #51 from doinachiroiu:master
PiperOrigin-RevId: 331767052 Change-Id: I286e746fec6248c88df563be00da9451ddd63eb7
This commit is contained in:
commit
da41899797
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "oss-internship-2020/pffft/master"]
|
||||
path = oss-internship-2020/pffft/master
|
||||
url = https://bitbucket.org/jpommier/pffft/src/master/
|
3
oss-internship-2020/pffft/.gitignore
vendored
Normal file
3
oss-internship-2020/pffft/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
*.o
|
||||
*.a
|
||||
pffft_main
|
104
oss-internship-2020/pffft/CMakeLists.txt
Normal file
104
oss-internship-2020/pffft/CMakeLists.txt
Normal file
|
@ -0,0 +1,104 @@
|
|||
# Copyright 2020 Google LLC
|
||||
#
|
||||
# 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.
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(pffft CXX C)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
add_library(pffft STATIC
|
||||
master/pffft.c
|
||||
master/pffft.h
|
||||
master/fftpack.c
|
||||
master/fftpack.h
|
||||
)
|
||||
|
||||
add_executable(pffft_main
|
||||
master/test_pffft.c
|
||||
)
|
||||
|
||||
target_link_libraries(pffft_main PRIVATE
|
||||
pffft
|
||||
)
|
||||
|
||||
set(MATH_LIBS "")
|
||||
include(CheckLibraryExists)
|
||||
check_library_exists(m sin "" LIBM)
|
||||
if(LIBM)
|
||||
list(APPEND MATH_LIBS "m")
|
||||
endif()
|
||||
|
||||
target_link_libraries(pffft PUBLIC ${MATH_LIBS})
|
||||
|
||||
# Adding dependencies
|
||||
set(SAPI_ROOT "../.." CACHE PATH "Path to the Sandboxed API source tree")
|
||||
# Then configure:
|
||||
# mkdir -p build && cd build
|
||||
# cmake .. -G Ninja -DSAPI_ROOT=$HOME/sapi_root
|
||||
|
||||
set(SAPI_ENABLE_EXAMPLES OFF CACHE BOOL "")
|
||||
set(SAPI_ENABLE_TESTS OFF CACHE BOOL "")
|
||||
add_subdirectory("${SAPI_ROOT}"
|
||||
"${CMAKE_BINARY_DIR}/sandboxed-api-build"
|
||||
# Omit this to have the full Sandboxed API in IDE
|
||||
EXCLUDE_FROM_ALL)
|
||||
|
||||
add_sapi_library(pffft_sapi
|
||||
FUNCTIONS pffft_new_setup
|
||||
pffft_destroy_setup
|
||||
pffft_transform
|
||||
pffft_transform_ordered
|
||||
pffft_zreorder
|
||||
pffft_zconvolve_accumulate
|
||||
pffft_aligned_malloc
|
||||
pffft_aligned_free
|
||||
pffft_simd_size
|
||||
cffti
|
||||
cfftf
|
||||
cfftb
|
||||
rffti
|
||||
rfftf
|
||||
rfftb
|
||||
cosqi
|
||||
cosqf
|
||||
cosqb
|
||||
costi
|
||||
cost
|
||||
sinqi
|
||||
sinqb
|
||||
sinqf
|
||||
sinti
|
||||
sint
|
||||
|
||||
INPUTS master/pffft.h master/fftpack.h
|
||||
LIBRARY pffft
|
||||
LIBRARY_NAME Pffft
|
||||
|
||||
NAMESPACE ""
|
||||
)
|
||||
|
||||
target_include_directories(pffft_sapi INTERFACE
|
||||
"${PROJECT_BINARY_DIR}"
|
||||
)
|
||||
|
||||
add_executable(pffft_sandboxed
|
||||
main_pffft_sandboxed.cc
|
||||
)
|
||||
|
||||
target_link_libraries(pffft_sandboxed PRIVATE
|
||||
pffft_sapi
|
||||
sapi::sapi
|
||||
)
|
87
oss-internship-2020/pffft/README.md
Normal file
87
oss-internship-2020/pffft/README.md
Normal file
|
@ -0,0 +1,87 @@
|
|||
# Sandboxing PFFFT library
|
||||
|
||||
Build System: CMake
|
||||
OS: Linux
|
||||
|
||||
### Check out the PFFFT library & CMake set up
|
||||
```
|
||||
git submodule update --init --recursive
|
||||
|
||||
mkdir -p build && cd build
|
||||
cmake .. -G Ninja -DPFFFT_ROOT_DIR=$PWD
|
||||
ninjas
|
||||
```
|
||||
### For testing:
|
||||
`cd build`, then `./pffft_sandboxed`
|
||||
|
||||
### For debug:
|
||||
display custom info with
|
||||
`./pffft_sandboxed --logtostderr`
|
||||
|
||||
## ***About the project***
|
||||
*PFFFT library is concerned with 1D Fast-Fourier Transformations finding a
|
||||
compromise between accuracy and speed. It deals with real and complex
|
||||
vectors, both cases being illustrated in the testing part (`test_pffft.c`
|
||||
for initially and original version, `main_pffft_sandboxed.cc` for our
|
||||
currently implemented sandboxed version).
|
||||
The original files can be found at: https://bitbucket.org/jpommier/pffft/src.*
|
||||
|
||||
*The purpose of sandboxing is to limit the permissions and capabilities of
|
||||
library’s methods, in order to secure the usage of them.
|
||||
After obtaining the sandbox, the functions will be called through an
|
||||
Sandbox API (being called `api` in the current test) and so, the
|
||||
operations, system calls or namspaces access may be controlled.
|
||||
From both `pffft.h` and `fftpack.h` headers, useful methods are added to
|
||||
sapi library builded with CMake. There is also a need to link math library
|
||||
as the transformations made require mathematical operators.
|
||||
Regarding the testing of the methods, one main is doing this job by
|
||||
iterating through a set of values, that represents the accuracy of
|
||||
transformations and print the speed for each value and type of
|
||||
transformation. More specifically, the input length is the target for
|
||||
accuracy (named as `n`) and it stands for the number of data points from
|
||||
the series that calculate the result of transformation. It is also
|
||||
important to mention that the `complex` variable stands for a boolean value
|
||||
that tells the type of transformation (0 for REAL and 1 for COMPLEX) and
|
||||
it is taken into account while testing.
|
||||
In the end, the performance of PFFFT library it is outlined by the output.
|
||||
There are two output formats available, from which you can choose through
|
||||
`--output_format=` command-line flag.
|
||||
Without using this type of argument when running, the output format is set
|
||||
by default.*
|
||||
|
||||
#### CMake observations resume:
|
||||
* linking pffft and fftpack (which contains necessary functions for pffft)
|
||||
* set math library
|
||||
|
||||
#### Sandboxed main observations resume:
|
||||
* containing two testing parts (fft / pffft benchmarks)
|
||||
* showing the performance of the transformations implies
|
||||
testing them through various FFT dimenstions.
|
||||
Variable n, the input length, will take specific values
|
||||
meaning the number of points to which it is set the calculus
|
||||
(more details of mathematical purpose of n - https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm).
|
||||
* output shows speed depending on the input length
|
||||
* use `--output_format=0` or `--output_format=1` arguments to choose between output formats.
|
||||
`0` is for a detailed output, while `1` is only displaying each transformation process speed.
|
||||
|
||||
### Bugs history
|
||||
1. [Solved] pffft benchmark bug: "Sandbox not active"
|
||||
|
||||
n = 64, status OK, `pffft_transform` generates error
|
||||
n > 64, status not OK
|
||||
Problem on initialising `sapi::StatusOr<PFFFT_Setup *> s;` the memory that stays
|
||||
for s is not the same with the address passed in `pffft_transform` function.
|
||||
(`sapi::v::GenericPtr` - to be changed)
|
||||
|
||||
Temporary solution: change the generated files to accept
|
||||
`uintptr_t` instead of `PFFFT_Setup`
|
||||
|
||||
Solution: using `sapi::v::RemotePtr` instead of `sapi::v::GenericPtr`
|
||||
to access the memory of object `s`
|
||||
|
||||
2. [Unresolved] compiling bug: "No space left on device"
|
||||
|
||||
The building process creates some `embed` files that use lots of
|
||||
memory, trying to write them on `/tmp`.
|
||||
|
||||
Temporary solution: clean /tmp directory by `sudo rm -rf /tmp/*`
|
207
oss-internship-2020/pffft/main_pffft_sandboxed.cc
Normal file
207
oss-internship-2020/pffft/main_pffft_sandboxed.cc
Normal file
|
@ -0,0 +1,207 @@
|
|||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include "pffft_sapi.sapi.h" // NOLINT(build/include)
|
||||
#include "sandboxed_api/util/flag.h"
|
||||
#include "sandboxed_api/vars.h"
|
||||
|
||||
ABSL_DECLARE_FLAG(string, sandbox2_danger_danger_permit_all);
|
||||
ABSL_DECLARE_FLAG(string, sandbox2_danger_danger_permit_all_and_log);
|
||||
|
||||
class PffftSapiSandbox : public PffftSandbox {
|
||||
public:
|
||||
std::unique_ptr<sandbox2::Policy> ModifyPolicy(sandbox2::PolicyBuilder*) {
|
||||
return sandbox2::PolicyBuilder()
|
||||
.AllowStaticStartup()
|
||||
.AllowOpen()
|
||||
.AllowRead()
|
||||
.AllowWrite()
|
||||
.AllowSystemMalloc()
|
||||
.AllowExit()
|
||||
.AllowSyscalls({
|
||||
__NR_futex,
|
||||
__NR_close,
|
||||
__NR_getrusage,
|
||||
})
|
||||
.BuildOrDie();
|
||||
}
|
||||
};
|
||||
|
||||
// output_format flag determines whether the output shows information in detail
|
||||
// or not. By default, the flag is set as 0, meaning an elaborate display
|
||||
// (see ShowOutput method).
|
||||
static bool ValidateFlag(const char* flagname, int32_t value) {
|
||||
if (value >= 0 && value < 32768) {
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG(ERROR) << "Invalid value for --" << flagname << ".";
|
||||
return false;
|
||||
}
|
||||
|
||||
DEFINE_int32(output_format, 0, "Value to specific the output format.");
|
||||
DEFINE_validator(output_format, &ValidateFlag);
|
||||
|
||||
double UclockSec() { return static_cast<double>(clock()) / CLOCKS_PER_SEC; }
|
||||
|
||||
void ShowOutput(const char* name, int n, int complex, float flops, float t0,
|
||||
float t1, int max_iter) {
|
||||
float mflops = flops / 1e6 / (t1 - t0 + 1e-16);
|
||||
if (FLAGS_output_format) {
|
||||
if (flops != -1) {
|
||||
printf("|%9.0f ", mflops);
|
||||
} else {
|
||||
printf("| n/a ");
|
||||
}
|
||||
} else if (flops != -1) {
|
||||
printf("n=%5d, %s %16s : %6.0f MFlops [t=%6.0f ns, %d runs]\n", n,
|
||||
(complex ? "CPLX" : "REAL"), name, mflops,
|
||||
(t1 - t0) / 2 / max_iter * 1e9, max_iter);
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
absl::Status PffftMain() {
|
||||
LOG(INFO) << "Initializing sandbox...\n";
|
||||
|
||||
PffftSapiSandbox sandbox;
|
||||
SAPI_RETURN_IF_ERROR(sandbox.Init());
|
||||
|
||||
PffftApi api(&sandbox);
|
||||
|
||||
// kTransformSizes is a vector keeping the values by which iterates n, its
|
||||
// value representing the input length. More concrete, n is the number of data
|
||||
// points the caclulus is up to (determinating its accuracy). To show the
|
||||
// performance of Fast-Fourier Transformations the program is testing for
|
||||
// various values of n.
|
||||
constexpr int kTransformSizes[] = {
|
||||
64, 96, 128, 160, 192, 256, 384, 5 * 96, 512, 5 * 128,
|
||||
3 * 256, 800, 1024, 2048, 2400, 4096, 8192, 9 * 1024, 16384, 32768};
|
||||
|
||||
for (int complex : {0, 1}) {
|
||||
for (int n : kTransformSizes) {
|
||||
const int n_float = n * (complex ? 2 : 1);
|
||||
int n_bytes = n_float * sizeof(float);
|
||||
|
||||
std::vector<float> work(2 * n_float + 15, 0.0);
|
||||
sapi::v::Array<float> work_array(&work[0], work.size());
|
||||
|
||||
std::vector<float> x(n_bytes, 0.0);
|
||||
sapi::v::Array<float> x_array(&x[0], x.size());
|
||||
|
||||
std::vector<float> y(n_bytes, 0.0);
|
||||
sapi::v::Array<float> y_array(&y[0], y.size());
|
||||
|
||||
std::vector<float> z(n_bytes, 0.0);
|
||||
sapi::v::Array<float> z_array(&z[0], z.size());
|
||||
|
||||
double t0;
|
||||
double t1;
|
||||
double flops;
|
||||
|
||||
int max_iter = 5120000 / n * 4;
|
||||
|
||||
for (int k = 0; k < n_float; ++k) {
|
||||
x[k] = 0;
|
||||
}
|
||||
|
||||
// FFTPack benchmark
|
||||
{
|
||||
// SIMD_SZ == 4 (returning value of pffft_simd_size())
|
||||
int simd_size_iter = max_iter / 4;
|
||||
|
||||
if (simd_size_iter == 0) simd_size_iter = 1;
|
||||
if (complex) {
|
||||
SAPI_RETURN_IF_ERROR(api.cffti(n, work_array.PtrBoth()))
|
||||
} else {
|
||||
SAPI_RETURN_IF_ERROR(api.rffti(n, work_array.PtrBoth()));
|
||||
}
|
||||
t0 = UclockSec();
|
||||
|
||||
for (int iter = 0; iter < simd_size_iter; ++iter) {
|
||||
if (complex) {
|
||||
SAPI_RETURN_IF_ERROR(
|
||||
api.cfftf(n, x_array.PtrBoth(), work_array.PtrBoth()));
|
||||
SAPI_RETURN_IF_ERROR(
|
||||
api.cfftb(n, x_array.PtrBoth(), work_array.PtrBoth()));
|
||||
} else {
|
||||
SAPI_RETURN_IF_ERROR(
|
||||
api.rfftf(n, x_array.PtrBoth(), work_array.PtrBoth()));
|
||||
SAPI_RETURN_IF_ERROR(
|
||||
api.rfftb(n, x_array.PtrBoth(), work_array.PtrBoth()));
|
||||
}
|
||||
}
|
||||
t1 = UclockSec();
|
||||
|
||||
flops = (simd_size_iter * 2) *
|
||||
((complex ? 5 : 2.5) * static_cast<double>(n) *
|
||||
log(static_cast<double>(n)) / M_LN2);
|
||||
ShowOutput("FFTPack", n, complex, flops, t0, t1, simd_size_iter);
|
||||
}
|
||||
|
||||
// PFFFT benchmark
|
||||
{
|
||||
SAPI_ASSIGN_OR_RETURN(
|
||||
PFFFT_Setup * s,
|
||||
api.pffft_new_setup(n, complex ? PFFFT_COMPLEX : PFFFT_REAL));
|
||||
|
||||
sapi::v::RemotePtr s_reg(s);
|
||||
|
||||
t0 = UclockSec();
|
||||
for (int iter = 0; iter < max_iter; ++iter) {
|
||||
SAPI_RETURN_IF_ERROR(
|
||||
api.pffft_transform(&s_reg, x_array.PtrBoth(), z_array.PtrBoth(),
|
||||
y_array.PtrBoth(), PFFFT_FORWARD));
|
||||
SAPI_RETURN_IF_ERROR(
|
||||
api.pffft_transform(&s_reg, x_array.PtrBoth(), z_array.PtrBoth(),
|
||||
y_array.PtrBoth(), PFFFT_FORWARD));
|
||||
}
|
||||
|
||||
t1 = UclockSec();
|
||||
SAPI_RETURN_IF_ERROR(api.pffft_destroy_setup(&s_reg));
|
||||
|
||||
flops = (max_iter * 2) * ((complex ? 5 : 2.5) * static_cast<double>(n) *
|
||||
log(static_cast<double>(n)) / M_LN2);
|
||||
ShowOutput("PFFFT", n, complex, flops, t0, t1, max_iter);
|
||||
|
||||
LOG(INFO) << "n = " << n << " SUCCESSFULLY";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
// Initialize Google's logging library.
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
|
||||
if (absl::Status status = PffftMain(); !status.ok()) {
|
||||
LOG(ERROR) << "Initialization failed: " << status.ToString();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue
Block a user