diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..580fb04 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2011-2012 Gabriel Hjort Blindell +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OF THIS SOFTWARE NOR THE COPYRIGHT +HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..99d548d --- /dev/null +++ b/Makefile @@ -0,0 +1,72 @@ +# Copyright (c) 2011-2012 Gabriel Hjort Blindell +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OF THIS SOFTWARE NOR THE +# COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +unexport + +SEP = "==============================" +export PREBUILDMSG = "$(SEP)\n Building % module...\n" +export POSTBUILDMSG = " Done.\n$(SEP)\n\n" +export ITEMBUILDMSG = " * %\n" +export PRELINKMSG = "$(SEP)\n Linking...\n" +export POSTLINKMSG = $(POSTBUILDMSG) +export ITEMLINKMSG = " * %\n" +export PREDOCSMSG = "$(SEP)" +export POSTDOCSMSG = " Done.\n$(SEP)\n\n" +export PARTDOCSMSG = "%...\n" + +export TARGET = bin +export TARGETPATH = $(CURDIR)/$(TARGET) +export DOMAKE = $(MAKE) --no-print-directory +TESTMODELSPATH = testmodels +TESTBENCHPATH = testbench + +build: $(TARGET) + @$(DOMAKE) -C ./source + +test_environment: clean build + cp $(TESTMODELSPATH)/*.* $(TARGET) + cp $(TESTBENCHPATH)/*.* $(TARGET) + +docs: + @$(DOMAKE) -C ./source docs + +help: + @printf "Usage:" + @printf + @printf "make: same as 'make build'" + @printf "make build: builds the entire f2cc" + @printf "make docs: generates the Doxygen API" + +$(TARGET): + @mkdir -p $(TARGET) + +clean: preclean doclean + @printf $(POSTBUILDMSG) + +preclean: + @printf $(subst Building % module,Cleaning modules,$(PREBUILDMSG)) + +doclean: + @rm -rf $(TARGET) + +.PHONY: clean preclean doclean all $(TARGET) docs diff --git a/source/Makefile b/source/Makefile new file mode 100644 index 0000000..44ea1af --- /dev/null +++ b/source/Makefile @@ -0,0 +1,83 @@ +# Copyright (c) 2011-2012 Gabriel Hjort Blindell +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OF THIS SOFTWARE NOR THE +# COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +SRCFILES = f2cc.cpp +OBJECTS = $(addprefix $(OBJPATH)/, \ + $(addsuffix .o, $(basename $(SRCFILES))) \ + ) +EXEC_ = f2cc +EXEC = $(addprefix $(TARGETPATH)/, $(EXEC_)) + +DEPENDENCIES = ticpp exceptions tools logger forsyde language frontend config \ + synthesizer +DEPOBJECTS = $(addprefix $(OBJPATH)/, \ + $(addsuffix /*.o, $(basename $(DEPENDENCIES))) \ + ) + +export LIBPATH = $(TARGETPATH)/lib +export OBJPATH = $(TARGETPATH)/obj + +export CC = g++ +export CCFLAGS = -Wall \ + -DSVNVERSION="\"`svnversion`\"" +export LDFLAGS = +export AR = ar +export ARFLAGS = crf + +all: $(LIBPATH) $(OBJPATH) link + +link: build prelink + @printf $(subst %,$(EXEC_),$(ITEMLINKMSG)) + @$(CC) $(CCFLAGS) $(LDFLAGS) -o $(TARGETPATH)/$(EXEC_) $(OBJECTS) \ + $(DEPOBJECTS) + @printf $(POSTLINKMSG) + +prelink: + @printf $(PRELINKMSG) + +build: $(DEPENDENCIES) prebuild $(OBJECTS) + @printf $(POSTBUILDMSG) + +prebuild: + @printf $(subst %,core,$(PREBUILDMSG)) + +$(LIBPATH) $(OBJPATH): + @mkdir -p $@ + +$(DEPENDENCIES): + @$(DOMAKE) -C ./$@ + +$(OBJPATH)/%.o: %.cpp + @printf $(subst %,$<,$(ITEMBUILDMSG)) + @$(CC) $(CCFLAGS) -o $@ -c $< + +docs: predocs + @printf $(subst %,Building API,$(PARTDOCSMSG)) + @doxygen dox + @printf $(POSTDOCSMSG) + @cat dox.log + +predocs: + @printf $(PREDOCSMSG) + +.PHONY: prebuild $(LIBPATH) $(OBJPATH) docs predocs $(DEPENDENCIES) diff --git a/source/config/Makefile b/source/config/Makefile new file mode 100644 index 0000000..d772dfe --- /dev/null +++ b/source/config/Makefile @@ -0,0 +1,44 @@ +# Copyright (c) 2011-2012 Gabriel Hjort Blindell +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OF THIS SOFTWARE NOR THE +# COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +MODULE = config +SRCFILES = config.cpp +THISOBJPATH = $(OBJPATH)/$(MODULE) +OBJECTS = $(addprefix $(THISOBJPATH)/, \ + $(addsuffix .o, $(basename $(SRCFILES))) \ + ) + +build: $(THISOBJPATH) prebuild $(OBJECTS) + @printf $(POSTBUILDMSG) + +$(THISOBJPATH): + @mkdir -p $@ + +prebuild: + @printf $(subst %,$(MODULE),$(PREBUILDMSG)) + +$(THISOBJPATH)/%.o: %.cpp %.h + @printf $(subst %,$<,$(ITEMBUILDMSG)) + @$(CC) $(CCFLAGS) -o $@ -c $< + +.PHONY: prebuild $(THISOBJPATH) diff --git a/source/config/config.cpp b/source/config/config.cpp new file mode 100644 index 0000000..8fbaff7 --- /dev/null +++ b/source/config/config.cpp @@ -0,0 +1,438 @@ +/* + * Copyright (c) 2011-2012 Gabriel Hjort Blindell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OF THIS SOFTWARE NOR THE + * COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "../tools/tools.h" +#include "../exceptions/invalidargumentexception.h" +#include + +using namespace f2cc; +using std::string; +using std::vector; + +Config::Config() throw() { + setDefaults(); +} + +Config::Config(int argc, const char** argv) throw(InvalidArgumentException, + InvalidFormatException) { + setDefaults(); + setFromCommandLine(argc, argv); +} + +Config::~Config() throw() {} + +bool Config::doPrintHelpMenu() const throw() { + return do_print_help_; +} + +string Config::getHelpMenu() const throw() { + const size_t maximum_line_length = 80; + string part; + string str = string() + + "Developer: Gabriel Hjort Blindell \n" + + "KTH - Royal Institute of Technology, Stockholm, Sweden\n" + + "Copyright (c) 2011-2012\n" + + "\n"; + + part = "This tool is part of the ForSyDe framework for synthesizing " + "programs modeled at a high level of abstraction into compilable C or " + "CUDA C code. The synthesis process is semantic-preserving which means " + "that a model which is proven to be correct will also yield correct C " + "or CUDA C code.\n" + "\n" + "The tool expects the model to be represented as a GraphML file. " + "Currently, the tool supports the following processes:\n"; + tools::breakLongLines(part, maximum_line_length, 0); + part += "" + " * MapSY\n" + " * ParallelMapSY\n" + " * ZipWithNSY\n" + " * UnzipxSY\n" + " * ZipxSY\n" + " * DelaySY\n" + "\n"; + str += part; + + part = "f2cc accepts the following command options:\n"; + str += part; + + size_t indents = 6; + + part = " -o FILE, --output-file=FILE\n" + " Specifies the output files. Default file names are the same as " + "the input file but with different file extensions." + "\n\n"; + tools::breakLongLines(part, maximum_line_length, indents); + str += part; + + part = " -tp PLATFORM, --target-platform=PLATFORM\n" + " Specifies the target platform which will affect the kind of " + "code generated. Valid options are C and CUDA." + "\n\n"; + tools::breakLongLines(part, maximum_line_length, indents); + str += part; + + part = " -no-pc, --no-process-coalescing\n" + " CUDA ONLY. Specifies that the tool should not coalesce " + "processes, even " + "when it is possible to do so for the given input model." + "\n\n"; + tools::breakLongLines(part, maximum_line_length, indents); + str += part; + + part = " -use-sm-i, --use-shared-memory-for-input\n" + " CUDA ONLY. Specifies that the synthesized code should make use " + "of shared memory for the input data." + "\n\n"; + tools::breakLongLines(part, maximum_line_length, indents); + str += part; + + part = " -lf FILE, --log-file=FILE\n" + " Specifies the path to the log file. Default setting is " + "output.log." + "\n\n"; + tools::breakLongLines(part, maximum_line_length, indents); + str += part; + + part = " -ll=LEVEL, --log-file=LEVEL\n" + " Specifies the log level. This affects how verbose the tool is " + "in its logging and prompt output. Valid options are CRITICAL, ERROR, " + "WARNING, INFO, and DEBUG. Default setting is INFO." + "\n\n"; + tools::breakLongLines(part, maximum_line_length, indents); + str += part; + + part = " -v, --version\n" + " Prints the version." + "\n\n"; + tools::breakLongLines(part, maximum_line_length, indents); + str += part; + + part = " -h, --help\n" + " Prints this menu." + "\n\n"; + tools::breakLongLines(part, maximum_line_length, indents); + str += part; + + part = "Report bugs to: \n"; + str += part; + + return str; +} + +bool Config::doPrintVersion() const throw() { + return do_print_version_; +} + +string Config::getInputFile() const throw() { + return input_file_; +} + +void Config::setInputFile(string file) throw() { + input_file_ = file; +} + +string Config::getHeaderOutputFile() const throw() { + return tools::getFileName(output_file_) + ".h"; +} + +string Config::getImplementationOutputFile() const throw() { + return output_file_; +} + +void Config::setOutputFile(string file) throw() { + output_file_ = file; +} + +string Config::getLogFile() const throw() { + return log_file_; +} + +void Config::setLogFile(string file) throw() { + log_file_ = file; +} + +Logger::LogLevel Config::getLogLevel() const throw() { + return log_level_; +} + +void Config::setLogLevel(Logger::LogLevel level) throw() { + log_level_ = level; +} + +void Config::setDefaults() throw() { + do_print_help_ = false; + do_print_version_ = false; + log_file_ = "output.log"; + log_level_ = Logger::INFO; + do_data_parallel_process_coalescing_ = true; + use_shared_memory_for_input_ = false; + use_shared_memory_for_output_ = false; + target_platform_ = Config::CUDA; +} + +void Config::setFromCommandLine(int argc, const char** argv) + throw(InvalidArgumentException, InvalidFormatException) { + if (!argv) { + THROW_EXCEPTION(InvalidArgumentException, "\"argv\" must not be NULL"); + } + + try { + bool found_input_file = false; + bool is_output_file_set = false; + for (int index = 1; index < argc; ++index) { + string current_str = argv[index]; + bool isLast = index == argc - 1; + if (!isOption(current_str) && isLast) { + input_file_ = current_str; + found_input_file = true; + } + else { + if (!isOption(current_str)) { + THROW_EXCEPTION(InvalidFormatException, string("\"") + + current_str + "\" is not an option"); + } + + // Extract option (and argument if it is composite) from string + string option, argument; + if (isCompositeOption(current_str)) { + vector splitted = tools::split(current_str, '='); + if (splitted.size() > 2) { + THROW_EXCEPTION(InvalidFormatException, + string("Multiple assignments ('=') on ") + + "option \"" + splitted[0] + "\""); + } + option = splitted[0]; + if (splitted.size() == 2) argument = splitted[1]; + } + else { + option = current_str; + } + + // Set boolean flags + bool isNextStrOption = isLast ? false + : isOption(argv[index + 1]); + bool has_argument; + if (isCompositeOption(option)) { + has_argument = argument.size() > 0; + } + else { + has_argument = !isLast && !isNextStrOption; + } + + // Analyze option + if (option == "-h" || option == "--help") { + do_print_help_ = true; + } + else if (option == "-v" || option == "--version") { + do_print_version_ = true; + } + else if (option == "-ll" || option == "--log-level") { + if (has_argument) { + if (!isCompositeOption(option)) { + argument = argv[index + 1]; + ++index; + } + } + else { + THROW_EXCEPTION(InvalidFormatException, + "No log level argument"); + } + + try { + tools::toUpperCase(argument); + log_level_ = Logger::stringToLogLevel(argument); + } + catch (InvalidArgumentException& ex) { + THROW_EXCEPTION(InvalidFormatException, + ex.getMessage()); + } + } + else if (option == "-lf" || option == "--log-file") { + if (has_argument) { + if (!isCompositeOption(option)) { + argument = argv[index + 1]; + ++index; + } + } + else { + THROW_EXCEPTION(InvalidFormatException, + "No log file argument"); + } + + log_file_ = argument; + } + else if (option == "-tp" || option == "--target-platform") { + if (has_argument) { + if (!isCompositeOption(option)) { + argument = argv[index + 1]; + ++index; + } + } + else { + THROW_EXCEPTION(InvalidFormatException, + "No target platform argument"); + } + + tools::toLowerCase(argument); + if (argument == "c") { + target_platform_ = Config::C; + } + else if (argument == "cuda") { + target_platform_ = Config::CUDA; + } + else { + THROW_EXCEPTION(InvalidFormatException, + "Invalid target platform argument"); + } + } + else if (option == "-o" || option == "--output-file") { + if (has_argument) { + if (!isCompositeOption(option)) { + argument = argv[index + 1]; + ++index; + } + } + else { + THROW_EXCEPTION(InvalidFormatException, + "No output file argument"); + } + + output_file_ = argument; + is_output_file_set = true; + } + else if (option == "-no-pc" + || option == "--no-process-coalescing") { + do_data_parallel_process_coalescing_ = false; + } + else if (option == "-use-sm-i" + || option == "--use-shared-memory-for-input") { + use_shared_memory_for_input_ = true; + } + /* + // Usage of shared memory for output data is not yet supported + else if (option == "-use-sm-o" + || option == "--use-shared-memory-for-output") { + use_shared_memory_for_output_ = true; + } + */ + else { + THROW_EXCEPTION(InvalidFormatException, + string("Unknown command option \"") + option + + "\""); + } + } + } + + if (!found_input_file && !do_print_help_ && !do_print_version_) { + THROW_EXCEPTION(InvalidFormatException, "No input file"); + } + if (!is_output_file_set) { + output_file_ = tools::getFileName(input_file_); + switch (target_platform_) { + case C: { + output_file_ += ".c"; + break; + } + case CUDA: { + output_file_ += ".cu"; + break; + } + } + } + } + catch(InvalidFormatException& ex) { + THROW_EXCEPTION(InvalidFormatException, ex.getMessage() + + "\nRerun program with option \"-h\" for help menu"); + } +} + +bool Config::doDataParallelProcessCoalesing() const throw() { + return do_data_parallel_process_coalescing_; +} + +void Config::setDoDataParallelProcessCoalesing(bool setting) throw() { + do_data_parallel_process_coalescing_ = setting; +} + +bool Config::useSharedMemoryForInput() const throw() { + return use_shared_memory_for_input_; +} + +void Config::setUseSharedMemoryForInput(bool setting) throw() { + use_shared_memory_for_input_ = setting; +} + +bool Config::useSharedMemoryForOutput() const throw() { + return use_shared_memory_for_output_; +} + +void Config::setUseSharedMemoryForOutput(bool setting) throw() { + use_shared_memory_for_output_ = setting; +} + +Config::TargetPlatform Config::getTargetPlatform() const throw() { + return target_platform_; +} + +void Config::setTargetPlatform(Config::TargetPlatform platform) throw() { + target_platform_ = platform; +} + +bool Config::isOption(const string& str) const throw() { + return str.substr(0, 1) == "-"; +} + +bool Config::isCompositeOption(const string& str) const throw() { + if (str.length() < 2) return false; + return str.substr(0, 2) == "--"; +} + +string Config::getVersion() throw() { + return "0.1"; +} + +string Config::getSvnRevision() throw() { +#ifdef SVNVERSION + string svn_str(SVNVERSION); + + // If the SVN revision string consists of two numbers, remove the first + size_t colon_pos = svn_str.find(':'); + if (colon_pos != string::npos) { + svn_str = svn_str.erase(0, colon_pos + 1); + } + + // Remove trailing no-numeric characters, if any + while (svn_str.length() > 0 + && !tools::isNumeric(svn_str.substr(svn_str.length() - 1))) { + svn_str.erase(svn_str.length() - 1); + } + + return svn_str; +#else + return "Unknown"; +#endif +} diff --git a/source/config/config.h b/source/config/config.h new file mode 100644 index 0000000..8375498 --- /dev/null +++ b/source/config/config.h @@ -0,0 +1,363 @@ +/* + * Copyright (c) 2011-2012 Gabriel Hjort Blindell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OF THIS SOFTWARE NOR THE + * COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef F2CC_SOURCE_CONFIG_CONFIG_H_ +#define F2CC_SOURCE_CONFIG_CONFIG_H_ + +/** + * @file + * @author Gabriel Hjort Blindell + * @version 0.1 + * + * @brief Defines a class for containing program settings. + */ + +#include "../logger/logger.h" +#include "../exceptions/invalidformatexception.h" +#include "../exceptions/invalidargumentexception.h" +#include + +namespace f2cc { + +/** + * @brief Defines a class for containing program settings. + * + * The \c Config class provides methods for accessing the program-related + * settings. The settings are usually given through the command-line and there + * is a special constructor for parsing the command-line into a \c Config + * object. + */ +class Config { + public: + /** + * Denotes the target platform to which the ForSyDe model is to be + * synthesized. + */ + enum TargetPlatform { + /** + * Sequential C code, where no processes are executed in parallel. + */ + C, + + /** + * Sequential C code annotaded with CUDA directives, where data parallel + * processes are executed in parallel. + */ + CUDA + }; + + /** + * Creates a configuration with default settings. + */ + Config() throw(); + + /** + * Creates a configuration using settings from the command + * line. Non-specified settings use default values. + * + * @param argc + * Number of arguments. + * @param argv + * Array of char arrays. + * @throws InvalidArgumentException + * When \c argc is less than 1 or when \c argv is NULL. + * @throws InvalidFormatException + * When the command line contains errors. + */ + Config(int argc, const char** argv) + throw(InvalidArgumentException, InvalidFormatException); + + /** + * Destroys this configuration. + */ + ~Config() throw(); + + /** + * Gets whether the user requested the help menu be printed. Default value + * is \c false. + * + * @returns \c true if the help menu should be printed. + */ + bool doPrintHelpMenu() const throw(); + + /** + * Gets whether the user requested the version be printed. Default value is + * \c false. + * + * @returns \c true if the help menu should be printed. + */ + bool doPrintVersion() const throw(); + + /** + * Gets the help menu. + * + * @returns Help menu. + */ + std::string getHelpMenu() const throw(); + + /** + * Gets the input file path. Default value is empty string. + * + * @returns Input file path. + */ + std::string getInputFile() const throw(); + + /** + * Sets the input file path. + * + * @param file + * Input file path. + */ + void setInputFile(std::string file) throw(); + + /** + * Gets the header output file path. Default value is the same name + * as the input file but with a different extension. + * + * @returns Header output file path. + */ + std::string getHeaderOutputFile() const throw(); + + /** + * Gets the implementation output file path. Default value is the same name + * as the input file but with a different extension. + * + * @returns Implementation output file path. + */ + std::string getImplementationOutputFile() const throw(); + + /** + * Sets the output file path. + * + * @param file + * Output file path. + */ + void setOutputFile(std::string file) throw(); + + /** + * Gets the log file path. Default file path is "output.log". + * + * @returns Log file path + */ + std::string getLogFile() const throw(); + + /** + * Sets the log file path + * + * @param file + * Log file path. + */ + void setLogFile(std::string file) throw(); + + /** + * Gets the log level. Default level is Logger::INFO. + * + * @returns Log level. + */ + Logger::LogLevel getLogLevel() const throw(); + + /** + * Sets the log level. + * + * @param level + * Log level. + */ + void setLogLevel(Logger::LogLevel level) throw(); + + /** + * Gets whether data parallel processes in the model should be coalesced. + * Default setting is \c true. + * + * @returns \c true if such action should be performed. + */ + bool doDataParallelProcessCoalesing() const throw(); + + /** + * Sets whether data parallel processes in the model should be coalesced. + * + * @param setting + * New setting. + */ + void setDoDataParallelProcessCoalesing(bool setting) throw(); + + /** + * Gets whether the shared memory on the device shall be used for input data + * in the synthesized CUDA code. Default setting is \c false. + * + * @returns \c true if the shared memory is to be used. + */ + bool useSharedMemoryForInput() const throw(); + + /** + * Sets whether the shared memory should be used for input data. + * + * @param setting + * New setting. + */ + void setUseSharedMemoryForInput(bool setting) throw(); + + /** + * Same as useSharedMemoryForInput() but for output data. + * + * @returns \c true if the shared memory is to be used. + */ + bool useSharedMemoryForOutput() const throw(); + + /** + * Same as setUseSharedMemoryForInput(bool) but for output data. + * + * @param setting + * New setting. + */ + void setUseSharedMemoryForOutput(bool setting) throw(); + + /** + * Gets the target platform. Default platform is Config::CUDA. + * + * @returns Target platform. + */ + TargetPlatform getTargetPlatform() const throw(); + + /** + * Sets the target platform. + * + * @param platform + * Target platform. + */ + void setTargetPlatform(TargetPlatform platform) throw(); + + /** + * Parses the command line and sets its specified settings to this + * configuration. + * + * @param argc + * Number of arguments. + * @param argv + * Array of char arrays. + * @throws InvalidArgumentException + * When \c argc is less than 1 or when \c argv is NULL. + * @throws InvalidFormatException + * When the command line contains errors. + */ + void setFromCommandLine(int argc, const char** argv) + throw(InvalidArgumentException, InvalidFormatException); + + /** + * Gets the program version. + * + * @returns Program version. + */ + static std::string getVersion() throw(); + + /** + * Gets the SVN revision number. + * + * @returns SVN revision. + */ + static std::string getSvnRevision() throw(); + + private: + /** + * Sets all settings to default values. + */ + void setDefaults() throw(); + + /** + * Checks whether a string is an option. + * + * @param str + * String to check. + * @returns \c true if the string starts with a '-'. + */ + bool isOption(const std::string& str) const throw(); + + /** + * Checks whether a string is a composite option, which is of the format + * "--