<commit_before>#include "chainerx/routines/linalg.h"

#include <algorithm>
#include <cassert>
#include <cstdint>
#include <tuple>
#include <utility>
#include <vector>

#include <absl/types/optional.h>

#include "chainerx/array.h"
#include "chainerx/axes.h"
#include "chainerx/backend.h"
#include "chainerx/backprop_mode.h"
#include "chainerx/backward_builder.h"
#include "chainerx/backward_context.h"
#include "chainerx/dtype.h"
#include "chainerx/error.h"
#include "chainerx/graph.h"
#include "chainerx/kernels/linalg.h"
#include "chainerx/routines/arithmetic.h"
#include "chainerx/routines/creation.h"
#include "chainerx/routines/indexing.h"
#include "chainerx/routines/manipulation.h"
#include "chainerx/routines/type_util.h"
#include "chainerx/shape.h"

namespace chainerx {

Array Dot(const Array& a, const Array& b, absl::optional<Dtype> out_dtype) {
    Dtype real_out_dtype = out_dtype.has_value() ? *out_dtype : ResultType(a, b);

    if (a.ndim() == 0 || b.ndim() == 0) {
        return a * b;
    }

    Array modified_b{};

    Shape out_shape{};
    std::copy(a.shape().begin(), a.shape().end() - 1, std::back_inserter(out_shape));

    if (b.ndim() > 2) {
        std::vector<int> b_transpose_axes{};
        b_transpose_axes.reserve(b.ndim());
        std::vector<int> axes_index(b.ndim());
        std::iota(axes_index.begin(), axes_index.end(), 0);
        std::copy(axes_index.begin(), axes_index.end() - 2, std::back_inserter(b_transpose_axes));
        std::reverse_copy(axes_index.end() - 2, axes_index.end(), std::back_inserter(b_transpose_axes));

        Axes axes(b_transpose_axes.begin(), b_transpose_axes.end());
        modified_b = b.Transpose(axes);
        std::copy(modified_b.shape().begin(), modified_b.shape().end() - 1, std::back_inserter(out_shape));

        modified_b = modified_b.Reshape({-1, modified_b.shape().back()});
        modified_b = modified_b.Transpose();
    } else {
        std::copy(b.shape().begin() + 1, b.shape().end(), std::back_inserter(out_shape));
        modified_b = b;
    }

    int64_t k = a.shape()[a.ndim() - 1];
    if (modified_b.shape()[0] != k) {
        throw DimensionError{"Axis dimension mismatch"};
    }
    if (k == 0) {
        return Zeros(out_shape, real_out_dtype, a.device());
    }

    // Make each operand a matrix
    int64_t m = a.GetTotalSize() / k;
    int64_t n = b.GetTotalSize() / k;
    Array a_matrix = a.Reshape({m, k});
    Array b_matrix = modified_b.Reshape({k, n});

    // Matrix-matrix product
    Array out_matrix = Empty({m, n}, real_out_dtype, a.device());
    {
        NoBackpropModeScope scope{};
        a.device().backend().CallKernel<DotKernel>(a_matrix, b_matrix, out_matrix);
    }

    {
        BackwardBuilder bb{"dot", {a_matrix, b_matrix}, out_matrix};
        if (BackwardBuilder::Target bt = bb.CreateTarget(0)) {
            bt.Define([b_matrix_tok = bb.RetainInput(1), a_dtype = a.dtype()](BackwardContext& bctx) {
                const Array& b_matrix = bctx.GetRetainedInput(b_matrix_tok);
                const Array& gout = *bctx.output_grad();
                bctx.input_grad() = Dot(gout, b_matrix.Transpose(), a_dtype);
            });
        }
        if (BackwardBuilder::Target bt = bb.CreateTarget(1)) {
            bt.Define([a_matrix_tok = bb.RetainInput(0), b_dtype = b.dtype()](BackwardContext& bctx) {
                const Array& a_matrix = bctx.GetRetainedInput(a_matrix_tok);
                const Array& gout = *bctx.output_grad();
                bctx.input_grad() = Dot(a_matrix.Transpose(), gout, b_dtype);
            });
        }
        bb.Finalize();
    }

    return out_matrix.Reshape(out_shape);
}

namespace {

void CheckRankTwoArray(const Array& a) {
    if (a.ndim() != 2) {
        throw DimensionError{"ChainerX linear algebra routines support only 2-dimensional arrays."};
    }
}

void CheckSquareMatrix(const Array& a) {
    if (a.shape()[0] != a.shape()[1]) {
        throw DimensionError{"Matrix is not square."};
    }
}

}  // namespace

Array Solve(const Array& a, const Array& b) {
    CheckRankTwoArray(a);
    CheckSquareMatrix(a);
    CheckEqual(a.device(), b.device());
    CheckEqual(a.dtype(), b.dtype());
    Dtype dtype = internal::GetMathResultDtype(b.dtype());
    Array out = Empty(b.shape(), dtype, b.device());

    {
        NoBackpropModeScope scope{};
        a.device().backend().CallKernel<SolveKernel>(a, b, out);
    }

    // Reference:
    // https://people.maths.ox.ac.uk/gilesm/files/NA-08-01.pdf
    // Sec. 2.3.1 Matrix inverse product
    {
        BackwardBuilder bb{"solve", {a, b}, out};
        if (BackwardBuilder::Target bt = bb.CreateTarget(0)) {
            bt.Define([out_tok = bb.RetainOutput(0), a_tok = bb.RetainInput(0), a_dtype = a.dtype()](BackwardContext& bctx) {
                const Array& a = bctx.GetRetainedInput(a_tok);
                const Array& out = bctx.GetRetainedOutput(out_tok);
                const Array& gout = *bctx.output_grad();
                auto updim = [&](const Array& x) {
                    if (x.ndim() == a.ndim()) {
                        return x;
                    }
                    return ExpandDims(x, 1);
                };
                bctx.input_grad() = -Dot(updim(Solve(a.Transpose(), gout)), updim(out).Transpose(), a_dtype);
            });
        }
        if (BackwardBuilder::Target bt = bb.CreateTarget(1)) {
            bt.Define([a_tok = bb.RetainInput(0)](BackwardContext& bctx) {
                const Array& a = bctx.GetRetainedInput(a_tok);
                const Array& gout = *bctx.output_grad();
                bctx.input_grad() = Solve(a.Transpose(), gout);
            });
        }
        bb.Finalize();
    }

    return out;
}

Array Inverse(const Array& a) {
    CheckRankTwoArray(a);
    CheckSquareMatrix(a);
    Dtype dtype = internal::GetMathResultDtype(a.dtype());
    Array out = Empty(a.shape(), dtype, a.device());

    {
        NoBackpropModeScope scope{};
        a.device().backend().CallKernel<InverseKernel>(a, out);
    }

    // Reference:
    // https://people.maths.ox.ac.uk/gilesm/files/NA-08-01.pdf
    // Sec. 2.2.3 Inverse
    {
        BackwardBuilder bb{"inv", a, out};
        if (BackwardBuilder::Target bt = bb.CreateTarget(0)) {
            bt.Define([out_tok = bb.RetainOutput(0), a_dtype = a.dtype()](BackwardContext& bctx) {
                const Array& out = bctx.GetRetainedOutput(out_tok);
                const Array& gout = *bctx.output_grad();
                bctx.input_grad() = -Dot(Dot(out.Transpose(), gout, a_dtype), out.Transpose(), a_dtype);
            });
        }
        bb.Finalize();
    }

    return out;
}

std::tuple<Array, Array, Array> SVD(const Array& a, bool full_matrices, bool compute_uv) {
    CheckRankTwoArray(a);
    Array u{};
    Array s{};
    Array v{};

    {
        NoBackpropModeScope scope{};
        std::tie(u, s, v) = a.device().backend().CallKernel<SVDKernel>(a, full_matrices, compute_uv);
    }

    // Reference:
    // https://j-towns.github.io/papers/svd-derivative.pdf
    {
        BackwardBuilder bb{"svd", a, {u, s, v}};
        if (BackwardBuilder::Target bt = bb.CreateTarget(0)) {
            bt.Define([a_tok = bb.RetainInput(0),
                       u_tok = bb.RetainOutput(0),
                       s_tok = bb.RetainOutput(1),
                       v_tok = bb.RetainOutput(2),
                       full_matrices,
                       compute_uv](BackwardContext& bctx) {
                if (full_matrices) {
                    throw ChainerxError{"ChainerX SVD differentiation is not implemented for full_matrices=true."};
                }
                if (!compute_uv) {
                    throw ChainerxError{"ChainerX SVD differentiation cannot be computed with compute_uv=false."};
                }

                const Array& a = bctx.GetRetainedInput(a_tok);
                const Array& u = bctx.GetRetainedOutput(u_tok);
                const Array& s = bctx.GetRetainedOutput(s_tok);
                const Array& vt = bctx.GetRetainedOutput(v_tok);

                auto m = a.shape()[0];
                auto n = a.shape()[1];
                auto k = s.shape()[0];

                const Array& gu = bctx.output_grad(0).has_value() ? *bctx.output_grad(0) : Zeros(u.shape(), a.dtype(), a.device());
                const Array& gsigma = bctx.output_grad(1).has_value() ? *bctx.output_grad(1) : Zeros(s.shape(), a.dtype(), a.device());
                const Array& gvt = bctx.output_grad(2).has_value() ? *bctx.output_grad(2) : Zeros(vt.shape(), a.dtype(), a.device());

                auto v = vt.Transpose();
                auto gv = gvt.Transpose();

                auto sigma_term = Dot(Dot(u, Diag(gsigma)), vt);

                auto ut = u.Transpose();
                auto im = Eye(m, m, 0, a.dtype(), a.device());
                auto in = Eye(n, n, 0, a.dtype(), a.device());
                auto sigma_mat = Diag(s);
                auto sigma_mat_inv = Diag(Power(s, -1));
                auto sigma_sq = Power(s, 2);
                auto F = ExpandDims(sigma_sq, 0) - ExpandDims(sigma_sq, 1);
                // Invert values of F, and fill the diagonal with 0s.
                // F has 0s on the diagonal, therefore fill it first with infinity.
                auto mask = Eye(F.shape()[0], F.shape()[1], 0, Dtype::kBool, a.device());
                F = Where(mask, INFINITY, F);
                F = Power(F, -1);

                Array u_term{};
                Array utgu = Dot(u.Transpose(), gu);
                u_term = Dot(Dot(u, F * (utgu - utgu.Transpose())), sigma_mat);
                if (m > k) {
                    u_term = u_term + Dot(Dot(im - Dot(u, ut), gu), sigma_mat_inv);
                }
                u_term = Dot(u_term, vt);

                Array v_term{};
                Array vtgv = Dot(vt, gv);
                v_term = Dot(Dot(sigma_mat, F * (vtgv - vtgv.Transpose())), vt);
                if (n > k) {
                    v_term = v_term + Dot(sigma_mat_inv, Dot(gvt, in - Dot(v, vt)));
                }
                v_term = Dot(u, v_term);

                bctx.input_grad() = u_term + sigma_term + v_term;
            });
        }
        bb.Finalize();
    }

    return std::make_tuple(std::move(u), std::move(s), std::move(v));
}

Array PseudoInverse(const Array& a, float rcond) {
    CheckRankTwoArray(a);
    Dtype dtype = internal::GetMathResultDtype(a.dtype());
    Array out = Empty(Shape({a.shape()[1], a.shape()[0]}), dtype, a.device());

    {
        NoBackpropModeScope scope{};
        a.device().backend().CallKernel<PseudoInverseKernel>(a, out, rcond);
    }

    // Reference:
    // https://mathoverflow.net/questions/25778/analytical-formula-for-numerical-derivative-of-the-matrix-pseudo-inverse
    {
        BackwardBuilder bb{"pinv", a, out};
        if (BackwardBuilder::Target bt = bb.CreateTarget(0)) {
            bt.Define([a_tok = bb.RetainInput(0), out_tok = bb.RetainOutput(0), a_dtype = a.dtype(), &a_device = a.device()](
                              BackwardContext& bctx) {
                const Array& a = bctx.GetRetainedInput(a_tok);
                const Array& out = bctx.GetRetainedOutput(out_tok);
                const Array& gout = *bctx.output_grad();
                Array I_a = Identity(a.shape()[0], a_dtype, a_device);
                Array I_out = Identity(out.shape()[0], a_dtype, a_device);
                bctx.input_grad() = (-Dot(Dot(out, gout.Transpose()), out) + Dot(Dot(Dot(out, out.Transpose()), gout), I_a - Dot(a, out)) +
                                     Dot(Dot(Dot(I_out - Dot(out, a), gout), out.Transpose()), out))
                                            .Transpose();
            });
        }
        bb.Finalize();
    }

    return out;
}

}  // namespace chainerx
<commit_msg>Use explicit type instead of auto<commit_after>#include "chainerx/routines/linalg.h"

