Skip to content
Snippets Groups Projects
Unverified Commit 9f18a505 authored by Thorsten Hater's avatar Thorsten Hater Committed by GitHub
Browse files

Fix #2250 by using a consistent naming strategy. (#2251)

Use the `module_name` string  to name files written by `modcc` consistently.

Fixes #2250
parent 93fb291b
Branches
Tags
No related merge requests found
...@@ -22,18 +22,19 @@ ...@@ -22,18 +22,19 @@
#include <fmt/format.h> #include <fmt/format.h>
using std::cout; #include <filesystem>
using std::cerr;
namespace fs = std::filesystem;
// Options and option parsing: // Options and option parsing:
int report_error(const std::string& message) { int report_error(const std::string& message) {
cerr << red("error trace:\n") << message << "\n"; std::cerr << red("error trace:\n") << message << "\n";
return 1; return 1;
} }
int report_ice(const std::string& message) { int report_ice(const std::string& message) {
cerr << red("internal compiler error:\n") << message << "\n" std::cerr << red("internal compiler error:\n") << message << "\n"
<< "\nPlease report this error to the modcc developers.\n"; << "\nPlease report this error to the modcc developers.\n";
return 1; return 1;
} }
...@@ -99,22 +100,19 @@ std::ostream& operator<<(std::ostream& out, const Options& opt) { ...@@ -99,22 +100,19 @@ std::ostream& operator<<(std::ostream& out, const Options& opt) {
targets += " "+key_by_value(targetKindMap, t); targets += " "+key_by_value(targetKindMap, t);
} }
for (const auto& f: opt.modfiles) { for (const auto& f: opt.modfiles) out << table_prefix{"file"} << f << line_end;
out << table_prefix{"file"} << f << line_end; out << table_prefix{"output"} << (opt.outprefix.empty() ? "-" : opt.outprefix) << line_end
} << table_prefix{"verbose"} << noyes[opt.verbose] << line_end
out << table_prefix{"output"} << (opt.outprefix.empty()? "-": opt.outprefix) << line_end << << table_prefix{"targets"} << targets << line_end
table_prefix{"verbose"} << noyes[opt.verbose] << line_end << << table_prefix{"analysis"} << noyes[opt.analysis] << line_end;
table_prefix{"targets"} << targets << line_end <<
table_prefix{"analysis"} << noyes[opt.analysis] << line_end;
return out; return out;
} }
std::ostream& operator<<(std::ostream& out, const printer_options& popt) { std::ostream& operator<<(std::ostream& out, const printer_options& popt) {
static const std::string line_end = cyan(" |") + "\n"; static const std::string line_end = cyan(" |") + "\n";
out << table_prefix{"namespace"} << popt.cpp_namespace << line_end
return out << << table_prefix{"simd"} << popt.simd << line_end;
table_prefix{"namespace"} << popt.cpp_namespace << line_end << return out;
table_prefix{"simd"} << popt.simd << line_end;
} }
std::istream& operator>> (std::istream& i, simd_spec& spec) { std::istream& operator>> (std::istream& i, simd_spec& spec) {
...@@ -146,8 +144,6 @@ const char* usage_str = ...@@ -146,8 +144,6 @@ const char* usage_str =
"<filenames> [Files to be compiled]\n"; "<filenames> [Files to be compiled]\n";
int main(int argc, char **argv) { int main(int argc, char **argv) {
using namespace to;
Options opt; Options opt;
printer_options popt; printer_options popt;
try { try {
...@@ -188,99 +184,96 @@ int main(int argc, char **argv) { ...@@ -188,99 +184,96 @@ int main(int argc, char **argv) {
if (!opt.catalogue.empty()) popt.cpp_namespace += "::" + opt.catalogue + "_catalogue"; if (!opt.catalogue.empty()) popt.cpp_namespace += "::" + opt.catalogue + "_catalogue";
std::vector<std::string> modules; std::vector<std::pair<std::string, std::string>> modules;
for (const auto& modfile: opt.modfiles) { auto outdir = fs::path(opt.outprefix);
for (const auto& input: opt.modfiles) {
auto modfile = fs::path(input);
try { try {
auto emit_header = [&opt](const char* h) { auto emit_header = [&opt](const char* h) {
if (opt.verbose) { if (opt.verbose) {
cout << green("[") << h << green("]") << "\n"; std::cout << green("[") << h << green("]") << "\n";
} }
}; };
if (opt.verbose) { if (opt.verbose) {
static const std::string tableline = cyan("."+std::string(60, '-')+".")+"\n"; static const std::string tableline = cyan("."+std::string(60, '-')+".")+"\n";
cout << tableline; std::cout << tableline
cout << opt; << opt
cout << popt; << popt
cout << tableline; << tableline;
} }
// Load module file and initialize Module object. // Load module file and initialize Module object.
Module m(io::read_all(modfile), modfile); Module m(io::read_all(modfile), modfile);
if (m.empty()) { if (m.empty()) return report_error(fmt::format("Input file is empty: {}", modfile.string()));
return report_error("empty file: "+modfile);
}
// Perform parsing and semantic analysis passes. // Perform parsing and semantic analysis passes.
emit_header("parsing"); emit_header("parsing");
Parser p(m, false); Parser p(m, false);
if (!p.parse()) { if (!p.parse()) return 1;
// Parser::parse() writes its own errors to stderr.
return 1;
}
emit_header("semantic analysis"); emit_header("semantic analysis");
m.semantic(); m.semantic();
if (m.has_warning()) { if (m.has_warning()) {
cerr << yellow("Warnings:\n"); std::cerr << yellow("Warnings:\n")
cerr << m.warning_string() << "\n"; << m.warning_string() << "\n";
}
if (m.has_error()) {
return report_error(m.error_string());
} }
// Generate backend-specific sources for each backend provided. if (m.has_error()) return report_error(m.error_string());
// Generate backend-specific sources for each backend provided.
emit_header("code generation"); emit_header("code generation");
std::string prefix = m.module_name(); std::string mod = m.module_name();
if (!opt.outprefix.empty()) {
if (opt.outprefix.back() != '/') opt.outprefix += "/";
prefix = opt.outprefix + prefix;
}
bool have_cpu = opt.targets.find(targetKind::cpu) != opt.targets.end(); bool have_cpu = opt.targets.find(targetKind::cpu) != opt.targets.end();
bool have_gpu = opt.targets.find(targetKind::gpu) != opt.targets.end(); bool have_gpu = opt.targets.find(targetKind::gpu) != opt.targets.end();
io::write_all(build_info_header(m, popt, have_cpu, have_gpu), prefix+".hpp"); auto prefix = modfile.filename().replace_extension("").string();
io::write_all(build_info_header(m, popt, have_cpu, have_gpu), outdir / (mod + ".hpp"));
for (targetKind target: opt.targets) { for (targetKind target: opt.targets) {
std::string outfile = prefix;
switch (target) { switch (target) {
case targetKind::gpu: case targetKind::gpu: {
io::write_all(emit_gpu_cpp_source(m, popt), outfile+"_gpu.cpp"); fs::path fn = outdir / (mod + "_gpu.cpp");
io::write_all(emit_gpu_cu_source(m, popt), outfile+"_gpu.cu"); io::write_all(emit_gpu_cpp_source(m, popt), fn.string());
fn.replace_extension(".cu");
io::write_all(emit_gpu_cu_source(m, popt), fn.string());
break; break;
case targetKind::cpu: }
io::write_all(emit_cpp_source(m, popt), outfile+"_cpu.cpp"); case targetKind::cpu: {
fs::path fn = outdir / (mod + "_cpu");
fn.replace_extension(".cpp");
io::write_all(emit_cpp_source(m, popt), fn.string());
break; break;
} }
} }
}
// Optional analysis report. // Optional analysis report.
if (opt.analysis) { if (opt.analysis) {
cout << green("performance analysis\n"); std::cout << green("performance analysis\n");
for (auto &symbol: m.symbols()) { for (auto &symbol: m.symbols()) {
if (auto method = symbol.second->is_api_method()) { if (auto method = symbol.second->is_api_method()) {
cout << white("-------------------------\n");
cout << yellow("method " + method->name()) << "\n";
cout << white("-------------------------\n");
FlopVisitor flops; FlopVisitor flops;
method->accept(&flops); method->accept(&flops);
cout << white("FLOPS\n") << flops.print() << "\n";
MemOpVisitor memops; MemOpVisitor memops;
method->accept(&memops); method->accept(&memops);
cout << white("MEMOPS\n") << memops.print() << "\n";
std::cout << white("-------------------------\n")
<< yellow("method " + method->name()) << "\n"
<< white("-------------------------\n")
<< white("FLOPS\n") << flops.print() << "\n"
<< white("MEMOPS\n") << memops.print() << "\n";
} }
} }
} }
modules.push_back(m.module_name()); modules.push_back({mod, prefix});
} }
catch (io::bulkio_error& e) { catch (io::bulkio_error& e) {
return report_error(e.what()); return report_error(e.what());
...@@ -297,27 +290,25 @@ int main(int argc, char **argv) { ...@@ -297,27 +290,25 @@ int main(int argc, char **argv) {
} }
if (!opt.catalogue.empty()) { if (!opt.catalogue.empty()) {
const auto prefix = std::regex_replace(popt.cpp_namespace, std::regex{"::"}, "_"); const auto ns = std::regex_replace(popt.cpp_namespace, std::regex{"::"}, "_");
{ {
std::ofstream out(opt.outprefix + opt.catalogue + "_catalogue.cpp"); std::ofstream out(outdir / (opt.catalogue + "_catalogue.cpp"));
out << "// Automatically generated by modcc\n" out << "// Automatically generated by modcc\n"
"\n" "\n"
"#include <arbor/mechanism_abi.h>\n" "#include <arbor/mechanism_abi.h>\n"
"\n"; "\n";
for (const auto& mod: modules) { for (const auto& [mod, prefix]: modules) out << fmt::format("#include \"{}.hpp\"\n", mod);
out << fmt::format("#include \"{}.hpp\"\n", mod);
}
out << "\n" out << "\n"
"#ifdef STANDALONE\n" "#ifdef STANDALONE\n"
"extern \"C\" {\n" "extern \"C\" {\n"
" [[gnu::visibility(\"default\")]] const void* get_catalogue(int* n) {\n"; " [[gnu::visibility(\"default\")]] const void* get_catalogue(int* n) {\n"
out << fmt::format(" *n = {0};\n" << fmt::format(" *n = {0};\n"
" static arb_mechanism cat[{0}] = {{\n", " static arb_mechanism cat[{0}] = {{\n",
opt.modfiles.size()); opt.modfiles.size());
for (const auto& mod: modules) { for (const auto& [mod, prefix]: modules) {
out << fmt::format(" make_{}_{}(),\n", prefix, mod); out << fmt::format(" make_{}_{}(),\n", ns, mod);
} }
out << " };\n" out << " };\n"
" return (void*)cat;\n" " return (void*)cat;\n"
...@@ -328,14 +319,14 @@ int main(int argc, char **argv) { ...@@ -328,14 +319,14 @@ int main(int argc, char **argv) {
"\n" "\n"
"#include <arbor/mechanism.hpp>\n" "#include <arbor/mechanism.hpp>\n"
"#include <arbor/assert.hpp>\n" "#include <arbor/assert.hpp>\n"
"\n"; "\n"
out << fmt::format("#include \"{0}_catalogue.hpp\"\n" << fmt::format("#include \"{0}_catalogue.hpp\"\n"
"\n" "\n"
"namespace arb {{\n" "namespace arb {{\n"
"mechanism_catalogue build_{0}_catalogue() {{\n" "mechanism_catalogue build_{0}_catalogue() {{\n"
" mechanism_catalogue cat;\n", " mechanism_catalogue cat;\n",
opt.catalogue); opt.catalogue);
for (const auto& mod: modules) { for (const auto& [mod, prefix]: modules) {
out << fmt::format(" {{\n" out << fmt::format(" {{\n"
" auto mech = make_{}_{}();\n" " auto mech = make_{}_{}();\n"
" auto ty = mech.type();\n" " auto ty = mech.type();\n"
...@@ -347,22 +338,21 @@ int main(int argc, char **argv) { ...@@ -347,22 +338,21 @@ int main(int argc, char **argv) {
" if (ic) cat.register_implementation(nm, std::make_unique<arb::mechanism>(ty, *ic));\n" " if (ic) cat.register_implementation(nm, std::make_unique<arb::mechanism>(ty, *ic));\n"
" if (ig) cat.register_implementation(nm, std::make_unique<arb::mechanism>(ty, *ig));\n" " if (ig) cat.register_implementation(nm, std::make_unique<arb::mechanism>(ty, *ig));\n"
" }}\n", " }}\n",
prefix, mod); ns, mod);
} }
out << " return cat;\n" out << " return cat;\n"
"}\n" "}\n"
"\n"; "\n"
out << fmt::format("ARB_ARBOR_API const mechanism_catalogue& global_{0}_catalogue() {{\n" << fmt::format("ARB_ARBOR_API const mechanism_catalogue& global_{0}_catalogue() {{\n"
" static mechanism_catalogue cat = build_{0}_catalogue();\n" " static mechanism_catalogue cat = build_{0}_catalogue();\n"
" return cat;\n" " return cat;\n"
"}}\n", "}}\n",
opt.catalogue); opt.catalogue)
out << "} // namespace arb\n" << "} // namespace arb\n"
"#endif\n"; "#endif\n";
} }
{ {
std::ofstream out(opt.outprefix + opt.catalogue + "_catalogue.hpp"); std::ofstream out(outdir / (opt.catalogue + "_catalogue.hpp"));
out << fmt::format("#pragma once\n" out << fmt::format("#pragma once\n"
"\n" "\n"
"#include <arbor/mechcat.hpp>\n" "#include <arbor/mechcat.hpp>\n"
......
#include <ostream> #include <ostream>
#include <set>
#include <string> #include <string>
#include <regex> #include <regex>
...@@ -15,8 +14,6 @@ ...@@ -15,8 +14,6 @@
#include "io/ostream_wrappers.hpp" #include "io/ostream_wrappers.hpp"
#include "io/prefixbuf.hpp" #include "io/prefixbuf.hpp"
using io::quote;
ARB_LIBMODCC_API std::string build_info_header(const Module& m, const printer_options& opt, bool cpu, bool gpu) { ARB_LIBMODCC_API std::string build_info_header(const Module& m, const printer_options& opt, bool cpu, bool gpu) {
using io::indent; using io::indent;
using io::popindent; using io::popindent;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment