8000 Templatize the examples. by pratikvn · Pull Request #513 · ginkgo-project/ginkgo · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Templatize the examples. #513

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Apr 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,12 @@ int main(int argc, char *argv[])
auto A = share(gko::read<mtx>(std::ifstream("data/A.mtx"), exec));
// Create RHS and initial guess as 1
gko::size_type size = A->get_size()[0];
auto host_x = gko::matrix::Dense<ValueType>::create(exec->get_master(),
gko::dim<2>(size, 1));
auto host_x = vec::create(exec->get_master(), gko::dim<2>(size, 1));
for (auto i = 0; i < size; i++) {
host_x->at(i, 0) = 1.;
}
auto x = gko::matrix::Dense<>::create(exec);
auto b = gko::matrix::Dense<>::create(exec);
auto x = vec::create(exec);
auto b = vec::create(exec);
x->copy_from(host_x.get());
b->copy_from(host_x.get());

Expand All @@ -93,11 +92,11 @@ int main(int argc, char *argv[])

// copy b again
b->copy_from(host_x.get());

const gko::remove_complex<ValueType> reduction_factor = 1e-7;
auto iter_stop =
gko::stop::Iteration::build().with_max_iters(10000u).on(exec);
auto tol_stop = gko::stop::ResidualNormReduction<ValueType>::build()
.with_reduction_factor(static_cast<ValueType>(1e-12))
.with_reduction_factor(reduction_factor)
.on(exec);

std::shared_ptr<const gko::log::Convergence<ValueType>> logger =
Expand Down
29 changes: 17 additions & 12 deletions examples/custom-logger/custom-logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Utility function which gets the scalar value of a Ginkgo gko::matrix::Dense
// matrix representing the norm of a vector.
template <typename ValueType>
double get_norm(const gko::matrix::Dense<ValueType> *norm)
gko::remove_complex<ValueType> get_norm(
const gko::matrix::Dense<ValueType> *norm)
{
// Put the value on CPU thanks to the master executor
auto cpu_norm = clone(norm->get_executor()->get_master(), norm);
// Return the scalar value contained at position (0, 0)
return cpu_norm->at(0, 0);
return std::real(cpu_norm->at(0, 0));
}