#include <algorithm>
#include <cassert>
#include <cstdint>
#include <tuple>
#include <utility>
#include <vector>

#include <absl/types/optional.h>

#include "chainerx/array.h"
#include "chainerx/axes.h"
#include "chainerx/backend.h"
#include "chainerx/backprop_mode.h"
#include "chainerx/backward_builder.h"
#include "chainerx/backward_context.h"
#include "chainerx/dtype.h"
#include "chainerx/error.h"
#include "chainerx/graph.h"
#include "chainerx/kernels/linalg.h"
#include "chainerx/routines/arithmetic.h"
#include "chainerx/routines/creation.h"
#include "chainerx/routines/indexing.h"
#include "chainerx/routines/manipulation.h"
#include "chainerx/routines/type_util.h"
#include "chainerx/shape.h"

namespace chainerx {

Array Dot(const Array& a, const Array& b, absl::optional<Dtype> out_dtype) {
    Dtype real_out_dtype = out_dtype.has_value() ? *out_dtype : ResultType(a, b);

    if (a.ndim() == 0 || b.ndim() == 0) {
        return a * b;
    }

    Array modified_b{};

    Shape out_shape{};
    std::copy(a.shape().begin(), a.shape().end() - 1, std::back_inserter(out_shape));

    if (b.ndim() > 2) {
        std::vector<int> b_transpose_axes{};
        b_transpose_axes.reserve(b.ndim());
        std::vector<int> axes_index(b.ndim());
        std::iota(axes_index.begin(), axes_index.end(), 0);
        std::copy(axes_index.begin(), axes_index.end() - 2, std::back_inserter(b_transpose_axes));
        std::reverse_copy(axes_index.end() - 2, axes_index.end(), std::back_inserter(b_transpose_axes));

        Axes axes(b_transpose_axes.begin(), b_transpose_axes.end());
        modified_b = b.Transpose(axes);
        std::copy(modified_b.shape().begin(), modified_b.shape().end() - 1, std::back_inserter(out_shape));

        modified_b = modified_b.Reshape({-1, modified_b.shape().back()});
        modified_b = modified_b.Transpose();
    } else {
        std::copy(b.shape().begin() + 1, b.shape().end(), std::back_inserter(out_shape));
        modified_b = b;
    }

    int64_t k = a.shape()[a.ndim() - 1];
    if (modified_b.shape()[0] != k) {
        throw DimensionError{"Axis dimension mismatch"};
    }
    if (k == 0) {
        return Zeros(out_shape, real_out_dtype, a.device());
    }

    // Make each operand a matrix
    int64_t m = a.GetTotalSize() / k;
    int64_t n = b.GetTotalSize() / k;
    Array a_matrix = a.Reshape({m, k});
    Array b_matrix = modified_b.Reshape({k, n});

    // Matrix-matrix product
    Array out_matrix = Empty({m, n}, real_out_dtype, a.device());
    {
        NoBackpropModeScope scope{};
        a.device().backend().CallKernel<DotKernel>(a_matrix, b_matrix, out_matrix);
    }

    {
        BackwardBuilder bb{"dot", {a_matrix, b_matrix}, out_matrix};
        if (BackwardBuilder::Target bt = bb.CreateTarget(0)) {
            bt.Define([b_matrix_tok = bb.RetainInput(1), a_dtype = a.dtype()](BackwardContext& bctx) {
                const Array& b_matrix = bctx.GetRetainedInput(b_matrix_tok);
                const Array& gout = *bctx.output_grad();
                bctx.input_grad() = Dot(gout, b_matrix.Transpose(), a_dtype);
            });
        }
        if (BackwardBuilder::Target bt = bb.CreateTarget(1)) {
            bt.Define([a_matrix_tok = bb.RetainInput(0), b_dtype = b.dtype()](BackwardContext& bctx) {
                const Array& a_matrix = bctx.GetRetainedInput(a_matrix_tok);
                const Array& gout = *bctx.output_grad();
                bctx.input_grad() = Dot(a_matrix.Transpose(), gout, b_dtype);
            });
        }
        bb.Finalize();
    }

    return out_matrix.Reshape(out_shape);
}

namespace {

void CheckRankTwoArray(const Array& a) {
    if (a.ndim() != 2) {
        throw DimensionError{"ChainerX linear algebra routines support only 2-dimensional arrays."};
    }
}

void CheckSquareMatrix(const Array& a) {
    if (a.shape()[0] != a.shape()[1]) {
        throw DimensionError{"Matrix is not square."};
    }
}

}  // namespace

Array Solve(const Array& a, const Array& b) {
    CheckRankTwoArray(a);
    CheckSquareMatrix(a);
    CheckEqual(a.device(), b.device());
    CheckEqual(a.dtype(), b.dtype());
    Dtype dtype = internal::GetMathResultDtype(b.dtype());
    Array out = Empty(b.shape(), dtype, b.device());

    {
        NoBackpropModeScope scope{};
        a.device().backend().CallKernel<SolveKernel>(a, b, out);
    }

    // Reference:
    // https://people.maths.ox.ac.uk/gilesm/files/NA-08-01.pdf
    // Sec. 2.3.1 Matrix inverse product
    {
        BackwardBuilder bb{"solve", {a, b}, out};
        if (BackwardBuilder::Target bt = bb.CreateTarget(0)) {
            bt.Define([out_tok = bb.RetainOutput(0), a_tok = bb.RetainInput(0), a_dtype = a.dtype()](BackwardContext& bctx) {
                const Array& a = bctx.GetRetainedInput(a_tok);
                const Array& out = bctx.GetRetainedOutput(out_tok);
                const Array& gout = *bctx.output_grad();
                auto updim = [&](const Array& x) {
                    if (x.ndim() == a.ndim()) {
                        return x;
                    }
                    return ExpandDims(x, 1);
                };
                bctx.input_grad() = -Dot(updim(Solve(a.Transpose(), gout)), updim(out).Transpose(), a_dtype);
            });
        }
        if (BackwardBuilder::Target bt = bb.CreateTarget(1)) {
            bt.Define([a_tok = bb.RetainInput(0)](BackwardContext& bctx) {
                const Array& a = bctx.GetRetainedInput(a_tok);
                const Array& gout = *bctx.output_grad();
                bctx.input_grad() = Solve(a.Transpose(), gout);
            });
        }
        bb.Finalize();
    }

    return out;
}

Array Inverse(const Array& a) {
    CheckRankTwoArray(a);
    CheckSquareMatrix(a);
    Dtype dtype = internal::GetMathResultDtype(a.dtype());
    Array out = Empty(a.shape(), dtype, a.device());

    {
        NoBackpropModeScope scope{};
        a.device().backend().CallKernel<InverseKernel>(a, out);
    }

    // Reference:
    // https://people.maths.ox.ac.uk/gilesm/files/NA-08-01.pdf
    // Sec. 2.2.3 Inverse
    {
        BackwardBuilder bb{"inv", a, out};
        if (BackwardBuilder::Target bt = bb.CreateTarget(0)) {
            bt.Define([out_tok = bb.RetainOutput(0), a_dtype = a.dtype()](BackwardContext& bctx) {
                const Array& out = bctx.GetRetainedOutput(out_tok);
                const Array& gout = *bctx.output_grad();
                bctx.input_grad() = -Dot(Dot(out.Transpose(), gout, a_dtype), out.Transpose(), a_dtype);
            });
        }
        bb.Finalize();
    }

    return out;
}

std::tuple<Array, Array, Array> SVD(const Array& a, bool full_matrices, bool compute_uv) {
    CheckRankTwoArray(a);
    Array u{};
    Array s{};
    Array v{};

    {
        NoBackpropModeScope scope{};
        std::tie(u, s, v) = a.device().backend().CallKernel<SVDKernel>(a, full_matrices, compute_uv);
    }

    // Reference:
    // https://j-towns.github.io/papers/svd-derivative.pdf
    {
        BackwardBuilder bb{"svd", a, {u, s, v}};
        if (BackwardBuilder::Target bt = bb.CreateTarget(0)) {
            bt.Define([a_tok = bb.RetainInput(0),
                       u_tok = bb.RetainOutput(0),
                       s_tok = bb.RetainOutput(1),
                       v_tok = bb.RetainOutput(2),
                       full_matrices,
                       compute_uv](BackwardContext& bctx) {
                if (full_matrices) {
                    throw ChainerxError{"ChainerX SVD differentiation is not implemented for full_matrices=true."};
                }
                if (!compute_uv) {
                    throw ChainerxError{"ChainerX SVD differentiation cannot be computed with compute_uv=false."};
                }

                const Array& a = bctx.GetRetainedInput(a_tok);
                const Array& u = bctx.GetRetainedOutput(u_tok);
                const Array& s = bctx.GetRetainedOutput(s_tok);
                const Array& vt = bctx.GetRetainedOutput(v_tok);

                auto m = a.shape()[0];
                auto n = a.shape()[1];
                auto k = s.shape()[0];

                const Array& gu = bctx.output_grad(0).has_value() ? *bctx.output_grad(0) : Zeros(u.shape(), a.dtype(), a.device());
                const Array& gsigma = bctx.output_grad(1).has_value() ? *bctx.output_grad(1) : Zeros(s.shape(), a.dtype(), a.device());
                const Array& gvt = bctx.output_grad(2).has_value() ? *bctx.output_grad(2) : Zeros(vt.shape(), a.dtype(), a.device());

                Array v = vt.Transpose();
                Array gv = gvt.Transpose();

                Array sigma_term = Dot(Dot(u, Diag(gsigma)), vt);

                Array ut = u.Transpose();
                Array im = Eye(m, m, 0, a.dtype(), a.device());
                Array in = Eye(n, n, 0, a.dtype(), a.device());
                Array sigma_mat = Diag(s);
                Array sigma_mat_inv = Diag(Power(s, -1));
                Array sigma_sq = Power(s, 2);
                Array F = ExpandDims(sigma_sq, 0) - ExpandDims(sigma_sq, 1);
                // Invert values of F, and fill the diagonal with 0s.
                // F has 0s on the diagonal, therefore fill it first with infinity.
                Array mask = Eye(F.shape()[0], F.shape()[1], 0, Dtype::kBool, a.device());
                F = Where(mask, INFINITY, F);
                F = Power(F, -1);

                Array u_term{};
                Array utgu = Dot(u.Transpose(), gu);
                u_term = Dot(Dot(u, F * (utgu - utgu.Transpose())), sigma_mat);
                if (m > k) {
                    u_term = u_term + Dot(Dot(im - Dot(u, ut), gu), sigma_mat_inv);
                }
                u_term = Dot(u_term, vt);

                Array v_term{};
                Array vtgv = Dot(vt, gv);
                v_term = Dot(Dot(sigma_mat, F * (vtgv - vtgv.Transpose())), vt);
                if (n > k) {
                    v_term = v_term + Dot(sigma_mat_inv, Dot(gvt, in - Dot(v, vt)));
                }
                v_term = Dot(u, v_term);

                bctx.input_grad() = u_term + sigma_term + v_term;
            });
        }
        bb.Finalize();
    }

    return std::make_tuple(std::move(u), std::move(s), std::move(v));
}

Array PseudoInverse(const Array& a, float rcond) {
    CheckRankTwoArray(a);
    Dtype dtype = internal::GetMathResultDtype(a.dtype());
    Array out = Empty(Shape({a.shape()[1], a.shape()[0]}), dtype, a.device());

    {
        NoBackpropModeScope scope{};
        a.device().backend().CallKernel<PseudoInverseKernel>(a, out, rcond);
    }

    // Reference:
    // https://mathoverflow.net/questions/25778/analytical-formula-for-numerical-derivative-of-the-matrix-pseudo-inverse
    {
        BackwardBuilder bb{"pinv", a, out};
        if (BackwardBuilder::Target bt = bb.CreateTarget(0)) {
            bt.Define([a_tok = bb.RetainInput(0), out_tok = bb.RetainOutput(0), a_dtype = a.dtype(), &a_device = a.device()](
                              BackwardContext& bctx) {
                const Array& a = bctx.GetRetainedInput(a_tok);
                const Array& out = bctx.GetRetainedOutput(out_tok);
                const Array& gout = *bctx.output_grad();
                Array I_a = Identity(a.shape()[0], a_dtype, a_device);
                Array I_out = Identity(out.shape()[0], a_dtype, a_device);
                bctx.input_grad() = (-Dot(Dot(out, gout.Transpose()), out) + Dot(Dot(Dot(out, out.Transpose()), gout), I_a - Dot(a, out)) +
                                     Dot(Dot(Dot(I_out - Dot(out, a), gout), out.Transpose()), out))
                                            .Transpose();
            });
        }
        bb.Finalize();
    }

    return out;
}

}  // namespace chainerx
<|endoftext|>


