I am working with CUDA and I am trying to stop my kernels work (i.e. terminate all running threads) after a certain if block is being hit. How can I do that? I am really stuck in here.
The CUDA execution model doesn't allow for inter-block communication by design. That can potentially make this sort of kernel abort on condition operation difficult to achieve reliably without resorting to the assert or trap type approaches which can potentially result in context destruction and loss of data which isn't what you probably want.
If your kernel design involves a small number of blocks with "resident" threads, then the only approach is some sort of atomic spinlock, which is hard to get to work reliably, and which will greatly degrade memory controller performance and achievable bandwidth.
If, on the other hand, your kernel design has rather large grids with a lot of blocks, and your main goal is to stop blocks which are not yet scheduled from running, then you could try something like this:
#include <iostream>
#include <vector>
__device__ unsigned int found_idx;
__global__ void setkernel(unsigned int *indata)
{
indata[115949] = 0xdeadbeef;
indata[119086] = 0xdeadbeef;
indata[60534] = 0xdeadbeef;
indata[37072] = 0xdeadbeef;
indata[163107] = 0xdeadbeef;
}
__global__ void searchkernel(unsigned int *indata, unsigned int *outdata)
{
if (found_idx > 0) {
return;
} else if (threadIdx.x == 0) {
outdata[blockIdx.x] = blockIdx.x;
};
unsigned int tid = threadIdx.x + blockIdx.x * blockDim.x;
if (indata[tid] == 0xdeadbeef) {
unsigned int oldval = atomicCAS(&found_idx, 0, 1+tid);
}
}
int main()
{
const unsigned int N = 1 << 19;
unsigned int* in_data;
cudaMalloc((void **)&in_data, sizeof(unsigned int) * size_t(N));
cudaMemset(in_data, 0, sizeof(unsigned int) * size_t(N));
setkernel<<<1,1>>>(in_data);
cudaDeviceSynchronize();
unsigned int block_size = 1024;
unsigned int grid_size = N / block_size;
unsigned int* out_data;
cudaMalloc((void **)&out_data, sizeof(unsigned int) * size_t(grid_size));
cudaMemset(out_data, 0xf0, sizeof(unsigned int) * size_t(grid_size));
const unsigned int zero = 0;
cudaMemcpyToSymbol(found_idx, &zero, sizeof(unsigned int));
searchkernel<<<grid_size, block_size>>>(in_data, out_data);
std::vector<unsigned int> output(grid_size);
cudaMemcpy(&output[0], out_data, sizeof(unsigned int) * size_t(grid_size), cudaMemcpyDeviceToHost);
cudaDeviceReset();
std::cout << "The following blocks did not run" << std::endl;
for(int i=0, j=0; i<grid_size; i++) {
if (output[i] == 0xf0f0f0f0) {
std::cout << " " << i;
if (j++ == 20) {
std::cout << std::endl;
j = 0;
}
}
}
std::cout << std::endl;
return 0;
}
Here I have a simple kernel which is searching for a magic word in a large array. To get the early exit behaviour, I use a single global word, which is set atomically by those threads which "win" or trigger the termination condition. Every new block checks the state of this global word, and if it is set, they return without doing any work.
If I compile and run this on a moderate sized Kepler device:
$ nvcc -arch=sm_30 -o blocking blocking.cu
$ ./blocking
The following blocks did not run
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 154 155 156 157 158 159 160 161 162 163 164 165 166 167
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503
504 505 506 507 508 509 510 511
you can see that a large number of blocks in the grid saw the change in the global word and early terminated without running the search code. This might be the best you can do without a severely invasive spinlock approach which will greatly harm performance.
I assume you want to stop a running kernel (not a single thread).
The simplest approach (and the one that I suggest) is to set up a global memory flag which is been tested by the kernel.
You can set the flag using cudaMemcpy() (or without if using unified memory).
Like the following:
if (gm_flag) {
__threadfence(); // ensure store issued before trap
asm("trap;"); // kill kernel with error
}
ams("trap;") will stop all running thread
Note that since cuda 2.0 you can use assert() to terminate a kernel!
A different approach could be the following (I haven't tried the code!)
__device__ bool go(int val){
return true;
}
__global__ void stopme(bool* flag, int* val, int size){
int idx= blockIdx.x *blockDim.x + threadIdx.x;
if(idx < size){
bool canContinue = true;
while(canContinue && (flag[0])){
printf("HELLO from %i\n",idx);
if(!(*flag)){
return;
}
else{
//do some computation
val[idx]++;
val[idx]%=100;
}
canContinue = go(val[idx]);
}
}
}
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
if (abort) exit(code);
}
}
int main(void)
{
int size = 128;
int* h_val = (int*)malloc(sizeof(int)*size);
bool * h_flag = new bool;
*h_flag=true;
bool* d_flag;
cudaMalloc(&d_flag,sizeof(bool));
cudaMemcpy(d_flag,h_flag,1,cudaMemcpyHostToDevice);
int* d_val;
cudaMalloc(&d_val,sizeof(int)*size );
for(int i=0;i<size;i++){
h_val[i] = i;
}
cudaMemcpy(d_val,h_val,size,cudaMemcpyHostToDevice);
int BSIZE=32;
int nblocks =size/BSIZE;
printf("%i,%i",nblocks,BSIZE);
stopme<<<nblocks,BSIZE>>>(d_flag,d_val,size);
//--------------sleep for a while --------------------------
*h_flag=false;
cudaMemcpy(d_flag,h_flag,1,cudaMemcpyHostToDevice);
cudaDeviceSynchronize();
gpuErrchk( cudaPeekAtLastError() );
printf("END\n");
}
where the kernel stopMe keeps running until someone from the host side sets up the flag to false. Note that your kernel could be much more complicated than this and the effort to synchronize all threads in order to execute the return could be much more than this (and can affect performance). Hope this helped.
More info here
Related
I have a tls file such as:
1224 926 1380 688 845 109 118 88 1275 1306 91 796 102 1361 27 995
1928 2097 138 1824 198 117 1532 2000 1478 539 1982 125 1856 139 475 1338
848 202 1116 791 1114 236 183 186 150 1016 1258 84 952 1202 988 866
946 155 210 980 896 875 925 613 209 746 147 170 577 942 475 850
1500 322 43 95 74 210 1817 1631 1762 128 181 716 171 1740 145 1123
3074 827 117 2509 161 206 2739 253 2884 248 3307 2760 2239 1676 1137 3055
183 85 143 197 243 72 291 279 99 189 30 101 211 209 77 198
175 149 259 372 140 250 168 142 146 284 273 74 162 112 78 29
169 578 97 589 473 317 123 102 445 217 144 398 510 464 247 109
3291 216 185 1214 167 495 1859 194 1030 3456 2021 1622 3511 222 3534 1580
2066 2418 2324 93 1073 82 102 538 1552 962 91 836 1628 2154 2144 1378
149 963 1242 849 726 1158 164 1134 658 161 1148 336 826 1303 811 178
3421 1404 2360 2643 3186 3352 1112 171 168 177 146 1945 319 185 2927 2289
543 462 111 459 107 353 2006 116 2528 56 2436 1539 1770 125 2697 2432
1356 208 5013 4231 193 169 3152 2543 4430 4070 4031 145 4433 4187 4394 1754
5278 113 4427 569 5167 175 192 3903 155 1051 4121 5140 2328 203 5653 3233
how can I read it in a list of list of int in haskell?
I have tried few options but I could not manage to do it. I am very new to haskell so please be patience.
First break your input into lines using lines:
let test = "1 2 3 4\n 5 6 7 \n 4 2 5"
let rows = lines test --literally "lines test"! Beautiful, eh?
Result:
["1 2 3 4"," 5 6 7 "," 4 2 5"] :: [[Char]]
Then, extract individual numbers as strings using words:
let nums_as_strings = map words rows
Result:
[["1","2","3","4"],["5","6","7"],["4","2","5"]] :: :: [[[Char]]]
The last thing to do is convert these strings to integers with read:
let numbers = map (map read) nums_as_strings :: [[Int]]
Result:
[[1,2,3,4],[5,6,7],[4,2,5]] :: [[Int]]
Or, squashed into one line:
let numbers = map (map read) (map words $ lines test) :: [[Int]]
Example with your data:
Prelude> let test = "1224 926 1380 688 845 109 118 88 1275 1306 91 796 102 1361 27 995\n1928 2097 138 1824 198 117 1532 2000 1478 539 1982 125 1856 139 475 1338"
Prelude> map (map read) (map words $ lines test) :: [[Int]]
[[1224,926,1380,688,845,109,118,88,1275,1306,91,796,102,1361,27,995],[1928,2097,138,1824,198,117,1532,2000,1478,539,1982,125,1856,139,475,1338]]
You may need to take care of empty lines, but that's really simple.
import System.IO
readListOfLists :: Handle -> IO [[Int]]
readListOfLists handle = do
contents <- hGetContents handle
let ls :: [String]
ls = lines contents
ws :: [[String]]
ws= map words ls
res :: [[Int]]
res = map (map read) ws
return res;
or you can write the same code in one line:
readListOfLists :: Handle -> IO [[Int]]
readListOfLists = fmap (map (map read . words) . lines) . hGetContents
To use it:
do
handle <- openFile fileName ReadMode
table <- readListOfLists handle
hClose handle
print table
I make this program to practice cudaMemcpy3D() and Texture Memory.
Here comes the questions,when I print out tex3D data,it is not same as initial data.The value I get is ncrss times the initial value, and there are ncrss interval numbers which equal to 0 between each other. If I set nsubs to 2 or other bigger one, the time should be ncrss*nsubs and interval will be ncrss*nsubs.
Can you piont out where I made the mistakes. I think it probably is make_cudaPitchedPtr at line 61, or make_cudaExtent at line 56. And also may related with the way of array storaged.
So I come here for your help,appreciate for your comments and advices.
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<cuda_runtime.h>
4 #include<helper_functions.h>
5 #include<helper_cuda.h>
6 #ifndef MIN
7 #define MIN(A,B) ((A) < (B) ? (A) : (B))
8 #endif
9 #ifndef MAX
10 #define MAX(A,B) ((A) > (B) ? (A) : (B))
11 #endif
12
13 texture<float,cudaTextureType3D,cudaReadModeElementType> vel_tex;
14
15 __global__ void mckernel(int ntab)
16 {
17 const int biy=blockIdx.y;//sub
18 const int bix=blockIdx.x;//crs
19 const int tid=threadIdx.x;
20
21 float test;
22 test=tex3D(vel_tex,biy,bix,tid);
23 printf("test=%f,bix=%d,tid=%d\n",test,bix,tid);
24
25 }
26
27 int main()
28 {
29 int n=10;//208
30 int ntab=10;
31 int submin=1;
32 int crsmin=1;
33 int submax=1;
34 int crsmax=2;
35 int subinc=1;
36 int crsinc=1;
37
38 int ncrss,nsubs;
39 ncrss=(crsmax-crsmin)/crsinc + 1;
40 nsubs=(submax-submin)/subinc + 1;
41 dim3 BlockPerGrid(ncrss,nsubs,1);
42 dim3 ThreadPerBlock(n,1,1);
43
44 float vel[nsubs][ncrss][ntab];
45 int i,j,k;
46 for(i=0;i<nsubs;i++)
47 for(j=0;j<ncrss;j++)
48 for(k=0;k<ntab;k++)
49 vel[i][j][k]=k;
50 for(i=0;i<nsubs;i++)
51 for(j=0;j<ncrss;j++)
52 for(k=0;k<ntab;k++)
53 printf("vel[%d][%d][%d]=%f\n",i,j,k,vel[i][j][k]);
54
55 cudaChannelFormatDesc velchannelDesc=cudaCreateChannelDesc<float>();
56 cudaExtent velExtent=make_cudaExtent(nsubs,ncrss,ntab);
57 cudaArray *d_vel;
58 cudaMalloc3DArray(&d_vel,&velchannelDesc,velExtent);
59
60 cudaMemcpy3DParms velParms = {0};
61 velParms.srcPtr=make_cudaPitchedPtr((void*)vel,sizeof(float)*nsubs,nsubs,ncrss);
62 velParms.dstArray=d_vel;
63 velParms.extent=velExtent;
64 velParms.kind=cudaMemcpyHostToDevice;
65 cudaMemcpy3D(&velParms);
66
67 cudaBindTextureToArray(vel_tex,d_vel);
68
69 printf("kernel start\n");
70 cudaDeviceSynchronize();
71 mckernel<<<BlockPerGrid,ThreadPerBlock>>>(ntab);
72 printf("kernel end\n");
73
74 cudaUnbindTexture(vel_tex);
75 cudaFreeArray(d_vel);
76 cudaDeviceReset();
77 return 0 ;
78 }
Here comes the printf data,nsubs=1 and ncrss=2;
1 vel[0][0][0]=0.000000
2 vel[0][0][1]=1.000000
3 vel[0][0][2]=2.000000
4 vel[0][0][3]=3.000000
5 vel[0][0][4]=4.000000
6 vel[0][0][5]=5.000000
7 vel[0][0][6]=6.000000
8 vel[0][0][7]=7.000000
9 vel[0][0][8]=8.000000
10 vel[0][0][9]=9.000000
11 vel[0][1][0]=0.000000
12 vel[0][1][1]=1.000000
13 vel[0][1][2]=2.000000
14 vel[0][1][3]=3.000000
15 vel[0][1][4]=4.000000
16 vel[0][1][5]=5.000000
17 vel[0][1][6]=6.000000
18 vel[0][1][7]=7.000000
19 vel[0][1][8]=8.000000
20 vel[0][1][9]=9.000000
21 kernel start
22 kernel end
23 test=1.000000,bix=1,tid=0
24 test=3.000000,bix=1,tid=1
25 test=5.000000,bix=1,tid=2
26 test=7.000000,bix=1,tid=3
27 test=9.000000,bix=1,tid=4
28 test=1.000000,bix=1,tid=5
29 test=3.000000,bix=1,tid=6
30 test=5.000000,bix=1,tid=7
31 test=7.000000,bix=1,tid=8
32 test=9.000000,bix=1,tid=9
33 test=0.000000,bix=0,tid=0
34 test=2.000000,bix=0,tid=1
35 test=4.000000,bix=0,tid=2
36 test=6.000000,bix=0,tid=3
37 test=8.000000,bix=0,tid=4
38 test=0.000000,bix=0,tid=5
39 test=2.000000,bix=0,tid=6
40 test=4.000000,bix=0,tid=7
41 test=6.000000,bix=0,tid=8
42 test=8.000000,bix=0,tid=9
After a night thinking ,I find out the problem.
the cuda array load as M[fast][mid][low] while c array is M[low][mid][fast].
so dim3(),cudaExtent(),pitchedPtr()should be same to [low][mid][fast] or at least should be same as each other.
In a coding contest I have a programming task to find minimum or maximum from different arrays, and the final result to put it at the end of the URL (www.example.com/result).
I can't figure out what format are they expecting...
They gave this hint:
look at the resulting values and see if they could represent something familiar), at the end of the root of the URL of the page you're on (of course add a slash if needed)
Update
For the result of the problem, you need to figure out a way to convert those numbers to a "URL friendly form" value.
For example, a URL friendly value means a string, so you need a 'standard' way to convert each number to a character and use the resulting string to go to the next problem.
I tried the following formats 1:2:3:4 , 1_2_3_4 no chance.
The numbers are 100,126,114,85,82,121,54 .
So I need them formatted in an url friendly form whatever that would mean.
This is the coding challenge :
You are given an input file containing:
On the first line a positive integer N
On the following N lines there will be arrays of integers, of variable length, each integer value separated by a white space from the next value
The start of each array will only contain one of the following possible numbers: 1 or -1
To get to the next step you will have to calculate the minimum (if start value is -1) or maximum (if start value is 1) of the arrays in the input file and then put the result, in a more human and URL friendly form (hint: look at the resulting values and see if they could represent somehting familiar), at the end of the root of the URL of the page you're on (of course add a slash if needed). Also keep the code used to solve this problem!
Here is your input data:
7
-1 156 198 171 134 197 120 149 177 130 100 103 126 169 115 199 188 119 168 151 161 167 141 111
-1 126 128 150 190 193 198 168 128 194 138 196 153 134 163 152 136 158 132 178 141 174 143 195 126 183 132 174 173 171 130 155 164 158
-1 178 115 166 161 164 134 130 164 147 114
1 73 78 81 66 77 0 26 42 48 42 12 24 33 4 54 31 50 34 78 13 21 37 29 85 56 68 12 79 81 82 25 7 16 44 32 82
1 62 35 54 82 30 7 28 78 74 34 12 80 40 16 5 39 29
-1 157 183 175 140 158 164 138 166 176 121 145 139 186 188 158 121 183 146 132 124 123 198 162 135 161 132 187 184 121 148 157 146 123 199 142 134 196 179
-1 70 74 81 105 121 129 148 91 160 76 146 94 64 154 54 102 142 68 62 88 63 144 143 138 118 117 148 166 146 159 162 130 183 184 156 172
Array.max = function( array ){
return Math.max.apply( Math, array );
};
Array.min = function( array ){
return Math.min.apply( Math, array );
};
function m(str) {
var parts = str.split(" ");
var what = parts.shift();
if (what=="-1") return Array.min(parts);
else return Array.max(parts);
}
var num=[];
num.push(7); // not sure about this one. Use the encode if yes
num.push(m("-1 156 198 171 134 197 120 149 177 130 100 103 126 169 115 199 188 119 168 151 161 167 141 111"))
num.push(m("-1 126 128 150 190 193 198 168 128 194 138 196 153 134 163 152 136 158 132 178 141 174 143 195 126 183 132 174 173 171 130 155 164 158"))
num.push(m("-1 178 115 166 161 164 134 130 164 147 114"))
num.push(m("1 1 73 78 81 66 77 0 26 42 48 42 12 24 33 4 54 31 50 34 78 13 21 37 29 85 56 68 12 79 81 82 25 7 16 44 32 82"))
num.push(m("1 62 35 54 82 30 7 28 78 74 34 12 80 40 16 5 39 29"))
num.push(m("-1 157 183 175 140 158 164 138 166 176 121 145 139 186 188 158 121 183 146 132 124 123 198 162 135 161 132 187 184 121 148 157 146 123 199 142 134 196 179"))
num.push(m("-1 70 74 81 105 121 129 148 91 160 76 146 94 64 154 54 102 142 68 62 88 63 144 143 138 118 117 148 166 146 159 162 130 183 184 156 172"))
var str = String.fromCharCode.apply(null, num);
console.log(num,str);
console.log(encodeURIComponent(str)); // if 7 is part of the numbers
// location = "http://www.example.com/"+str;
I am working on verifying the access token on AWS Cognito. One thing I have to do is to convert the key from jwks.json (of the userpool) into a rsa Public Key structure (depending on the used JWT API).
So the values for 'n' and 'e' must be big int (long) and int.
What would be the proper value of those two variables, for example:
raw_n := "rdTmzrh7t0i_YN0MDLejnS0jXIFoSzRfFEbqf-bwGuRLnhLI4T3zGAk9HGZeAG6B5gg1D40Jsz1upo4E70VS0raGfSBPYPO7ZAJ2VCUUeblr9X_aWK4f294v4Cf3n8jZyFcGK9qhgcqy3DlHqqDANtjamWVtEhTRTFc-qoz1ScvHmPupsXlj1FsAEFEbVhP4705ez5gW3uQOoidrm38sPFwCN7g7xhA9CyzF04Zsjky55OfMCyWlIt7nljLx7ZRG3dVRD3vdEBI99qtxf43qMCWSPUk7Whn11Wf_u0xDrWhtGR9k599rKBBRWuqcujYYnFuOT0BeQIL25cePPK8lxw"
raw_e := "AQAB"
I suppose this is Base64 URL encoded.
I am using Go and when decoding them, I am having those values:
Value of N = 21944212446918148307583266513211511961176501179660110972882270757464120247554839864039423096862533136364974693915136668416630333929475539217929135693935014796040215031370110392351836608149288005498214604075814317642291632460369313969964278103135047317799644939426174469533574133378199425168189176269507635563270873057483981163804984573367938044175828995131343800369166239708527999544583873649523245709447765091038652758632917341001616695912404965678061555823269517387737693508193881028187912513285002546706797506255288735805912213209305939523528571103281920754204216834697552752238593850648051945624431639572960454087
Value of E = 65537
And the final values are:
TokenSignature= GYZQKv7o8_o9E4ktVKZngYD4BS5QluOMwE-MRcJB432CmNimQm6JbvT3H48ECThe4f3sZ1KyVbgDJbyUnlkaAwMEBjMnlV7AUaZb-ifveM7kHM30BS5LCV_SCiCk-PvmWjeIHu9bR3EwG8azJCceD5A7gDLmhAtPN94gRy-opXJPAnaCba00AwKBd_pN3UH7LYu4u4EQ29eIfn4k4RCLuR31jr7ad3dvvjhhy658dQSHzSuPZGcN1-CRVSlrd0nk0Ba2t8W33LtjxM6wzPThWgh0fpy2XEDosGU_9FiXdEjUKisE3VHxroygQ8ekVWKHssa2eujXCx8OthWzaGag0w1
Signing String= eyJhbGciOiJSUzI1NiIsImtpZCI6ImpBNlFvakp0RkI0TmNIR1BmcS85ZWgzSHI2YnVXWEI0VzkxRTd5bWNjSk09In0.eyJleHAiOjE0NzAyNzgzMTEsInRva2VuX3VzZSI6ImFjY2VzcyIsImlzcyI6Imh0dHBzOi8vY29nbml0by1pZHAudXMtZWFzdC0xLmFtYXpvbmF3cy5jb20vdXMtZWFzdC0xX0d1OFlhVGg3MiIsImNsaWVudF9pZCI6IjRwNzNuYjhra3NsbHJrbTlzMzdzYXZsNzEzIiwidXNlcm5hbWUiOiJtYXRlbyIsImtpZCI6IiIsImFsZyI6IiIsImp0aSI6IjhmNTBiZmU4LWVlNGUtNGFkZi04MDQxLWU5MGM4YWJkZDExZCIsImlhdCI6MTQ3MDI3NDcxMSwic3ViIjoiYjFjMDZhMTktYjE5Yy00NGMwLTgzZjctODY2NTZjYzRmMjMxIn0
rsa.PublicKey{N:21944212446918148307583266513211511961176501179660110972882270757464120247554839864039423096862533136364974693915136668416630333929475539217929135693935014796040215031370110392351836608149288005498214604075814317642291632460369313969964278103135047317799644939426174469533574133378199425168189176269507635563270873057483981163804984573367938044175828995131343800369166239708527999544583873649523245709447765091038652758632917341001616695912404965678061555823269517387737693508193881028187912513285002546706797506255288735805912213209305939523528571103281920754204216834697552752238593850648051945624431639572960454087, E:65537}
However, with those revisiter values, I am still getting crypto/rsa: verification error. How can I determine if the problem is coming from the JWT Library or the values?
Thank you very much
You should be able to verify the signature with the rsa.PublicKey generated by the program below or at https://play.golang.org/p/VZqD5m057b. It is based on code from https://github.com/mendsley/gojwk (please see the playground link or https://github.com/mendsley/gojwk/blob/master/LICENSE for the Copyright attribution) - I would recommend to clone that repository and use it as an example and model.
package main
import (
"crypto/rsa"
"encoding/base64"
"encoding/binary"
"fmt"
"math/big"
)
func main() {
rawN := "rdTmzrh7t0i_YN0MDLejnS0jXIFoSzRfFEbqf-bwGuRLnhLI4T3zGAk9HGZeAG6B5gg1D40Jsz1upo4E70VS0raGfSBPYPO7ZAJ2VCUUeblr9X_aWK4f294v4Cf3n8jZyFcGK9qhgcqy3DlHqqDANtjamWVtEhTRTFc-qoz1ScvHmPupsXlj1FsAEFEbVhP4705ez5gW3uQOoidrm38sPFwCN7g7xhA9CyzF04Zsjky55OfMCyWlIt7nljLx7ZRG3dVRD3vdEBI99qtxf43qMCWSPUk7Whn11Wf_u0xDrWhtGR9k599rKBBRWuqcujYYnFuOT0BeQIL25cePPK8lxw"
rawE := "AQAB"
decodedE, err := base64.RawURLEncoding.DecodeString(rawE)
if err != nil {
panic(err)
}
// make sure that the E field is at least 4 bytes, pad if necessary
if len(decodedE) < 4 {
ndata := make([]byte, 4)
copy(ndata[4-len(decodedE):], decodedE)
decodedE = ndata
}
pubKey := &rsa.PublicKey{
N: &big.Int{},
E: int(binary.BigEndian.Uint32(decodedE[:])),
}
decodedN, err := base64.RawURLEncoding.DecodeString(rawN)
if err != nil {
panic(err)
}
pubKey.N.SetBytes(decodedN)
fmt.Println(decodedN)
fmt.Println(decodedE)
fmt.Printf("%#v\n", *pubKey)
}
Output:
[173 212 230 206 184 123 183 72 191 96 221 12 12 183 163 157 45 35 92 129 104 75 52 95 20 70 234 127 230 240 26 228 75 158 18 200 225 61 243 24 9 61 28 102 94 0 110 129 230 8 53 15 141 9 179 61 110 166 142 4 239 69 82 210 182 134 125 32 79 96 243 187 100 2 118 84 37 20 121 185 107 245 127 218 88 174 31 219 222 47 224 39 247 159 200 217 200 87 6 43 218 161 129 202 178 220 57 71 170 160 192 54 216 218 153 101 109 18 20 209 76 87 62 170 140 245 73 203 199 152 251 169 177 121 99 212 91 0 16 81 27 86 19 248 239 78 94 207 152 22 222 228 14 162 39 107 155 127 44 60 92 2 55 184 59 198 16 61 11 44 197 211 134 108 142 76 185 228 231 204 11 37 165 34 222 231 150 50 241 237 148 70 221 213 81 15 123 221 16 18 61 246 171 113 127 141 234 48 37 146 61 73 59 90 25 245 213 103 255 187 76 67 173 104 109 25 31 100 231 223 107 40 16 81 90 234 156 186 54 24 156 91 142 79 64 94 64 130 246 229 199 143 60 175 37 199]
[0 1 0 1]
rsa.PublicKey{N:21944212446918148307583266513211511961176501179660110972882270757464120247554839864039423096862533136364974693915136668416630333929475539217929135693935014796040215031370110392351836608149288005498214604075814317642291632460369313969964278103135047317799644939426174469533574133378199425168189176269507635563270873057483981163804984573367938044175828995131343800369166239708527999544583873649523245709447765091038652758632917341001616695912404965678061555823269517387737693508193881028187912513285002546706797506255288735805912213209305939523528571103281920754204216834697552752238593850648051945624431639572960454087, E:65537}
I have used npm module jwk-to-pem in my nodeJS app. As seen in the documentation:
var jwkToPem = require('jwk-to-pem'),
jwt = require('jsonwebtoken');
var jwk = { kty: 'EC', crv: 'P-256', x: '...', y: '...' },
pem = jwkToPem(jwk);
jwt.verify(token, pem);
You can export pem to a file and use it in your code.
Decoding a JWK into a *rsa.PublicKey can be done by unmarshing the JSON into the following data structure and using the method below.
A link to this data structure:
// JSONKey represents a raw key inside a JWKs.
type JSONKey struct {
Curve string `json:"crv"`
Exponent string `json:"e"`
ID string `json:"kid"`
Modulus string `json:"n"`
X string `json:"x"`
Y string `json:"y"`
precomputed interface{}
}
A link to this method:
// RSA parses a JSONKey and turns it into an RSA public key.
func (j *JSONKey) RSA() (publicKey *rsa.PublicKey, err error) {
// Check if the key has already been computed.
if j.precomputed != nil {
var ok bool
if publicKey, ok = j.precomputed.(*rsa.PublicKey); ok {
return publicKey, nil
}
}
// Confirm everything needed is present.
if j.Exponent == "" || j.Modulus == "" {
return nil, fmt.Errorf("%w: rsa", ErrMissingAssets)
}
// Decode the exponent from Base64.
//
// According to RFC 7518, this is a Base64 URL unsigned integer.
// https://tools.ietf.org/html/rfc7518#section-6.3
var exponent []byte
if exponent, err = base64.RawURLEncoding.DecodeString(j.Exponent); err != nil {
return nil, err
}
// Decode the modulus from Base64.
var modulus []byte
if modulus, err = base64.RawURLEncoding.DecodeString(j.Modulus); err != nil {
return nil, err
}
// Create the RSA public key.
publicKey = &rsa.PublicKey{}
// Turn the exponent into an integer.
//
// According to RFC 7517, these numbers are in big-endian format.
// https://tools.ietf.org/html/rfc7517#appendix-A.1
publicKey.E = int(big.NewInt(0).SetBytes(exponent).Uint64())
// Turn the modulus into a *big.Int.
publicKey.N = big.NewInt(0).SetBytes(modulus)
// Keep the public key so it won't have to be computed every time.
j.precomputed = publicKey
return publicKey, nil
}
If you're looking to authenticate JWTs from a JWKs resource like AWS Cognito, I took these examples from a project that does just that: github.com/MicahParks/keyfunc
I'm a complete novice when it comes to SQL, just getting started.
I need help writing a query to update values in my SQL table:
Two tables: Members, Chapters
Concerned with three columns in Chapters table: CHAP_NO, FA, FA2
i.e.
CHAP_NO FA FA2
111 1234567 2345689
222 2234567 4567899
333 3225545
444
555 2358878 4566665
666 4568799
777 4566878 1233666
888 1119998
999 3555879 6544799
etc. . .
Each value is a unique identifier
Concerned with two columns in Members table: MEMB_NO, CURR_CHAP
i.e.
MEMB_NO CURR_CHAP
1234567 665
5468787 664
4577789 122
4578767 233
7775666 588
4114748 787
etc. . .
Is it possible to automate an update based on if FA or FA2 is in Chapters table, update their CURR_CHAP value in the Members table from the CHAP_NO value?
From the above example data, I need MEMB_NO '1234567' to have his CURR_CHAP updated to '111' because he is listed as FA for CHAP_NO '111'
I really need to do this for similar MS SQL and MySQL databases if possible. If this can't be automated, I need help writing a query to manually update the Members table as exampled above with a 2 column manual update row of data:
MEMB_NO CURR_CHAP
5470011 547
5030038 545
3880188 544
1140753 543
4130019 543
5420011 542
5410010 541
2590511 540
4190109 540
4180296 539
5380020 538
5370012 537
1050859 536
4390125 535
4860144 535
5330009 533
5330061 533
1080746 532
2060321 531
1750750 529
4250135 528
8070013 528
1080645 527
5270053 527
2580695 526
2440073 525
2440163 525
5240010 524
4980035 523
2120380 522
4000418 521
3270185 520
4350210 519
4610218 518
5160004 516
1610450 515
5150065 515
5130046 513
5130050 513
5120047 512
1940306 510
2500170 510
5090087 509
5080014 508
1270803 505
1381026 505
2260505 504
3900106 504
5030006 503
1770526 501
1780355 501
5000017 500
4980037 498
2380411 497
4970019 497
4960044 496
4960127 496
4950012 495
4950095 495
1720409 494
2260867 494
2300466 493
3990055 492
4920204 492
1311252 491
2100252 491
1750592 490
1760563 490
2520403 489
4890051 489
4870076 487
4870143 487
4860153 486
1670856 485
4840054 484
4840143 484
2920024 483
4830136 483
1751087 482
1790828 481
1970128 481
2050815 480
4800027 480
1870246 478
3210174 478
4770100 477
4760124 476
4760126 476
1350640 475
2280722 475
2200077 474
3410230 474
4730100 473
4250159 470
4250156 470
3790179 464
4630164 463
4630139 463
2210062 461
4610188 461
4210110 460
4870065 459
4500246 450
1110937 449
1110934 449
2280501 447
4450323 445
4440114 444
4410135 441
4410216 441
1600799 435
2280449 435
4080089 431
4310132 431
1780525 427
4270190 427
4260502 426
4260550 426
4250467 425
4250485 425
4210328 421
4190230 419
4180005 418
4180341 418
4250232 417
4130004 413
4110444 411
4090133 409
4080308 408
4430119 408
4070279 407
4070443 407
1650354 405
1670725 404
2240204 402
2870319 400
3990114 399
3980014 398
4050073 398
3170399 397
3970348 397
1760487 395
4180191 395
1800443 394
2580288 394
1280499 393
3930227 393
3780058 391
3900377 390
2590362 389
1720492 385
1720398 384
2840325 383
3710142 381
3800235 380
3780407 378
1760459 375
1730026 373
3710306 371
3710228 371
1051294 370
3700332 370
3670174 367
1780583 359
4640038 359
1280614 358
2580373 358
3570449 357
3530560 353
3500046 350
3490275 349
3490244 349
3320203 348
3480310 348
4210188 346
3440364 344
4490223 344
1750642 342
3990257 342
1790541 341
3370562 337
3370738 337
1870336 334
3340382 334
1950674 333
1460619 328
3280586 328
4250013 326
1340705 324
2590495 324
2870029 322
3030290 322
1880232 321
2280415 321
3200547 320
3200568 320
3180132 318
3180178 318
3930433 317
4850072 317
2870449 315
3150168 315
1390763 313
3120170 312
3110048 311
3110110 311
3070267 307
3500231 306
3980122 306
1160708 305
3050510 305
2280197 304
3040348 304
1060785 303
1340760 303
3020534 302
3980151 301
2990239 299
1770425 297
2950573 295
2280513 294
2320434 287
2870594 287
4110133 284
4260131 278
2770221 277
2770366 277
2760484 276
2750397 275
2580694 272
1751006 267
4010252 267
2660235 266
2780335 265
2640326 264
3840125 263
1270872 259
2590690 259
2580728 258
2030556 257
4600151 257
2550390 255
4440010 255
2520461 252
4130095 252
3910117 250
2490314 249
1361032 247
1900370 247
2440211 244
2440101 244
1730150 243
1440258 242
2420062 242
1350511 238
2380559 238
1800598 237
2350417 235
2340372 234
2320453 232
2590582 232
2120104 230
2280696 228
3480122 227
1111011 226
2260626 226
3230234 222
2270200 221
4470101 221
3010326 219
2180334 218
2170591 217
1620648 213
2120524 212
3010424 212
3130060 210
2070261 207
2070313 207
1640858 206
1620684 205
2030573 203
2030810 203
1270589 201
1111015 200
1990448 199
1950384 195
1920328 192
1920684 192
1750798 188
1880607 188
1870445 187
1850587 185
2960295 185
1800721 180
1791166 179
3990116 178
3130119 177
4170034 177
1051172 176
1380942 176
1751011 175
4500021 175
2840346 174
3460307 174
1730027 173
4070275 173
1110986 171
1670586 167
1111222 166
2060385 164
1560459 163
1740135 162
3130093 161
1600695 160
1600682 160
1350600 159
1590341 159
1580464 158
1570742 157
1570761 157
4440077 156
1520404 152
4700010 152
3390033 147
4170240 145
4730144 143
4250191 142
1400502 140
2170212 140
1360713 139
3040299 139
1800519 136
1270930 135
1720638 134
1800462 133
3930387 133
1111000 131
1311274 131
1360547 128
2260776 128
4830091 127
1800431 123
1280523 122
1750851 122
1291052 121
3850165 121
1180219 118
1180477 118
2240110 116
2870263 116
3900143 114
1111488 111
1490386 111
1060765 110
1780463 110
3200394 108
5050015 108
3870219 105
I think this should work on both...
UPDATE
IGNORE Chapters,
Members
SET Members.CURR_CHAP = Chapters.CHAP_NO
WHERE Chapters.FA = Members.MEMB_NO
AND Chapters.FA != ''
AND Chapters.FA2 != ''
UPDATE members m
INNER JOIN chapters c on (m.memb_no = c.fa or m.memb_no=c.fa2)
SET m.curr_chap=c.chap_no
This query worked for me in MySql
update Members m
INNER JOIN chapters c
ON (m.memb_no=c.FA or m.memb_no=c.FA2)
set CURR_CHAP = c.CHAP_NO