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 #include "opencl_backend.h" 27 28 29 /* 30 OpenCLBuffer 31 */ 32 33 OpenCLBackend::OpenCLBuffer::OpenCLBuffer(Backend *backend, Arg_s *arg, BufferState_s *bufferState) 34 : Backend::Buffer(backend, arg, bufferState) { 35 cl_int status; 36 OpenCLBackend * openclBackend = dynamic_cast<OpenCLBackend *>(backend); 37 clMem = clCreateBuffer( 38 openclBackend->context, 39 CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE, 40 bufferState->length,// arg->value.buffer.sizeInBytes, 41 arg->value.buffer.memorySegment, 42 &status); 43 44 if (status != CL_SUCCESS) { 45 std::cerr << OpenCLBackend::errorMsg(status) << std::endl; 46 exit(1); 47 } 48 bufferState->vendorPtr = static_cast<void *>(this); 49 if (openclBackend->openclConfig.traceCopies){ 50 std::cout << "created buffer for arg idx "<< arg->idx << std::endl; 51 } 52 53 } 54 55 bool OpenCLBackend::OpenCLBuffer::shouldCopyToDevice( Arg_s *arg){ 56 //std::cout << "shouldCopyToDevice( Arg_s *arg)" <<std::endl; 57 // std::cout <<std::hex; 58 //// std::cout << "arg=="<<((long) arg) <<std::endl; 59 // std::cout << "arg->idx=="<<arg->idx <<std::endl; 60 // std::cout << "bufferState=="<<((long) bufferState) <<std::endl; 61 // std::cout << "kernel=="<<((long) kernel) <<std::endl; 62 // std::cout << "kernel->name=="<<kernel->name <<std::endl; 63 // std::cout << "kernel->program=="<<((long) kernel->program) <<std::endl; 64 // std::cout << "kernel->program->backend=="<<((long) kernel->program->backend) <<std::endl; 65 // std::cout <<std::dec; 66 OpenCLBackend * openclBackend = dynamic_cast<OpenCLBackend *>(backend); 67 68 69 bool kernelReadsFromThisArg = (arg->value.buffer.access==RW_BYTE) || (arg->value.buffer.access==RO_BYTE); 70 bool isAlwaysCopyingOrNewStateOrHostOwned = 71 openclBackend->openclConfig.alwaysCopy 72 || (bufferState->state == BufferState_s::NEW_STATE) 73 || ((bufferState->state == BufferState_s::HOST_OWNED)); 74 75 if (openclBackend->openclConfig.showWhy){ 76 std::cout<< 77 "config.alwaysCopy="<<openclBackend->openclConfig.alwaysCopy 78 << " | arg.RW="<<(arg->value.buffer.access==RW_BYTE) 79 << " | arg.RO="<<(arg->value.buffer.access==RO_BYTE) 80 << " | kernel.needsToRead="<< kernelReadsFromThisArg 81 << " | Buffer state = "<< BufferState_s::stateNames[bufferState->state] 82 <<" so " 83 ; 84 } 85 return isAlwaysCopyingOrNewStateOrHostOwned; 86 } 87 bool OpenCLBackend::OpenCLBuffer::shouldCopyFromDevice(Arg_s *arg){ 88 OpenCLBackend * openclBackend = dynamic_cast<OpenCLBackend *>(backend); 89 bool kernelWroteToThisArg = (arg->value.buffer.access==WO_BYTE) | (arg->value.buffer.access==RW_BYTE); 90 if (openclBackend->openclConfig.showWhy){ 91 std::cout<< 92 "config.alwaysCopy="<<openclBackend->openclConfig.alwaysCopy 93 << " | arg.WO="<<(arg->value.buffer.access==WO_BYTE) 94 << " | arg.RW="<<(arg->value.buffer.access==RW_BYTE) 95 << " | kernel.wroteToThisArg="<< kernelWroteToThisArg 96 << "Buffer state = "<< BufferState_s::stateNames[bufferState->state] 97 <<" so " ; 98 } 99 return openclBackend->openclConfig.alwaysCopy; 100 } 101 102 103 void OpenCLBackend::OpenCLBuffer::copyToDevice() { 104 // OpenCLKernel *openclKernel = dynamic_cast<OpenCLKernel *>(kernel); 105 OpenCLBackend *openclBackend = dynamic_cast<OpenCLBackend *>(backend); 106 // std::cout << "copyTo(" <<std::hex << (long) arg->value.buffer.memorySegment << "," << std::dec<< bufferState->length <<")"<<std::endl; 107 108 cl_int status = clEnqueueWriteBuffer( 109 openclBackend->openclQueue.command_queue, 110 clMem, 111 CL_FALSE, 112 0, 113 bufferState->length, // arg->value.buffer.sizeInBytes, 114 arg->value.buffer.memorySegment, 115 openclBackend->openclQueue.eventc, 116 openclBackend->openclQueue.eventListPtr(), 117 openclBackend->openclQueue.nextEventPtr() 118 ); 119 openclBackend->openclQueue.markAsCopyToDeviceAndInc(arg->idx); 120 121 if (status != CL_SUCCESS) { 122 std::cerr << OpenCLBackend::errorMsg(status) << std::endl; 123 exit(1); 124 } 125 if(openclBackend->openclConfig.traceCopies){ 126 std::cout << "enqueued buffer for arg idx " << arg->idx << " in OpenCLBuffer::copyToDevice()" << std::endl; 127 } 128 } 129 130 void OpenCLBackend::OpenCLBuffer::copyFromDevice() { 131 // OpenCLKernel * openclKernel = dynamic_cast<OpenCLKernel *>(kernel); 132 OpenCLBackend * openclBackend = dynamic_cast<OpenCLBackend *>(backend); 133 // std::cout << "copyFrom(" <<std::hex << (long) arg->value.buffer.memorySegment << "," << std::dec<< bufferState->length <<")"<<std::endl; 134 135 cl_int status = clEnqueueReadBuffer( 136 openclBackend->openclQueue.command_queue, 137 clMem, 138 CL_FALSE, 139 0, 140 bufferState->length,//arg->value.buffer.sizeInBytes, 141 arg->value.buffer.memorySegment, 142 openclBackend->openclQueue.eventc, 143 openclBackend->openclQueue.eventListPtr(), 144 openclBackend->openclQueue.nextEventPtr() 145 ); 146 openclBackend->openclQueue.markAsCopyFromDeviceAndInc(arg->idx); 147 if (status != CL_SUCCESS) { 148 std::cerr << OpenCLBackend::errorMsg(status) << std::endl; 149 exit(1); 150 } 151 if(openclBackend->openclConfig.traceCopies){ 152 std::cout << "enqueued buffer for arg idx " << arg->idx << " in OpenCLBuffer::copyFromDevice()" << std::endl; 153 } 154 } 155 156 OpenCLBackend::OpenCLBuffer::~OpenCLBuffer() { 157 clReleaseMemObject(clMem); 158 } 159 160