<commit_before>// Copyright 2017 The Ray Authors.
//
// 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.

// clang-format off
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "ray/gcs/gcs_server/gcs_placement_group_manager.h"
#include "mock/ray/gcs/gcs_server/gcs_placement_group_manager.h"
#include "mock/ray/gcs/gcs_server/gcs_placement_group_scheduler.h"
#include "mock/ray/gcs/gcs_server/gcs_resource_manager.h"
#include "mock/ray/gcs/store_client/store_client.h"
#include "ray/gcs/test/gcs_test_util.h"
// clang-format on

using namespace ::testing;
using namespace ray;
using namespace ray::gcs;
namespace ray {
namespace gcs {

class GcsPlacementGroupManagerMockTest : public Test {
 public:
  void SetUp() override {
    store_client_ = std::make_shared<MockStoreClient>();
    gcs_table_storage_ = std::make_shared<GcsTableStorage>(store_client_);
    gcs_placement_group_scheduler_ =
        std::make_shared<MockGcsPlacementGroupSchedulerInterface>();
    resource_manager_ =
        std::make_shared<MockGcsResourceManager>(io_context_, nullptr, nullptr, true);

    gcs_placement_group_manager_ = std::make_unique<GcsPlacementGroupManager>(
        io_context_, gcs_placement_group_scheduler_, gcs_table_storage_,
        *resource_manager_, [](auto &) { return ""; });
  }

