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 <sys/wait.h>
27 #include <chrono>
28 #include <thread>
29 #include "cuda_backend.h"
30 
31 /*
32 //http://mercury.pr.erau.edu/~siewerts/extra/code/digital-media/CUDA/cuda_work/samples/0_Simple/matrixMulDrv/matrixMulDrv.cpp
33  */
34 CudaBackend::CudaBuffer::CudaBuffer(Backend *backend,  BufferState *bufferState)
35         : Buffer(backend, bufferState), devicePtr() {
36 
37     auto cudaBackend = dynamic_cast<CudaBackend*>(backend);
38     if (cudaBackend->config->traceCalls) {
39         std::cout << "CudaBuffer()" << std::endl;
40     }
41 
42     WHERE{.f=__FILE__, .l=__LINE__,
43             .e=cuMemAlloc(&devicePtr, (size_t) bufferState->length),
44             .t="cuMemAlloc"
45     }.report();
46     if (cudaBackend->config->traceCalls) {
47         std::cout << "devptr=" << std::hex<<  (long)devicePtr << "stream=" <<dynamic_cast<CudaQueue *>(backend->queue)->cuStream <<std::dec <<std::endl;
48     }
49     // Attempt to solve healing brush crash (where thread for creation of stream differs from the one where we are copying).
50   //  WHERE{.f=__FILE__, .l=__LINE__,
51     //        .e=cuStreamAttachMemAsync(dynamic_cast<CudaQueue *>(backend->queue)->cuStream, devicePtr, 0,  CU_MEM_ATTACH_GLOBAL),
52     //        .t="cuStreamAttachMemAsync"
53    // }.report();
54 
55   bufferState->vendorPtr= static_cast<void *>(this);
56 }
57 
58 CudaBackend::CudaBuffer::~CudaBuffer() {
59     auto cudaBackend = dynamic_cast<CudaBackend*>(backend);
60     if (cudaBackend->config->traceCalls) {
61         std::thread::id thread_id = std::this_thread::get_id();
62 
63         std::cout << "~CudaBuffer()"<< "devptr =" << std::hex << (long) devicePtr << std::dec
64                 << " thread=" <<thread_id
65         <<std::endl;
66     }
67     WHERE{.f=__FILE__, .l=__LINE__,
68             .e=cuMemFree(devicePtr),
69             .t="cuMemFree"
70     }.report();
71     bufferState->vendorPtr= nullptr;
72 }
73 
74