<commit_before>// Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "bench.hpp"

#ifdef MFEM_USE_BENCHMARK

/*
  This benchmark is inspired by the CEED's bake-off problems to benchmark the
  performance of the action of the partial assembly (PA) of DG Convection on
  nonconforming meshes.

   * --benchmark_filter=BK_DG/[1-max_order]/[prob]
   * --benchmark_context=device=[cpu/cuda/hip]
*/

// The maximum polynomial order used for benchmarking
const int max_order = 6;
// The maximum number of dofs for benchmarking
const int max_dofs = 1e7;

void velocity_function(const Vector &x, Vector &v)
{
   int dim = x.Size();
   switch (dim)
   {
      case 1: v(0) = 1.0; break;
      case 2: v(0) = x(1); v(1) = -x(0); break;
      case 3: v(0) = x(1); v(1) = -x(0); v(2) = x(0); break;
   }
}

/// A kernel testing DG Convection
struct KernelMesh
{
   const int N;
   Mesh mesh;

   KernelMesh(int N, double prob)
   : N(N), mesh(Mesh::MakeCartesian3D(N,N,N,Element::HEXAHEDRON))
   {
      if (prob >= 0.0)
      {
         mesh.EnsureNCMesh();
         if (prob > 0.0)
         {
            mesh.RandomRefinement(prob);
         }            
      }
   }
};

struct Kernel: public KernelMesh
{
   const int p, q, dim = 3;
   DG_FECollection fec;
   FiniteElementSpace fes;
   // const Geometry::Type geom_type;
   // IntegrationRules IntRulesGLL;
   // const IntegrationRule *irGLL;
   // const IntegrationRule *ir;
   // ConstantCoefficient one;
   const int dofs;
   GridFunction x,y;
   BilinearForm a;
   double mdofs;
   VectorFunctionCoefficient velocity;

   Kernel(int order, int N, double prob = -1, bool GLL = false)
   : 
      KernelMesh(N, prob),
      p(order),
      q(2*p + (GLL?-1:3)),
      fec(p, dim, BasisType::GaussLobatto),
      fes(&mesh, &fec),
      // geom_type(fes.GetFE(0)->GetGeomType()),
      // IntRulesGLL(0, Quadrature1D::GaussLobatto),
      // irGLL(&IntRulesGLL.Get(geom_type, q)),
      // ir(&IntRules.Get(geom_type, q)),
      // one(1.0),
      dofs(fes.GetTrueVSize()),
      x(&fes),
      y(&fes),
      a(&fes),
      mdofs(0.0),
      velocity(dim, velocity_function)
   {
      if (is_runnable())
      {
         x.Randomize(1);
         a.SetAssemblyLevel(AssemblyLevel::PARTIAL);
         a.AddDomainIntegrator(new ConvectionIntegrator(velocity, -1.0));
         a.AddInteriorFaceIntegrator(
            new TransposeIntegrator(new DGTraceIntegrator(velocity, 1.0, -0.5)));
         a.AddBdrFaceIntegrator(
            new TransposeIntegrator(new DGTraceIntegrator(velocity, 1.0, -0.5)));
         a.Assemble();
         a.Mult(x, y);
         MFEM_DEVICE_SYNC;
      }
   }

   /// @brief Heuristic to evaluate if the case will run out of memory
   bool is_runnable() const
   {
      const long long int gB = 1073741824/8;
      const int mem_size = Device::IsEnabled()?16:256;
      const long long int max_mem = mem_size * gB;
      const int num_elems = fes.GetNE();
      long long int mem = num_elems * pow(p+1, dim+1) * 8;
      // std::cout << "mem = " << mem << " , max_mem = " << max_mem << std::endl;
      return mem < max_mem;
   }

   void setup()
   {
      a.Assemble();
   }

   void benchmark_setup()
   {
      setup();
      MFEM_DEVICE_SYNC;
      mdofs += MDofs();
   }

   void benchmark_action()
   {
      a.Mult(x, y);
      MFEM_DEVICE_SYNC;
      mdofs += MDofs();
   }

   double SumMdofs() const { return mdofs; }

   double MDofs() const { return 1e-6 * dofs; }
};

/// BK_DG inspired benchmark for the action
static void BK_DG(bm::State &state){
   const int dim = 3;
   const int p = state.range(1);
   const int target_dofs = state.range(0);
   const int elem_dofs = pow(p+1, dim);
   const int N = pow(target_dofs / elem_dofs, 1.0/dim) + 1;
   const double prob = ((double)state.range(2))/100;
   Kernel ker(p, N, prob);
   if ( !ker.is_runnable() ) { state.SkipWithError("MAX_MEM"); }
   while (state.KeepRunning()) { ker.benchmark_action(); }
   state.counters["MDof/s"] = bm::Counter(ker.SumMdofs(), bm::Counter::kIsRate);
   state.counters["Dofs"] = bm::Counter(ker.dofs, bm::Counter::kDefaults);
   state.counters["Order"] = bm::Counter(ker.p);
   state.counters["Prob"] = bm::Counter(prob);}