  std::unique_ptr<GcsPlacementGroupManager> gcs_placement_group_manager_;
  std::shared_ptr<MockGcsPlacementGroupSchedulerInterface> gcs_placement_group_scheduler_;
  std::shared_ptr<gcs::GcsTableStorage> gcs_table_storage_;
  std::shared_ptr<MockStoreClient> store_client_;
  std::shared_ptr<GcsResourceManager> resource_manager_;
  instrumented_io_context io_context_;
};

TEST_F(GcsPlacementGroupManagerMockTest, PendingQueuePriorityReschedule) {
  // Test priority works
  //   When return with reschedule, it should be given with the highest pri
  auto req =
      Mocker::GenCreatePlacementGroupRequest("", rpc::PlacementStrategy::SPREAD, 1);
  auto pg = std::make_shared<GcsPlacementGroup>(req, "");
  auto cb = [](Status s) {};
  PGSchedulingFailureCallback failure_callback;
  PGSchedulingSuccessfulCallback success_callback;
  StatusCallback put_cb;
  EXPECT_CALL(*store_client_, AsyncPut(_, _, _, _))
      .WillOnce(DoAll(SaveArg<3>(&put_cb), Return(Status::OK())));
  EXPECT_CALL(*gcs_placement_group_scheduler_, ScheduleUnplacedBundles(_, _, _))
      .WillOnce(DoAll(SaveArg<1>(&failure_callback), SaveArg<2>(&success_callback)));
  auto now = absl::GetCurrentTimeNanos();
  gcs_placement_group_manager_->RegisterPlacementGroup(pg, cb);
  auto &pending_queue = gcs_placement_group_manager_->pending_placement_groups_;
  ASSERT_EQ(1, pending_queue.size());
  ASSERT_LE(now, pending_queue.begin()->first);
  ASSERT_GE(absl::GetCurrentTimeNanos(), pending_queue.begin()->first);
  put_cb(Status::OK());
  pg->UpdateState(rpc::PlacementGroupTableData::RESCHEDULING);
  failure_callback(pg, true);
  ASSERT_EQ(1, pending_queue.size());
  ASSERT_GE(0, pending_queue.begin()->first);
}

TEST_F(GcsPlacementGroupManagerMockTest, PendingQueuePriorityFailed) {
  // Test priority works
  //   When return with a failure, exp backoff should work
  auto req =
      Mocker::GenCreatePlacementGroupRequest("", rpc::PlacementStrategy::SPREAD, 1);
  auto pg = std::make_shared<GcsPlacementGroup>(req, "");
  auto cb = [](Status s) {};
  PGSchedulingFailureCallback failure_callback;
  PGSchedulingSuccessfulCallback success_callback;
  StatusCallback put_cb;
  EXPECT_CALL(*store_client_, AsyncPut(_, _, _, _))
      .WillOnce(DoAll(SaveArg<3>(&put_cb), Return(Status::OK())));
  EXPECT_CALL(*gcs_placement_group_scheduler_, ScheduleUnplacedBundles(_, _, _))
      .Times(2)
      .WillRepeatedly(
          DoAll(SaveArg<1>(&failure_callback), SaveArg<2>(&success_callback)));
  auto now = absl::GetCurrentTimeNanos();
  gcs_placement_group_manager_->RegisterPlacementGroup(pg, cb);
  auto &pending_queue = gcs_placement_group_manager_->pending_placement_groups_;
  ASSERT_EQ(1, pending_queue.size());
  ASSERT_LE(now, pending_queue.begin()->first);
  ASSERT_GE(absl::GetCurrentTimeNanos(), pending_queue.begin()->first);
  put_cb(Status::OK());
  pg->UpdateState(rpc::PlacementGroupTableData::PENDING);
  now = absl::GetCurrentTimeNanos();
  failure_callback(pg, true);
  auto exp_backer = ExponentialBackOff(
      1000000 * RayConfig::instance().gcs_create_placement_group_retry_min_interval_ms(),
      RayConfig::instance().gcs_create_placement_group_retry_multiplier(),
      1000000 * RayConfig::instance().gcs_create_placement_group_retry_max_interval_ms());
  auto next = exp_backer.Next();
  ASSERT_DOUBLE_EQ(
      next,
      1000000 * RayConfig::instance().gcs_create_placement_group_retry_min_interval_ms());
  ASSERT_EQ(1, pending_queue.size());
  auto rank = pending_queue.begin()->first;
  ASSERT_LE(now + next, rank);
  // ScheduleUnplacedBundles is not called here
  gcs_placement_group_manager_->SchedulePendingPlacementGroups();
  ASSERT_EQ(1, pending_queue.size());
  ASSERT_EQ(rank, pending_queue.begin()->first);

  absl::SleepFor(absl::Nanoseconds(rank - absl::GetCurrentTimeNanos()));
  gcs_placement_group_manager_->SchedulePendingPlacementGroups();
  ASSERT_EQ(0, pending_queue.size());
  pg->UpdateState(rpc::PlacementGroupTableData::PENDING);
  now = absl::GetCurrentTimeNanos();
  failure_callback(pg, true);
  next = RayConfig::instance().gcs_create_placement_group_retry_multiplier() * next;
  ASSERT_EQ(1, pending_queue.size());
  ASSERT_LE(now + next, pending_queue.begin()->first);
}

TEST_F(GcsPlacementGroupManagerMockTest, PendingQueuePriorityOrder) {
  // Test priority works
  //   Add two pgs
  //   Fail one and make sure it's scheduled later
  auto req1 =
      Mocker::GenCreatePlacementGroupRequest("", rpc::PlacementStrategy::SPREAD, 1);
  auto pg1 = std::make_shared<GcsPlacementGroup>(req1, "");
  auto req2 =
      Mocker::GenCreatePlacementGroupRequest("", rpc::PlacementStrategy::SPREAD, 1);
  auto pg2 = std::make_shared<GcsPlacementGroup>(req2, "");
  auto cb = [](Status s) {};
  PGSchedulingFailureCallback failure_callback;
  PGSchedulingSuccessfulCallback success_callback;
  StatusCallback put_cb;
  EXPECT_CALL(*store_client_, AsyncPut(_, _, _, _))
      .Times(2)
      .WillRepeatedly(DoAll(SaveArg<3>(&put_cb), Return(Status::OK())));
  EXPECT_CALL(*gcs_placement_group_scheduler_, ScheduleUnplacedBundles(_, _, _))
      .Times(2)
      .WillRepeatedly(
          DoAll(SaveArg<1>(&failure_callback), SaveArg<2>(&success_callback)));
  gcs_placement_group_manager_->RegisterPlacementGroup(pg1, cb);
  gcs_placement_group_manager_->RegisterPlacementGroup(pg2, cb);
  auto &pending_queue = gcs_placement_group_manager_->pending_placement_groups_;
  ASSERT_EQ(2, pending_queue.size());
  put_cb(Status::OK());
  ASSERT_EQ(1, pending_queue.size());
  // PG1 is scheduled first, so PG2 is in pending queue
  ASSERT_EQ(pg2, pending_queue.begin()->second.second);
  failure_callback(pg1, true);
  ASSERT_EQ(2, pending_queue.size());
  gcs_placement_group_manager_->SchedulePendingPlacementGroups();
  // PG2 is scheduled for the next, so PG1 is in pending queue
  ASSERT_EQ(1, pending_queue.size());
  ASSERT_EQ(pg1, pending_queue.begin()->second.second);
}

}  // namespace gcs
}  // namespace ray
<commit_msg>fix (#19094)<commit_after>// Copyright 2017 The Ray Authors.
//
// 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.

// clang-format off
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "ray/gcs/gcs_server/gcs_placement_group_manager.h"
#include "mock/ray/gcs/gcs_server/gcs_placement_group_manager.h"
#include "mock/ray/gcs/gcs_server/gcs_placement_group_scheduler.h"
#include "mock/ray/gcs/gcs_server/gcs_resource_manager.h"
#include "mock/ray/gcs/store_client/store_client.h"
#include "ray/gcs/test/gcs_test_util.h"
// clang-format on

using namespace ::testing;
using namespace ray;
using namespace ray::gcs;
namespace ray {
namespace gcs {

class GcsPlacementGroupManagerMockTest : public Test {
 public:
  void SetUp() override {
    store_client_ = std::make_shared<MockStoreClient>();
    gcs_table_storage_ = std::make_shared<GcsTableStorage>(store_client_);
    gcs_placement_group_scheduler_ =
        std::make_shared<MockGcsPlacementGroupSchedulerInterface>();
    resource_manager_ =
        std::make_shared<MockGcsResourceManager>(io_context_, nullptr, nullptr, true);

    gcs_placement_group_manager_ = std::make_unique<GcsPlacementGroupManager>(
        io_context_, gcs_placement_group_scheduler_, gcs_table_storage_,
        *resource_manager_, [](auto &) { return ""; });
  }

  std::unique_ptr<GcsPlacementGroupManager> gcs_placement_group_manager_;
  std::shared_ptr<MockGcsPlacementGroupSchedulerInterface> gcs_placement_group_scheduler_;
  std::shared_ptr<gcs::GcsTableStorage> gcs_table_storage_;
  std::shared_ptr<MockStoreClient> store_client_;
  std::shared_ptr<GcsResourceManager> resource_manager_;
  instrumented_io_context io_context_;
};

TEST_F(GcsPlacementGroupManagerMockTest, PendingQueuePriorityReschedule) {
  // Test priority works
  //   When return with reschedule, it should be given with the highest pri
  auto req =
      Mocker::GenCreatePlacementGroupRequest("", rpc::PlacementStrategy::SPREAD, 1);
  auto pg = std::make_shared<GcsPlacementGroup>(req, "");
  auto cb = [](Status s) {};
  PGSchedulingFailureCallback failure_callback;
  PGSchedulingSuccessfulCallback success_callback;
  StatusCallback put_cb;
  EXPECT_CALL(*store_client_, AsyncPut(_, _, _, _))
      .WillOnce(DoAll(SaveArg<3>(&put_cb), Return(Status::OK())));
  EXPECT_CALL(*gcs_placement_group_scheduler_, ScheduleUnplacedBundles(_, _, _))
      .WillOnce(DoAll(SaveArg<1>(&failure_callback), SaveArg<2>(&success_callback)));
  auto now = absl::GetCurrentTimeNanos();
  gcs_placement_group_manager_->RegisterPlacementGroup(pg, cb);
  auto &pending_queue = gcs_placement_group_manager_->pending_placement_groups_;
  ASSERT_EQ(1, pending_queue.size());
  ASSERT_LE(now, pending_queue.begin()->first);
  ASSERT_GE(absl::GetCurrentTimeNanos(), pending_queue.begin()->first);
  put_cb(Status::OK());
  pg->UpdateState(rpc::PlacementGroupTableData::RESCHEDULING);
  failure_callback(pg, true);
  ASSERT_EQ(1, pending_queue.size());
  ASSERT_GE(0, pending_queue.begin()->first);
}

TEST_F(GcsPlacementGroupManagerMockTest, PendingQueuePriorityFailed) {
  // Test priority works
  //   When return with a failure, exp backoff should work
  auto req =
      Mocker::GenCreatePlacementGroupRequest("", rpc::PlacementStrategy::SPREAD, 1);
  auto pg = std::make_shared<GcsPlacementGroup>(req, "");
  auto cb = [](Status s) {};
  PGSchedulingFailureCallback failure_callback;
  PGSchedulingSuccessfulCallback success_callback;
  StatusCallback put_cb;
  EXPECT_CALL(*store_client_, AsyncPut(_, _, _, _))
      .WillOnce(DoAll(SaveArg<3>(&put_cb), Return(Status::OK())));
  EXPECT_CALL(*gcs_placement_group_scheduler_, ScheduleUnplacedBundles(_, _, _))
      .Times(2)
      .WillRepeatedly(
          DoAll(SaveArg<1>(&failure_callback), SaveArg<2>(&success_callback)));
  auto now = absl::GetCurrentTimeNanos();
  gcs_placement_group_manager_->RegisterPlacementGroup(pg, cb);
  auto &pending_queue = gcs_placement_group_manager_->pending_placement_groups_;
  ASSERT_EQ(1, pending_queue.size());
  ASSERT_LE(now, pending_queue.begin()->first);
  ASSERT_GE(absl::GetCurrentTimeNanos(), pending_queue.begin()->first);
  put_cb(Status::OK());
  pg->UpdateState(rpc::PlacementGroupTableData::PENDING);
  now = absl::GetCurrentTimeNanos();
  failure_callback(pg, true);
  auto exp_backer = ExponentialBackOff(
      1000000 * RayConfig::instance().gcs_create_placement_group_retry_min_interval_ms(),
      RayConfig::instance().gcs_create_placement_group_retry_multiplier(),
      1000000 * RayConfig::instance().gcs_create_placement_group_retry_max_interval_ms());
  auto next = exp_backer.Next();
  ASSERT_DOUBLE_EQ(
      next,
      1000000 * RayConfig::instance().gcs_create_placement_group_retry_min_interval_ms());
  ASSERT_EQ(1, pending_queue.size());
  auto rank = pending_queue.begin()->first;
  ASSERT_LE(now + next, rank);
  // ScheduleUnplacedBundles is not called here
  gcs_placement_group_manager_->SchedulePendingPlacementGroups();
  ASSERT_EQ(1, pending_queue.size());
  ASSERT_EQ(rank, pending_queue.begin()->first);

  absl::SleepFor(absl::Milliseconds(1) +
                 absl::Nanoseconds(rank - absl::GetCurrentTimeNanos()));
  gcs_placement_group_manager_->SchedulePendingPlacementGroups();
  ASSERT_EQ(0, pending_queue.size());
  pg->UpdateState(rpc::PlacementGroupTableData::PENDING);
  now = absl::GetCurrentTimeNanos();
  failure_callback(pg, true);
  next = RayConfig::instance().gcs_create_placement_group_retry_multiplier() * next;
  ASSERT_EQ(1, pending_queue.size());
  ASSERT_LE(now + next, pending_queue.begin()->first);
}

TEST_F(GcsPlacementGroupManagerMockTest, PendingQueuePriorityOrder) {
  // Test priority works
  //   Add two pgs
  //   Fail one and make sure it's scheduled later
  auto req1 =
      Mocker::GenCreatePlacementGroupRequest("", rpc::PlacementStrategy::SPREAD, 1);
  auto pg1 = std::make_shared<GcsPlacementGroup>(req1, "");
  auto req2 =
      Mocker::GenCreatePlacementGroupRequest("", rpc::PlacementStrategy::SPREAD, 1);
  auto pg2 = std::make_shared<GcsPlacementGroup>(req2, "");
  auto cb = [](Status s) {};
  PGSchedulingFailureCallback failure_callback;
  PGSchedulingSuccessfulCallback success_callback;
  StatusCallback put_cb;
  EXPECT_CALL(*store_client_, AsyncPut(_, _, _, _))
      .Times(2)
      .WillRepeatedly(DoAll(SaveArg<3>(&put_cb), Return(Status::OK())));
  EXPECT_CALL(*gcs_placement_group_scheduler_, ScheduleUnplacedBundles(_, _, _))
      .Times(2)
      .WillRepeatedly(
          DoAll(SaveArg<1>(&failure_callback), SaveArg<2>(&success_callback)));
  gcs_placement_group_manager_->RegisterPlacementGroup(pg1, cb);
  gcs_placement_group_manager_->RegisterPlacementGroup(pg2, cb);
  auto &pending_queue = gcs_placement_group_manager_->pending_placement_groups_;
  ASSERT_EQ(2, pending_queue.size());
  put_cb(Status::OK());
  ASSERT_EQ(1, pending_queue.size());
  // PG1 is scheduled first, so PG2 is in pending queue
  ASSERT_EQ(pg2, pending_queue.begin()->second.second);
  failure_callback(pg1, true);
  ASSERT_EQ(2, pending_queue.size());
  gcs_placement_group_manager_->SchedulePendingPlacementGroups();
  // PG2 is scheduled for the next, so PG1 is in pending queue
  ASSERT_EQ(1, pending_queue.size());
  ASSERT_EQ(pg1, pending_queue.begin()->second.second);
}

}  // namespace gcs
}  // namespace ray
<|endoftext|>


<commit_before>#include <stan/prob/distributions/univariate/continuous/student_t.hpp>
#include <gtest/gtest.h>
#include <boost/random/mersenne_twister.hpp>
#include<boost/math/distributions.hpp>

TEST(ProbDistributionsStudentT, random) {
  boost::random::mt19937 rng;
  EXPECT_NO_THROW(stan::prob::student_t_rng(3.0, 2.0, 1.0, rng));
}

TEST(ProbDistributionsStudentT, doesFit) {
  boost::random::mt19937 rng;
  boost::math::students_t_distribution<>dist (3.0);
  int N = 10000;
  int K = 5;
  boost::math::chi_squared mydist(K-1);

  double loc[4];
  for(int i = 1; i < K; i++)
    loc[i - 1] = quantile(dist, 0.2 * i);

  int count = 0;
  int bin [5] = {0, 0, 0, 0, 0};

  while (count < N) {
    double a = stan::prob::student_t_rng(3.0,2.0,1.0,rng);
    int i = 0;
    while (i < K-1 && a > loc[i])
	++i;
    ++bin[i];
    count++;
   }

  double chi = 0;
  double expect [5] = {N / K, N / K, N / K, N / K, N / K};

  for(int j = 0; j < K; j++)
    chi += ((bin[j] - expect[j]) * (bin[j] - expect[j]) / expect[j]);

  EXPECT_TRUE(chi < quantile(complement(mydist, 1e-6)));
}
<commit_msg>added rng test for student_t<commit_after>#include <stan/prob/distributions/univariate/continuous/student_t.hpp>
#include <gtest/gtest.h>
#include <boost/random/mersenne_twister.hpp>
#include<boost/math/distributions.hpp>

TEST(ProbDistributionsStudentT, random) {
  boost::random::mt19937 rng;
  EXPECT_NO_THROW(stan::prob::student_t_rng(3.0, 2.0, 1.0, rng));
}

TEST(ProbDistributionsStudentT, doesFit) {
  boost::random::mt19937 rng;
  boost::math::students_t_distribution<>dist (3.0);
  int N = 10000;
  int K = 5;
  boost::math::chi_squared mydist(K-1);

  double loc[4];
  for(int i = 1; i < K; i++)
    loc[i - 1] = quantile(dist, 0.2 * i);

  int count = 0;
  int bin [5] = {0, 0, 0, 0, 0};

  while (count < N) {
    double a = stan::prob::student_t_rng(3.0,2.0,1.0,rng) / 1.0 - 2.0;
    int i = 0;
    while (i < K-1 && a > loc[i])
	++i;
    ++bin[i];
    count++;
   }

  double chi = 0;
  double expect [5] = {N / K, N / K, N / K, N / K, N / K};

  for(int j = 0; j < K; j++)
    chi += ((bin[j] - expect[j]) * (bin[j] - expect[j]) / expect[j]);

  EXPECT_TRUE(chi < quantile(complement(mydist, 1e-6)));
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <set>
#include <string>

#include "chrome/browser/download/download_util.h"

#include "base/logging.h"
#include "base/string_util.h"

namespace download_util {

// For file extensions taken from mozilla:

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Mozilla Communicator client code, released
 * March 31, 1998.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998-1999
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Doug Turner <dougt@netscape.com>
 *   Dean Tessman <dean_tessman@hotmail.com>
 *   Brodie Thiesfield <brofield@jellycan.com>
 *   Jungshik Shin <jshin@i18nl10n.com>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either of the GNU General Public License Version 2 or later (the "GPL"),
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

static const char* const g_executables[] = {
#if defined(OS_WIN)
  "ad",
  "ade",
  "adp",
  "app",
  "application",
  "asp",
  "asx",
  "bas",
  "bat",
  "chm",
  "cmd",
  "com",
  "cpl",
  "crt",
  "dll",
  "exe",
  "fxp",
  "hlp",
  "hta",
  "htm",
  "html",
  "htt",
  "inf",
  "ins",
  "isp",
  "jar",
  "js",
  "jse",
  "lnk",
  "mad",
  "maf",
  "mag",
  "mam",
  "maq",
  "mar",
  "mas",
  "mat",
  "mau",
  "mav",
  "maw",
  "mda",
  "mdb",
  "mde",
  "mdt",
  "mdw",
  "mdz",
  "mht",
  "mhtml",
  "msc",
  "msh",
  "mshxml",
  "msi",
  "msp",
  "mst",
  "ops",
  "pcd",
  "pif",
  "plg",
  "prf",
  "prg",
  "pst",
  "reg",
  "scf",
  "scr",
  "sct",
  "shb",
  "shs",
  "shtm",
  "shtml",
  "svg",
  "url",
  "vb",
  "vbe",
  "vbs",
  "vsd",
  "vsmacros",
  "vss",
  "vst",
  "vsw",
  "ws",
  "wsc",
  "wsf",
  "wsh",
  "xht",
  "xhtm",
  "xhtml",
  "xml",
  "xsl",
  "xslt",
#elif defined(OS_MACOSX)
  // TODO(thakis): Figure out what makes sense here -- crbug.com/19096
  "dmg",
#elif defined(OS_POSIX)
  // TODO(estade): lengthen this list.
  "exe",
  "pl",
  "py",
  "rb",
  "sh",
#endif
};

bool IsExecutableExtension(const std::string& extension) {
  for (size_t i = 0; i < arraysize(g_executables); ++i) {
    if (LowerCaseEqualsASCII(extension, g_executables[i]))
      return true;
  }
  return false;
}

}  // namespace download_util
<commit_msg>Add "deb" and "rpm" to dangerous extension list on linux.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <set>
#include <string>

#include "chrome/browser/download/download_util.h"

#include "base/logging.h"
#include "base/string_util.h"

namespace download_util {

// For file extensions taken from mozilla:

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Mozilla Communicator client code, released
 * March 31, 1998.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998-1999
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Doug Turner <dougt@netscape.com>
 *   Dean Tessman <dean_tessman@hotmail.com>
 *   Brodie Thiesfield <brofield@jellycan.com>
 *   Jungshik Shin <jshin@i18nl10n.com>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either of the GNU General Public License Version 2 or later (the "GPL"),
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

static const char* const g_executables[] = {
#if defined(OS_WIN)
  "ad",
  "ade",
  "adp",
  "app",
  "application",
  "asp",
  "asx",
  "bas",
  "bat",
  "chm",
  "cmd",
  "com",
  "cpl",
  "crt",
  "dll",
  "exe",
  "fxp",
  "hlp",
  "hta",
  "htm",
  "html",
  "htt",
  "inf",
  "ins",
  "isp",
  "jar",
  "js",
  "jse",
  "lnk",
  "mad",
  "maf",
  "mag",
  "mam",
  "maq",
  "mar",
  "mas",
  "mat",
  "mau",
  "mav",
  "maw",
  "mda",
  "mdb",
  "mde",
  "mdt",
  "mdw",
  "mdz",
  "mht",
  "mhtml",
  "msc",
  "msh",
  "mshxml",
  "msi",
  "msp",
  "mst",
  "ops",
  "pcd",
  "pif",
  "plg",
  "prf",
  "prg",
  "pst",
  "reg",
  "scf",
  "scr",
  "sct",
  "shb",
  "shs",
  "shtm",
  "shtml",
  "svg",
  "url",
  "vb",
  "vbe",
  "vbs",
  "vsd",
  "vsmacros",
  "vss",
  "vst",
  "vsw",
  "ws",
  "wsc",
  "wsf",
  "wsh",
  "xht",
  "xhtm",
  "xhtml",
  "xml",
  "xsl",
  "xslt",
#elif defined(OS_MACOSX)
  // TODO(thakis): Figure out what makes sense here -- crbug.com/19096
  "dmg",
#elif defined(OS_POSIX)
  // TODO(estade): lengthen this list.
  "exe",
  "pl",
  "py",
  "rb",
  "sh",
  "deb",
  "rpm",
#endif
};

bool IsExecutableExtension(const std::string& extension) {
  for (size_t i = 0; i < arraysize(g_executables); ++i) {
    if (LowerCaseEqualsASCII(extension, g_executables[i]))
      return true;
  }
  return false;
}

}  // namespace download_util
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "temp_scaffolding_stubs.h"

#include "build/build_config.h"

#include <vector>

#include "base/logging.h"
#include "chrome/browser/automation/automation_provider.h"
#include "chrome/browser/download/download_request_dialog_delegate.h"
#include "chrome/browser/download/download_request_manager.h"
#include "chrome/browser/first_run.h"
#include "chrome/browser/hung_renderer_dialog.h"
#include "chrome/browser/memory_details.h"
#include "chrome/browser/options_window.h"
#include "chrome/browser/rlz/rlz.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/common/process_watcher.h"

#if defined(OS_MACOSX)
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_shelf.h"
#endif

class TabContents;

//--------------------------------------------------------------------------

void AutomationProvider::GetActiveWindow(int* handle) { NOTIMPLEMENTED(); }

void AutomationProvider::ActivateWindow(int handle) { NOTIMPLEMENTED(); }

void AutomationProvider::SetWindowVisible(int handle, bool visible,
                                          bool* result) { NOTIMPLEMENTED(); }

void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
void AutomationProvider::GetAutocompleteEditForBrowser(
    int browser_handle,
    bool* success,
    int* autocomplete_edit_handle) {
  *success = false;
  NOTIMPLEMENTED();
}
#endif

void AutomationProvider::GetBrowserForWindow(int window_handle,
                                             bool* success,
                                             int* browser_handle) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetSecurityState(int handle, bool* success,
                                          SecurityStyle* security_style,
                                          int* ssl_cert_status,
                                          int* mixed_content_status) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetPageType(int handle, bool* success,
                                     NavigationEntry::PageType* page_type) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
                                                 IPC::Message* reply_message) {
  NOTIMPLEMENTED();
}

void AutomationProvider::PrintNow(int tab_handle,
                                  IPC::Message* reply_message) {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
                                                 bool* success,
                                                 std::wstring* text) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
                                                 const std::wstring& text,
                                                 bool* success) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::AutocompleteEditGetMatches(
    int autocomplete_edit_handle,
    bool* success,
    std::vector<AutocompleteMatchData>* matches) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::AutocompleteEditIsQueryInProgress(
    int autocomplete_edit_handle,
    bool* success,
    bool* query_in_progress) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::OnMessageFromExternalHost(
    int handle, const std::string& message, const std::string& origin,
    const std::string& target) {
  NOTIMPLEMENTED();
}
#endif  // defined(OS_MACOSX)