// Utility function which computes the norm of a Ginkgo gko::matrix::Dense
// vector.
template <typename ValueType>
double compute_norm(const gko::matrix::Dense<ValueType> *b)
gko::remove_complex<ValueType> compute_norm(
const gko::matrix::Dense<ValueType> *b)
{
// Get the executor of the vector
auto exec = b->get_executor();
Expand All @@ -83,10 +85,10 @@ struct ResidualLogger : gko::log::Logger {
void write() const
{
// Print a header for the table
std::cout << "Recurrent vs real residual norm:" << std::endl;
std::cout << "Recurrent vs true residual norm:" << std::endl;
std::cout << '|' << std::setw(10) << "Iteration" << '|' << std::setw(25)
<< "Recurrent Residual Norm" << '|' << std::setw(25)
<< "Real Residual Norm" << '|' << std::endl;
<< "True Residual Norm" << '|' << std::endl;
// Print a separation line. Note that for creating `10` characters
// `std::setw()` should be set to `11`.
std::cout << '|' << std::setfill('-') << std::setw(11) << '|'
Expand Down Expand Up @@ -188,14 +190,16 @@ int main(int argc, char *argv[])
// with one column/one row. The advantage of this concept is that using
// multiple vectors is a now a natural extension of adding columns/rows are
// necessary.
using vec = gko::matrix::Dense<>;
using ValueType = double;
using IndexType = int;
using vec = gko::matrix::Dense<ValueType>;
// The gko::matrix::Csr class is used here, but any other matrix class such
// as gko::matrix::Coo, gko::matrix::Hybrid, gko::matrix::Ell or
8000 // gko::matrix::Sellp could also be used.
using mtx = gko::matrix::Csr<>;
using mtx = gko::matrix::Csr<ValueType, IndexType>;
// The gko::solver::Cg is used here, but any other solver class can also be
// used.
using cg = gko::solver::Cg<>;
using cg = gko::solver::Cg<ValueType>;

// Print the ginkgo version information.
std::cout << gko::version_info::get() << std::endl;
Expand Down Expand Up @@ -237,6 +241,7 @@ int main(int argc, char *argv[])
auto A = share(gko::read<mtx>(std::ifstream("data/A.mtx"), exec));
auto b = gko::read<vec>(std::ifstream("data/b.mtx"), exec);
auto x = gko::read<vec>(std::ifstream("data/x0.mtx"), exec);
const gko::remove_complex<ValueType> reduction_factor = 1e-7;

// @sect3{Creating the solver}
// Generate the gko::solver factory. Ginkgo uses the concept of Factories to
Expand All @@ -251,14 +256,14 @@ int main(int argc, char *argv[])
cg::build()
.with_criteria(
gko::stop::Iteration::build().with_max_iters(20u).on(exec),
gko::stop::ResidualNormReduction<>::build()
.with_reduction_factor(1e-15)
gko::stop::ResidualNormReduction<ValueType>::build()
.with_reduction_factor(reduction_factor)
.on(exec))
.on(exec);

// Instantiate a ResidualLogger logger.
auto logger = std::make_shared<ResidualLogger<double>>(exec, gko::lend(A),
gko::lend(b));
auto logger = std::make_shared<ResidualLogger<ValueType>>(
exec, gko::lend(A), gko::lend(b));

// Add the previously created logger to the solver factory. The logger will
// be automatically propagated to all solvers created from this factory.
Expand Down
2 changes: 1 addition & 1 deletion examples/custom-matrix-format/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ if (GINKGO_BUILD_CUDA AND GINKGO_BUILD_OMP)
stencil_kernel.cu)
target_link_libraries(custom-matrix-format ginkgo)
target_include_directories(custom-matrix-format PRIVATE
${PROJECT_SOURCE_DIR})
${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
endif()
65 changes: 38 additions & 27 deletions examples/custom-matrix-format/custom-matrix-format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A CUDA kernel implementing the stencil, which will be used if running on the
// CUDA executor. Unfortunately, NVCC has serious problems interpreting some
// parts of Ginkgo's code, so the kernel has to be compiled separately.
extern void stencil_kernel(std::size_t size, const double *coefs,
const double *b, double *x);
template <typename ValueType>
void stencil_kernel(std::size_t size, const ValueType *coefs,
const ValueType *b, ValueType *x);


// A stencil matrix class representing the 3pt stencil linear operator.
Expand All @@ -57,21 +58,22 @@ extern void stencil_kernel(std::size_t size, const double *coefs,
// implementation of the static create method. This method will forward all its
// arguments to the constructor to create the object, and return an
// std::unique_ptr to the created object.
class StencilMatrix : public gko::EnableLinOp<StencilMatrix>,
public gko::EnableCreateMethod<StencilMatrix> {
template <typename ValueType>
class StencilMatrix : public gko::EnableLinOp<StencilMatrix<ValueType>>,
public gko::EnableCreateMethod<StencilMatrix<ValueType>> {
public:
// This constructor will be called by the create method. Here we initialize
// the coefficients of the stencil.
StencilMatrix(std::shared_ptr<const gko::Executor> exec,
gko::size_type size = 0, double left = -1.0,
double center = 2.0, double right = -1.0)
gko::size_type size = 0, ValueType left = -1.0,
ValueType center = 2.0, ValueType right = -1.0)
: gko::EnableLinOp<StencilMatrix>(exec, gko::dim<2>{size}),
coefficients(exec, {left, center, right})
{}

protected:
using vec = gko::matrix::Dense<>;
using coef_type = gko::Array<double>;
using vec = gko::matrix::Dense<ValueType>;
using coef_type = gko::Array<ValueType>;

// Here we implement the application of the linear operator, x = A * b.
// apply_impl will be called by the apply method, after the arguments have
Expand Down Expand Up @@ -156,14 +158,15 @@ class StencilMatrix : public gko::EnableLinOp<StencilMatrix>,

// Creates a stencil matrix in CSR format for the given number of discretization
// points.
void generate_stencil_matrix(gko::matrix::Csr<> *matrix)
template <typename ValueType, typename IndexType>
void generate_stencil_matrix(gko::matrix::Csr<ValueType, IndexType> *matrix)
{
const auto discretization_points = matrix->get_size()[0];
auto row_ptrs = matrix->get_row_ptrs();
auto col_idxs = matrix->get_col_idxs();
auto values = matrix->get_values();
int pos = 0;
const double coefs[] = {-1, 2, -1};
IndexType pos = 0;
const ValueType coefs[] = {-1, 2, -1};
row_ptrs[0] = pos;
for (int i = 0; i < discretization_points; ++i) {
for (auto ofs : {-1, 0, 1}) {
Expand All @@ -179,14 +182,15 @@ void generate_stencil_matrix(gko::matrix::Csr<> *matrix)


// Generates the RHS vector given `f` and the boundary conditions.
template <typename Closure>
void generate_rhs(Closure f, double u0, double u1, gko::matrix::Dense<> *rhs)
template <typename Closure, typename ValueType>
void generate_rhs(Closure f, ValueType u0, ValueType u1,
gko::matrix::Dense<ValueType> *rhs)
{
const auto discretization_points = rhs->get_size()[0];
auto values = rhs->get_values();
const auto h = 1.0 / (discretization_points + 1);
const ValueType h = 1.0 / (discretization_points + 1);
for (int i = 0; i < discretization_points; ++i) {
const auto xi = (i + 1) * h;
const ValueType xi = ValueType(i + 1) * h;
values[i] = -f(xi) * h * h;
}
values[0] += u0;
Expand All @@ -195,7 +199,9 @@ void generate_rhs(Closure f, double u0, double u1, gko::matrix::Dense<> *rhs)


// Prints the solution `u`.
void print_solution(double u0, double u1, const gko::matrix::Dense<> *u)
template <typename ValueType>
void print_solution(ValueType u0, ValueType u1,
const gko::matrix::Dense<ValueType> *u)
{
std::cout << u0 << '\n';
for (int i = 0; i < u->get_size()[0]; ++i) {
Expand All @@ -207,8 +213,9 @@ void print_solution(double u0, double u1, const gko::matrix::Dense<> *u)

// Computes the 1-norm of the error given the computed `u` and the correct
// solution function `correct_u`.
template <typename Closure>
double calculate_error(int discretization_points, const gko::matrix::Dense<> *u,
template <typename Closure, typename ValueType>
double calculate_error(int discretization_points,
const gko::matrix::Dense<ValueType> *u,
Closure correct_u)
{
const auto h = 1.0 / (discretization_points + 1);
Expand All @@ -226,9 +233,12 @@ double calculate_error(int discretization_points, const gko::matrix::Dense<> *u,
int main(int argc, char *argv[])
{
// Some shortcuts
using vec = gko::matrix::Dense<double>;
using mtx = gko::matrix::Csr<double, int>;
using cg = gko::solver::Cg<double>;
using ValueType = double;
using IndexType = int;

using vec = gko::matrix::Dense<ValueType>;
using mtx = gko::matrix::Csr<ValueType, IndexType>;
using cg = gko::solver::Cg<ValueType>;

if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " DISCRETIZATION_POINTS [executor]"
Expand All @@ -255,8 +265,8 @@ int main(int argc, char *argv[])
const auto app_exec = exec_map["omp"];

// problem:
auto correct_u = [](double x) { return x * x * x; };
auto f = [](double x) { return 6 * x; };
auto correct_u = [](ValueType x) { return x * x * x; };
auto f = [](ValueType x) { return ValueType(6) * x; };
auto u0 = correct_u(0);
auto u1 = correct_u(1);

Expand All @@ -268,19 +278,20 @@ int main(int argc, char *argv[])
u->get_values()[i] = 0.0;
}

const ValueType reduction_factor = 1e-7;
// Generate solver and solve the system
cg::build()
.with_criteria(gko::stop::Iteration::build()
.with_max_iters(discretization_points)
.on(exec),
gko::stop::ResidualNormReduction<>::build()
.with_reduction_factor(1e-6)
gko::stop::ResidualNormReduction<ValueType>::build()
.with_reduction_factor(reduction_factor)
.on(exec))
.on(exec)
// notice how our custom StencilMatrix can be used in the same way as
// any built-in type
->generate(
StencilMatrix::create(exec, discretization_points, -1, 2, -1))
->generate(StencilMatrix<ValueType>::create(exec, discretization_points,
-1, 2, -1))
->apply(lend(rhs), lend(u));

print_solution(u0, u1, lend(u));
Expand Down
24 changes: 20 additions & 4 deletions examples/custom-matrix-format/stencil_kernel.cu
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <cstdlib>

#include <ginkgo/ginkgo.hpp>


#define INSTANTIATE_FOR_EACH_VALUE_TYPE(_macro) \
template _macro(float); \
template _macro(double);


#define STENCIL_KERNEL(_type) \
void stencil_kernel(std::size_t size, const _type *coefs, const _type *b, \
_type *x);


namespace {


// a parallel CUDA kernel that computes the application of a 3 point stencil
__global__ void stencil_kernel_impl(std::size_t size, const double *coefs,
const double *b, double *x)
template <typename ValueType>
__global__ void stencil_kernel_impl(std::size_t size, const ValueType *coefs,
const ValueType *b, ValueType *x)
{
const auto thread_id = blockIdx.x * blockDim.x + threadIdx.x;
if (thread_id >= size) {
Expand All @@ -58,10 +71,13 @@ __global__ void stencil_kernel_impl(std::size_t size, const double *coefs,
} // namespace


void stencil_kernel(std::size_t size, const double *coefs, const double *b,
double *x)
template <typename ValueType>
void stencil_kernel(std::size_t size, const ValueType *coefs,
const ValueType *b, ValueType *x)
{
constexpr auto block_size = 512;
const auto grid_size = (size + block_size - 1) / block_size;
stencil_kernel_impl<<<grid_size, block_size>>>(size, coefs, b, x);
}

INSTANTIATE_FOR_EACH_VALUE_TYPE(STENCIL_KERNEL);
11 changes: 7 additions & 4 deletions examples/custom-stopping-criterion/custom-stopping-criterion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,12 @@ void run_solver(volatile bool *stop_iteration_process,
std::shared_ptr<gko::Executor> exec)
{
// Some shortcuts
using mtx = gko::matrix::Csr<>;
using vec = gko::matrix::Dense<>;
using bicg = gko::solver::Bicgstab<>;
using ValueType = double;
using IndexType = int;

using mtx = gko::matrix::Csr<ValueType, IndexType>;
using vec = gko::matrix::Dense<ValueType>;
using bicg = gko::solver::Bicgstab<ValueType>;

// Read Data
auto A = share(gko::read<mtx>(std::ifstream("data/A.mtx"), exec));
Expand All @@ -110,7 +113,7 @@ void run_solver(volatile bool *stop_iteration_process,
.on(exec))
.on(exec)
->generate(A);
solver->add_logger(gko::log::Stream<>::create(
solver->add_logger(gko::log::Stream<ValueType>::create(
exec, gko::log::Logger::iteration_complete_mask, std::cout, true));
solver->apply(lend(b), lend(x));

Expand Down
12 changes: 7 additions & 5 deletions examples/ginkgo-overhead/ginkgo-overhead.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <iostream>


[[noreturn]] void print_usage_and_exit(const char *name)
{
[[noreturn]] void print_usage_and_exit(const char *name) {
std::cerr << "Usage: " << name << " [NUM_ITERS]" << std::endl;
std::exit(-1);
}


int main(int argc, char *argv[])
{
using vec = gko::matrix::Dense<>;
using mtx = gko::matrix::Dense<>;
using cg = gko::solver::Cg<>;
using ValueType = double;
using IndexType = int;

using vec = gko::matrix::Dense<ValueType>;
using mtx = gko::matrix::Csr<ValueType, IndexType>;
using cg = gko::solver::Cg<ValueType>;

long unsigned num_iters = 1000000;
if (argc > 2) {
Expand Down
Loading
0