--- /dev/null
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+
+/**
+ * \file program.hpp
+ * \author Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+
+#ifndef __GBE_PROGRAM_HPP__
+#define __GBE_PROGRAM_HPP__
+
+#include "backend/gbe_program.h"
+#include "sys/hash_map.hpp"
+#include <string>
+
+namespace gbe {
+namespace ir {
+
+ class Unit; // Compilation unit. Contains the program to compile
+ class Liveness; // Describes liveness of each ir function register
+ class FunctionDAG; // Describes the instruction dependencies
+
+} /* namespace ir */
+} /* namespace gbe */
+
+namespace gbe {
+
+ struct KernelArgument {
+ gbe_arg_type type; //!< Pointer, structure, regular value?
+ size_t size; //!< Size of each argument
+ };
+
+ /*! Describe a compiled kernel */
+ struct Kernel : public NonCopyable
+ {
+ /*! Create an empty kernel with the given name */
+ Kernel(const std::string &name);
+ /*! Destroy it */
+ virtual ~Kernel(void);
+ /*! Return the instruction stream */
+ virtual const char *getCode(void) const = 0;
+ /*! Return the instruction stream size */
+ virtual size_t getCodeSize(void) const = 0;
+ /*! Get the kernel name */
+ INLINE const char *getName(void) const { return name.c_str(); }
+ /*! Return the number of arguments for the kernel call */
+ INLINE uint32_t getArgNum(void) const { return argNum; }
+ /*! Return the size of the given argument */
+ INLINE uint32_t getArgSize(uint32_t argID) const {
+ if (argID >= argNum)
+ return 0u;
+ else
+ return args[argID].size;
+ }
+ /*! Return the type of the given argument */
+ INLINE gbe_arg_type getArgType(uint32_t argID) const {
+ if (argID >= argNum)
+ return GBE_ARG_INVALID;
+ else
+ return args[argID].type;
+ }
+ protected:
+ friend class Program; //!< Owns the kernels
+ const std::string name; //!< Kernel name
+ KernelArgument *args; //!< Each argument
+ uint32_t argNum; //!< Number of function arguments
+ ir::Liveness *liveness; //!< Used only for the build
+ ir::FunctionDAG *dag; //!< Used only for the build
+ };
+
+ /*! Describe a compiled program */
+ struct Program : public NonCopyable
+ {
+ /*! Create an empty program */
+ Program(void);
+ /*! Destroy the program */
+ virtual ~Program(void);
+ /*! Get the number of kernels in the program */
+ uint32_t getKernelNum(void) const { return kernels.size(); }
+ /*! Get the kernel from its name */
+ Kernel *getKernel(const std::string &name) const {
+ auto it = kernels.find(name);
+ if (it == kernels.end())
+ return NULL;
+ else
+ return it->second;
+ }
+ /*! Get the kernel from its ID */
+ Kernel *getKernel(const uint32_t ID) const {
+ uint32_t currID = 0;
+ Kernel *kernel = NULL;
+ for (auto it = kernels.begin(); it != kernels.end(); ++it) {
+ if (currID == ID) {
+ kernel = it->second;
+ break;
+ }
+ }
+ return kernel;
+ }
+ /*! Build a program from a ir::Unit */
+ bool buildFromUnit(const ir::Unit &unit, std::string &error);
+ /*! Buils a program from a LLVM source code */
+ bool buildFromLLVMFile(const char *fileName, std::string &error);
+ /*! Buils a program from a OCL string */
+ bool buildFromSource(const char *source, std::string &error);
+ /*! Compile a kernel */
+ virtual Kernel *compileKernel(const std::string &name) = 0;
+ protected:
+ /*! Kernels sorted by their name */
+ hash_map<std::string, Kernel*> kernels;
+ };
+
+} /* namespace gbe */
+
+#endif /* __GBE_PROGRAM_HPP__ */
+
#include "backend/gbe_program.h"
#include "backend/sim/program.h"
+#include "backend/sim/program.hpp"
+#include <cstring>
+#include <cstdio>
+#include <fstream>
+#include "dlfcn.h"
namespace gbe {
namespace sim {
+ SimKernel::SimKernel(const std::string &name) :
+ Kernel(name), fn(NULL), handle(NULL) {}
+ SimKernel::~SimKernel(void) { if (this->handle) dlclose(this->handle); }
+
+ SimProgram::SimProgram(void) {}
+ SimProgram::~SimProgram(void) {}
+
+ Kernel *SimProgram::compileKernel(const std::string &name) {
+ SimKernel *kernel = GBE_NEW(SimKernel, name);
+ char srcStr[L_tmpnam+1], libStr[L_tmpnam+1];
+ const std::string srcName = std::string(tmpnam_r(srcStr)) + ".cpp"; // unsecure but we don't care
+ const std::string libName = std::string(tmpnam_r(libStr)) + ".so"; // unsecure but we don't care
+
+ // Output the code first
+ std::ofstream ostream;
+ ostream.open(srcName);
+ ostream << "extern \"C\" void " << name << "() {}" << std::endl;
+ ostream.close();
+
+ // Compile the function
+ std::cout << srcName << " " << libName;
+ std::string compileCmd = "g++ -shared -O3 -o ";
+ compileCmd += libName;
+ compileCmd += " ";
+ compileCmd += srcName;
+ printf(compileCmd.c_str());
+ if (UNLIKELY(system(compileCmd.c_str()) != 0))
+ FATAL("Simulation program compilation failed");
+
+ // Load it and get the function pointer
+ kernel->handle = dlopen(libName.c_str(), RTLD_NOW);
+ if (UNLIKELY(kernel->handle == NULL))
+ FATAL("Failed to open the compiled shared object");
+ kernel->fn = (SimKernelCallBack*) dlsym(kernel->handle, name.c_str());
+ if (UNLIKELY(kernel->fn == NULL))
+ FATAL("Failed to get the symbol from the compiled shared object");
+ return kernel;
+ }
} /* namespace sim */
} /* namespace gen */
- void simSetupCallBacks(void)
- {
-#if 0
- GBEProgramNewFromSource = SimProgramNewFromSource;
- GBEProgramNewFromBinary = SimProgramNewFromBinary;
- GBEProgramNewFromLLVM = SimProgramNewFromLLVM;
- GBEProgramDelete = SimProgramDelete;
- GBEProgramGetKernelNum = SimProgramGetKernelNum;
- GBEProgramGetKernelByName = SimProgramGetKernelByName;
- GBEProgramGetKernel = SimProgramGetKernel;
- GBEKernelGetName = SimKernelGetName;
- GBEKernelGetCode = SimKernelGetCode;
- GBEKernelGetCodeSize = SimKernelGetCodeSize;
- GBEKernelGetArgNum = SimKernelGetArgNum;
- GBEKernelGetArgSize = SimKernelGetArgSize;
- GBEKernelGetArgType = SimKernelGetArgType;
- GBEKernelGetSIMDWidth = SimKernelGetSIMDWidth;
- GBEKernelGetRequiredWorkGroupSize = SimKernelGetRequiredWorkGroupSize;
-#endif
+static gbe_program SimProgramNewFromSource(const char *source) {
+ NOT_IMPLEMENTED;
+ return NULL;
+}
+
+static gbe_program SimProgramNewFromBinary(const char *binary, size_t size) {
+ NOT_IMPLEMENTED;
+ return NULL;
+}
+
+static gbe_program SimProgramNewFromLLVM(const char *fileName,
+ size_t stringSize,
+ char *err,
+ size_t *errSize)
+{
+ using namespace gbe::sim;
+ SimProgram *program = GBE_NEW(SimProgram);
+ std::string error;
+
+ // Try to compile the program
+ if (program->buildFromLLVMFile(fileName, error) == false) {
+ if (err != NULL && errSize != NULL && stringSize > 0u) {
+ const size_t msgSize = std::min(error.size(), stringSize-1u);
+ std::memcpy(err, error.c_str(), msgSize);
+ *errSize = error.size();
+ }
+ GBE_DELETE(program);
+ return NULL;
}
+ // Everything run fine
+ return (gbe_program) program;
+}
+
+void simSetupCallBacks(void)
+{
+ gbe_program_new_from_source = SimProgramNewFromSource;
+ gbe_program_new_from_binary = SimProgramNewFromBinary;
+ gbe_program_new_from_llvm = SimProgramNewFromLLVM;
+}
+
--- /dev/null
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+
+/**
+ * \file program.hpp
+ * \author Benjamin Segovia <benjamin.segovia@intel.com>
+ */
+
+#ifndef __GBE_SIM_PROGRAM_HPP__
+#define __GBE_SIM_PROGRAM_HPP__
+
+#include "backend/gbe_program.h"
+#include "backend/gbe_program.hpp"
+#include "backend/gen/brw_structs.h"
+
+namespace gbe {
+namespace sim {
+
+ /*! We basically create one real C function for each */
+ typedef void (SimKernelCallBack)();
+
+ /*! Describe a compiled kernel */
+ struct SimKernel : public Kernel
+ {
+ /*! Create an empty kernel with the given name */
+ SimKernel(const std::string &name);
+ /*! Destroy it */
+ virtual ~SimKernel(void);
+ /*! Implements base class */
+ virtual const char *getCode(void) const { return (const char*) fn; }
+ /*! Implements base class */
+ virtual size_t getCodeSize(void) const { return sizeof(fn); }
+ SimKernelCallBack *fn; //!< Function that runs the code
+ void *handle; //!< dlopen / dlclose / dlsym handle
+ GBE_STRUCT(SimKernel); //!< Use gbe allocators
+ };
+
+ /*! Describe a compiled program */
+ struct SimProgram : public Program
+ {
+ /*! Create an empty program */
+ SimProgram(void);
+ /*! Destroy the program */
+ virtual ~SimProgram(void);
+ /*! Implements base class */
+ virtual Kernel *compileKernel(const std::string &name);
+ GBE_STRUCT(SimProgram); //!< Use gbe allocators
+ };
+
+} /* namespace sim */
+} /* namespace gbe */
+
+#endif /* __GBE_SIM_PROGRAM_HPP__ */
+