//--------------------------------------------------------------------------

#if defined(OS_LINUX)
bool ShellIntegration::SetAsDefaultBrowser() {
  NOTIMPLEMENTED();
  return true;
}

bool ShellIntegration::IsDefaultBrowser() {
  NOTIMPLEMENTED();
  return true;
}
#endif

//--------------------------------------------------------------------------

// static
bool FirstRun::IsChromeFirstRun() {
  // http://code.google.com/p/chromium/issues/detail?id=11971
  return false;
}

// static
bool FirstRun::ProcessMasterPreferences(const FilePath& user_data_dir,
                                        const FilePath& master_prefs_path,
                                        int* preference_details,
                                        std::vector<std::wstring>* new_tabs) {
  // http://code.google.com/p/chromium/issues/detail?id=11971
  return false;
}

// static
int FirstRun::ImportNow(Profile* profile, const CommandLine& cmdline) {
  // http://code.google.com/p/chromium/issues/detail?id=11971
  return 0;
}

// static
bool Upgrade::IsBrowserAlreadyRunning() {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return false;
}

// static
bool Upgrade::RelaunchChromeBrowser(const CommandLine& command_line) {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return true;
}

// static
bool Upgrade::SwapNewChromeExeIfPresent() {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return true;
}

void OpenFirstRunDialog(Profile* profile, ProcessSingleton* process_singleton) {
  NOTIMPLEMENTED();
}

