1 /* 2 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #pragma once 27 28 #include <iostream> 29 #include <map> 30 #include <vector> 31 #include <cstdio> 32 #include <cstring> 33 #include <unistd.h> 34 #include <sys/time.h> 35 #include <iostream> 36 #include <iomanip> 37 #include <bitset> 38 #include <stack> 39 40 #ifdef __APPLE__ 41 #define LongUnsignedNewline "%llu\n" 42 #define Size_tNewline "%lu\n" 43 #define LongHexNewline "(0x%llx)\n" 44 #define alignedMalloc(size, alignment) memalign(alignment, size) 45 #define SNPRINTF snprintf 46 #else 47 48 #include <malloc.h> 49 50 #define LongHexNewline "(0x%lx)\n" 51 #define LongUnsignedNewline "%lu\n" 52 #define Size_tNewline "%lu\n" 53 #if defined (_WIN32) 54 #include "windows.h" 55 #define alignedMalloc(size, alignment) _aligned_malloc(size, alignment) 56 #define SNPRINTF _snprintf 57 #else 58 #define alignedMalloc(size, alignment) memalign(alignment, size) 59 #define SNPRINTF snprintf 60 #endif 61 #endif 62 typedef char s8_t; 63 typedef char byte; 64 typedef char boolean; 65 typedef char z1_t; 66 typedef unsigned char u8_t; 67 typedef short s16_t; 68 typedef unsigned short u16_t; 69 typedef unsigned int u32_t; 70 typedef int s32_t; 71 typedef float f32_t; 72 typedef double f64_t; 73 typedef long s64_t; 74 typedef unsigned long u64_t; 75 76 extern void hexdump(void *ptr, int buflen); 77 78 struct Buffer_s { 79 void *memorySegment; // Address of a Buffer/MemorySegment 80 long sizeInBytes; // The size of the memory segment in bytes 81 void *vendorPtr; // The vendor side can reference vendor into 82 u8_t access; // 0=??/1=RO/2=WO/3=RW if this is a buffer 83 u8_t state; // 0=UNKNOWN/1=GPUDIRTY/2=JAVADIRTY 84 } ; 85 86 union Value_u { 87 boolean z1; // 'Z' 88 u8_t s8; // 'B' 89 u16_t u16; // 'C' 90 s16_t s16; // 'S' 91 u16_t x16; // 'C' or 'S" 92 s32_t s32; // 'I' 93 s32_t x32; // 'I' or 'F' 94 f32_t f32; // 'F' 95 f64_t f64; // 'D' 96 s64_t s64; // 'J' 97 s64_t x64; // 'D' or 'J' 98 Buffer_s buffer; // '&' 99 } ; 100 101 struct Arg_s { 102 u32_t idx; // 0..argc 103 u8_t variant; // which variant 'I','Z','S','J','F', '&' implies Buffer/MemorySegment 104 u8_t pad8[8]; 105 Value_u value; 106 u8_t pad6[6]; 107 }; 108 109 struct ArgArray_s { 110 u32_t argc; 111 u8_t pad12[12]; 112 Arg_s argv[0/*argc*/]; 113 // void * vendorPtr; 114 // int schemaLen 115 // char schema[schemaLen] 116 }; 117 118 class ArgSled { 119 private: 120 ArgArray_s *argArray; 121 public: 122 int argc() { 123 return argArray->argc; 124 } 125 126 Arg_s *arg(int n) { 127 Arg_s *a = (argArray->argv + n); 128 return a; 129 } 130 131 void hexdumpArg(int n) { 132 hexdump(arg(n), sizeof(Arg_s)); 133 } 134 135 void dumpArg(int n) { 136 Arg_s *a = arg(n); 137 int idx = (int) a->idx; 138 std::cout << "arg[" << idx << "]"; 139 char variant = (char) a->variant; 140 switch (variant) { 141 case 'F': 142 std::cout << " f32 " << a->value.f32 << std::endl; 143 break; 144 case 'I': 145 std::cout << " s32 " << a->value.s32 << std::endl; 146 break; 147 case 'D': 148 std::cout << " f64 " << a->value.f64 << std::endl; 149 break; 150 case 'J': 151 std::cout << " s64 " << a->value.s64 << std::endl; 152 break; 153 case 'C': 154 std::cout << " u16 " << a->value.u16 << std::endl; 155 break; 156 case 'S': 157 std::cout << " s16 " << a->value.s32 << std::endl; 158 break; 159 case 'Z': 160 std::cout << " z1 " << a->value.z1 << std::endl; 161 break; 162 case '&': 163 std::cout << " buffer {" 164 << " void *address = 0x" << std::hex << (long) a->value.buffer.memorySegment << std::dec 165 << ", long bytesSize= 0x" << std::hex << (long) a->value.buffer.sizeInBytes << std::dec 166 << "}" << std::endl; 167 break; 168 default: 169 std::cout << (char) variant << std::endl; 170 break; 171 } 172 } 173 174 void *vendorPtrPtr() { 175 Arg_s *a = arg(argc()); 176 return (void *) a; 177 } 178 179 int *schemaLenPtr() { 180 int *schemaLenP = (int *) ((char *) vendorPtrPtr() + sizeof(void *)); 181 return schemaLenP; 182 } 183 184 int schemaLen() { 185 return *schemaLenPtr(); 186 } 187 188 char *schema() { 189 int *schemaLenP = ((int *) ((char *) vendorPtrPtr() + sizeof(void *)) + 1); 190 return (char *) schemaLenP; 191 } 192 193 ArgSled(ArgArray_s *argArray) 194 : argArray(argArray) {} 195 }; 196 197 198 class Timer { 199 struct timeval startTV, endTV; 200 public: 201 unsigned long elapsed_us; 202 203 void start() { 204 gettimeofday(&startTV, NULL); 205 } 206 207 unsigned long end() { 208 gettimeofday(&endTV, NULL); 209 elapsed_us = (endTV.tv_sec - startTV.tv_sec) * 1000000; // sec to us 210 elapsed_us += (endTV.tv_usec - startTV.tv_usec); 211 return elapsed_us; 212 } 213 }; 214 215 216 class BuildInfo { 217 public: 218 char *src; 219 char *log; 220 bool ok; 221 222 BuildInfo(char *src, char *log, bool ok) 223 : src(src), log(log), ok(ok) { 224 } 225 226 ~BuildInfo() { 227 if (src) { 228 delete[] src; 229 } 230 if (log) { 231 delete[] log; 232 } 233 } 234 235 }; 236 237 238 //extern "C" void dumpArgArray(void *ptr); 239 240 241 extern void hexdump(void *ptr, int buflen); 242 243 class Sled { 244 public: 245 static void show(std::ostream &out, void *argArray); 246 }; 247 248 249 class NDRange { 250 public: 251 int x; 252 int maxX; 253 }; 254 255 class Backend { 256 public: 257 class Config { 258 public: 259 }; 260 261 class Program { 262 public: 263 class Kernel { 264 public: 265 class Buffer { 266 public: 267 Kernel *kernel; 268 Arg_s *arg; 269 270 virtual void copyToDevice() = 0; 271 272 virtual void copyFromDevice() = 0; 273 274 Buffer(Kernel *kernel, Arg_s *arg) 275 : kernel(kernel), arg(arg) { 276 } 277 278 virtual ~Buffer() {} 279 }; 280 281 char *name;// strduped! 282 283 Program *program; 284 285 virtual long ndrange(void *argArray) = 0; 286 static char *copy(char *name){ 287 size_t len =::strlen(name); 288 char *buf = new char[len+1]; 289 memcpy(buf, name, len); 290 buf[len]='\0'; 291 return buf; 292 } 293 Kernel(Program *program, char *name) 294 : program(program), name(copy(name)) { 295 } 296 297 virtual ~Kernel() { 298 if (name) { 299 delete[] name; 300 } 301 } 302 }; 303 304 public: 305 Backend *backend; 306 BuildInfo *buildInfo; 307 308 virtual long getKernel(int nameLen, char *name) = 0; 309 310 virtual bool programOK() = 0; 311 312 Program(Backend *backend, BuildInfo *buildInfo) 313 : backend(backend), buildInfo(buildInfo) { 314 } 315 316 virtual ~Program() { 317 if (buildInfo != nullptr) { 318 delete buildInfo; 319 } 320 }; 321 322 }; 323 324 Config *config; 325 int configSchemaLen; 326 char *configSchema; 327 328 Backend(Config *config, int configSchemaLen, char *configSchema) 329 : config(config), configSchemaLen(configSchemaLen), configSchema(configSchema) {} 330 331 virtual ~Backend() {}; 332 333 virtual void info() = 0; 334 335 virtual int getMaxComputeUnits() = 0; 336 337 virtual long compileProgram(int len, char *source) = 0; 338 339 340 }; 341 342 extern "C" long getBackend(void *config, int configSchemaLen, char *configSchema); 343 extern "C" void info(long backendHandle); 344 extern "C" int getMaxComputeUnits(long backendHandle); 345 extern "C" long compileProgram(long backendHandle, int len, char *source); 346 extern "C" long getKernel(long programHandle, int len, char *name); 347 extern "C" void releaseBackend(long backendHandle); 348 extern "C" void releaseProgram(long programHandle); 349 extern "C" bool programOK(long programHandle); 350 extern "C" void releaseKernel(long kernelHandle); 351 extern "C" long ndrange(long kernelHandle, void *argArray); 352