Compare commits

...
77 Commits
Author SHA1 Message Date
Andrew Ho 15e85586b1 Merge branch 'gpu_em' into gpu-maxwell 2026-07-02 18:55:08 -07:00
Andrew Ho 70b5d7c501 Merge branch 'gpu_em' into gpu-maxwell 2026-07-02 08:43:50 -07:00
Andrew Ho b4e7cf1a1a specializations to work with quadratic meshes 2026-07-01 18:31:20 -07:00
Andrew Ho 83747810f3 Merge branch 'gpu_em' into gpu-maxwell 2026-07-01 16:11:29 -07:00
Andrew Ho e3ee3868e8 Merge remote-tracking branch 'base/gpu-maxwell' into gpu-maxwell 2026-06-29 17:01:43 -07:00
Andrew Ho 93c3db3c2c Merge branch 'curl_interp_pa' into gpu-maxwell 2026-06-29 14:54:33 -07:00
Andrew Ho f0f15cac86 Merge branch 'curl_interp_pa' into gpu-maxwell 2026-06-29 12:23:51 -07:00
Andrew Ho 5bce913668 old comment 2026-06-29 11:46:07 -07:00
Andrew Ho 6ec7186f5d Merge branch 'hcurl_mass_pa' into gpu-maxwell 2026-06-29 11:31:19 -07:00
Andrew Ho ac3062abab matrix coefficient version not implemented yet 2026-06-17 22:40:11 -07:00
Andrew Ho f11c649b20 Merge branch 'hcurl_mass_pa' into gpu-maxwell 2026-06-17 22:01:29 -07:00
Andrew Ho e87398b84b minor changes 2026-06-17 22:00:16 -07:00
Andrew Ho 902bb43e8d Merge branch 'hcurl_mass_pa' into gpu-maxwell 2026-06-17 21:54:34 -07:00
Andrew Ho 87d3488424 missing forwarding addmult/addmulttranspose to bilinearform extensions 2026-06-17 20:09:01 -07:00
Andrew Ho 4c1abe4a87 Remove full assembly option
Just use the regular Maxwell miniapp for full assembly.
2026-06-17 19:09:56 -07:00
Andrew Ho 2969dabdf9 need an operator which operates on tdofs 2026-06-16 23:18:11 -07:00
Andrew Ho b5b2749946 fixed dt calculation partially applying bcs 2026-06-16 22:44:37 -07:00
Andrew Ho d97d93a3ac implemented partial assembly dt calculation 2026-06-15 22:50:43 -07:00
Andrew Ho 7783ee88a5 wrong variable name 2026-06-14 23:09:14 -07:00
Andrew Ho 3233fe5ef5 windows compiler is trying to capture constexpr local variables 2026-06-14 22:55:14 -07:00
Andrew Ho 7869614b2d can use fewer max threads 2026-06-14 18:45:31 -07:00
Andrew Ho eb0c90e7b7 Merge branch 'hcurl_mass_pa' into gpu-maxwell 2026-06-14 18:44:30 -07:00
Andrew Ho d2220abf93 implemented addmult transpose
fixed a few bugs in assemblepa
2026-06-13 23:40:21 -07:00
Andrew Ho acfda7a20e offsetting is beneficial on matrix 2026-06-13 08:42:22 -07:00
Andrew Ho dc2c5b0acb added launch bounds, testing if thread offsetting is beneficial or not 2026-06-13 08:15:46 -07:00
Andrew Ho 813fccdcb2 implemented batching 2026-06-13 08:04:39 -07:00
Andrew Ho a8d70d8947 fixed kernel execution bug and added unit test 2026-06-12 16:53:06 -07:00
Andrew Ho 7bab30392e Merge branch 'hcurl_mass_pa' into gpu-maxwell 2026-06-12 12:53:36 -07:00
Andrew Ho 56ba38a0aa switched to 3d offset wrappers to simplify code 2026-06-12 10:07:55 -07:00
Andrew Ho 5c1fa29ff0 Merge branch 'hcurl_mass_pa' into gpu-maxwell 2026-06-12 09:12:46 -07:00
Andrew Ho 6766332897 have smem curl interpolator apply implemented 2026-06-12 03:11:28 -07:00
Andrew Ho 56305bb57b fixed typo 2026-06-10 15:52:29 -07:00
Andrew Ho 37a2ec2230 Merge branch 'hcurl_mass_pa' into gpu-maxwell 2026-06-10 15:34:51 -07:00
Andrew Ho 1704a02128 use kernel specializations for curl interpolator 2026-06-10 11:15:50 -07:00
Andrew Ho ba98d630bf Merge remote-tracking branch 'base/gpu-maxwell' into gpu-maxwell 2026-06-09 11:28:04 -07:00
Andrew Ho 584b933a7f stub for "partial-assembly" CurlInterpolator 2026-06-09 11:27:43 -07:00
Andrew Ho 5f04cf5e6f Merge branch 'master' into gpu-maxwell 2026-06-09 11:27:00 -07:00
Andrew Ho e7e9c4707d Merge branch 'hcurl_mass_pa' into gpu-maxwell 2026-05-18 11:35:24 -07:00
Andrew Ho f96fe0358d Merge branch 'hcurl_domain_lf' into gpu-maxwell 2026-05-18 11:11:30 -07:00
Andrew Ho 2cafc41e9d change contiguous order to have dim1 last 2026-05-18 11:09:38 -07:00
Andrew Ho 38c2f7a6ea Merge branch 'hcurl_domain_lf' into gpu-maxwell 2026-05-15 01:20:57 -07:00
Andrew Ho afe84565d8 Merge branch 'hcurl_domain_lf' into gpu-maxwell 2026-05-15 01:17:28 -07:00
Andrew Ho f072fde956 Implemented adaptive dt calculation
also have another hcurl mass kernel which performs really well on AMD GPUs,
but is not great at high order on NVidia GPUs.
2026-05-14 15:02:35 -07:00
Andrew Ho 65ed4e1188 msvc incorrectly captures vdim instead of treating it as constexpr 2026-05-08 23:37:58 -07:00
Andrew Ho f432e7fef3 even more msvc warnings 2026-05-08 22:57:17 -07:00
Andrew Ho 03145336b6 more mvsc warnings 2026-05-08 22:44:27 -07:00
Andrew Ho f077a45cce fix another msvc warning 2026-05-08 22:23:37 -07:00
Andrew Ho 4e568ae2e1 Merge remote-tracking branch 'base/gpu-maxwell' into gpu-maxwell 2026-05-08 21:59:21 -07:00
Andrew Ho dc53c87f63 compiler complaining about indexing with bool 2026-05-08 21:58:55 -07:00
Andrew Ho 0919b965f7 Merge branch 'master' into gpu-maxwell 2026-05-08 21:28:48 -07:00
Andrew Ho 9c687e3e83 bug fixes 2026-05-08 13:02:36 -07:00
Andrew Ho 5e244e1512 fixed bug reading markers 2026-05-08 12:12:16 -07:00
Andrew Ho f0d5a8a406 implemented hcurl domain lininteg device assembly 2026-05-08 12:06:19 -07:00
Andrew Ho 67e5ea9e74 switch VectorFEDomainLFIntegrator to use kernel dispatcher 2026-05-08 11:49:00 -07:00
Andrew Ho 9ff10d4c24 test windows build failure fix 2026-05-08 09:30:25 -07:00
Andrew Ho 2f42e93943 more CI warnings 2026-05-07 17:35:32 -07:00
Andrew Ho d0984442da CI compiler warnings 2026-05-06 19:13:30 -07:00
Andrew Ho b7188b08ab initialization order warning 2026-05-06 17:53:48 -07:00
Andrew Ho e61a0d629b missing doxygen escapes
added specializations for P=Q
2026-05-06 17:43:02 -07:00
Andrew Ho ca4ffc731b allow passing a specific integration rule to VectorFELFIntegrator 2026-05-05 11:55:01 -07:00
Andrew Ho f64e6a714b improved HCurl mass 3d apply performance 2026-05-05 09:25:27 -07:00
Andrew Ho b764432dae Merge branch 'batchmass3d' into gpu-maxwell 2026-04-27 23:58:23 -07:00
Andrew Ho 29b796be29 working on re-working parallelization of hcurl mass pa apply 2026-04-27 23:57:37 -07:00
Andrew Ho e2d73eb5de change vectorfemass to use the kernel specialization infrastructure 2026-04-27 19:14:24 -07:00
Andrew Ho baab626655 Have the correct RHS now 2026-04-26 23:51:12 -07:00
Andrew Ho f4c43542fe implemented current source 2026-04-26 02:27:40 -07:00
Andrew Ho f4442f229a wrong number of dofs in 3D h(div) linear form assembly 2026-04-26 00:57:57 -07:00
Andrew Ho 20424db300 Have a normalized plane wave example working on GPU 2026-04-25 11:14:55 -07:00
Andrew Ho dc427a4b04 have visualization, but seems to have some sort of bug still? 2026-04-25 01:00:36 -07:00
Andrew Ho b34f43359e Fixed missing RAP setup for MPI 2026-04-24 23:45:47 -07:00
Andrew Ho fc42855ce4 need pmesh coordinate information for current integrator 2026-04-23 10:51:14 -07:00
Andrew Ho 5abcb25851 have basic GPU solve with partial assembly working 2026-04-22 15:58:05 -07:00
Andrew Ho 7a02c5d256 setup coefficients and some terms in ampere's equation 2026-04-19 08:44:59 -07:00
Andrew Ho ba9ba59a08 getting global true vsize is a collective operation 2026-04-19 01:45:35 -07:00
Andrew Ho 06a8223fa6 implemented faraday's equation 2026-04-19 01:31:45 -07:00
Andrew Ho ffeef80ed4 stub for GPU maxwell implementation 2026-04-14 12:36:18 -07:00
Andrew Ho 34278b85fd added an enumeration list option to optparser 2026-04-08 12:41:10 -07:00
8 changed files with 1524 additions and 51 deletions
+2 -2
View File
@@ -258,8 +258,8 @@ void BatchedLOR_DG::Assemble2D()
const int w_idx = (n_idx == 0) ? iy : ix;
const int x_idx = (n_idx == 0) ? i_0 : j_0;
const real_t J1 = J(ix, iy, n_idx, !n_idx, iel_ho);
const real_t J2 = J(ix, iy, !n_idx, !n_idx, iel_ho);
const real_t J1 = J(ix, iy, n_idx, (int)!n_idx, iel_ho);
const real_t J2 = J(ix, iy, (int)!n_idx, (int)!n_idx, iel_ho);
const real_t Jh = (J1*J1 + J2*J2) / detJ(ix, iy, iel_ho);
V(v_idx, ix, iy, iel_ho) =
+15 -12
View File
@@ -136,8 +136,8 @@ inline void EvalHDiv2D(const int NE,
{
qq += QD(qx,dy,vd) * By(dy,qy);
}
if (FLAGS & (QuadratureInterpolator::PHYSICAL_VALUES |
QuadratureInterpolator::PHYSICAL_MAGNITUDES))
if ((FLAGS & (QuadratureInterpolator::PHYSICAL_VALUES |
QuadratureInterpolator::PHYSICAL_MAGNITUDES)) != 0)
{
QQ(qx,qy,vd) = qq;
}
@@ -153,8 +153,8 @@ inline void EvalHDiv2D(const int NE,
}
}
MFEM_SYNC_THREAD;
if (FLAGS & (QuadratureInterpolator::PHYSICAL_VALUES |
QuadratureInterpolator::PHYSICAL_MAGNITUDES))
if ((FLAGS & (QuadratureInterpolator::PHYSICAL_VALUES |
QuadratureInterpolator::PHYSICAL_MAGNITUDES)) != 0)
{
if (tidz == 0)
{
@@ -178,7 +178,7 @@ inline void EvalHDiv2D(const int NE,
const real_t detJ = kernels::Det<DIM>(J_loc);
kernels::Mult(DIM, DIM, J_loc, u_ref, u_phys);
kernels::Set(DIM, 1, 1_r/detJ, u_phys, u_phys);
if (FLAGS & QuadratureInterpolator::PHYSICAL_VALUES)
if ((FLAGS & QuadratureInterpolator::PHYSICAL_VALUES) != 0)
{
MFEM_UNROLL(DIM)
for (int sd = 0; sd < DIM; sd++)
@@ -193,7 +193,8 @@ inline void EvalHDiv2D(const int NE,
}
}
}
else if (FLAGS & QuadratureInterpolator::PHYSICAL_MAGNITUDES)
else if ((FLAGS &
QuadratureInterpolator::PHYSICAL_MAGNITUDES) != 0)
{
y(qx,qy,0,e) = kernels::Norml2(DIM, u_phys);
}
@@ -372,8 +373,9 @@ inline void EvalHDiv3D(const int NE,
MFEM_UNROLL(MQ1)
for (int qz = 0; qz < Q1D; ++qz)
{
if (FLAGS & (QuadratureInterpolator::PHYSICAL_VALUES |
QuadratureInterpolator::PHYSICAL_MAGNITUDES))
if ((FLAGS & (QuadratureInterpolator::PHYSICAL_VALUES |
QuadratureInterpolator::PHYSICAL_MAGNITUDES)) !=
0)
{
QQQ(qx,qy,qz,vd) = u[qz];
}
@@ -390,8 +392,8 @@ inline void EvalHDiv3D(const int NE,
}
}
MFEM_SYNC_THREAD;
if (FLAGS & (QuadratureInterpolator::PHYSICAL_VALUES |
QuadratureInterpolator::PHYSICAL_MAGNITUDES))
if ((FLAGS & (QuadratureInterpolator::PHYSICAL_VALUES |
QuadratureInterpolator::PHYSICAL_MAGNITUDES)) != 0)
{
MFEM_FOREACH_THREAD(qz,z,Q1D)
{
@@ -415,7 +417,7 @@ inline void EvalHDiv3D(const int NE,
const real_t detJ = kernels::Det<DIM>(J_loc);
kernels::Mult(DIM, DIM, J_loc, u_ref, u_phys);
kernels::Set(DIM, 1, 1_r/detJ, u_phys, u_phys);
if (FLAGS & QuadratureInterpolator::PHYSICAL_VALUES)
if ((FLAGS & QuadratureInterpolator::PHYSICAL_VALUES) != 0)
{
MFEM_UNROLL(DIM)
for (int sd = 0; sd < DIM; sd++)
@@ -430,7 +432,8 @@ inline void EvalHDiv3D(const int NE,
}
}
}
else if (FLAGS & QuadratureInterpolator::PHYSICAL_MAGNITUDES)
else if ((FLAGS &
QuadratureInterpolator::PHYSICAL_MAGNITUDES) != 0)
{
y(qx,qy,qz,0,e) = kernels::Norml2(DIM, u_phys);
}
+54 -12
View File
@@ -148,9 +148,26 @@ void parseVector(char * str, Vector & var)
}
}
bool parseEnumOption(const char *str, size_t &var,
const std::vector<std::string> &options)
{
for (size_t i = 0; i < options.size(); ++i)
{
auto &v = options[i];
if (v == str)
{
var = i;
// success
return true;
}
}
// failure
return false;
}
void OptionsParser::Parse()
{
option_check.SetSize(options.Size());
option_check.SetSize(options.size());
option_check = 0;
for (int i = 1; i < argc; )
{
@@ -161,9 +178,9 @@ void OptionsParser::Parse()
return;
}
for (int j = 0; true; j++)
for (size_t j = 0; true; j++)
{
if (j >= options.Size())
if (j >= options.size())
{
// unrecognized option
error_type = 2;
@@ -171,8 +188,8 @@ void OptionsParser::Parse()
return;
}
if (strcmp(argv[i], options[j].short_name) == 0 ||
strcmp(argv[i], options[j].long_name) == 0)
if (strcmp(argv[i], options[j].short_name.c_str()) == 0 ||
strcmp(argv[i], options[j].long_name.c_str()) == 0)
{
OptionType type = options[j].type;
@@ -224,6 +241,11 @@ void OptionsParser::Parse()
case VECTOR:
parseVector(argv[i++], *(Vector*)(options[j].var_ptr) );
break;
case ENUM_OPTION:
isValid =
parseEnumOption(argv[i++], *(size_t *)(options[j].var_ptr),
options[j].options);
break;
}
if (!isValid)
@@ -239,7 +261,7 @@ void OptionsParser::Parse()
}
// check for missing required options
for (int i = 0; i < options.Size(); i++)
for (size_t i = 0; i < options.size(); i++)
if (options[i].required &&
(option_check[i] == 0 ||
(options[i].type == ENABLE && option_check[++i] == 0)))
@@ -323,6 +345,12 @@ void OptionsParser::WriteValue(const Option &opt, std::ostream &os)
break;
}
case ENUM_OPTION:
{
os << opt.options.at(*((size_t *)opt.var_ptr));
break;
}
default: // provide a default to suppress warning
break;
}
@@ -333,7 +361,7 @@ void OptionsParser::PrintOptions(ostream &os) const
static const char *indent = " ";
os << "Options used:\n";
for (int j = 0; j < options.Size(); j++)
for (size_t j = 0; j < options.size(); j++)
{
OptionType type = options[j].type;
@@ -355,7 +383,7 @@ void OptionsParser::PrintOptions(ostream &os) const
os << options[j].long_name << " ";
WriteValue(options[j], os);
}
os << '\n';
os << std::endl;
}
}
@@ -410,12 +438,13 @@ void OptionsParser::PrintHelp(ostream &os) const
static const char *line_sep = "";
static const char *types[] = { " <int>", " <double>", " <string>",
" <string>", "", "", " '<int>...'",
" '<double>...'"
" '<double>...'",
" <string>",
};
os << indent << "-h" << seprtr << "--help" << descr_sep
<< "Print this help message and exit.\n" << line_sep;
for (int j = 0; j < options.Size(); j++)
for (size_t j = 0; j < options.size(); j++)
{
OptionType type = options[j].type;
@@ -451,9 +480,22 @@ void OptionsParser::PrintHelp(ostream &os) const
}
os << descr_sep;
if (options[j].description)
if (options[j].description.size())
{
os << options[j].description << '\n';
os << options[j].description << std::endl;
}
if (options[j].type == ENUM_OPTION)
{
os << "\tavailable choices: ";
for (size_t i = 0; i < options[j].options.size(); ++i)
{
os << '"' << options[j].options[i] << '"';
if (i + 1 < options[j].options.size())
{
os << ", ";
}
}
os << std::endl;
}
os << line_sep;
}
+45 -21
View File
@@ -15,6 +15,9 @@
#include "../config/config.hpp"
#include "array.hpp"
#include <string>
#include <vector>
namespace mfem
{
@@ -31,17 +34,18 @@ class Vector;
class OptionsParser
{
public:
enum OptionType { INT, DOUBLE, STRING, STD_STRING, ENABLE, DISABLE, ARRAY, VECTOR };
enum OptionType { INT, DOUBLE, STRING, STD_STRING, ENABLE, DISABLE, ARRAY, VECTOR, ENUM_OPTION };
private:
struct Option
{
OptionType type;
void *var_ptr;
const char *short_name;
const char *long_name;
const char *description;
std::string short_name;
std::string long_name;
std::string description;
bool required;
std::vector<std::string> options;
Option() = default;
@@ -49,11 +53,19 @@ private:
const char *long_name_, const char *description_, bool req)
: type(type_), var_ptr(var_ptr_), short_name(short_name_),
long_name(long_name_), description(description_), required(req) { }
Option(size_t *var_ptr_, const char *short_name_, const char *long_name_,
const char *description_, std::vector<std::string> &&options_,
bool req)
: type(ENUM_OPTION), var_ptr(var_ptr_), short_name(short_name_),
long_name(long_name_), description(description_),
required(req), options(std::move(options_))
{}
};
int argc;
char **argv;
Array<Option> options;
std::vector<Option> options;
Array<int> option_check;
// error_type can be:
// 0 - no error
@@ -84,26 +96,26 @@ public:
const char *disable_long_name, const char *description,
bool required = false)
{
options.Append(Option(ENABLE, var, enable_short_name, enable_long_name,
description, required));
options.Append(Option(DISABLE, var, disable_short_name, disable_long_name,
description, required));
options.emplace_back(ENABLE, var, enable_short_name, enable_long_name,
description, required);
options.emplace_back(DISABLE, var, disable_short_name, disable_long_name,
description, required);
}
/// Add an integer option and set 'var' to receive the value.
void AddOption(int *var, const char *short_name, const char *long_name,
const char *description, bool required = false)
{
options.Append(Option(INT, var, short_name, long_name, description,
required));
options.emplace_back(INT, var, short_name, long_name, description,
required);
}
/// Add a double option and set 'var' to receive the value.
void AddOption(real_t *var, const char *short_name, const char *long_name,
const char *description, bool required = false)
{
options.Append(Option(DOUBLE, var, short_name, long_name, description,
required));
options.emplace_back(DOUBLE, var, short_name, long_name, description,
required);
}
/// Add a string (char*) option and set 'var' to receive the value.
@@ -111,8 +123,8 @@ public:
const char *long_name, const char *description,
bool required = false)
{
options.Append(Option(STRING, var, short_name, long_name, description,
required));
options.emplace_back(STRING, var, short_name, long_name, description,
required);
}
/// Add a string (std::string) option and set 'var' to receive the value.
@@ -120,8 +132,8 @@ public:
const char *long_name, const char *description,
bool required = false)
{
options.Append(Option(STD_STRING, var, short_name, long_name, description,
required));
options.emplace_back(STD_STRING, var, short_name, long_name, description,
required);
}
/** Add an integer array (separated by spaces) option and set 'var' to
@@ -130,8 +142,8 @@ public:
const char *long_name, const char *description,
bool required = false)
{
options.Append(Option(ARRAY, var, short_name, long_name, description,
required));
options.emplace_back(ARRAY, var, short_name, long_name, description,
required);
}
/** Add a vector (doubles separated by spaces) option and set 'var' to
@@ -140,8 +152,20 @@ public:
const char *long_name, const char *description,
bool required = false)
{
options.Append(Option(VECTOR, var, short_name, long_name, description,
required));
options.emplace_back(VECTOR, var, short_name, long_name, description,
required);
}
/**
* Add an option which must be one of a given list of options
*/
void AddOptionChoice(size_t *index, const char *short_name,
const char *long_name, const char *description,
std::vector<std::string> options_,
bool required = false)
{
options.emplace_back(index, short_name, long_name, description,
std::move(options_), required);
}
/** @brief Parse the command-line options.
+5
View File
@@ -34,6 +34,11 @@ if (MFEM_USE_MPI)
EXTRA_HEADERS maxwell_solver.hpp ${MFEM_MINIAPPS_COMMON_HEADERS}
LIBRARIES mfem-common)
add_mfem_miniapp(maxwell-gpu
MAIN maxwell_gpu.cpp
EXTRA_HEADERS ${MFEM_MINIAPPS_COMMON_HEADERS}
LIBRARIES mfem-common)
if (MFEM_USE_GSLIB)
add_mfem_miniapp(lorentz
MAIN lorentz.cpp
@@ -12,6 +12,8 @@
#ifndef MFEM_ELECTROMAGNETICS_HPP
#define MFEM_ELECTROMAGNETICS_HPP
#include <cmath>
namespace mfem
{
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -308,7 +308,7 @@ MaxwellSolver::~MaxwellSolver()
{
int i = mit1->first;
delete pcg_[i];
delete diagScale_[i];
// delete diagScale_[i];
delete A1_[i];
delete a1_[i];
}
@@ -377,7 +377,7 @@ MaxwellSolver::Mult(const Vector &B, Vector &dEdt) const
void
MaxwellSolver::ImplicitSolve(real_t dt, const Vector &B, Vector &dEdt)
{
implicitSolve(dt, B, dEdt);
const_cast<const MaxwellSolver *>(this)->implicitSolve(dt, B, dEdt);
}
void
@@ -420,12 +420,12 @@ MaxwellSolver::setupSolver(const int idt, const real_t dt) const
a1_[idt]->Finalize();
A1_[idt] = a1_[idt]->ParallelAssemble();
diagScale_[idt] = new HypreDiagScale(*A1_[idt]);
// diagScale_[idt] = new HypreDiagScale(*A1_[idt]);
pcg_[idt] = new HyprePCG(*A1_[idt]);
pcg_[idt]->SetTol(1.0e-12);
pcg_[idt]->SetMaxIter(200);
pcg_[idt]->SetPrintLevel(0);
pcg_[idt]->SetPreconditioner(*diagScale_[idt]);
// pcg_[idt]->SetPreconditioner(*diagScale_[idt]);
}
}