//--------------------------------------------------------------------------

void InstallJankometer(const CommandLine&) {
  // http://code.google.com/p/chromium/issues/detail?id=8077
}

void UninstallJankometer() {
  // http://code.google.com/p/chromium/issues/detail?id=8077
}

//--------------------------------------------------------------------------

void RLZTracker::CleanupRlz() {
  // http://code.google.com/p/chromium/issues/detail?id=8152
}

bool RLZTracker::GetAccessPointRlz(AccessPoint point, std::wstring* rlz) {
  // http://code.google.com/p/chromium/issues/detail?id=8152
  return false;
}

bool RLZTracker::RecordProductEvent(Product product, AccessPoint point,
                                    Event event) {
  // http://code.google.com/p/chromium/issues/detail?id=8152
  return false;
}

//--------------------------------------------------------------------------

#if defined(OS_MACOSX)

class DownloadShelfMac : public DownloadShelf {
 public:
  explicit DownloadShelfMac(TabContents* tab_contents)
      : DownloadShelf(tab_contents) { }
  virtual void AddDownload(BaseDownloadItemModel* download_model) { }
  virtual bool IsShowing() const { return false; }
};

// static
DownloadShelf* DownloadShelf::Create(TabContents* tab_contents) {
  return new DownloadShelfMac(tab_contents);
}

#endif

//--------------------------------------------------------------------------

void RunRepostFormWarningDialog(NavigationController*) {
}

LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info,
                                URLRequest* request,
                                MessageLoop* ui_loop) {
  NOTIMPLEMENTED();
  return NULL;
}

//--------------------------------------------------------------------------

MemoryDetails::MemoryDetails() {
  NOTIMPLEMENTED();
}

void MemoryDetails::StartFetch() {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

InfoBar* AlertInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

InfoBar* LinkInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}
#endif

DownloadRequestDialogDelegate* DownloadRequestDialogDelegate::Create(
    TabContents* tab,
    DownloadRequestManager::TabDownloadState* host) {
  NOTIMPLEMENTED();
  return NULL;
}

namespace download_util {

void DragDownload(const DownloadItem* download, SkBitmap* icon) {
  NOTIMPLEMENTED();
}

}  // namespace download_util

#if defined(OS_LINUX)
void WindowSizer::GetBrowserWindowBounds(const std::wstring& app_name,
                                         const gfx::Rect& specified_bounds,
                                         Browser* browser,
                                         gfx::Rect* window_bounds,
                                         bool* maximized) {
  // If we're given a bounds, use it (for things like tearing off tabs during
  // drags). If not, make up something reasonable until the rest of the
  // WindowSizer infrastructure is in place.
  *window_bounds = specified_bounds;
  if (specified_bounds.IsEmpty()) {
    *window_bounds = gfx::Rect(0, 0, 1024, 768);
  }
}
#endif

#if defined(OS_MACOSX)
void HungRendererDialog::HideForTabContents(TabContents*) {
  NOTIMPLEMENTED();
}

void HungRendererDialog::ShowForTabContents(TabContents*) {
  NOTIMPLEMENTED();
}
#endif

void BrowserList::AllBrowsersClosed() {
  // TODO(port): Close any dependent windows if necessary when the last browser
  //             window is closed.
}

//--------------------------------------------------------------------------

#if defined(OS_MACOSX)
void ShowOptionsWindow(OptionsPage page,
                       OptionsGroup highlight_group,
                       Profile* profile) {
  NOTIMPLEMENTED();
}
#endif
<commit_msg>scaffolding: SetAsDefaultBrowser NOTIMPLEMENTED made into a bug.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "temp_scaffolding_stubs.h"

#include "build/build_config.h"

#include <vector>

#include "base/logging.h"
#include "chrome/browser/automation/automation_provider.h"
#include "chrome/browser/download/download_request_dialog_delegate.h"
#include "chrome/browser/download/download_request_manager.h"
#include "chrome/browser/first_run.h"
#include "chrome/browser/hung_renderer_dialog.h"
#include "chrome/browser/memory_details.h"
#include "chrome/browser/options_window.h"
#include "chrome/browser/rlz/rlz.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/common/process_watcher.h"

#if defined(OS_MACOSX)
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_shelf.h"
#endif

class TabContents;

//--------------------------------------------------------------------------

void AutomationProvider::GetActiveWindow(int* handle) { NOTIMPLEMENTED(); }

void AutomationProvider::ActivateWindow(int handle) { NOTIMPLEMENTED(); }

void AutomationProvider::SetWindowVisible(int handle, bool visible,
                                          bool* result) { NOTIMPLEMENTED(); }

