summaryrefslogtreecommitdiffstats
path: root/test.c
blob: f9805d8322ab8b03c734904404f66098456e342a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <errno.h>

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include "CL/cl.h"
#include "CL/cl_ext.h"



#define ITERS 1l
#define DATA_SIZE (16384)


#define CL_CHECK_STATUS(error) { \
    if ((error) != CL_SUCCESS) fprintf (stderr, "OpenCL error <%s:%i>: %i\n", __FILE__, __LINE__, (error)); }


int sysfs_write(const char *path, const char *arg) {
    int err;

    FILE *f = fopen(path, "w");
    if (!f) return -ENOENT;

    err = (fprintf(f, "%s", arg) < 1);

    fclose(f);

    return err;
}

int sysfs_read(const char *path, size_t size, char *arg) {
    int err = 0;
    size_t bytes;

    FILE *f = fopen(path, "r");
    if (!f) return -ENOENT;

    bytes = fread((void*)arg, 1, size - 1, f);
    if (bytes == 0) err = EIO;
    else arg[bytes] = 0;

    fclose(f);

    return err;
}


int sysfs_write_int(const char *path, long arg) {
    char s[16];
    sprintf(s, "%d", arg);
    return sysfs_write(path, s);
}

long sysfs_read_int(const char *path, int *reterr) {
    int err;
    char s[32];

    long res = 0;

    err = sysfs_read(path, 32, s);
    if (!err)  {
	if (s[1] == 'x') {
	    err = (sscanf(s + 2, "%lx", &res) < 1);
	} else {
	    err = (sscanf(s, "%lu", &res) < 1);
	}
    }

    if (reterr) *reterr = err;
    return res;
}


int main(void)
{
    int i;
    size_t work_size = 1;

    cl_context context;
    cl_command_queue command_queue;
    cl_int err;
    cl_uint num_of_platforms=0;
    cl_platform_id platform_id;
    cl_device_id device_id;
    cl_uint num_of_devices=0;
    cl_mem input;//, output, host;
    cl_event event;

    cl_int status;
    cl_command_type type;
    size_t res_size;

    uint32_t check;

    CL_CHECK_STATUS(clGetPlatformIDs(1, &platform_id, &num_of_platforms));

    CL_CHECK_STATUS(clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id,&num_of_devices));

    cl_context_properties properties[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties) platform_id, 0 };
    context = clCreateContext(properties, 1, &device_id, NULL,NULL, &err);
    CL_CHECK_STATUS(err);

    command_queue = clCreateCommandQueue(context, device_id, 0, &err);
    CL_CHECK_STATUS(err);

	// CL_MEM_ALLOC_HOST_PTR does not help to access the data directly


    sysfs_write_int("/sys/class/nvtrace/enable", 1);
    input = clCreateBuffer(context, CL_MEM_READ_WRITE/*|CL_MEM_ALLOC_HOST_PTR*/,  DATA_SIZE, NULL, &err); CL_CHECK_STATUS(err);
    CL_CHECK_STATUS (clEnqueueWriteBuffer (command_queue, input, CL_TRUE, 0, 4, &i, 0, NULL, NULL));
    sysfs_write_int("/sys/class/nvtrace/enable", 0);

    uint32_t nv_user = sysfs_read_int("/sys/class/nvtrace/user", NULL);
    uint32_t nv_buffer = sysfs_read_int("/sys/class/nvtrace/buffer", NULL);

    printf("Detected context & buffer: %x %x\n", nv_user, nv_buffer);
    
    int nvfd = open("/dev/nvidia0", O_RDWR);
    if (nvfd >= 0) {
	uint32_t gpu_method_param = nv_buffer;
	uint32_t gpu_method[8] = {
	    nv_user,
	    0x5c00000eu,
	    0x503c0104u,
	    0x00000000u,
	    0,
	    0,
	    0x00000004u,
	    0x00000000u
	};
	
	((uint64_t*)gpu_method)[2] = (uint64_t)&gpu_method_param;

	sysfs_write_int("/sys/class/nvtrace/enable", 1);
	if (ioctl(nvfd, 0xc020462a, gpu_method) < 0)
	    printf(" ==> Error communicating with nvidia device, errno %i\n", errno);
	sysfs_write_int("/sys/class/nvtrace/enable", 0);
	
	close(nvfd);
    }

    clReleaseMemObject(input);
    clReleaseCommandQueue(command_queue);
    clReleaseContext(context);
}