BENCHMARK(BK_DG)->ArgsProduct({
      benchmark::CreateRange(1024, max_dofs, /*step=*/2),
      benchmark::CreateDenseRange(1, max_order, /*step=*/1),
      {-1, 0, 1, 10, 50}<commit_msg>Small edit to bench dg amr.<commit_after>// Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "bench.hpp"

#ifdef MFEM_USE_BENCHMARK

/*
  This benchmark is inspired by the CEED's bake-off problems to benchmark the
  performance of the action of the partial assembly (PA) of DG Convection on
  nonconforming meshes.

   * --benchmark_filter=BK_DG/[1-max_order]/[prob]
   * --benchmark_context=device=[cpu/cuda/hip]
*/

// The maximum polynomial order used for benchmarking
const int max_order = 6;
// The maximum number of dofs for benchmarking
const int max_dofs = 1e7;

void velocity_function(const Vector &x, Vector &v)
{
   int dim = x.Size();
   switch (dim)
   {
      case 1: v(0) = 1.0; break;
      case 2: v(0) = x(1); v(1) = -x(0); break;
      case 3: v(0) = x(1); v(1) = -x(0); v(2) = x(0); break;
   }
}

/// A kernel testing DG Convection
struct KernelMesh
{
   const int N;
   Mesh mesh;

   KernelMesh(int N, double prob)
   : N(N), mesh(Mesh::MakeCartesian3D(N,N,N,Element::HEXAHEDRON))
   {
      if (prob >= 0.0)
      {
         mesh.EnsureNCMesh();
         if (prob > 0.0)
         {
            mesh.RandomRefinement(prob);
         }            
      }
   }
};

struct Kernel: public KernelMesh
{
   const int p, q, dim = 3;
   DG_FECollection fec;
   FiniteElementSpace fes;
   // const Geometry::Type geom_type;
   // IntegrationRules IntRulesGLL;
   // const IntegrationRule *irGLL;
   // const IntegrationRule *ir;
   // ConstantCoefficient one;
   const int dofs;
   GridFunction x,y;
   BilinearForm a;
   double mdofs;
   VectorFunctionCoefficient velocity;

   Kernel(int order, int N, double prob = -1, bool GLL = false)
   : 
      KernelMesh(N, prob),
      p(order),
      q(2*p + (GLL?-1:3)),
      fec(p, dim, BasisType::GaussLobatto),
      fes(&mesh, &fec),
      // geom_type(fes.GetFE(0)->GetGeomType()),
      // IntRulesGLL(0, Quadrature1D::GaussLobatto),
      // irGLL(&IntRulesGLL.Get(geom_type, q)),
      // ir(&IntRules.Get(geom_type, q)),
      // one(1.0),
      dofs(fes.GetTrueVSize()),
      x(&fes),
      y(&fes),
      a(&fes),
      mdofs(0.0),
      velocity(dim, velocity_function)
   {
      if (is_runnable())
      {
         x.Randomize(1);
         a.SetAssemblyLevel(AssemblyLevel::PARTIAL);
         a.AddDomainIntegrator(new ConvectionIntegrator(velocity, -1.0));
         a.AddInteriorFaceIntegrator(
            new TransposeIntegrator(new DGTraceIntegrator(velocity, 1.0, -0.5)));
         a.AddBdrFaceIntegrator(
            new TransposeIntegrator(new DGTraceIntegrator(velocity, 1.0, -0.5)));
         a.Assemble();
         a.Mult(x, y);
         MFEM_DEVICE_SYNC;
      }
   }

   /// @brief Heuristic to evaluate if the case will run out of memory
   bool is_runnable() const
   {
      const long long int gB = 1073741824/8;
      const int mem_size = Device::IsEnabled()?16:256;
      const long long int max_mem = mem_size * gB;
      const int num_elems = fes.GetNE();
      long long int mem = num_elems * pow(p+1, dim+1) * 8;
      // std::cout << "mem = " << mem << " , max_mem = " << max_mem << std::endl;
      return mem < max_mem;
   }

   void setup()
   {
      a.Assemble();
   }

   void benchmark_setup()
   {
      setup();
      MFEM_DEVICE_SYNC;
      mdofs += MDofs();
   }

   void benchmark_action()
   {
      a.Mult(x, y);
      MFEM_DEVICE_SYNC;
      mdofs += MDofs();
   }

   double SumMdofs() const { return mdofs; }

   double MDofs() const { return 1e-6 * dofs; }
};

/// BK_DG inspired benchmark for the action
static void BK_DG(bm::State &state){
   const int dim = 3;
   const int p = state.range(1);
   const int target_dofs = state.range(0);
   const int elem_dofs = pow(p+1, dim);
   const int N = pow(target_dofs / elem_dofs, 1.0/dim) + 1;
   const double prob = ((double)state.range(2))/100;
   Kernel ker(p, N, prob);
   if ( !ker.is_runnable() ) { state.SkipWithError("MAX_MEM"); }
   while (state.KeepRunning()) { ker.benchmark_action(); }
   state.counters["MDof/s"] = bm::Counter(ker.SumMdofs(), bm::Counter::kIsRate);
   state.counters["Dofs"] = bm::Counter(ker.dofs, bm::Counter::kDefaults);
   state.counters["Order"] = bm::Counter(ker.p);
   state.counters["Prob"] = bm::Counter(state.range(2));}

BENCHMARK(BK_DG)->ArgsProduct({
      benchmark::CreateRange(1024, max_dofs, /*step=*/2),
      benchmark::CreateDenseRange(1, max_order, /*step=*/1),
      {-1, 0, 1, 10, 30}
{'fraction_non_alphanumeric': 0.14200697722142416, 'fraction_numerical': 0.022470757233736916, 'mean_word_length': 2.7373466257668713, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 11, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4492604', 'n_tokens_mistral': 3634, 'n_tokens_neox': 3420, 'n_words': 866}