void AutomationProvider::GetFocusedViewID(int handle, int* view_id) {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
void AutomationProvider::GetAutocompleteEditForBrowser(
    int browser_handle,
    bool* success,
    int* autocomplete_edit_handle) {
  *success = false;
  NOTIMPLEMENTED();
}
#endif

void AutomationProvider::GetBrowserForWindow(int window_handle,
                                             bool* success,
                                             int* browser_handle) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetSecurityState(int handle, bool* success,
                                          SecurityStyle* security_style,
                                          int* ssl_cert_status,
                                          int* mixed_content_status) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::GetPageType(int handle, bool* success,
                                     NavigationEntry::PageType* page_type) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::ActionOnSSLBlockingPage(int handle, bool proceed,
                                                 IPC::Message* reply_message) {
  NOTIMPLEMENTED();
}

void AutomationProvider::PrintNow(int tab_handle,
                                  IPC::Message* reply_message) {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
void AutomationProvider::GetAutocompleteEditText(int autocomplete_edit_handle,
                                                 bool* success,
                                                 std::wstring* text) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::SetAutocompleteEditText(int autocomplete_edit_handle,
                                                 const std::wstring& text,
                                                 bool* success) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::AutocompleteEditGetMatches(
    int autocomplete_edit_handle,
    bool* success,
    std::vector<AutocompleteMatchData>* matches) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::AutocompleteEditIsQueryInProgress(
    int autocomplete_edit_handle,
    bool* success,
    bool* query_in_progress) {
  *success = false;
  NOTIMPLEMENTED();
}

void AutomationProvider::OnMessageFromExternalHost(
    int handle, const std::string& message, const std::string& origin,
    const std::string& target) {
  NOTIMPLEMENTED();
}
#endif  // defined(OS_MACOSX)

//--------------------------------------------------------------------------

#if defined(OS_LINUX)
bool ShellIntegration::SetAsDefaultBrowser() {
  // http://code.google.com/p/chromium/issues/detail?id=11972
  return true;
}

bool ShellIntegration::IsDefaultBrowser() {
  // http://code.google.com/p/chromium/issues/detail?id=11972
  return true;
}
#endif

//--------------------------------------------------------------------------

// static
bool FirstRun::IsChromeFirstRun() {
  // http://code.google.com/p/chromium/issues/detail?id=11971
  return false;
}

// static
bool FirstRun::ProcessMasterPreferences(const FilePath& user_data_dir,
                                        const FilePath& master_prefs_path,
                                        int* preference_details,
                                        std::vector<std::wstring>* new_tabs) {
  // http://code.google.com/p/chromium/issues/detail?id=11971
  return false;
}

// static
int FirstRun::ImportNow(Profile* profile, const CommandLine& cmdline) {
  // http://code.google.com/p/chromium/issues/detail?id=11971
  return 0;
}

// static
bool Upgrade::IsBrowserAlreadyRunning() {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return false;
}

// static
bool Upgrade::RelaunchChromeBrowser(const CommandLine& command_line) {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return true;
}

// static
bool Upgrade::SwapNewChromeExeIfPresent() {
  // http://code.google.com/p/chromium/issues/detail?id=9295
  return true;
}

void OpenFirstRunDialog(Profile* profile, ProcessSingleton* process_singleton) {
  NOTIMPLEMENTED();
}

//--------------------------------------------------------------------------

void InstallJankometer(const CommandLine&) {
  // http://code.google.com/p/chromium/issues/detail?id=8077
}

void UninstallJankometer() {
  // http://code.google.com/p/chromium/issues/detail?id=8077
}

//--------------------------------------------------------------------------

void RLZTracker::CleanupRlz() {
  // http://code.google.com/p/chromium/issues/detail?id=8152
}

bool RLZTracker::GetAccessPointRlz(AccessPoint point, std::wstring* rlz) {
  // http://code.google.com/p/chromium/issues/detail?id=8152
  return false;
}

bool RLZTracker::RecordProductEvent(Product product, AccessPoint point,
                                    Event event) {
  // http://code.google.com/p/chromium/issues/detail?id=8152
  return false;
}

//--------------------------------------------------------------------------

#if defined(OS_MACOSX)

class DownloadShelfMac : public DownloadShelf {
 public:
  explicit DownloadShelfMac(TabContents* tab_contents)
      : DownloadShelf(tab_contents) { }
  virtual void AddDownload(BaseDownloadItemModel* download_model) { }
  virtual bool IsShowing() const { return false; }
};

// static
DownloadShelf* DownloadShelf::Create(TabContents* tab_contents) {
  return new DownloadShelfMac(tab_contents);
}

#endif

//--------------------------------------------------------------------------

void RunRepostFormWarningDialog(NavigationController*) {
}

LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info,
                                URLRequest* request,
                                MessageLoop* ui_loop) {
  NOTIMPLEMENTED();
  return NULL;
}

//--------------------------------------------------------------------------

MemoryDetails::MemoryDetails() {
  NOTIMPLEMENTED();
}

void MemoryDetails::StartFetch() {
  NOTIMPLEMENTED();
}

#if defined(OS_MACOSX)
InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

InfoBar* AlertInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}

InfoBar* LinkInfoBarDelegate::CreateInfoBar() {
  NOTIMPLEMENTED();
  return NULL;
}
#endif

DownloadRequestDialogDelegate* DownloadRequestDialogDelegate::Create(
    TabContents* tab,
    DownloadRequestManager::TabDownloadState* host) {
  NOTIMPLEMENTED();
  return NULL;
}

namespace download_util {

void DragDownload(const DownloadItem* download, SkBitmap* icon) {
  NOTIMPLEMENTED();
}

}  // namespace download_util

#if defined(OS_LINUX)
void WindowSizer::GetBrowserWindowBounds(const std::wstring& app_name,
                                         const gfx::Rect& specified_bounds,
                                         Browser* browser,
                                         gfx::Rect* window_bounds,
                                         bool* maximized) {
  // If we're given a bounds, use it (for things like tearing off tabs during
  // drags). If not, make up something reasonable until the rest of the
  // WindowSizer infrastructure is in place.
  *window_bounds = specified_bounds;
  if (specified_bounds.IsEmpty()) {
    *window_bounds = gfx::Rect(0, 0, 1024, 768);
  }
}
#endif

#if defined(OS_MACOSX)
void HungRendererDialog::HideForTabContents(TabContents*) {
  NOTIMPLEMENTED();
}

void HungRendererDialog::ShowForTabContents(TabContents*) {
  NOTIMPLEMENTED();
}
#endif

void BrowserList::AllBrowsersClosed() {
  // TODO(port): Close any dependent windows if necessary when the last browser
  //             window is closed.
}

//--------------------------------------------------------------------------

#if defined(OS_MACOSX)
void ShowOptionsWindow(OptionsPage page,
                       OptionsGroup highlight_group,
                       Profile* profile) {
  NOTIMPLEMENTED();
}
#endif
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/common/nacl_fork_delegate_linux.h"

#include <signal.h>
#include <stdlib.h>
#include <sys/socket.h>

#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/eintr_wrapper.h"
#include "base/logging.h"
#include "base/file_path.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "content/common/unix_domain_socket_posix.h"
#include "content/common/zygote_fork_delegate_linux.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/nacl_helper_linux.h"

NaClForkDelegate::NaClForkDelegate()
    : ready_(false),
      sandboxed_(false),
      fd_(-1) {}

const char kNaClHelperAtZero[] = "--at-zero";

void NaClForkDelegate::Init(const bool sandboxed,
                            const int browserdesc,
                            const int sandboxdesc) {
  VLOG(1) << "NaClForkDelegate::Init()";
  int fds[2];

  sandboxed_ = sandboxed;
  // Confirm a couple hard-wired assumptions.
  // The NaCl constants are from chrome/nacl/nacl_linux_helper.h
  DCHECK(kNaClBrowserDescriptor == browserdesc);
  DCHECK(kNaClSandboxDescriptor == sandboxdesc);

  CHECK(socketpair(PF_UNIX, SOCK_SEQPACKET, 0, fds) == 0);
  base::file_handle_mapping_vector fds_to_map;
  fds_to_map.push_back(std::make_pair(fds[1], kNaClZygoteDescriptor));
  fds_to_map.push_back(std::make_pair(sandboxdesc, kNaClSandboxDescriptor));
  ready_ = false;
  FilePath helper_exe;
  FilePath helper_bootstrap_exe;
  if (PathService::Get(chrome::FILE_NACL_HELPER, &helper_exe) &&
      PathService::Get(chrome::FILE_NACL_HELPER_BOOTSTRAP,
                       &helper_bootstrap_exe)) {
    CommandLine::StringVector argv = CommandLine::ForCurrentProcess()->argv();
    argv[0] = helper_bootstrap_exe.value();
    argv[1] = helper_exe.value();
    argv[2] = kNaClHelperAtZero;
    base::LaunchOptions options;
    options.fds_to_remap = &fds_to_map;
    options.clone_flags = CLONE_FS | SIGCHLD;
    ready_ = base::LaunchProcess(argv, options, NULL);
    // parent and error cases are handled below
  }
  if (HANDLE_EINTR(close(fds[1])) != 0)
    LOG(ERROR) << "close(fds[1]) failed";
  if (ready_) {
    const ssize_t kExpectedLength = strlen(kNaClHelperStartupAck);
    char buf[kExpectedLength];

    // Wait for ack from nacl_helper, indicating it is ready to help
    const ssize_t nread = HANDLE_EINTR(read(fds[0], buf, sizeof(buf)));
    if (nread == kExpectedLength &&
        memcmp(buf, kNaClHelperStartupAck, nread) == 0) {
      // all is well
      fd_ = fds[0];
      return;
    }
    LOG(ERROR) << "Bad NaCl helper startup ack (" << nread << " bytes)";
  }
  // TODO(bradchen): Make this LOG(ERROR) when the NaCl helper
  // becomes the default.
  ready_ = false;
  fd_ = -1;
  if (HANDLE_EINTR(close(fds[0])) != 0)
    LOG(ERROR) << "close(fds[0]) failed";
}

NaClForkDelegate::~NaClForkDelegate() {
  // side effect of close: delegate process will terminate
  if (ready_) {
    if (HANDLE_EINTR(close(fd_)) != 0)
      LOG(ERROR) << "close(fd_) failed";
  }
}

bool NaClForkDelegate::CanHelp(const std::string& process_type) {
  return (process_type == switches::kNaClLoaderProcess && ready_);
}

pid_t NaClForkDelegate::Fork(const std::vector<int>& fds) {
  base::ProcessId naclchild;
  VLOG(1) << "NaClForkDelegate::Fork";

  DCHECK(fds.size() == kNaClParentFDIndex + 1);
  if (!UnixDomainSocket::SendMsg(fd_, kNaClForkRequest,
                                 strlen(kNaClForkRequest), fds)) {
    LOG(ERROR) << "NaClForkDelegate::Fork: SendMsg failed";
    return -1;
  }
  int nread = HANDLE_EINTR(read(fd_, &naclchild, sizeof(naclchild)));
  if (nread != sizeof(naclchild)) {
    LOG(ERROR) << "NaClForkDelegate::Fork: read failed";
    return -1;
  }
  VLOG(1) << "nacl_child is " << naclchild << " (" << nread << " bytes)";
  return naclchild;
}

bool NaClForkDelegate::AckChild(const int fd,
                                const std::string& channel_switch) {
  int nwritten = HANDLE_EINTR(write(fd, channel_switch.c_str(),
                                    channel_switch.length()));
  if (nwritten != static_cast<int>(channel_switch.length())) {
    return false;
  }
  return true;
}
<commit_msg>Don't use NaCl helper when run under Valgrind TBR=bradchen,eugenis TEST=Valgrind bots go greener BUG=95171 Review URL: http://codereview.chromium.org/7792096<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/common/nacl_fork_delegate_linux.h"

#include <signal.h>
#include <stdlib.h>
#include <sys/socket.h>

#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/eintr_wrapper.h"
#include "base/logging.h"
#include "base/file_path.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "content/common/unix_domain_socket_posix.h"
#include "content/common/zygote_fork_delegate_linux.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/nacl_helper_linux.h"

NaClForkDelegate::NaClForkDelegate()
    : ready_(false),
      sandboxed_(false),
      fd_(-1) {}

const char kNaClHelperAtZero[] = "--at-zero";

void NaClForkDelegate::Init(const bool sandboxed,
                            const int browserdesc,
                            const int sandboxdesc) {
  VLOG(1) << "NaClForkDelegate::Init()";
  int fds[2];

  sandboxed_ = sandboxed;
  // Confirm a couple hard-wired assumptions.
  // The NaCl constants are from chrome/nacl/nacl_linux_helper.h
  DCHECK(kNaClBrowserDescriptor == browserdesc);
  DCHECK(kNaClSandboxDescriptor == sandboxdesc);

  CHECK(socketpair(PF_UNIX, SOCK_SEQPACKET, 0, fds) == 0);
  base::file_handle_mapping_vector fds_to_map;
  fds_to_map.push_back(std::make_pair(fds[1], kNaClZygoteDescriptor));
  fds_to_map.push_back(std::make_pair(sandboxdesc, kNaClSandboxDescriptor));
  ready_ = false;
  FilePath helper_exe;
  FilePath helper_bootstrap_exe;
  if (PathService::Get(chrome::FILE_NACL_HELPER, &helper_exe) &&
      PathService::Get(chrome::FILE_NACL_HELPER_BOOTSTRAP,
                       &helper_bootstrap_exe) &&
      !RunningOnValgrind()) {
    CommandLine::StringVector argv = CommandLine::ForCurrentProcess()->argv();
    argv[0] = helper_bootstrap_exe.value();
    argv[1] = helper_exe.value();
    argv[2] = kNaClHelperAtZero;
    base::LaunchOptions options;
    options.fds_to_remap = &fds_to_map;
    options.clone_flags = CLONE_FS | SIGCHLD;
    ready_ = base::LaunchProcess(argv, options, NULL);
    // parent and error cases are handled below
  }
  if (HANDLE_EINTR(close(fds[1])) != 0)
    LOG(ERROR) << "close(fds[1]) failed";
  if (ready_) {
    const ssize_t kExpectedLength = strlen(kNaClHelperStartupAck);
    char buf[kExpectedLength];

    // Wait for ack from nacl_helper, indicating it is ready to help
    const ssize_t nread = HANDLE_EINTR(read(fds[0], buf, sizeof(buf)));
    if (nread == kExpectedLength &&
        memcmp(buf, kNaClHelperStartupAck, nread) == 0) {
      // all is well
      fd_ = fds[0];
      return;
    }
    LOG(ERROR) << "Bad NaCl helper startup ack (" << nread << " bytes)";
  }
  // TODO(bradchen): Make this LOG(ERROR) when the NaCl helper
  // becomes the default.
  ready_ = false;
  fd_ = -1;
  if (HANDLE_EINTR(close(fds[0])) != 0)
    LOG(ERROR) << "close(fds[0]) failed";
}

NaClForkDelegate::~NaClForkDelegate() {
  // side effect of close: delegate process will terminate
  if (ready_) {
    if (HANDLE_EINTR(close(fd_)) != 0)
      LOG(ERROR) << "close(fd_) failed";
  }
}

bool NaClForkDelegate::CanHelp(const std::string& process_type) {
  return (process_type == switches::kNaClLoaderProcess && ready_);
}

pid_t NaClForkDelegate::Fork(const std::vector<int>& fds) {
  base::ProcessId naclchild;
  VLOG(1) << "NaClForkDelegate::Fork";

  DCHECK(fds.size() == kNaClParentFDIndex + 1);
  if (!UnixDomainSocket::SendMsg(fd_, kNaClForkRequest,
                                 strlen(kNaClForkRequest), fds)) {
    LOG(ERROR) << "NaClForkDelegate::Fork: SendMsg failed";
    return -1;
  }
  int nread = HANDLE_EINTR(read(fd_, &naclchild, sizeof(naclchild)));
  if (nread != sizeof(naclchild)) {
    LOG(ERROR) << "NaClForkDelegate::Fork: read failed";
    return -1;
  }
  VLOG(1) << "nacl_child is " << naclchild << " (" << nread << " bytes)";
  return naclchild;
}

bool NaClForkDelegate::AckChild(const int fd,
                                const std::string& channel_switch) {
  int nwritten = HANDLE_EINTR(write(fd, channel_switch.c_str(),
                                    channel_switch.length()));
  if (nwritten != static_cast<int>(channel_switch.length())) {
    return false;
  }
  return true;
}
<|endoftext|>


<commit_before>/**
 * @file stereoRectify.cpp
 * @brief mex interface for stereoRectify
 * @author Kota Yamaguchi
 * @date 2011
 */
#include "mexopencv.hpp"
using namespace std;
using namespace cv;

/// Field names for struct
const char* _fieldnames[] = {"R1", "R2", "P1", "P2", "Q", "roi1", "roi2"};
/// Create a struct
mxArray* valueStruct(const Mat& R1, const Mat& R2, const Mat& P1, const Mat& P2,
    const Mat& Q, const Rect& roi1, const Rect& roi2)
{
    MxArray s = MxArray::Struct(_fieldnames,7);
    s.set("R1",R1);
    s.set("R2",R2);
    s.set("P1",P1);
    s.set("P2",P2);
    s.set("Q",Q);
    s.set("roi1",roi1);
    s.set("roi2",roi2);
    return s;
}

/**
 * Main entry called from Matlab
 * @param nlhs number of left-hand-side arguments
 * @param plhs pointers to mxArrays in the left-hand-side
 * @param nrhs number of right-hand-side arguments
 * @param prhs pointers to mxArrays in the right-hand-side
 */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
    // Check the number of arguments
    if (nrhs<7 || ((nrhs%2)!=1) || nlhs>1)
        mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");

    // Argument vector
    vector<MxArray> rhs(prhs,prhs+nrhs);

    Mat cameraMatrix1(rhs[0].toMat()), distCoeffs1(rhs[2].toMat());
    Mat cameraMatrix2(rhs[1].toMat()), distCoeffs2(rhs[3].toMat());
    Size imageSize(rhs[4].toSize());
    Mat R(rhs[5].toMat()), T(rhs[6].toMat());
    double alpha=-1;
    Size newImageSize(0,0);
    bool zeroDisparity=false;
    // Option processing
    for (int i=7; i<nrhs; i+=2) {
        string key = rhs[i].toString();
        if (key=="Alpha")
            alpha = rhs[i+1].toDouble();
        else if (key=="NewImageSize")
            newImageSize = rhs[i+1].toSize();
        else if (key=="ZeroDisparity")
            zeroDisparity = rhs[i+1].toBool();
        else
            mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
    }
    int flags = ((zeroDisparity) ? CV_CALIB_ZERO_DISPARITY : 0);

    // Process
    Mat R1, R2, P1, P2, Q;
    Rect roi1, roi2;
#if CV_MINOR_VERSION >= 2
    stereoRectify(cameraMatrix1, cameraMatrix2, distCoeffs1, distCoeffs2,
        imageSize, R, T, R1, R2, P1, P2, Q, flags, alpha, newImageSize,
        &roi1, &roi2);
#else
    stereoRectify(cameraMatrix1, cameraMatrix2, distCoeffs1, distCoeffs2,
        imageSize, R, T, R1, R2, P1, P2, Q, flags);
#endif
    plhs[0] = valueStruct(R1, R2, P1, P2, Q, roi1, roi2);
}
<commit_msg>Fixed stereoRectify argument error<commit_after>/**
 * @file stereoRectify.cpp
 * @brief mex interface for stereoRectify
 * @author Kota Yamaguchi
 * @date 2011
 */
#include "mexopencv.hpp"
using namespace std;
using namespace cv;

/// Field names for struct
const char* _fieldnames[] = {"R1", "R2", "P1", "P2", "Q", "roi1", "roi2"};
/// Create a struct
mxArray* valueStruct(const Mat& R1, const Mat& R2, const Mat& P1, const Mat& P2,
    const Mat& Q, const Rect& roi1, const Rect& roi2)
{
    MxArray s = MxArray::Struct(_fieldnames,7);
    s.set("R1",R1);
    s.set("R2",R2);
    s.set("P1",P1);
    s.set("P2",P2);
    s.set("Q",Q);
    s.set("roi1",roi1);
    s.set("roi2",roi2);
    return s;
}

/**
 * Main entry called from Matlab
 * @param nlhs number of left-hand-side arguments
 * @param plhs pointers to mxArrays in the left-hand-side
 * @param nrhs number of right-hand-side arguments
 * @param prhs pointers to mxArrays in the right-hand-side
 */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
    // Check the number of arguments
    if (nrhs<7 || ((nrhs%2)!=1) || nlhs>1)
        mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");

    // Argument vector
    vector<MxArray> rhs(prhs,prhs+nrhs);

    Mat cameraMatrix1(rhs[0].toMat()), distCoeffs1(rhs[2].toMat());
    Mat cameraMatrix2(rhs[1].toMat()), distCoeffs2(rhs[3].toMat());
    Size imageSize(rhs[4].toSize());
    Mat R(rhs[5].toMat()), T(rhs[6].toMat());
    double alpha=-1;
    Size newImageSize(0,0);
    bool zeroDisparity=false;
    // Option processing
    for (int i=7; i<nrhs; i+=2) {
        string key = rhs[i].toString();
        if (key=="Alpha")
            alpha = rhs[i+1].toDouble();
        else if (key=="NewImageSize")
            newImageSize = rhs[i+1].toSize();
        else if (key=="ZeroDisparity")
            zeroDisparity = rhs[i+1].toBool();
        else
            mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
    }
    int flags = ((zeroDisparity) ? CV_CALIB_ZERO_DISPARITY : 0);

    // Process
    Mat R1, R2, P1, P2, Q;
    Rect roi1, roi2;
#if CV_MINOR_VERSION >= 2
    stereoRectify(cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2,
        imageSize, R, T, R1, R2, P1, P2, Q, flags, alpha, newImageSize,
        &roi1, &roi2);
#else
    stereoRectify(cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2,
        imageSize, R, T, R1, R2, P1, P2, Q, flags);
#endif
    plhs[0] = valueStruct(R1, R2, P1, P2, Q, roi1, roi2);
}
<|endoftext|>